Encode what cannot be NSCoded

Isn’t it annoying that UIImage can’t be serialized (as evident with the error “UIImage unrecognized encodeWithCoder”).  Really throws a spanner in the works when trying to serialise your UI (or applying this hack) given that images are everywhere…

Well this can easily be fixed with a monkey-patch, and a pretty safe one at that.

Here it is (just throw this in a “.m” file, and include it in your project):

@implementation UIImage (NSCoder)

- (id) initWithCoder:(NSCoder *)coder {

	self = [self initWithData:[coder decodeObjectForKey:@"PNGdata"]];

	return self;
}

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

	// if space is a concern, replace with UIImageJPEGRepresentation

	[encoder encodeObject:UIImagePNGRepresentation(self) forKey:@"PNGdata"];
}

@end

So there you go!  This hack was brought to you by the people behind GPS Log for iPhone (please check it out, it’s free to try!).

Why do I claim that this monkey-patch is safe?  Well it encodes and decodes your image. The method is doing what it is contracted to do.  *If* UIImage were to implement this method, then you would have issues, but *only* if you serialized with one implementation, and deserialized with another (which wouldn’t normally happen, and it’s a pretty big *if* anyway…).

Why is it a “monkey patch”?  Well you’re throwing your own code into UIImage implementing standard methods…  pretty much the text-book definition.

Be aware… serialising images to PNG format will consume a decent amount of memory and disk space, and can be slow, especially if those images are big.  So if you already have these images on disk somewhere else, then you probably should be loading them from disk rather than doing this (I have a feeling this is why Apple did not implement this method, to force people to load from disk).

So why is this method useful?  Well for one, you can use it to Copy what cannot be NSCopied :)

*name

*e-mail

web site

leave a comment