У меня есть класс наклейки, и я сохраняю объекты наклейки в NSMutableDictionary. Наклейка класс ниже:Не удалось сохранить словарь NSMutable в документах. UIImage не будет сохранять/отображать
#import "Sticker.h"
@implementation Sticker
-(instancetype)initWithTitle:(NSString *)title stickerNO:(int)stickerNO image:(UIImage *)image {
self=[super init];
if(self){
self.title=title;
self.stickerNO=[NSNumber numberWithInt:stickerNO];;
self.image=image;
}
return self;
}
//CODING METHODS//////////////
-(void)encodeWithCoder:(NSCoder *)aCoder{
//choose what we save, these are objects
[aCoder encodeObject:self.title forKey:@"title"];
[aCoder encodeObject:self.stickerNO forKey:@"stickerNO"];
[aCoder encodeObject:self.image forKey:@"image"];
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
self=[super init];
if(self){
self.title=[aDecoder decodeObjectForKey:@"title"];
self.stickerNO=[aDecoder decodeObjectForKey:@"stickerNO"];
self.image=[aDecoder decodeObjectForKey:@"image"];
}
return self;
}
@end
Словарь управляется классом StickerManager:
@implementation StickerManager
-(instancetype)init {
self = [super init];
//load the dictionary
NSString *path = [self itemArchivePath];
self.stickerDictionary=[NSKeyedUnarchiver unarchiveObjectWithFile:path];
//if there is no dictionary create it and add the default
if(!self.stickerDictionary) {
NSLog(@"Creating dictionary and adding default");
self.stickerDictionary=[[NSMutableDictionary alloc] init];
[self addDefaultStickers];
[self saveStickerDictionary];
}
//if empty fill it
else if ([self.stickerDictionary count]==0){
NSLog(@"Dictionary exists but it empty");
[self addDefaultStickers];
[self saveStickerDictionary];
}
return self;
}
//add the stickers included in the app bundle
-(void)addDefaultStickers {
Sticker *sticker = [[Sticker alloc] initWithTitle:@“Batman” stickerNO:1 image:[UIImage imageNamed:@“batman.png"]];
[self.stickerDictionary setObject:sticker forKey:sticker.title];
}
-(BOOL)saveStickerDictionary{
NSLog(@"Saving stickers");
//get the path from above
NSString *path = [self itemArchivePath];
return [NSKeyedArchiver archiveRootObject:self.stickerDictionary toFile:path];
}
-(NSString *)itemArchivePath
{
//get the directory
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//set it to a string
NSString *documentDirectory = [documentDirectories firstObject];
//here we call the file items.archive
return [documentDirectory stringByAppendingPathComponent:@"stickers.archive"];
}
@end
Если когда StickerManager будет инициализации, если она пуста или не существует, он будет создан и заполнить словарь с наклейки по умолчанию, вызывая addDefaultStickers. Это работает для одного стикера, который у меня есть в коде. Я могу загрузить и восстановить словарь и использовать NSLog для проверки содержимого. Наклейка есть, но по какой-то причине UIImage имеет значение null, и я не могу ее отобразить. Я действительно не уверен, почему, я использовал encodeWithCoder для него, так что не должно ли это работать? Странно то, что если я загружу стикер из Parse.com (у меня есть идентичный класс на нем), а затем конвертируйте это изображение из NSData в png и сохраните его, это сработает. Может ли кто-нибудь дать мне несколько указателей, пожалуйста, что здесь может быть неправильным? Благодаря
EDIT Это моя загрузка с Parse.com кода:
- (void)getNewStickersWithCompletionHandler:(stickerCompletionHandler)handler
{
__weak StickerManager *weakSelf = self;
PFQuery *stickersQuery = [PFQuery queryWithClassName:@"sticker"];
[stickersQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error) {
for(PFObject *object in objects) {
NSString *title = object[@"title"];
int stickerNO = [[object objectForKey:@"stickerNO"] intValue];
//DOWNLOAD IMAGE CODE
PFFile *image = object[@"image"];
[image getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if(!error){
UIImage *image = [UIImage imageWithData:data];
Sticker *sticker = [[Sticker alloc] initWithTitle:title stickerNO:stickerNO image:image];
[weakSelf.stickerDictionary setObject:sticker forKey:sticker.title];
[self saveStickerDictionary];
handler(YES,nil);
}
}];//end get image block
}//end for
}
}];//end download stickers block
}
Если я сохранить наклейку словаря таким образом нет никаких проблем, и я могу отобразить изображение. Это почти идентично addDefaultStickers, я сохраняю UIImage и не сохраняю NSData. Нет идеи, что здесь происходит.
Почему downvote? Это хорошо спроектированный вопрос, и ответ вовсе не очевиден. – trojanfoe
OP: Я предполагаю, что 'Sticker' заявляет, что он соответствует' NSCoding'? (Я не уверен, что словарь будет проверять свои члены с помощью 'СоответствиеТоПротокол' или если они реализуют методы протокола). – trojanfoe
да, это соответствует NSCoding – KeXMeX