Chris
Chris

Reputation: 5627

Apply NSURLIsExcludedFromBackupKey to Server URL or URL of Directory on iPhone?

I am battling with an app rejection due to how I am saving some downloaded files on the iPhone.

I have implemented NSURLIsExcludedFromBackupKey but I am not clear if I am doing it correctly. Should I be applying NSURLIsExcludedFromBackupKey to the NSURL that represents the file on my server, or do I somehow apply it to the directory on the iPhone where I am saving the file?

Here is what I have created now, after the app was rejected:

// Get / Create the File Directory on the iPhone 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"MyDirectory"];

if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil]; 

// Setup the NSURL where the PNG is located
NSURL *imageURL = [NSURL URLWithString:@"http://www.myserver.com/image.png"];

NSError *err = nil; // Exclude This Image from the iCloud backup system
BOOL excluded = [imageURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&err];

if (!excluded) {
        //NSLog(@"Failed to exclude from backup");
} else {
    //NSLog(@"Excluding from backup"); // this works...
}
// Create the UIImage
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:imageURL]];

// Data about the downloaded image
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(image)];

if ([data1 writeToFile:pngFilePath atomically:YES] && [data1 writeToFile:pngFilePathRetina atomically:YES]) {
        // Saved to phone
} else {        
        // Did not save to phone
}

Upvotes: 0

Views: 1118

Answers (2)

Mike Abdullah
Mike Abdullah

Reputation: 15013

To more succinctly answer your original question:

You should apply NSURLIsExcludedFromBackupKey to the destination. i.e. the files or directories you don't want to be backed up.

The iPhone has no knowledge of what remote files your app might be making use of, and so can't possibly attempt to back them up. More importantly, if you try to set NSURLIsExcludedFromBackupKey on such URLs, you'll quickly see it fails due to an unsupported URL.

Upvotes: 0

Chris
Chris

Reputation: 5627

Here is how I ended up coding it so that it got approved. It is probably a little overkill, but better than spending an month trying to guess exactly how to get it approved.

 // Get / Create the File Directory on the iPhone 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"MyDirectory"];

// if the directory does not yet exist on the phone, create it
    if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
    [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil]; 


    // Assign NSURLIsExcludedFromBackupKey to the directory at dataPath, so is does not backup to iCloud
    NSURL *directoryUrl = [NSURL fileURLWithPath:dataPath isDirectory:YES];
    NSError *err1 = nil;
    BOOL excluded1 = [directoryUrl
                         setResourceValue:[NSNumber numberWithBool:YES]
                         forKey:NSURLIsExcludedFromBackupKey
                         error:&err1];

    if (!excluded1) {
            //NSLog(@"Failed to exclude directory from backup");
    } else {
            //NSLog(@"Excluding directory from backup");
    }



    // Setup the NSURL where the PNG, which will be downloaded, is located 
    NSURL *imageURL = [NSURL URLWithString:@"http://www.myserver.com/image.png"];

    NSError *err2 = nil; // Exclude This Image from the iCloud backup system, Not sure if I need this or not…
    BOOL excluded2 = [imageURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&err2];

    if (!excluded2) {
        //NSLog(@"Failed to exclude from backup");
    } else {
        //NSLog(@"Excluding from backup"); // this works...
    }


   // Create the UIImage
    UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:imageURL]];

    // Data about the downloaded image
    NSData *downloadedImageData = [NSData dataWithData:UIImagePNGRepresentation(image)];

    // Path for where we are going to save the image
    NSString *storePath = [NSString stringWithFormat:@"%@/myimage.png", dataPath]; 

    if ([downloadedImageData writeToFile:storePath atomically:YES]) {

  // the Image is saved to the phone

  // NSURL representing the image that is now saved on the phone          
  NSURL *imageOnPhone = [NSURL fileURLWithPath:storePath isDirectory:YES];

        // Exclude this image, which is now stored on the phone, from iCloud Backup
        NSError *err3 = nil;
        BOOL excluded3 = [imageOnPhone
                                  setResourceValue:[NSNumber numberWithBool:YES]
                                  forKey:NSURLIsExcludedFromBackupKey
                                  error:&err3];
            if (!excluded3) {
                //NSLog(@"Failed to exclude from backup (standard)");
            } else {
                //NSLog(@"Excluding from backup (standard)");
            }

    } else {        
            // Did not save to phone
    }

Upvotes: 1

Related Questions