Commit Graph
11 Commits
Author SHA1 Message Date
NachoSoto 1234c4ea91 CacheableNetworkOperation: avoid unnecessarily creating operations for cache hits (#2135)
### Changes:
- Created `CacheableNetworkOperationFactory` to abstract operation and
cache key creation
- Instead of always creating an operation, we create a factory first,
which pre-computes the cache key
- This cache key is used to determine if it's a cache hit, as well as
for the subsequently created operation

I'm still investigating a leak (#2105), and I suspect it's coming from
us creating and storing completion blocks, and those staying in memory
beyond the lifetime of the operation.
This refactor and performance improvement helps us avoid get more things
in memory than we need to.

See #2138 for how this is tested.
2022-12-21 08:13:41 -08:00
NachoSoto b93b082690 Fixed Xcode 13.2.x / Swift 5.5 compatibility (#1994)
Fixes [SDKONCALL-156].

This will be covered by #1990.

[SDKONCALL-156]:
https://revenuecats.atlassian.net/browse/SDKONCALL-156?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-10-24 14:36:05 -07:00
NachoSoto b08fb7dc08 Renamed CallbackCache.add(callback:) (#1970)
This is the Swifty way to avoid the duplication in `cache.add(callback: callback)`.
2022-10-11 12:47:17 -07:00
NachoSoto 46d9366fa4 PostReceiptDataOperation: added initiationSource parameter (#1957)
For [TRIAGE-82].

[TRIAGE-82]:
https://revenuecats.atlassian.net/browse/TRIAGE-82?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-10-07 08:21:30 -07:00
NachoSoto 43d474d813 GetCustomerInfoAPI: avoid making a request if there's any PostReceiptDataOperation in progress (#1911)
Fixes [CSDK-419].

This is an improvement over the fix in #1292. In there, we avoided
appending on an existing `CustomerInfoOperation` if there were any
`PostReceiptDataOperation`s in progress, because those might come back
with outdated entitlements.
This fix removes that cache key hack, and instead *reuses* the entire
response to that `PostReceiptDataOperation` by "stealing" that request's
cache key.

This is perfectly captured by the existing test
`BackendPostReceiptDataTests.testGetsUpdatedSubscriberInfoAfterPost`,
added in #1292. Amazingly enough, that test still passes with one minor
change: the entire process requires one fewer API call 🎉 🐼

[CSDK-419]:
https://revenuecats.atlassian.net/browse/CSDK-419?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-09-21 13:34:43 -07:00
NachoSoto 0bff3f65fe Sendable support (#1795)
Fixes [CSDK-379] and https://github.com/RevenueCat/purchases-ios/issues/1041#issuecomment-1206445939

[CSDK-379]: https://revenuecats.atlassian.net/browse/CSDK-379?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

### Main changes:
- `Sendable` conformances to all types that are thread-safe
- `@unchecked Sendable` for types that the compiler can't enforce, but with documentation as to why
- Made classes that aren't mocked `final` (note that this doesn't change the API, because none of these were `open` to begin with)
- Made some classes thread-safe that weren't (like `DeviceCache`)

For the non-`final` `class`es, I've actually managed to compile the SDK with all of them as `final` and `Sendable`, to make sure that making them `@unchecked Sendable` didn't hide any other issues.

### Future improvements:
- https://twitter.com/nachosoto/status/1557139992056500224?s=21&t=arWdvEzTIFANBvwqQ0vPiA
- https://twitter.com/nachosoto/status/1557141944777592832?s=21&t=arWdvEzTIFANBvwqQ0vPiA
- https://twitter.com/nachosoto/status/1557143374922059776?s=21&t=arWdvEzTIFANBvwqQ0vPiA

### Depends on:
- #1794
- #1804
- #1806
- #1807
- #1808
- #1813
- #1822
- #1823
- #1824
- #1825
- #1826
2022-08-31 13:30:38 -07:00
NachoSoto 4f8589a30a Backend: fixed potential race conditions introduced by OperationDispatcher.dispatchOnWorkerThread(withRandomDelay:) (#1827)
Fixes [CSDK-391]. As described in that ticket, calling a method that introduces a random delay before performing an API request could lead to a race condition. Example:

> Request 1: delay 0 seconds. Start now.
> Request 2: delay 2 seconds. Waiting…
> Request 1 finishes.
> Request 2: 2 seconds past. There is no in progress request, so we start it again

This also solves [CSDK-394]. If any part of our code (or users) call a method that would enqueue a request multiple times, we need to insert it into the callback queue right away.
That's what this does: it moves the random delay to *after* the callback has been added to the `CallbackCache`.

[CSDK-391]: https://revenuecats.atlassian.net/browse/CSDK-391?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[CSDK-394]: https://revenuecats.atlassian.net/browse/CSDK-394?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-08-16 09:29:36 -07:00
NachoSoto 0f99e94836 CallbackCache: simplified implementation using Atomic (#1834)
We don't actually need to share a single queue to synchronize all the callback caches.
This new implementation also avoids using the risky `DispatchQueue.sync`.

This also fixes potential issues because `cachedCallbacksByKey` was exposed, and it could have been read without synchronizing access with the queue. This is now impossible.
2022-08-15 15:10:50 -07:00
343ba7eaf4 AdServices (#1727)
* [CF-106] Fetch AdServices Token (#1519)

Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Co-authored-by: Josh Holtz <me@joshholtz.com>

* [CF-553] Post AdServices token (#1534)

Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Co-authored-by: Josh Holtz <me@joshholtz.com>

* Update ios 14 snapshots tets

* Reworked adservices to use new Purchases.shared.attribution API

* Updated with some comments from PR

* Add iAd code back (#1739)

Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>

* use new mapKeys dictionary extension for device cache

* update for some pr comments

* remove purchasestests

* generate missing snapshots

* fix deprecation messages to clarify method now called on shared instance

* Fix for inserting nonstring into userdefaults

* Add tests for bug

* fix lint

* Added availablility checks for tests and removed unused varialbes

* Whoops... wrong class

Co-authored-by: beylmk <maddie@revenuecat.com>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
2022-08-08 07:42:42 -05:00
NachoSoto a2fc04c09e SubscriberAttribute: converted into struct (#1648)
### Motivation:

Initially I wanted to make `SubscriberAttribute.asDictionary` work using `Codable`. However, this isn't the right refactor because we need the actual raw types to be encoded inside `UserDefaults`.
At least this refactor provides several improvements:

### Changes:

- `SubscriberAttribute` now has value semantics
- ⚠️  `SubscriberAttribute.isSynced` used to be mutable, with reference semantics, which was dangerous
- `SubscriberAttribute: Equatable` implementation is now automatic
- Cleaned up `SubscriberAttribute.asDictionary` implementation, extracting keys into an `enum`
- Moved `Dictionary` -> `SubscriberAttribute` creation to the type itself
- ⚠️ `SubscriberAttribute.init(dictionary:)` returns an `Optional` instead of using force-unwrap, avoiding potential crashes
- Added more serialization / deserialization tests
- Removed `SubscriberAttributesMarshaller` and moved method into `SubscriberAttribute` extension
- Moved `SubscriberAttributeDict` into `SubscriberAttribute.Dictionary`
2022-06-17 10:00:51 -07:00
Joshua Liebowitz 858bef3f9b Extract Offerings-related things into OfferingsAPI (#1706)
Extract Offerings-related things into OfferingsAPI
2022-06-16 14:00:40 -07:00