Skip to content

ISO8601DateFormatter.withMilliseconds: fixed iOS 11 crash#2037

Merged
NachoSoto merged 2 commits into
mainfrom
date-formatter-ios-11
Nov 8, 2022
Merged

ISO8601DateFormatter.withMilliseconds: fixed iOS 11 crash#2037
NachoSoto merged 2 commits into
mainfrom
date-formatter-ios-11

Conversation

@NachoSoto

@NachoSoto NachoSoto commented Nov 8, 2022

Copy link
Copy Markdown
Contributor

Fixes TRIAGE-172

See stacktrace:

Fatal Exception: NSInternalInconsistencyException
Invalid parameter not satisfying: formatOptions == 0 || !(formatOptions & ~(NSISO8601DateFormatWithYear | NSISO8601DateFormatWithMonth | NSISO8601DateFormatWithWeekOfYear | NSISO8601DateFormatWithDay | NSISO8601DateFormatWithTime | NSISO8601DateFormatWithTimeZone | NSISO8601DateFormatWithSpaceBetweenDateAndTime | NSISO8601DateFormatWithDashSeparatorInDate | NSISO8601DateFormatWithColonSeparatorInTime | NSISO8601DateFormatWithColonSeparatorInTimeZone | NSISO8601DateFormatWithFullDate | NSISO8601DateFormatWithFullTime | NSISO8601DateFormatWithInternetDateTime))
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x141d04 __exceptionPreprocess
1 libobjc.A.dylib 0x8528 objc_exception_throw
2 CoreFoundation 0x141bd8 +[NSException raise:format:]
3 Foundation 0xacc24 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4 Foundation 0xe4794 -[NSISO8601DateFormatter setFormatOptions:]
5 RevenueCat 0x4795c one-time initialization function for withMilliseconds
6 libdispatch.dylib 0x1048 _dispatch_client_callout
7 libdispatch.dylib 0x4710 dispatch_once_f$VARIANT$mp
8 RevenueCat 0x47b0c date(from:) in Formatter #1 in closure #1 in variable initialization expression of static NSISO8601DateFormatter.default + 60 (DateFormatter+Extensions.swift:60)
9 RevenueCat 0x47b68 protocol witness for DateFormatterType.date(from:) in conformance Formatter #1 in closure #1 in variable initialization expression of static NSISO8601DateFormatter.default (<compiler-generated>)
10 RevenueCat 0xe6b8 AppleReceiptBuilder.build(fromContainer:) (AppleReceiptBuilder.swift)

This is the key part:
formatOptions == 0 || !(formatOptions & ~(NSISO8601DateFormatWithYear | NSISO8601DateFormatWithMonth | NSISO8601DateFormatWithWeekOfYear | NSISO8601DateFormatWithDay | NSISO8601DateFormatWithTime | NSISO8601DateFormatWithTimeZone | NSISO8601DateFormatWithSpaceBetweenDateAndTime | NSISO8601DateFormatWithDashSeparatorInDate | NSISO8601DateFormatWithColonSeparatorInTime | NSISO8601DateFormatWithColonSeparatorInTimeZone | NSISO8601DateFormatWithFullDate | NSISO8601DateFormatWithFullTime | NSISO8601DateFormatWithInternetDateTime))

This is coming from the following code:

static let withMilliseconds: DateFormatterType = {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [
        .withInternetDateTime,
        .withFractionalSeconds
    ]

    return formatter
}()

Even though .withFractionalSeconds is available in iOS 11, that assertion seems wrong, as it's treating that option as invalid. This was a regression in #998, almost a year ago, but since we have very little coverage on iOS 11 we never noticed until now.

Unfortunately it seems like we won't be able to run iOS 11 tests in CI (#2036), but this change is fairly safe, it just reverts to using the old DateFormatter for older versions.

@NachoSoto NachoSoto added the pr:fix A bug fix label Nov 8, 2022
@NachoSoto NachoSoto requested a review from a team November 8, 2022 00:07
@NachoSoto NachoSoto merged commit f54a30a into main Nov 8, 2022
@NachoSoto NachoSoto deleted the date-formatter-ios-11 branch November 8, 2022 17:27
NachoSoto pushed a commit that referenced this pull request Nov 9, 2022
**This is an automatic release.**

### Bugfixes
* `ISO8601DateFormatter.withMilliseconds`: fixed iOS 11 crash (#2037)
via NachoSoto (@NachoSoto)
* Changed `StoreKit2Setting.default` back to
`.enabledOnlyForOptimizations` (#2022) via NachoSoto (@NachoSoto)
### Other Changes
* `Integration Tests`: changed weekly to monthly subscriptions to work
around 0-second subscriptions (#2042) via NachoSoto (@NachoSoto)
* `Integration Tests`: fixed `testPurchaseWithAskToBuyPostsReceipt`
(#2040) via NachoSoto (@NachoSoto)
* `ReceiptRefreshPolicy.retryUntilProductIsFound`: default to returning
"invalid" receipt (#2024) via NachoSoto (@NachoSoto)
* `CachingProductsManager`: use partial cached products (#2014) via
NachoSoto (@NachoSoto)
* Added `BackendErrorCode.purchasedProductMissingInAppleReceipt` (#2033)
via NachoSoto (@NachoSoto)
* `PurchaseTesterSwiftUI`: replaced `Purchases` dependency with `SPM`
(#2027) via NachoSoto (@NachoSoto)
* `Integration Tests`: changed log output to `raw` (#2031) via NachoSoto
(@NachoSoto)
* `Integration Tests`: run on iOS 16 (#2035) via NachoSoto (@NachoSoto)
* CI: fixed `iOS 14` tests Xcode version (#2030) via NachoSoto
(@NachoSoto)
* `Async.call`: added non-throwing overload (#2006) via NachoSoto
(@NachoSoto)
* Documentation: Fixed references in `V4_API_Migration_guide.md` (#2018)
via NachoSoto (@NachoSoto)
* `eligiblePromotionalOffers`: don't log error if response is ineligible
(#2019) via NachoSoto (@NachoSoto)
* Runs push-pods after make-release (#2025) via Cesar de la Vega
(@vegaro)
* Some updates on notify-on-non-patch-release-branches: (#2026) via
Cesar de la Vega (@vegaro)
* Deploy `PurchaseTesterSwiftUI` to TestFlight (#2003) via NachoSoto
(@NachoSoto)
* `PurchaseTesterSwiftUI`: added "logs" screen (#2012) via NachoSoto
(@NachoSoto)
* `PurchaseTesterSwiftUI`: allow configuring API key at runtime (#1999)
via NachoSoto (@NachoSoto)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants