Save iOS 8 Documents to iCloud Drive

后端 未结 2 1141
[愿得一人]
[愿得一人] 2020-12-01 05:39

I want to have my app save the documents it creates to iCloud Drive, but I am having a hard time following along with what Apple has written. Here is what I have so far, bu

2条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-01 06:28

    Well, you've got me interested in this matter myself and as a result I've spent way to much time on this question, but now that I've got it working I hope it helps you as well!

    File on my Mac

    To see what actually happens in the background, you can have a look at ~/Library/Mobile Documents/, as this is the folder where the files eventually will show up. Another very cool utility is brctl, to monitor what happens on your mac after storing a file in the iCloud. Run brctl log --wait --shorten from a Terminal window to start the log.

    First thing to do, after enabling the iCloud ability (with iCloud documents selected), is provide information for iCloud Drive Support (Enabling iCloud Drive Support). I also had to bump my bundle version before running the app again; took me some time to figure this out. Add the following to your info.plist:

    NSUbiquitousContainers
    
        iCloud.YOUR_BUNDLE_IDENTIFIER
        
            NSUbiquitousContainerIsDocumentScopePublic
            
            NSUbiquitousContainerSupportedFolderLevels
            Any
            NSUbiquitousContainerName
            iCloudDriveDemo
        
    
    

    Next up, the code:

    - (IBAction)btnStoreTapped:(id)sender {
        // Let's get the root directory for storing the file on iCloud Drive
        [self rootDirectoryForICloud:^(NSURL *ubiquityURL) {
            NSLog(@"1. ubiquityURL = %@", ubiquityURL);
            if (ubiquityURL) {
    
                // We also need the 'local' URL to the file we want to store
                NSURL *localURL = [self localPathForResource:@"demo" ofType:@"pdf"];
                NSLog(@"2. localURL = %@", localURL);
    
                // Now, append the local filename to the ubiquityURL
                ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent];
                NSLog(@"3. ubiquityURL = %@", ubiquityURL);
    
                // And finish up the 'store' action
                NSError *error;
                if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) {
                    NSLog(@"Error occurred: %@", error);
                }
            }
            else {
                NSLog(@"Could not retrieve a ubiquityURL");
            }
        }];
    }
    
    - (void)rootDirectoryForICloud:(void (^)(NSURL *))completionHandler {
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"];
    
            if (rootDirectory) {
                if (![[NSFileManager defaultManager] fileExistsAtPath:rootDirectory.path isDirectory:nil]) {
                    NSLog(@"Create directory");
                    [[NSFileManager defaultManager] createDirectoryAtURL:rootDirectory withIntermediateDirectories:YES attributes:nil error:nil];
                }
            }
    
            dispatch_async(dispatch_get_main_queue(), ^{
                completionHandler(rootDirectory);
            });
        });
    }
    
    - (NSURL *)localPathForResource:(NSString *)resource ofType:(NSString *)type {
        NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
        NSString *resourcePath = [[documentsDirectory stringByAppendingPathComponent:resource] stringByAppendingPathExtension:type];
        return [NSURL fileURLWithPath:resourcePath];
    }
    

    I have a file called demo.pdf stored in the Documents folder, which I'll be 'uploading'.

    I'll highlight some parts:

    URLForUbiquityContainerIdentifier: provides the root directory for storing files, if you want to them to show up in de iCloud Drive on your Mac, then you need to store them in the Documents folder, so here we add that folder to the root:

    NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"];
    

    You also need to add the file name to the URL, here I copy the filename from the localURL (which is demo.pdf):

    // Now, append the local filename to the ubiquityURL
    ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent];
    

    And that's basically it...

    As a bonus, check out how you can provide an NSError pointer to get potential error information:

    // And finish up the 'store' action
    NSError *error;
    if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) {
        NSLog(@"Error occurred: %@", error);
    }
    

提交回复
热议问题