diff --git a/Example/UnsplashKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/UnsplashKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Example/UnsplashKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/README.md b/README.md
index a2cfeab..214ec4c 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,8 @@
Unsplash API client written in Swift.
+This Fork updates the Official API section to swift 5.0
+
[Unsplash](https://unsplash.com/) offers 2 APIs:
- [Source API](https://source.unsplash.com/) (unlimited requests)
- [Official API](https://unsplash.com/documentation)
diff --git a/UnsplashKit.podspec b/UnsplashKit.podspec
index 4bdac20..6fb6b8d 100644
--- a/UnsplashKit.podspec
+++ b/UnsplashKit.podspec
@@ -10,13 +10,14 @@ Swift client for unsplash.com API
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Caramba.io' => 'hello@caramba.io' }
s.source = { :git => 'https://github.com/carambalabs/UnsplashKit.git', :tag => s.version.to_s }
+ s.swift_version = '5.0'
s.default_subspec = 'Source'
s.subspec "Foundation" do |ss|
ss.source_files = 'UnsplashKit/Classes/Foundation/**/*.swift'
- ss.dependency 'Unbox', '~> 2.3'
- ss.dependency 'Result', '~> 3.1'
+ ss.dependency 'Unbox', '~> 4.0'
+ ss.dependency 'Result', '~> 5.0'
ss.dependency 'HTTPStatusCodes', '~> 3.1'
ss.frameworks = ["CoreLocation"]
end
diff --git a/UnsplashKit/Classes/Foundation/Resource.swift b/UnsplashKit/Classes/Foundation/Resource.swift
index b15ec45..bc04142 100644
--- a/UnsplashKit/Classes/Foundation/Resource.swift
+++ b/UnsplashKit/Classes/Foundation/Resource.swift
@@ -48,11 +48,11 @@ public struct Resource {
internal init(request: @escaping (URLComponents) -> URLRequest,
jsonParse: @escaping (Any, HTTPURLResponse) throws -> A) {
self.request = request
- self.parse = { input -> A in
- guard let json = try JSONSerialization.jsonObject(with: input.0, options: []) as? [String: Any] else {
+ self.parse = { data,response -> A in
+ guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
throw ResourceError.invalidData
}
- return try jsonParse(json, input.1)
+ return try jsonParse(json, response)
}
}
diff --git a/UnsplashKit/Classes/Foundation/WebLinking.swift b/UnsplashKit/Classes/Foundation/WebLinking.swift
index 1cb6bf8..02d835b 100644
--- a/UnsplashKit/Classes/Foundation/WebLinking.swift
+++ b/UnsplashKit/Classes/Foundation/WebLinking.swift
@@ -14,9 +14,8 @@ public struct Link: Equatable, Hashable {
self.parameters = parameters ?? [:]
}
- /// Returns the hash value
- public var hashValue: Int {
- return uri.hashValue
+ public func hash(into hasher: inout Hasher) {
+ hasher.combine(uri)
}
/// Relation type of the Link.
@@ -170,9 +169,9 @@ func split(_ separator: String) -> (String) -> (String, String) {
let range = input.range(of: separator, options: NSString.CompareOptions(rawValue: 0), range: nil, locale: nil)
if let range = range {
- let lhs = input.substring(to: range.lowerBound)
- let rhs = input.substring(from: range.upperBound)
- return (lhs, rhs)
+ let lhs = input[.. (String, ArraySlice) {
func trim(_ lhs: Character, _ rhs: Character) -> (String) -> String {
return { input in
if input.hasPrefix("\(lhs)") && input.hasSuffix("\(rhs)") {
- return input[input.characters.index(after: input.startIndex).. Resource<[Collection]> {
var queryItems: [URLQueryItem] = []
queryItems.append(URLQueryItem(name: "page", value: "\(page)"))
@@ -90,7 +90,7 @@ public extension Collection {
/// - page: page to be fetched.
/// - perPage: number of items to be fetched.
/// - Returns: resource for fetching the featured collections.
- public static func featured(page: Int = 1,
+ static func featured(page: Int = 1,
perPage: Int = 10) -> Resource<[Collection]> {
var queryItems: [URLQueryItem] = []
queryItems.append(URLQueryItem(name: "page", value: "\(page)"))
@@ -111,7 +111,7 @@ public extension Collection {
/// - page: page to be fetched.
/// - perPage: number of items to be fetched.
/// - Returns: resource for fetching curated collections.
- public static func curated(page: Int = 1,
+ static func curated(page: Int = 1,
perPage: Int = 10) -> Resource<[Collection]> {
var queryItems: [URLQueryItem] = []
queryItems.append(URLQueryItem(name: "page", value: "\(page)"))
@@ -130,7 +130,7 @@ public extension Collection {
///
/// - Parameter id: collection identifier.
/// - Returns: resource for fetching the collection.
- public static func get(id: String) -> Resource {
+ static func get(id: String) -> Resource {
let queryItems: [URLQueryItem] = []
return Resource { (components: URLComponents) -> URLRequest in
var mutable: URLComponents = components
@@ -149,7 +149,7 @@ public extension Collection {
/// - page: page to be fetched.
/// - perPage: items per page.
/// - Returns: resource for fetching the photos.
- public static func photos(id: String,
+ static func photos(id: String,
page: Int = 1,
perPage: Int = 10) -> Resource<[Photo]> {
var queryItems: [URLQueryItem] = []
@@ -172,7 +172,7 @@ public extension Collection {
/// - page: page to be fetched.
/// - perPage: number of items per page.
/// - Returns: resource for fetching the photos.
- public static func curatedPhotos(id: String,
+ static func curatedPhotos(id: String,
page: Int = 1,
perPage: Int = 10) -> Resource<[Photo]> {
var queryItems: [URLQueryItem] = []
@@ -192,7 +192,7 @@ public extension Collection {
///
/// - Parameter id: collection identifier whose related ones will be fetched.
/// - Returns: resource for fetching the related collections.
- public static func related(id: String) -> Resource<[Collection]> {
+ static func related(id: String) -> Resource<[Collection]> {
let queryItems: [URLQueryItem] = []
return Resource { (components: URLComponents) -> URLRequest in
var mutable: URLComponents = components
@@ -211,7 +211,7 @@ public extension Collection {
/// - description: collection title.
/// - isPrivate: collection private value.
/// - Returns: resource for creating the collection.
- public static func create(title: String,
+ static func create(title: String,
description: String? = nil,
isPrivate: Bool? = nil) -> Resource {
var queryItems: [URLQueryItem] = []
@@ -240,7 +240,7 @@ public extension Collection {
/// - description: new description.
/// - isPrivate: new private value.
/// - Returns: resource for updating theh collection.
- public static func update(id: String,
+ static func update(id: String,
title: String? = nil,
description: String? = nil,
isPrivate: Bool? = nil) -> Resource {
@@ -268,7 +268,7 @@ public extension Collection {
///
/// - Parameter id: collection identifier.
/// - Returns: resource for deleting the collection.
- public static func delete(id: String) -> Resource {
+ static func delete(id: String) -> Resource {
let queryItems: [URLQueryItem] = []
return Resource(request: { (components) -> URLRequest in
var mutable: URLComponents = components
@@ -288,7 +288,7 @@ public extension Collection {
/// - id: photo identifier.
/// - collection: collection identifier.
/// - Returns: resource for adding the photo.
- public static func addPhoto(with id: String,
+ static func addPhoto(with id: String,
to collection: String) -> Resource {
var queryItems: [URLQueryItem] = []
queryItems.append(URLQueryItem(name: "photo_id", value: "\(id)"))
@@ -310,7 +310,7 @@ public extension Collection {
/// - id: photo identifier.
/// - collection: collection identifier.
/// - Returns: resource for deleting the photo.
- public static func deletePhoto(with id: String,
+ static func deletePhoto(with id: String,
from collection: String) -> Resource {
var queryItems: [URLQueryItem] = []
queryItems.append(URLQueryItem(name: "photo_id", value: "\(id)"))
diff --git a/UnsplashKit/Classes/UnsplashAPI/Models/Photo.swift b/UnsplashKit/Classes/UnsplashAPI/Models/Photo.swift
index 7d05bc9..9315e08 100644
--- a/UnsplashKit/Classes/UnsplashAPI/Models/Photo.swift
+++ b/UnsplashKit/Classes/UnsplashAPI/Models/Photo.swift
@@ -41,6 +41,12 @@ public struct Photo: Unboxable {
/// Photo current user collections.
public let currentUserCollections: [Collection]?
+ /// Photo description
+ public let description: String?
+
+ /// Photo alternative description
+ public let altDescription: String?
+
// MARK: - Unboxable
/// Initialize an instance of this model by unboxing a dictionary using an Unboxer
@@ -51,11 +57,13 @@ public struct Photo: Unboxable {
self.height = try unboxer.unbox(key: "height")
self.color = try unboxer.unbox(key: "color")
self.likes = try unboxer.unbox(key: "likes")
- self.urls = unboxer.unbox(key: "urls")
- self.links = unboxer.unbox(key: "links")
- self.categories = unboxer.unbox(key: "categories")
- self.user = unboxer.unbox(key: "user")
- self.currentUserCollections = unboxer.unbox(key: "current_user_collections")
+ self.urls = try? unboxer.unbox(key: "urls")
+ self.links = try? unboxer.unbox(key: "links")
+ self.categories = try? unboxer.unbox(key: "categories")
+ self.user = try? unboxer.unbox(key: "user")
+ self.currentUserCollections = try? unboxer.unbox(key: "current_user_collections")
+ self.description = try? unboxer.unbox(key: "description")
+ self.altDescription = try? unboxer.unbox(key: "alt_description")
}
}
@@ -72,7 +80,7 @@ public extension Photo {
/// - perPage: number of items per page.
/// - orderBy: order by value.
/// - Returns: resource for fetching photos.
- public static func list(page: Int = 1,
+ static func list(page: Int = 1,
perPage: Int = 10,
orderBy: Order = .latest) -> Resource<[Photo]> {
var queryItems: [URLQueryItem] = []
@@ -96,7 +104,7 @@ public extension Photo {
/// - perPage: number of items per page.
/// - orderBy: order by value.
/// - Returns: resource for fetching the curated photos.
- public static func curated(page: Int = 1,
+ static func curated(page: Int = 1,
perPage: Int = 10,
orderBy: Order = .latest) -> Resource<[Photo]> {
var queryItems: [URLQueryItem] = []
@@ -120,7 +128,7 @@ public extension Photo {
/// - size: photo size.
/// - rect: photo rect.
/// - Returns: resource for fetching a photo.
- public static func get(id: String,
+ static func get(id: String,
size: CGSize? = nil,
rect: CGRect? = nil) -> Resource {
var queryItems: [URLQueryItem] = []
@@ -152,7 +160,7 @@ public extension Photo {
/// - size: size of the photos.
/// - orientation: orientation filtering.
/// - Returns: resource for fetching the photos.
- public static func random(categories: [String] = [],
+ static func random(categories: [String] = [],
collections: [String] = [],
featured: Bool? = nil,
username: String? = nil,
@@ -195,7 +203,7 @@ public extension Photo {
/// - size: size of the photos.
/// - orientation: orientation used for filtering.
/// - Returns: resource for fetching the photos.
- public static func random(count: Int,
+ static func random(count: Int,
categories: [String] = [],
collections: [String] = [],
featured: Bool? = nil,
@@ -233,7 +241,7 @@ public extension Photo {
///
/// - Parameter id: photo identifier.
/// - Returns: resource for fetching the stats.
- public static func stats(id: String) -> Resource {
+ static func stats(id: String) -> Resource {
return Resource { (components: URLComponents) -> URLRequest in
var mutable: URLComponents = components
mutable.path = "/photos/\(id)/stats"
@@ -247,7 +255,7 @@ public extension Photo {
///
/// - Parameter id: photo identifier.
/// - Returns: resource for fetching the photo download link.
- public static func downloadLink(id: String) -> Resource {
+ static func downloadLink(id: String) -> Resource {
return Resource(request: { (components) -> URLRequest in
var mutable: URLComponents = components
mutable.path = "/photos/\(id)/download"
@@ -275,7 +283,7 @@ public extension Photo {
/// - exifFocalLength: photo new exif focal length.
/// - exifIsoSpeedRatings: photo new exif iso speed ratings.
/// - Returns: resource for updating the photo.
- public static func update(id: String,
+ static func update(id: String,
locationPosition: CLLocation? = nil,
locationName: String? = nil,
locationCity: String? = nil,
@@ -336,7 +344,7 @@ public extension Photo {
///
/// - Parameter id: photo to be liked.
/// - Returns: resource for liking the photo.
- public static func like(id: String) -> Resource {
+ static func like(id: String) -> Resource {
return Resource(request: { (components) -> URLRequest in
var mutable: URLComponents = components
mutable.path = "/photos/\(id)/like"
@@ -352,7 +360,7 @@ public extension Photo {
///
/// - Parameter id: photo to be unliked.
/// - Returns: resource for unliking the photo.
- public static func unlike(id: String) -> Resource {
+ static func unlike(id: String) -> Resource {
return Resource(request: { (components) -> URLRequest in
var mutable: URLComponents = components
mutable.path = "/photos/\(id)/like"
diff --git a/UnsplashKit/Classes/UnsplashAPI/Models/PhotoCategory.swift b/UnsplashKit/Classes/UnsplashAPI/Models/PhotoCategory.swift
index 3418f31..9a2b85c 100644
--- a/UnsplashKit/Classes/UnsplashAPI/Models/PhotoCategory.swift
+++ b/UnsplashKit/Classes/UnsplashAPI/Models/PhotoCategory.swift
@@ -21,7 +21,7 @@ public struct PhotoCategory: Unboxable {
public init(unboxer: Unboxer) throws {
self.id = try unboxer.unbox(key: "id")
self.title = try unboxer.unbox(key: "title")
- self.links = unboxer.unbox(key: "links")
+ self.links = try? unboxer.unbox(key: "links")
}
}
diff --git a/UnsplashKit/Classes/UnsplashAPI/Models/PhotoExif.swift b/UnsplashKit/Classes/UnsplashAPI/Models/PhotoExif.swift
index 3ba993d..7435899 100644
--- a/UnsplashKit/Classes/UnsplashAPI/Models/PhotoExif.swift
+++ b/UnsplashKit/Classes/UnsplashAPI/Models/PhotoExif.swift
@@ -28,11 +28,11 @@ public struct PhotoExif: Unboxable {
/// Initialize an instance of this model by unboxing a dictionary using an Unboxer
public init(unboxer: Unboxer) throws {
- self.make = unboxer.unbox(key: "make")
- self.model = unboxer.unbox(key: "model")
- self.exposureTime = unboxer.unbox(key: "exposure_time")
- self.aperture = unboxer.unbox(key: "aperture")
- self.focalLength = unboxer.unbox(key: "focal_length")
- self.iso = unboxer.unbox(key: "iso")
+ self.make = try? unboxer.unbox(key: "make")
+ self.model = try? unboxer.unbox(key: "model")
+ self.exposureTime = try? unboxer.unbox(key: "exposure_time")
+ self.aperture = try? unboxer.unbox(key: "aperture")
+ self.focalLength = try? unboxer.unbox(key: "focal_length")
+ self.iso = try? unboxer.unbox(key: "iso")
}
}
diff --git a/UnsplashKit/Classes/UnsplashAPI/Models/PhotoLocation.swift b/UnsplashKit/Classes/UnsplashAPI/Models/PhotoLocation.swift
index 51c19e3..9adcc8c 100644
--- a/UnsplashKit/Classes/UnsplashAPI/Models/PhotoLocation.swift
+++ b/UnsplashKit/Classes/UnsplashAPI/Models/PhotoLocation.swift
@@ -23,11 +23,11 @@ public struct PhotoLocation: Unboxable {
/// Initialize an instance of this model by unboxing a dictionary using an Unboxer
public init(unboxer: Unboxer) throws {
- self.name = unboxer.unbox(key: "name")
- self.city = unboxer.unbox(key: "city")
- self.country = unboxer.unbox(key: "country")
- if let latitude: Double = unboxer.unbox(key: "position.latitude"),
- let longitude: Double = unboxer.unbox(key: "position.longitude") {
+ self.name = try? unboxer.unbox(key: "name")
+ self.city = try? unboxer.unbox(key: "city")
+ self.country = try? unboxer.unbox(key: "country")
+ if let latitude: Double = try? unboxer.unbox(key: "position.latitude"),
+ let longitude: Double = try? unboxer.unbox(key: "position.longitude") {
self.location = CLLocation(latitude: latitude, longitude: longitude)
} else {
self.location = nil
diff --git a/UnsplashKit/Classes/UnsplashAPI/Models/Search.swift b/UnsplashKit/Classes/UnsplashAPI/Models/Search.swift
index 3f06590..7169174 100644
--- a/UnsplashKit/Classes/UnsplashAPI/Models/Search.swift
+++ b/UnsplashKit/Classes/UnsplashAPI/Models/Search.swift
@@ -1,6 +1,10 @@
import Foundation
import Unbox
+public enum SearchOrder: String {
+ case latest, relevant
+}
+
/// Resources
public struct Search {
@@ -13,11 +17,13 @@ public struct Search {
/// - Returns: resource for searching photos.
public static func photos(query: String,
page: Int = 1,
- perPage: Int = 10) -> Resource<[Photo]> {
+ perPage: Int = 10,
+ orderBy: SearchOrder = .relevant ) -> Resource<[Photo]> {
var queryItems: [URLQueryItem] = []
queryItems.append(URLQueryItem(name: "query", value: query))
queryItems.append(URLQueryItem(name: "page", value: "\(page)"))
queryItems.append(URLQueryItem(name: "per_page", value: "\(perPage)"))
+ queryItems.append(URLQueryItem(name: "order_by", value: orderBy.rawValue))
return Resource(request: { (components) -> URLRequest in
var mutable: URLComponents = components
mutable.path = "/search/photos"
diff --git a/UnsplashKit/Classes/UnsplashAPI/Models/User.swift b/UnsplashKit/Classes/UnsplashAPI/Models/User.swift
index 90614cd..2bd5ab7 100644
--- a/UnsplashKit/Classes/UnsplashAPI/Models/User.swift
+++ b/UnsplashKit/Classes/UnsplashAPI/Models/User.swift
@@ -63,22 +63,22 @@ public struct User: Unboxable {
/// Initialize an instance of this model by unboxing a dictionary using an Unboxer
public init(unboxer: Unboxer) throws {
self.id = try unboxer.unbox(key: "id")
- self.name = unboxer.unbox(key: "name")
+ self.name = try? unboxer.unbox(key: "name")
self.username = try unboxer.unbox(key: "username")
self.firstName = try unboxer.unbox(key: "first_name")
- self.lastName = unboxer.unbox(key: "last_name")
- self.portfolioUrl = unboxer.unbox(key: "portfolio_url")
- self.bio = unboxer.unbox(key: "bio")
- self.location = unboxer.unbox(key: "location")
+ self.lastName = try? unboxer.unbox(key: "last_name")
+ self.portfolioUrl = try? unboxer.unbox(key: "portfolio_url")
+ self.bio = try? unboxer.unbox(key: "bio")
+ self.location = try? unboxer.unbox(key: "location")
self.totalLikes = try unboxer.unbox(key: "total_likes")
self.totalPhotos = try unboxer.unbox(key: "total_photos")
self.totalCollections = try unboxer.unbox(key: "total_collections")
- self.followedByUser = unboxer.unbox(key: "followed_by_user")
- self.downloads = unboxer.unbox(key: "downloads")
- self.uploadsRemaining = unboxer.unbox(key: "uploads_remaining")
- self.instagramUsername = unboxer.unbox(key: "instagram_username")
- self.email = unboxer.unbox(key: "email")
- self.links = unboxer.unbox(key: "links")
+ self.followedByUser = try? unboxer.unbox(key: "followed_by_user")
+ self.downloads = try? unboxer.unbox(key: "downloads")
+ self.uploadsRemaining = try? unboxer.unbox(key: "uploads_remaining")
+ self.instagramUsername = try? unboxer.unbox(key: "instagram_username")
+ self.email = try? unboxer.unbox(key: "email")
+ self.links = try? unboxer.unbox(key: "links")
}
}
@@ -88,7 +88,7 @@ public struct User: Unboxable {
public extension User {
/// Returns the resource to fetch the authenticated user.
- public static var me: Resource = Resource { (components: URLComponents) -> URLRequest in
+ static var me: Resource = Resource { (components: URLComponents) -> URLRequest in
var mutable: URLComponents = components
mutable.path = "/me"
return URLRequest(url: mutable.url!)
@@ -106,7 +106,7 @@ public extension User {
/// - bio: user new biography.
/// - instagramUsername: user new instagram username.
/// - Returns: resource for updating the user.
- public static func updateMe(username: String? = nil,
+ static func updateMe(username: String? = nil,
firstName: String? = nil,
lastName: String? = nil,
email: String? = nil,
@@ -139,7 +139,7 @@ public extension User {
/// - username: user username.
/// - size: profile photo size.
/// - Returns: resource for fetching an user.
- public static func get(username: String,
+ static func get(username: String,
size: CGSize? = nil) -> Resource {
var queryItems: [URLQueryItem] = []
if let size = size {
@@ -160,7 +160,7 @@ public extension User {
///
/// - Parameter username: user username.
/// - Returns: resource for fetching the portfolio url.
- public static func portfolio(username: String) -> Resource {
+ static func portfolio(username: String) -> Resource {
return Resource(request: { (components) -> URLRequest in
var mutable: URLComponents = components
mutable.path = "/users/\(username)/portfolio"
@@ -180,7 +180,7 @@ public extension User {
/// - perPage: number of items per page.
/// - orderBy: order by value.
/// - Returns: resource for fetching the user's photos.
- public static func photos(username: String,
+ static func photos(username: String,
page: Int = 1,
perPage: Int = 10,
orderBy: Order = .latest) -> Resource<[Photo]> {
@@ -206,7 +206,7 @@ public extension User {
/// - perPage: number of items per page.
/// - orderBy: order by value.
/// - Returns: resource for fetching the liked photos.
- public static func likes(username: String,
+ static func likes(username: String,
page: Int = 1,
perPage: Int = 10,
orderBy: Order = .latest) -> Resource<[Photo]> {
@@ -232,7 +232,7 @@ public extension User {
/// - perPage: number of items per page.
/// - orderBy: order by value.
/// - Returns: resource for fetching the collections.
- public static func collections(username: String,
+ static func collections(username: String,
page: Int = 1,
perPage: Int = 10,
orderBy: Order = .latest) -> Resource<[Collection]> {
diff --git a/UnsplashKit/Classes/UnsplashAPI/Models/UserLinks.swift b/UnsplashKit/Classes/UnsplashAPI/Models/UserLinks.swift
index aafb6a9..e431695 100644
--- a/UnsplashKit/Classes/UnsplashAPI/Models/UserLinks.swift
+++ b/UnsplashKit/Classes/UnsplashAPI/Models/UserLinks.swift
@@ -36,8 +36,8 @@ public struct UserLinks: Unboxable {
self.photos = try unboxer.unbox(key: "photos")
self.likes = try unboxer.unbox(key: "likes")
self.portfolio = try unboxer.unbox(key: "portfolio")
- self.followers = unboxer.unbox(key: "followers")
- self.following = unboxer.unbox(key: "following")
+ self.followers = try? unboxer.unbox(key: "followers")
+ self.following = try? unboxer.unbox(key: "following")
}
}