使用NSURLIsExcludedFromBackupKey而不会在iOS 5.0上崩溃

时间:2012-03-08 15:56:44

标签: iphone objective-c ios

检查可用性似乎工作正常但我似乎无法设置NSURLIsExcludedFromBackupKey密钥而不会在启动时出现此崩溃:

  

dyld:未找到符号:_NSURLIsExcludedFromBackupKey参考自:   / Users / sam / Library / Application Support / iPhone   模拟器/ 5.0 /应用/ B0872A19-3230-481C-B5CE-D4BDE264FBDF / Transit.app /过境   期望:   /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/System/Library/Frameworks/Foundation.framework/Foundation   in / Users / sam / Library / Application Support / iPhone   模拟器/ 5.0 /应用/ B0872A19-3230-481C-B5CE-D4BDE264FBDF / Transit.app /交通

这是我的方法:

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL {    
    if (&NSURLIsExcludedFromBackupKey == nil)
        return NO;

    NSError *error;
    [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
    return (error != nil);
}

如果我注释掉这一行,崩溃就会消失:

[URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];

我必须弱化基金会吗?

编辑:不确定它是否有所作为,但此方法放在NSFileManager类别中。

6 个答案:

答案 0 :(得分:19)

这是iOS< = 5.0.1和> = 5.1的代码,包括@Cocoanetics提到的迁移技术。

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    const char* filePath = [[URL path] fileSystemRepresentation];
    const char* attrName = "com.apple.MobileBackup";
    if (&NSURLIsExcludedFromBackupKey == nil) {
        // iOS 5.0.1 and lower
        u_int8_t attrValue = 1;
        int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
        return result == 0;
    } else {
        // First try and remove the extended attribute if it is present
        int result = getxattr(filePath, attrName, NULL, sizeof(u_int8_t), 0, 0);
        if (result != -1) {
            // The attribute exists, we need to remove it
            int removeResult = removexattr(filePath, attrName, 0);
            if (removeResult == 0) {
                NSLog(@"Removed extended attribute on file %@", URL);
            }
        }

        // Set the new key
        return [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
    }
}

答案 1 :(得分:5)

这似乎是iPhone 5.0模拟器的一个错误。我尝试在5.0设备上运行代码,没有崩溃。将此错误报告为rdar://11017158

编辑:这已在Xcode 4.5 DP2中修复(不确定是否在4.4中)。

答案 2 :(得分:4)

添加此行以强制符号为弱导入:

extern NSString * const NSURLIsExcludedFromBackupKey __attribute__((weak_import));

答案 3 :(得分:2)

根据您的操作,此快速修复可能适合您。它确实适合我。

CoreFoundation框架添加到您的项目中,并将其标记为可选(不是必需的)。

答案 4 :(得分:1)

问题是此密钥仅出现在5.1及更高版本上。对于5.0.1,您需要设置扩展文件属性。唯一向后兼容的方法是找出此密钥的NSString值,并将其设置为低于5.1。

答案 5 :(得分:0)

在更新ShareKit并将项目重做为目标iOS 5.1后,我有同样的事情。我会在编译时或在与NSURLIsExcludedFromBackupKey相关的链接中遇到错误。 ShareKit人员似乎建议您通过确保项目与CoreFoundation框架链接并将其设置为“Optional”而不是“Required”来解决问题。然而,这对我不起作用。

最终我使用预处理器解决了这个问题:

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    #ifndef NSURLIsExcludedFromBackupKey                   
    // iOS <= 5.0.1.
    const char* filePath = [[URL 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;
    #else                                                                       
    // iOS >= 5.1
    // First try and remove the extended attribute if it is present
    int result = getxattr(filePath, attrName, NULL, sizeof(u_int8_t), 0, 0);
    if (result != -1) {
        // The attribute exists, we need to remove it
        int removeResult = removexattr(filePath, attrName, 0);
        if (removeResult == 0) {
            NSLog(@"Removed extended attribute on file %@", URL);
        }
    }
    return [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
    #endif
}