Can I use NSUserDefaults with tvOS? - nsuserdefaults

The App Programming Guide for tvOS briefly states that
There is no persistent local storage for apps on Apple TV. This means that every app developed for the new Apple TV must be able to store data in iCloud and retrieve it in a way that provides a great customer experience.
Does this mean NSUserDefaults is unavailable? What mechanisms are available for data storage?

According to an Apple Staff member on the devforums, you can use NSUserDefaults on tvOS for up to 500 kb of data:
https://forums.developer.apple.com/message/50696#50696

You can use NSUserDefaults for TVOS as per documentation.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/UserDefaults/AccessingPreferenceValues/AccessingPreferenceValues.html

Apple really wants you (and AppleTV customers) to sign up for and use iCloud.
Here is the current documentation on what to do for persistent storage with AppleTV.
The introductory paragraph:
Storage on Apple TV is limited, and there is no guarantee that
information stored on the device will be available the next time a
user opens your app. Also, in order to share the user’s data across
multiple devices, you need to store the user’s information somewhere
other than the Apple TV. Apple provides two shared storage options for
Apple TV: iCloud Key-Value Storage (KVS), and CloudKit.
For files less than 1 meg, you'll use iCloud Key-Value Storage (KVS). For storage more than 1 Meg, you'll use CloudKit.

To follow up #vegashacker's answer, the same Apple staff member also said:
You can also store content locally using the application temp and
cache directories, but note that this data will be purged.
The purge is likely to happen when you app is no longer running, e.g. when resources are under pressure, or at reboot.

NSUserDefaults is available but has a limited size on tvOS. According to Apple staff on forum "NSUserDefaults is allowed, and supports up to 500KB of data." and also "The behaviour is the same as on iOS: NSUserDefaults is persistent as long as the user does not delete the app from the device."
Also according to NSUserDefaults.h header
"NSUserDefaultsSizeLimitExceededNotification is posted on the main queue when more data is stored in user defaults than is allowed. Currently there is no limit for local user defaults except on tvOS, where a warning notification will be posted at 512kB, and the process terminated at 1MB. For ubiquitous defaults, the limit depends on the logged in iCloud user."

Related

Disabling iCloud per app in iPhone Settings

I am using iCloud key-value storage in my app (ios 5.0+) and I wonder if it is possible to turn it on/off from within Settings/iCloud, similar way we can turn off Facebook/Twitter (per app) ?
I would prefer not to implement my own popups etc.
Best regards
In Settings -> iCloud -> Documents and Data you can enable / disable use of iCloud for Documents and Core Data on a per app basis, but not for iCloud key value storage.
If your app only uses iCloud key value storage it won't even appear in the list of apps on the settings pane.
So, the answer to your question is, no, it's not possible.

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

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.

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.

RestKit and iCloud directory backup policies

I am working on an IOS 5.0+ project that uses the latest RestKit to download, map and persist core data. I am looking for a definitive answer on Apple's iCloud storage guidelines with RestKit. Do I need to take any extra steps to make sure the data downloaded for use in the app is not automatically backed up to an iCloud account.Do I need to alter the default location for the directories used. Thanks in advance.
If your Core Data store is not saved in an ubiquity container (See: URLForUbiquityContainerIdentifier:) it will never be synced.
Also in the Using iCloud in Conjunction with Core Data section of the documentation they state:
Setting up your Core Data store to handle iCloud requires only a
little extra effort on your part. The steps you must follow depend on
whether you are using a single Core Data store as a central library
for your app or whether you are creating separate stores for
individual documents.
You have to do some explicit changes for synchronization. If you read the documents further, they mention some keys like NSPersistentStoreUbiquitousContentNameKey. If you search for this in the RestKit source, you will not find it - this is because RestKit does not sync with iCloud automatically (and they can not because iCloud is an app level synchronization framework).
Our app was just rejected for storing our database in the Documents folder. The seed file or app content in the database has got 3.3MB. We also store user created content in the database of course. The official statement is: 2.23 Apps must follow the iOS Data Storage Guidelines or they will be rejected
So now we are checking out on Technical Q&A QA1719 to prevent the database from being synced to iCloud.

Data Protection on iOS

If targetting iOS 4, you can use the Data Protection APIs.
If you have 'Full' protection, does this encrypt the entire sandbox?
Specifically, If I downloaded say a .doc file to disk programatically will this be encrypted? Or is it only encrypted if I use the NSData data protection options?
It's only encrypted if you use data protection. See App States and Multitasking, and Protecting Data Using On-Disk Encryption.
My understanding is that you must use the data protection options. There was a WWDC 2010 talk on exactly this topic. See "Session 209 - Securing Application Data" which goes into detail. These videos are free and highly informative.
Login through developer.apple.com and then you can use the link in the page to get to the videos. FYI, the video contains all the example code you should need.
WWDC 2010 videos
if somebody were to jailbreak your device and bypass your passcode, information protected by the Data Protection API would remain encrypted and therefore inaccessible, since your passcode—the important piece of the decryption key, is not known.
Data Protection is enabled automatically simply by setting a passcode on the device.
The catch, however, is that the Data Protection feature only secures data in applications that have been specifically designed to use the Data Protection APIs.
In terms of built-in applications, that’s only the Mail app, and third-party apps that actually make use of the Data Protection features are surprisingly rare;
GoodReader and Box.net come to mind as good examples, but many other file storage apps such as Dropbox do not provide this support, meaning that your cached data is no more secure than your physical possession of the device.
This means that if you’re concerned about storing confidential data with secure encryption you will need to look to exclusively using third-party apps that support the Data Protection APIs.
It’s also important to keep in mind that any apps that use iCloud storage cannot use Data Protection, as the two are mutually exclusive due to the requirement for background synchronization of iCloud data when the device is locked.
Even GoodReader, for example, notes that documents you choose to store in the “iCloud” section of the app will not be protected by the Data Protection encryption.
Of course even Data Protection is only as secure as the passcode on the device. Using the Apple Configurator you can configure requirements for more complex passcode policies on devices to help improve security in this regard, as well as enabling an automatic erase of the device after a specified number of failed attempts.
Read more at
here
If I recall correctly, starting with iPhone 3GS, hardware encryption is on by default for data on the iPhone, and additional encryption is available if you implement -- though if you are distributing/selling through AppStore, and you're implementing your own custom encryption beyond what Apple provides, the terms of AppStore requires you to get US Dept of Commerce (if my memory is correct) approval because encryption is classified as munition.
A good starting document is http://www.apple.com/iphone/business/it-center/security.html
More info on this is available within (paid) iPhone Registered Developer website which for obvious reason, I couldn't reveal, and you'll have to discover/read yourself.
Hope the information helps, and please mark the response as answered if this helps, thanks.