开发者

Issue with save file to Documents NSMutableArray with NSObjects

I'm a newbie iOS developer. I wrote a small application that save an NSMutableArray array with my objects that derived from NSObject. Application do the save but the file isn't created in document directory and application can't read. this issue is both on the simulator and my iPhone 3gs 4.2.1

My NSMutableArray definition inside the appDelegate class:

@property (nonatomic,retain, readwrite) NSMutableArray *places;

My NSObject class:

 #import <Foundation/Foundation.h>


@interface Place : NSObject {
    NSString *name;
    NSString *location;
}

-(id) init:(NSString *)name: (NSString *)location;

@property (retain,nonatomic,readwrite) NSString *name;
@property (retain,nonatomic,readwrite) NSString *location;

@end

My StorageService library class:

 #import "StorageService.h"


@implementation StorageService

-(id) init {
    self = [super init];
    if (self != nil) {

    }
    return self;
}


-(void) saveArrayToFile:(NSString*) filename : (NSMutableArray *)arrayToSave{
    // get full path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *fullPath = [paths objectAtIndex:0];
    fullPath = [fullPath stringByAppendingPathComponent:filename];  
    NSLog(@"Save in %@",fullPath);
    [arrayToSave writeToFile:fullPath atomically:YES];
}

-(NSMutableArray*) readArrayFromFile:(NSString *)filename {
    // get full path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *fullPath = [paths objectAtIndex:0];
    fullPath = [fullPath stringByAppendingPathComponent:filename];

    if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
        NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:fullPath];
        if (data == nil) {
            data = [[NSMutableArray alloc] init];
        }
        NSLog(@"Read from %@",fullPath);
        return data;
    } else {
        NSMutableArray *data = 开发者_JS百科[[NSMutableArray alloc] initWithContentsOfFile:fullPath];
        return data;
    }
}

-(void) dealloc {
    [super dealloc];
}

@end

and My functions in the appDelegate:

    -(void) saveApplicationData {
    [self.storageService saveArrayToFile : PLACES_FILE : self.places];
}

-(void) loadApplicationData {
    self.places = [self.storageService readArrayFromFile:PLACES_FILE];
}

Here is my class that holds constant to filename:

    #import <Foundation/Foundation.h>

extern NSString * const PLACES_FILE = @"Places.dat";

@interface ApplicationConstants : NSObject {

}

@end

So what is wrong?

Thank you guys.


What you want is to let Place conform to the NSCoding protocol, to allow for serialization to and from files (and in memory data if wanted)

Extend Place as (I have also changed the name of the init method as your name was against every naming practice iOS has):

@interface Place : NSObject <NSCoding> {
    NSString *name; 
    NSString *location; 
}

-(id)initWithName:(NSString *)name location:(NSString *)location;

@property (retain,nonatomic,readwrite) NSString *name; 
@property (retain,nonatomic,readwrite) NSString *location;

@end

Your implementation is quite simple but you also need to implement two methods defined by the NSCoding protocol:

@implementation Place

@synthesize name, location;

-(id)initWithName:(NSString *)aName location:(NSString *)aLocation {
    self = [super init];
    if (self) {
        self.name = aName;
        self.location = aLocation;
    }
    return self;
}

-(id)initWithWithCoder:(NSCoder)decoder {
    self = [super initWithCoder:decoder];
    if (self) {
       self.name = [decoder decodeObjectForKey:@"name"];
       self.location = [decoder decodeObjectForKey:@"location";
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder*)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeObject:self.location forKey:@"location"];
    [super encodeWithCoder:encoder];
}

@end

With this in place, saving the places array to disk is as easy as:

[NSKeyedArchiver archiveRootObject:places toFile:path];

And decoding just as easy:

places = [[KSKeyUnarchiver unarchiveObjectWithFile:path] retain];


To use writeToFile objects in array need to be plist capable type (NSDate, NSDate, NSString, NSArray, NSDictionary)

Implement NSCoding on the objects in array and use NSKeyedArchiver to serialize/deserialize. write:

[NSKeyedArchiver archiveRootObject:myArray toFile:self.places];

read:

[NSKeyedUnarchiver unarchiveObjectWithFile:path];

More info can be found here:

Persisting Custom Objects

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜