Store File to iCloud?

I want to save a simple text file to iCloud from my iOS device and have it show up on my Mac. I don’t care if the file is located in the main iCloud documents folder or in a special folder for my app. Probably just in documents is the easiest.

And at the same time I want to be able to read that file on my iOS device.

What’s the path to doing that in the iOS framework?

It should be SpecialFolder.Documents

That’s what I thought. But I save a file there and then look in files. Not there.

Keep in mind iOS has everything sandboxed. I think SpecialFolder.Documents is only for the documents folder for your app. It’s not accessible by anything else.

It is, but I’m pretty sure I recall trying this about three years ago and having it work. I’ll have to see if I have any notes or example projects.

Ah right, so if you write to the Documents folder, the file shows up in the Music app or in Finder (depending on the version of macOS you are running) under “Files” when the phone is plugged into your computer:

I’ve been playing around with this problem this morning and while I’ve been able to write into an app-specific container on iCloud, there are a few things that you should be thinking about…

  1. The easiest way to allow users to save into iCloud is through a sharing panel. The interface is already there, familiar and allows the user to just choose a filename and where to save the file.
  2. Not all users have iCloud file sharing turned on. Whatever you do to make this work is going to need to handle this fact. If you don’t, the app will crash (and I’d bet that an Apple app testers will catch that and reject your app)
  3. iCloud allows files to be stored in the cloud for retrieval at the time of use. That means that if you want to be able to read these files in your app, you’ll need to “ask” for them and then access them later when the file actually arrives.
1 Like

I’ve got a working example of this but there are a lot of moving pieces. I’ll put together instructions and a project sometime today.

I’ll have to file some bug reports too because the IDE is getting some things wrong.

Before you spend too much time on that Greg, let me explain more what I am looking to do.

I want to save a file when the user takes a particular action and allow it to be saved to somewhere accessible in iCloud. I want this done w/o any interaction with the user. Yes, I am fine with the user being able to allow this or not from a preferences pane. But once the user chooses to allow this, they never mess with it again.

What I am trying to do is a “poor man’s” cloud control. When the user of my app is on their home LAN the app communicates and does things over the local network. When not on the home lan, you can’t obviously do anything. So instead of going through the headache and hassle and expense of creating a cloud server that would allow this, I thought I’d do it over iCloud. There’s no extra account to set up. The security is already there and is Apple’s problem. I’m not saying any potential user information to where I, the developer, can utilize it - so privacy is not a concern.

On the other end, the desktop app will periodically scan the iCloud folder looking for this file. When it receives it, it reads it and takes the action requested.

My app basically controls an entertainment system. So let’s say you are a bar owner using my app and you realized you forgot to shut the TVs off before you left. Well, press the power off button and the desktop app gets it via iCloud and sees to shut the power off and done.

I’ve got an iOS app called Terminal that has a “Terminall” folder in iCloud. Right now there’s nothing in it, but inside that folder is a folder called Keys. Perhaps that’s for the Key storage that is causing the whole provisioning problem right now. But how do you create a folder like that even. Just something to easily get file over iCloud to any of your other iCloud clients. Since it never leaves the user’s account, then it can’t be a privacy issue for Apple.

What I did was to figure out the declares, entitlements, etc, necessary to create an app-specific folder in iCloud and be able to write files into that directory which will be synced to other devices.

It’s a real mess and Apple has (in)conveniently made it very hard to figure out… but I’ve got it working on my test device.

1 Like

To get started, go to your Apple dev account and add an iCloud identifier with an id that matches your app’s bundle identifier. For example, if your app is

com.mycompany.myapp

Then the cloud ID should be

iCloud.com.mycompany.myapp

Once that’s done, you’ll need to update the identifier for your app and add the iCloud identifier to the entitlement.

Unfortunately that will invalidate the development and distribution profiles, so edit each of them and then just click save to update them.

Next, go to Xcode’s preferences, go to Accounts and click the Download Manual Certificates" button.

This will get the Apple portion ready to go.

Cool, Greg! Thanks! That is exactly what I am looking for. I’m surprised no one has requested this before now.

I have the iCloud container set up in my developer account but it doesn’t match the app bundle ID. I’ll fix that and update the profiles.

1 Like

begging for it for many many years.

1 Like

begging for what?

A way for Xojo written apps to use iCloud to exchange files with other devices and apps in an understandable manner.
This whole post really…

‘I want to save a simple text file to iCloud from my iOS device and have it show up on my Mac.’

I’m glad you found a way to

… figure out the declares, entitlements, etc, necessary to create an app-specific folder in iCloud and be able to write files into that directory which will be synced to other devices.

I couldn’t. :slight_smile:

Well first of all, your requirement of “in an understandable manner” is not really Xojo’s fault. You can put that squarely on the shoulders of Apple. It took me three hours of searching and trying random hints to get it right and in the end, I ended up having to use some deprecated plist keys to get the files to appear. I’ll try to put something together at lunch today.

Wow. It seems like it should not be that hard! I love Apple, but sometimes they just make things way more complicated than they should be. iCloud should be easily accessible.

Thank you for your work. I may need to send you a case of beer or a bottle of Bourbon or something… You deserve it after all this!

1 Like

I know you have a life and it’s not to service my needs. That said, were you able to put anything together?

Thanks!

Had a few fires at work today that had to get resolved. I’ll try to do it tonight.

Part 2:

You’ll need to make a plist file with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSUbiquitousContainers</key>
    <dict>
        <key>iCloud.com.mycompany.myapp</key>
        <dict>
            <key>NSUbiquitousContainerIsDocumentScopePublic</key>
            <true/>
            <key>NSUbiquitousContainerName</key>
            <string>My Example App</string>
            <key>NSUbiquitousContainerSupportedFolderLevels</key>
            <string>None</string>
        </dict>
    </dict>
</dict>
</plist>

Note the key near the top that has the same identifier that you added to your account:

NSUbiquitousContainerName defines the name of the folder that appears for your app (as opposed to the name of your app’s bundle).

iCloud.com.mycompany.myapp

Drag this plist file to your project