Проблема с сохранением файла в Documents NSMutableArray с NSObjects - PullRequest
2 голосов
/ 12 августа 2011

Я новичок в разработке для iOS.Я написал небольшое приложение, которое сохраняет массив NSMutableArray с моими объектами, полученными из NSObject.Приложение выполняет сохранение, но файл не создается в каталоге документов и приложение не может прочитать.эта проблема есть и на симуляторе, и на моем iPhone 3gs 4.2.1

My NSMutableArray определение в классе appDelegate:

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

Мой класс NSObject:

 #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

Мой класс библиотеки StorageService:

 #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 = [[NSMutableArray alloc] initWithContentsOfFile:fullPath];
        return data;
    }
}

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

@end

и Мои функции в appDelegate:

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

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

Вот мой класс, который содержит константу имени файла:

    #import <Foundation/Foundation.h>

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

@interface ApplicationConstants : NSObject {

}

@end

Так что не так?

Спасибо, ребята.

Ответы [ 2 ]

2 голосов
/ 12 августа 2011

Вы хотите, чтобы Place соответствовал протоколу NSCoding, чтобы разрешить сериализацию в и из файлов (и в данные памяти, если требуется)

Расширить Place как (я также изменил название метода init, так как ваше имя было против любой практики именования, которую имеет iOS) :

@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

Ваша реализация довольно проста, но вам также нужно реализовать два метода, определенных протоколом NSCoding:

@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

Имея это, сохранить массив places на диск так же просто, как:

[NSKeyedArchiver archiveRootObject:places toFile:path];

И декодирование так же просто:

places = [[KSKeyUnarchiver unarchiveObjectWithFile:path] retain];
2 голосов
/ 12 августа 2011

Для использования объектов writeToFile в массиве должен быть тип с поддержкой plist (NSDate, NSDate, NSString, NSArray, NSDictionary)

Реализация NSCoding для объектов в массиве и использование NSKeyedArchiver для сериализации / десериализации. написать:

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

следующим образом:

[NSKeyedUnarchiver unarchiveObjectWithFile:path];

Более подробную информацию можно найти здесь:

Сохранение пользовательских объектов

...