Re-fetch cached offerings and products after Storefront changes (3/4) #1743
Conversation
… OfferingsManager as dependency
| } | ||
|
|
||
| func clearCachedProducts() { | ||
| func invalidateAndReFetchCachedProductsIfAppropiate() { |
There was a problem hiding this comment.
I'm not sure here if we should log the error when the re-request fails. WDYT? 🤔
| return productIDsFromBackend.subtracting(productIDsFromStore) | ||
| } | ||
|
|
||
| func invalidateAndReFetchCachedOfferingsIfAppropiate(appUserID: String) { |
There was a problem hiding this comment.
I didn't add any test case to cover this logic. The problem is the OfferingsManager tests file belongs to the UnitTests framework I'm not sure if we should move it to StoreKitTests framework in order to be able to change the Storefront. I also thought about creating another test file called OfferingsManagerSKTests that contains the test cases related to StoreKit. WDYT? 🤔
There was a problem hiding this comment.
I also thought about creating another test file called OfferingsManagerSKTests that contains the test cases related to StoreKit. WDYT?
Yeah that makes sense, we do that for other classes 👍🏻 Maybe OfferingsManagerStoreKitTests
NachoSoto
left a comment
There was a problem hiding this comment.
This looks great! Just a few suggestions.
| let cachedProductIdentifiers = self.cachedProductsByIdentifier.keys | ||
| if !cachedProductIdentifiers.isEmpty { | ||
| self.cachedProductsByIdentifier.removeAll(keepingCapacity: false) | ||
| } | ||
| return Set(cachedProductIdentifiers) |
There was a problem hiding this comment.
I was like "this is a race condition!". Then realized this is an actor 😄
| await productsFetcherSK2.clearCache() | ||
| let removedProductIdentifiers = await productsFetcherSK2.clearCache() | ||
| if !removedProductIdentifiers.isEmpty { | ||
| _ = try? await self.productsFetcherSK2.products(identifiers: removedProductIdentifiers) |
There was a problem hiding this comment.
I think this makes sense 👍🏻
Maybe we can add a debug log here? :)
There was a problem hiding this comment.
Do you mean only when the request fails or just to inform that the products have been re-fetched? 🤔
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>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Thanks for the feedback 👌🏼 I made the suggested changes. LMK if you find anything else that could be improved 👍🏼 |
NachoSoto
left a comment
There was a problem hiding this comment.
Cool I think this is ready.
| // changes to invalidate the cache. The changes are now managed by | ||
| // `StoreKit2StorefrontListenerDelegate`. | ||
| sk1Fetcher.clearCache() | ||
| sk1Fetcher.clearCache { _ in } |
There was a problem hiding this comment.
You should be able to revert this now with the optional completion
| // changes to invalidate the cache. The changes are now managed by | ||
| // `StoreKit2StorefrontListenerDelegate`. | ||
| await sk2Fetcher.clearCache() | ||
| _ = await sk2Fetcher.clearCache() |
| expect(cachedProducts).notTo(beEmpty()) | ||
|
|
||
| await productsFetcherSK2.clearCache() | ||
| _ = await productsFetcherSK2.clearCache() |
| // changes to invalidate the cache. The changes are now managed by | ||
| // `StoreKit2StorefrontListenerDelegate`. | ||
| sk1Fetcher.clearCache() | ||
| sk1Fetcher.clearCache { _ in } |
| // changes to invalidate the cache. The changes are now managed by | ||
| // `StoreKit2StorefrontListenerDelegate`. | ||
| await sk2Fetcher.clearCache() | ||
| _ = await sk2Fetcher.clearCache() |
| mockProducts.forEach(self.productsFetcherSK1.cacheProduct) | ||
|
|
||
| productsFetcherSK1.clearCache() | ||
| productsFetcherSK1.clearCache { _ in } |
| let cachedProductIdentifiers = self.cachedProductsByIdentifier.keys | ||
| if !cachedProductIdentifiers.isEmpty { | ||
| Logger.debug(Strings.offering.product_cache_invalid_for_storefront_change) | ||
| self.cachedProductsByIdentifier.removeAll() |
There was a problem hiding this comment.
Maybe add keepingCapacity: false here too?
There was a problem hiding this comment.
Just to be sure, is there a possibility that there may not be the same number of products in different Storefronts?
There was a problem hiding this comment.
Oh no, it should be the same. I was just suggesting that since you had keepingCapacity: false in the SK2 version. Might make sense to empty cache storage in both cases?
There was a problem hiding this comment.
yep, well, keepingCapacity: false was already in SK2 and false is the default value, but I think it might be a good idea to explicitly state that we are completely clearing the storage 👍🏼
There was a problem hiding this comment.
I was just asking to be consistent hehe 👍🏻
…thub.com/Juanpe/purchases-ios into refetch_products_after_Storefront_change
|
There's a couple lint issues in |
Oups, you're right. I've disabled this rule for these properties. (9988fb5) BTW, my local copy of the project has 35 warnings related to the linter. Is it ok? I checked and I think I have the config files up to date 🤔 |
NachoSoto
left a comment
There was a problem hiding this comment.
Weird. What version of SwiftLint do you have? I wonder if there a new rule that got added?
| var invokedInvalidateAndReFetchCachedOfferingsIfAppropiate = false | ||
| var invokedInvalidateAndReFetchCachedOfferingsIfAppropiateCount = 0 | ||
|
|
||
| // swiftlint:disable identifier_name |
There was a problem hiding this comment.
This is just my technique, if you're disabling a rule next to the code that breaks it I'd either re-enable it afterwards or do disable:next. Otherwise I would move this to the top of the file.
There was a problem hiding this comment.
Makes sense. I used this technique because this code is at the end of this file and as far as I know this disable only affects the code below. However, I agree with you that we need to re-enable this rule after code because we may add more code in the future that would be affected by this disable. Let me change it 👍🏼
|
I made the change. Finally, I disable the BTW, in order to make all the necessary changes...could you please review the comment related to keep the capacity after cleaning the cache? Thanks for the review and the feedback! 🤙 |

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
OfferingsManagerandProductsManagerto manage the logic of invalidate and re-fetch the data.Changes:
invalidateAndReFetchCachedOfferingsIfAppropiatemethod toOfferingsManagerclass.clearCachedProductsmethod toinvalidateAndReFetchCachedProductsIfAppropiateinProductsManagerclass.OfferingsManageras a dependency ofPurchasesOrchestrator.