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
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 ofNSFileManager
orNSPathUtilities
. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With