Я думал, что знаю, что является причиной этой ошибки, но я не могу понять, что я сделал не так.
Вот полное сообщение об ошибке, которое я получаю:
Попытка установить объект не-списка свойств ( «<BC_Person: 0x8f3c140>» ) в качестве значения NSUserDefaults для ключа personDataArray
У меня есть Person
класс, который, я думаю, соответствует NSCoding
протоколу, где у меня есть оба эти метода в моем личном классе:
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.personsName forKey:@"BCPersonsName"];
[coder encodeObject:self.personsBills forKey:@"BCPersonsBillsArray"];
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
self.personsName = [coder decodeObjectForKey:@"BCPersonsName"];
self.personsBills = [coder decodeObjectForKey:@"BCPersonsBillsArray"];
}
return self;
}
В какой-то момент приложения установлено значение NSString
in BC_PersonClass
, и у меня есть DataSave
класс, который, я думаю, обрабатывает кодирование свойств в моем BC_PersonClass
. Вот код, который я использую из DataSave
класса:
- (void)savePersonArrayData:(BC_Person *)personObject
{
// NSLog(@"name of the person %@", personObject.personsName);
[mutableDataArray addObject:personObject];
// set the temp array to the mutableData array
tempMuteArray = [NSMutableArray arrayWithArray:mutableDataArray];
// save the person object as nsData
NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];
// first add the person object to the mutable array
[tempMuteArray addObject:personEncodedObject];
// NSLog(@"Objects in the array %lu", (unsigned long)mutableDataArray.count);
// now we set that data array to the mutable array for saving
dataArray = [[NSArray alloc] initWithArray:mutableDataArray];
//dataArray = [NSArray arrayWithArray:mutableDataArray];
// save the object to NS User Defaults
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:dataArray forKey:@"personDataArray"];
[userData synchronize];
}
Я надеюсь, что этого кода достаточно, чтобы дать вам представление о том, что я пытаюсь сделать. Опять же, я знаю, что моя проблема заключается в том, как я кодирую свои свойства в своем классе BC_Person, я просто не могу понять, что, хотя я делаю неправильно.
Спасибо за помощь!
источник
that I think is conforming to the NSCoding protocol
для этого очень просто добавить модульное тестирование, и оно того стоит.Ответы:
Размещенный вами код пытается сохранить массив пользовательских объектов
NSUserDefaults
. Ты не можешь этого сделать. РеализацияNSCoding
методов не помогает. Вы можете хранить только такие вещи , какNSArray
,NSDictionary
,NSString
,NSData
,NSNumber
, иNSDate
вNSUserDefaults
.Вам нужно преобразовать объект в
NSData
(как у вас есть в некотором коде) и сохранить егоNSData
вNSUserDefaults
. Вы даже можете хранитьNSArray
вNSData
случае необходимости.Когда вы читаете обратно массив, вам нужно разархивировать его,
NSData
чтобы вернуть вашиBC_Person
объекты.Возможно, вы хотите это:
источник
NSMutableArray
расширяетсяNSArray
. Это прекрасно, чтобы передатьNSMutableArray
любой метод, который ожидаетNSArray
. Имейте в виду, что массив, фактически сохраненный в,NSUserDefaults
будет неизменным, когда вы будете читать его обратно.Мне кажется довольно расточительным бегать по массиву и кодировать объекты в NSData самостоятельно. Ваша ошибка
BC_Person is a non-property-list object
говорит вам, что фреймворк не знает, как сериализовать ваш объект person.Таким образом, все, что нужно, это убедиться, что ваш объект person соответствует NSCoding, тогда вы можете просто преобразовать свой массив пользовательских объектов в NSData и сохранить их по умолчанию. Вот детская площадка:
Редактировать : Запись в не
NSUserDefaults
работает на Xcode 7, поэтому игровая площадка будет архивировать данные и обратно и распечатывать вывод. Шаг UserDefaults включается в случае, если он исправлен на более позднем этапеИ вуаля, вы сохранили массив пользовательских объектов в NSUserDefaults
источник
func encode(with aCoder: NSCoder)
Сохранить:
Получить:
Для удаления
источник
Swift 3 Solution
Простой служебный класс
Модельный класс
Как позвонить
источник
Swift-4 Xcode 9.1
попробуй этот код
вы не можете хранить маппер в NSUserDefault, вы можете хранить только NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary.
источник
Во-первых, ответ rmaddy (выше) правильный: реализация
NSCoding
не помогает. Тем не менее, вам нужно реализовать,NSCoding
чтобы использоватьNSKeyedArchiver
и все такое, так что это всего лишь еще один шаг ... преобразование черезNSData
.Примеры методов
Таким образом, вы можете обернуть ваши
NSCoding
объекты вNSArray
илиNSDictionary
или что-то еще ...источник
У меня была проблема при попытке сохранить словарь
NSUserDefaults
. Оказывается, он не будет сохранять, потому что он содержитNSNull
значения. Поэтому я просто скопировал словарь в изменяемый словарь, удалил нули и затем сохранилNSUserDefaults
В этом случае я знал, какие ключи могут быть
NSNull
значениями.источник
Свифт с
@propertyWrapper
Сохранить
Codable
объект вUserDefault
Пример пользовательской модели подтверждения Codable
Как это использовать
источник
Структура Pref - это пользовательская оболочка вокруг стандартного объекта UserDefaults.
Так что вы можете использовать это так:
источник
if let data = UserDefaults.standard.data(forKey: keyUser) {
И, между прочим, просто бессмысленноUser
делатьUser
этоreturn try JSONDecoder().decode(User.self, from: data)
источник
Swift 5 Очень простой способ
источник