In initWithCoder: what are the keys in the NSCoder (a UINibDecoder)? (for UIImageView)

Go To


Specifically, I'm trying to find the image path. This would be a super useful thing to be able to get, and as far as I've found nobody knows how. I've looked at the generated nib file for keys, and I'm able to see the image URL in there (test.jpg) but can't find the key to get it. The key "UIImage" returns the actual already constructed image (constructed via initWithCGImageStored:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientation and a mysterious UIKit function call GetImageAtPath which calls the mentioned init call), so that's not helpful.

I've also tried writing the UIImageView to disk with a NSKeyedArchiver and none of those values seem correct either, nor does the test.jpg value exist there.

If nobody can figure this out - anyone know how to read in a binary file as text? I could just read through the nib and parse out URLs, which is better than nothing, but NSString's constructors fail regardless of what format I try.

2012-04-04 17:58
by Eli


Have you tried to implement a category on NSKeyedUnarchiver and catch the keys that way? Quick implementation and investigation and you will find that the key is "UIResourceName". However bear in mind that the keyed unarchiver returns you only the objects for key within the current decoding scope. This means that you cannot query for this key from the root and you have to dig deep into the object hierarchy.

Below is a code which logs any linked resources. It is up to you how do you use it. It also logs when a UIImage is decoded. You can return your own class here if you want.

@interface NSKeyedUnarchiver (MyKeyedUnarchiver)

@implementation NSKeyedUnarchiver (MyKeyedUnarchiver)

- (id) mydecodeObjectForKey:(NSString *)key
    id obj = [self mydecodeObjectForKey:key];
    if ( [key isEqualToString:@"UIResourceName"] )
        NSLog(@"The linked resource name is: %@", obj);
    return obj;

- (Class) myclassForClassName:(NSString *)codedName
    if ( [codedName isEqualToString:@"UIImageNibPlaceholder"] )
        NSLog(@"Decoding a UIImage");
    return [self myclassForClassName:codedName];

+ (void) load
    SEL origM = @selector( decodeObjectForKey: );
    SEL newM = @selector( mydecodeObjectForKey: );
    method_exchangeImplementations( class_getInstanceMethod( self, origM ), class_getInstanceMethod( self, newM ) );

    origM = @selector( classForClassName: );
    newM = @selector( myclassForClassName: );
    method_exchangeImplementations( class_getInstanceMethod( self, origM ), class_getInstanceMethod( self, newM ) );


Hope this helps.

2013-10-28 10:04
by Szabi Tolnai