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

Commit 18653c5

Browse files
committed
Merge branch 'trunk' into refactor-xml-rpc-error-1
2 parents 616150b + 10f03c5 commit 18653c5

15 files changed

+534
-34
lines changed

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,28 @@ _None._
4242

4343
### Bug Fixes
4444

45-
_None._
45+
- Fix a bug in parsing XMLRPC link from a RSD Link. [#671]
4646

4747
### Internal Changes
4848

4949
_None._
5050

51+
## 9.0.3
52+
53+
_Note: This version should have been 9.1.0, because it introduces a new feature._
54+
_However, WordPressAuthenticator currently depends on WordPressKit via `~> 9.0.0` which would result in this version being incompatible._
55+
_In the interest of minimizing changes in the WordPress [24.0](https://github.com/wordpress-mobile/WordPress-iOS/milestone/265) release, we shipped this as 9.0.3 and decided to follow up in WordPressAuthenticator separately._
56+
57+
### New Features
58+
59+
- Add `deviceId` param to `DashboardServiceRemote.fetch` method. [#674]
60+
61+
## 9.0.2
62+
63+
### Bug Fixes
64+
65+
- Improve XML-RPC error messages to suggest contacting the host. [#655]
66+
5167
## 9.0.1
5268

5369
### Internal Changes

WordPressKit.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Pod::Spec.new do |s|
44
s.name = 'WordPressKit'
5-
s.version = '9.0.1'
5+
s.version = '9.0.3'
66

77
s.summary = 'WordPressKit offers a clean and simple WordPress.com and WordPress.org API.'
88
s.description = <<-DESC

WordPressKit.xcodeproj/project.pbxproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
4A05E7A62B34142200C25E3B /* xmlrpc-response-invalid.html in Resources */ = {isa = PBXBuildFile; fileRef = 4A05E7A52B34142200C25E3B /* xmlrpc-response-invalid.html */; };
143143
4A05E7A82B34EAF400C25E3B /* xmlrpc-response-mobile-plugin-redirect.html in Resources */ = {isa = PBXBuildFile; fileRef = 4A05E7A72B34EAF400C25E3B /* xmlrpc-response-mobile-plugin-redirect.html */; };
144144
4A05E7AA2B34FC4300C25E3B /* xmlrpc-response-list-methods.xml in Resources */ = {isa = PBXBuildFile; fileRef = 4A05E7A92B34FC4300C25E3B /* xmlrpc-response-list-methods.xml */; };
145+
4A05E7AC2B35048A00C25E3B /* RSDParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A05E7AB2B35048A00C25E3B /* RSDParserTests.swift */; };
145146
4A11239A2B19269A004690CF /* WordPressAPIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1123992B19269A004690CF /* WordPressAPIError.swift */; };
146147
4A11239C2B1926B7004690CF /* HTTPRequestBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A11239B2B1926B7004690CF /* HTTPRequestBuilder.swift */; };
147148
4A11239E2B1926D1004690CF /* HTTPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A11239D2B1926D1004690CF /* HTTPClient.swift */; };
@@ -160,6 +161,9 @@
160161
4A6B4A862B269D0C00802316 /* URLSessionHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A6B4A852B269D0C00802316 /* URLSessionHelperTests.swift */; };
161162
4AA5A1A32AA68F6B00969464 /* MediaLibraryTestSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA5A1A22AA68F6B00969464 /* MediaLibraryTestSupport.swift */; };
162163
4AA5A1A52AA695D700969464 /* LoadMediaLibraryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AA5A1A42AA695D700969464 /* LoadMediaLibraryTests.swift */; };
164+
4AE278442B2FAF6200E4D9B1 /* HTTPProtocolHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE278432B2FAF6200E4D9B1 /* HTTPProtocolHelpers.swift */; };
165+
4AE278482B2FBF1100E4D9B1 /* HTTPBodyEncodingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE278472B2FBF1100E4D9B1 /* HTTPBodyEncodingTests.swift */; };
166+
4AE2784A2B2FC6C600E4D9B1 /* HTTPHeaderValueParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE278492B2FC6C600E4D9B1 /* HTTPHeaderValueParserTests.swift */; };
163167
57BCD3D426209D9500292CB3 /* AppTransportSecuritySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57BCD3D326209D9500292CB3 /* AppTransportSecuritySettings.swift */; };
164168
730E869F21E44EFD00753E1A /* WordPressComServiceRemote+SiteVerticals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 730E869E21E44EFD00753E1A /* WordPressComServiceRemote+SiteVerticals.swift */; };
165169
731BA83621DECD61000FDFCD /* SiteCreationRequestEncodingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 731BA83521DECD61000FDFCD /* SiteCreationRequestEncodingTests.swift */; };
@@ -615,6 +619,7 @@
615619
F3FF8A25279C960F00E5C90F /* site-email-followers-get-auth-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = F3FF8A24279C960F00E5C90F /* site-email-followers-get-auth-failure.json */; };
616620
F3FF8A27279C967200E5C90F /* site-email-followers-get-failure.json in Resources */ = {isa = PBXBuildFile; fileRef = F3FF8A26279C967200E5C90F /* site-email-followers-get-failure.json */; };
617621
F3FF8A29279C991B00E5C90F /* site-email-followers-get-success-more-pages.json in Resources */ = {isa = PBXBuildFile; fileRef = F3FF8A28279C991B00E5C90F /* site-email-followers-get-success-more-pages.json */; };
622+
F41D98EA2B48602B004EC050 /* SessionDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41D98E92B48602B004EC050 /* SessionDetails.swift */; };
618623
F4B0F4732ACAF498003ABC61 /* DomainsServiceRemote+AllDomains.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4B0F4722ACAF498003ABC61 /* DomainsServiceRemote+AllDomains.swift */; };
619624
F4B0F47C2ACB4B74003ABC61 /* get-all-domains-response.json in Resources */ = {isa = PBXBuildFile; fileRef = F4B0F47B2ACB4B74003ABC61 /* get-all-domains-response.json */; };
620625
F4B0F4802ACB4EA9003ABC61 /* AllDomainsResultDomainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4B0F47F2ACB4EA9003ABC61 /* AllDomainsResultDomainTests.swift */; };
@@ -842,6 +847,7 @@
842847
4A05E7A52B34142200C25E3B /* xmlrpc-response-invalid.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "xmlrpc-response-invalid.html"; sourceTree = "<group>"; };
843848
4A05E7A72B34EAF400C25E3B /* xmlrpc-response-mobile-plugin-redirect.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "xmlrpc-response-mobile-plugin-redirect.html"; sourceTree = "<group>"; };
844849
4A05E7A92B34FC4300C25E3B /* xmlrpc-response-list-methods.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "xmlrpc-response-list-methods.xml"; sourceTree = "<group>"; };
850+
4A05E7AB2B35048A00C25E3B /* RSDParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSDParserTests.swift; sourceTree = "<group>"; };
845851
4A1123992B19269A004690CF /* WordPressAPIError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WordPressAPIError.swift; sourceTree = "<group>"; };
846852
4A11239B2B1926B7004690CF /* HTTPRequestBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPRequestBuilder.swift; sourceTree = "<group>"; };
847853
4A11239D2B1926D1004690CF /* HTTPClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPClient.swift; sourceTree = "<group>"; };
@@ -860,6 +866,9 @@
860866
4A6B4A852B269D0C00802316 /* URLSessionHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionHelperTests.swift; sourceTree = "<group>"; };
861867
4AA5A1A22AA68F6B00969464 /* MediaLibraryTestSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaLibraryTestSupport.swift; sourceTree = "<group>"; };
862868
4AA5A1A42AA695D700969464 /* LoadMediaLibraryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadMediaLibraryTests.swift; sourceTree = "<group>"; };
869+
4AE278432B2FAF6200E4D9B1 /* HTTPProtocolHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPProtocolHelpers.swift; sourceTree = "<group>"; };
870+
4AE278472B2FBF1100E4D9B1 /* HTTPBodyEncodingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPBodyEncodingTests.swift; sourceTree = "<group>"; };
871+
4AE278492B2FC6C600E4D9B1 /* HTTPHeaderValueParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPHeaderValueParserTests.swift; sourceTree = "<group>"; };
863872
57BCD3D326209D9500292CB3 /* AppTransportSecuritySettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTransportSecuritySettings.swift; sourceTree = "<group>"; };
864873
6C2A33D76FD1052D6F30466D /* Pods-WordPressKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressKit/Pods-WordPressKit.debug.xcconfig"; sourceTree = "<group>"; };
865874
6F2E0CC4FA01B5475A378DA2 /* Pods-WordPressKitTests.release-alpha.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressKitTests.release-alpha.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressKitTests/Pods-WordPressKitTests.release-alpha.xcconfig"; sourceTree = "<group>"; };
@@ -1326,6 +1335,7 @@
13261335
F3FF8A24279C960F00E5C90F /* site-email-followers-get-auth-failure.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "site-email-followers-get-auth-failure.json"; sourceTree = "<group>"; };
13271336
F3FF8A26279C967200E5C90F /* site-email-followers-get-failure.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "site-email-followers-get-failure.json"; sourceTree = "<group>"; };
13281337
F3FF8A28279C991B00E5C90F /* site-email-followers-get-success-more-pages.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "site-email-followers-get-success-more-pages.json"; sourceTree = "<group>"; };
1338+
F41D98E92B48602B004EC050 /* SessionDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetails.swift; sourceTree = "<group>"; };
13291339
F4B0F4722ACAF498003ABC61 /* DomainsServiceRemote+AllDomains.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DomainsServiceRemote+AllDomains.swift"; sourceTree = "<group>"; };
13301340
F4B0F47B2ACB4B74003ABC61 /* get-all-domains-response.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "get-all-domains-response.json"; sourceTree = "<group>"; };
13311341
F4B0F47F2ACB4EA9003ABC61 /* AllDomainsResultDomainTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllDomainsResultDomainTests.swift; sourceTree = "<group>"; };
@@ -2105,6 +2115,7 @@
21052115
FEF7419C28085D89002C4203 /* RemoteBloggingPrompt.swift */,
21062116
FE20A6A3282A96C00025E975 /* RemoteBloggingPromptsSettings.swift */,
21072117
1DAC3D2529AF4F250068FE13 /* RemoteVideoPressVideo.swift */,
2118+
F41D98E92B48602B004EC050 /* SessionDetails.swift */,
21082119
);
21092120
name = Models;
21102121
sourceTree = "<group>";
@@ -2458,6 +2469,7 @@
24582469
57BCD3D326209D9500292CB3 /* AppTransportSecuritySettings.swift */,
24592470
465F88A1263B325C00F4C950 /* ChecksumUtil.swift */,
24602471
3F3195AC266FF94B00397EE7 /* ZendeskMetadata.swift */,
2472+
4AE278432B2FAF6200E4D9B1 /* HTTPProtocolHelpers.swift */,
24612473
);
24622474
name = Utility;
24632475
sourceTree = "<group>";
@@ -2650,6 +2662,9 @@
26502662
4A6B4A832B26974F00802316 /* HTTPRequestBuilderTests.swift */,
26512663
4A6B4A852B269D0C00802316 /* URLSessionHelperTests.swift */,
26522664
4A40F6542B2A5A1A0015DA77 /* WordPressAPIErrorTests.swift */,
2665+
4AE278472B2FBF1100E4D9B1 /* HTTPBodyEncodingTests.swift */,
2666+
4AE278492B2FC6C600E4D9B1 /* HTTPHeaderValueParserTests.swift */,
2667+
4A05E7AB2B35048A00C25E3B /* RSDParserTests.swift */,
26532668
);
26542669
path = Utilities;
26552670
sourceTree = "<group>";
@@ -3293,6 +3308,7 @@
32933308
E1BD95151FD5A2B800CD5CE3 /* PluginDirectoryServiceRemote.swift in Sources */,
32943309
7430C9D71F1933210051B8E6 /* RemoteReaderCrossPostMeta.swift in Sources */,
32953310
1DAC3D2629AF4F250068FE13 /* RemoteVideoPressVideo.swift in Sources */,
3311+
4AE278442B2FAF6200E4D9B1 /* HTTPProtocolHelpers.swift in Sources */,
32963312
FA68CD152993C6CD00FA4C29 /* BlazeServiceRemote.swift in Sources */,
32973313
4081976F221DDE9B00A298E4 /* StatsTopPostsTimeIntervalData.swift in Sources */,
32983314
9311A68B1F22625A00704AC9 /* TaxonomyServiceRemoteXMLRPC.m in Sources */,
@@ -3393,6 +3409,7 @@
33933409
82FFBF501F45EFD100F4573F /* RemoteBlogJetpackSettings.swift in Sources */,
33943410
74650F741F0EA1E200188EDB /* RemoteGravatarProfile.swift in Sources */,
33953411
40E7FEB4221063480032834E /* StatsTodayInsight.swift in Sources */,
3412+
F41D98EA2B48602B004EC050 /* SessionDetails.swift in Sources */,
33963413
436D563C2118E18D00CEAA33 /* WPState.swift in Sources */,
33973414
439A44DA2107C93000795ED7 /* RemotePlan_ApiVersion1_3.swift in Sources */,
33983415
93BD27811EE73944002BB00B /* WordPressOrgXMLRPCApi.swift in Sources */,
@@ -3450,6 +3467,7 @@
34503467
isa = PBXSourcesBuildPhase;
34513468
buildActionMask = 2147483647;
34523469
files = (
3470+
4AE2784A2B2FC6C600E4D9B1 /* HTTPHeaderValueParserTests.swift in Sources */,
34533471
E1E89C6A1FD6BDB1006E7A33 /* PluginDirectoryTests.swift in Sources */,
34543472
4A6B4A862B269D0C00802316 /* URLSessionHelperTests.swift in Sources */,
34553473
9F3E0BAA20873773009CB5BA /* MockServiceRequest.swift in Sources */,
@@ -3547,6 +3565,7 @@
35473565
FE5096522A13938500DDD071 /* SharingServiceRemoteTests.swift in Sources */,
35483566
FFA4D4AA2423B10A00BF5180 /* WordPressOrgRestApiTests.swift in Sources */,
35493567
74A44DD51F13C6D8006CD8F4 /* PushAuthenticationServiceRemoteTests.swift in Sources */,
3568+
4AE278482B2FBF1100E4D9B1 /* HTTPBodyEncodingTests.swift in Sources */,
35503569
731BA83621DECD61000FDFCD /* SiteCreationRequestEncodingTests.swift in Sources */,
35513570
7EC60EBE22DC4F9000FB0336 /* EditorServiceRemoteTests.swift in Sources */,
35523571
931924241F1662FA0069CBCC /* JSONLoader.swift in Sources */,
@@ -3555,6 +3574,7 @@
35553574
FA1D0F8E299534FF0025D76C /* BlazeServiceRemoteTests.swift in Sources */,
35563575
740B23D21F17F6BB00067A2A /* PostServiceRemoteRESTTests.m in Sources */,
35573576
F9E56DFB24EB18C300916770 /* FeatureFlagRemoteTests.swift in Sources */,
3577+
4A05E7AC2B35048A00C25E3B /* RSDParserTests.swift in Sources */,
35583578
46ABD0E0262EED3D00C7FF24 /* WordPressOrgXMLRPCValidatorTests.swift in Sources */,
35593579
D813437621F6D70D0060D99A /* SiteSegmentsResponseDecodingTests.swift in Sources */,
35603580
8B9F0CAE2762414F00DBE144 /* WordPressComRestApiTests+AsyncAwait.swift in Sources */,

WordPressKit/DashboardServiceRemote.swift

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import Foundation
22

33
open class DashboardServiceRemote: ServiceRemoteWordPressComREST {
4-
open func fetch(cards: [String], forBlogID blogID: Int, success: @escaping (NSDictionary) -> Void, failure: @escaping (Error) -> Void) {
5-
guard let requestUrl = endpoint(for: cards, blogID: blogID) else {
6-
return
4+
open func fetch(
5+
cards: [String],
6+
forBlogID blogID: Int,
7+
deviceId: String? = nil,
8+
success: @escaping (NSDictionary) -> Void,
9+
failure: @escaping (Error) -> Void
10+
) {
11+
let requestUrl = self.path(forEndpoint: "sites/\(blogID)/dashboard/cards-data/", withVersion: ._2_0)
12+
var params: [String: AnyObject]?
13+
14+
do {
15+
params = try self.makeQueryParams(cards: cards, deviceId: deviceId)
16+
} catch {
17+
failure(error)
718
}
819

920
wordPressComRestApi.GET(requestUrl,
10-
parameters: nil,
21+
parameters: params,
1122
success: { response, _ in
1223
guard let cards = response as? NSDictionary else {
1324
failure(ResponseError.decodingFailure)
@@ -21,17 +32,19 @@ open class DashboardServiceRemote: ServiceRemoteWordPressComREST {
2132
})
2233
}
2334

24-
private func endpoint(for cards: [String], blogID: Int) -> String? {
25-
var path = URLComponents(string: "sites/\(blogID)/dashboard/cards-data/")
26-
27-
let cardsEncoded = cards.joined(separator: ",")
28-
path?.queryItems = [URLQueryItem(name: "cards", value: cardsEncoded)]
29-
30-
guard let endpoint = path?.string else {
31-
return nil
35+
private func makeQueryParams(cards: [String], deviceId: String?) throws -> [String: AnyObject] {
36+
let cardsParams: [String: AnyObject] = [
37+
"cards": cards.joined(separator: ",") as NSString
38+
]
39+
let featureFlagParams: [String: AnyObject]? = try {
40+
guard let deviceId else {
41+
return nil
42+
}
43+
return try SessionDetails(deviceId: deviceId).dictionaryRepresentation()
44+
}()
45+
return cardsParams.merging(featureFlagParams ?? [:]) { first, second in
46+
return first
3247
}
33-
34-
return self.path(forEndpoint: endpoint, withVersion: ._2_0)
3548
}
3649

3750
enum ResponseError: Error {

WordPressKit/FeatureFlagRemote.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ open class FeatureFlagRemote: ServiceRemoteWordPressComREST {
99
}
1010

1111
open func getRemoteFeatureFlags(forDeviceId deviceId: String, callback: @escaping FeatureFlagResponseCallback) {
12-
12+
let params = SessionDetails(deviceId: deviceId)
1313
let endpoint = "mobile/feature-flags"
1414
let path = self.path(forEndpoint: endpoint, withVersion: ._2_0)
15+
var dictionary: [String: AnyObject]?
1516

16-
let parameters: [String: AnyObject] = [
17-
"device_id": deviceId as NSString,
18-
"platform": "ios" as NSString,
19-
"build_number": NSString(string: Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "Unknown"),
20-
"marketing_version": NSString(string: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown"),
21-
"identifier": NSString(string: Bundle.main.bundleIdentifier ?? "Unknown")
22-
]
17+
do {
18+
dictionary = try params.dictionaryRepresentation()
19+
} catch let error {
20+
callback(.failure(error))
21+
return
22+
}
2323

2424
wordPressComRestApi.GET(path,
25-
parameters: parameters,
25+
parameters: dictionary,
2626
success: { response, _ in
2727

2828
if let featureFlagList = response as? NSDictionary {

WordPressKit/HTTPClient.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ struct HTTPAPIResponse<Body> {
77
var body: Body
88
}
99

10+
extension HTTPAPIResponse where Body == Data {
11+
var bodyText: String? {
12+
var encoding: String.Encoding?
13+
if let charset = response.textEncodingName {
14+
encoding = String.Encoding(ianaCharsetName: charset)
15+
}
16+
17+
let defaultEncoding = String.Encoding.isoLatin1
18+
return String(data: body, encoding: encoding ?? defaultEncoding)
19+
}
20+
}
21+
1022
extension URLSession {
1123

1224
func perform<E: LocalizedError>(

0 commit comments

Comments
 (0)