Where should I store data that needs to persist for a given appleID? - iphone

The answer to this question may be iCloud storage, but I am using this for a very light-weight piece of data and think it may be extreme to use iCloud for this one purpose. We have an in-app subscription app. Before we provided the app for free but would not deliver any content to it until the user subscribed to content through the in-app subscription.
Some reviews indicate people think that we are trying to trick them by saying free and then saying they have to subscribe. We want the app to be listed as the price of the subscription to avoid this misunderstanding but after the first year has elapsed offer them the in-app subscription to continue. We plan to store the initial launch date in persistent storage so that we can determine when to begin requiring a subscription receipt.
1) We wanted to use the keychain storage since this information will persist even if a user removes the app from his/her device and then re-installs. The problem is if the user gets a new device and does not restore it from an encrypted backup, then the initialized value will be lost.
2) If we use our servers to store this value for them, then there seems to be no way to tie it to that appleID; so that is ruled out as a possibility.
3) Back to iCloud, it just seems like a lot to add iCloud support just for this, and I believe the user still has to have iCloud enabled for this to work.
Does anyone know the solution to this data persistence problem? Help is appreciated!

Yes, nsubiquitouskeyvaluestore is the way to get it synched with new devices. Using this in conjunction with both keychain for storing on a device after app as been removed and nsuserdefaults for quick and easy unconstrained access is the way to go. Apple also has a way to read receipts for the actual app purchase now, but it only works for iOS 7. Solutions should conditionally rely on receipt data from nsbundle.mainbundle url if it is available.

Related

iOS give users default downloadable content

I'm facing this problem while designing my iOS app. Suppose that a user purchases an app and downloads it to the iPhone. I would like to provide him with a default consumable item the first time he runs the app to use whenever he wants , however I would also like to track if the user has already consumed the item. This way if he decides to reinstall the app we can restore the transactions (if he used the item) or we can avoid possible intents to download different kind of content by reinstalling app and consuming default items each time. (Guess NSUserDefaults is not an option here).
One approach that came to my mind was using UDID(or any iOS 6 alternatives) to keep a record on server of the user's device the moment he uses the default item. But this will limit items just to the device from which they consumed content.
It would be great to support all the user's devices (like inAppPurchases), but I can't figure out a way to implement this.
Any suggestions or help would be great.
Thanks a lot.
In order to tie information to a user (not just a device she used at one time), you'll need to ask the user to identify herself and save it someplace other than the device. In other words, a backend that implements registration and login.
From scratch, this can be a lot of effort that an iOS developer didn't count on. Fortunately, there are several services in the world that provide a substantial head start. Here's a nice round-up. I've had direct experience only with Parse.com, and think it's excellent.

Do apps need to ask user preference in order to use iCloud for simple data?

We are currently working on an app and would like to sync favorites across devices using iCloud. The favorites are fairly lightweight and text only. Do we need to ask the user for permission to use iCloud or can we simply go ahead and use iCloud if available?
I have setup all iCloud syncing code already. So it is more a question about AppStore submission rules. Any experiences?
Apple guidelines state that you should invite the user to use iCloud, and give them the choice as to whether they want to use it or not. (Documentation, see "Prepare Your App to Use iCloud").
As per the App Store Review Guidelines, there isn't a concrete rule that states you need to do this, it's more of a guideline and a courtesy. I'd suggest you do though, it provides a better user experience, and happy customers.
Why should I need permission anyway?
Users only have a limited amount of storage (typically the 5GB allowance), and it's up to them how it should be used. If all applications decided to use iCloud without permission, it'd be a free-for-all, and space would be eaten up fast.

How should an iOS app prevent consumable items from being reused?

Probably a newbie question, I am using the Verify Store Receipts API to verify purchases of consumable items. How can I mark these items consumed so that the same receipt cannot be used again? Is there any option other than storing the used receipts?
Perhaps you could use a backend service to track receipts. Parse has brilliantly simple SDKs for iOS and Android that make it easy to persist bits of data to a provided server.
You could use iCloud (or normal UserDefaults) for that. However, you will probably prefer using your own servers.

StoreKit: can I offer a user a free download for a product of his choice that normally costs?

I'll soon have to implement the StoreKit functionality and I was wondering...
is there a way to also offer a product for free to a user once, like as a gift for using the app for the first time ?
In my special scenario I'll offer several products in my educational app, which the user will need to buy time by time, if he is interested in continuing to learn with the app.
But the first product I want the user to have for free and it should be his choice which one he takes. So generally all products should have a price, but the first download shall be free.
And I want this to get logged on my server so I can reidentify him, so (A) he can't delete the app, reinstall and download yet another free product and (B) so he will also get the products on any other of his devices.
I'm also open to workarounds, like maybe get something similar to the apple id or so, to be able to store it on the server. I know that I could also use the [[UIDevice currentDevice] uniqueIdentifier], but I want the user to have this first free product on all his devices, and ONLY ONE.
Is there a way to get (A) and (B)?
Apple's In-App Purchase infrastructure (and by extension, StoreKit) does not support free content.
But there's nothing stopping you from providing free content via your own mechanisms, as you surmise. You would have to do all the tracking yourself in terms of remembering device IDs on a server somewhere, and noting that device != user, so would miss some edge cases.
You don't get access to (iTunes) user data at all, so you probably can't guarantee the "only once" across multiple devices, unless your app has an associated backend service account that is already unique per user.
(Before building infrastructure for this, you should double-check the developer agreement/contracts on this stuff. You're not circumventing Apple's revenue stream here, which is good, but what you're talking about may be unusual enough to raise a flag with them in terms of experience consistency if nothing else.)

iPhone trial period for app

I need to implement trail period in my app. How to do it? Store day count in NSDefault? or some other?
You could store a counter in the preferences as you mention, although that counter would disappear if the user reset their phone.
However, I think it's all slightly besides the point. In general, Apple frowns upon apps that have this kind of functionality, so don't be surprised if your app gets rejected. Consider launching two different versions of your app instead, a "Lite" app and a "Full" app. The Lite app should have a reduced feature set, but it should never stop working.
Apple is against the idea of you disabling features to prompt people to pay money for something. Your app needs to be fully functional and a 'lite' version and a paid version seems to be how things work at the moment.
That being said - if you implemented it properly you could add in app purchase items to enhance your app. Your original 'lite' app could be $0 and additional features can be added for a fee.
The most bullet-proof method would be to send and maintain a copy of the iPhone's UUID in a database.
Then if the App is not "unlocked" it requires a "key" form the database every time it launches. You can then implement the trial period on the server side.
However, if you decide to use some type of encryption to store or transmit keys etc you will need a licence to distribute the App.
You make a light version of your app. There is no official way to have a trial version at this time. Hopefully Apple will eventually address the need, but I can't say I would hold my breath...