Подтвердить что ты не робот

Использовать NSURLIsExcludedFromBackupKey без сбоев в iOS 5.0

Проверка доступности, похоже, работает нормально, но я не могу установить ключ NSURLIsExcludedFromBackupKey, не получив этот сбой при запуске:

dyld: Символ не найден: _NSURLIsExcludedFromBackupKey Ссылка на: /Пользователи/sam/Library/Поддержка приложений /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/Пользователи/sam/Library/Поддержка приложений /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];

Нужно ли мне создавать слабые ссылки?

EDIT: не уверен, что это имеет значение, но этот метод помещается внутри категории NSFileManager.

4b9b3361

Ответ 1

Кажется, это ошибка с симулятором iPhone 5.0. Я попытался запустить код на устройстве 5.0 и без сбоев. Сообщается об этой ошибке как rdar://11017158.

EDIT: это было исправлено в Xcode 4.5 DP2 (не уверен, что оно находится в 4.4).

Ответ 2

Здесь код для 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];
    }
}

Ответ 3

Добавьте эту строку, чтобы заставить символ быть слабым.

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

Ответ 4

В зависимости от того, что вы делаете, это быстрое исправление может сработать для вас. Это было для меня.

Добавьте в проект инфраструктуру CoreFoundation и отметьте ее как ДОПОЛНИТЕЛЬНО (не обязательно).

Ответ 5

Проблема в том, что этот ключ присутствует только на 5.1 и выше. Для 5.0.1 вам нужно установить расширенный атрибут файла. Единственным методом обратной совместимости было бы узнать значение NSString этого ключа и установить это ниже 5.1.

Ответ 6

У меня было то же самое после обновления ShareKit и перепроектирования проекта для iOS 5.1. Я бы либо получил ошибку при компиляции, либо связан с NSURLIsExcludedFromBackupKey. Люди ShareKit, похоже, рекомендуют решить эту проблему, убедившись, что ваш проект связан с базой CoreFoundation и установите его "Необязательно", а не "Обязательно". Однако это не сработало для меня.

В конце концов я обошел его, используя препроцессор:

- (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
}