2015-03-05 3 views
2

У меня есть класс наклейки, и я сохраняю объекты наклейки в 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. Нет идеи, что здесь происходит.

+0

Почему downvote? Это хорошо спроектированный вопрос, и ответ вовсе не очевиден. – trojanfoe

+0

OP: Я предполагаю, что 'Sticker' заявляет, что он соответствует' NSCoding'? (Я не уверен, что словарь будет проверять свои члены с помощью 'СоответствиеТоПротокол' или если они реализуют методы протокола). – trojanfoe

+0

да, это соответствует NSCoding – KeXMeX

ответ

1

только для справки других людей проблема заключалась в том, что сначала не было преобразование UIImage в NSData. Я изменил UIImage строки в методе aCoder ниже:

[aCoder encodeObject:UIImagePNGRepresentation(self.image) forKey:@"image"]; 

и в aDecoder: self.image = [UIImage imageWithData:[aDecoder decodeObjectForKey:@"image"]];

не совсем понимаю, почему он работал NSData, который был преобразован в UIImage для загрузки Разбор перед тем но сейчас все работает.