Skip to content

Commit 300c668

Browse files
authored
Merge pull request #28 from SDWebImage/demo/upgrade
Enhance PhotosKit error handling case and update demo
2 parents 6246c1a + a87eb2c commit 300c668

File tree

9 files changed

+69
-13
lines changed

9 files changed

+69
-13
lines changed

Example/SDWebImagePhotosPlugin.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@
653653
GCC_C_LANGUAGE_STANDARD = gnu11;
654654
INFOPLIST_FILE = "SDWebImagePhotosPlugin_Example macOS/Info.plist";
655655
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
656-
MACOSX_DEPLOYMENT_TARGET = 10.13;
656+
MACOSX_DEPLOYMENT_TARGET = 10.15;
657657
MTL_ENABLE_DEBUG_INFO = YES;
658658
PRODUCT_BUNDLE_IDENTIFIER = "com.dreampiggy.SDWebImagePhotosPlugin-Example-macOS";
659659
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -683,7 +683,7 @@
683683
GCC_C_LANGUAGE_STANDARD = gnu11;
684684
INFOPLIST_FILE = "SDWebImagePhotosPlugin_Example macOS/Info.plist";
685685
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
686-
MACOSX_DEPLOYMENT_TARGET = 10.13;
686+
MACOSX_DEPLOYMENT_TARGET = 10.15;
687687
MTL_ENABLE_DEBUG_INFO = NO;
688688
PRODUCT_BUNDLE_IDENTIFIER = "com.dreampiggy.SDWebImagePhotosPlugin-Example-macOS";
689689
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -737,7 +737,7 @@
737737
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
738738
GCC_WARN_UNUSED_FUNCTION = YES;
739739
GCC_WARN_UNUSED_VARIABLE = YES;
740-
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
740+
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
741741
ONLY_ACTIVE_ARCH = YES;
742742
SDKROOT = iphoneos;
743743
TARGETED_DEVICE_FAMILY = "1,2";
@@ -783,7 +783,7 @@
783783
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
784784
GCC_WARN_UNUSED_FUNCTION = YES;
785785
GCC_WARN_UNUSED_VARIABLE = YES;
786-
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
786+
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
787787
SDKROOT = iphoneos;
788788
TARGETED_DEVICE_FAMILY = "1,2";
789789
VALIDATE_PRODUCT = YES;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>PreviewsEnabled</key>
6+
<false/>
7+
</dict>
8+
</plist>

Example/SDWebImagePhotosPlugin/MasterViewController.m

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,22 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
125125
}
126126

127127
cell.customTextLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row];
128+
SDWebImageMutableContext *context = [@{SDWebImageContextStoreCacheType : @(SDImageCacheTypeNone)} mutableCopy];
129+
BOOL supportsHDR = NO;
130+
if (@available(iOS 16.0, *)) {
131+
supportsHDR = UIScreen.mainScreen.potentialEDRHeadroom > 1.0;
132+
}
133+
if (supportsHDR) {
134+
if (@available(iOS 17.0, *)) {
135+
cell.customImageView.preferredImageDynamicRange = UIImageDynamicRangeHigh; // Enable Image View Level control for HDR
136+
}
137+
context[SDWebImageContextPhotosRequestImageData] = @(YES); // Photos Library only load HDR info when requestImageData
138+
context[SDWebImageContextImageDecodeToHDR] = @(YES); // When decoding HDR data, we need explicit enable HDR decoding
139+
}
128140
[cell.customImageView sd_setImageWithURL:self.objects[indexPath.row]
129141
placeholderImage:placeholderImage
130142
options:SDWebImageFromLoaderOnly
131-
context:@{SDWebImageContextStoreCacheType : @(SDImageCacheTypeNone)}]; // Disable memory cache query/store
143+
context:context]; // Disable memory cache query/store
132144
return cell;
133145
}
134146

Example/SDWebImagePhotosPlugin/SDAppDelegate.m

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#import "SDAppDelegate.h"
1010
#import "MasterViewController.h"
11+
#import <SDWebImage/SDWebImage.h>
1112

1213
@implementation SDAppDelegate
1314

@@ -17,9 +18,14 @@ @implementation SDAppDelegate
1718
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
1819
{
1920
// Override point for customization after application launch.
21+
if (@available(iOS 14.0, *)) {
22+
[SDImageCodersManager.sharedManager addCoder:SDImageAWebPCoder.sharedCoder];
23+
}
24+
if (@available(iOS 13.0, *)) {
25+
[SDImageCodersManager.sharedManager addCoder:SDImageHEICCoder.sharedCoder];
26+
}
2027

2128
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
22-
// Override point for customization after application launch.
2329

2430
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
2531
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];

Example/SDWebImagePhotosPlugin_Example macOS/AppDelegate.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "AppDelegate.h"
10+
#import <SDWebImage/SDWebImage.h>
1011

1112
@interface AppDelegate ()
1213

@@ -16,6 +17,10 @@ @implementation AppDelegate
1617

1718
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
1819
// Insert code here to initialize your application
20+
if (@available(macOS 11.0, *)) {
21+
[SDImageCodersManager.sharedManager addCoder:SDImageAWebPCoder.sharedCoder];
22+
}
23+
[SDImageCodersManager.sharedManager addCoder:SDImageHEICCoder.sharedCoder];
1924
}
2025

2126

Example/SDWebImagePhotosPlugin_Example macOS/ViewController.m

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#import "ViewController.h"
1010
#import <SDWebImagePhotosPlugin/SDWebImagePhotosPlugin.h>
11+
#import <SDWebImagePhotosPlugin/SDWebImagePhotosDefine.h>
1112
#import "TestCollectionViewItem.h"
1213

1314
@interface ViewController () <NSCollectionViewDelegate, NSCollectionViewDataSource>
@@ -81,8 +82,18 @@ - (void)reloadData {
8182
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
8283
TestCollectionViewItem *cell = [collectionView makeItemWithIdentifier:@"TestCollectionViewItem" forIndexPath:indexPath];
8384
NSURL *photosURL = self.objects[indexPath.item];
85+
BOOL supportsHDR = NSScreen.mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1.0;
86+
SDWebImageMutableContext *context = [@{SDWebImageContextStoreCacheType: @(SDImageCacheTypeNone)} mutableCopy];
87+
if (supportsHDR) {
88+
if (@available (macOS 14.0, *)) {
89+
cell.imageViewDisplay.preferredImageDynamicRange = NSImageDynamicRangeHigh; // Enable Image View Level control for HDR
90+
}
91+
context[SDWebImageContextPhotosRequestImageData] = @(YES); // Photos Library only load HDR info when requestImageData
92+
context[SDWebImageContextImageDecodeToHDR] = @(YES); // When decoding HDR data, we need explicit enable HDR decoding
93+
}
94+
cell.imageViewDisplay.animates = YES;
8495
cell.imageViewDisplay.sd_imageTransition = SDWebImageTransition.fadeTransition;
85-
[cell.imageViewDisplay sd_setImageWithURL:photosURL placeholderImage:nil options:SDWebImageFromLoaderOnly context:@{SDWebImageContextStoreCacheType: @(SDImageCacheTypeNone)}];
96+
[cell.imageViewDisplay sd_setImageWithURL:photosURL placeholderImage:nil options:SDWebImageFromLoaderOnly context:context];
8697
return cell;
8798
}
8899

SDWebImagePhotosPlugin/Classes/PHAsset+SDWebImagePhotosPlugin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@interface PHAsset (SDWebImagePhotosPlugin)
1212

1313
/// The convenience way to retrive the URL representation of PHAsset. The same as `+[NSURL sd_URLWithAsset:]`.
14-
/// @note This API always return new object in Objective-C/struct in Swift of URL.
14+
/// @note This API always create and return new object in Objective-C/struct in Swift of URL. (which does not store the URL inside PHAssets, to avoid retain cycle)
1515
@property (nonatomic, strong, readonly, nonnull) NSURL *sd_URLRepresentation;
1616

1717
@end

SDWebImagePhotosPlugin/Classes/SDImagePhotosLoader.m

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,14 @@ - (instancetype)init {
8686
return self;
8787
}
8888

89+
#if SD_UIKIT
8990
- (void)didReceiveMemoryWarning:(NSNotification *)notification {
9091
for (SDImagePhotosLoaderOperation *operation in self.operationsTable) {
9192
[operation cancel];
9293
}
9394
[self.operationsTable removeAllObjects];
9495
}
96+
#endif
9597

9698
#pragma mark - Helper
9799
+ (BOOL)isAnimatedImageWithUTType:(NSString *)UTType {
@@ -156,11 +158,20 @@ - (BOOL)canRequestImageForURL:(NSURL *)url {
156158
NSString *localIdentifier = url.sd_assetLocalIdentifier;
157159
PHFetchResult<PHAsset *> *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:fetchOptions];
158160
asset = fetchResult.firstObject;
161+
if (!asset) {
162+
NSString *desc = [NSString stringWithFormat:@"Invalid PHAsset localIdentifier: %@", localIdentifier];
163+
NSError *error = [NSError errorWithDomain:SDWebImagePhotosErrorDomain code:SDWebImagePhotosErrorInvalidLocalIdentifier userInfo:@{NSLocalizedDescriptionKey: desc}];
164+
if (completedBlock) {
165+
completedBlock(nil, nil, error, YES);
166+
}
167+
return;
168+
}
159169
}
160170
// Check whether we should request only image asset
161-
if (!asset || (self.requestImageAssetOnly && asset.mediaType != PHAssetMediaTypeImage)) {
171+
if (self.requestImageAssetOnly && asset.mediaType != PHAssetMediaTypeImage) {
162172
// Call error
163-
NSError *error = [NSError errorWithDomain:SDWebImagePhotosErrorDomain code:SDWebImagePhotosErrorNotImageAsset userInfo:nil];
173+
NSString *desc = [NSString stringWithFormat:@"Unsupported PHAsset localIdentifier: %d, PHAssetMediaType: %d", asset.localIdentifier, asset.mediaType];
174+
NSError *error = [NSError errorWithDomain:SDWebImagePhotosErrorDomain code:SDWebImagePhotosErrorNotImageAsset userInfo:@{NSLocalizedDescriptionKey: desc}];
164175
if (completedBlock) {
165176
completedBlock(nil, nil, error, YES);
166177
}
@@ -263,7 +274,7 @@ - (void)fetchImageWithAsset:(PHAsset *)asset operation:(SDImagePhotosLoaderOpera
263274

264275
__weak typeof(operation) weakOperation = operation;
265276
PHImageRequestID requestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:targetSize contentMode:contentMode options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
266-
if (weakOperation.isCancelled) {
277+
if (weakOperation.isCancelled || [info[PHImageCancelledKey] boolValue]) {
267278
// Cancelled
268279
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil];
269280
if (completedBlock) {
@@ -319,7 +330,7 @@ - (void)fetchImageDataWithAsset:(PHAsset *)asset operation:(SDImagePhotosLoaderO
319330

320331
__weak typeof(operation) weakOperation = operation;
321332
PHImageRequestID requestID = [(id<PHImageManager>)[PHImageManager defaultManager] requestImageDataForAsset:asset options:requestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, SDImageOrientation orientation, NSDictionary * _Nullable info) {
322-
if (weakOperation.isCancelled) {
333+
if (weakOperation.isCancelled || [info[PHImageCancelledKey] boolValue]) {
323334
// Cancelled
324335
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil];
325336
if (completedBlock) {

SDWebImagePhotosPlugin/Classes/SDWebImagePhotosError.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010

1111
FOUNDATION_EXPORT NSErrorDomain const SDWebImagePhotosErrorDomain;
1212

13+
/// The error domain for SDWebImagePhotosPlugin's NSError
1314
typedef NS_ERROR_ENUM(SDWebImagePhotosErrorDomain, SDWebImagePhotosError) {
1415
/// Photos framework access is not authorized by user
1516
SDWebImagePhotosErrorNotAuthorized = 10001,
1617
/// Photos URL is not image asset type (like Video or Audio)
17-
SDWebImagePhotosErrorNotImageAsset = 10002
18+
SDWebImagePhotosErrorNotImageAsset = 10002,
19+
/// Photos local identifier failed to query PHAsset, is this valid ?
20+
SDWebImagePhotosErrorInvalidLocalIdentifier = 10003
1821
};

0 commit comments

Comments
 (0)