Where to store a piece of important data (away from users) that will be backed up by itunes - ios

I am currently making an app and there is an important piece of information I need to store. The user can make a one time in-app purchase.
My question is, what is the apple recommended or approved method for storing this?
No. 1 is most important to me. For example imagine the user can purchase 10 lives. After his purchase he will use some of them so imagine he now has a balance of 5. Where should this number be stored.
The issues or thoughts or random ideas I have as a result of reading things are;
if its saved in a simple file then a jailbreaker can just go in an
edit the file.
if its saved in an encrypted file I think I have extra issues with my
app/Apple/certain countries because I am using encryption.
what happens when the user accidentally removes the app. He cannot
restore his purchases as its a one time purchase
should I be and how should this important piece of information be
backed up on a sync
how do I ensure this information is saved as part of a backup.

I am not sure there is one answer to this problem. In my case I save the information in the keychain. Other iOS SDKs such as Amazon's or Facebook's do the same thing as far as I can see.

Related

How to restore consumable In App Purchases?

I want to restore consumable In App Purchases for a game. This game has only consumable in app purchases such as:
$0.99 for 1000 coins
$1.99 for 3000 coins
Using NSUserDefaults to persist the coins is not good because the user could delete the app and when they reinstall, they lose their coins. Also Apple has a restoreCompletedTransactions method but this isn’t for consumables so the developer has to keep track of this.
Please don't mention to use GameKit (Game Center) or a Web Server. Are there any other solutions? I've read that iCloud and Keychain are two other possible solutions (not sure if these are good for this).
PS: There are many answers on SO that are a few years old and that won't work for my case, so I am asking here again.
Keychain and iCloud is what you are looking at. Keychain data will also not be deleted when you uninstall the app.
There is a good helper on GitHub for keychain, which makes using it a breeze.
https://github.com/jrendel/SwiftKeychainWrapper
General read about data storing
How secure is NSUserDefaults on iOS 8,9?
To store your data in iCloud you should use key value storage for small data.
I use a singleton class to handle all this. For a simple example check out this answer I posted
SpriteKit: Why does it wait one round for the score to update? (Swift)
which is based in this great article
https://www.raywenderlich.com/63235/how-to-save-your-game-data-tutorial-part-1-of-2
Hope this helps

iOS in-app purchase for a paid app

I created an app which is a paid app. Now I want to make it free so more user can download the app and use in app purchase to limit some features. But some user already paid to buy my app. How can I implement in app purchase for new user at the same time keep full feature access to old user?
If you connect to your server for registering user info, you can always create an API which executes on app launch to verify that user is full access user or not.
But I am afraid your case is not the above one.
In that case you would require to sync your data (some encrypted key in this context) with iCloud and when application is launched you can verify the type of user.
Using data in iCloud is more safer as compared to keychain as it covers device format scenario. But definitely not foolproof.
Other solution can be using Apple Purchase Receipt to verify the version of previous purchase. But this is only supported since iOS7.
Checkout some opensource libs to understand the parsing of receipts:
https://github.com/rmaddy/VerifyStoreReceiptiOS
So combining multiple strategies is the only answer for your question.
You can do this by reading the App Store receipt. The receipt contains the version number and date of the original purchase.
There are two main caveats: first, this only works on iOS 7 and above. Secondly, Apple don't include code for parsing the receipt (so it's not too easy for users to hack I understand). There are, however, onen source libraries, though using a common one will be less secure.
There are no perfect solutions to this scenario.
Suggestion 1:
Roll out one last paid update. In this update, use keychain to store those IAP flags. Then in the free version, check for these flags in keychain. This will work even if app was deleted and reinstalled with the free version later. But it will not work if the device is being reset completely whether due to some iOS version updates or user's unless a backup and restore also is involved.
Suggestion 2:
Not quite a suggestion. But I have seen similar apps on AppStore have just rollout free version. Then app incurred bad reviews from those previous users!
This is a simple example, but if you're working with a database on a server (not on the phone itself), can't you use a boolean for each feature you plan on selling, and just set that boolean to true for all users currently in the database. This is assuming true means they've bought the feature, and false means they haven't bought it.
You could run this query once after releasing your updated app, and then every user after that would have a default value of false for these features you're selling.

Stop deleting and downloading apps again to gain free access

I want to offer my app free for a period and then charge to continue using it. I understand that the way to do this is to force the user to buy an In-App product after the free period. However, if I simply record the date that the user starts using the app in the standardUserDefaults and use this to calculate when the user must buy the upgrade the user could simply delete the app when the time arrives (I assume the sandbox is also deleted) and download the app again for another free period.
First question. Is my reasoning so far correct?
Second question. Is there any way of accessing the date that an app is first downloaded?
Assuming the answers to these questions are Yes and No I have come up with the following solution.
Upon downloading the app the user is first forced to "buy" free an In-App product which then will have the date it was added to the transaction queue. This In-App product would then be downloaded for any subsequent download and I could use the date of this product as my reference date.
As I can find no reference to this problem or solutions I really wanted confirmation that this was a sound way to proceed or if there was another more standard way of dealing with the problem.
Thank you
Silas
You are not allowed to limit you app for free for a limited period:
11.9 Apps containing content or services that expire after a limited time will be rejected, except for specific approved content (e.g.
films, television programs, music, books)
If you want to risk it, you could save the date (encrypted) in keychain to make it more persistent. Just so you know, user are able to access their keychain data if they iCloud keychain sharing and are on a Mac. So if they delete the correct key or rest there device your app will fall back to the free/trial mode.
This does not seem entirely consistent with:
Communicate the value of your products to your users. Users want to
know exactly what they’re going to buy. Combine information from the
App Store, such as product prices and descriptions, with additional
data from your server or the app bundle, such as images or demos of
your products. Let users interact with a product in a limited way
before buying it. For example, a game that gives the user the option
to buy new race cars can allow users to run a test lap with the new
car. Likewise, a drawing app that lets the user buy additional brushes
can give users the chance to draw with the new brush on a small
scratch pad and see the difference between brushes. This kind of
design provides users an opportunity to experience the product and be
convinced they want to purchase it.
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/ShowUI.html
One way of letting the user interact with a product feature in a limited way is to let them use it a few times before requiring that they pay to use the feature.

iOS in-app purchase free / paid persistence

I am building a game that will be free to play, and will include 100 free consumable 'hints'. I intend to offer more hints for purchase through in-app purchase. My current method is to store a file locally with the number of hints the user still has left. When the game is first downloaded the local file doesn't exist, so a new file is created with 100 hints. When an in-app purchase happens, it simply adds to the number of hints. (In the game, each hint simply removes a choice from a multiple choice question - the file simply stores a counter.)
My problem: A user could simply delete the app when they have 0 hints remaining (which will delete my local file that has a count of 0), re-download the app from the app store and they will then start again with 100 hints.
My question: How do I prevent this? Is there a different method I should use for storing hints?
use the Keychain to store your data, because the Keychain items are not deleted even if the app is Uninstalled or removed. This Api will help a lot link, have a look
or
You can refer to Apple's documentation on Keychain data
If you are going to offer some part of your hints as an in-app product, I suggest you to keep track of all your hints (both purchased and free) on a server. This way you can keep track of each user and even if they delete and re-download your app, you will still be able to keep track of your hints.
Edit: If you are implementing IAP you might find it healthy to keep track of your purchased goods anyway (ie. keeping track of your purchase statistics, watching out for fake in-app purchases, etc.)
usualy you use a server for such things, so not the device but the account is the interesting. Also a good possibility to save your progress and share to other devices ;)

How do I protect in app purchase content? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Secure way to unlock full version via In-App Purchase
What is the recommended way to protect content which has been downloaded following an in-app purchase from being copied to another device? The typical process seems to be copy the content to the 'Application Support' folder and set a flag in the NSUserDefaults. Both of these could be updated by someone accessing the iOS device via Finder or similar. If I store the transaction receipt, that could also be copied across.
I can potentially use the restoreTransactions functionality to validate when the device is online, but that requires the user to enter their password, so it isn't a silent background check and obviously wouldn't work if the device is offline.
I'm tempted to use a device ID to tie the content to the device when it is downloaded, but Apple advise against using this.
Am I missing something?
As you mentioned saving it the state in the NSUserDefaults is easily edited, but save the state in the KeyChain makes it harder for the user to change the flag state for a download.
I save all my IAP download state in the KeyChain, there by make sure that you can't just set the key to true in NSUserDefaults.
In a game we developed we also check server side if the user has bought the game item (also including the recept checking).
In a reader we made the PDF is password protected, via a sort of random code based on the name plus some secret stuff ;)
My guesses are that this should make you are less easy to crack, just keep in mind that you can't also keep a head of the crackers. But you can definitely slow them down.

Resources