Harish Harish - 1 month ago 10
iOS Question

How to save NSMutablearray that is present in a class to a file?

Student.h

#import <Foundation/Foundation.h>
#import "Subject.h"

@interface Student : NSObject <NSCoding> {
NSString *studentID;
NSString *studentName;
NSMutableArray<Subject* > *subjects;
}

@property (copy) NSString *studentID;
@property (copy) NSString *studentName;
@property (copy) NSMutableArray<Subject* > *subjects;

-(Student *)initWithStudentID:(NSString *)ID andStudentName:(NSString *)name;

-(void)addSubject:(Subject *) subject;
@end


Student.m

#import "Student.h"

@implementation Student

@synthesize studentName;
@synthesize studentID;
@synthesize subjects;

-(Student *)initWithStudentID:(NSString *)ID andStudentName:(NSString *)name {

Student *student = [[Student alloc] init];

student.studentID = [NSString stringWithString:ID];
student.studentName = [NSString stringWithString:name];

return student;
}

-(void)addSubject:(Subject *)subject{
if(subjects==nil){
subjects=[[NSMutableArray alloc]init];
}
[subjects addObject:subject];


}

- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
[self setStudentID:[aDecoder decodeObjectForKey:@"studentID"]];
[self setStudentName:[aDecoder decodeObjectForKey:@"studentName"]];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:subjects] forKey:@"subjects"];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:studentID forKey:@"studentID"];
[aCoder encodeObject:studentName forKey:@"studentName"];
[aCoder encodeObject:subjects forKey:@"subjects"];
}

@end


Subject.h

#import <Foundation/Foundation.h>

@interface Subject : NSObject
@property NSString *subjectID;
@property NSString *subjectName;
@end


Subject.m

#import "Subject.h"

@implementation Subject
@end


Main.m

#import <Foundation/Foundation.h>
#import "Student.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *student1=[[Student alloc ]initWithStudentID:@"Nirmal" andStudentName:@"101"];

Subject *subject = [Subject alloc];
subject.subjectID=@"S01";
subject.subjectName=@"PHY";

[student1 addSubject:subject];

[NSKeyedArchiver archiveRootObject:student1 toFile:@"/Users/kuzhandaivel/Documents/nirmal.plist"];

Student *student2=[NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/kuzhandaivel/Documents/nirmal.plist"];

NSLog(@"%@",student2.studentID);
NSLog(@"%@",student2.studentName);
NSLog(@"%@",[student2.subjects description]);

}
return 0;
}


How to save NSMutablearray that is present in a class to a file?
The above program throws the below error at line:

[aCoder encodeObject:subjects forKey:@"subjects"];


at
encodeWithCoder
function present in student.m file.


Archiver[4667:102276] -[Subject encodeWithCoder:]: unrecognized selector sent to instance 0x1006000a0
2016-10-22 20:25:57.738 Archiver[4667:102276] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Subject encodeWithCoder:]: unrecognized selector sent to instance 0x1006000a0'
*** First throw call stack:

Answer

Subject also needs to conform to the NSCoding protocol just like Student.

Every class stored within the root object you are archiving must conform to the NSCoding protocol.