0

EDIT: Have checked and rechecked file paths, code for archiving and unarchiving and no bugs found. Is there an issue with App File System between launches that I am not aware of?

I am using NSCoder to store images in my app. I create a unique file path, store that file path to Core Data, and archive an image using that same file path in the documents.

On the app's first launch, everything works as expected - the file paths saved in Core Data are used to unarchive the images stored in Documents. On subsequent launches, however, the unarchiver returns nil, and I get a crash.

ImageForArchiving.m - the object that is to be saved with init and encode methods

   + (ImageForArchiving *)createImageWithImage:(NSData*)data andDate:(NSDate*)date {

    ImageForArchiving *archiveImage = [[ImageForArchiving alloc] init];

    [archiveImage setDate:date];
    [archiveImage setImageData:data];

    return archiveImage;
}

- (id) initWithCoder: (NSCoder *)coder
{
    if (self = [super init])
    {
        [self setDate: [coder decodeObjectForKey:@"date"]];
        [self setImageData: [coder decodeObjectForKey:@"image"]];

    }
    return self;
}

- (void) encodeWithCoder: (NSCoder *)coder
{

    [coder encodeObject:self.date forKey:@"date"];
    [coder encodeObject:self.imageData forKey:@"image"];

}

Saving to archive, Core Data, creation of file path and unarchiving code

 - (void)saveItemsAtFilePath:(NSString*)filePath andImageToArchive:(ImageForArchiving*)imageRecord {

    [NSKeyedArchiver archiveRootObject:imageRecord toFile:filePath];
}

- (void)loadItemsWithFilePath:(NSString*)filePath {


    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        ImageForArchiving *image = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        NSLog(@"image %@", image.date);
    } else {
        NSLog(@"nothing saved");
    }
}

-(void)saveToCoreDataWithFilePath:(NSString*)filePath{

    AppDelegate *delegate = [UIApplication sharedApplication].delegate;
    NSManagedObjectContext *context = delegate.managedObjectContext;
    NSManagedObject *photoAndDate = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:context];
    [photoAndDate setValue:[NSDate date] forKey:@"date"];
     [photoAndDate setValue:filePath forKey:@"image"];
    NSError *error = nil;
    if (![context save:&error]) {
        NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
    }

}

- (NSString *)createPathForDataFile
{
    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];

    documentsPath = [documentsPath stringByExpandingTildeInPath];
    NSError *error = nil;
    if ([fileManager fileExistsAtPath: documentsPath] == NO)
    {
        [fileManager createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:&error];
    }
    NSString *stringForSaving = [[NSUUID UUID]UUIDString];
    NSString *filePath = [documentsPath stringByAppendingPathComponent:stringForSaving];
    return filePath;
}

Looping through Core Data array to load up data source. The addition of the unarchived object is w

noobsmcgoobs
  • 2,716
  • 5
  • 32
  • 52
  • You don't show how all these different methods are called... – Wain Sep 12 '15 at 10:46
  • Are the self.array object has right array strings??? – Jason Nam Sep 13 '15 at 01:26
  • The file path string looks like this. Don't know if this is what it's supposed to look like /var/mobile/Containers/Data/Application/76C19807-8080-4F21-8AD8-3497DCC81600/Documents/DEEB9DAE-8BC5-47AD-B062-E49D438ADE9F – noobsmcgoobs Sep 13 '15 at 06:14

2 Answers2

0

I was encountered the same problem before. You write a image to a path and save it to the core data. Later read the image path, it is exactly same but no image is loaded.

So, Did you tested the app in the simulator? I don't know if it is intended or a kind of a bug but it would be working as you wanted on the real devices.

So try to run your app in the real devices and see if it works.

Jason Nam
  • 2,011
  • 2
  • 13
  • 22
  • Real device and it doesn't work. That's why I wanted to see if it was a problem with my code. Did you see any problems with my code? – noobsmcgoobs Sep 12 '15 at 21:59
0

I just found out that in iOS 8 the file paths are reset after each app launch. The code above save the file name to Core Data and re-create the file path to Documents when calling for the file.

For instance, the below would create the file name.

- (NSString *)createPathForDataFile
{

    NSString *stringForSaving = [[NSUUID UUID]UUIDString];

    NSLog(@"filePath in CreatePathForDataFile %@", stringForSaving);

    return stringForSaving;
}

Saving would occur by calling the path to the Documents folder and passing in the file name as the parameter filePath.

- (void)saveItemsAtFilePath:(NSString*)filePath andImageToArchive:(ImageForArchiving*)imageRecord {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsPath = [paths objectAtIndex:0];

    NSString *finalFilePath = [documentsPath stringByAppendingPathComponent:filePath];

    [NSKeyedArchiver archiveRootObject:imageRecord toFile:finalFilePath];
}
noobsmcgoobs
  • 2,716
  • 5
  • 32
  • 52