From 8fb7ca25726926a8695be3ec8119cb3f088874cb Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sat, 13 Apr 2024 09:17:15 +1000 Subject: [PATCH 1/7] Make `WordPressComRestApiError` `CaseIterable` --- Sources/CoreAPI/WordPressOrgXMLRPCApi.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift index 2698c89f..a12e2538 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift @@ -290,7 +290,7 @@ private class SessionDelegate: NSObject, URLSessionDelegate { } /// Error constants for the WordPress XML-RPC API -@objc public enum WordPressOrgXMLRPCApiError: Int, Error { +@objc public enum WordPressOrgXMLRPCApiError: Int, Error, CaseIterable { /// An error HTTP status code was returned. case httpErrorStatusCode /// The serialization of the request failed. @@ -428,5 +428,4 @@ private extension WordPressAPIError where EndpointError == WordPressOrgXMLRPCApi return WordPressOrgXMLRPCApi.convertError(error, data: data, statusCode: statusCode) } - } From 0d08c55a94576493b3165629b81bdee6f58d258d Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sun, 14 Apr 2024 07:29:19 +1000 Subject: [PATCH 2/7] Make `WordPressOrgXMLRPCApiError` conform to `CustomNSError` This ensures that the error domain is the same between SPM and Framework/CocoaPods builds. --- Sources/CoreAPI/WordPressOrgXMLRPCApi.swift | 2 +- ...PressOrgXMLRPCApiError+NSErrorBridge.swift | 9 ++++++ .../WordPressOrgXMLRPCApiErrorDomain.swift | 28 +++++++++++++++++++ .../WordPressComRestApiTests+Error.swift | 1 - .../WordPressOrgXMLRPCApiErrorTests.swift | 24 ++++++++++++++++ .../WordPressOrgXMLRPCApiTests.swift | 15 ---------- WordPressKit.xcodeproj/project.pbxproj | 12 ++++++++ 7 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift create mode 100644 Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift create mode 100644 Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift index a12e2538..ebbd2c3d 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift @@ -391,7 +391,7 @@ private extension WordPressAPIError where EndpointError == WordPressOrgXMLRPCApi /// Convert to NSError for backwards compatiblity. /// /// Some Objective-C code in the WordPress app checks domain of the errors returned by `WordPressOrgXMLRPCApi`, - /// which can be WordPressOrgXMLRPCApiError or WPXMLRPCFaultErrorDomain. + /// which can be `WordPressOrgXMLRPCApiError` or `WPXMLRPCFaultErrorDomain`. /// /// Swift code should avoid dealing with NSError instances. Instead, they should use the strongly typed /// `WordPressAPIError`. diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift new file mode 100644 index 00000000..55661d56 --- /dev/null +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift @@ -0,0 +1,9 @@ +/// See `extension WordPressComRestApiEndpointError: CustomNSError` for documentation and rationale. +extension WordPressOrgXMLRPCApiError: CustomNSError { + + public static let errorDomain = WordPressOrgXMLRPCApiErrorDomain + + public var errorCode: Int { self.rawValue } + + public var errorUserInfo: [String: Any] { [:] } +} diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift new file mode 100644 index 00000000..b04cf038 --- /dev/null +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift @@ -0,0 +1,28 @@ +/// Error domain of `NSError` instances that are converted from `WordPressOrgXMLRPCApiError` +/// and `WordPressAPIError` instances. +/// +/// See `extension WordPressOrgXMLRPCApiError: CustomNSError` for context. +let WordPressOrgXMLRPCApiErrorDomain = "WordPressKit.WordPressOrgXMLRPCApiError" + +// WordPressOrgXMLRPCApiErrorDomain is accessible only in Swift and, since it's a global, cannot be made @objc. +// As a workaround, here is a builder to init NSError with that domain and a method to check the domain. +@objc +public extension NSError { + + @objc + static func wordPressOrgXMLRPCApiError( + code: Int, + userInfo: [String: Any]? + ) -> NSError { + NSError( + domain: WordPressOrgXMLRPCApiErrorDomain, + code: code, + userInfo: userInfo + ) + } + + @objc + func hasWordPressOrgXMLRPCApiErrorDomain() -> Bool { + domain == WordPressOrgXMLRPCApiErrorDomain + } +} diff --git a/Tests/CoreAPITests/WordPressComRestApiTests+Error.swift b/Tests/CoreAPITests/WordPressComRestApiTests+Error.swift index f122bbec..fdb5a2e0 100644 --- a/Tests/CoreAPITests/WordPressComRestApiTests+Error.swift +++ b/Tests/CoreAPITests/WordPressComRestApiTests+Error.swift @@ -21,5 +21,4 @@ class WordPressComRestApiErrorTests: XCTestCase { func testErrorDomain() { XCTAssertEqual(WordPressComRestApiErrorDomain, WordPressComRestApiEndpointError.errorDomain) } - } diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift new file mode 100644 index 00000000..cc697ae3 --- /dev/null +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift @@ -0,0 +1,24 @@ +#if SWIFT_PACKAGE +@testable import CoreAPI +#else +@testable import WordPressKit +#endif +import XCTest + +class WordPressOrgXMLRPCApiErrorTests: XCTestCase { + + func testNSErrorBridging() throws { + for error in WordPressOrgXMLRPCApiError.allCases { + let xmlRPCError = try XCTUnwrap(WordPressOrgXMLRPCApiError(rawValue: error.rawValue)) + let apiError = WordPressAPIError.endpointError(xmlRPCError) + let newNSError = apiError as NSError + + XCTAssertEqual(newNSError.domain, "WordPressKit.WordPressOrgXMLRPCApiError") + XCTAssertEqual(newNSError.code, error.rawValue) + } + } + + func testErrorDomain() { + XCTAssertEqual(WordPressOrgXMLRPCApiErrorDomain, WordPressOrgXMLRPCApiError.errorDomain) + } +} diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift index b198c5d0..6693223e 100644 --- a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift @@ -63,12 +63,7 @@ class WordPressOrgXMLRPCApiTests: XCTestCase { }, failure: { (error, _) in expect.fulfill() - // When building for SPM, the compiler doesn't generate the domain constant. -#if SWIFT_PACKAGE - XCTAssertEqual(error.domain, "CoreAPI.WordPressOrgXMLRPCApiError") -#else XCTAssertEqual(error.domain, WordPressOrgXMLRPCApiErrorDomain) -#endif XCTAssertEqual(error.code, WordPressOrgXMLRPCApiError.httpErrorStatusCode.rawValue) XCTAssertEqual(error.localizedFailureReason, "An HTTP error code 404 was returned.") XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyData as String]) @@ -96,12 +91,7 @@ class WordPressOrgXMLRPCApiTests: XCTestCase { expect.fulfill() XCTAssertFalse(error is WordPressOrgXMLRPCApiError) - // When building for SPM, the compiler doesn't generate the domain constant. -#if SWIFT_PACKAGE - XCTAssertEqual(error.domain, "CoreAPI.WordPressOrgXMLRPCApiError") -#else XCTAssertEqual(error.domain, WordPressOrgXMLRPCApiErrorDomain) -#endif XCTAssertEqual(error.code, 403) XCTAssertEqual(error.localizedFailureReason, "An HTTP error code 403 was returned.") XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyData as String]) @@ -129,12 +119,7 @@ class WordPressOrgXMLRPCApiTests: XCTestCase { expect.fulfill() XCTAssertTrue(error is WordPressOrgXMLRPCApiError) - // When building for SPM, the compiler doesn't generate the domain constant. -#if SWIFT_PACKAGE - XCTAssertEqual(error.domain, "CoreAPI.WordPressOrgXMLRPCApiError") -#else XCTAssertEqual(error.domain, WordPressOrgXMLRPCApiErrorDomain) -#endif XCTAssertEqual(error.code, WordPressOrgXMLRPCApiError.unknown.rawValue) XCTAssertEqual(error.localizedFailureReason, WordPressOrgXMLRPCApiError.unknown.failureReason) XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyData as String]) diff --git a/WordPressKit.xcodeproj/project.pbxproj b/WordPressKit.xcodeproj/project.pbxproj index 6b7eca31..2f229071 100644 --- a/WordPressKit.xcodeproj/project.pbxproj +++ b/WordPressKit.xcodeproj/project.pbxproj @@ -64,6 +64,9 @@ 32FC20CE255DCC6100CD0A7B /* JetpackScanThreat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32FC20CD255DCC6100CD0A7B /* JetpackScanThreat.swift */; }; 3F3195AD266FF94B00397EE7 /* ZendeskMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3195AC266FF94B00397EE7 /* ZendeskMetadata.swift */; }; 3F3C9E9C289A3E31009A1357 /* TestCollector+Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3C9E9B289A3E31009A1357 /* TestCollector+Constants.swift */; }; + 3F6128112BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6128102BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift */; }; + 3F6128132BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6128122BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift */; }; + 3F6128162BCB320B0063810D /* WordPressOrgXMLRPCApiErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6128142BCB31DB0063810D /* WordPressOrgXMLRPCApiErrorTests.swift */; }; 3F758FD324F6C68200BBA2FC /* AnnouncementServiceRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F758FD224F6C68200BBA2FC /* AnnouncementServiceRemote.swift */; }; 3F8308A729EE683500354497 /* ActivityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8308A629EE683500354497 /* ActivityTests.swift */; }; 3FA4258F2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FA4258E2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -812,6 +815,9 @@ 32FC20CD255DCC6100CD0A7B /* JetpackScanThreat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JetpackScanThreat.swift; sourceTree = ""; }; 3F3195AC266FF94B00397EE7 /* ZendeskMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZendeskMetadata.swift; sourceTree = ""; }; 3F3C9E9B289A3E31009A1357 /* TestCollector+Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TestCollector+Constants.swift"; sourceTree = ""; }; + 3F6128102BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressOrgXMLRPCApiErrorDomain.swift; sourceTree = ""; }; + 3F6128122BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WordPressOrgXMLRPCApiError+NSErrorBridge.swift"; sourceTree = ""; }; + 3F6128142BCB31DB0063810D /* WordPressOrgXMLRPCApiErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressOrgXMLRPCApiErrorTests.swift; sourceTree = ""; }; 3F758FD224F6C68200BBA2FC /* AnnouncementServiceRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementServiceRemote.swift; sourceTree = ""; }; 3F8308A629EE683500354497 /* ActivityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityTests.swift; sourceTree = ""; }; 3FA4258E2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WordPressComRestApiErrorDomain.h; sourceTree = ""; }; @@ -1580,6 +1586,7 @@ 4A05E79B2B2FDC6100C25E3B /* WordPressOrgAPITests.swift */, FFA4D4A82423B10A00BF5180 /* WordPressOrgRestApiTests.swift */, 74B335DB1F06F4180053A184 /* WordPressOrgXMLRPCApiTests.swift */, + 3F6128142BCB31DB0063810D /* WordPressOrgXMLRPCApiErrorTests.swift */, 46ABD0DF262EED3D00C7FF24 /* WordPressOrgXMLRPCValidatorTests.swift */, ); path = CoreAPITests; @@ -2135,6 +2142,8 @@ 3FE2E97A2BC3A332002CA2E1 /* WordPressComRestApi.swift */, 4A05E7992B2FDC3200C25E3B /* WordPressOrgRestApi.swift */, 93BD27791EE73944002BB00B /* WordPressOrgXMLRPCApi.swift */, + 3F6128102BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift */, + 3F6128122BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift */, 3FD634E32BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift */, 93BD277B1EE73944002BB00B /* WordPressRSDParser.swift */, ); @@ -3381,6 +3390,7 @@ 74BA04F61F06DC0A00ED5CD8 /* CommentServiceRemoteXMLRPC.m in Sources */, 40819778221F00E600A298E4 /* StatsSummaryTimeIntervalData.swift in Sources */, 7430C9A81F1927180051B8E6 /* ReaderTopicServiceRemote.m in Sources */, + 3F6128132BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift in Sources */, 17CE77F120C6EB41001DEA5A /* ReaderFeed.swift in Sources */, 93C674F21EE8351E00BFAF05 /* NSMutableDictionary+Helpers.m in Sources */, 4624222D2548BA0F002B8A12 /* RemoteSiteDesign.swift in Sources */, @@ -3389,6 +3399,7 @@ 740B23C31F17EE8000067A2A /* RemotePostCategory.m in Sources */, 8B2F4BF124ACE3C30056C08A /* RemoteReaderInterest.swift in Sources */, 74B5F0E71EF8699C00B411E7 /* RemotePostType.m in Sources */, + 3F6128112BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift in Sources */, 93188D1F1F2262BF0028ED4D /* RemotePostTag.m in Sources */, 3FD634F72BC3AD6200CEDF5E /* WebauthChallengeInfo.swift in Sources */, 74D67F081F15BEB70010C5ED /* RemotePerson.swift in Sources */, @@ -3516,6 +3527,7 @@ 1DC837C229B9F04F009DCD4B /* RemoteVideoPressVideoTests.swift in Sources */, 3FFCC04D2BABA6980051D229 /* NSDate+WordPressComTests.swift in Sources */, FAD1345125909DEA00A8FEB1 /* JetpackBackupServiceRemoteTests.swift in Sources */, + 3F6128162BCB320B0063810D /* WordPressOrgXMLRPCApiErrorTests.swift in Sources */, 8B2F4BE924ABC9DC0056C08A /* ReaderPostServiceRemote+CardsTests.swift in Sources */, FEF87FEF2BB7343700A1D2C1 /* ReaderTopicServiceRemoteTests.swift in Sources */, 40F9880C221ACEEE00B7B369 /* StatsRemoteV2Tests.swift in Sources */, From eeb26d837f5fcbf544bb144be92be28f5942af9c Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sun, 14 Apr 2024 07:45:49 +1000 Subject: [PATCH 3/7] Import Foundation in `WordPressOrgXMLRPCApiError*` files for SPM builds --- Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift | 2 ++ Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift index 55661d56..312e9361 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift @@ -1,3 +1,5 @@ +import Foundation + /// See `extension WordPressComRestApiEndpointError: CustomNSError` for documentation and rationale. extension WordPressOrgXMLRPCApiError: CustomNSError { diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift index b04cf038..5fc4d838 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift @@ -1,3 +1,5 @@ +import Foundation + /// Error domain of `NSError` instances that are converted from `WordPressOrgXMLRPCApiError` /// and `WordPressAPIError` instances. /// From 277f0cab7f0cb581eada2326a07694336af44353 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 17 Apr 2024 13:54:25 +1000 Subject: [PATCH 4/7] Move `WordPressOrgXMLRPCApiErrorDomain` definition to APIInterface --- .../WordPressOrgXMLRPCApiErrorDomain.h | 9 ++++++ ...PressOrgXMLRPCApiError+NSErrorBridge.swift | 3 ++ .../WordPressOrgXMLRPCApiErrorDomain.swift | 30 ------------------- Sources/WordPressKit/WordPressKit.h | 1 + .../WordPressOrgXMLRPCApiErrorTests.swift | 1 + .../WordPressOrgXMLRPCApiTests.swift | 1 + WordPressKit.xcodeproj/project.pbxproj | 8 ++--- 7 files changed, 19 insertions(+), 34 deletions(-) create mode 100644 Sources/APIInterface/include/WordPressOrgXMLRPCApiErrorDomain.h delete mode 100644 Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift diff --git a/Sources/APIInterface/include/WordPressOrgXMLRPCApiErrorDomain.h b/Sources/APIInterface/include/WordPressOrgXMLRPCApiErrorDomain.h new file mode 100644 index 00000000..1b33b7d7 --- /dev/null +++ b/Sources/APIInterface/include/WordPressOrgXMLRPCApiErrorDomain.h @@ -0,0 +1,9 @@ +#import + +/// Error domain of `NSError` instances that are converted from `WordPressOrgXMLRPCApiError` +/// and `WordPressAPIError` instances. +/// +/// This matches the compiler generated value and is used to ensure consistent error domain across error types and SPM or Framework build modes. +/// +/// See `extension WordPressComRestApiEndpointError: CustomNSError` in CoreAPI package for context. +static NSString *const _Nonnull WordPressOrgXMLRPCApiErrorDomain = @"WordPressKit.WordPressOrgXMLRPCApiError"; diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift index 312e9361..e8bcacac 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift @@ -1,4 +1,7 @@ import Foundation +#if SWIFT_PACKAGE +import APIInterface +#endif /// See `extension WordPressComRestApiEndpointError: CustomNSError` for documentation and rationale. extension WordPressOrgXMLRPCApiError: CustomNSError { diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift deleted file mode 100644 index 5fc4d838..00000000 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApiErrorDomain.swift +++ /dev/null @@ -1,30 +0,0 @@ -import Foundation - -/// Error domain of `NSError` instances that are converted from `WordPressOrgXMLRPCApiError` -/// and `WordPressAPIError` instances. -/// -/// See `extension WordPressOrgXMLRPCApiError: CustomNSError` for context. -let WordPressOrgXMLRPCApiErrorDomain = "WordPressKit.WordPressOrgXMLRPCApiError" - -// WordPressOrgXMLRPCApiErrorDomain is accessible only in Swift and, since it's a global, cannot be made @objc. -// As a workaround, here is a builder to init NSError with that domain and a method to check the domain. -@objc -public extension NSError { - - @objc - static func wordPressOrgXMLRPCApiError( - code: Int, - userInfo: [String: Any]? - ) -> NSError { - NSError( - domain: WordPressOrgXMLRPCApiErrorDomain, - code: code, - userInfo: userInfo - ) - } - - @objc - func hasWordPressOrgXMLRPCApiErrorDomain() -> Bool { - domain == WordPressOrgXMLRPCApiErrorDomain - } -} diff --git a/Sources/WordPressKit/WordPressKit.h b/Sources/WordPressKit/WordPressKit.h index 482fdb30..35b8b22b 100644 --- a/Sources/WordPressKit/WordPressKit.h +++ b/Sources/WordPressKit/WordPressKit.h @@ -11,6 +11,7 @@ FOUNDATION_EXPORT const unsigned char WordPressKitVersionString[]; #import #import #import +#import #import #import diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift index cc697ae3..6b986578 100644 --- a/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift @@ -1,4 +1,5 @@ #if SWIFT_PACKAGE +import APIInterface @testable import CoreAPI #else @testable import WordPressKit diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift index 6693223e..635d2f43 100644 --- a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift @@ -2,6 +2,7 @@ import XCTest import OHHTTPStubs import wpxmlrpc #if SWIFT_PACKAGE +import APIInterface @testable import CoreAPI import OHHTTPStubsSwift #else diff --git a/WordPressKit.xcodeproj/project.pbxproj b/WordPressKit.xcodeproj/project.pbxproj index 2f229071..d9309a73 100644 --- a/WordPressKit.xcodeproj/project.pbxproj +++ b/WordPressKit.xcodeproj/project.pbxproj @@ -64,12 +64,12 @@ 32FC20CE255DCC6100CD0A7B /* JetpackScanThreat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32FC20CD255DCC6100CD0A7B /* JetpackScanThreat.swift */; }; 3F3195AD266FF94B00397EE7 /* ZendeskMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3195AC266FF94B00397EE7 /* ZendeskMetadata.swift */; }; 3F3C9E9C289A3E31009A1357 /* TestCollector+Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3C9E9B289A3E31009A1357 /* TestCollector+Constants.swift */; }; - 3F6128112BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6128102BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift */; }; 3F6128132BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6128122BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift */; }; 3F6128162BCB320B0063810D /* WordPressOrgXMLRPCApiErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6128142BCB31DB0063810D /* WordPressOrgXMLRPCApiErrorTests.swift */; }; 3F758FD324F6C68200BBA2FC /* AnnouncementServiceRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F758FD224F6C68200BBA2FC /* AnnouncementServiceRemote.swift */; }; 3F8308A729EE683500354497 /* ActivityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8308A629EE683500354497 /* ActivityTests.swift */; }; 3FA4258F2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FA4258E2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3FA425A72BCF7EDC007539BF /* WordPressOrgXMLRPCApiErrorDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FA425A62BCF7E7C007539BF /* WordPressOrgXMLRPCApiErrorDomain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3FB8642C2888089F003A86BE /* BuildkiteTestCollector in Frameworks */ = {isa = PBXBuildFile; productRef = 3FB8642B2888089F003A86BE /* BuildkiteTestCollector */; }; 3FD634E52BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD634E32BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift */; }; 3FD634E62BC3A55F00CEDF5E /* Date+WordPressCom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD634E42BC3A55F00CEDF5E /* Date+WordPressCom.swift */; }; @@ -815,12 +815,12 @@ 32FC20CD255DCC6100CD0A7B /* JetpackScanThreat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JetpackScanThreat.swift; sourceTree = ""; }; 3F3195AC266FF94B00397EE7 /* ZendeskMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZendeskMetadata.swift; sourceTree = ""; }; 3F3C9E9B289A3E31009A1357 /* TestCollector+Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TestCollector+Constants.swift"; sourceTree = ""; }; - 3F6128102BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressOrgXMLRPCApiErrorDomain.swift; sourceTree = ""; }; 3F6128122BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WordPressOrgXMLRPCApiError+NSErrorBridge.swift"; sourceTree = ""; }; 3F6128142BCB31DB0063810D /* WordPressOrgXMLRPCApiErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressOrgXMLRPCApiErrorTests.swift; sourceTree = ""; }; 3F758FD224F6C68200BBA2FC /* AnnouncementServiceRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementServiceRemote.swift; sourceTree = ""; }; 3F8308A629EE683500354497 /* ActivityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityTests.swift; sourceTree = ""; }; 3FA4258E2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WordPressComRestApiErrorDomain.h; sourceTree = ""; }; + 3FA425A62BCF7E7C007539BF /* WordPressOrgXMLRPCApiErrorDomain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WordPressOrgXMLRPCApiErrorDomain.h; sourceTree = ""; }; 3FB8642D288813E9003A86BE /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; 3FD634E32BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WordPressOrgXMLRPCValidator.swift; sourceTree = ""; }; 3FD634E42BC3A55F00CEDF5E /* Date+WordPressCom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+WordPressCom.swift"; sourceTree = ""; }; @@ -2102,6 +2102,7 @@ children = ( 3FE2E94E2BB29A1B002CA2E1 /* FilePart.h */, 3FA4258E2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h */, + 3FA425A62BCF7E7C007539BF /* WordPressOrgXMLRPCApiErrorDomain.h */, 3FFCC0552BABC78B0051D229 /* WordPressComRESTAPIInterfacing.h */, 3FE2E9662BBEB8D2002CA2E1 /* WordPressComRESTAPIVersion.h */, 3FD635032BC3F03200CEDF5E /* WordPressComRESTAPIVersionedPathBuilder.h */, @@ -2142,7 +2143,6 @@ 3FE2E97A2BC3A332002CA2E1 /* WordPressComRestApi.swift */, 4A05E7992B2FDC3200C25E3B /* WordPressOrgRestApi.swift */, 93BD27791EE73944002BB00B /* WordPressOrgXMLRPCApi.swift */, - 3F6128102BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift */, 3F6128122BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift */, 3FD634E32BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift */, 93BD277B1EE73944002BB00B /* WordPressRSDParser.swift */, @@ -2725,6 +2725,7 @@ 9311A6881F22625A00704AC9 /* TaxonomyServiceRemoteREST.h in Headers */, 93188D1E1F2262BF0028ED4D /* RemotePostTag.h in Headers */, 9311A6871F22625A00704AC9 /* TaxonomyServiceRemote.h in Headers */, + 3FA425A72BCF7EDC007539BF /* WordPressOrgXMLRPCApiErrorDomain.h in Headers */, 9309994D1F1657C600F006A1 /* ThemeServiceRemote.h in Headers */, B5969E1C20A49AC4005E9DF1 /* NSString+MD5.h in Headers */, 740B23C41F17EE8000067A2A /* RemotePost.h in Headers */, @@ -3399,7 +3400,6 @@ 740B23C31F17EE8000067A2A /* RemotePostCategory.m in Sources */, 8B2F4BF124ACE3C30056C08A /* RemoteReaderInterest.swift in Sources */, 74B5F0E71EF8699C00B411E7 /* RemotePostType.m in Sources */, - 3F6128112BCB310F0063810D /* WordPressOrgXMLRPCApiErrorDomain.swift in Sources */, 93188D1F1F2262BF0028ED4D /* RemotePostTag.m in Sources */, 3FD634F72BC3AD6200CEDF5E /* WebauthChallengeInfo.swift in Sources */, 74D67F081F15BEB70010C5ED /* RemotePerson.swift in Sources */, From f6f0c1ca6d1840e483948ce68dd1c9679c91a8d5 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 17 Apr 2024 14:10:25 +1000 Subject: [PATCH 5/7] Add workaround to avoid `WordPressOrgXMLRPCApiErrorDomain` redefinition --- Sources/CoreAPI/WordPressOrgXMLRPCApi.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift index ebbd2c3d..c84cb2b9 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift @@ -289,8 +289,13 @@ private class SessionDelegate: NSObject, URLSessionDelegate { } } +// Hack to avoid the Swift compiler generating a domain constant for us that would then conflict with the one we define in APIInterface. +// The automatic generation occurs, as far as I can tell, because of @objc and Error, neither of which we can remove. +// Reminder: We define our own constant for the domain so that we can conform WordPressOrgXMLRPCApiError to CustomNSError. +typealias WordPressOrgXMLRPCApiError = WordPressOrgXMLRPCAPIError + /// Error constants for the WordPress XML-RPC API -@objc public enum WordPressOrgXMLRPCApiError: Int, Error, CaseIterable { +@objc public enum WordPressOrgXMLRPCAPIError: Int, Error, CaseIterable { /// An error HTTP status code was returned. case httpErrorStatusCode /// The serialization of the request failed. From ac15e9aa016f09a26074d5811407f755ba3ce762 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 17 Apr 2024 16:25:05 +1000 Subject: [PATCH 6/7] Wrap .org XML RPC error `enum` in an `Error`-conforming `struct` Jumping through this hoop was necessary to avoid the Swift compiler automatically generating an error domain for the `Error` and making it impossible to successfully redefine the domain at the `CustomNSError` conformance site. --- CHANGELOG.md | 18 ++++++ Sources/CoreAPI/WordPressOrgXMLRPCApi.swift | 55 +++++-------------- ...PressOrgXMLRPCApiError+NSErrorBridge.swift | 2 +- .../CoreAPI/WordPressOrgXMLRPCApiError.swift | 39 +++++++++++++ .../WordPressOrgXMLRPCApiErrorTests.swift | 4 +- .../WordPressOrgXMLRPCApiTests.swift | 8 +-- WordPressKit.xcodeproj/project.pbxproj | 4 ++ 7 files changed, 83 insertions(+), 47 deletions(-) create mode 100644 Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index dbc43ab7..62319223 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,24 @@ _None._ --> +## Unreleased + +### Breaking Changes + +- The Objective-C-visible `WordPressOrgXMLRPCError` `enum` has been renamed to `WordPressOrgXMLRPCErrorCode` [#790] + +### New Features + +_None._ + +### Bug Fixes + +_None._ + +### Internal Changes + +_None._ + ## 17.0.0 ### Breaking Changes diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift index c84cb2b9..c43e0c76 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApi.swift @@ -288,43 +288,6 @@ private class SessionDelegate: NSObject, URLSessionDelegate { } } } - -// Hack to avoid the Swift compiler generating a domain constant for us that would then conflict with the one we define in APIInterface. -// The automatic generation occurs, as far as I can tell, because of @objc and Error, neither of which we can remove. -// Reminder: We define our own constant for the domain so that we can conform WordPressOrgXMLRPCApiError to CustomNSError. -typealias WordPressOrgXMLRPCApiError = WordPressOrgXMLRPCAPIError - -/// Error constants for the WordPress XML-RPC API -@objc public enum WordPressOrgXMLRPCAPIError: Int, Error, CaseIterable { - /// An error HTTP status code was returned. - case httpErrorStatusCode - /// The serialization of the request failed. - case requestSerializationFailed - /// The serialization of the response failed. - case responseSerializationFailed - /// An unknown error occurred. - case unknown -} - -extension WordPressOrgXMLRPCApiError: LocalizedError { - public var errorDescription: String? { - return NSLocalizedString("There was a problem communicating with the site.", comment: "A general error message shown to the user when there was an API communication failure.") - } - - public var failureReason: String? { - switch self { - case .httpErrorStatusCode: - return NSLocalizedString("An HTTP error code was returned.", comment: "A failure reason for when an error HTTP status code was returned from the site.") - case .requestSerializationFailed: - return NSLocalizedString("The serialization of the request failed.", comment: "A failure reason for when the request couldn't be serialized.") - case .responseSerializationFailed: - return NSLocalizedString("The serialization of the response failed.", comment: "A failure reason for when the response couldn't be serialized.") - case .unknown: - return NSLocalizedString("An unknown error occurred.", comment: "A failure reason for when the error that occured wasn't able to be determined.") - } - } -} - public struct WordPressOrgXMLRPCApiFault: LocalizedError, HTTPURLResponseProviding { public var response: HTTPAPIResponse public let code: Int? @@ -352,7 +315,13 @@ private extension WordPressAPIResult, WordPressOrgXMLRPCAp // https://github.com/wordpress-mobile/WordPressKit-iOS/blob/11.0.0/WordPressKit/WordPressOrgXMLRPCApi.swift#L265 flatMap { response in guard let contentType = response.response.allHeaderFields["Content-Type"] as? String else { - return .failure(.unparsableResponse(response: response.response, body: response.body, underlyingError: WordPressOrgXMLRPCApiError.unknown)) + return .failure( + .unparsableResponse( + response: response.response, + body: response.body, + underlyingError: WordPressOrgXMLRPCApiError(code: .unknown) + ) + ) } if (400..<600).contains(response.response.statusCode) { @@ -366,7 +335,13 @@ private extension WordPressAPIResult, WordPressOrgXMLRPCAp } guard contentType.hasPrefix("application/xml") || contentType.hasPrefix("text/xml") else { - return .failure(.unparsableResponse(response: response.response, body: response.body, underlyingError: WordPressOrgXMLRPCApiError.unknown)) + return .failure( + .unparsableResponse( + response: response.response, + body: response.body, + underlyingError: WordPressOrgXMLRPCApiError(code: .unknown) + ) + ) } guard let decoder = WPXMLRPCDecoder(data: response.body) else { @@ -418,7 +393,7 @@ private extension WordPressAPIError where EndpointError == WordPressOrgXMLRPCApi data = fault.response.body statusCode = nil case let .unacceptableStatusCode(response, body): - error = WordPressOrgXMLRPCApiError.httpErrorStatusCode as NSError + error = WordPressOrgXMLRPCApiError(code: .httpErrorStatusCode) as NSError data = body statusCode = response.statusCode case let .unparsableResponse(_, body, underlyingError): diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift index e8bcacac..f1c26d0a 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiError+NSErrorBridge.swift @@ -8,7 +8,7 @@ extension WordPressOrgXMLRPCApiError: CustomNSError { public static let errorDomain = WordPressOrgXMLRPCApiErrorDomain - public var errorCode: Int { self.rawValue } + public var errorCode: Int { code.rawValue } public var errorUserInfo: [String: Any] { [:] } } diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift new file mode 100644 index 00000000..c359c061 --- /dev/null +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift @@ -0,0 +1,39 @@ +import Foundation + +/// Error constants for the WordPress XML-RPC API +@objc public enum WordPressOrgXMLRPCApiErrorCode: Int, CaseIterable { + /// An error HTTP status code was returned. + case httpErrorStatusCode + /// The serialization of the request failed. + case requestSerializationFailed + /// The serialization of the response failed. + case responseSerializationFailed + /// An unknown error occurred. + case unknown +} + +public struct WordPressOrgXMLRPCApiError: Error { + let code: WordPressOrgXMLRPCApiErrorCode +} + +extension WordPressOrgXMLRPCApiError: LocalizedError { + public var errorDescription: String? { + return NSLocalizedString( + "There was a problem communicating with the site.", + comment: "A general error message shown to the user when there was an API communication failure." + ) + } + + public var failureReason: String? { + switch code { + case .httpErrorStatusCode: + return NSLocalizedString("An HTTP error code was returned.", comment: "A failure reason for when an error HTTP status code was returned from the site.") + case .requestSerializationFailed: + return NSLocalizedString("The serialization of the request failed.", comment: "A failure reason for when the request couldn't be serialized.") + case .responseSerializationFailed: + return NSLocalizedString("The serialization of the response failed.", comment: "A failure reason for when the response couldn't be serialized.") + case .unknown: + return NSLocalizedString("An unknown error occurred.", comment: "A failure reason for when the error that occured wasn't able to be determined.") + } + } +} diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift index 6b986578..03b0e61a 100644 --- a/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift @@ -9,8 +9,8 @@ import XCTest class WordPressOrgXMLRPCApiErrorTests: XCTestCase { func testNSErrorBridging() throws { - for error in WordPressOrgXMLRPCApiError.allCases { - let xmlRPCError = try XCTUnwrap(WordPressOrgXMLRPCApiError(rawValue: error.rawValue)) + for error in WordPressOrgXMLRPCApiErrorCode.allCases { + let xmlRPCError = try XCTUnwrap(WordPressOrgXMLRPCApiError(code: error)) let apiError = WordPressAPIError.endpointError(xmlRPCError) let newNSError = apiError as NSError diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift index 635d2f43..88283d07 100644 --- a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift @@ -65,7 +65,7 @@ class WordPressOrgXMLRPCApiTests: XCTestCase { failure: { (error, _) in expect.fulfill() XCTAssertEqual(error.domain, WordPressOrgXMLRPCApiErrorDomain) - XCTAssertEqual(error.code, WordPressOrgXMLRPCApiError.httpErrorStatusCode.rawValue) + XCTAssertEqual(error.code, WordPressOrgXMLRPCApiErrorCode.httpErrorStatusCode.rawValue) XCTAssertEqual(error.localizedFailureReason, "An HTTP error code 404 was returned.") XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyData as String]) XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyStatusCode as String]) @@ -119,10 +119,10 @@ class WordPressOrgXMLRPCApiTests: XCTestCase { failure: { (error, _) in expect.fulfill() - XCTAssertTrue(error is WordPressOrgXMLRPCApiError) XCTAssertEqual(error.domain, WordPressOrgXMLRPCApiErrorDomain) - XCTAssertEqual(error.code, WordPressOrgXMLRPCApiError.unknown.rawValue) - XCTAssertEqual(error.localizedFailureReason, WordPressOrgXMLRPCApiError.unknown.failureReason) + let errorUnknonw = WordPressOrgXMLRPCApiError(code: .unknown) + XCTAssertEqual(error.code, errorUnknonw.code.rawValue) + XCTAssertEqual(error.localizedFailureReason, errorUnknonw.failureReason) XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyData as String]) XCTAssertNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyStatusCode as String]) } diff --git a/WordPressKit.xcodeproj/project.pbxproj b/WordPressKit.xcodeproj/project.pbxproj index d9309a73..056ddf9b 100644 --- a/WordPressKit.xcodeproj/project.pbxproj +++ b/WordPressKit.xcodeproj/project.pbxproj @@ -70,6 +70,7 @@ 3F8308A729EE683500354497 /* ActivityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8308A629EE683500354497 /* ActivityTests.swift */; }; 3FA4258F2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FA4258E2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3FA425A72BCF7EDC007539BF /* WordPressOrgXMLRPCApiErrorDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FA425A62BCF7E7C007539BF /* WordPressOrgXMLRPCApiErrorDomain.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3FA425A92BCF8721007539BF /* WordPressOrgXMLRPCApiError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FA425A82BCF8721007539BF /* WordPressOrgXMLRPCApiError.swift */; }; 3FB8642C2888089F003A86BE /* BuildkiteTestCollector in Frameworks */ = {isa = PBXBuildFile; productRef = 3FB8642B2888089F003A86BE /* BuildkiteTestCollector */; }; 3FD634E52BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD634E32BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift */; }; 3FD634E62BC3A55F00CEDF5E /* Date+WordPressCom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD634E42BC3A55F00CEDF5E /* Date+WordPressCom.swift */; }; @@ -821,6 +822,7 @@ 3F8308A629EE683500354497 /* ActivityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityTests.swift; sourceTree = ""; }; 3FA4258E2BCCFDA6007539BF /* WordPressComRestApiErrorDomain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WordPressComRestApiErrorDomain.h; sourceTree = ""; }; 3FA425A62BCF7E7C007539BF /* WordPressOrgXMLRPCApiErrorDomain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WordPressOrgXMLRPCApiErrorDomain.h; sourceTree = ""; }; + 3FA425A82BCF8721007539BF /* WordPressOrgXMLRPCApiError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressOrgXMLRPCApiError.swift; sourceTree = ""; }; 3FB8642D288813E9003A86BE /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; 3FD634E32BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WordPressOrgXMLRPCValidator.swift; sourceTree = ""; }; 3FD634E42BC3A55F00CEDF5E /* Date+WordPressCom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+WordPressCom.swift"; sourceTree = ""; }; @@ -2143,6 +2145,7 @@ 3FE2E97A2BC3A332002CA2E1 /* WordPressComRestApi.swift */, 4A05E7992B2FDC3200C25E3B /* WordPressOrgRestApi.swift */, 93BD27791EE73944002BB00B /* WordPressOrgXMLRPCApi.swift */, + 3FA425A82BCF8721007539BF /* WordPressOrgXMLRPCApiError.swift */, 3F6128122BCB31660063810D /* WordPressOrgXMLRPCApiError+NSErrorBridge.swift */, 3FD634E32BC3A55F00CEDF5E /* WordPressOrgXMLRPCValidator.swift */, 93BD277B1EE73944002BB00B /* WordPressRSDParser.swift */, @@ -3314,6 +3317,7 @@ 9AB6D647218705E90008F274 /* RemoteDiff.swift in Sources */, 93BD277C1EE73944002BB00B /* HTTPAuthenticationAlertController.swift in Sources */, 7433BC011EFC4505002D9E92 /* PlanServiceRemote.swift in Sources */, + 3FA425A92BCF8721007539BF /* WordPressOrgXMLRPCApiError.swift in Sources */, 4041405E220F9EF500CF7C5B /* StatsDotComFollowersInsight.swift in Sources */, 74650F721F0EA1A700188EDB /* GravatarServiceRemote.swift in Sources */, B5969E1D20A49AC4005E9DF1 /* NSString+MD5.m in Sources */, From e8ee86f3ae8251e8b01b57d9b740665e2a2b5fb0 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 17 Apr 2024 16:53:57 +1000 Subject: [PATCH 7/7] Make `WordPressOrgXMLRPCApiErrorCode` into a nested `enum` --- CHANGELOG.md | 2 +- .../CoreAPI/WordPressOrgXMLRPCApiError.swift | 27 ++++++++++--------- .../WordPressOrgXMLRPCApiErrorTests.swift | 2 +- .../WordPressOrgXMLRPCApiTests.swift | 2 +- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62319223..60243521 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ _None._ ### Breaking Changes -- The Objective-C-visible `WordPressOrgXMLRPCError` `enum` has been renamed to `WordPressOrgXMLRPCErrorCode` [#790] +- The Objective-C-visible `WordPressOrgXMLRPCError` `enum` has been renamed to `WordPressOrgXMLRPCErrorCode`, `WordPressOrgXMLRPCError.Code` in Swift [#790] ### New Features diff --git a/Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift b/Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift index c359c061..946b4a37 100644 --- a/Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift +++ b/Sources/CoreAPI/WordPressOrgXMLRPCApiError.swift @@ -1,19 +1,20 @@ import Foundation -/// Error constants for the WordPress XML-RPC API -@objc public enum WordPressOrgXMLRPCApiErrorCode: Int, CaseIterable { - /// An error HTTP status code was returned. - case httpErrorStatusCode - /// The serialization of the request failed. - case requestSerializationFailed - /// The serialization of the response failed. - case responseSerializationFailed - /// An unknown error occurred. - case unknown -} - public struct WordPressOrgXMLRPCApiError: Error { - let code: WordPressOrgXMLRPCApiErrorCode + + /// Error constants for the WordPress XML-RPC API + @objc public enum Code: Int, CaseIterable { + /// An error HTTP status code was returned. + case httpErrorStatusCode + /// The serialization of the request failed. + case requestSerializationFailed + /// The serialization of the response failed. + case responseSerializationFailed + /// An unknown error occurred. + case unknown + } + + let code: Code } extension WordPressOrgXMLRPCApiError: LocalizedError { diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift index 03b0e61a..8a6d0f9a 100644 --- a/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiErrorTests.swift @@ -9,7 +9,7 @@ import XCTest class WordPressOrgXMLRPCApiErrorTests: XCTestCase { func testNSErrorBridging() throws { - for error in WordPressOrgXMLRPCApiErrorCode.allCases { + for error in WordPressOrgXMLRPCApiError.Code.allCases { let xmlRPCError = try XCTUnwrap(WordPressOrgXMLRPCApiError(code: error)) let apiError = WordPressAPIError.endpointError(xmlRPCError) let newNSError = apiError as NSError diff --git a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift index 88283d07..e687e21e 100644 --- a/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift +++ b/Tests/CoreAPITests/WordPressOrgXMLRPCApiTests.swift @@ -65,7 +65,7 @@ class WordPressOrgXMLRPCApiTests: XCTestCase { failure: { (error, _) in expect.fulfill() XCTAssertEqual(error.domain, WordPressOrgXMLRPCApiErrorDomain) - XCTAssertEqual(error.code, WordPressOrgXMLRPCApiErrorCode.httpErrorStatusCode.rawValue) + XCTAssertEqual(error.code, WordPressOrgXMLRPCApiError.Code.httpErrorStatusCode.rawValue) XCTAssertEqual(error.localizedFailureReason, "An HTTP error code 404 was returned.") XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyData as String]) XCTAssertNotNil(error.userInfo[WordPressOrgXMLRPCApi.WordPressOrgXMLRPCApiErrorKeyStatusCode as String])