From 2307437825739e430729b8104c7bf75f9953766f Mon Sep 17 00:00:00 2001 From: Brandon Li Date: Tue, 22 Jun 2021 17:58:23 -0400 Subject: [PATCH 1/4] Add categories for alternative image types that can be decoded using registered custom decoders --- PINRemoteImage.xcodeproj/project.pbxproj | 8 ++++ .../Categories/PINImage+AlternativeTypes.h | 40 ++++++++++++++++ .../Categories/PINImage+AlternativeTypes.m | 46 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 Source/Classes/Categories/PINImage+AlternativeTypes.h create mode 100644 Source/Classes/Categories/PINImage+AlternativeTypes.m diff --git a/PINRemoteImage.xcodeproj/project.pbxproj b/PINRemoteImage.xcodeproj/project.pbxproj index cb0504c2..31cae2c9 100644 --- a/PINRemoteImage.xcodeproj/project.pbxproj +++ b/PINRemoteImage.xcodeproj/project.pbxproj @@ -96,6 +96,8 @@ 938E98DA2224775B00029E4D /* PINRemoteImageManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 939546BF2220AF84006031BB /* PINRemoteImageManagerConfiguration.m */; }; 939546C02220AF84006031BB /* PINRemoteImageManagerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 939546BE2220AF84006031BB /* PINRemoteImageManagerConfiguration.h */; }; 939546C12220AF84006031BB /* PINRemoteImageManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 939546BF2220AF84006031BB /* PINRemoteImageManagerConfiguration.m */; }; + 9A079DD826826EFD00F2E70A /* PINImage+AlternativeTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A079DD726826EFD00F2E70A /* PINImage+AlternativeTypes.m */; }; + 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */; }; 9DD47F9D1C699F4B00F12CA0 /* PINButton+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD47F991C699F4B00F12CA0 /* PINButton+PINRemoteImage.m */; }; 9DD47F9F1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD47F9B1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m */; }; 9DD47FA41C699FDC00F12CA0 /* PINImage+DecodedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DD47FA01C699FDC00F12CA0 /* PINImage+DecodedImage.h */; }; @@ -252,6 +254,8 @@ 926E015D1F0DFCAE00874D01 /* PINRequestRetryStrategy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PINRequestRetryStrategy.m; sourceTree = ""; }; 939546BE2220AF84006031BB /* PINRemoteImageManagerConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PINRemoteImageManagerConfiguration.h; sourceTree = ""; }; 939546BF2220AF84006031BB /* PINRemoteImageManagerConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PINRemoteImageManagerConfiguration.m; sourceTree = ""; }; + 9A079DD726826EFD00F2E70A /* PINImage+AlternativeTypes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "PINImage+AlternativeTypes.m"; sourceTree = ""; }; + 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PINImage+AlternativeTypes.h"; sourceTree = ""; }; 9DD47F991C699F4B00F12CA0 /* PINButton+PINRemoteImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PINButton+PINRemoteImage.m"; sourceTree = ""; }; 9DD47F9B1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PINImageView+PINRemoteImage.m"; sourceTree = ""; }; 9DD47FA01C699FDC00F12CA0 /* PINImage+DecodedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PINImage+DecodedImage.h"; sourceTree = ""; }; @@ -525,6 +529,8 @@ 686D48CE1ED38FC0003DB4C2 /* PINRemoteImageTask+Subclassing.h */, ACD28EAE81695DDF84BB76B8 /* NSHTTPURLResponse+MaxAge.m */, ACD28A0374E664CFF0BB3297 /* NSHTTPURLResponse+MaxAge.h */, + 9A079DD726826EFD00F2E70A /* PINImage+AlternativeTypes.m */, + 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */, ); path = Categories; sourceTree = ""; @@ -635,6 +641,7 @@ FBC820A22526277E007FD40D /* PINProgressiveImage.h in Headers */, 939546C02220AF84006031BB /* PINRemoteImageManagerConfiguration.h in Headers */, FBC820BA2526277E007FD40D /* PINButton+PINRemoteImage.h in Headers */, + 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */, FBC820B82526277E007FD40D /* PINRemoteImageMacros.h in Headers */, FBC820AE2526277E007FD40D /* PINGIFAnimatedImage.h in Headers */, FBC8209E2526277E007FD40D /* PINRemoteImageCategoryManager.h in Headers */, @@ -879,6 +886,7 @@ 9DD47F9D1C699F4B00F12CA0 /* PINButton+PINRemoteImage.m in Sources */, 6858C0761C9CC5BA00E420EB /* PINRemoteLock.m in Sources */, F1B919191BCF23C900710963 /* PINRemoteImageManagerResult.m in Sources */, + 9A079DD826826EFD00F2E70A /* PINImage+AlternativeTypes.m in Sources */, F1B9191D1BCF23C900710963 /* PINRemoteImageTask.m in Sources */, 68B1F2821E679D7A00ED87C4 /* PINRemoteImageDownloadQueue.m in Sources */, F1B919011BCF23C900710963 /* NSData+ImageDetectors.m in Sources */, diff --git a/Source/Classes/Categories/PINImage+AlternativeTypes.h b/Source/Classes/Categories/PINImage+AlternativeTypes.h new file mode 100644 index 00000000..1c94b997 --- /dev/null +++ b/Source/Classes/Categories/PINImage+AlternativeTypes.h @@ -0,0 +1,40 @@ +// +// PINImage+AlternativeTypes.h +// PINRemoteImage +// +// Created by Brandon Li on 6/22/21. +// + +#import + +#import "PINRemoteImageMacros.h" + +#if PIN_TARGET_IOS +#import +#elif PIN_TARGET_MAC +#import +#endif + +// A decoder that knows how to convert image data into a PINImage. +@protocol PINImageCustomDecoder + +- (PINImage *)imageFromData:(NSData *)imageData targetSize:(CGSize)size; + +- (BOOL)canRender:(NSData *)imageData; + +@end + +@interface PINImage (AlternativeTypes) + +// The encoded / compressed form of the image data. The data will only be used +// at least one custom decoder that recognizes this data is registered using +// pin_registerCustomDecoder below. +@property(nonatomic, nullable) NSData *pin_encodedImageData; + +// Returns an image of the target size. +- (nullable PINImage *)pin_decodedImageUsingCustomDecodersWithSize:(CGSize)size; + +// Registers a custom image decoder type. ++ (void)pin_registerCustomDecoder:(id)customDecoder; + +@end diff --git a/Source/Classes/Categories/PINImage+AlternativeTypes.m b/Source/Classes/Categories/PINImage+AlternativeTypes.m new file mode 100644 index 00000000..d51238df --- /dev/null +++ b/Source/Classes/Categories/PINImage+AlternativeTypes.m @@ -0,0 +1,46 @@ +// +// PINImage+AlternativeTypes.m +// PINRemoteImage +// +// Created by Brandon Li on 6/22/21. +// + +#import "PINImage+AlternativeTypes.h" + +#import + +@implementation PINImage (AlternativeTypes) + ++ (void)pin_registerCustomDecoder:(id)customDecoder { + NSMutableArray> *decoders = [PINImage pin_decoders]; + [decoders addObject:customDecoder]; + objc_setAssociatedObject(self, @selector(pin_registerCustomDecoder:), decoders, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + +} + +- (nullable NSData *)pin_encodedImageData { + return (NSData *)objc_getAssociatedObject(self, @selector(pin_encodedImageData)); +} + +- (void)setPin_encodedImageData:(NSData *)data { + objc_setAssociatedObject(self, @selector(pin_encodedImageData), data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (nullable PINImage *)pin_decodedImageUsingCustomDecodersWithSize:(CGSize)size { + NSMutableArray> *decoders = [PINImage pin_decoders]; + for (id decoder in decoders) { + if ([decoder canRender:self.pin_encodedImageData]) { + return [decoder imageFromData:self.pin_encodedImageData targetSize:size]; + } + } + + return nil; +} + +#pragma mark - Private + ++ (NSMutableArray> *)pin_decoders { + return objc_getAssociatedObject(self, @selector(pin_registerCustomDecoder:)) ?: [NSMutableArray array]; +} + +@end From 8267817baeb954303e7c3b76e722c544b84670d5 Mon Sep 17 00:00:00 2001 From: Brandon Li Date: Tue, 22 Jun 2021 17:58:23 -0400 Subject: [PATCH 2/4] Add categories for alternative image types that can be decoded using registered custom decoders --- PINRemoteImage.xcodeproj/project.pbxproj | 8 ++++ .../Categories/PINImage+AlternativeTypes.h | 40 ++++++++++++++++ .../Categories/PINImage+AlternativeTypes.m | 46 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 Source/Classes/Categories/PINImage+AlternativeTypes.h create mode 100644 Source/Classes/Categories/PINImage+AlternativeTypes.m diff --git a/PINRemoteImage.xcodeproj/project.pbxproj b/PINRemoteImage.xcodeproj/project.pbxproj index cb0504c2..4ca96d72 100644 --- a/PINRemoteImage.xcodeproj/project.pbxproj +++ b/PINRemoteImage.xcodeproj/project.pbxproj @@ -96,6 +96,8 @@ 938E98DA2224775B00029E4D /* PINRemoteImageManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 939546BF2220AF84006031BB /* PINRemoteImageManagerConfiguration.m */; }; 939546C02220AF84006031BB /* PINRemoteImageManagerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 939546BE2220AF84006031BB /* PINRemoteImageManagerConfiguration.h */; }; 939546C12220AF84006031BB /* PINRemoteImageManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 939546BF2220AF84006031BB /* PINRemoteImageManagerConfiguration.m */; }; + 9A079DD826826EFD00F2E70A /* PINImage+AlternativeTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A079DD726826EFD00F2E70A /* PINImage+AlternativeTypes.m */; }; + 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DD47F9D1C699F4B00F12CA0 /* PINButton+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD47F991C699F4B00F12CA0 /* PINButton+PINRemoteImage.m */; }; 9DD47F9F1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD47F9B1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m */; }; 9DD47FA41C699FDC00F12CA0 /* PINImage+DecodedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DD47FA01C699FDC00F12CA0 /* PINImage+DecodedImage.h */; }; @@ -252,6 +254,8 @@ 926E015D1F0DFCAE00874D01 /* PINRequestRetryStrategy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PINRequestRetryStrategy.m; sourceTree = ""; }; 939546BE2220AF84006031BB /* PINRemoteImageManagerConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PINRemoteImageManagerConfiguration.h; sourceTree = ""; }; 939546BF2220AF84006031BB /* PINRemoteImageManagerConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PINRemoteImageManagerConfiguration.m; sourceTree = ""; }; + 9A079DD726826EFD00F2E70A /* PINImage+AlternativeTypes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "PINImage+AlternativeTypes.m"; sourceTree = ""; }; + 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PINImage+AlternativeTypes.h"; sourceTree = ""; }; 9DD47F991C699F4B00F12CA0 /* PINButton+PINRemoteImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PINButton+PINRemoteImage.m"; sourceTree = ""; }; 9DD47F9B1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PINImageView+PINRemoteImage.m"; sourceTree = ""; }; 9DD47FA01C699FDC00F12CA0 /* PINImage+DecodedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PINImage+DecodedImage.h"; sourceTree = ""; }; @@ -525,6 +529,8 @@ 686D48CE1ED38FC0003DB4C2 /* PINRemoteImageTask+Subclassing.h */, ACD28EAE81695DDF84BB76B8 /* NSHTTPURLResponse+MaxAge.m */, ACD28A0374E664CFF0BB3297 /* NSHTTPURLResponse+MaxAge.h */, + 9A079DD726826EFD00F2E70A /* PINImage+AlternativeTypes.m */, + 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */, ); path = Categories; sourceTree = ""; @@ -633,6 +639,7 @@ FBC820B22526277E007FD40D /* PINRemoteImageManager.h in Headers */, FBC820A62526277E007FD40D /* PINAnimatedImageView+PINRemoteImage.h in Headers */, FBC820A22526277E007FD40D /* PINProgressiveImage.h in Headers */, + 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */, 939546C02220AF84006031BB /* PINRemoteImageManagerConfiguration.h in Headers */, FBC820BA2526277E007FD40D /* PINButton+PINRemoteImage.h in Headers */, FBC820B82526277E007FD40D /* PINRemoteImageMacros.h in Headers */, @@ -879,6 +886,7 @@ 9DD47F9D1C699F4B00F12CA0 /* PINButton+PINRemoteImage.m in Sources */, 6858C0761C9CC5BA00E420EB /* PINRemoteLock.m in Sources */, F1B919191BCF23C900710963 /* PINRemoteImageManagerResult.m in Sources */, + 9A079DD826826EFD00F2E70A /* PINImage+AlternativeTypes.m in Sources */, F1B9191D1BCF23C900710963 /* PINRemoteImageTask.m in Sources */, 68B1F2821E679D7A00ED87C4 /* PINRemoteImageDownloadQueue.m in Sources */, F1B919011BCF23C900710963 /* NSData+ImageDetectors.m in Sources */, diff --git a/Source/Classes/Categories/PINImage+AlternativeTypes.h b/Source/Classes/Categories/PINImage+AlternativeTypes.h new file mode 100644 index 00000000..1c94b997 --- /dev/null +++ b/Source/Classes/Categories/PINImage+AlternativeTypes.h @@ -0,0 +1,40 @@ +// +// PINImage+AlternativeTypes.h +// PINRemoteImage +// +// Created by Brandon Li on 6/22/21. +// + +#import + +#import "PINRemoteImageMacros.h" + +#if PIN_TARGET_IOS +#import +#elif PIN_TARGET_MAC +#import +#endif + +// A decoder that knows how to convert image data into a PINImage. +@protocol PINImageCustomDecoder + +- (PINImage *)imageFromData:(NSData *)imageData targetSize:(CGSize)size; + +- (BOOL)canRender:(NSData *)imageData; + +@end + +@interface PINImage (AlternativeTypes) + +// The encoded / compressed form of the image data. The data will only be used +// at least one custom decoder that recognizes this data is registered using +// pin_registerCustomDecoder below. +@property(nonatomic, nullable) NSData *pin_encodedImageData; + +// Returns an image of the target size. +- (nullable PINImage *)pin_decodedImageUsingCustomDecodersWithSize:(CGSize)size; + +// Registers a custom image decoder type. ++ (void)pin_registerCustomDecoder:(id)customDecoder; + +@end diff --git a/Source/Classes/Categories/PINImage+AlternativeTypes.m b/Source/Classes/Categories/PINImage+AlternativeTypes.m new file mode 100644 index 00000000..d51238df --- /dev/null +++ b/Source/Classes/Categories/PINImage+AlternativeTypes.m @@ -0,0 +1,46 @@ +// +// PINImage+AlternativeTypes.m +// PINRemoteImage +// +// Created by Brandon Li on 6/22/21. +// + +#import "PINImage+AlternativeTypes.h" + +#import + +@implementation PINImage (AlternativeTypes) + ++ (void)pin_registerCustomDecoder:(id)customDecoder { + NSMutableArray> *decoders = [PINImage pin_decoders]; + [decoders addObject:customDecoder]; + objc_setAssociatedObject(self, @selector(pin_registerCustomDecoder:), decoders, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + +} + +- (nullable NSData *)pin_encodedImageData { + return (NSData *)objc_getAssociatedObject(self, @selector(pin_encodedImageData)); +} + +- (void)setPin_encodedImageData:(NSData *)data { + objc_setAssociatedObject(self, @selector(pin_encodedImageData), data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (nullable PINImage *)pin_decodedImageUsingCustomDecodersWithSize:(CGSize)size { + NSMutableArray> *decoders = [PINImage pin_decoders]; + for (id decoder in decoders) { + if ([decoder canRender:self.pin_encodedImageData]) { + return [decoder imageFromData:self.pin_encodedImageData targetSize:size]; + } + } + + return nil; +} + +#pragma mark - Private + ++ (NSMutableArray> *)pin_decoders { + return objc_getAssociatedObject(self, @selector(pin_registerCustomDecoder:)) ?: [NSMutableArray array]; +} + +@end From 7b7274272bb64a27b398b3db32134a549054dc02 Mon Sep 17 00:00:00 2001 From: Brandon Li Date: Thu, 29 Jul 2021 10:00:34 -0400 Subject: [PATCH 3/4] Remove registry of custom decoders from PINRemoteImage, instead allowing a single supplied custom decoder to be assigned --- PINRemoteImage.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PINRemoteImage.xcodeproj/project.pbxproj b/PINRemoteImage.xcodeproj/project.pbxproj index 31cae2c9..4ca96d72 100644 --- a/PINRemoteImage.xcodeproj/project.pbxproj +++ b/PINRemoteImage.xcodeproj/project.pbxproj @@ -97,7 +97,7 @@ 939546C02220AF84006031BB /* PINRemoteImageManagerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 939546BE2220AF84006031BB /* PINRemoteImageManagerConfiguration.h */; }; 939546C12220AF84006031BB /* PINRemoteImageManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 939546BF2220AF84006031BB /* PINRemoteImageManagerConfiguration.m */; }; 9A079DD826826EFD00F2E70A /* PINImage+AlternativeTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A079DD726826EFD00F2E70A /* PINImage+AlternativeTypes.m */; }; - 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */; }; + 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A079DDB26826F0E00F2E70A /* PINImage+AlternativeTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DD47F9D1C699F4B00F12CA0 /* PINButton+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD47F991C699F4B00F12CA0 /* PINButton+PINRemoteImage.m */; }; 9DD47F9F1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD47F9B1C699F4B00F12CA0 /* PINImageView+PINRemoteImage.m */; }; 9DD47FA41C699FDC00F12CA0 /* PINImage+DecodedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DD47FA01C699FDC00F12CA0 /* PINImage+DecodedImage.h */; }; @@ -639,9 +639,9 @@ FBC820B22526277E007FD40D /* PINRemoteImageManager.h in Headers */, FBC820A62526277E007FD40D /* PINAnimatedImageView+PINRemoteImage.h in Headers */, FBC820A22526277E007FD40D /* PINProgressiveImage.h in Headers */, + 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */, 939546C02220AF84006031BB /* PINRemoteImageManagerConfiguration.h in Headers */, FBC820BA2526277E007FD40D /* PINButton+PINRemoteImage.h in Headers */, - 9A079DE1268270F900F2E70A /* PINImage+AlternativeTypes.h in Headers */, FBC820B82526277E007FD40D /* PINRemoteImageMacros.h in Headers */, FBC820AE2526277E007FD40D /* PINGIFAnimatedImage.h in Headers */, FBC8209E2526277E007FD40D /* PINRemoteImageCategoryManager.h in Headers */, From cce8bf1b6f6b93cf06da3299f28ff94693a66083 Mon Sep 17 00:00:00 2001 From: Brandon Li Date: Thu, 29 Jul 2021 10:03:35 -0400 Subject: [PATCH 4/4] Add missing files --- .../Categories/PINImage+AlternativeTypes.h | 19 ++++++------ .../Categories/PINImage+AlternativeTypes.m | 31 +++++++------------ 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/Source/Classes/Categories/PINImage+AlternativeTypes.h b/Source/Classes/Categories/PINImage+AlternativeTypes.h index 1c94b997..6ec02167 100644 --- a/Source/Classes/Categories/PINImage+AlternativeTypes.h +++ b/Source/Classes/Categories/PINImage+AlternativeTypes.h @@ -18,23 +18,24 @@ // A decoder that knows how to convert image data into a PINImage. @protocol PINImageCustomDecoder -- (PINImage *)imageFromData:(NSData *)imageData targetSize:(CGSize)size; +// Decodes the given image data into a PINImage of the target size. +- (nullable PINImage *)imageFromData:(nonnull NSData *)imageData targetSize:(CGSize)size; -- (BOOL)canRender:(NSData *)imageData; +// Whether this decoder can handle the given image data. +- (BOOL)canRender:(nonnull NSData *)imageData; @end @interface PINImage (AlternativeTypes) -// The encoded / compressed form of the image data. The data will only be used -// at least one custom decoder that recognizes this data is registered using -// pin_registerCustomDecoder below. +// The encoded / compressed form of the image data. Intended to be decoded by +// @c pin_encodedImageDataCustomDecoder. @property(nonatomic, nullable) NSData *pin_encodedImageData; -// Returns an image of the target size. -- (nullable PINImage *)pin_decodedImageUsingCustomDecodersWithSize:(CGSize)size; +// The selected custom decoder to use for the @c pin_encodedImageData. +@property(nonatomic, nullable) id pin_encodedImageDataCustomDecoder; -// Registers a custom image decoder type. -+ (void)pin_registerCustomDecoder:(id)customDecoder; +// Returns an image of the target size. +- (nullable PINImage *)pin_decodedImageUsingCustomDecoderWithSize:(CGSize)size; @end diff --git a/Source/Classes/Categories/PINImage+AlternativeTypes.m b/Source/Classes/Categories/PINImage+AlternativeTypes.m index d51238df..2fed8533 100644 --- a/Source/Classes/Categories/PINImage+AlternativeTypes.m +++ b/Source/Classes/Categories/PINImage+AlternativeTypes.m @@ -11,36 +11,27 @@ @implementation PINImage (AlternativeTypes) -+ (void)pin_registerCustomDecoder:(id)customDecoder { - NSMutableArray> *decoders = [PINImage pin_decoders]; - [decoders addObject:customDecoder]; - objc_setAssociatedObject(self, @selector(pin_registerCustomDecoder:), decoders, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - -} - - (nullable NSData *)pin_encodedImageData { return (NSData *)objc_getAssociatedObject(self, @selector(pin_encodedImageData)); } - (void)setPin_encodedImageData:(NSData *)data { - objc_setAssociatedObject(self, @selector(pin_encodedImageData), data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(self, @selector(pin_encodedImageData), data, OBJC_ASSOCIATION_RETAIN); } -- (nullable PINImage *)pin_decodedImageUsingCustomDecodersWithSize:(CGSize)size { - NSMutableArray> *decoders = [PINImage pin_decoders]; - for (id decoder in decoders) { - if ([decoder canRender:self.pin_encodedImageData]) { - return [decoder imageFromData:self.pin_encodedImageData targetSize:size]; - } - } - - return nil; +- (nullable id)pin_encodedImageDataCustomDecoder { + return (id)objc_getAssociatedObject( + self, @selector(pin_encodedImageDataCustomDecoder)); } -#pragma mark - Private +- (void)setPin_encodedImageDataCustomDecoder:(id)customDecoder { + objc_setAssociatedObject(self, @selector(pin_encodedImageDataCustomDecoder), customDecoder, + OBJC_ASSOCIATION_RETAIN); +} -+ (NSMutableArray> *)pin_decoders { - return objc_getAssociatedObject(self, @selector(pin_registerCustomDecoder:)) ?: [NSMutableArray array]; +- (nullable PINImage *)pin_decodedImageUsingCustomDecoderWithSize:(CGSize)size { + return [self.pin_encodedImageDataCustomDecoder imageFromData:self.pin_encodedImageData + targetSize:size]; } @end