Skip to content

Commit

Permalink
#51 [refactor] Replaced Promises in Discogs & DiscogsClient with Swif…
Browse files Browse the repository at this point in the history
…t 5.5 async/await.
  • Loading branch information
jrtibbetts committed Jul 31, 2022
1 parent a74bf38 commit 2b116c1
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 171 deletions.
45 changes: 21 additions & 24 deletions Source/Discogs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ public protocol Discogs {

var isSignedIn: Bool { get }

func authorize(presentingViewController: UIViewController,
callbackUrlString: String) async -> OAuthSwiftCredential

func signOut()

func userIdentity() async -> UserIdentity
func userIdentity() async throws -> UserIdentity

func userProfile(userName: String) async -> UserProfile
func userProfile(userName: String) async throws -> UserProfile

// MARK: - Database

Expand All @@ -46,76 +43,76 @@ public protocol Discogs {
/// - parameter identifier: The numeric ID of the artist.
/// - parameter completion: The completion block that will be applied to
/// the artist, if found, or the error, if one was thrown.
func artist(identifier: Int) async -> Artist
func artist(identifier: Int) async throws -> Artist

/// Look up the releases by the specified artist's ID.
///
/// - parameter artistId: The numeric ID of the artist.
/// - parameter completion: The completion block that will be applied to
/// all of the artist's releases, or to the error, if one was thrown.
func releases(forArtist artistId: Int) async -> ReleaseSummaries
func releases(forArtist artistId: Int) async throws -> ReleaseSummaries

/// Look up the record label by its ID.
///
/// - parameter identifier: The label's unique ID.
/// - parameter completion: The completion block that will be applied to
/// the label, or to the error, if one was thrown.
func label(identifier: Int) async -> RecordLabel
func label(identifier: Int) async throws -> RecordLabel

/// Look up the record label's releases by the label's name.
///
/// - parameter labelId: The label's unique ID.
/// - parameter completion: The completion block that will be applied to
/// all of the label's releases, or to the error, if one was thrown.
func releases(forLabel labelId: Int) async -> ReleaseSummaries
func releases(forLabel labelId: Int) async throws -> ReleaseSummaries

/// Process a master release with a specified ID.
///
/// - parameter identifier: The unique ID of the master release.
/// - parameter completion: The completion block that will be applied to
/// the master release, or to the error, if one was thrown.
func masterRelease(identifier: Int) async -> MasterRelease
func masterRelease(identifier: Int) async throws -> MasterRelease

/// Process all of the release versions that belong to a master release.
///
/// - parameter identifier: The unique ID of the master release.
/// - parameter pageNumber: The number of the page (i.e. batch).
func releasesForMasterRelease(_ identifier: Int,
pageNumber: Int,
resultsPerPage: Int) async -> MasterReleaseVersions
resultsPerPage: Int) async throws -> MasterReleaseVersions

/// Process a release with a specified ID.
///
/// - parameter identifier: The unique ID of the release.
/// - parameter completion: The completion block that will be applied to
/// the release, or to the error, if one was thrown.
func release(identifier: Int) async -> Release
func release(identifier: Int) async throws -> Release

// MARK: - Collections

func customCollectionFields(forUserName: String) async -> CollectionCustomFields
func collectionValue(forUserName: String) async -> CollectionValue
func collectionFolders(forUserName: String) async -> CollectionFolders
func customCollectionFields(forUserName: String) async throws -> CollectionCustomFields
func collectionValue(forUserName: String) async throws -> CollectionValue
func collectionFolders(forUserName: String) async throws -> CollectionFolders
func collectionFolderInfo(forFolderID: Int,
userName: String) async -> CollectionFolder
userName: String) async throws -> CollectionFolder
func createFolder(named: String,
forUserName: String) async -> CollectionFolder
forUserName: String) async throws -> CollectionFolder
func edit(_ folder: CollectionFolder,
forUserName: String) async -> CollectionFolder
forUserName: String) async throws -> CollectionFolder
func collectionItems(inFolderID: Int,
userName: String,
pageNumber: Int,
resultsPerPage: Int) async -> CollectionFolderItems
resultsPerPage: Int) async throws -> CollectionFolderItems
func addItem(_ itemId: Int,
toFolderID: Int,
userName: String) async -> CollectionItemInfo
userName: String) async throws -> CollectionItemInfo

// MARK: - Search

func search(for queryString: String,
type: String) async -> SearchResults
type: String) async throws -> SearchResults

func search(forArtist artistName: String) async -> SearchResults
func search(forArtist artistName: String) async throws -> SearchResults
}

public enum DiscogsSearchType: String {
Expand All @@ -126,8 +123,8 @@ public enum DiscogsSearchType: String {

public extension Discogs {

func search(forArtist artistName: String) async -> SearchResults {
return await search(for: artistName, type: DiscogsSearchType.artist.rawValue)
func search(forArtist artistName: String) async throws -> SearchResults {
return try await search(for: artistName, type: DiscogsSearchType.artist.rawValue)
}

}
104 changes: 53 additions & 51 deletions Source/DiscogsClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,125 +40,127 @@ open class DiscogsClient: OAuth1JSONClient, Discogs {

// MARK: - JSONClient

open override func get<T>(path: String,
headers: JSONClient.Headers = Headers(),
parameters: JSONClient.Parameters = Parameters())
async -> T where T: Decodable, T: Encodable {
open override func get<T: Codable>(path: String,
headers: JSONClient.Headers = Headers(),
parameters: JSONClient.Parameters = Parameters()) async throws -> T {
print("GET for \(path); headers: \(headers); params: \(parameters)")
debugPrint(path, headers, parameters)
return super.get(path: path, headers: headers, parameters: parameters)

return try await super.get(path: path, headers: headers, parameters: parameters)
}

// MARK: - AuthorizedJSONClient

open override func authorizedGet<T>(path: String,
headers: AuthorizedJSONClient.Headers = Headers(),
parameters: AuthorizedJSONClient.Parameters = Parameters())
async -> T where T: Decodable, T: Encodable {
open override func authorizedGet<T: Codable>(path: String,
headers: AuthorizedJSONClient.Headers = Headers(),
parameters: AuthorizedJSONClient.Parameters = Parameters()) async throws -> T {
print("Authorized GET for \(path); headers: \(headers); params: \(parameters)")
debugPrint(path, headers, parameters)
return super.authorizedGet(path: path, headers: headers, parameters: parameters)

return try await super.authorizedGet(path: path, headers: headers, parameters: parameters)
}

// MARK: - Authorization & User Identity

public func userIdentity() async -> UserIdentity {
return await authorizedGet(path: "/oauth/identity", headers: headers)
public func userIdentity() async throws -> UserIdentity {
return try await authorizedGet(path: "/oauth/identity", headers: headers)
}

public func userProfile(userName: String) async -> UserProfile {
return await authorizedGet(path: "/users/\(userName)", headers: headers)
public func userProfile(userName: String) async throws -> UserProfile {
return try await authorizedGet(path: "/users/\(userName)", headers: headers)
}

// MARK: - Database

public func artist(identifier: Int) async -> Artist {
return await get(path: "/artists/\(identifier)", headers: headers)
public func artist(identifier: Int) async throws -> Artist {
return try await get(path: "/artists/\(identifier)", headers: headers)
}

public func label(identifier: Int) async -> RecordLabel {
return await get(path: "/labels/\(identifier)", headers: headers)
public func label(identifier: Int) async throws -> RecordLabel {
return try await get(path: "/labels/\(identifier)", headers: headers)
}

public func masterRelease(identifier: Int) async -> MasterRelease {
return await get(path: "/masters/\(identifier)", headers: headers)
public func masterRelease(identifier: Int) async throws -> MasterRelease {
return try await get(path: "/masters/\(identifier)", headers: headers)
}

public func release(identifier: Int) async -> Release {
return await get(path: "/releases/\(identifier)", headers: headers)
public func release(identifier: Int) async throws -> Release {
return try await get(path: "/releases/\(identifier)", headers: headers)
}

public func releases(forArtist artistId: Int) async -> ReleaseSummaries {
return await get(path: "/artists/\(artistId)/releases", headers: headers)
public func releases(forArtist artistId: Int) async throws -> ReleaseSummaries {
return try await get(path: "/artists/\(artistId)/releases", headers: headers)
}

public func releases(forLabel labelId: Int) async -> ReleaseSummaries {
return await get(path: "/labels/\(labelId)/releases", headers: headers)
public func releases(forLabel labelId: Int) async throws -> ReleaseSummaries {
return try await get(path: "/labels/\(labelId)/releases", headers: headers)
}

public func releasesForMasterRelease(_ identifier: Int,
pageNumber: Int = 1,
resultsPerPage: Int = 50) async -> MasterReleaseVersions {
resultsPerPage: Int = 50) async throws -> MasterReleaseVersions {
// turn the pageNumber and resultsPerPage into query parameters
return await get(path: "/masters/\(identifier)/versions",
headers: headers,
parameters: ["per_page": "\(resultsPerPage)", "page": "\(pageNumber)"])
return try await get(path: "/masters/\(identifier)/versions",
headers: headers,
parameters: ["per_page": "\(resultsPerPage)", "page": "\(pageNumber)"])
}

// MARK: - Collections

public func customCollectionFields(forUserName userName: String) async -> CollectionCustomFields {
return await authorizedGet(path: "/users/\(userName)/collection/fields", headers: headers)
public func customCollectionFields(forUserName userName: String) async throws -> CollectionCustomFields {
return try await authorizedGet(path: "/users/\(userName)/collection/fields", headers: headers)
}

public func collectionValue(forUserName userName: String) async -> CollectionValue {
return await authorizedGet(path: "/users/\(userName)/collection/value", headers: headers)
public func collectionValue(forUserName userName: String) async throws -> CollectionValue {
return try await authorizedGet(path: "/users/\(userName)/collection/value", headers: headers)
}

public func collectionFolders(forUserName userName: String) async -> CollectionFolders {
return await authorizedGet(path: "/users/\(userName)/collection/folders", headers: headers)
public func collectionFolders(forUserName userName: String) async throws -> CollectionFolders {
return try await authorizedGet(path: "/users/\(userName)/collection/folders", headers: headers)
}

public func collectionFolderInfo(forFolderID folderID: Int,
userName: String) async -> CollectionFolder {
return await authorizedGet(path: "/users/\(userName)/collection/folders/\(folderID)", headers: headers)
userName: String) async throws -> CollectionFolder {
return try await authorizedGet(path: "/users/\(userName)/collection/folders/\(folderID)", headers: headers)
}

public func createFolder(named folderName: String,
forUserName userName: String) async -> CollectionFolder {
return authorizedPost(path: "/users/\(userName)/collection/folders/\(folderName)", headers: headers)
forUserName userName: String) async throws -> CollectionFolder {
return try await authorizedPost(path: "/users/\(userName)/collection/folders/\(folderName)", headers: headers)
}

public func edit(_ folder: CollectionFolder,
forUserName userName: String) async -> CollectionFolder {
return Promise<CollectionFolder> { _ in
}
forUserName userName: String) async throws -> CollectionFolder {
throw DiscogsError.unknown(nil)
}

public func collectionItems(inFolderID folderID: Int,
userName: String,
pageNumber: Int = 1,
resultsPerPage: Int = 50) async -> CollectionFolderItems {
return await authorizedGet(path: "/users/\(userName)/collection/folders/\(folderID)/releases",
resultsPerPage: Int = 50) async throws -> CollectionFolderItems {
return try await authorizedGet(
path: "/users/\(userName)/collection/folders/\(folderID)/releases",
headers: headers,
parameters: ["per_page": "\(resultsPerPage)", "page": "\(pageNumber)"])
parameters: ["per_page": "\(resultsPerPage)", "page": "\(pageNumber)"]
)
}

public func addItem(_ itemID: Int,
toFolderID folderID: Int,
userName: String) async -> CollectionItemInfo {
return authorizedPost(
userName: String) async throws -> CollectionItemInfo {
return try await authorizedPost(
path: "/users/\(userName)/collection/folders/\(folderID)/releases/{itemId}",
headers: headers)
headers: headers
)
}

// MARK: - Search

public func search(for queryString: String,
type: String) async -> SearchResults {
type: String) async throws -> SearchResults {
let params = ["q": queryString]

return await authorizedGet(path: "/database/search", headers: headers, parameters: params)
return try await authorizedGet(path: "/database/search", headers: headers, parameters: params)
}

}
4 changes: 2 additions & 2 deletions SwiftDiscogs.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2413,8 +2413,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/jrtibbetts/JSONClient";
requirement = {
branch = main;
kind = branch;
kind = upToNextMinorVersion;
minimumVersion = 3.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down
Loading

0 comments on commit 2b116c1

Please sign in to comment.