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

Commit e4f8fba

Browse files
committed
Breaking change – Move NSDate WordPress.com implementation to Date
The breaking change is actually in having removed `NSDate.rfc3339Formatter`, which is no longer necessary.
1 parent ca4b342 commit e4f8fba

File tree

6 files changed

+81
-20
lines changed

6 files changed

+81
-20
lines changed

WordPressKit.xcodeproj/project.pbxproj

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,12 @@
7171
3F758FD324F6C68200BBA2FC /* AnnouncementServiceRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F758FD224F6C68200BBA2FC /* AnnouncementServiceRemote.swift */; };
7272
3F8308A729EE683500354497 /* ActivityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8308A629EE683500354497 /* ActivityTests.swift */; };
7373
3FB8642C2888089F003A86BE /* BuildkiteTestCollector in Frameworks */ = {isa = PBXBuildFile; productRef = 3FB8642B2888089F003A86BE /* BuildkiteTestCollector */; };
74-
3FFCC0412BA995290051D229 /* NSDate+RFC3339Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC0402BA995290051D229 /* NSDate+RFC3339Tests.swift */; };
75-
3FFCC0472BAA6EF40051D229 /* NSDate+RFC3339.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC0462BAA6EF40051D229 /* NSDate+RFC3339.swift */; };
74+
3FFCC0412BA995290051D229 /* Date+WordPressComTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC0402BA995290051D229 /* Date+WordPressComTests.swift */; };
75+
3FFCC0472BAA6EF40051D229 /* NSDate+WordPressCom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC0462BAA6EF40051D229 /* NSDate+WordPressCom.swift */; };
7676
3FFCC0492BAB98130051D229 /* DateFormatter+WordPressCom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC0482BAB98130051D229 /* DateFormatter+WordPressCom.swift */; };
7777
3FFCC04B2BABA5220051D229 /* DateFormatter+WordPressComTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC04A2BABA5220051D229 /* DateFormatter+WordPressComTests.swift */; };
78+
3FFCC04D2BABA6980051D229 /* NSDate+WordPressComTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC04C2BABA6980051D229 /* NSDate+WordPressComTests.swift */; };
79+
3FFCC04F2BABA6E60051D229 /* Date+WordPressCom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFCC04E2BABA6E60051D229 /* Date+WordPressCom.swift */; };
7880
40247DFA2120D8E100AE1C3C /* AutomatedTransferService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40247DF92120D8E100AE1C3C /* AutomatedTransferService.swift */; };
7981
40247DFC2120E69600AE1C3C /* AutomatedTransferStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40247DFB2120E69600AE1C3C /* AutomatedTransferStatus.swift */; };
8082
404057C5221B30400060250C /* StatsSearchTermTimeIntervalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 404057C4221B30400060250C /* StatsSearchTermTimeIntervalData.swift */; };
@@ -800,10 +802,12 @@
800802
3F758FD224F6C68200BBA2FC /* AnnouncementServiceRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementServiceRemote.swift; sourceTree = "<group>"; };
801803
3F8308A629EE683500354497 /* ActivityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityTests.swift; sourceTree = "<group>"; };
802804
3FB8642D288813E9003A86BE /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = "<group>"; };
803-
3FFCC0402BA995290051D229 /* NSDate+RFC3339Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSDate+RFC3339Tests.swift"; sourceTree = "<group>"; };
804-
3FFCC0462BAA6EF40051D229 /* NSDate+RFC3339.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSDate+RFC3339.swift"; sourceTree = "<group>"; };
805+
3FFCC0402BA995290051D229 /* Date+WordPressComTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+WordPressComTests.swift"; sourceTree = "<group>"; };
806+
3FFCC0462BAA6EF40051D229 /* NSDate+WordPressCom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSDate+WordPressCom.swift"; sourceTree = "<group>"; };
805807
3FFCC0482BAB98130051D229 /* DateFormatter+WordPressCom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+WordPressCom.swift"; sourceTree = "<group>"; };
806808
3FFCC04A2BABA5220051D229 /* DateFormatter+WordPressComTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+WordPressComTests.swift"; sourceTree = "<group>"; };
809+
3FFCC04C2BABA6980051D229 /* NSDate+WordPressComTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSDate+WordPressComTests.swift"; sourceTree = "<group>"; };
810+
3FFCC04E2BABA6E60051D229 /* Date+WordPressCom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+WordPressCom.swift"; sourceTree = "<group>"; };
807811
40247DF92120D8E100AE1C3C /* AutomatedTransferService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutomatedTransferService.swift; sourceTree = "<group>"; };
808812
40247DFB2120E69600AE1C3C /* AutomatedTransferStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutomatedTransferStatus.swift; sourceTree = "<group>"; };
809813
404057C4221B30400060250C /* StatsSearchTermTimeIntervalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsSearchTermTimeIntervalData.swift; sourceTree = "<group>"; };
@@ -1908,7 +1912,8 @@
19081912
FFA4D4A82423B10A00BF5180 /* WordPressOrgRestApiTests.swift */,
19091913
74B335DB1F06F4180053A184 /* WordPressOrgXMLRPCApiTests.swift */,
19101914
740B23D51F17F7C100067A2A /* XMLRPCTestable.swift */,
1911-
3FFCC0402BA995290051D229 /* NSDate+RFC3339Tests.swift */,
1915+
3FFCC0402BA995290051D229 /* Date+WordPressComTests.swift */,
1916+
3FFCC04C2BABA6980051D229 /* NSDate+WordPressComTests.swift */,
19121917
3FFCC04A2BABA5220051D229 /* DateFormatter+WordPressComTests.swift */,
19131918
);
19141919
name = Tests;
@@ -2524,7 +2529,8 @@
25242529
4A05E7952B2FCB6400C25E3B /* NonceRetrieval.swift */,
25252530
4A05E7992B2FDC3200C25E3B /* WordPressOrgRestApi.swift */,
25262531
93BD27741EE73944002BB00B /* HTTPAuthenticationAlertController.swift */,
2527-
3FFCC0462BAA6EF40051D229 /* NSDate+RFC3339.swift */,
2532+
3FFCC0462BAA6EF40051D229 /* NSDate+WordPressCom.swift */,
2533+
3FFCC04E2BABA6E60051D229 /* Date+WordPressCom.swift */,
25282534
3FFCC0482BAB98130051D229 /* DateFormatter+WordPressCom.swift */,
25292535
93BD27771EE73944002BB00B /* WordPressComOAuthClient.swift */,
25302536
93BD27781EE73944002BB00B /* WordPressComRestApi.swift */,
@@ -3398,6 +3404,7 @@
33983404
93BD277F1EE73944002BB00B /* WordPressComOAuthClient.swift in Sources */,
33993405
740B23B91F17EC7300067A2A /* PostServiceRemoteREST.m in Sources */,
34003406
93BD27801EE73944002BB00B /* WordPressComRestApi.swift in Sources */,
3407+
3FFCC04F2BABA6E60051D229 /* Date+WordPressCom.swift in Sources */,
34013408
404057D2221C56AB0060250C /* StatsTopCountryTimeIntervalData.swift in Sources */,
34023409
E11C2AD21FA77FB90023BDE2 /* SitePlugin.swift in Sources */,
34033410
4A68E3DF29407100004AC3DC /* RemoteReaderTopic.swift in Sources */,
@@ -3463,7 +3470,7 @@
34633470
E632D7781F6E047400297F6D /* SocialLogin2FANonceInfo.swift in Sources */,
34643471
32FC1D29255C91ED00CD0A7B /* JetpackScanServiceRemote.swift in Sources */,
34653472
9F3E0B9B208732B3009CB5BA /* RemoteReaderSiteInfoSubscription.swift in Sources */,
3466-
3FFCC0472BAA6EF40051D229 /* NSDate+RFC3339.swift in Sources */,
3473+
3FFCC0472BAA6EF40051D229 /* NSDate+WordPressCom.swift in Sources */,
34673474
7403A2E41EF06ED500DED7DC /* AccountSettingsRemote.swift in Sources */,
34683475
3236F77824AE34B40088E8F3 /* ReaderTopicServiceRemote+Interests.swift in Sources */,
34693476
FE20A6A4282A96C00025E975 /* RemoteBloggingPromptsSettings.swift in Sources */,
@@ -3617,12 +3624,13 @@
36173624
F4B0F4802ACB4EA9003ABC61 /* AllDomainsResultDomainTests.swift in Sources */,
36183625
74585B901F0D51F900E7E667 /* DomainsServiceRemoteRESTTests.swift in Sources */,
36193626
BAFA775624ADAB3C000F0D3A /* MockPluginDirectoryEntryProvider.swift in Sources */,
3620-
3FFCC0412BA995290051D229 /* NSDate+RFC3339Tests.swift in Sources */,
3627+
3FFCC0412BA995290051D229 /* Date+WordPressComTests.swift in Sources */,
36213628
3F8308A729EE683500354497 /* ActivityTests.swift in Sources */,
36223629
9AB6D64A218727D60008F274 /* PostServiceRemoteRESTRevisionsTest.swift in Sources */,
36233630
01438D382B6A35FB0097D60A /* stats-summary.json in Sources */,
36243631
7430C9BD1F192C0F0051B8E6 /* ReaderPostServiceRemoteTests.m in Sources */,
36253632
1DC837C229B9F04F009DCD4B /* RemoteVideoPressVideoTests.swift in Sources */,
3633+
3FFCC04D2BABA6980051D229 /* NSDate+WordPressComTests.swift in Sources */,
36263634
FAD1345125909DEA00A8FEB1 /* JetpackBackupServiceRemoteTests.swift in Sources */,
36273635
8B2F4BE924ABC9DC0056C08A /* ReaderPostServiceRemote+CardsTests.swift in Sources */,
36283636
40F9880C221ACEEE00B7B369 /* StatsRemoteV2Tests.swift in Sources */,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
extension Date {
2+
3+
/// Parses a date string
4+
///
5+
/// Dates in the format specified in http://www.w3.org/TR/NOTE-datetime should be OK.
6+
/// The kind of dates returned by the REST API should match that format, even if the doc promises ISO 8601.
7+
///
8+
/// Parsing the full ISO 8601, or even RFC 3339 is more complex than this, and makes no sense right now.
9+
///
10+
/// - SeeAlso: [WordPress.com REST API docs](https://developer.wordpress.com/docs/api/)
11+
/// - Warning: This method doesn't support fractional seconds or dates with leap seconds (23:59:60 turns into 23:59:00)
12+
static func with(wordPressComJSONString jsonString: String) -> Date? {
13+
DateFormatter.wordPressCom.date(from: jsonString)
14+
}
15+
16+
var wordPressComJSONString: String {
17+
DateFormatter.wordPressCom.string(from: self)
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
import Foundation
22

3+
// This `NSDate` extension wraps the `Date` implementation.
4+
//
5+
// It's done in two types because we cannot expose the `Date` methods to Objective-C, since `Date` is not a class:
6+
//
7+
// `@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes`
38
extension NSDate {
49

5-
static let rfc3339Formatter = DateFormatter.wordPressCom
6-
710
/// Parses a date string
811
///
912
/// Dates in the format specified in http://www.w3.org/TR/NOTE-datetime should be OK.
1013
/// The kind of dates returned by the REST API should match that format, even if the doc promises ISO 8601.
1114
///
1215
/// Parsing the full ISO 8601, or even RFC 3339 is more complex than this, and makes no sense right now.
1316
///
17+
/// - SeeAlso: [WordPress.com REST API docs](https://developer.wordpress.com/docs/api/)
1418
/// - Warning: This method doesn't support fractional seconds or dates with leap seconds (23:59:60 turns into 23:59:00)
1519
//
1620
// Needs to be `public` because of the usages in the Objective-C code.
1721
@objc(dateWithWordPressComJSONString:)
1822
public static func with(wordPressComJSONString jsonString: String) -> Date? {
19-
self.rfc3339Formatter.date(from: jsonString)
23+
Date.with(wordPressComJSONString: jsonString)
2024
}
2125

2226
@objc(WordPressComJSONString)
2327
public func wordPressComJSONString() -> String {
24-
NSDate.rfc3339Formatter.string(from: self as Date)
28+
(self as Date).wordPressComJSONString
2529
}
2630
}

WordPressKit/PostServiceRemoteREST+Extended.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ private func decodePost(from object: AnyObject) async throws -> RemotePost {
4040

4141
private func makeParameters<T: Encodable>(from value: T) throws -> [String: AnyObject] {
4242
let encoder = JSONEncoder()
43-
encoder.dateEncodingStrategy = .formatted(NSDate.rfc3339Formatter)
43+
encoder.dateEncodingStrategy = .formatted(.wordPressCom)
4444
let data = try encoder.encode(value)
4545
let object = try JSONSerialization.jsonObject(with: data)
4646
guard let dictionary = object as? [String: AnyObject] else {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@testable import WordPressKit
2+
import XCTest
3+
4+
// This is an incomplete test for implementing RFC 3339.
5+
// It's purpose is to ensure our code "works".
6+
//
7+
// See also:
8+
//
9+
// - https://developer.wordpress.com/docs/api/
10+
// - https://datatracker.ietf.org/doc/html/rfc3339
11+
class DateWordPressComTests: XCTestCase {
12+
13+
func testValidRFC3339DateFromString() {
14+
XCTAssertEqual(
15+
Date.with(wordPressComJSONString: "2023-03-19T15:00:00Z"),
16+
Date(timeIntervalSince1970: 1_679_238_000)
17+
)
18+
}
19+
20+
func testInvalidRFC3339DateFromString() {
21+
XCTAssertNil(Date.with(wordPressComJSONString: "2024-01-01"))
22+
}
23+
24+
func testInvalidDateFromString() {
25+
XCTAssertNil(Date.with(wordPressComJSONString: "not a date"))
26+
}
27+
28+
func testValidRFC3339StringFromDate() {
29+
XCTAssertEqual(
30+
Date(timeIntervalSince1970: 1_679_238_000).wordPressComJSONString,
31+
// Apparently, NSDateFormatter doesn't offer a way to specify Z vs +0000.
32+
// This might go all the way back to the ISO 8601 and RFC 3339 specs overlap.
33+
"2023-03-19T15:00:00+0000"
34+
)
35+
}
36+
}

WordPressKitTests/NSDate+RFC3339Tests.swift renamed to WordPressKitTests/NSDate+WordPressComTests.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
@testable import WordPressKit
22
import XCTest
33

4-
// This is an incomplete test for implementing RFC 3339.
5-
// It's purpose is to ensure our code "works".
6-
//
7-
// See also:
8-
//
9-
// - https://datatracker.ietf.org/doc/html/rfc3339
10-
class NSDateRFC3339Tests: XCTestCase {
4+
class NSDateWordPressComTests: XCTestCase {
115

126
func testValidRFC3339DateFromString() {
137
XCTAssertEqual(

0 commit comments

Comments
 (0)