Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSKeyedArchiver archiveRootObject always returns NO

I'm new to objective C and writing some simple programs to familiarize myself.

Trying to save / read information with NSKeyedArchiver but every time I do it fails to create the .plist file. I've looked around and haven't been able to find an answer. Can anyone help me understand why "Something went wrong..." is always the final output?

Thanks!

// main.m
#import <Foundation/Foundation.h>
#import "Domicile.h"

void CreateAndArchive(NSMutableArray* objs, NSURL *saveLocation)
{
    NSLog(@"Creating DOMICILE objects...");

    Domicile *now = [[Domicile alloc] init];
    Domicile *then = [[Domicile alloc] init];

    now.HouseName = @"place1;
    now.Address = @"506 99th street";
    now.Residents = [[NSMutableArray alloc] initWithObjects: @"Erik", @"Jeremiah", @"Alex", @"Ryan", @"Kyle", @"Connor", nil];
    now.City = @"aCity";
    now.State = @"CA";
    now.Zip = @"12345";

    then.HouseName = @"place2";
    then.Address = @"1011 E Fairmont street";
    then.Residents = [[NSMutableArray alloc] initWithObjects: @"Erik", @"Asa", @"Ryan", @"Gabe", @"Josh", nil];
    then.City = @"anotherCity";
    then.State = @"VA";
    then.Zip = @"54321";

    NSMutableArray *saveThis = [[NSMutableArray alloc] initWithObjects: now, then, nil];

    NSLog(@"saving to %@", [saveLocation absoluteString]);
    if ([NSKeyedArchiver archiveRootObject:saveThis toFile:[saveLocation absoluteString]])
    {
        NSLog(@"SAVED!");
    }
    else{
        NSLog(@"Something went wrong...");
    }
}

NSMutableArray* Load(NSURL *location){
    NSLog(@"Loading data from %@", [location absoluteString]);

    return [NSKeyedUnarchiver unarchiveObjectWithFile: [location absoluteString]];
}


int main(int argc, const char * argv[])
{
    @autoreleasepool {

        NSURL *dir = [[NSFileManager defaultManager] URLForDirectory:NSDesktopDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        NSURL *file = [dir URLByAppendingPathComponent:@"data.plist"];

        NSMutableArray *domiciles = [[NSMutableArray alloc] init];

        if ([[NSFileManager defaultManager] fileExistsAtPath:[file absoluteString]])
        {
            domiciles = Load(file);
            NSLog(@"data loaded!");
            NSLog(@"displaying for your convenience:");

            for (Domicile *dom in domiciles) {
                NSLog(@"\n\n%@", dom);
            }
        }
        else
        {
            CreateAndArchive(domiciles, file);
        }

    }
    return 0;
}

//  Domicile.m
#import "Domicile.h"

@implementation Domicile

-(instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        _HouseName = [coder decodeObjectForKey:@"name"];
        _Residents = [coder decodeObjectForKey:@"residents"];
        _Address = [coder decodeObjectForKey:@"address"];
        _City = [coder decodeObjectForKey:@"city"];
        _State = [coder decodeObjectForKey:@"state"];
        _Zip = [coder decodeObjectForKey:@"zip"];
    }
    return self;
}

-(void) encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.HouseName forKey:@"name"];
    [aCoder encodeObject:self.Residents forKey:@"residents"];
    [aCoder encodeObject:self.Address forKey:@"address"];
    [aCoder encodeObject:self.City forKey:@"city"];
    [aCoder encodeObject:self.State forKey:@"state"];
    [aCoder encodeObject:self.Zip forKey:@"zip"];
}


-(NSString *) description{
    NSString *desc = [[NSString alloc] initWithFormat: @"House : %@\n%@\n%@, %@\n%@\n", self.HouseName, self.Address, self.City, self.State, self.Zip];
    return desc;
}
@end
like image 813
E.T. Avatar asked Aug 14 '14 04:08

E.T.


1 Answers

When you want to convert a file NSURL for use in a method that needs a path, you should use the path method, not the absoluteString method. As the path method documentation says:

If the URL object contains a file or file reference URL (as determined with isFileURL), the return value of this method [path] is suitable for input into methods of NSFileManager or NSPathUtilities. If the path has a trailing slash, it is stripped.

The absoluteString method is returning a string that looks like file:///Users/..., but you don't want that file:// scheme prefix in these methods that are looking for a path for some resource. The path method returns your file path, unencumbered by the file:// prefix.

like image 55
Rob Avatar answered Oct 05 '22 12:10

Rob