From 09cd37372d8ce9ab7f4492e676f07b2f60d12550 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Tue, 26 Mar 2024 09:49:49 +1100 Subject: [PATCH 1/4] Update `WordPressComRESTAPIInterfacing` to generate `Any` in Swift --- .../WordPressComRESTAPIInterfacing.h | 8 +++++-- .../WordPressAPI/WordPressComRestApi.swift | 22 +++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Sources/WordPressKit/WordPressAPI/WordPressComRESTAPIInterfacing.h b/Sources/WordPressKit/WordPressAPI/WordPressComRESTAPIInterfacing.h index e1a669e8..1f652fd6 100644 --- a/Sources/WordPressKit/WordPressAPI/WordPressComRESTAPIInterfacing.h +++ b/Sources/WordPressKit/WordPressAPI/WordPressComRESTAPIInterfacing.h @@ -6,13 +6,17 @@ @property (strong, nonatomic, readonly) NSURL * _Nonnull baseURL; +/// - Note: `parameters` has `id` instead of the more common `NSObject *` as its value type so it will convert to `AnyObject` in Swift. +/// In Swift, it's simpler to work with `AnyObject` than with `NSObject`. For example `"abc" as AnyObject` over `"abc" as NSObject`. - (NSProgress * _Nullable)get:(NSString * _Nonnull)URLString - parameters:(NSDictionary * _Nullable)parameters + parameters:(NSDictionary * _Nullable)parameters success:(void (^ _Nonnull)(id _Nonnull, NSHTTPURLResponse * _Nullable))success failure:(void (^ _Nonnull)(NSError * _Nonnull, NSHTTPURLResponse * _Nullable))failure; +/// - Note: `parameters` has `id` instead of the more common `NSObject *` as its value type so it will convert to `AnyObject` in Swift. +/// In Swift, it's simpler to work with `AnyObject` than with `NSObject`. For example `"abc" as AnyObject` over `"abc" as NSObject`. - (NSProgress * _Nullable)post:(NSString * _Nonnull)URLString - parameters:(NSDictionary * _Nullable)parameters + parameters:(NSDictionary * _Nullable)parameters success:(void (^ _Nonnull)(id _Nonnull, NSHTTPURLResponse * _Nullable))success failure:(void (^ _Nonnull)(NSError * _Nonnull, NSHTTPURLResponse * _Nullable))failure; diff --git a/Sources/WordPressKit/WordPressAPI/WordPressComRestApi.swift b/Sources/WordPressKit/WordPressAPI/WordPressComRestApi.swift index 3764903c..a0b9d605 100644 --- a/Sources/WordPressKit/WordPressAPI/WordPressComRestApi.swift +++ b/Sources/WordPressKit/WordPressAPI/WordPressComRestApi.swift @@ -615,20 +615,34 @@ extension WordPressComRestApi: WordPressComRESTAPIInterfacing { // The same applies for the other methods below. public func get( _ URLString: String, - parameters: [String: NSObject]?, + parameters: [String: Any]?, success: @escaping (Any, HTTPURLResponse?) -> Void, failure: @escaping (any Error, HTTPURLResponse?) -> Void ) -> Progress? { - GET(URLString, parameters: parameters, success: success, failure: failure) + GET( + URLString, + // It's possible `WordPressComRestApi` could be updated to use `[String: Any]` instead. + // But leaving that investigation for later. + parameters: parameters as? [String: AnyObject], + success: success, + failure: failure + ) } public func post( _ URLString: String, - parameters: [String: NSObject]?, + parameters: [String: Any]?, success: @escaping (Any, HTTPURLResponse?) -> Void, failure: @escaping (any Error, HTTPURLResponse?) -> Void ) -> Progress? { - POST(URLString, parameters: parameters, success: success, failure: failure) + POST( + URLString, + // It's possible `WordPressComRestApi` could be updated to use `[String: Any]` instead. + // But leaving that investigation for later. + parameters: parameters as? [String: AnyObject], + success: success, + failure: failure + ) } public func multipartPOST( From cbc56619c04858100de856d0e056dc4c4a802146 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Tue, 26 Mar 2024 09:50:22 +1100 Subject: [PATCH 2/4] Use `WordPressComRESTAPIInterfacing` in `DomainsServiceRemote` --- .../Services/Domains/DomainsServiceRemote.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/WordPressKit/Services/Domains/DomainsServiceRemote.swift b/Sources/WordPressKit/Services/Domains/DomainsServiceRemote.swift index 78fdeb12..51b57386 100644 --- a/Sources/WordPressKit/Services/Domains/DomainsServiceRemote.swift +++ b/Sources/WordPressKit/Services/Domains/DomainsServiceRemote.swift @@ -112,7 +112,7 @@ public class DomainsServiceRemote: ServiceRemoteWordPressComREST { let endpoint = "sites/\(siteID)/domains" let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) - wordPressComRestApi.GET(path, parameters: nil, + wordPressComRESTAPI.get(path, parameters: nil, success: { response, _ in do { @@ -133,7 +133,7 @@ public class DomainsServiceRemote: ServiceRemoteWordPressComREST { let parameters: [String: AnyObject] = ["domain": domain as AnyObject] - wordPressComRestApi.POST(path, parameters: parameters, + wordPressComRESTAPI.post(path, parameters: parameters, success: { _, _ in success() @@ -149,7 +149,7 @@ public class DomainsServiceRemote: ServiceRemoteWordPressComREST { let endPoint = "domains/supported-states/\(countryCode)" let servicePath = path(forEndpoint: endPoint, withVersion: ._1_1) - wordPressComRestApi.GET( + wordPressComRESTAPI.get( servicePath, parameters: nil, success: { @@ -175,7 +175,7 @@ public class DomainsServiceRemote: ServiceRemoteWordPressComREST { let endPoint = "me/domain-contact-information" let servicePath = path(forEndpoint: endPoint, withVersion: ._1_1) - wordPressComRestApi.GET( + wordPressComRESTAPI.get( servicePath, parameters: nil, success: { (response, _) in @@ -201,7 +201,7 @@ public class DomainsServiceRemote: ServiceRemoteWordPressComREST { let parameters: [String: AnyObject] = ["contact_information": contactInformation as AnyObject, "domain_names": domainNames as AnyObject] - wordPressComRestApi.POST( + wordPressComRESTAPI.post( servicePath, parameters: parameters, success: { response, _ in @@ -239,7 +239,7 @@ public class DomainsServiceRemote: ServiceRemoteWordPressComREST { parameters["quantity"] = quantity as AnyObject } - wordPressComRestApi.GET(servicePath, + wordPressComRESTAPI.get(servicePath, parameters: parameters, success: { response, _ in @@ -257,7 +257,7 @@ public class DomainsServiceRemote: ServiceRemoteWordPressComREST { } } -private func map(suggestions response: AnyObject) throws -> [DomainSuggestion] { +private func map(suggestions response: Any) throws -> [DomainSuggestion] { guard let jsonSuggestions = response as? [[String: AnyObject]] else { throw DomainsServiceRemote.ResponseError.decodingFailed } @@ -272,7 +272,7 @@ private func map(suggestions response: AnyObject) throws -> [DomainSuggestion] { return suggestions } -private func mapDomainsResponse(_ response: AnyObject) throws -> [RemoteDomain] { +private func mapDomainsResponse(_ response: Any) throws -> [RemoteDomain] { guard let json = response as? [String: AnyObject], let domainsJson = json["domains"] as? [[String: AnyObject]] else { throw DomainsServiceRemote.ResponseError.decodingFailed From 42b00d8a2299a85095fc1562501f38459b8d9966 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Tue, 26 Mar 2024 09:53:45 +1100 Subject: [PATCH 3/4] Use `Error` in `connect|disconnect` methods in `AccountServiceRemoteREST` Instead of `NSError`. This way, we'll be able to pass the error to the `WordPressComRESTAPIInterfacing` version without needing to make any conversion. As far as I could see, the only consumer already worked in terms of `Error`. https://github.com/wordpress-mobile/WordPressAuthenticator-iOS/blob/30aada20beb9e0871f4da35a5634501536898b3b/WordPressAuthenticator/Services/WordPressComAccountService.swift#L31-L44 --- .../Services/AccountServiceRemoteREST+SocialService.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift b/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift index 559b0226..707cdfdc 100644 --- a/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift +++ b/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift @@ -23,7 +23,7 @@ extension AccountServiceRemoteREST { oAuthClientID: String, oAuthClientSecret: String, success: @escaping (() -> Void), - failure: @escaping ((NSError) -> Void)) { + failure: @escaping ((Error) -> Void)) { let path = self.path(forEndpoint: "me/social-login/connect", withVersion: ._1_1) var params = [ @@ -65,7 +65,7 @@ extension AccountServiceRemoteREST { /// - oAuthClientSecret The WPCOM REST API client secret. /// - success The block that will be executed on success. /// - failure The block that will be executed on failure. - public func disconnectFromSocialService(_ service: SocialServiceName, oAuthClientID: String, oAuthClientSecret: String, success: @escaping(() -> Void), failure: @escaping((NSError) -> Void)) { + public func disconnectFromSocialService(_ service: SocialServiceName, oAuthClientID: String, oAuthClientSecret: String, success: @escaping(() -> Void), failure: @escaping((Error) -> Void)) { let path = self.path(forEndpoint: "me/social-login/disconnect", withVersion: ._1_1) let params = [ "client_id": oAuthClientID, From 52a7ea45eb22adaa3105ec835ce488c4d2aa1709 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Tue, 26 Mar 2024 09:56:46 +1100 Subject: [PATCH 4/4] Use `WordPressComRESTAPIInterfacing` in `AccountServiceRemoteREST` --- .../AccountServiceRemoteREST+SocialService.swift | 4 ++-- .../Services/AccountSettingsRemote.swift | 16 ++++++++-------- .../ActivityServiceRemote_ApiVersion1_0.swift | 7 ++++--- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift b/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift index 707cdfdc..02432a1f 100644 --- a/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift +++ b/Sources/WordPressKit/Services/AccountServiceRemoteREST+SocialService.swift @@ -37,7 +37,7 @@ extension AccountServiceRemoteREST { params.merge(connectParameters, uniquingKeysWith: { (current, _) in current }) } - wordPressComRestApi.POST(path, parameters: params, success: { (_, _) in + wordPressComRESTAPI.post(path, parameters: params, success: { (_, _) in success() }, failure: { (error, _) in failure(error) @@ -73,7 +73,7 @@ extension AccountServiceRemoteREST { "service": service.rawValue ] as [String: AnyObject] - wordPressComRestApi.POST(path, parameters: params, success: { (_, _) in + wordPressComRESTAPI.post(path, parameters: params, success: { (_, _) in success() }, failure: { (error, _) in failure(error) diff --git a/Sources/WordPressKit/Services/AccountSettingsRemote.swift b/Sources/WordPressKit/Services/AccountSettingsRemote.swift index 384c479a..e029ab5d 100644 --- a/Sources/WordPressKit/Services/AccountSettingsRemote.swift +++ b/Sources/WordPressKit/Services/AccountSettingsRemote.swift @@ -32,7 +32,7 @@ public class AccountSettingsRemote: ServiceRemoteWordPressComREST { let parameters = ["context": "edit"] let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) - wordPressComRestApi.GET(path, + wordPressComRESTAPI.get(path, parameters: parameters as [String: AnyObject]?, success: { responseObject, _ in @@ -54,7 +54,7 @@ public class AccountSettingsRemote: ServiceRemoteWordPressComREST { let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) let parameters = [fieldNameForChange(change): change.stringValue] - wordPressComRestApi.POST(path, + wordPressComRESTAPI.post(path, parameters: parameters as [String: AnyObject]?, success: { _, _ in @@ -79,7 +79,7 @@ public class AccountSettingsRemote: ServiceRemoteWordPressComREST { let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) - wordPressComRestApi.POST(path, + wordPressComRESTAPI.post(path, parameters: parameters as [String: AnyObject]?, success: { _, _ in success() @@ -99,7 +99,7 @@ public class AccountSettingsRemote: ServiceRemoteWordPressComREST { let endpoint = "me/username/validate/\(username)" let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) - wordPressComRestApi.GET(path, + wordPressComRESTAPI.get(path, parameters: nil, success: { _, _ in // The success block needs to be changed if @@ -116,7 +116,7 @@ public class AccountSettingsRemote: ServiceRemoteWordPressComREST { let endpoint = "wpcom/v2/users/username/suggestions" let parameters = ["name": base] - wordPressComRestApi.GET(endpoint, parameters: parameters as [String: AnyObject]?, success: { (responseObject, _) in + wordPressComRESTAPI.get(endpoint, parameters: parameters as [String: AnyObject]?, success: { (responseObject, _) in guard let response = responseObject as? [String: AnyObject], let suggestions = response["suggestions"] as? [String] else { finished([]) @@ -134,7 +134,7 @@ public class AccountSettingsRemote: ServiceRemoteWordPressComREST { let path = self.path(forEndpoint: endpoint, withVersion: ._1_1) let parameters = ["password": password] - wordPressComRestApi.POST(path, + wordPressComRESTAPI.post(path, parameters: parameters as [String: AnyObject]?, success: { _, _ in @@ -149,14 +149,14 @@ public class AccountSettingsRemote: ServiceRemoteWordPressComREST { let endpoint = "me/account/close" let path = path(forEndpoint: endpoint, withVersion: ._1_1) - wordPressComRestApi.POST(path, parameters: nil) { _, _ in + wordPressComRESTAPI.post(path, parameters: nil) { _, _ in success() } failure: { error, _ in failure(error) } } - private func settingsFromResponse(_ responseObject: AnyObject) throws -> AccountSettings { + private func settingsFromResponse(_ responseObject: Any) throws -> AccountSettings { guard let response = responseObject as? [String: AnyObject], let firstName = response["first_name"] as? String, let lastName = response["last_name"] as? String, diff --git a/Sources/WordPressKit/Services/ActivityServiceRemote_ApiVersion1_0.swift b/Sources/WordPressKit/Services/ActivityServiceRemote_ApiVersion1_0.swift index 96001e9c..2aa4ac2b 100644 --- a/Sources/WordPressKit/Services/ActivityServiceRemote_ApiVersion1_0.swift +++ b/Sources/WordPressKit/Services/ActivityServiceRemote_ApiVersion1_0.swift @@ -28,11 +28,12 @@ parameters["types"] = types.toDictionary() as AnyObject } - wordPressComRestApi.POST(path, + wordPressComRESTAPI.post(path, parameters: parameters, success: { response, _ in - guard let restoreID = response["restore_id"] as? Int, - let jobID = response["job_id"] as? Int else { + guard let responseDict = response as? [String: Any], + let restoreID = responseDict["restore_id"] as? Int, + let jobID = responseDict["job_id"] as? Int else { failure(ResponseError.decodingFailure) return }