1

I am working on an iOS App that involves saving and retrieving an NSMutableArray containing multiple instances of a single custom object I made. I have seen several guides such as Apple's Documentation

I get the gist of how to do it (I think), it seems I have to use archiving since my objects in the array are not primitive variables, therefore I have already made my objects NSCoding compliant. However I have also seen examples using NSDefaults or whatever that I don't understand (I have no file IO experience). After seeing all of this info, I am having a particularly hard time piecing everything together. What am looking for is a complete guide, from start to finish, of an example program that successfully uses archiving to save and retrieve custom objects (in an array or not). If someone could point out a good guide to me or make their own on this post, that would be GREATLY appreciated! Thanks everyone, Stack Overflow is an awesome place!

P.S. If more information is needed please tell me in the comments!

jscs
  • 63,694
  • 13
  • 151
  • 195
willbattel
  • 1,040
  • 1
  • 10
  • 37

1 Answers1

4

Make sure that any class you are trying to archive implements the NSCoding protocol, then do something like this:

@interface MyClass<NSCoding>

@property(strong,nonatomic) NSString *myProperty;

@end

@implementation MyClass
#define myPropertyKey @"myKey"
-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if( self != nil )
    {
        self.myProperty = [aDecoder decodeObjectForKey:myPropertyKey];
    }

    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:[self.myProperty copy] forKey:myPropertyKey];

}

@end

Then I use a class called FileUtils to do my archiving work:

@implementation FileUtils


+ (NSObject *)readArchiveFile:(NSString *)inFileName
{
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectoryPath, inFileName];


    NSObject *returnObject = nil;
    if( [fileMgr fileExistsAtPath:filePath] )
    {
        @try
        {
            returnObject = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        }
        @catch (NSException *exception)
        {
            returnObject = nil;
        }
    }

    return returnObject;

}

+ (void)archiveFile:(NSString *)inFileName inObject:(NSObject *)inObject
{
    NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectoryPath, inFileName];
    @try
    {
        BOOL didSucceed = [NSKeyedArchiver archiveRootObject:inObject toFile:filePath];
        if( !didSucceed )
        {
            NSLog(@"File %@ write operation %@", inFileName, didSucceed ? @"success" : @"error" );
        }
    }
    @catch (NSException *exception)
    {
        NSLog(@"File %@ write operation threw an exception:%@", filePath,     exception.reason);
    }

}

+ (void)deleteFile:(NSString *)inFileName
{
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectoryPath, inFileName];
    NSError *error;
    if ( [fileMgr fileExistsAtPath:filePath] && [fileMgr removeItemAtPath:filePath error:&error] != YES)
    {
        NSLog(@"Unable to delete file: %@", [error localizedDescription]);
    }
}


@end
JonahGabriel
  • 3,066
  • 2
  • 18
  • 28
  • What is FileUtils a subclass of then? Since I am assuming it is a standard Objective-c Class. – willbattel Sep 12 '13 at 22:53
  • FileUtils is just a utility class...notice all the methods are class methods. – JonahGabriel Sep 12 '13 at 22:56
  • Perfect, and when I use those methods what do I pass it for the NSString inFileName? And I assume the NSObject inObject is the object I want to archive correct? Thank you very much this is very helpful! – willbattel Sep 13 '13 at 01:49
  • Yes, inFilename is whatever you want to call the file and inObject is the file you want to archive. – JonahGabriel Sep 13 '13 at 03:29
  • This is a solid answer. I'd say for clarity purposes it would be helpful to rename the methods just a little bit. "inObject" kind of makes it sound like you're going to do something inside of that object. But the comments here clarify that of course. Nice job. – Brian Sachetta Jan 16 '15 at 16:32