Skip to content

Clear cached offerings and products after Storefront changes (2/4)#1583

Merged
NachoSoto merged 52 commits into
RevenueCat:mainfrom
Juanpe:clear_cache_after_changing_Storefront
Jun 16, 2022
Merged

Clear cached offerings and products after Storefront changes (2/4)#1583
NachoSoto merged 52 commits into
RevenueCat:mainfrom
Juanpe:clear_cache_after_changing_Storefront

Conversation

@Juanpe

@Juanpe Juanpe commented May 17, 2022

Copy link
Copy Markdown
Contributor

Follow up to #1557. Subtask of #1382

Description

This PR aims to clear the stuff in the cache when the Storefront changes.

Changes:

  • Add clearCachedOfferings method to DeviceCache.
  • Add clearCache method to ProductFetcherSK1.
  • Make internal the clearCache method in ProductsFetcherSK2.
  • Handle the Storefront changes in the PurchasesOrchestator.
  • Add tests to cover some scenarios.

Juanpe and others added 25 commits May 9, 2022 09:29
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
@Juanpe Juanpe changed the title Clear cache after changing storefront Clear cached offerings and products after Storefront changes (2/4) May 17, 2022
Comment thread Sources/Purchasing/ProductsManager.swift Outdated
Comment thread Sources/Purchasing/PurchasesOrchestrator.swift Outdated
Comment thread Sources/Purchasing/StoreKit1/ProductsFetcherSK1.swift Outdated
}

@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
func testClearCachedProductsAndOfferingsAfterStorefrontChangesWithSK2() async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome

Comment thread Tests/UnitTests/Purchasing/ProductsFetcherSK1Tests.swift Outdated
Comment thread Tests/UnitTests/Purchasing/ProductsFetcherSK1Tests.swift
Juanpe and others added 2 commits May 20, 2022 10:41
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>

@taquitos taquitos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome to me, I'd love your thoughts on the .async(flags: .barrier) comment.

Comment thread Sources/Purchasing/PurchasesOrchestrator.swift Outdated
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>

@NachoSoto NachoSoto left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is ready! Looks a lot better with the logic taken out now of both fetchers :)

}

func clearCache() {
self.cachedProductsByIdentifier.removeAll(keepingCapacity: false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻


await productsFetcherSK2.clearCache()

let cachedProducts = await productsFetcherSK2.cachedProductsByIdentifier

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check that this isn't empty before clearing the cache.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point 👍🏼

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done ✅ (9d556b3)

Comment thread Tests/StoreKitUnitTests/ProductsFetcherSK2Tests.swift Outdated
Comment thread Tests/StoreKitUnitTests/ProductsFetcherSK2Tests.swift Outdated
self.productsFetcherSK2 = ProductsFetcherSK2()
}

func testCachedProductsAreEmptyAfterClearingCachedProductCorrectly() async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs try AvailabilityChecks.iOS15APIAvailableOrSkipTest() so it gets skipped on iOS 14.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done ✅ (9d556b3)

@testable import RevenueCat

@available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *)
class ProductsFetcherSK2Tests: StoreKitConfigTestCase {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa we didn't have any tests before? 😕

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope :/

@Juanpe

Juanpe commented Jun 15, 2022

Copy link
Copy Markdown
Contributor Author

I think this is ready! Looks a lot better with the logic taken out now of both fetchers :)

Yeah, totally agree. Thanks for the feedback 👍🏼

@Juanpe

Juanpe commented Jun 16, 2022

Copy link
Copy Markdown
Contributor Author

Hi guys, I made the suggested changes but I didn't re-request the review. Should I do it? Please, let me know, ok? 🙂 Thanks!

@NachoSoto

Copy link
Copy Markdown
Contributor

I'm about to run tests on here and merge this 🎉

@NachoSoto

Copy link
Copy Markdown
Contributor

Looks StoreProductTests.testSk2PriceFormatterReactsToStorefrontChanges is failing:
Screen Shot 2022-06-16 at 09 27 37

Comment on lines +293 to +295
// Note: this test passes only because the fetcher is recreated
// therefore clearing the cache. `ProductsFetcherSK2` does not
// detect Storefront changes to invalidate the cache.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh makes sense.
Can you expand this comment to explain that this is done by StoreKit2StorefrontListenerDelegate?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe it makes more sense to call clearCache() on the fetcher to mimic the real-world behavior?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it's a good point, let me expand it 👍🏼

@Juanpe Juanpe Jun 16, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, I thought the same, but I wanted to use the same logic for both fetchers. 🤔 Although... I agree with you that it would mimic real-world behaviour. Let me change it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done ✅ (645cf5d). I've updated the test cases. Now, we clear manually the cache to mimic the real-world behaviour. Moreover, I've updated the comment to indicate that now, the changes of the Storefront are managed by the SK2 listener delegate.

I think, now it looks better 👍🏼 Thanks!

@NachoSoto NachoSoto left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All tests passing!

@NachoSoto NachoSoto merged commit 9482e8d into RevenueCat:main Jun 16, 2022
@NachoSoto

Copy link
Copy Markdown
Contributor

Thanks again for the hard work with this!

@Juanpe

Juanpe commented Jun 16, 2022

Copy link
Copy Markdown
Contributor Author

Thanks again for the hard work with this!

Thank you all for the feedback and for being so patient 🙂

@Juanpe Juanpe deleted the clear_cache_after_changing_Storefront branch June 17, 2022 07:07
@NachoSoto NachoSoto mentioned this pull request Jun 30, 2022
NachoSoto added a commit that referenced this pull request Jul 4, 2022
### Changes:
* Replaced `CustomerInfo.nonSubscriptionTransactions` with a new non-`StoreTransaction` type (#1733) via NachoSoto (@NachoSoto)
* `Purchases.configure`: added overload taking a `Configuration.Builder` (#1720) via NachoSoto (@NachoSoto)
* Extract Attribution logic out of Purchases (#1693) via Joshua Liebowitz (@taquitos)
* Remove create alias (#1695) via Joshua Liebowitz (@taquitos)

All attribution APIs can now be accessed from `Purchases.shared.attribution`.

### Improvements:
* Improved purchasing logs, added promotional offer information (#1725) via NachoSoto (@NachoSoto)
* `PurchasesOrchestrator`: don't log attribute errors if there are none (#1742) via NachoSoto (@NachoSoto)
* `FatalErrorUtil`: don't override `fatalError` on release builds (#1736) via NachoSoto (@NachoSoto)
* `SKPaymentTransaction`: added more context to warnings about missing properties (#1731) via NachoSoto (@NachoSoto)
* New SwiftUI Purchase Tester example (#1722) via Josh Holtz (@joshdholtz)
* update docs for `showManageSubscriptions` (#1729) via aboedo (@aboedo)
* `PurchasesOrchestrator`: unify finish transactions between SK1 and SK2 (#1704) via NachoSoto (@NachoSoto)
* `SubscriberAttribute`: converted into `struct` (#1648) via NachoSoto (@NachoSoto)
* `CacheFetchPolicy.notStaleCachedOrFetched`: added warning to docstring (#1708) via NachoSoto (@NachoSoto)
* Clear cached offerings and products after Storefront changes (2/4) (#1583) via Juanpe Catalán (@Juanpe)
* `ROT13`: optimized initialization and removed magic numbers (#1702) via NachoSoto (@NachoSoto)

### Fixes:
* `logIn`/`logOut`: sync attributes before aliasing (#1716) via NachoSoto (@NachoSoto)
* `Purchases.customerInfo(fetchPolicy:)`: actually use `fetchPolicy` parameter (#1721) via NachoSoto (@NachoSoto)
* `PurchasesOrchestrator`: fix behavior dealing with `nil` `SKPaymentTransaction.productIdentifier` during purchase (#1680) via NachoSoto (@NachoSoto)
* `PurchasesOrchestrator.handlePurchasedTransaction`: always refresh receipt data (#1703) via NachoSoto (@NachoSoto)
NachoSoto pushed a commit that referenced this pull request Jul 6, 2022
…#1743)

Follow up to #1583. Subtask of #1382.

### Description

This PR aims to invalidate and re-fetch if appropriate the stuff in the cache when the Storefront changes. I've used both `OfferingsManager` and `ProductsManager` to manage the logic of invalidate and re-fetch the data.

Changes:
- Add `invalidateAndReFetchCachedOfferingsIfAppropiate` method to `OfferingsManager` class.
- Rename `clearCachedProducts` method to `invalidateAndReFetchCachedProductsIfAppropiate` in `ProductsManager` class.
- Add `OfferingsManager` as a dependency of `PurchasesOrchestrator`.
- Clear cache methods returns the identifiers of the elements that have been removed or an empty list if there was no stuff in the cache.
- Add tests to cover some scenarios.
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.

4 participants