Discussion:
Sharing Files Between My Apps via iCloud
(too old to reply)
Michal L. Wright
2018-09-16 18:27:28 UTC
Permalink
I have apps for Mac OS (myMacApp) and iOS (myIOSApp) that use the same file format. The apps can synchronize files using WiFi or Dropbox.

Now I’m working on using iCloud for synchronization. I’m using the same approach that works with Dropbox, which is:

1. myIOSApp can read from and write to the app folder on Dropbox.

2. If the file has not been previously synced, a copy can be written to Dropbox for uploading to myIOSApp.

3. Once copies of the file exist on both platforms, they can be synced after one or both has been edited.

4. If the copy in myIOSApp has been edited, that copy is written to Dropbox.

5. In myMacApp, when the sync menu item is selected, myMacApp looks for the file (by name) on Dropbox, downloads it and saves it with a temporary file name.

6. The temporary file is compared with the original, and any differences are resolved.

7. The temporary file is deleted from the Mac, and myMacApp writes the resolved file to Dropbox.

8. myIOSApp reads the resolved file from Dropbox.

I’ve gotten to the point that both myMacApp and myIOSApp can read from and write to the same ubiquity container, using NSFileManager routines.

When myMacApp reads files from iCloud, the files have the correct file extension, something like this: MyFile.xten

When myIOSApp running on the iPhone reads files that it wrote, the file names are fine, but when reading files written by myMacApp, they look like this: .MyFile.xten.icloud

I was thinking that I must be missing something regarding how entitlements or info.plist were set up for each app, but it turns out that files written by myIOSApp running on the iPad are treated the same way. And, myIOSApp running on the iPad treats files that were written from the same app running on the iPhone the same way.

The ubiquity container can be viewed in Terminal on the Mac by typing ls -r "Library/Mobile Documents/iCloud~com~mycompany~myiosapp”

When the files are listed in Terminal, all I see are the file names, with nothing to differentiate them based on which app wrote them, nor based on which device they came from. None of them have the leading period or the trailing .icloud.

I also use the following to create a listing of the files in the ubiquity container:

NSURL *iCloudURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (iCloudURL)
NSArray* fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:iCloudURL.path error:NULL];

I step through the fileList array and use fprintf to show the paths. They show the same problem with the leading period and trailing icloud.

Trying to work around the modified file names hasn’t produced any useful results so far. If I read the files with the incorrect name, the content is incorrect. If I strip off the the leading period and trailing icloud before trying to read, the read fails.

I would appreciate any insights as to the cause of the problem and, of course, it’s solution.

Thanks,
Mike Wright

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.na
Uli Kusterer
2018-10-23 07:03:35 UTC
Permalink
AFAIK the .icloud files are placeholders iCloud creates for Finder to show while a file is still downloading (there will be a little indicator next to it in Finder list view showing it's still downloading.

You should probably just ignore those files and wait until iCloud has finished downloading.

Their content is probably just information needed to show the progress in Finder, if anything at all. Or it is partial file data, maybe with space already reserved for the final size.

Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de
Post by Michal L. Wright
I have apps for Mac OS (myMacApp) and iOS (myIOSApp) that use the same file format. The apps can synchronize files using WiFi or Dropbox.
1. myIOSApp can read from and write to the app folder on Dropbox.
2. If the file has not been previously synced, a copy can be written to Dropbox for uploading to myIOSApp.
3. Once copies of the file exist on both platforms, they can be synced after one or both has been edited.
4. If the copy in myIOSApp has been edited, that copy is written to Dropbox.
5. In myMacApp, when the sync menu item is selected, myMacApp looks for the file (by name) on Dropbox, downloads it and saves it with a temporary file name.
6. The temporary file is compared with the original, and any differences are resolved.
7. The temporary file is deleted from the Mac, and myMacApp writes the resolved file to Dropbox.
8. myIOSApp reads the resolved file from Dropbox.
I’ve gotten to the point that both myMacApp and myIOSApp can read from and write to the same ubiquity container, using NSFileManager routines.
When myMacApp reads files from iCloud, the files have the correct file extension, something like this: MyFile.xten
When myIOSApp running on the iPhone reads files that it wrote, the file names are fine, but when reading files written by myMacApp, they look like this: .MyFile.xten.icloud
I was thinking that I must be missing something regarding how entitlements or info.plist were set up for each app, but it turns out that files written by myIOSApp running on the iPad are treated the same way. And, myIOSApp running on the iPad treats files that were written from the same app running on the iPhone the same way.
The ubiquity container can be viewed in Terminal on the Mac by typing ls -r "Library/Mobile Documents/iCloud~com~mycompany~myiosapp”
When the files are listed in Terminal, all I see are the file names, with nothing to differentiate them based on which app wrote them, nor based on which device they came from. None of them have the leading period or the trailing .icloud.
NSURL *iCloudURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (iCloudURL)
NSArray* fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:iCloudURL.path error:NULL];
I step through the fileList array and use fprintf to show the paths. They show the same problem with the leading period and trailing icloud.
Trying to work around the modified file names hasn’t produced any useful results so far. If I read the files with the incorrect name, the content is incorrect. If I strip off the the leading period and trailing icloud before trying to read, the read fails.
I would appreciate any insights as to the cause of the problem and, of course, it’s solution.
Thanks,
Mike Wright
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/witness.of.teachtext%40gmx.net
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narki
Michal L. Wright
2018-10-25 17:32:54 UTC
Permalink
Thanks, Uli.

I used a dev support issue several weeks back, and received the following info from Dev Tech Support:

-------
The file with a leading dot and a .icloud extension is a stub representing a file that is not downloadeded; it is replaced after the file is downloaded. When synchronizing a file to an iOS device, which is not a greedy client, iCloud automatically transfers the file metadata; the real file, however, is only downloaded when requested. When the metadata comes in, iOS creates a stub to represent the file. You can get more details from our document, Designing for Documents in iCloud <https://developer.apple.com/library/archive/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForDocumentsIniCloud.html#//apple_ref/doc/uid/TP40012094-CH2-SW10>.

You see the stub because you use file system APIs to search the content in your iCloud container, which is not the right way to go. In any case, you shouldn’t work directly with a stub with file system APIs.

The right way is to use NSMetadataQuery which can give you the items you have in your container and then notify you of the incremental changes. With that, you will get the right file metadata, including the file name, and can access a file via NSFileCoordinator.
-------

It seems that iCloud is not designed to work as a simple file storage mechanism, the way MobileMe was (and the way Dropbox can work now). It can be done, but it seems much more complex than those systems, and I’m not confident that I can make it work reliably, so I’ve decided not to pursue it at this time.

— Mike
Post by Uli Kusterer
AFAIK the .icloud files are placeholders iCloud creates for Finder to show while a file is still downloading (there will be a little indicator next to it in Finder list view showing it's still downloading.
You should probably just ignore those files and wait until iCloud has finished downloading.
Their content is probably just information needed to show the progress in Finder, if anything at all. Or it is partial file data, maybe with space already reserved for the final size.
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de
Post by Michal L. Wright
I have apps for Mac OS (myMacApp) and iOS (myIOSApp) that use the same file format. The apps can synchronize files using WiFi or Dropbox.
1. myIOSApp can read from and write to the app folder on Dropbox.
2. If the file has not been previously synced, a copy can be written to Dropbox for uploading to myIOSApp.
3. Once copies of the file exist on both platforms, they can be synced after one or both has been edited.
4. If the copy in myIOSApp has been edited, that copy is written to Dropbox.
5. In myMacApp, when the sync menu item is selected, myMacApp looks for the file (by name) on Dropbox, downloads it and saves it with a temporary file name.
6. The temporary file is compared with the original, and any differences are resolved.
7. The temporary file is deleted from the Mac, and myMacApp writes the resolved file to Dropbox.
8. myIOSApp reads the resolved file from Dropbox.
I’ve gotten to the point that both myMacApp and myIOSApp can read from and write to the same ubiquity container, using NSFileManager routines.
When myMacApp reads files from iCloud, the files have the correct file extension, something like this: MyFile.xten
When myIOSApp running on the iPhone reads files that it wrote, the file names are fine, but when reading files written by myMacApp, they look like this: .MyFile.xten.icloud
I was thinking that I must be missing something regarding how entitlements or info.plist were set up for each app, but it turns out that files written by myIOSApp running on the iPad are treated the same way. And, myIOSApp running on the iPad treats files that were written from the same app running on the iPhone the same way.
The ubiquity container can be viewed in Terminal on the Mac by typing ls -r "Library/Mobile Documents/iCloud~com~mycompany~myiosapp”
When the files are listed in Terminal, all I see are the file names, with nothing to differentiate them based on which app wrote them, nor based on which device they came from. None of them have the leading period or the trailing .icloud.
NSURL *iCloudURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (iCloudURL)
NSArray* fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:iCloudURL.path error:NULL];
I step through the fileList array and use fprintf to show the paths. They show the same problem with the leading period and trailing icloud.
Trying to work around the modified file names hasn’t produced any useful results so far. If I read the files with the incorrect name, the content is incorrect. If I strip off the the leading period and trailing icloud before trying to read, the read fails.
I would appreciate any insights as to the cause of the problem and, of course, it’s solution.
Thanks,
Mike Wright
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/witness.of.teachtext%40gmx.net
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.na
Uli Kusterer
2018-10-26 10:43:10 UTC
Permalink
That iCloud doesn't work the way you expected it to is good.

Many apps make that assumption about Dropbox as well, and it is dangerous. Dropbox does not know about file packages or relationships between multiple files in a folder, so if you have anything but a single-file format, you can get document corruption where a table of contents file refers to files that don't exist or doesn't reference existing files because an addition and a deletion happened simultaneously. Storage mechanisms like this are *already* unreliable.

The iCloud API should be fairly simple. You basically just use different API to enumerate and access files that lets you ensure your entire change is applied *before* anything gets synched, which ensures related files are updated atomically and no other device can get "in sideways". You can still lose edits, but at least the files themselves stay consistent.
Post by Michal L. Wright
Thanks, Uli.
-------
The file with a leading dot and a .icloud extension is a stub representing a file that is not downloadeded; it is replaced after the file is downloaded. When synchronizing a file to an iOS device, which is not a greedy client, iCloud automatically transfers the file metadata; the real file, however, is only downloaded when requested. When the metadata comes in, iOS creates a stub to represent the file. You can get more details from our document, Designing for Documents in iCloud.
You see the stub because you use file system APIs to search the content in your iCloud container, which is not the right way to go. In any case, you shouldn’t work directly with a stub with file system APIs.
The right way is to use NSMetadataQuery which can give you the items you have in your container and then notify you of the incremental changes. With that, you will get the right file metadata, including the file name, and can access a file via NSFileCoordinator.
-------
It seems that iCloud is not designed to work as a simple file storage mechanism, the way MobileMe was (and the way Dropbox can work now). It can be done, but it seems much more complex than those systems, and I’m not confident that I can make it work reliably, so I’ve decided not to pursue it at this time.
— Mike
Post by Uli Kusterer
AFAIK the .icloud files are placeholders iCloud creates for Finder to show while a file is still downloading (there will be a little indicator next to it in Finder list view showing it's still downloading.
You should probably just ignore those files and wait until iCloud has finished downloading.
Their content is probably just information needed to show the progress in Finder, if anything at all. Or it is partial file data, maybe with space already reserved for the final size.
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de
Post by Michal L. Wright
I have apps for Mac OS (myMacApp) and iOS (myIOSApp) that use the same file format. The apps can synchronize files using WiFi or Dropbox.
1. myIOSApp can read from and write to the app folder on Dropbox.
2. If the file has not been previously synced, a copy can be written to Dropbox for uploading to myIOSApp.
3. Once copies of the file exist on both platforms, they can be synced after one or both has been edited.
4. If the copy in myIOSApp has been edited, that copy is written to Dropbox.
5. In myMacApp, when the sync menu item is selected, myMacApp looks for the file (by name) on Dropbox, downloads it and saves it with a temporary file name.
6. The temporary file is compared with the original, and any differences are resolved.
7. The temporary file is deleted from the Mac, and myMacApp writes the resolved file to Dropbox.
8. myIOSApp reads the resolved file from Dropbox.
I’ve gotten to the point that both myMacApp and myIOSApp can read from and write to the same ubiquity container, using NSFileManager routines.
When myMacApp reads files from iCloud, the files have the correct file extension, something like this: MyFile.xten
When myIOSApp running on the iPhone reads files that it wrote, the file names are fine, but when reading files written by myMacApp, they look like this: .MyFile.xten.icloud
I was thinking that I must be missing something regarding how entitlements or info.plist were set up for each app, but it turns out that files written by myIOSApp running on the iPad are treated the same way. And, myIOSApp running on the iPad treats files that were written from the same app running on the iPhone the same way.
The ubiquity container can be viewed in Terminal on the Mac by typing ls -r "Library/Mobile Documents/iCloud~com~mycompany~myiosapp”
When the files are listed in Terminal, all I see are the file names, with nothing to differentiate them based on which app wrote them, nor based on which device they came from. None of them have the leading period or the trailing .icloud.
NSURL *iCloudURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (iCloudURL)
NSArray* fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:iCloudURL.path error:NULL];
I step through the fileList array and use fprintf to show the paths. They show the same problem with the leading period and trailing icloud.
Trying to work around the modified file names hasn’t produced any useful results so far. If I read the files with the incorrect name, the content is incorrect. If I strip off the the leading period and trailing icloud before trying to read, the read fails.
I would appreciate any insights as to the cause of the problem and, of course, it’s solution.
Thanks,
Mike Wright
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/witness.of.teachtext%40gmx.net
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to geg
Jens Alfke
2018-10-26 19:31:14 UTC
Permalink
Post by Uli Kusterer
Many apps make that assumption about Dropbox as well, and it is dangerous.
Yup. Case in point is the support forums for Scrivener (an excellent word processor for book-writing, which uses a bundle file format), where there are numerous complaints about the data-loss problems people have had with Dropbox sync.

—Jens
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.nark

Continue reading on narkive:
Loading...