Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 700
Eli Avatar asked Apr 04 '12 17:04

Eli


1 Answers

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)
@end

@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 ) );
}

@end

Hope this helps.

like image 63
Szabi Tolnai Avatar answered Oct 15 '22 05:10

Szabi Tolnai