Приложение сбой при хранении NSArray в NSUserDefaults
Я не мог хранить NSArray в NsUserDefaults
. Приложение разбилось
в этой строке
[savedData setObject:jsonValue forKey:@"JSONDATA"];
Ниже мой код. и я упоминаю мою ошибку журнала ниже
NSArray *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
[savedData setObject:jsonValue forKey:@"JSONDATA"];
[savedData synchronize];
Журнал ошибок:
*** Terminating app due to uncaught exception '`NSInvalidArgumentException`', reason: '*** -
[NSUserDefaults setObject:forKey:]: attempt to insert non-property list object <CFBasicHash 0x8c62b10 [0x1d2aec8]>{type = immutable dict, count = 3,
entries =>
Ответы
Ответ 1
Да, они не могут быть сохранены как в NSUserDefaults.
Я пишу код ниже, пожалуйста, посмотрите и для более подробного изучения посмотрите, как выглядят документы яблока.
Код находится здесь:
//Для сохранения
NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject:yourArrayToBeSave]];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:@"array"];
[[NSUserDefaults standardUserDefaults] synchronize]; // this will save you UserDefaults
//Для получения
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Ответ 2
В то время как ответ kshitij правильный, к сожалению, на этом не заканчивается. Если вы хотите сохранить пользовательские объекты внутри своего NSUserDefaults
, ваш пользовательский объект должен реализовать протокол NSCoding
и переопределить методы initWithCoder
и encodeWithCoder
. Примером такого может быть:
@interface Book : NSObject <NSCoding>
@property NSString *title;
@property NSString *author;
@property NSUInteger pageCount;
@property NSSet *categories;
@property (getter = isAvailable) BOOL available;
@end
@implementation Book
#pragma mark - NSCoding
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (!self) {
return nil;
}
self.title = [decoder decodeObjectForKey:@"title"];
self.author = [decoder decodeObjectForKey:@"author"];
self.pageCount = [decoder decodeIntegerForKey:@"pageCount"];
self.categories = [decoder decodeObjectForKey:@"categories"];
self.available = [decoder decodeBoolForKey:@"available"];
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.title forKey:@"title"];
[encoder encodeObject:self.author forKey:@"author"];
[encoder encodeInteger:self.pageCount forKey:@"pageCount"];
[encoder encodeObject:self.categories forKey:@"categories"];
[encoder encodeBool:[self isAvailable] forKey:@"available"];
}
@end
Ответ 3
Я думаю, что jsonValue - это NSDictionary, а не NSArray..
id jsonValue = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
if ([jsonValue isKindOfClass:[NSDictionary class]])
{
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:jsonvalue];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"JSONDATA"];
[savedData synchronize];
}
//(ИЛИ)
NSDictionary *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:jsonvalue];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"JSONDATA"];
[savedData synchronize];
Также я думаю, что вы не можете хранить NSDictionary прямо в NSUserDefaults. Пройдите через @kshitij godara, чтобы сделать это/сохранить.
Вы можете использовать NSKeyedArchiver для записи своего словаря в NSData.
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:jsonvalue];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"JSONDATA"];
Для получения данных:
NSData *dictionaryData = [defaults objectForKey:@"JSONDATA"];
NSDictionary *dictionary = [NSKeyedUnarchiver unarchiveObjectWithData:dictionaryData];
Надеюсь, это поможет вам!..
Ответ 4
попробуйте это
NSMutableArray *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSData *yourEncodedObject = [NSKeyedArchiver archivedDataWithRootObject: jsonValue];
NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
[userData setObject: yourEncodedObject forKey:@"JSONDATA"];
[savedData synchronize];
Ответ 5
NSUserDefaults принимает объекты списка свойств - NSDictionary, NSArray, NSString, NSNumber, NSDate и NSData. Документы JSON содержат NSDictionary, NSArray, NSString, NSNumber и NSNull. Вы видите, что объекты списка различий - свойств не могут содержать значения NSNull.
Если ваш объект JSON содержит объект NSNull (в документе JSON, который вы проанализировали, содержится "нулевое" значение), вы не можете сохранить его в NSUserDefaults. Кроме того, все комментарии о том, что вы не можете хранить данные JSON в NSUserDefaults, - это нонсенс. Это вызовут только объекты NSNull.
Существует очень, очень простое решение вашей проблемы. Просто сохраните исходные данные json как объект NSData в NSUserDefaults. Затем, когда вы читаете NSUserDefaults, вы получаете NSData и анализируете их. Вместо
NSArray *jsonValue =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
[savedData setObject:jsonValue forKey:@"JSONDATA"];
[savedData synchronize];
вы просто пишете
NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
[savedData setObject:data forKey:@"JSONDATA"];
[savedData synchronize];
Ответ 6
Вы должны сначала выделить NSArray, тогда вы можете передать значения в массиве. Вы не можете напрямую передать значение.
NSArray * a = [[NSArray alloc] initWithObjects: [NSJSONSerialization JSONObjectWithData: параметры данных: 0 error: nil], nil];
Ответ 7
NSUserDefaults следует использовать только для 500 000 данных (https://forums.developer.apple.com/message/50696#50696)
При хранении больших объемов приложений приложения могут упасть, из личного опыта я видел приложения, в которых хранилось 1 МБ данных, сбой/вскоре после [NSUserDefaults setObject:] и [NSUserDefaults synchronize];
Чтобы проверить, сколько данных используется в реальном времени, откройте Xcode → Window → Devices, выберите ваше устройство, выберите ваше приложение в Installed Apps и загрузите App Container. Значения по умолчанию хранятся в AppData- > Preferences- > your.app.plist
Альтернативой сохранению данных для пользовательских настроек по умолчанию является запись в файл:
-(void)saveObject:(NSObject *)object toFile:(NSString *)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:name];
[NSKeyedArchiver archiveRootObject:object toFile:appFile];
}
-(NSObject *)loadFromFile:(NSString *)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:name];
if([[NSFileManager defaultManager] fileExistsAtPath:appFile])
return [NSKeyedUnarchiver unarchiveObjectWithFile:appFile];
else{
NSLog(@"No File: %@", name) ;
return nil ;
}
}