Skip to content

Commit 7d4a72e

Browse files
committed
Adopt to the breaking changes in WordPressOrgRestApi
1 parent 0b17477 commit 7d4a72e

6 files changed

Lines changed: 82 additions & 84 deletions

File tree

WordPress/Classes/Models/Blog.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ - (WordPressOrgXMLRPCApi *)xmlrpcApi
889889
- (WordPressOrgRestApi *)wordPressOrgRestApi
890890
{
891891
if (_wordPressOrgRestApi == nil) {
892-
_wordPressOrgRestApi = [[WordPressOrgRestApi alloc] initWithBlog:self];
892+
_wordPressOrgRestApi = self.account == nil ? [[WordPressOrgRestApi alloc] initWithBlog:self] : nil;
893893
}
894894
return _wordPressOrgRestApi;
895895
}

WordPress/Classes/Networking/WordPressOrgRestApi+WordPress.swift

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,29 @@ private func apiBase(blog: Blog) -> URL? {
3737
}
3838

3939
extension WordPressOrgRestApi {
40-
@objc public convenience init?(blog: Blog) {
41-
guard let apiBase = apiBase(blog: blog),
42-
let authenticator = makeAuthenticator(blog: blog) else {
40+
@objc
41+
convenience init?(blog: Blog) {
42+
if let dotComID = blog.dotComID?.uint64Value,
43+
let token = blog.account?.authToken,
44+
token.count > 0 {
45+
self.init(dotComSiteID: dotComID, bearerToken: token, userAgent: WPUserAgent.wordPress())
46+
} else if let apiBase = apiBase(blog: blog),
47+
let loginURL = try? blog.loginUrl().asURL(),
48+
let adminURL = try? blog.adminUrl(withPath: "").asURL(),
49+
let username = blog.username,
50+
let password = blog.password {
51+
self.init(
52+
selfHostedSiteWPJSONURL: apiBase,
53+
credential: .init(
54+
loginURL: loginURL,
55+
username: username,
56+
password: password,
57+
adminURL: adminURL
58+
),
59+
userAgent: WPUserAgent.wordPress()
60+
)
61+
} else {
4362
return nil
4463
}
45-
self.init(
46-
apiBase: apiBase,
47-
authenticator: authenticator,
48-
userAgent: WPUserAgent.wordPress()
49-
)
5064
}
5165
}

WordPress/Classes/Services/BlockEditorSettingsService.swift

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,15 @@ class BlockEditorSettingsService {
2222
}
2323

2424
convenience init?(blog: Blog, coreDataStack: CoreDataStackSwift) {
25-
let remoteAPI: WordPressRestApi
26-
if blog.isAccessibleThroughWPCom(),
27-
blog.dotComID?.intValue != nil,
28-
let restAPI = blog.wordPressComRestApi() {
29-
remoteAPI = restAPI
30-
} else if let orgAPI = blog.wordPressOrgRestApi {
31-
remoteAPI = orgAPI
32-
} else {
25+
guard let remoteAPI = WordPressOrgRestApi(blog: blog) else {
3326
// This is should only happen if there is a problem with the blog itsself.
3427
return nil
3528
}
3629

3730
self.init(blog: blog, remoteAPI: remoteAPI, coreDataStack: coreDataStack)
3831
}
3932

40-
init(blog: Blog, remoteAPI: WordPressRestApi, coreDataStack: CoreDataStackSwift) {
33+
init(blog: Blog, remoteAPI: WordPressOrgRestApi, coreDataStack: CoreDataStackSwift) {
4134
assert(blog.objectID.persistentStore != nil, "The blog instance should be saved first")
4235
self.blog = blog
4336
self.coreDataStack = coreDataStack
@@ -65,7 +58,7 @@ class BlockEditorSettingsService {
6558
// MARK: Editor `theme_supports` support
6659
private extension BlockEditorSettingsService {
6760
func fetchTheme(_ completion: @escaping BlockEditorSettingsServiceCompletion) {
68-
remote.fetchTheme(forSiteID: blog.dotComID?.intValue) { [weak self] (response) in
61+
remote.fetchTheme { [weak self] (response) in
6962
guard let `self` = self else { return }
7063
switch response {
7164
case .success(let editorTheme):
@@ -127,7 +120,7 @@ private extension BlockEditorSettingsService {
127120
// MARK: Editor Global Styles support
128121
private extension BlockEditorSettingsService {
129122
func fetchBlockEditorSettings(_ completion: @escaping BlockEditorSettingsServiceCompletion) {
130-
remote.fetchBlockEditorSettings(forSiteID: blog.dotComID?.intValue) { [weak self] (response) in
123+
remote.fetchBlockEditorSettings { [weak self] (response) in
131124
guard let `self` = self else { return }
132125
switch response {
133126
case .success(let remoteSettings):

WordPress/Classes/Services/BloggingPrompts/BloggingPromptsService.swift

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -323,20 +323,17 @@ private extension BloggingPromptsService {
323323
return params
324324
}()
325325

326-
api.GET(path, parameters: requestParameter as [String: AnyObject]) { result, _ in
327-
switch result {
328-
case .success(let responseObject):
329-
do {
330-
let data = try JSONSerialization.data(withJSONObject: responseObject, options: [])
331-
let remotePrompts = try Self.jsonDecoder.decode([BloggingPromptRemoteObject].self, from: data)
332-
completion(.success(remotePrompts))
333-
} catch {
334-
completion(.failure(error))
335-
}
336-
case .failure(let error):
326+
api.GET(path, parameters: requestParameter as [String: AnyObject], success: { (responseObject, _) in
327+
do {
328+
let data = try JSONSerialization.data(withJSONObject: responseObject, options: [])
329+
let remotePrompts = try Self.jsonDecoder.decode([BloggingPromptRemoteObject].self, from: data)
330+
completion(.success(remotePrompts))
331+
} catch {
337332
completion(.failure(error))
338333
}
339-
}
334+
}, failure: { (error, _) in
335+
completion(.failure(error))
336+
})
340337
}
341338

342339
/// Loads local prompts based on the given parameters.

WordPress/Classes/ViewRelated/Gutenberg/GutenbergNetworking.swift

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,37 +70,36 @@ struct GutenbergNetworkRequest {
7070
return
7171
}
7272

73+
let task: Task<WordPressAPIResult<Any, WordPressOrgRestApiError>, Never>
74+
7375
switch method {
7476
case .get:
75-
api.GET(path, parameters: nil) { (result, httpResponse) in
76-
switch result {
77-
case .success(let response):
78-
completion(.success(response))
79-
case .failure(let error):
80-
if handleEmbedError(path: path, error: error, completion: completion) {
81-
return
82-
}
83-
completion(.failure(error as NSError))
84-
}
77+
task = Task {
78+
await api.get(path: path)
8579
}
8680
case .post:
87-
api.POST(path, parameters: data) { (result, httpResponse) in
88-
switch result {
89-
case .success(let response):
90-
completion(.success(response))
91-
case .failure(let error):
92-
if handleEmbedError(path: path, error: error, completion: completion) {
93-
return
94-
}
95-
completion(.failure(error as NSError))
81+
task = Task {
82+
await api.post(path: path, parameters: data ?? [:])
83+
}
84+
}
85+
86+
Task { @MainActor in
87+
let result = await task.value
88+
switch result {
89+
case .success(let response):
90+
completion(.success(response))
91+
case .failure(let error):
92+
if handleEmbedError(path: path, error: error, completion: completion) {
93+
return
9694
}
95+
completion(.failure(error as NSError))
9796
}
9897
}
9998
}
10099

101-
private func handleEmbedError(path: String, error: Error, completion: @escaping CompletionHandler) -> Bool {
100+
private func handleEmbedError(path: String, error: WordPressAPIError<WordPressOrgRestApiError>, completion: @escaping CompletionHandler) -> Bool {
102101
if path.starts(with: "/oembed/1.0/") {
103-
if let error = error as? AFError, error.responseCode == 404 {
102+
if case let .unacceptableStatusCode(response: response, body: _) = error, response.statusCode == 404 {
104103
completion(.failure(URLError(URLError.Code(rawValue: 404)) as NSError))
105104
return true
106105
}

WordPress/Classes/ViewRelated/Jetpack/Install/JetpackNativeConnectionService.swift

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,25 @@ final class JetpackNativeConnectionService: NSObject {
4040
/// - Parameter completion: Result with either Jetpack connection URL or JetpackNativeConnectionURLError
4141
///
4242
func fetchJetpackConnectionURL(completion: @escaping (Result<URL, JetpackNativeConnectionURLError>) -> ()) {
43-
api.request(method: .get, path: Path.getConnectionURL, parameters: [:], completion: { result, response in
44-
switch result {
45-
case .success(let data):
46-
if let urlString = data as? String,
47-
let url = URL(string: urlString),
48-
urlString.hasPrefix(Constants.jetpackAccountConnectionURL) {
49-
completion(.success(url))
50-
} else {
51-
/// If the site didn't implement the site-level connection, the URL would be at the form: https://{site_url}/wp-admin/admin.php?page=jetpack&action=register&_wpnonce={nonce}
52-
/// In this case, we need to take cookies from current response, call the returned URL,
53-
/// and get the connection URL through redirection (See https://github.com/woocommerce/woocommerce-android/issues/7525)
43+
Task { @MainActor in
44+
let result = await self.api.get(path: Path.getConnectionURL, type: String.self)
45+
.mapError { JetpackNativeConnectionURLError.remote($0.localizedDescription) }
46+
.flatMap { urlString in
47+
if let url = URL(string: urlString),
48+
urlString.hasPrefix(Constants.jetpackAccountConnectionURL) {
49+
return .success(url)
50+
} else {
51+
/// If the site didn't implement the site-level connection, the URL would be at the form: https://{site_url}/wp-admin/admin.php?page=jetpack&action=register&_wpnonce={nonce}
52+
/// In this case, we need to take cookies from current response, call the returned URL,
53+
/// and get the connection URL through redirection (See https://github.com/woocommerce/woocommerce-android/issues/7525)
5454

55-
/// When site-level connection is not implemented, JetpackConnectionWebViewController
56-
/// does not use JetpackNativeConnectionService so this case is ignored for now
57-
completion(.failure(.jetpackSiteNotRegistered))
55+
/// When site-level connection is not implemented, JetpackConnectionWebViewController
56+
/// does not use JetpackNativeConnectionService so this case is ignored for now
57+
return .failure(.jetpackSiteNotRegistered)
58+
}
5859
}
59-
case .failure(let error):
60-
completion(.failure(.remote(error.localizedDescription)))
61-
}
62-
})
60+
completion(result)
61+
}
6362
}
6463

6564
/// Fetches Jetpack User that contains Jetpack plugin connection information using Jetpack REST API
@@ -68,19 +67,15 @@ final class JetpackNativeConnectionService: NSObject {
6867
/// - Parameter completion: Result with either JetpackUser or JetpackNativeConnectionDataError
6968
///
7069
func fetchJetpackUser(completion: @escaping (Result<JetpackUser, JetpackNativeConnectionDataError>) -> ()) {
71-
api.request(method: .get, path: Path.getJetpackUserData, parameters: [:], completion: { result, response in
72-
switch result {
73-
case .success(let json):
74-
do {
75-
let data = try JSONSerialization.data(withJSONObject: json)
76-
let jetpackUserData = try JSONDecoder().decode(JetpackUserData.self, from: data)
77-
completion(.success(jetpackUserData.currentUser))
78-
} catch {
79-
completion(.failure(.parsingError))
70+
Task { @MainActor in
71+
let result = await self.api.get(path: Path.getJetpackUserData, type: JetpackUserData.self)
72+
.map { $0.currentUser }
73+
.flatMapError { original in
74+
if case let .unparsableResponse(response, _, underlyingError) = original, response?.statusCode == 200, underlyingError is DecodingError {
75+
return .failure(JetpackNativeConnectionDataError.parsingError)
76+
}
77+
return .failure(.remote(original.localizedDescription))
8078
}
81-
case .failure(let error):
82-
completion(.failure(.remote(error.localizedDescription)))
83-
}
84-
})
79+
}
8580
}
8681
}

0 commit comments

Comments
 (0)