Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit db1acee

Browse files
authored
Offline Mode: Add getPost(withID) (#785)
2 parents 7c7439b + a056604 commit db1acee

File tree

5 files changed

+62
-31
lines changed

5 files changed

+62
-31
lines changed

Sources/WordPressKit/Services/PostServiceRemoteExtended.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
import Foundation
22

33
public protocol PostServiceRemoteExtended: PostServiceRemote {
4+
/// Returns a post with the given ID.
5+
///
6+
/// - throws: ``PostServiceRemoteError`` or oher underlying errors
7+
/// (see ``WordPressAPIError``)
8+
func post(withID postID: Int) async throws -> RemotePost
9+
410
/// Creates a new post with the given parameters.
511
func createPost(with parameters: RemotePostCreateParameters) async throws -> RemotePost
612

713
/// Performs a partial update to the existing post.
814
///
9-
/// - throws: ``PostServiceRemoteUpdatePostError`` or oher underlying errors
15+
/// - throws: ``PostServiceRemoteError`` or oher underlying errors
1016
/// (see ``WordPressAPIError``)
1117
func patchPost(withID postID: Int, parameters: RemotePostUpdateParameters) async throws -> RemotePost
1218

1319
/// Permanently deletes a post with the given ID.
1420
///
15-
/// - throws: ``PostServiceRemoteUpdatePostError`` or oher underlying errors
21+
/// - throws: ``PostServiceRemoteError`` or oher underlying errors
1622
/// (see ``WordPressAPIError``)
1723
func deletePost(withID postID: Int) async throws
1824
}
1925

20-
public enum PostServiceRemoteUpdatePostError: Error {
26+
public enum PostServiceRemoteError: Error {
2127
/// 409 (Conflict)
2228
case conflict
2329
/// 404 (Not Found)

Sources/WordPressKit/Services/PostServiceRemoteREST+Extended.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
import Foundation
22

33
extension PostServiceRemoteREST: PostServiceRemoteExtended {
4+
public func post(withID postID: Int) async throws -> RemotePost {
5+
let path = self.path(forEndpoint: "sites/\(siteID)/posts/\(postID)?context=edit", withVersion: ._1_1)
6+
let result = await wordPressComRestApi.perform(.get, URLString: path)
7+
switch result {
8+
case .success(let response):
9+
return try await decodePost(from: response.body)
10+
case .failure(let error):
11+
if case .endpointError(let error) = error, error.apiErrorCode == "unknown_post" {
12+
throw PostServiceRemoteError.notFound
13+
}
14+
throw error
15+
}
16+
}
17+
418
public func createPost(with parameters: RemotePostCreateParameters) async throws -> RemotePost {
519
let path = self.path(forEndpoint: "sites/\(siteID)/posts/new?context=edit", withVersion: ._1_2)
620
let parameters = try makeParameters(from: RemotePostCreateParametersWordPressComEncoder(parameters: parameters))
@@ -22,8 +36,8 @@ extension PostServiceRemoteREST: PostServiceRemoteExtended {
2236
throw error
2337
}
2438
switch error.apiErrorCode ?? "" {
25-
case "unknown_post": throw PostServiceRemoteUpdatePostError.notFound
26-
case "old-revision": throw PostServiceRemoteUpdatePostError.conflict
39+
case "unknown_post": throw PostServiceRemoteError.notFound
40+
case "old-revision": throw PostServiceRemoteError.conflict
2741
default: throw error
2842
}
2943
}
@@ -40,7 +54,7 @@ extension PostServiceRemoteREST: PostServiceRemoteExtended {
4054
throw error
4155
}
4256
switch error.apiErrorCode ?? "" {
43-
case "unknown_post": throw PostServiceRemoteUpdatePostError.notFound
57+
case "unknown_post": throw PostServiceRemoteError.notFound
4458
default: throw error
4559
}
4660
}

Sources/WordPressKit/Services/PostServiceRemoteXMLRPC+Extended.swift

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,28 @@ import Foundation
22
import wpxmlrpc
33

44
extension PostServiceRemoteXMLRPC: PostServiceRemoteExtended {
5+
public func post(withID postID: Int) async throws -> RemotePost {
6+
let parameters = xmlrpcArguments(withExtra: postID) as [AnyObject]
7+
let result = await api.call(method: "wp.getPost", parameters: parameters)
8+
switch result {
9+
case .success(let response):
10+
return try await decodePost(from: response.body)
11+
case .failure(let error):
12+
if case .endpointError(let error) = error, error.code == 404 {
13+
throw PostServiceRemoteError.notFound
14+
}
15+
throw error
16+
}
17+
}
18+
519
public func createPost(with parameters: RemotePostCreateParameters) async throws -> RemotePost {
620
let dictionary = try makeParameters(from: RemotePostCreateParametersXMLRPCEncoder(parameters: parameters))
721
let parameters = xmlrpcArguments(withExtra: dictionary) as [AnyObject]
822
let response = try await api.call(method: "metaWeblog.newPost", parameters: parameters).get()
923
guard let postID = (response.body as? NSObject)?.numericValue() else {
1024
throw URLError(.unknown) // Should never happen
1125
}
12-
return try await getPost(withID: postID)
26+
return try await post(withID: postID.intValue)
1327
}
1428

1529
public func patchPost(withID postID: Int, parameters: RemotePostUpdateParameters) async throws -> RemotePost {
@@ -21,14 +35,14 @@ extension PostServiceRemoteXMLRPC: PostServiceRemoteExtended {
2135
let result = await api.call(method: "metaWeblog.editPost", parameters: parameters)
2236
switch result {
2337
case .success:
24-
return try await getPost(withID: postID as NSNumber)
38+
return try await post(withID: postID)
2539
case .failure(let error):
2640
guard case .endpointError(let error) = error else {
2741
throw error
2842
}
2943
switch error.code ?? 0 {
30-
case 404: throw PostServiceRemoteUpdatePostError.notFound
31-
case 409: throw PostServiceRemoteUpdatePostError.conflict
44+
case 404: throw PostServiceRemoteError.notFound
45+
case 409: throw PostServiceRemoteError.conflict
3246
default: throw error
3347
}
3448
}
@@ -41,28 +55,19 @@ extension PostServiceRemoteXMLRPC: PostServiceRemoteExtended {
4155
case .success:
4256
return
4357
case .failure(let error):
44-
guard case .endpointError(let error) = error else {
45-
throw error
46-
}
47-
switch error.code ?? 0 {
48-
case 404: throw PostServiceRemoteUpdatePostError.notFound
49-
default: throw error
58+
if case .endpointError(let error) = error, error.code == 404 {
59+
throw PostServiceRemoteError.notFound
5060
}
61+
throw error
5162
}
5263
}
64+
}
5365

54-
private func getPost(withID postID: NSNumber) async throws -> RemotePost {
55-
try await withUnsafeThrowingContinuation { continuation in
56-
getPostWithID(postID) { post in
57-
guard let post else {
58-
return continuation.resume(throwing: URLError(.unknown)) // Should never happen
59-
}
60-
continuation.resume(returning: post)
61-
} failure: { error in
62-
continuation.resume(throwing: error ?? URLError(.unknown))
63-
}
64-
}
66+
private func decodePost(from object: AnyObject) async throws -> RemotePost {
67+
guard let dictionary = object as? [AnyHashable: Any] else {
68+
throw WordPressAPIError<WordPressComRestApiEndpointError>.unparsableResponse(response: nil, body: nil)
6569
}
70+
return PostServiceRemoteXMLRPC.remotePost(fromXMLRPCDictionary: dictionary)
6671
}
6772

6873
private func makeParameters<T: Encodable>(from value: T) throws -> [String: AnyObject] {

Sources/WordPressKit/Services/PostServiceRemoteXMLRPC.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44

55
@interface PostServiceRemoteXMLRPC : ServiceRemoteWordPressXMLRPC <PostServiceRemote>
66

7+
+ (RemotePost *)remotePostFromXMLRPCDictionary:(NSDictionary *)xmlrpcDictionary;
8+
79
@end

Sources/WordPressKit/Services/PostServiceRemoteXMLRPC.m

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ - (NSDictionary *)dictionaryWithRemoteOptions:(id <PostServiceRemoteOptions>)opt
294294
}
295295

296296
- (RemotePost *)remotePostFromXMLRPCDictionary:(NSDictionary *)xmlrpcDictionary {
297+
return [PostServiceRemoteXMLRPC remotePostFromXMLRPCDictionary:xmlrpcDictionary];
298+
}
299+
300+
+ (RemotePost *)remotePostFromXMLRPCDictionary:(NSDictionary *)xmlrpcDictionary {
297301
RemotePost *post = [RemotePost new];
298302

299303
post.postID = [xmlrpcDictionary numberForKey:@"post_id"];
@@ -339,7 +343,7 @@ - (RemotePost *)remotePostFromXMLRPCDictionary:(NSDictionary *)xmlrpcDictionary
339343
return post;
340344
}
341345

342-
- (NSString *)statusForPostStatus:(NSString *)status andDate:(NSDate *)date
346+
+ (NSString *)statusForPostStatus:(NSString *)status andDate:(NSDate *)date
343347
{
344348
// Scheduled posts are synced with a post_status of 'publish' but we want to
345349
// work with a status of 'future' from within the app.
@@ -349,20 +353,20 @@ - (NSString *)statusForPostStatus:(NSString *)status andDate:(NSDate *)date
349353
return status;
350354
}
351355

352-
- (NSArray *)tagsFromXMLRPCTermsArray:(NSArray *)terms {
356+
+ (NSArray *)tagsFromXMLRPCTermsArray:(NSArray *)terms {
353357
NSArray *tags = [terms filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"taxonomy = 'post_tag' AND name != NIL"]];
354358
return [tags valueForKey:@"name"];
355359
}
356360

357-
- (NSArray *)remoteCategoriesFromXMLRPCTermsArray:(NSArray *)terms {
361+
+ (NSArray *)remoteCategoriesFromXMLRPCTermsArray:(NSArray *)terms {
358362
return [[terms wp_filter:^BOOL(NSDictionary *category) {
359363
return [[category stringForKey:@"taxonomy"] isEqualToString:@"category"];
360364
}] wp_map:^id(NSDictionary *category) {
361365
return [self remoteCategoryFromXMLRPCDictionary:category];
362366
}];
363367
}
364368

365-
- (RemotePostCategory *)remoteCategoryFromXMLRPCDictionary:(NSDictionary *)xmlrpcCategory {
369+
+ (RemotePostCategory *)remoteCategoryFromXMLRPCDictionary:(NSDictionary *)xmlrpcCategory {
366370
RemotePostCategory *category = [RemotePostCategory new];
367371
category.categoryID = [xmlrpcCategory numberForKey:@"term_id"];
368372
category.name = [xmlrpcCategory stringForKey:@"name"];

0 commit comments

Comments
 (0)