Can I use iCloud to sync the NSUserDefaults plist file - ios

I was wondering if it was possible to use iCloud to sync an app's preferences file between devices. The preference file I am talking about is the com.domain.appname.plist file created by NSUserDafults to store the app's preferences.
I would like to have the option of keeping my app's preferences file in sync between two different devices (an iPad and an iPhone, for example). Is this an acceptable use of iCloud syncing? Or would I need to convert the plist file into a different type of document, store it on the cloud, and convert it back into the app's preferences file upon retrieving it?
thanks!

Similar to MKiCloudSync, I also have a library on GitHub called SDCloudDefaults. Rather than sync automatically, there's a new object that you use instead of NSUserDefaults that saves to both iCloud and NSUserDefaults. This means you can decide which elements are stored locally and which are stored in the cloud.
(I found MKiCloudSync after I'd implemented it. I think it's clever but I don't want to sync everything to iCloud so my solution still works better for me.)

There is a library available to do this with one line of code
https://github.com/MugunthKumar/MKiCloudSync

It is possible to sync preferences between devices using iCloud. However, I would recommend against sharing the plist file between devices.
The NSUbiquitousKeyValueStore should be suitable for what you trying to do. It is very similar to NSUserDefaults, so it should be easy to pick up.
To use it, simply enable the com.apple.developer.ubiquity-kvstore-identifier entitlement in your entitlements file and just duplicate the preferences you like to sync in the ubiquitous key value store. Once it's in the ubiquitous kvstore, you'll be able to see it from the application on other devices. You can even sync between different applications as long as they use the same identifier.
You should also register for the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification to watch for new changes and update the standardUserDefaults on the device accordingly.

Related

MacOS - creating Finder Sync Extension with iCloud for iOS/MacOS

This is a very theoretical question, but quiet important for me, how I approach my next steps.
I am developing a SwiftUI MacOS app, where a user can upload own files. The metadata getting stored in CoreData and the file I store manually in the file system. At the moment I am using the default file folder for my application.
Soon I want to have a iCloud sync between my Mac OSX app and my iOS app. I read about it and it should work. CoreData should be no problem.
Now to my question if it will be possible to approach it that way I am thinking of:
I would like to create a Finder Sync Extension for my Mac OSX app, so I get a own folder, which can be added to the favorites and be observed. I want all my local files to be stored there. That should work..
Will I am able to sync these files which are stored in the Finder Sync Extension with iCloud to my iOS app?
Can I create a extension on iOS aswell, to display these files?
I am not storing my documents in a Data blob of the CoreData or allowing External Storage. I store all manually. Will I am able to still sync my documents via iCloud.
All in all, I want to know if I can store my files in the Finder folder, and still keep them synced with iCloud to iOS? If that is not possible, please let me know. Would be interesting to know in forehand.
A Finder Sync Extension should not "do" any syncing. In fact, Apple specifically recommends that a separate background process be used for any networking-like activity:
It’s generally best if the extension focuses on handling the badges, contextual menus, and toolbar buttons. Place in a separate service (a Login Item or Launch Agent) any code that performs the sync, updates state, or communicates with remote data sources. This approach ensures that there is only one syncing service running at a time.
https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/Finder.html
A Finder Sync Extension is used to provide file badges, menus, and otherwise modify the UI of Finder.
Adding a Finder extension doesn't give you a folder, let alone one that syncs.
You need to provide the folder and all sandbox details related to that. Your main app and/or background process needs to provide the syncing service.
In summary, your main app handles all of the syncing.
The Finder Extension only updates the UI for certain folders. It doesn't provide any syncing itself. So any "syncing with iCloud" question you have should be asked independently of the Finder Sync Extension context.

(iCloud) How to programmatically Backup/Restore data for all Apps like iTunes does?

I'd like to backup and restore files (or other type of informations like key-value, SQL-like transaction based info.) for NOT ONLY my app but also all the other Apps using iCloud.
I'm just new to iCloud and read only a few documents but it seems iCloud APIs are just for single App boundary (of course I understand there is an option for sharing information between 'Group' of applications).
What I want to do is backup and restore almost everything. How can I do that?
(There some apps doing this like
http://www.copytrans.net/copytranscontacts.php
http://www.macrumors.com/2012/05/18/elcomsofts-phone-forensics-software-offers-near-real-time-access-to-icloud-backups/)
I checked that the some of the Mobile App files are stored inside the "~/Library/Application\ Support/MobileSync/Backup" directory but there are only some of the files from all the files actually stored in iCloud.
And I tested CloudKit, but it just takes control over App's own data only.
Thanks in advance.
One thing to keep in mind when thinking about this is that iTunes actually doesn't backup or restore anything to/from iCloud. iOS device does it on its own: there's a daemon process running and if iCloud Backup is enabled, it will backup directly to iCloud, without talking to iTunes. Restore is also done without interaction with iTunes.
Next, as #rmaddy pointed out, your app on the device cannot access files of other apps, so you won't be able to do what you want from the device. If you want to do this via companion app running on PC/Mac then it might be possible, but will depend on what exactly do you need/want.
Re: contacts. Apps can access AddressBook and thus can sync/upload its contents. Apps can also access some other shared data, such as Photo Library. This is still a far cry from your original request to "Backup/Restore data for all Apps".
Re: downloading iCloud backups. Downloading isn't a big deal those days (Disclosure: I am the author of that forensic tool to download iCloud backups you're mentioned). There is even an open-source code for that. However, downloading and restoring are two very different processes. Specifically, you can download, but your app won't have enough permissions to write files in place.
Hope this helps and clears things up.

NSUserDefaults preferences that don't sync in iTunes

It's difficult to find explicit info on this.
Let's say I have something stored in NSUserDefaults and I do not want it to sync with iTunes. Should it be stored in the keychain instead? Does the keychain sync?
Instead of messing with the device keychain (whose elements don't get deleted on app removal) you can simply use an NSMutableDictionary and mix it with initWithContentsOfFile:, writeToFile:atomically: and the kCFURLIsExcludedFromBackupKey, this way you would have exactly the same structure of the NSUserDefaults (that is no other that a NSMutableDictionary at its heart) and you have control over if it should backed up or not. Mind that #rmaddy suggestion of putting it in the cache directory means that, if the device needs memory, your file would be wiped.
EDIT: Sorry probably I misread, the kCFURLIsExcludedFromBackupKey is to not have it synced from iCloud not iTunes. If you simply want to not be syncd with iTunes you can set the UIFileSharingEnabled to NO in your app's plist
EDIT2: According to the documentation (section Where You Should Put Your App’s Files) the kCFURLIsExcludedFromBackupKey will exclude it to be backed up by iTunes too.

iOS Data Storage Guidelines issues for a backwards-compatible app

I'm developing an iOS app that has to support iOS 5+. I've read the iOS Data Storage Guidelines in order to prepare the app for the submission and read several questions and solutions about those guidelines here in Stackoverflow, but I still have some doubts about how I should handle this.
I have an sqlite database whose tables are defined in an .sqlite file. I copy this file into \Documents folder when app starts, and I keep such file always there in \Documents. This database firstly contains some collections of fixed data that app may need (lists of cities to select and things like that), and the rest is user-dependent data that will be downloaded. I've read this post: Apps must follow the iOS Data Storage Guidelines or they will be rejected in app that contains .sqlite3, but I still don't know what criteria should I apply. The .sqlite is not downloadable, it is included in Supported Files of the Xcode project, and some of the initial data is inserted from inside the app and it is neither downloadable. The user-dependent data, well, I can download it whenever I need. I've not integrated any iCloud stuff in my app. So, should it be correct to keep the .sqlite file always in Documents? AFAIK, you need the file to be there for performing all database operations...
As I said, I've not included any iCloud related code in my app, and in fact I don´t know how iCloud is managed because I've never told to do it, are backups of the app made anyway? Should I use the flags the iOS Data Storage Guidelines says in order to prevent files to be backuped? I need some guidence regarding backups and iCloud considerations.
And there is another thing: my app also downloads some user-dependent images. I show them in several views throughout the app, so I need them to persist while the normal working of the app. However, it is downloadable content. So, where should I place them?
Thanks a lot!
I believe your .sqlite file should be in Documents, this is the correct place for it.
You downloaded images should probably be in Caches, but you could also get away with them in documents as long as you set the "do not backup" attribute.
You can set the skip backup attribute like this:
BOOL success = [url setResourceValue: [NSNumber numberWithBool: skip]
forKey: NSURLIsExcludedFromBackupKey error: &error];

turn off iCloud backup for my application iOS sdk

I have some problems because of iCloud and i want to turn off its for my app,how can i do it in the code of my application,i thought about my problem and the decision can be turning off the iCloud, thanks for help
If you store files in Documents, they will be backed up to iCloud automatically. If you don't want that, the easiest way is to just store them somewhere else. Library/Caches is a good choice. If you really MUST store in Documents but you want to disable iCloud backup you can use the technique outlined here:
https://developer.apple.com/library/ios/#qa/qa1719/_index.html

Resources