Skip to content

[FINAL] Rename shared secret to API key#1

Merged
jeiting merged 7 commits into
masterfrom
feature/rename-shared-secret-to-api-key
Oct 27, 2017
Merged

[FINAL] Rename shared secret to API key#1
jeiting merged 7 commits into
masterfrom
feature/rename-shared-secret-to-api-key

Conversation

@jeiting

@jeiting jeiting commented Oct 27, 2017

Copy link
Copy Markdown
Contributor

API key helps to disambiguate from the App-Specific Shared Secret in iTunesConnect.

Note: This is not compatible with the current version of the backend. The backend will be updated when 0.2.0 is ready.

@jeiting jeiting merged commit 019fb36 into master Oct 27, 2017
@jeiting jeiting deleted the feature/rename-shared-secret-to-api-key branch October 27, 2017 19:23
jeiting pushed a commit that referenced this pull request Nov 15, 2018
NachoSoto added a commit that referenced this pull request Nov 8, 2022
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:
```swift
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.

[TRIAGE-172]:
https://revenuecats.atlassian.net/browse/TRIAGE-172?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
NachoSoto added a commit that referenced this pull request Nov 22, 2022
…d on posting thread

This could solve [CSDK-519], and at the very least it makes the semantics simpler to understand.

The traditional `NotificationCenter.addObserver` seems to always lead to a jump to the main thread when modifying `UserDefaults` from any other thread.
See:
```
Thread 1:
0 libsystem_kernel.dylib 0x1fa81041c __psynch_cvwait + 8
1 libsystem_pthread.dylib 0x20aa5406c _pthread_cond_wait + 1232
2 Foundation 0x1b85b3800 -[NSOperation waitUntilFinished] + 508
3 CoreFoundation 0x1be16fe0c _CFXNotificationPost + 772
4 Foundation 0x1b85d04dc -[NSNotificationCenter postNotificationName:object:userInfo:] + 92
5 AudioMemos2 0x102ed18a4 specialized closure #1 in DeviceCache.cache(customerInfo:appUserID:) + 972964 (<compiler-generated>:0)
```

There were no potential race condition (and as far as we can tell, no deadlocks possible) because of how synchronization is done, but using the modern `NotificationCenter.addObserver` simplifies this, because `handleUserDefaultsChanged` will now be invoked synchronously in the calling thread.
NachoSoto added a commit that referenced this pull request Nov 22, 2022
…d on posting thread (#2078)

This could solve [CSDK-519], and at the very least it makes the
semantics simpler to understand.

The traditional `NotificationCenter.addObserver` seems to always lead to
a jump to the main thread when modifying `UserDefaults` from any other
thread.
See:
```
Thread 1:
0 libsystem_kernel.dylib 0x1fa81041c __psynch_cvwait + 8
1 libsystem_pthread.dylib 0x20aa5406c _pthread_cond_wait + 1232
2 Foundation 0x1b85b3800 -[NSOperation waitUntilFinished] + 508
3 CoreFoundation 0x1be16fe0c _CFXNotificationPost + 772
4 Foundation 0x1b85d04dc -[NSNotificationCenter postNotificationName:object:userInfo:] + 92
5 AudioMemos2 0x102ed18a4 specialized closure #1 in DeviceCache.cache(customerInfo:appUserID:) + 972964 (<compiler-generated>:0)
```

There were no potential race condition (and as far as we can tell, no
deadlocks possible) because of how synchronization is done, but using
the modern `NotificationCenter.addObserver` simplifies this, because
`handleUserDefaultsChanged` will now be invoked synchronously in the
calling thread.

[CSDK-519]:
https://revenuecats.atlassian.net/browse/CSDK-519?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
NachoSoto added a commit that referenced this pull request Jul 13, 2023
Fixes https://app.circleci.com/pipelines/github/RevenueCat/purchases-ios/12839/workflows/2b1e24b9-428a-40ed-bcfd-a94d7591236d/jobs/89720/steps

I noticed when downloading the `.xcresult` that the tests had crashed with this:
```
Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libswiftCore.dylib            	       0x10bc64589 swift::runtime::AccessSet::insert(swift::runtime::Access*, void*, void*, swift::ExclusivityFlags) + 73
1   libswiftCore.dylib            	       0x10bc647e2 swift_beginAccess + 66
2   BackendIntegrationTests       	       0x13ab37c76 default argument 1 of Expectation.toEventually(_:timeout:pollInterval:description:) + 54
3   BackendIntegrationTests       	       0x13ab37b44 closure #1 in BaseBackendIntegrationTests.verifyPurchasesDoesNotLeak() + 276 (BaseBackendIntegrationTests.swift:167)
```

Turns out that because of the way it was written, normally `Nimble` tries to print the instance during a failure:
```
BasePurchasesTests.swift:116: error: -[UnitTests.PurchasesConfiguringTests testSettingTheDelegateAfterInitializationSendsCachedCustomerInfo] : failed - Purchases has leaked
expected to eventually be nil, got <<RCPurchases: 0x125d13bf0>>
```

That crash points to a race condition inside Swift's runtime. To avoid that, this changes the expectation so `Nimble` would only try to print "expected true, got false", with our own provided description.
Therefore making sure that it doesn't try to access the instance while it's being deallocated.
NachoSoto added a commit that referenced this pull request Jul 13, 2023
Fixes
https://app.circleci.com/pipelines/github/RevenueCat/purchases-ios/12839/workflows/2b1e24b9-428a-40ed-bcfd-a94d7591236d/jobs/89720/steps

I noticed when downloading the `.xcresult` that the tests had crashed
with this:
```
Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libswiftCore.dylib            	       0x10bc64589 swift::runtime::AccessSet::insert(swift::runtime::Access*, void*, void*, swift::ExclusivityFlags) + 73
1   libswiftCore.dylib            	       0x10bc647e2 swift_beginAccess + 66
2   BackendIntegrationTests       	       0x13ab37c76 default argument 1 of Expectation.toEventually(_:timeout:pollInterval:description:) + 54
3   BackendIntegrationTests       	       0x13ab37b44 closure #1 in BaseBackendIntegrationTests.verifyPurchasesDoesNotLeak() + 276 (BaseBackendIntegrationTests.swift:167)
```

Turns out that because of the way it was written, normally `Nimble`
tries to print the instance during a failure:
```
BasePurchasesTests.swift:116: error: -[UnitTests.PurchasesConfiguringTests testSettingTheDelegateAfterInitializationSendsCachedCustomerInfo] : failed - Purchases has leaked
expected to eventually be nil, got <<RCPurchases: 0x125d13bf0>>
```

That crash points to a race condition inside Swift's runtime. To avoid
that, this changes the expectation so `Nimble` would only try to print
"expected true, got false", with our own provided description. Therefore
making sure that it doesn't try to access the instance while it's being
deallocated.
NachoSoto added a commit that referenced this pull request Jul 17, 2023
Looks like #2806 didn't work.
I still see this race-condition crash:
```
Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libswiftCore.dylib            	       0x10bc64589 swift::runtime::AccessSet::insert(swift::runtime::Access*, void*, void*, swift::ExclusivityFlags) + 73
1   libswiftCore.dylib            	       0x10bc647e2 swift_beginAccess + 66
2   BackendIntegrationTests       	       0x13ab37c76 default argument 1 of Expectation.toEventually(_:timeout:pollInterval:description:) + 54
3   BackendIntegrationTests       	       0x13ab37b44 closure #1 in BaseBackendIntegrationTests.verifyPurchasesDoesNotLeak() + 276 (BaseBackendIntegrationTests.swift:167)
```

This slight refactor matches the implementation in `BasePurchasesTests`, and I haven't the crash there. So hopefully this will work.
NachoSoto added a commit that referenced this pull request Jul 18, 2023
Looks like #2806 didn't work.
I still see this race-condition crash:
```
Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libswiftCore.dylib            	       0x10bc64589 swift::runtime::AccessSet::insert(swift::runtime::Access*, void*, void*, swift::ExclusivityFlags) + 73
1   libswiftCore.dylib            	       0x10bc647e2 swift_beginAccess + 66
2   BackendIntegrationTests       	       0x13ab37c76 default argument 1 of Expectation.toEventually(_:timeout:pollInterval:description:) + 54
3   BackendIntegrationTests       	       0x13ab37b44 closure #1 in BaseBackendIntegrationTests.verifyPurchasesDoesNotLeak() + 276 (BaseBackendIntegrationTests.swift:167)
```

This slight refactor matches the implementation in `BasePurchasesTests`,
and I haven't the crash there. So hopefully this will work.

I filed swiftlang/swift#67361 with the crash.
NachoSoto added a commit that referenced this pull request Jul 24, 2023
…perty

This is a similar change to #2532.

I noticed yet another source of crashes in our integration tests.
This is what the result was:
```
failed - Message 'Finishing transaction' should not have been logged
expected to not find object in collection that satisfies predicate
```

That came from this code:
```swift
self.logger.verifyMessageWasNotLogged("Finishing transaction")

let info1 = try await Purchases.shared.customerInfo()
```

After that assertion failure, `XCTest` continued execusion, while it had already tear down `Purchases`, which lead to this crash:
```
Thread 0 Crashed:
0   libswiftCore.dylib            	       0x103b84e81 _assertionFailure(_:_:file:line:flags:) + 353
1   RevenueCat                    	       0x1332516d0 static Purchases.shared.getter + 352 (Purchases.swift:65)
2   BackendIntegrationTests       	       0x130f7048a OfflineStoreKit1IntegrationTests.testPurchaseWhileServerIsDownPostsReceiptWhenForegroundingApp() + 362 (OfflineStoreKitIntegrationTests.swift:289)
3   BackendIntegrationTests       	       0x130f75ee1 @objc closure #1 in OfflineStoreKit1IntegrationTests.testPurchaseWhileServerIsDownPostsReceiptWhenForegroundingApp() + 1
4   BackendIntegrationTests       	       0x130f77d91 partial apply for @objc closure #1 in OfflineStoreKit1IntegrationTests.testPurchaseWhileServerIsDownPostsReceiptWhenForegroundingApp() + 1
```

To prevent this, instead of using `Purchases.shared` this replaces that with a throwing `self.purchases`.
Just like we don't use force-unwraps in tests and instead use `XCTUwnrap`, this now will fail the test instead of crashing it.
NachoSoto added a commit that referenced this pull request Jul 24, 2023
…perty (#2867)

This is a similar change to #2532.

I noticed yet another source of crashes in our integration tests.
This is what [the
result](https://app.circleci.com/pipelines/github/RevenueCat/purchases-ios/13247/workflows/52fd2014-7a19-442f-a572-64116393abec/jobs/94728)
was:
```
failed - Message 'Finishing transaction' should not have been logged
expected to not find object in collection that satisfies predicate
```

That came from this code:
```swift
self.logger.verifyMessageWasNotLogged("Finishing transaction")

let info1 = try await Purchases.shared.customerInfo()
```

After that assertion failure, `XCTest` continued execution, while it had
already tear down `Purchases`, which lead to this crash:
```
Thread 0 Crashed:
0   libswiftCore.dylib            	       0x103b84e81 _assertionFailure(_:_:file:line:flags:) + 353
1   RevenueCat                    	       0x1332516d0 static Purchases.shared.getter + 352 (Purchases.swift:65)
2   BackendIntegrationTests       	       0x130f7048a OfflineStoreKit1IntegrationTests.testPurchaseWhileServerIsDownPostsReceiptWhenForegroundingApp() + 362 (OfflineStoreKitIntegrationTests.swift:289)
3   BackendIntegrationTests       	       0x130f75ee1 @objc closure #1 in OfflineStoreKit1IntegrationTests.testPurchaseWhileServerIsDownPostsReceiptWhenForegroundingApp() + 1
4   BackendIntegrationTests       	       0x130f77d91 partial apply for @objc closure #1 in OfflineStoreKit1IntegrationTests.testPurchaseWhileServerIsDownPostsReceiptWhenForegroundingApp() + 1
```

To prevent this, instead of using `Purchases.shared` this replaces that
with a throwing `self.purchases`.
Just like we don't use force-unwraps in tests and instead use
`XCTUwnrap`, this now will fail the test instead of crashing it.
@claude claude Bot mentioned this pull request Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant