iPhone: move resources to Application bundle

2020-07-27 05:52发布

问题:

My application just got rejected from Apple because I store my resources under Documents folder! The Documents folder gets synched to iCloude automatically so only user generated data should be stored under Documents. All application data should go under Application bundle.

I use following method through out my project

- (NSString *)filePath:(NSString *)fileName {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName];
    return path;
}   

For example, following line unzip my resources under documents folder.

[SSZipArchive unzipFileAtPath: zipFileName toDestination:[self filePath: @""]];

How can I move these files and Resources folder images into Application bundle and access them?

[EDIT]

- (NSString *)filePath:(NSString *)fileName {
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/DoNotBackUp"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:nil];
        // Set do not backup attribute to whole folder
        if (iOS5) {
            BOOL success = [self addSkipBackupAttributeToItemAtURL:path];
            if (success) 
                NSLog(@"Marked %@", path);
            else
                NSLog(@"Can't marked %@", path);
        }
    }
    path = [path stringByAppendingPathComponent:fileName];

    return path;
}

/*
 set the document files attribute to marked "do not backup"
*/
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSString *)path
{
    const char* filePath = [path fileSystemRepresentation];

    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
}

Where iOS5 is BOOL variable:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

iOS5 = NO;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0.1")) 
    iOS5 = YES;

Thanks.

回答1:

You cannot write to the Bundle at runtime. You can only add resources to the bundle when creating the binary. You will need to place the results of the unzip process into the Caches Directory.

Because the contents of this folder can be deleted at any time by the system, you should check at every startup if the file needs to be unzipped again.

You will likely only need to change the first line of the above method to:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);


回答2:

in iOS 5.0.1 yo can add a new file attributo to mark them as non iCloud sync:

#include <sys/xattr.h>
- (void) AddSkipBackupAttributeToFile: (NSURL*) url
{
    u_int8_t b = 1;
    setxattr([[url path] fileSystemRepresentation], "com.apple.MobileBackup", &b, 1, 0, 0);
}