apache / cordova-plugin-file

Apache Cordova File Plugin
https://cordova.apache.org/
Apache License 2.0
740 stars 757 forks source link

iOS cordova.file.syncedDataDirectory writable/readable but files aren't synced between devices #558

Open Faksprod opened 1 year ago

Faksprod commented 1 year ago

Bug Report

Hi Cordova team, I'm not sure if it's a bug or if I misunderstood the documentation about cordova-plugin-file so any help/advices would be very appreciated (I'm targeting/working on an iOS webapp).

Problem

I'de like to read/write file in a synced folder automatically synced with iCloud. The goal is to be able of writing the file from device1 and reading the same file from device2 (and vice-versa). Files wouldn't have to be accessible from the user, only from the app (private files such as user preferences, user infos, etc).

What is expected to happen?

From the doc, I understood that files saved into the cordova.file.syncedDataDirectory folder would be automatically synced. The value of the syncedDataDirectory key returns: file:///var/mobile/Containers/Data/Application/01234-56789/Library/Cloud/

What does actually happen?

I can write/read file from this folder from the same device, everything works as expected. However, files are not synced at all between devices.

In a first time, I just like to get a confirmation from developers of this plugin about the goal of this syncedDataDirectory? What do you mean by "Holds app-specific files that should be synced (e.g. to iCloud)"? Do you confirm that files written on device1 could be read from device2?

Information

Of course all iOS devices on which I did test are connected to the same iCloud account, iCloud is enabled in device settings, iCloud Drive is enabled (don't know if it has anything to do with), iCloud for my app is enabled too.

Command or Code

I have added to my config.xml (from the doc but I'm not sure it would be necessary in my case):

<preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" />
<preference name="iosPersistentFileLocation" value="Library" />

I also tried to add iCloud Capabilities from Xcode (from TARGET > SIGNING & CAPABILITIES). I have created a new iCloud container iCloud.com.company.container-name. I have checked the box iCloud Documents in my iCloud Capabilities. I have upgraded my app build version number (such as explained in the Apple Doc about NSUbiquitousContainers). I also tried to add these new key/value in my info.plist:

<key>NSUbiquitousContainers</key>
<dict>
<key>iCloud.com.company.container-name</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerName</key>
        <string>TEST NEW CONTAINER</string>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>ANY</string>
    </dict>
</dict>

Environment, Platform, Device

• cordova -v: 11.0.0 • platform ios: 6.1.1 • cordova-plugin-file: 7.0.0

• Devices tested: iPhone7 Plus, iPhone 12 Pro, iPad Air Pro, iPad Air

Thanks for your help.

JamesIde commented 2 months ago

Did you find any solution? @Faksprod

Faksprod commented 1 month ago

@JamesIde: Unfortunately no (if you find how to make it works your feedback would be very much appreciated). I had to find an other way for saving/syncing file. I finally used cordova-plugin-save-dialog which allow a user to save a file in the iOS File folder, then the user can choose the Cloud folder. Not the best experience for the user but it works... Good luck!

breautek commented 1 month ago

I believe syncedDataDirectory is working as intended here.

The directly is synced with iCloud, which means users that backups their device can restore the app and the files for that app install. It doesn't mean that file will be synced across different devices. If it did, it's also the wrong way to do it (see last paragraph).

When you install an iOS app, it will have an install ID, which is something that is randomly generated. These ids may not match across devices, even for the same app. This part I'm not really sure on, but I think syncedDataDirectory effectively links against an install id, rather than a bundle id, making the files synced to iCloud only accessible by the app install that put the files there. Synced directories in this context effectively means the files will be saved as part of itunes backups.

Syncing files across devices I believe requires the use of other APIs that isn't really a File System based to manage documents on iCloud, and to resolve potential version conflicts, should remote have a version that local doesn't have, and local also has an update that remote doesn't have. This is something not exposed by the file plugin.

Faksprod commented 1 month ago

Ok it seems I misunderstood the cordova-plugin-file documentation 😅 Thanks for great clarifications @breautek