-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Looking forward to the first stable version #1
Comments
Hi Volodymyr! So glad StoreHelper's been useful for you! I'm getting towards "finishing" SKHelper - it's currently in a beta state. The main driver for doing this new package was to move away from creating my own views and reply on the new StoreKit Views. In particular, using the Also, I wanted to remove all dependencies on the old StoreKit1. This was required to support App Store promotions of in-app purchases. StoreKit2 now support using App Intents for promotions - much simpler. However, it looks like to use this you need to support iOS17 as a minimum. Not 100% sure at this point. Thanks again for the kind words! Russell |
Sounds great! As for iOS 16, we’re considering dropping support, but it feels a bit early—maybe next year? I’m keeping an eye on my app’s analytics. Once iOS 16 usage drops to 5% or less, we’ll likely drop it. Though, I already feel like dropping it now! :) |
Hey Russell,
I have a question about this. Even though we're only using subscriptions and a lifetime (non-consumable) purchase, why is the minimum version set to iOS 18? With this new release, a lot of users are still on iOS 17, and many will continue using it. Setting iOS 18 as the minimum seems too early, as it could exclude a significant number of devices that haven’t upgraded yet. I also know plenty of users who will never upgrade! :D |
Hi Volodymyr, everything absolutely should build correctly for iOS 17. iOS 18 is only required if you want to support consumables. The reason is that prior to iOS 18 StoreKit did not store transaction details for consumables and you had to track them yourself. With iOS 18 consumable transactions can now be accessed via:
You also have to set So, if you were to use |
I see, that’s good. One more question: we’re looking for the ability to track subscription statuses, such as when a user starts a trial and then the next states, like unsubscribed or converted to paid, and so on. Would this be easily possible with iOS 17 as the minimum target(mean any new API's now available)? |
Yes, |
I've just implemented an optional closure that can be passed to the
Let me know if this is the sort of thing you were looking for or not! |
I'm not sure if I should post bugs here, but I just created a simple project, added SKHelper and tried to build it in release mode and got a lot of error like:
|
Ooops! Thanks for letting me know. Will check it out tomorrow (Sunday)Sent from my iPhoneOn 5 Oct 2024, at 15:11, Volodymyr-13 ***@***.***> wrote:
I'm not sure if I should post bugs here, but I just created a simple project, added SKHelper and tried to build it in release mode and got a lot of error like:
SKHelperLog.swift:72:58 Cannot find 'storeLog' in scope
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: ***@***.***>
|
Fixed the logging issue. Also added a new
|
Thanks for the quick fix and the updates! Now it works(probably a new minor release would be pushed soon? Since, I'm using version currently 1.1.2 for SPM) I’m looking forward to easily tracking users who have subscribed, canceled, or converted to a paid subscription state. That would be great for testing! We’re preparing a new class for this to try on our RC app version for future tests. I'll keep you posted as soon as we get some results or bugs/problems :D |
Hey Russell, We conducted a partial release with version 1.1.4 and encountered issues where the Premium status unexpectedly reverted to Free for some users. It seems this issue may be related to the cache, which we had disabled—perhaps I should have clarified this earlier... That said, isn’t cache generally necessary? Why is there an option to disable it? Is it intended for situations where the Premium state is managed externally, rather than by the app itself? |
Hi Volodymyr,
The entitlement cache is used when calling Transaction.currentEntitlement(for:) returns nil. This normally means the user hasn’t purchased or subscribed to the product.
However, if you take a look at the code comments for isPurchased(productId:) or isSubscribed(productId) you’ll see that sometimes Transaction.currentEntitlement(for:) will return nil when the user DOES have an entitlement to the product.
This is what the cache is for. If we have a “positive” result from Transaction.currentEntitlement(for:) at any point we cache it so that if we get a “negative” result in the future we can make an “are you sure that user doesn’t have an entitlement?” check.
As it stands it feels a bit “hacky” (and I had to have something similar in StoreHelper), but without it you will sometimes get results that say a user isn’t entitled to use a product when in fact they are.
As you’ve seen you can disable the entitlements cache, in which case everything will mostly work as expected, but occasionally not!
Russell
… On 3 Nov 2024, at 12:50, Volodymyr-13 ***@***.***> wrote:
@russell-archer <https://github.com/russell-archer>
Hey Russell,
We conducted a partial release with version 1.1.4 and encountered issues where the Premium status unexpectedly reverted to Free for some users.
It seems this issue may be related to the cache, which we had disabled—perhaps I should have clarified this earlier...
That said, isn’t cache generally necessary? Why is there an option to disable it? Is it intended for situations where the Premium state is managed externally, rather than by the app itself?
In our case, we can’t think of any scenario like that; we just want a library that handles everything autonomously without us thinking about that :D
—
Reply to this email directly, view it on GitHub <#1 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABRLWA7YQZMZ6DUCVOYDAVDZ6YLX7AVCNFSM6AAAAABNQF6CJGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJTGQYTMNZXGU>.
You are receiving this because you were mentioned.
|
I meant to say that I will have a look for any issues I can see with the cache when it’s disabled!
… On 3 Nov 2024, at 13:15, Russell Archer ***@***.***> wrote:
Hi Volodymyr,
The entitlement cache is used when calling Transaction.currentEntitlement(for:) returns nil. This normally means the user hasn’t purchased or subscribed to the product.
However, if you take a look at the code comments for isPurchased(productId:) or isSubscribed(productId) you’ll see that sometimes Transaction.currentEntitlement(for:) will return nil when the user DOES have an entitlement to the product.
This is what the cache is for. If we have a “positive” result from Transaction.currentEntitlement(for:) at any point we cache it so that if we get a “negative” result in the future we can make an “are you sure that user doesn’t have an entitlement?” check.
As it stands it feels a bit “hacky” (and I had to have something similar in StoreHelper), but without it you will sometimes get results that say a user isn’t entitled to use a product when in fact they are.
As you’ve seen you can disable the entitlements cache, in which case everything will mostly work as expected, but occasionally not!
Russell
> On 3 Nov 2024, at 12:50, Volodymyr-13 ***@***.***> wrote:
>
>
> @russell-archer <https://github.com/russell-archer>
> Hey Russell,
>
> We conducted a partial release with version 1.1.4 and encountered issues where the Premium status unexpectedly reverted to Free for some users.
>
> It seems this issue may be related to the cache, which we had disabled—perhaps I should have clarified this earlier...
>
> That said, isn’t cache generally necessary? Why is there an option to disable it? Is it intended for situations where the Premium state is managed externally, rather than by the app itself?
> In our case, we can’t think of any scenario like that; we just want a library that handles everything autonomously without us thinking about that :D
>
> —
> Reply to this email directly, view it on GitHub <#1 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABRLWA7YQZMZ6DUCVOYDAVDZ6YLX7AVCNFSM6AAAAABNQF6CJGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJTGQYTMNZXGU>.
> You are receiving this because you were mentioned.
>
|
@russell-archer Thanks!
Users who reported this issue were able to restore their premium version using Restore Purchases, so I think it's simply due to a lack of internet connection when running the app. |
Here’s an edited version of your message: @russell-archer, with cache enabled and the updated release, I haven’t encountered any issues so far, but I’m still in the testing phase. I do have a question: after initializing SKHelper, I noticed the following log output:
Our main goal is to use a public library for handling all in-app purchases within our app. However, we are not using the library exactly as intended; while we leverage its core functionality, we use custom product models, so we don’t need SKHelper as an Observable. Given this, we have a couple of questions: • Is it possible to make the requestProducts method optional? |
Re your log output. That's not what I see. The call to requestProducts() is made in the SKHelper initializer, so somehow you're creating SKHelper twice. or maybe you're calling requestProducts() separately as well? I could certainly create a convenience initializer and not call requestProducts() in that case. However, requestProducts() also builds the cache of entitlements. Re making SKHelper more modular. I know what you mean, but it kind of goes the opposite way in which I'd intended. With StoreHelper (which was more modular I think) it had become overly complex. With SKHelper my intention was to have the minimum of custom StoreKit code and rely as much as possible on SwiftUI StoreKit Views. So I was really not intending to support UIKit. This is, of course, because I created SKHelper to fit my needs :-) |
Yes. So if it used as part of the cache this might not work well.. all right, so perhaps this might not be a good idea if disabling it..
Well, our goal is to always use new things and use the latest technologies. Our application is made entirely on SwiftUI, the minimum version is iOS17. |
@russell-archer I tested with the debug build using a sandbox account with purchased a non-consumable in-app purchase for premium access. So the app was Premium state. Another test, when cached Premium state, then even after logging out of the actual App Store account - premium access remains... this I call like too aggressive) or maybe I'm wrong, don't have that experience.. perhaps its ok to keep this state for a several days.. So I’m wondering, how long this state persists? What would happen in cases of billing issues, subscription cancellations, or account logouts in terms of days or how this is managed..? UPD: |
@russell-archer And what about logs, can I disable them? So far I can see a lot of: |
Hey Russell!
I’m really excited about this—it’s just the lightweight and modern in-app package we’ve been looking for!
Currently, we’re using StoreHelper for subscriptions and non-consumable in-app purchases, and it’s been working well. However, your package aligns perfectly with our goals of adopting the latest technologies. We’re targeting iOS 16 (16.4 could be) as our minimum and always aim to use the latest Xcode.
This is exactly what we need, and we can’t wait to integrate it into our app. We’re eager to test it out, report any bugs, and provide feedback. Once it’s ready for a first release candidate, like version 0.1, we’ll definitely give it a try and contribute to its improvement if needed.
The text was updated successfully, but these errors were encountered: