0

I loaded an image using frames downloaded from a web server.

NSArray* frames = [self fetchFramesFromServer];
imageView.image = [UIImage animatedImageWithImages:frames duration:1.0];

Whenever I try to archive these frames, the encoding function returns NO:

BOOL success = [NSKeyedArchiver archiveRootObject:(frames) toFile:archivePath];

Whenever I try to archive the image, the encoding function also returns NO:

BOOL success = [NSKeyedArchiver archiveRootObject:(imageView.image) toFile:archivePath];

Is this even possible, or am I missing some caveat of archiveRootObject that requires the UIImage to be loaded from the bundle, in png-format, or non-animated?

Just FYI, the archivePath when printed out in the debugger is

NSPathStore2 * @"/var/mobile/Containers/Data/Application/E475E3C1-4E3F-43D6-AD66-0F98320CF279/Library/Private Documents/assets/a/b/c.archive"   0x000000012c555a60

UPDATE:

I am storing the individual frames of the animation inside a for-loop, but I get the following:

+ (void) saveImage:(UIImage*)inputImage
    withSuffix:(NSString*)fileSuffix
{
if (inputImage == nil) {
    NSLog(@"ERROR: input image is nil!");
    return;
}

// strip away intermediate folders to avoid over-nesting
// ex: __F1/MF/FR/1_MF_FR_Animation_a1.png
// ===> 1_MF_FR_Animation_a1.png
NSString* suffixStub = [MyDatabase stubOfFilepath:fileSuffix];

NSURL* url = [MyDatabase folderURL];
NSURL* imageURL = [url URLByAppendingPathComponent:suffixStub];

NSData* pngData = UIImagePNGRepresentation(inputImage);
[NSKeyedArchiver archiveRootObject:pngData toFile:imageURL.path];
pngData = nil;

NSLog(@"Image %@ successfully saved!", fileSuffix);
} 

But on the NSKeyedArchiver line, I get "malloc: *** error for object 0x178202340: Freeing unallocated pointer"

Erika Electra
  • 1,854
  • 3
  • 20
  • 31
  • 1
    Do not archive images. Store the images on disk and archive their names. – matt Feb 08 '16 at 02:41
  • So in my example, if I got my image through AFNetworking, which already writes the file to the documents folder [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"/imageName.png"]; then you'd recommend archiving the NSString filePath and then after unarchiving the file name, reading from that location with [NSData dataWithContentsOfURL:unarchivedPath]? – Erika Electra Feb 09 '16 at 01:52
  • Just FYI, I also found out that my example was not working because archivePath contained a bunch of nested folders. If I just append to the documents URL once, it works... – Erika Electra Feb 09 '16 at 01:52
  • Actually, why even archive the names? If I can generate the path from the name of the image I want, I can just archive an NSNumber boolean @0 or @1 to tell if the image has been downloaded or not.... right? – Erika Electra Feb 09 '16 at 19:35

1 Answers1

0

First convert your image to NSData and then try archiving it

NSData* data = UIImagePNGRepresentation(imageView.image);
BOOL success = [NSKeyedArchiver archiveRootObject:data toFile:archivePath];

In case of NSArray, archiving is possible only if all the objects of array conforms to NSCoding protocol. If your array has custom object refer Custom object archiving on how to conform to NSCoding.

UPDATE

If objects of your array are frames of type CGRect the you can use NSStringFromCGRect() and CGRectFromString() to store and then retrieve them.

Vishnu gondlekar
  • 3,896
  • 21
  • 35
  • I did this for every frame, inside a for-loop: + (void) saveImage:(UIImage*)inputImage withSuffix:(NSString*)fileSuffix; { // strip away intermediate folders to avoid over-nesting NSString* suffixStub = [MyDatabase stubOfFilepath:fileSuffix]; NSURL* url = [MyDatabase folderURL]; NSURL* imageURL = [url URLByAppendingPathComponent:suffixStub]; NSData* pngData = UIImagePNGRepresentation(inputImage); [NSKeyedArchiver archiveRootObject:pngData toFile:imageURL.path]; } But malloc: *** error for object 0x178202340: Freeing unallocated pointer – Erika Electra Dec 07 '16 at 21:21