I have a NSMutableArray filled with objects of my Movie class wich i want to save but it doesn't work and i can not figure out why...
Movie.h:
@interface Movie : NSObject <NSCoding>{
NSString *name;
int year;
int length;
NSString *file_size;
int rating;
NSArray *genre;
NSString *plot;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) int year;
@property (nonatomic, assign) int length;
@property (nonatomic, retain, retain) NSString *file_size;
@property (nonatomic, assign) int rating;
@property (nonatomic, retain) NSArray *genre;
@property (nonatomic, retain) NSString *plot;
-(id) initWithName:(NSString*)newName year:(int)newYear length:(int)newLength filesize:(NSString*)newFileSize rating:(int)newRating genre:(NSArray*)newGenre plot:(NSString*)newPlot;
- (void) encodeWithCoder : (NSCoder *)encode ;
- (id) initWithCoder : (NSCoder *)decode;
@end
Movie.m:
@implementation Movie
@synthesize name;
@synthesize year;
@synthesize length;
@synthesize file_size;
@synthesize rating;
@synthesize genre;
@synthesize plot;
-(id)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot{
self.name = newName;
self.year = newYear;
self.length = newLength;
self.file_size = newFileSize;
self.rating = newRating;
self.genre = newGenre;
self.plot = newPlot;
return self;
}
- (void)encodeWithCoder:(NSCoder *)encode;
{
[encode encodeObject:name forKey:@"name"];
[encode encodeInt32:year forKey:@"year"];
[encode encodeInt32:length forKey:@"length"];
[encode encodeObject:file_size forKey:@"file_size"];
[encode encodeInt32:rating forKey:@"rating"];
[encode encodeObject:genre forKey:@"genre"];
[encode encodeObject:plot forKey:@"plot"];
}
- (id)initWithCoder:(NSCoder *)decode;
{
NSString *name_decode = [decode decodeObjectForKey:@"name"];
int year_decode = [decode decodeInt32ForKey:@"year"];
int length_decode = [decode decodeInt32ForKey:@"length"];
NSString *file_size_decode = [decode decodeObjectForKey:@"file_size"];
int rating_decode = [decode decodeInt32ForKey:@"rating"];
NSArray *genre_decode = [decode decodeObjectForKey:@"genre"];
NSString *plot_decode =[decode decodeObjectForKey:@"plot"];
return [self initWithName:name_decode year:year_decode length:length_decode filesize:file_size_decode rating:rating_decode genre:genre_decode plot:plot_decode];
}
@end
Save Action (Movies is the NSMutableArray containing my Objects):
NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:Movies];
[userDefault setObject:encodedData forKey:[NSString stringWithFormat:@"MOVIES"]];
Load Action:
NSData *decodedData = [userDefault objectForKey: [NSString stringWithFormat:@"MOVIES"]];
NSArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: decodedData];
The returned Array is always (null)... i have no clue I tried several different kind of code snippets i found on the internet and/or stackoverflow
Your Movie initWithName...
method is incorrect. It needs to be:
- (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot {
self = [super init];
if (self) {
self.name = newName;
self.year = newYear;
self.length = newLength;
self.file_size = newFileSize;
self.rating = newRating;
self.genre = newGenre;
self.plot = newPlot;
}
return self;
}
Also, you seem to be following a very out-of-date tutorial.
@synthesize
.retain
properties should be strong
(thought the NSString
properties should be copy
.init
methods should return instancetype
, not id
.With all of that in mind, your Movie
class should be as follows:
Movie.h
@interface Movie : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int year;
@property (nonatomic, assign) int length;
@property (nonatomic, copy) NSString *file_size;
@property (nonatomic, assign) int rating;
@property (nonatomic, strong) NSArray *genre;
@property (nonatomic, copy) NSString *plot;
- (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot;
@end
Movie.m
@implementation Movie
- (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot {
self = [super init];
if (self) {
_name = newName;
_year = newYear;
_length = newLength;
_file_size = newFileSize;
_rating = newRating;
_genre = newGenre;
_plot = newPlot;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encode;
{
[encode encodeObject:self.name forKey:@"name"];
[encode encodeInt32:self.year forKey:@"year"];
[encode encodeInt32:self.length forKey:@"length"];
[encode encodeObject:self.file_size forKey:@"file_size"];
[encode encodeInt32:self.rating forKey:@"rating"];
[encode encodeObject:self.genre forKey:@"genre"];
[encode encodeObject:self.plot forKey:@"plot"];
}
- (instancetype)initWithCoder:(NSCoder *)decode;
{
NSString *name_decode = [decode decodeObjectForKey:@"name"];
int year_decode = [decode decodeInt32ForKey:@"year"];
int length_decode = [decode decodeInt32ForKey:@"length"];
NSString *file_size_decode = [decode decodeObjectForKey:@"file_size"];
int rating_decode = [decode decodeInt32ForKey:@"rating"];
NSArray *genre_decode = [decode decodeObjectForKey:@"genre"];
NSString *plot_decode =[decode decodeObjectForKey:@"plot"];
return [self initWithName:name_decode year:year_decode length:length_decode filesize:file_size_decode rating:rating_decode genre:genre_decode plot:plot_decode];
}
@end
You don't show how you create and populate your Movies
variable (which should be named movies
, not Movies
. Make sure it isn't nil
.
Also, don't needlessly use stringWithFormat
.
Your saving code should be:
NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:movies];
[userDefault setObject:encodedData forKey:@"MOVIES"];
and your loading code should be:
NSData *decodedData = [userDefault objectForKey:@"MOVIES"];
NSArray *decodedArray = [NSKeyedUnarchiver unarchiveObjectWithData: decodedData];