0

@interface

@interface Patient : NSObject <NSCoding>

@implementation

- (id)initWithCoder:(NSCoder *)decoder{

    self.patientPhoto = [decoder decodeObjectForKey:kPatientPhoto];
    self.firstName = [decoder decodeObjectForKey:kFirstName];
    self.lastName = [decoder decodeObjectForKey:kLastName];
    self.age = [decoder decodeIntForKey:kAge];
    self.photoPaths = [decoder decodeObjectForKey:kPhotoPaths];
    self.photoDates = [decoder decodeObjectForKey:kPhotoDates];

    return self;

   }

- (void)encodeWithCoder:(NSCoder *)encoder{

        [encoder encodeObject:self.patientPhoto forKey:kPatientPhoto];
        [encoder encodeObject:self.firstName forKey:kFirstName];
        [encoder encodeObject:self.lastName forKey:kLastName];
        [encoder encodeInt:self.age forKey:kAge];
        [encoder encodeObject:self.photoPaths forKey:kPhotoPaths];
        [encoder encodeObject:self.photoDates forKey:kPhotoDates];

    }

In a different implementation I attempt to archive the Patient Object.

     IMDataController* dataCtr = [IMDataController sharedDataController];

     Patient *currentPatient = [[Patient alloc]init];

     currentPatient.patientPhoto = self.photo.image;
     currentPatient.firstName = self.firstName.text;
     currentPatient.lastName = self.lastName.text;
     currentPatient.age = [self.lastName.text intValue];
     currentPatient.photoDates = nil;
     currentPatient.photoPaths = nil;

     NSString *patientNameForWriting = [self.firstName.text stringByAppendingString:self.lastName.text];

     NSString *stringToPatientObjectFile = [dataCtr createPatient:patientNameForWriting];

     NSFileManager* filemanager = [NSFileManager defaultManager];

    NSData *patientObjectArchived = [NSKeyedArchiver archivedDataWithRootObject:currentPatient];


     if([patientObjectArchived writeToFile:stringToPatientObjectFile atomically:YES]){


     }else{

         NSLog(@"Patient Object Didn't Archive");

     }

The above method within the if statement is not returning YES. I have checked the data against nil, I have checked my encoder method and I cannot find the problem. I am writing the data to a NSString file Path:.../Documents/PatientName/PatientObject.archive. I am conforming to the protocol in the patient class also.

Michael
  • 6,561
  • 5
  • 38
  • 55
  • You might be able to get more information about exactly what is going wrong by using `writeToFile:options:error:` to write the file and then inspecting the `NSError` object for details. – aroth May 03 '12 at 03:51
  • What does createPatient: do? If that's not creating a full path to write to, then that's your problem. – rdelmar May 03 '12 at 06:17
  • createPatient returns a full path to my file. I NSLoged it to verify that the path was correct, and indeed it was. So I do not think the problem is the path – Michael May 03 '12 at 14:12

2 Answers2

1

Make sure the parent directory exists. As far as I can remember, writeToFile:atomically: does not create the directory hierarchy automatically.

Costique
  • 23,712
  • 4
  • 76
  • 79
0

Replace your NSCoding implementation with the following:

- (id)initWithCoder:(NSCoder *)decoder{
    if (self = [super initWithCoder:(NSCoder *) decoder]) 
    {
        self.patientPhoto = [decoder decodeObjectForKey:kPatientPhoto];
        self.firstName = [decoder decodeObjectForKey:kFirstName];
        self.lastName = [decoder decodeObjectForKey:kLastName];
        self.age = [decoder decodeIntForKey:kAge];
        self.photoPaths = [decoder decodeObjectForKey:kPhotoPaths];
        self.photoDates = [decoder decodeObjectForKey:kPhotoDates];
    }
    return self;

   }

- (void)encodeWithCoder:(NSCoder *)encoder{
        [super encodeWithCoder:encoder];
        [encoder encodeObject:self.patientPhoto forKey:kPatientPhoto];
        [encoder encodeObject:self.firstName forKey:kFirstName];
        [encoder encodeObject:self.lastName forKey:kLastName];
        [encoder encodeInt:self.age forKey:kAge];
        [encoder encodeObject:self.photoPaths forKey:kPhotoPaths];
        [encoder encodeObject:self.photoDates forKey:kPhotoDates];

 }

And then, change the line:

NSData *patientObjectArchived = [NSKeyedArchiver archivedDataWithRootObject:currentPatient];

with:

NSMutableData *patientObjectArchived = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData: patientObjectArchived];
[archiver encodeObject:currentPatient forKey:@"someKey"];
[archiver finishEncoding];
graver
  • 15,183
  • 4
  • 46
  • 62
  • I am inheriting from NSObject which does not conform to the NSCoding protocol, is it still necessary to call initWIthCoder on super? – Michael May 03 '12 at 14:14
  • No, if your superclass doesn't conform to NSCoding you could call any initializer you want, in this case probably just `-init` – JSquared Jun 13 '18 at 16:45