Will iCloud keep user's data that was belonging to a deleted app? - iphone

My use case is:
User downloads my app and uploads some data/Files onto iCloud within the sandbox of my app.
User deletes my app
Questions:
Will iClould keep user's data that was belonging to the deleted app? (Based on my experiment, the data is kept on iCloud when my App is deleted, however, I am not sure whether the behaviour is official).
If the answer is Yes, then I have the following questions:
a. How user's data eventually get deleted/cleared from user's iCloud storage? (My concern is that if the user decide never to use my app again, the data would become useless therefore should be cleared on iCloud to free spaces)
b. If user decide re-download my app, how can he get access to the data iCloud he originally uploaded?
c. Can I manage the user's data from iCloud web portal (www.icloud.com)? I don't see my uploaded document appears in iCloud web portal, even I put my files under "Documents" subfolder.
d. Is there any official documentation that describes this behavior?
Thanks in advance!

Yes, iCloud will keep a person's data belonging to the deleted app by default.
Follow up questions
A: The data will stay in iCloud storage until the person decides to delete the data. Using the Settings app, a person can manage their iCloud storage, down to turning off backups of each app's storage. Or the entire backup for a device can be deleted to start over with a fresh backup.
B: If a person reloads an app on their iOS device, meaning any app with the exact same App ID so it could be an updated version, iCloud should restore the data from the app's backup.
C: No, the iCloud Web portal only gives access to the apps loaded by Apple, currently Mail, Contacts, Calendar, Find My iPhone, and iWork. Apple could offer the ability to add apps to the iCloud Web portal, just like we add apps to our iOS and Mac devices. But that would be some future offering.
D: Much of this is documented in the developer documentation. Some of this answer is undocumented, and gleaned from experimenting with iCloud (so please correct me where I'm wrong).

Related

How Can I Setup My iOS App To Use Automatic iCloud Backup?

I have written an app the uses the RealmDB, which produces a file called default.realm. This is the database storage file. I would like to setup my app to make use of the iCloud automatic backup feature. How can I setup my app to do this?
You can't! Because your app is already set up like that! :)
According to the File System Basics page on Apple's website, all files in an app's Documents folder will automatically be backed up to iCloud, or the user's local iTunes account if they've chosen such. This is on by default, and must be explicitly disabled through code if disabling backup is desired.
By default, Realm places default.realm in the Documents directory for this exact reason: to ensure any user-generated data stored in it will be properly backed up in through iCloud and/or iTunes sync operations.
So you don't need to worry! Your Realm data is already being properly backed up by iCloud as we speak! :)

How to update iOS app with exception of a file

I'm making my first iOS app. And I have a question.In my app I want to save the current state of the app: levels completed, score reached, money, in-App purchases, etc. in a Settings.plist. The problem is, how can I place this plist so that if the user updates the app, he/she not to lose these settings. I read about The app sandbox, but I don't understand
how it works, and how can I manage that from Xcode.
You should store these settings in the NSUserDefaults. They are kept when new app versions are installed, so you won't have any problems.
Two points:
a) When you update your app after its in the app store by submitting a new version of the same app the files created by the old version will not be lost. So you can store whatever you like in the app's Document or Library directories and expect it to still be there after an update. The Library/Caches directory will not be backed up or restored by iTunes so don't put anything there that you can't re-create. If you submit a different version of the app (not an update but a new app, so you have two separate apps in the app store, perhaps free and paid) there is no way that I know of for the new version to get to the files that the first version created.
b) It's easy for the user to read, delete, or change whatever files you create in Documents/ or Library/. It can be done with an app on his/her Mac such as iExplorer (downloadable from macroplant.com). So be aware that if the file is human-readable, which a .plist file is, the user can change it to improve his/her score, get more consumables, or whatever. You can prevent that by encrypting the data, or somehow obscuring the meaning, or by some kind of checksum scheme so you can at least detect that it was changed. Any of those measures involve complications of course and may not be worth the trouble.
BTW... if you're developing an app that uses data files iExplorer is a great debugging tool. I have no vested interest in it except that I've learned how to use it and want it to continue to be supported. There are probably other apps that do the same thing but this one works great and is fast and easy to use.

Can downloaded images/files be added to my app bundle?

I have an app that allows me to download characters (images), sounds, etc. When the user chooses which character to download can I store that in a directory in my App Bundle? If not, where is the best place to store my content (data)? I was thinking the documents directory, but then I saw somewhere that Apple now wants data stored in the caches directory.
Thanks for the help.
can I store that in a directory in my App Bundle?
No, you can not modify the app bundle.
If not, where is the best place to store my content (data)?
If your app must support iOS 5.0 or earlier, you will need to store your app data in the Caches directory. However, keep in mind the files could be deleted in low space situations so your app will need to degrade gracefully if your app data is deleted.
As of iOS 5.0.1, you can store your data files in the Documents Directory and flag them as "do not back up". By flagging the files, your app complies with the guideline that apps are responsible for ensuring that only user data and not application data is backed up to iCloud and iTunes and avoids a possible rejection by Apple. In this case, the files will not be deleted in low space situations.
As of iOS 5.1, you can store your data files in the Documents Directory and use either NSURLIsExcludedFromBackupKey or kCFURLIsExcludedFromBackupKey file properties to exclude files from backups. Either of these APIs is preferred over flagging them as "do not back up". In this case, your app complies with the App Store guidelines and the files will not be deleted in low space situations.
I know that this is quite a long discussion, but you should probably read it. :)
The iOS Data Storage Guidelines state:
To ensure that backups are as efficient as possible, be sure to store your app’s data according to the following guidelines:
Only documents and other data that is user-generated, or that cannot otherwise be recreated by your application, should be stored in the /Documents directory and will be automatically backed up by iCloud.
Data that can be downloaded again or regenerated should be stored in the /Library/Caches directory. Examples of files you should put in the Caches directory include database cache files and downloadable content, such as that used by magazine, newspaper, and map applications.
Data that is used only temporarily should be stored in the /tmp directory. Although these files are not backed up to iCloud, remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device.
If you have an OS X or Unix background, it’s easy to understand Apple’s position that such directories have no guarantee as to how long the data in them will persist.
The fact that the tmp directory in in the app’s sandbox is not the same as the root /tmp directory, should not make a difference how you think about this directory.
If you have never observed files being removed from these directories in the past, that is not a guarantee that it will not change in the future. Especially when the change is in accordance with documentation. This is a general rule.
Changes/gaps in Apple’s documentation:
As late as June 29, 2011 Apple’s documentation regarding /Documents said:
Use this directory to store user documents and application data files.
This is pretty clear. No wonder developers are unhappy that the rules for the Documents directory have changed in iOS 5 without any suitable alternative.
Regarding /Library/Caches:
Use this directory to write any application-specific support files that you want to persist between launches of the application or during application updates. Your application is generally responsible for adding and removing these files. It should also be able to re-create these files as needed because iTunes removes them during a full restoration of the device.
App review rejections
Developers are reporting that apps that store any/some/much data in the Documents directory are being rejected by App Review.
It’s unlikely that the App Review team has detailed knowledge of which files are being stored in which directory and which of those are user generated vs. data that can be downloaded again or regenerated. Some developers have reported success in responding to the App Review team with an explanation of how their app is storing data and how that is in accordance with the rules.
What is being backed up by iTunes and iCloud
Everything in the app’s home directory is backed up, with the exception of:
The app bundle itself (.app)
/tmp directory
/Library/Caches directory
Other documentation clearly states that the Application Support directory is also backed up by iTunes (and presumably iCloud). In the discussions some developers have suggested that Application Support directory would be safer (= more permanent) alternative to Caches. To me it seems that App Review would crack down on large amounts of data stored in Application Support with the same fervor as for the Documents directory, since it’s all about iCloud storage.
Changes in behavior in iOS 5
As of iOS 5, /Library/Caches may be purged while your app is not running if the device experiences a low disk space warning.
There is no longer a directory where your app can store files that are:
Not backed up to iTunes/iCloud
Not at risk of being purged
Downloaded content should not be stored in the Documents directory according to Apple's Guidelines:
Only documents and other data that is user-generated, or that cannot otherwise be recreated by your application, should be stored in the <Application_Home>/Documents
Use the /Library/Caches directory instead
Data that is used only temporarily should be stored in the <Application_Home>/tmp directory.

saving a file outside of my application bundel in iphone

i want to save a file outside of my application bundle as a backup of database so that when user reinstall my app or my app crashes he can backup his data from that location.
Apple already does this, with iTunes.
What you are asking is technically against apple's policy, unless you store it off site, on a server (which you could easily do)
If you have a lot of applications, I'm not aware of the policy, but perhaps you could make an app to back up your other app's data.

iOS -- How to save in-app purchase data?

I'm planning on implementing some in-app purchase items and I want to save purchase information/data such that iTunes will backup said information when my customers sync. The Apple provided documentation states that this is possible, but doesn't really tell you how.
Where/how do I save purchase history (let's say, a NSString for each item) such that iTunes will back it up on the next sync?
Lastly, how would you suggest that I test this before making all of this go live?
Thanks.
P.S. Right now I'm using NSUserDefaults to store this info.
NSUserDefaults is fine for storing that kind of thing, but you should also use StoreKit's “check for purchased items” capability—a lot of apps that use in-app purchases have a button somewhere that checks the “purchased” state of the available products and re-enables them in the app, in case a user uninstalls and then reinstalls the app or installs it on a different device.
Testing in-app purchases can be done using the sandbox environment—iTunes Connect will let you set up a test iTunes Store account which has free access to all of your app's in-app purchases.
Actually NSUserDefaults is under
<Application_Home>/Library/Preferences
And the Library directory will be backed up by the iTunes.
Another way to save your in app purchase data (because it's very little) is to save it to keychain. Because keychain is safe and will be reserved when the app is deleted. So when user install the app again user can get their purchase instantly. Check this link:Lockbox: Easily Secure Your App’s Sensitive Data
As already mentioned you can use UserDefaults for this purpose, but as Apple states it can also be achieved using iCloud and NSUbiquitousKeyValueStore
https://developer.apple.com/documentation/storekit/in-app_purchase/persisting_a_purchase
Testing can be easily done nowadays right within Xcode using .storekit configuration file.
https://developer.apple.com/documentation/storekit/in-app_purchase/testing_in-app_purchases_in_xcode
While NSUserDefaults can be used to store purchase history, it's possible for a hacker to modify that and get access to paid features for free.
Keychain is a little better in that it's more persistent (will still be there after an app is removed and re-installed) but it's still possible for a really dedicated hack to add data to the keychain that makes your application think a purchase has been made.
You could also write out purchase info into some encrypted file you store within the app, that would be backed up with the app as well and might be more flexible.
The best approach is to store purchase data wherever is most convenient for your app, but then also check the receipt of the application that is stored in Bundle.main.appStoreReceiptURL to make sure what you have stored, Apple also considers to have been purchased.
That receipt is supposed to be sent through your own server to Apple, which returns receipt JOSN from the data stored at that appStoreReceiptURL.
For testing, although you can also use a sandbox iTunes account for testing on device, a newer method introduced with Xcode 12 is to use a StoreKit configuration where you can define all of your products without having to enter them in appStoreConnect first. When you run it will process purchase transactions locally, including within the simulator (not possible with the iTunes sandbox).
For more information on testing using the Xcode App Store Config files read this article:
https://www.namiml.com/blog/inapp-purchases-ios14-simulator