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?
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