Add additional information to a UIImage

119 views Asked by At

I'm trying to add some information to a UIImage I am doing some experimentation with to add details like the number of UILabel's present on the screen and their frames.

I tried using setValue:forKeyPath: but this does not work since UIImage is not key-value compliant. What is an efficient way to do this?

Adding metadata using the CGImageMetadata API's seems to need me to convert the UIImage to NSData. Also, I would like to access the data without saving it every time. Can anyone point me to a good way to do this?

1

There are 1 answers

1
The Dreams Wind On BEST ANSWER

You can get use of associated objects to complement objects of classes source of which you don't have access to with some additional data (with use of objc_setAssociatedObject to set and objc_getAssociatedObject to read the data):

UIImage *image = [UIImage new];
NSString *extraData = @"extra info";

objc_setAssociatedObject(image, @"example", extraData, OBJC_ASSOCIATION_COPY_NONATOMIC);
NSLog(@"%@", objc_getAssociatedObject(image, @"example"));

For convenience it can be effectively wrapped with a property by extending the class with a category:

//  UIImage+TDWExtraData.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIImage (TDWExtraData)

@property (nonatomic, copy) NSString *tdw_extraData;

@end

NS_ASSUME_NONNULL_END
//  UIImage+TDWExtraData.m

#import "UIImage+TDWExtraData.h"
#import <objc/runtime.h>

static void const *const kExtraDataKey = &kExtraDataKey;

@implementation UIImage (TDWExtraData)

- (NSString *)tdw_extraData {
    return objc_getAssociatedObject(self, kExtraDataKey);
}

- (void)setTdw_extraData:(NSString *)data {
    objc_setAssociatedObject(self, kExtraDataKey, data, OBJC_ASSOCIATION_COPY_NONATOMIC);
}


@end

P.S. It's not correct to say that UIImage is not KVC compliant only because it doesn't support setValue:forKeyPath: for non-existing key paths. It's perfectly compliant for key-paths the class has defined:

UIImage *obj = [UIImage new];
NSLog(@"%@", [obj valueForKey:@"size"]); // prints size