2

Question:
Where on an iOS-device can small pieces of information (just a few bytes, in my case just 1 bit) be stored, so that they keep available after the app gets deleted from the phone and reinstalled later again?

Background:
I am developing an App that will come into appstore for free. Together with the app comes a free test-package. This test-package gives access to a limited number of items on my server for a limited time. If the user wants, he/she can buy additional packages for more items and for a longer duration.

To use this packages each user must create an account on my server. It is easy to make shure that per each account only one free package can be used. But I don't see a way to hold a user from creating hundrets of additional accounts. So I want more:

I want, that each user (each living person) can only use one free package, independend from the number of accounts he/she will create.

I know, that it is imposible to restrict this at the level of users (living persons). But to restict it on phones is acceptable, since I believe, that there are not many persons using more that 2 or 3 iPhones at the same time. If a single person uses my app on 3 different iPhones just to be able to use 3 free packages with 3 different accounts, then this is acceptable to me.

But to do so, I need to store the information somewhere on the phone, that the free package, that was delivered together with the app, is already in use. But when the user uninstalls the app and reinstalles it later, then this information must still be available to the app. And I don't know where to store this tiny 1-bit-information to stay stored after the app is deleted from the phone.

Can you help?

Hubert Schölnast
  • 8,341
  • 9
  • 39
  • 76
  • I don't think Apple will approve 'limited time functionality' for an app in the store. Whatever you provide, it should be time-unlimited. – Nicolas Miari Jul 19 '12 at 10:50
  • @ranReloaded: The funcionality of the app is not limited by time. the validity of the free package is limited. Also payed packages will have an expiration date. See also my comment to the answer from rockoenes. – Hubert Schölnast Jul 19 '12 at 11:08

4 Answers4

2

The easiest way to solve this is to store the iPhone UniqueDeviceId on your server. Then the next time someone tries to register an account from the device you can check to see if the device has already had an account created.

Apple removed (depreciated) the UDID from the SDK, so an alternative is to use OpenUDID which is available on GitHub. This will give you a unique id to identify a device:

OpenUDID - GitHub

Craig Mellon
  • 5,399
  • 2
  • 20
  • 25
  • 2
    You should not do this, because your are not identifying users but devices. So if I sell my iPhone the new owner will nto be able to user your apps 'demo'. But it could be worse the new owner will see my data if you link an account to the UDID (or OpenUDID). – rckoenes Jul 19 '12 at 10:40
  • I knew that UDID was deprecated from IOS, but I didn't know that there was something like OpenUDID. This sounds like a good idea, I will have a look at it. – Hubert Schölnast Jul 19 '12 at 10:43
  • @rckoenes: Good demur. But I think the chances that someone installes my app on a second-hand iPhone where my app was in use before are very low. But I'll think about this. – Hubert Schölnast Jul 19 '12 at 11:02
  • Apple provides an API to generate an app-specific device identifier different from the UDID (unique for each device, but different accross different apps). If you don't intend to share this identifier with other developers (e.g., ad networks) it should be as good to you as the UDID. – Nicolas Miari Jul 19 '12 at 11:14
  • @ranReloaded: Will this API generate the same device identifier if the app gets deleted from the phone and then a newer version of the same app is installed later? – Hubert Schölnast Jul 19 '12 at 11:28
  • I believe you can also 'share' this ID between your own apps, but not with other developers/publishers. – Nicolas Miari Jul 19 '12 at 11:54
1

There is no such place available in iOS. You can use the KeyChain to store some data to persist if the app is removed. But if the user clears the device these settings will be going to.

There is just not sure way to do this, make an freemium app one should not restrict to use in time but more in functionality.

rckoenes
  • 69,092
  • 8
  • 134
  • 166
  • 1
    the app allows users to store data about books and other media on my server. I don't want to have my server filled up with unused data form thousands of free packages for decades. I want to get rid of those data some day and this is why free packages as well as payed packages have an expiration date (free: 1 month, payed: 1, 2 or 5 years). Payed packages can easily be prolonged by buying additional packages. Packages are also scalable by the number of storeable items (free: 20, payed: 200, 500, 1000, and even bigger packages) – Hubert Schölnast Jul 19 '12 at 10:52
  • Mmhh... Are these 'time limited packages' some sort of In App Purchase products? Subscriptions, perhaps? – Nicolas Miari Jul 19 '12 at 11:11
  • @ranReloaded: Yes, but the service is not only available via iPhone. There will be a website too, and you can buy packages on that site too. – Hubert Schölnast Jul 19 '12 at 11:18
1

This is what i do Hubert Schölnast:

  1. My app requires log in so everybody must has valid log in username and password.

  2. The app is using UUID instead of UDID or any alternatives, and every time when the app talk to the server, it will send both UUID and user's identity to the server.

  3. On the server side, I have database tables store both user's identities and their UUIDs.

  4. On the server side, in the code, I enforce the logic to check the user as well as their UUIDs for every web service call. If they violet the rules, I flag them either in user table or device table based on the rules.

There is still a problem, if they keep uninstall the app and re-intall it, and register with another username every time, then it's hard to identify. But, that depends on how much effort they really want to put to abuse your system.

In my app that's not a problem since the registration as a user is not open to the public.

Hope this helps.

Raymond Wang
  • 1,484
  • 2
  • 18
  • 33
  • I am a little bit confused. Apples UDIDs (Unique Device IDentifiers) are a subset of all possible UUIDs (Universal Unique IDentifiers). So using "UUID instead of UDID" is like using "latin letters instead of consonants" or like talking to "people instead of women". – Hubert Schölnast Jul 19 '12 at 16:16
  • A UUID is something your app is responsible to generate and use it for your app. UDID is device level unique id. Your UDID don't change and apple has already stop programmers from accessing it due to legal issues. For UUID, it's per app instance based, for an app you installed on your device, no matter what you do to the app, as long as you don't uninstall it, you will have the same UUID. If you re-install the app, you'll find yourself getting another UUID. Try it and you'll see what I mean. – Raymond Wang Jul 19 '12 at 18:18
  • Any ID that changes when the app is uninstalled and reinstalled later is of no use for me. – Hubert Schölnast Jul 20 '12 at 05:56
  • Yes I understand your situation. Unfortunately, that's just the way how UUID works. If keychain can fit your needs the best, go ahead and use it man, it is very easy to use. As you said, people still can abuse your system if they really wanna do so, but it is not that easy. Again, it is just how much effort they are willing to put. – Raymond Wang Jul 20 '12 at 13:25
1

I just found the answer myself: Data stored in the keychain will stay there even if the app is deleted and can be accessed from the same app after re-installation. This is exactly what I need.
Only a complete re-installation of the firmware can delete the entries, but this does also delete every other entry of every other app. People won't do that very often, and I think it really is a overkill just to get access to an additional free package for my app. This is acceptable to me.

Apple provides an example-app for keychain-access. I didn't read this example-app in detail, but I'm shur it contains everything I need: http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Introduction/Intro.html


EDIT:

Storing the information as a generic password is the best solution to my problem, but Apples example-app has a bug. In this bug is a wrong attribute used as "unique key" to store generic passwords. For more details and how to make keychain-items really unique look at this question: What makes a keychain item unique (in iOS)?

Community
  • 1
  • 1
Hubert Schölnast
  • 8,341
  • 9
  • 39
  • 76