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

Commit 32840bd

Browse files
committed
Add PostServiceRemoteExtended
1 parent 39e9dac commit 32840bd

File tree

8 files changed

+91
-71
lines changed

8 files changed

+91
-71
lines changed

WordPressKit.xcodeproj/project.pbxproj

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
0847B92C2A4442730044D32F /* IPLocationRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0847B92B2A4442730044D32F /* IPLocationRemote.swift */; };
1717
08C7493E2A45EA11000DA0E2 /* IPLocationRemoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08C7493D2A45EA11000DA0E2 /* IPLocationRemoteTests.swift */; };
1818
0C1C08382B9B675400E52F8C /* StringCodingKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1C08372B9B675400E52F8C /* StringCodingKey.swift */; };
19-
0C9CD7992B9A107E0045BE03 /* RemotePostUpdateParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9CD7982B9A107E0045BE03 /* RemotePostUpdateParameters.swift */; };
19+
0C1C08412B9CD79900E52F8C /* PostServiceRemoteExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1C08402B9CD79900E52F8C /* PostServiceRemoteExtended.swift */; };
20+
0C1C08432B9CD8D200E52F8C /* PostServiceRemoteREST+Extended.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1C08422B9CD8D200E52F8C /* PostServiceRemoteREST+Extended.swift */; };
21+
0C1C08452B9CDB0B00E52F8C /* PostServiceRemoteXMLRPC+Extended.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1C08442B9CDB0B00E52F8C /* PostServiceRemoteXMLRPC+Extended.swift */; };
22+
0C9CD7992B9A107E0045BE03 /* RemotePostParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9CD7982B9A107E0045BE03 /* RemotePostParameters.swift */; };
2023
0CB1905E2A2A5E83004D3E80 /* BlazeCampaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB1905D2A2A5E83004D3E80 /* BlazeCampaign.swift */; };
2124
0CB190612A2A6A13004D3E80 /* blaze-campaigns-search.json in Resources */ = {isa = PBXBuildFile; fileRef = 0CB1905F2A2A6943004D3E80 /* blaze-campaigns-search.json */; };
2225
0CB190652A2A7569004D3E80 /* BlazeCampaignsSearchResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB190642A2A7569004D3E80 /* BlazeCampaignsSearchResponse.swift */; };
@@ -738,8 +741,11 @@
738741
0847B92B2A4442730044D32F /* IPLocationRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPLocationRemote.swift; sourceTree = "<group>"; };
739742
08C7493D2A45EA11000DA0E2 /* IPLocationRemoteTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPLocationRemoteTests.swift; sourceTree = "<group>"; };
740743
0C1C08372B9B675400E52F8C /* StringCodingKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringCodingKey.swift; sourceTree = "<group>"; };
744+
0C1C08402B9CD79900E52F8C /* PostServiceRemoteExtended.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostServiceRemoteExtended.swift; sourceTree = "<group>"; };
745+
0C1C08422B9CD8D200E52F8C /* PostServiceRemoteREST+Extended.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PostServiceRemoteREST+Extended.swift"; sourceTree = "<group>"; };
746+
0C1C08442B9CDB0B00E52F8C /* PostServiceRemoteXMLRPC+Extended.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PostServiceRemoteXMLRPC+Extended.swift"; sourceTree = "<group>"; };
741747
0C3A2A412A2E7BA500FD91D6 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
742-
0C9CD7982B9A107E0045BE03 /* RemotePostUpdateParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemotePostUpdateParameters.swift; sourceTree = "<group>"; };
748+
0C9CD7982B9A107E0045BE03 /* RemotePostParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemotePostParameters.swift; sourceTree = "<group>"; };
743749
0CB1905D2A2A5E83004D3E80 /* BlazeCampaign.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlazeCampaign.swift; sourceTree = "<group>"; };
744750
0CB1905F2A2A6943004D3E80 /* blaze-campaigns-search.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blaze-campaigns-search.json"; sourceTree = "<group>"; };
745751
0CB190642A2A7569004D3E80 /* BlazeCampaignsSearchResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlazeCampaignsSearchResponse.swift; sourceTree = "<group>"; };
@@ -2017,12 +2023,15 @@
20172023
E1BD95141FD5A2B800CD5CE3 /* PluginDirectoryServiceRemote.swift */,
20182024
E13EE1461F33258E00C15787 /* PluginServiceRemote.swift */,
20192025
740B23B21F17EC7300067A2A /* PostServiceRemote.h */,
2026+
0C1C08402B9CD79900E52F8C /* PostServiceRemoteExtended.swift */,
20202027
740B23BC1F17ECB500067A2A /* PostServiceRemoteOptions.h */,
20212028
740B23B31F17EC7300067A2A /* PostServiceRemoteREST.h */,
20222029
740B23B41F17EC7300067A2A /* PostServiceRemoteREST.m */,
2030+
0C1C08422B9CD8D200E52F8C /* PostServiceRemoteREST+Extended.swift */,
20232031
9AF4F2FB218331DC00570E4B /* PostServiceRemoteREST+Revisions.swift */,
20242032
740B23B51F17EC7300067A2A /* PostServiceRemoteXMLRPC.h */,
20252033
740B23B61F17EC7300067A2A /* PostServiceRemoteXMLRPC.m */,
2034+
0C1C08442B9CDB0B00E52F8C /* PostServiceRemoteXMLRPC+Extended.swift */,
20262035
F181EA0127184D3C00F26141 /* ProductServiceRemote.swift */,
20272036
74A44DCA1F13C533006CD8F4 /* PushAuthenticationServiceRemote.swift */,
20282037
C7A09A4F284104DB003096ED /* QR Login */,
@@ -2120,7 +2129,7 @@
21202129
E61A51A521B172A900A5F902 /* RemoteWpcomPlan.swift */,
21212130
740B23C01F17EE8000067A2A /* RemotePost.h */,
21222131
740B23C11F17EE8000067A2A /* RemotePost.m */,
2123-
0C9CD7982B9A107E0045BE03 /* RemotePostUpdateParameters.swift */,
2132+
0C9CD7982B9A107E0045BE03 /* RemotePostParameters.swift */,
21242133
740B23BE1F17EE8000067A2A /* RemotePostCategory.h */,
21252134
740B23BF1F17EE8000067A2A /* RemotePostCategory.m */,
21262135
93188D1C1F2262BF0028ED4D /* RemotePostTag.h */,
@@ -3486,14 +3495,17 @@
34863495
436D56352118D85800CEAA33 /* WPCountry.swift in Sources */,
34873496
74A44DCB1F13C533006CD8F4 /* NotificationSettingsServiceRemote.swift in Sources */,
34883497
FAD1344525908F5F00A8FEB1 /* JetpackBackupServiceRemote.swift in Sources */,
3498+
0C1C08452B9CDB0B00E52F8C /* PostServiceRemoteXMLRPC+Extended.swift in Sources */,
34893499
F1BB7806240FB90B0030ADDC /* AtomicAuthenticationServiceRemote.swift in Sources */,
34903500
404057CE221C38130060250C /* StatsTopVideosTimeIntervalData.swift in Sources */,
34913501
7E0D64FF22D855700092AD10 /* EditorServiceRemote.swift in Sources */,
3502+
0C1C08412B9CD79900E52F8C /* PostServiceRemoteExtended.swift in Sources */,
34923503
9AF4F2FF2183346B00570E4B /* RemoteRevision.swift in Sources */,
34933504
17D936252475D8AB008B2205 /* RemoteHomepageType.swift in Sources */,
34943505
74BA04F41F06DC0A00ED5CD8 /* CommentServiceRemoteREST.m in Sources */,
34953506
74C473AC1EF2F75E009918F2 /* SiteManagementServiceRemote.swift in Sources */,
34963507
74585B971F0D54B400E7E667 /* RemoteDomain.swift in Sources */,
3508+
0C1C08432B9CD8D200E52F8C /* PostServiceRemoteREST+Extended.swift in Sources */,
34973509
74A44DD01F13C64B006CD8F4 /* RemoteNotification.swift in Sources */,
34983510
8B52B901257AC5A200221663 /* Date+endOfDay.swift in Sources */,
34993511
E1D6B558200E473A00325669 /* TimeZoneServiceRemote.swift in Sources */,
@@ -3509,7 +3521,7 @@
35093521
93BD27811EE73944002BB00B /* WordPressOrgXMLRPCApi.swift in Sources */,
35103522
4A57A6832B54A326008D0660 /* WordPressAPIError+NSErrorBrdige.swift in Sources */,
35113523
439A44D62107C66A00795ED7 /* JSONDecoderExtension.swift in Sources */,
3512-
0C9CD7992B9A107E0045BE03 /* RemotePostUpdateParameters.swift in Sources */,
3524+
0C9CD7992B9A107E0045BE03 /* RemotePostParameters.swift in Sources */,
35133525
B5A4822B20AC6C0B009D95F6 /* WPKitLogging.swift in Sources */,
35143526
B5A4822E20AC6C1A009D95F6 /* WPKitLogging.m in Sources */,
35153527
7430C9A61F1927180051B8E6 /* ReaderSiteServiceRemote.m in Sources */,

WordPressKit/PostServiceRemote.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,6 @@
6363
success:(void (^)(RemotePost *post))success
6464
failure:(void (^)(NSError *error))failure;
6565

66-
/**
67-
* @brief Updates a blog's post.
68-
*
69-
* @param postID The ID of the post to update. Cannot be nil.
70-
* @param success The block that will be executed on success. Can be nil.
71-
* @param failure The block that will be executed on failure. Can be nil.
72-
*/
73-
- (void)patchPostWithID:(NSNumber *)postID
74-
parameters:(RemotePostUpdateParameters *)post
75-
success:(void (^)(RemotePost *post))success
76-
failure:(void (^)(NSError *error))failure;
77-
7866
/**
7967
* @brief Deletes a post.
8068
*
@@ -115,4 +103,7 @@
115103
*/
116104
- (NSDictionary *)dictionaryWithRemoteOptions:(id <PostServiceRemoteOptions>)options;
117105

106+
/// Returns a remote post with the given data.
107+
+ (RemotePost *)remotePostFromJSONDictionary:(NSDictionary *)jsonPost;
108+
118109
@end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Foundation
2+
3+
public protocol PostServiceRemoteExtended: PostServiceRemote {
4+
/// Performs a partial update of the given post.
5+
func patchPost(withID postID: Int, changes: RemotePostUpdateParameters) async throws -> RemotePost
6+
}

WordPressKit/RemotePostUpdateParameters.swift renamed to WordPressKit/PostServiceRemoteREST+Extended.swift

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
11
import Foundation
22

3-
/// Represents a partial update to be applied to a post.
4-
public final class RemotePostUpdateParameters: NSObject, Encodable {
5-
public var ifNotModifiedSince: Date?
3+
extension PostServiceRemoteREST: PostServiceRemoteExtended {
4+
public func patchPost(withID postID: Int, changes: RemotePostUpdateParameters) async throws -> RemotePost {
5+
let path = self.path(forEndpoint: "sites/\(siteID)/posts/\(postID)?context=edit", withVersion: ._1_2)
6+
let parameters = RemotePostUpdateParametersWordPressComEncoder.makeParameters(for: changes)
67

7-
public var status: String?
8-
public var date: Date?
9-
public var authorID: Int??
10-
public var title: String??
11-
public var content: String??
12-
public var password: String??
13-
public var excerpt: String??
14-
public var slug: String??
15-
public var featuredImageID: Int??
16-
17-
// Pages
18-
public var parentPageID: Int??
8+
return try await withUnsafeThrowingContinuation { continuation in
9+
wordPressComRestApi.POST(path, parameters: parameters) { responseObject, _ in
10+
if let dictionary = responseObject as? [AnyHashable: Any],
11+
let post = PostServiceRemoteREST.remotePost(fromJSONDictionary: dictionary) {
12+
continuation.resume(returning: post)
13+
} else {
14+
continuation.resume(throwing: URLError(.unknown)) // Should never happen
15+
}
16+
} failure: { error, _ in
17+
continuation.resume(throwing: error)
18+
}
19+
}
20+
}
21+
}
1922

20-
// Posts
21-
public var format: String??
22-
public var tags: [String]?
23-
public var categoryIDs: [Int]?
24-
public var isSticky: Bool?
23+
private struct RemotePostUpdateParametersWordPressComEncoder: Encodable {
24+
let parameters: RemotePostUpdateParameters
2525

26-
// Makes it compatible with Objective-C.
27-
@objc public func makeWordPressCOMParameters() -> [String: Any]? {
26+
static func makeParameters(for parameters: RemotePostUpdateParameters) -> [String: AnyObject]? {
2827
let encoder = JSONEncoder()
2928
encoder.dateEncodingStrategy = .formatted(NSDate.rfc3339DateFormatter())
30-
guard let data = try? encoder.encode(RemotePostUpdateParametersWordPressComEncoder(parameters: self)),
29+
guard let data = try? encoder.encode(RemotePostUpdateParametersWordPressComEncoder(parameters: parameters)),
3130
let object = try? JSONSerialization.jsonObject(with: data) else {
3231
return nil // Should never happen
3332
}
34-
return object as? [String: Any]
33+
return object as? [String: AnyObject]
3534
}
36-
}
37-
38-
private struct RemotePostUpdateParametersWordPressComEncoder: Encodable {
39-
let parameters: RemotePostUpdateParameters
4035

4136
func encode(to encoder: Encoder) throws {
4237
var container = encoder.container(keyedBy: StringCodingKey.self)

WordPressKit/PostServiceRemoteREST.m

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -210,29 +210,6 @@ - (void)updatePost:(RemotePost *)post
210210
}];
211211
}
212212

213-
- (void)patchPostWithID:(NSNumber *)postID
214-
parameters:(RemotePostUpdateParameters *)postUpdateParameters
215-
success:(void (^)(RemotePost *))success
216-
failure:(void (^)(NSError *))failure {
217-
NSString *path = [NSString stringWithFormat:@"sites/%@/posts/%@?context=edit", self.siteID, postID];
218-
NSString *requestUrl = [self pathForEndpoint:path withVersion:ServiceRemoteWordPressComRESTApiVersion_1_2];
219-
220-
NSDictionary *parameters = [postUpdateParameters makeWordPressCOMParameters];
221-
222-
[self.wordPressComRestApi POST:requestUrl
223-
parameters:parameters
224-
success:^(id responseObject, NSHTTPURLResponse *httpResponse) {
225-
RemotePost *post = [self remotePostFromJSONDictionary:responseObject];
226-
if (success) {
227-
success(post);
228-
}
229-
} failure:^(NSError *error, NSHTTPURLResponse *httpResponse) {
230-
if (failure) {
231-
failure(error);
232-
}
233-
}];
234-
}
235-
236213
- (void)autoSave:(RemotePost *)post
237214
success:(void (^)(RemotePost *, NSString *))success
238215
failure:(void (^)(NSError *))failure
@@ -458,6 +435,10 @@ - (NSArray *)remotePostsFromJSONArray:(NSArray *)jsonPosts {
458435
}
459436

460437
- (RemotePost *)remotePostFromJSONDictionary:(NSDictionary *)jsonPost {
438+
return [PostServiceRemoteREST remotePostFromJSONDictionary:jsonPost];
439+
}
440+
441+
+ (RemotePost *)remotePostFromJSONDictionary:(NSDictionary *)jsonPost {
461442
RemotePost *post = [RemotePost new];
462443
post.postID = jsonPost[@"ID"];
463444
post.siteID = jsonPost[@"site_ID"];
@@ -496,7 +477,7 @@ - (RemotePost *)remotePostFromJSONDictionary:(NSDictionary *)jsonPost {
496477

497478
post.isStickyPost = [jsonPost numberForKeyPath:@"sticky"];
498479

499-
// FIXME: remove conversion once API is fixed #38-io
480+
// FIXME: remove conversion once API is fixed #38-;
500481
// metadata should always be an array but it's returning false when there are no custom fields
501482
post.metadata = [jsonPost arrayForKey:@"metadata"];
502483
// Or even worse, in some cases (Jetpack sites?) is an array containing false
@@ -634,13 +615,13 @@ - (NSArray *)metadataForPost:(RemotePost *)post {
634615
}];
635616
}
636617

637-
- (NSArray *)remoteCategoriesFromJSONArray:(NSArray *)jsonCategories {
618+
+ (NSArray *)remoteCategoriesFromJSONArray:(NSArray *)jsonCategories {
638619
return [jsonCategories wp_map:^id(NSDictionary *jsonCategory) {
639620
return [self remoteCategoryFromJSONDictionary:jsonCategory];
640621
}];
641622
}
642623

643-
- (RemotePostCategory *)remoteCategoryFromJSONDictionary:(NSDictionary *)jsonCategory {
624+
+ (RemotePostCategory *)remoteCategoryFromJSONDictionary:(NSDictionary *)jsonCategory {
644625
RemotePostCategory *category = [RemotePostCategory new];
645626
category.categoryID = jsonCategory[@"ID"];
646627
category.name = jsonCategory[@"name"];
@@ -649,7 +630,7 @@ - (RemotePostCategory *)remoteCategoryFromJSONDictionary:(NSDictionary *)jsonCat
649630
return category;
650631
}
651632

652-
- (NSArray *)tagNamesFromJSONDictionary:(NSDictionary *)jsonTags {
633+
+ (NSArray *)tagNamesFromJSONDictionary:(NSDictionary *)jsonTags {
653634
return [jsonTags allKeys];
654635
}
655636

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Foundation
2+
3+
extension PostServiceRemoteXMLRPC: PostServiceRemoteExtended {
4+
public func patchPost(withID postID: Int, changes: RemotePostUpdateParameters) async throws -> RemotePost {
5+
throw URLError(.unknown, userInfo: [NSLocalizedFailureErrorKey: "Unimplemented"])
6+
}
7+
}

WordPressKit/RemotePost.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern NSString * const PostStatusScheduled;
99
extern NSString * const PostStatusTrash;
1010
extern NSString * const PostStatusDeleted;
1111

12+
/// Represents the response object for APIs that create or update posts.
1213
@interface RemotePost : NSObject
1314
- (id)initWithSiteID:(NSNumber *)siteID status:(NSString *)status title:(NSString *)title content:(NSString *)content;
1415

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Foundation
2+
3+
/// Represents a partial update to be applied to a post.
4+
public struct RemotePostUpdateParameters {
5+
public var ifNotModifiedSince: Date?
6+
7+
public var status: String?
8+
public var date: Date?
9+
public var authorID: Int??
10+
public var title: String??
11+
public var content: String??
12+
public var password: String??
13+
public var excerpt: String??
14+
public var slug: String??
15+
public var featuredImageID: Int??
16+
17+
// Pages
18+
public var parentPageID: Int??
19+
20+
// Posts
21+
public var format: String??
22+
public var tags: [String]?
23+
public var categoryIDs: [Int]?
24+
public var isSticky: Bool?
25+
26+
public init() {}
27+
}

0 commit comments

Comments
 (0)