Store File to iCloud?

Part 3:
In the Xojo Capabilities list, check iCloud and set up the Options panel like this:

Again, note the identifier.

Part 4:

Now we need to get the correct path on the device. Keep in mind, if the user doesn’t have iCloud Drive enabled, this method returns Nil.

Function ICloudFolder() As FolderItem
  #If TargetiOS
    Declare Function NSClassFromString Lib "Foundation" (name As cfstringref) As ptr
    
    // @property(class, readonly, strong) NSFileManager *defaultManager;
    Declare Function getDefaultManager Lib "Foundation" Selector "defaultManager" (cls As ptr) As Ptr
    
    Dim mgr As ptr = getDefaultManager(NSClassFromString("NSFileManager"))
    
    // create the path to the file within the iCloud folder
    
    // - (NSURL *)URLForUbiquityContainerIdentifier:(NSString *)containerIdentifier;
    Declare Function URLForUbiquityContainerIdentifier_ Lib "Foundation" Selector "URLForUbiquityContainerIdentifier:" (obj As ptr, containerIdentifier As Ptr) As Ptr
    
    Dim iCloudFolder As ptr = URLForUbiquityContainerIdentifier_(mgr, Nil) // Nil uses the first one defined in the entitlements
    
    If iCloudFolder=Nil Then
      // iCloud Drive is not turned on for this device?
      Break
      Return Nil
    End If
    
    Declare Function getPath Lib "Foundation" Selector "path" (obj As ptr) As CFStringRef
    
    Dim filepath As String = getPath(iCloudFolder)
    
    Return New FolderItem(filepath, FolderItem.PathModes.Native)
  #EndIf
End Function

Part 5:
oh… and you should add the following code as a pre-build script:

PropertyValue("App.NonReleaseVersion") = str(val(PropertyValue("App.NonReleaseVersion")) + 1)

Auto Increment Version doesn’t do anything for debugging and it’s critical that the version change each time you make a change.

Part 6: (optional)
Something else to keep in mind. If you want your files to show a custom icon and file type info, you’ll need to add a FileTypeGroup to both your iOS app and your Desktop app.

2 Likes

Is there a Part 1? I don’t see that…

Thank you!

Edit: I think that’s back up higher where you talk about creating the iCloud identifier

Why is this so critical?

And here’s another question…

Now that I can see the file path, why can’t you just write to:

/private/var/mobile/Library/Mobile Documents

That would seem to put it in the main iCloud documents folder…

Why doesn’t Xojo have a “special folder” path to that??

Well you can’t just write to /private/var/mobile/Library/Mobile Documents it seems. So maybe that’s why.

Anyhow, I’ve successfully executed the code, but the folder has not shown up nor the file I’ve written to it…

I see the folder item now. It’s hidden. Not sure why that is, but I found my folder with my files on my desktop machine using terminal. So it appears to be working…

OK - I see why now. If you write to the Documents folder inside the iCloud container, then it shows up as a folder in iCloud on your Mac. Otherwise, it just stays in the container in Mobile Documents.

This is perfect. Exactly what I want and even better that I can write to a spot where the most users never look…

1 Like

Excellent thread. Thank you @Jon_Ogden & @Greg_O

3 Likes

iOS (and macOS) caches plist files based on their version number and if they haven’t changed, it makes assumptions about what has changed overall. Making sure that the non-release version changes every time saves you from running into that without actually changing your major.minor.bug version.

This is also helpful if you’re having trouble getting an app released because of rejections.

The call I gave you through the declares looks up that location and gives your app access to it.

1 Like

Because none of this existed in iOS 5 when Xojo iOS was first released. it was only released in iOS 6.

So do I have to keep doing this always? Or just twjenever I change the plist?

You can probably only do it when changing the plist and any time you change any of the capabilities or their options. Like I said, it’s also helpful when trying to get a release out so you don’t have to change the visible version number.

What I usually do is just have this number increment on every run/build and then zero it out whenever one of the major, minor or bug versions changes.

But it actually does update the non-release version number and every time you run the app in the debugger.

But it’s a good tip. I didn’t realize the plists were tied to versions like that.

What I don’t understand is Apple’s syncing mechanism.

I have updated/written to a file from my iOS app multiple times this morning. Yet the desktop is still showing the copy I wrote last night as the latest.

What drives iCloud to sync files? You would think that as soon as you modify the file on either end that it would sync. That does not appear to be the case. Is there a spec for the timeframe on what I file gets uploaded to iCloud from the phone and when it then appears on the desktop?

It’s not instantaneous. Syncing can depend on battery level, whether you’re using a cellular or WiFi connection (user configurable), whether the device is in low-power mode, available bandwidth, etc.

I even had a problem on my mac up until a year ago where the cloud sync would hang on a particular file and not allow any more syncs to work beyond that until I moved the file out of the sync folder and then back. Took me months to figure that one out.

@Greg_O, I believe that this is a very interesteng subjet to include in the Cojo blog and also to develop a complete example for all the community.

Yup. We’re working on the blog post. there’s no good way to make an example though since you need to do external work (at Apple) to make it work. People would just assume that it failed.

1 Like

Yup. On plenty fast WiFi. AC power. And hours later and it didn’t change. Still the same. I’ve seen iCloud do this sometimes and it’s maddening.

Have you tried deleting the file instead of just overwriting it?

Slghtly off topic… I recently had to fix a bug in ‘my’ software, which went like this:

Create a temp file … check it exists, set a flag if no.
Delete it, check it doesnt exist, set a flag if yes

The second one reported that the file still exists after deletion, on a few machines where the file is in an iCloud synched folder, and internet speed is slow.
I had to add a delay between delete and check for exists to ‘fix’ it.
So I believe that deletion can be delayed by iCloud, as well as synching.