In App Purchases (IOS)

Hey all,

I´ve added in app purchase to my app following and I am wondering two things. I´ve added a “remove ads” purchase.

So, how would I go about to check that It has been purchased and then remove the ads? Do I stamp the app with a value the moment the purchase is done successfully, or should I check app store every time the app starts or … ? Previously on another app, but using native android, there was an api call I made on start of the app to check what purchases was done. Is there something similar here?

Why would I validate the purchase on my server, as suggested in the same blog ?


Why you don’t use ngCordova inAppBrowser plugin?

If you can implement your own payment system, you can do this with inAppBrowser after user closed the payment window :

$rootScope.$on('$cordovaInAppBrowser:exit', function(e, event){
    // now send an http request to check whether payment was successful or not
    // if yes, then store a key in your localStorage

Yeah, gotcha. Just store the result in Localstorage. Cool Thanks. I wasn´t sure that was a good enough solution.

Now, I am not sure I follow on using cordovaInAppBrowser to make purchases?

I have already asked the same question about last year. Be sure for using this.

But there just a small issue in cordova inAppBrowser that I asked yesterday here. If you implemented this, please let me know whether you confront with this issue or not.

I just don’t understand how you can use this with InAppPurchases?

On the success callback of a purchase just add some kind of flag and store it using SQLite - don’t use local storage because it can be wiped. Also make sure that you have a way for users to restore purchases (basically just trigger that same process, you’ll get a callback and then store the flag in storage), otherwise your app will be rejected. If a user removes ads from your app on one device, that purchase needs to be able to be applied to any device they use (the restore purchases option solves this).

@joshmorony localStorage never expire! Both localStorage and SQLite will be removed after app unistalling. So there is no different in this point. For this case it’s better to use localStorage to store only a flag. No need to implement local database.

@Lona I didn’t mean using both inAppBrowser and inAppPurchase.

Unless something has changed recently, localStorage isn’t permanent. Anything you store in local storage will likely stick around, but it can be cleared by the OS at any point. So you could store a value and it works fine for 2 months (or forever), but it could disappear at any time.

@joshmorony is correct. Local storage is NOT permanent. Especially true for iOS that is quite aggressive in clearing it (unlike Android). I have a user base with several thousand android devices and iOS devices using my app and I’ve learned the hard way that local storage + iOS == recipe for disaster somewhere down the line when it comes to data persistence.

My app data kept getting deleted for some users. I switched to localforage - SQLite for iOS. For android on only on some phones SQLite seems to randomly hang depending on length of data being stored. So I am using indexDB for android.

1 Like

@joshmorony @pliablepixels That’s sessionStorage not localStorage. As docs mention us:

while data stored in localStorage has no expiration time.

But you shouldn’t worry about missing local storage. Imagine a user registered from device A, then uses device B. We don’t have any storage in device B. So, in this case user is known as unpurchased!

So when the app runs, we must check the server to see whether the user is purchased or not and then update our storage.

EDIT: It can be some difference approaches in ios. Recently I confronted with an strange problem in ios. You can read more about that here. :sweat_smile:

no that is not correct. Having no expiration time doesn’t mean it won’t be deleted. Operating systems can clear localStorage when disk space is low. (read 2nd answer)
iOS localstorage persistence (read through)

and many other posts on stack overflow.

And one more issue. As you know SQlite is an async request unlike local storage, so in each part of an authentication system, user will be able to see the view if it’s not authenticated.
event.preventDefault() will work after rendered view.