How do I properly enable iCloud document sync for iOS app? - ios

In my cordova iOS app, users can back up their data to a file which is saved in the Documents folder within the app's container, which then should be synced to iCloud. However, though the file is saved it is never synced to iCloud, so clearly I must be missing something. These are the steps I have taken:
iCloud container registered on developer.apple.com and iCloud Documents capability enabled in xcode:
NSUbiquitousContainers dictionary added to Info.plist:
Archive build created and uploaded to App Store, build released to testers via Test Flight (Note: app has already gone through review process and been released to App Store).
Note, Cordova config.xml does not contain BackupWebStorage setting so cloud backup should be enabled (not sure exactly whether this affects document sync).
User saves backup file, which is saved to app's Documents folder (Note: the app uses the cordova-plugin-file plugin to save the file to the location denoted by the plugin variable cordova.file.documentsDirectory):
At this point I would have expected to see xBrowserSync appear in Storage & iCloud usage settings, but I do not:
And neither do I see an xBrowserSync folder appear in the iCloud Drive app:
And of course I never see the files synced to my Mac or on icloud.com.
Clearly I'm missing something but I can't see what. I've read many SO posts regarding getting this working and I find Apple's documentation unclear and confusing so I'm kind of stuck at this point. Could someone please point me in the right direction?

After some further reading I believe I know what's missing here. I hadn't realised you need to explicitly tell iOS to upload a file to iCloud Document Storage, which is what will allow files to appear in iCloud Drive on the user's devices.
So, I need to write some (iOS) code that utilise the FileManager class to:
Call the url(forUbiquityContainerIdentifier:) method in order to get the location of the local iCloud container and initialise it (at which point the app will appear in Storage & iCloud usage settings)
Tell iOS to upload the file to iCloud by calling setUbiquitous(_:itemAt:destinationURL:)
I'm building a very basic Cordova plugin to do this. I'll update this answer with a link when I'm finished.
Edit:
The cordova plugin I developed is called cordova-plugin-icloud-document-storage. It currently only implements uploading documents to iCloud (i.e. setUbiquitous), it doesn't implement the other iCloud functionality of the FileManager class (such as managing cloud updates or version conflicts). If anyone would like to develop this functionality please do submit a pull request.

Related

Create a file through a Cordova/Phonegap app that can be opened by another app (ios)?

I'm able to create and save files using cordova-plugin-file, and have been saving and accessing them from within the app to cordova.file.documentsDirectory.
The problem it seems is that all the directories that one can save to are private, Cordova-plugin-file documentation
I would like to be able to have these files saved in (or moved to) the ios blue "files" folder, so that they can be opened by other apps such as Numbers, Pages, etc. It seems so simple there has to be a way to do this, but I can't find it after more than a few evenings of searching and trying different ways.
I'd be grateful if someone could point me in the right direction.
From what I can tell you can save to the documents directory "cordova.file.documentsDirectory". By default this directory is shared with iCloud, so a file saved here could be opened through the ios File folder and a user could then select the files and hit the share icon to open with the appropriate app, such as Numbers etc.
In order to turn on iCloud you have to pay the developer fee to Apple and select the options to do so. I found the article "Working with the Files App in iOS 11" to be helpful in starting this process.
I don't have the paid developer account yet, but from what I'm reading it should work once I activate one. I'm open to a better solution or critique.

iOS File Retrieval - NSDocumentDirectory

I am working on a library with a very verbose logger module that, on iOS, writes xml logs to NSDocumentDirectory in a consistent file tree. I want to come up with a way for the user of this library to easily access these logs.
I know it is simple to programatically retrieve files from this directory, but is it possible to access this directory on an iOS physical device in any way from outside Xcode to retrieve these logs? I feel like I have seen it somewhere before, something in the manner of extracting the .ipa file and going into the package contents, but I could be wrong.
---------------------------------------------------------EDIT------------------------------------------------------------------
This (Browse the files created on a device by the IOS application I'm developing, on workstation?) is how to do it with Xcode on a device, but I have to assume that there is some way we can create that gets the logs off of a device for a user.
is it possible to access this directory on an iOS physical device in any way from outside Xcode to retrieve these logs?
It is possible to expose the Documents directory by enabling iTunes file sharing. When file sharing is enabled through this method, the contents of Documents directory would be visible to the user in iTunes, which can also be exported. The documents would also be visible for export through some third party desktop apps like iExplorer.
Here is the link to Apple documentation. You may also refer this thread to understand how this is done.
If you're using a simulator (apparently your task doesn't seem to need te real device) you are in luck.
You should go to a folder similar to this one:
/Users/[YOUR_USER_NAME]/Library/Developer/CoreSimulator/Devices/[RANDOM_HASH_YOU_SHOULD_DISCOVER]/data/Containers/Data/Application/[RANDOM_HASH_2_YOU_SHOULD_ALSO_DISCOVER]
Once there, with finder, you'll get the "documents" folder of the simulator and the app you're trying to retrieve your logs from.
You might say: I don't know which 2 RANDOM_HASHES should I go to.
Yes, you're right. If you have MANY simulators installed and or being used, it might be tricky to discover which one is the one you're trying to debug.
The same thing with your APP, your app will live in another RANDOM_HASH folder, and you should browse them, one by one, and then discover your documents folder.
Someone needed to solve this "mess" and created a Xcode Alcatraz Extension that leads you to the exact live simulator and APP you're debugging in any given moment, and then you don't need to guess which 2 random_hash paths you need to navigate to.
If Xcode + Alcartaz plugin extension manager is somewhat out of your reach, you might need to google it. It's not a difficult process.
PS: That magical Alcatraz Extension is named "XCodeWay" (in case you are brave enough to install Alcatraz onto your copy of XCode).
EDIT: Useful link to get Alcatraz: http://alcatraz.io/ Follow its easy instructions and you're done.
EDIT2: If Xcode cannot be used, then the last question in this other thread might come in handy: Browse the files created on a device by the IOS application I'm developing, on workstation?
(Still, an external application in your users machine will be needed )

Having a bit of trouble with copying a local file on iOS

Having only worked with Android/web dev before I am having a hard time figuring out where in the world my file should be getting copied to in iOS. After reading the file browser documentation on the iOS developer resource page it says that each app is an "island" which contains its own folder system. If I want to have my user be able to copy a file from my app's sdk to their iOS device, where should I put it?
I downloaded a file browser app from the app store on my iOS testing device but am I right in thinking that there is no global file browsing system?
I am using a Cordova plugin called Asset2sd which works perfectly for me in Android, getting the root storage folder and downloading the file to there. It has no iOS alternative so I'm going to have to figure something else out, I just need to know where to start. Do I have to have the user access my app's internal files somehow? Can I create a folder for them to look in when they download my app? Some documentation or something would be wonderful. I am totally lost.
Thanks!
You're right. Apps don't have access to the global file system. Each app only has access to their own app directory. Here's in-depth information on Sandboxing: https://developer.apple.com/app-sandboxing/
In your app's sandbox, you basically can manage files as you want, i.e. download, copy, move, delete, etc. So you can create a folder Downloads in your apps documents directory and then display the contents of this folder for instance in a table view.
Related documentation/links:
https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/index.html
https://stackoverflow.com/a/6907432/967327
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/iPhoneAppProgrammingGuide.pdf

Should I follow iOS Data Storage Guidelines?

My iOS app is intended to be compatible with iOS 5.0 and above, and it has iCloud capabilities turned off in it's target settings, I'm not integrating with iCloud. My app stores an sqlite file and some image files into Documents folder. The sqlite file is not downloadable, but images are.
I've read some posts from people saying that their app's submission was rejected because they don't met the iOS Data Storage Guidelines, but I'm not sure if that is only required if your app has iCloud capabilities enabled, is it? Should I set the NSURLIsExcludedFromBackupKey for my files anyway?
Thanks in advance
EDIT
I've read this here:
It is not possible to exclude data from backups on iOS 5.0. If your app must support iOS 5.0, then you will need to store your app data in Caches to avoid that data being backed up. iOS will delete your files from the Caches directory when necessary, so your app will need to degrade gracefully if it's data files are deleted.
But I need the sqlite file to be in Documents to insert data... how should I handle this?
It has nothing at all to do with whether your app uses iCloud or not. It has to do with the user performing backups to iCloud which is beyond the control of your app.
If all of the data in your app that is stored in the app sandbox is data that is created and stored by the user through the use of the app then Apple will have no problem with the data being backed up.
They have issue with replaceable files being backed up needlessly. If the database file is read-only and could be obtained from a server or the app bundle then don't let it be backed up. But if it starts out mostly empty and then gets data added as the user adds data through the app then it should be backed up. Same for the images.

Which technique will be better to store IOS app data and run app in offline mode??Documents directory or cache directory or temprary directory?

Hi recently my app has been rejected by APPLE, they says
We found that your app does not follow the iOS Data Storage Guidelines, which is required per the App Store Review Guidelines.
In particular, we found that on launch and/or content download, your app stores 3.11 MB. To check how much data your app is storing:
- Install and launch your app
- Go to Settings > iCloud > Storage & Backup > Manage Storage
- If necessary, tap "Show all apps"
- Check your app's storage
The iOS Data Storage Guidelines indicate that only content that the user creates using your app, e.g., documents, new files, edits, etc., should be backed up by iCloud.
Temporary files used by your app should only be stored in the/tmp directory; please remember to delete the files stored in this location when the user exits the app.
Data that can be recreated but must persist for proper functioning of your app - or because customers expect it to be available for offline use - should be marked with the "do not back up" attribute. For NSURL objects, add the NSURLIsExcludedFromBackupKey attribute to prevent the corresponding file from being backed up. For CFURLRef objects, use the corresponding kCFURLIsExcludedFromBackupKey attribute.
For more information, please see Technical Q&A 1719: How do I prevent files from being backed up to iCloud and iTunes?.
It is necessary to revise your app to meet the requirements of the iOS Data Storage Guidelines.
For discrete code-level questions, you may wish to consult withApple Developer Technical Support. Please be sure to:
- include the complete details of your rejection issues
- prepare any symbolicated crash logs, screenshots, and steps to reproduce the issues for when the DTS engineer follows up.
For information on how to symbolicate and read a crash log, please see Tech Note TN2151 Understanding and Analyzing iPhone OS Application Crash Reports.
If you have difficulty reproducing this issue, please try testing the workflow as described in https://developer.apple.com/library/ios/qa/qa1764/TestingWorkflow with Xcode's Archive feature".
What should i do now??Need Help
I have also face the same issue. To resolve this issue you should do some code so that your DocumentDirectory should not sync with iCould. For that you have to set one flat to your DocumentDirectory which is known as Don't BackUp.
To achieve that use code provided by the Apple..
To know more then you can refere this.
Hope this will help you.
All the best !!!
Basically, what Apple is telling you that only documents that the user expressly creates and wants to save are what should be stored in iCloud.
Otherwise, you can save the files your app creates to the "Documents" directory (if you want it to persist between launches) or the Temporary folder (if you don't care what happens to the files between the device being powered up and down).
And in connection with Yashesh's answer (+1 to him!), make certain that iCloud is turned off by going to the Target (app) settings and turning the "iCloud" checkbox to off, like this:

Resources