Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

iCloud file reading and writing (iOS)

On my first attempt at adding iCloud to my existing app this is how far I've gotten. For reasons that I won't go into, the use case for my app does not need coordination. I have successfully made my app write a file to the Documents directory of iCloud and read back that same file without errors. In testing on a real iPhone 13 and iPhone 7 I have verified that my app can write a file to iCloud from the iPhone 7 and then read back that same file on the iPhone 13, so I know that the file truly exists in the cloud. But when I make my app on the iPhone 13 write to iCloud, my app on the iPhone 7 says the file does not exist. Exactly the same build of my app is running in both phones. This is problem #1. Problem #2 is that none of these files appear in the iCloud section of the Files app on either of these Phones, nor do they appear in the iCloud section of my Mac. All devices are signed in to my same Apple account in iCloud. Also my info.plist file in the app contains:

<key>NSUbiquitousContainers</key>
  <dict>
    <dict>
  <key>iCloud.com.{my domain}.{my app}</key>
   <dict>
<key>NSUbiquitousContainerIsDocumentScopePublic</key>
  <true/>
<key>NSUbiquitousContainerSupportedFolderLevels</key> 
  <string>Any</string>
<key>NSUbiquitousContainerName</key>
  <string>{my app}</string>
    </dict>
   </dict>
  </dict>
<key>UIFileSharingEnabled</key><true/>

The iPhone 7 is running iOS 15.8.4 and the iPhone 13 is running iOS 18.3.2.

The code that does the writing to iCloud is:

    NSFileManager *fman = [NSFileManager defaultManager];
    NSURL *urlDrive = [fman URLForUbiquityContainerIdentifier: nil];
    NSURL *urlDocs = [urlDrive URLByAppendingPathComponent:@"Documents"];
    if(urlDocs.path == nil) {
        NSLog(@"NULL path");
       return; //..big problem
    }

    if( ! [fman fileExistsAtPath: urlDocs.path] ) { //..need to create the Docs directory
        NSError *err00 = nil;
        @try {
            [fman createDirectoryAtURL: urlDocs withIntermediateDirectories:true
                            attributes:nil error:&err00];
            NSLog(@"created the directory");
        } @catch (NSException *except) {
            NSLog(@"Exception creating directory %@", except);
        }
    }   //..directory is now created
    
    NSLog(@"url=%@", urlDocs);
    NSURL *urlFile = [urlDocs URLByAppendingPathComponent:txtfname()];
    
    NSData *fdata = [@"Hello world" dataUsingEncoding: NSUTF8StringEncoding];
    NSLog(@"file url=%@", urlFile);
    NSLog(@"file Data=%@", fdata);

    NSError *errorReturn = nil;
    Boolean ret = [fdata writeToURL: urlFile options: NSDataWritingAtomic error: &errorReturn];
    
    NSLog(@"returned %1d, error=%@", ret?1:0, errorReturn);

And the code that does the reading is:

   NSFileManager *fman = [NSFileManager defaultManager];
    NSURL *urlDrive = [fman URLForUbiquityContainerIdentifier: nil];
    NSURL *urlDocs = [urlDrive URLByAppendingPathComponent:@"Documents"];
    NSLog(@"url=%@", urlDocs);
    if(urlDocs.path == nil) {
        NSLog(@"urlDocs.path is NULL!");
        return; //..big problem
    }

    if( ! [fman fileExistsAtPath: urlDocs.path] ) { //..need to create the Docs directory
        NSLog(@"It seems the urlDocs folder does not exist");
    }

    NSURL *urlFile = [urlDocs URLByAppendingPathComponent:txtfname()];
    if([fman fileExistsAtPath: urlFile.path]) {
        NSLog(@"file %@ exists", urlFile);
        
        [fman copyItemAtURL: urlFile toURL:<#(nonnull NSURL *)#> error:<#(NSError *__autoreleasing  _Nullable * _Nullable)#>];
    } else {
        NSLog(@"file %@ DOES NOT EXIST!", urlFile);
    }

Correction: I should have posted this as the reading and writing code:

void writeToiCloud(void) {
  NSFileManager *fman = [NSFileManager defaultManager];
  NSURL *urlDrive = [fman URLForUbiquityContainerIdentifier: nil];
  NSURL *urlDocs = [urlDrive URLByAppendingPathComponent:@"Documents"];
  if( ! [fman fileExistsAtPath: urlDocs.path] ) { //..need to create the Docs directory
    NSError *err00 = nil;
    @try {
         [fman createDirectoryAtURL: urlDocs withIntermediateDirectories:true
            attributes:nil error:&err00];
    } @catch (NSException *except) {
            NSLog(@"Exception creating directory %@", except);
    }
  }   //..directory is now created if needed
  NSURL *urlFile = [urlDocs URLByAppendingPathComponent:@"hello.txt"];
  NSData *fdata = [@"Hello world" dataUsingEncoding: NSUTF8StringEncoding];
  NSError *errorReturn = nil;
  Boolean ret = [fdata writeToURL: urlFile options: NSDataWritingAtomic error: &errorReturn];
  NSLog(@"returned %1d, error=%@", ret?1:0, errorReturn);  //always says "1 error=(nil)"
}

void readFromiCloud(void) {
  NSFileManager *fman = [NSFileManager defaultManager];
  NSURL *urlDrive = [fman URLForUbiquityContainerIdentifier: nil];
  NSURL *urlDocs = [urlDrive URLByAppendingPathComponent:@"Documents"];
  NSURL *urlFile = [urlDocs URLByAppendingPathComponent:@"hello.txt"];
  if([fman fileExistsAtPath: urlFile.path]) {
    NSString *fullFN = [localDocsDirectory() stringByAppendingPathComponent: @"hello-Local.txt"];
    NSURL *destURL = [NSURL fileURLWithPath: fullFN];
    @try {
         [fman copyItemAtURL: urlFile toURL:destURL error:&errReading];
              NSLog(@"file copied from iCloud to local");
    } @catch(NSException *exc) {
              NSLog(@"copyItem threw %@", exc);
    }
  } else {NSLog(@"file %@ DOES NOT EXIST!", urlFile);}
}
iCloud file reading and writing (iOS)
 
 
Q