Устранение `+ [NSKeyedUnarchiver unarchiveTopLevelObjectWithData: error:]` устаревание приводит к ошибке «данные не могут быть прочитаны» - PullRequest
1 голос
/ 15 января 2020

У меня есть этот код, и он работает:

Foo *foo = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:&error];

Однако он выдает мне следующее предупреждение:

'unarchiveTopLevelObjectWithData: error:' устарел: первый устарел в iOS 12.0 - Использовать + unarchivedObjectOfClass: fromData: error: вместо

Когда я пытаюсь сделать эту простую замену на:

Foo *foo = [NSKeyedUnarchiver unarchivedObjectOfClass:[Foo class] fromData:data error:&error];

... происходит сбой со следующей ошибкой :

Данные не могут быть прочитаны, поскольку они не в правильном формате.

Как правильно заменить этот устаревший метод на устаревший метод

1 Ответ

1 голос
/ 15 января 2020

Это возможно потому, что ваш объект соответствует NSCoding, но он должен соответствовать NSSecureCoding.

Если вы посмотрите документацию для unarchivedObjectOfClass: fromData: error: вы заметите, что он говорит:

Важно
Убедитесь, что вы приняли NSSecureCoding в типах, которые вы декодируете. Если какой-либо вызов метода с префиксом декодирования завершается неудачно, defaultodingDailFileurePolicy устанавливает ошибку, а не вызывает исключение. В этом случае текущие и все последующие вызовы декодирования возвращают 0 или ноль.

Таким образом, вам нужно сделать следующее, чтобы переключиться на неотрицательную функцию:

  1. Переключите функцию с [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:&error] на [NSKeyedUnarchiver unarchivedObjectOfClass:[Foo class] fromData:data error:&error], как говорится в предупреждении об устаревании.
  2. Поддержка Secure Кодирование:

    1. Switch ваше соответствие от NSCoding до NSSecureCoding для вашего объекта верхнего уровня.
    2. Добавьте свойство:

      @property (class, readonly) BOOL supportsSecureCoding;
      
    3. Реализуйте метод:

      + (BOOL)supportsSecureCoding {
          return YES;
      }
      
    4. Если у вашего объекта есть какие-либо другие свойства, которые NSCoding, повторите все эти шаги для них, чтобы они в конечном итоге соответствовали NSSecureCoding. Например, если в вашем кодируемом объекте Foo было свойство @property (nonatomic, strong) Bar *bar;, вам необходимо убедиться, что Bar также соответствует NSSecureCoding, а не просто NSCoding.

  3. (Необязательно) Измените вызов кодирования, чтобы требовать безопасного кодирования (т. Е. Вторым параметром может быть YES):

    [NSKeyedArchiver archivedDataWithRootObject:self requiringSecureCoding:YES error:&error];
    

Похоже, Apple хочет, чтобы люди переключились с NSCoding на NSSecureCoding, и проблема, описанная выше, была бы более очевидной, если бы NSCoding также устарела.

...