diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 09d00b2816..92d75212a8 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -374,9 +374,10 @@ B350625D1B0111740018CF92 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943141A1575670030A7D0 /* Photos.framework */; }; B350625E1B0111780018CF92 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943121A1575630030A7D0 /* AssetsLibrary.framework */; }; B350625F1B0111800018CF92 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09AF195D04C000B7D73C /* Foundation.framework */; }; - CC7FD9DE1BB5E962005CCB2B /* ASPhotosImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosImageRequest.h */; settings = {ASSET_TAGS = (); }; }; + CC7FD9DE1BB5E962005CCB2B /* ASPhotosImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC7FD9DF1BB5E962005CCB2B /* ASPhotosImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosImageRequest.m */; settings = {ASSET_TAGS = (); }; }; CC7FD9E11BB5F750005CCB2B /* ASPhotosImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosImageRequestTests.m */; settings = {ASSET_TAGS = (); }; }; + CC7FD9E21BB603FF005CCB2B /* ASPhotosImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; D785F6621A74327E00291744 /* ASScrollNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D785F6601A74327E00291744 /* ASScrollNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; D785F6631A74327E00291744 /* ASScrollNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D785F6611A74327E00291744 /* ASScrollNode.m */; }; DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; }; @@ -1218,6 +1219,7 @@ 9C8221961BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */, 9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */, 34EFC7701B701CFA00AD841F /* ASStackLayoutDefines.h in Headers */, + CC7FD9E21BB603FF005CCB2B /* ASPhotosImageRequest.h in Headers */, 34EFC7711B701CFF00AD841F /* ASStackLayoutSpec.h in Headers */, 2767E9411BB19BD600EA9B77 /* ASViewController.h in Headers */, 044284FE1BAA387800D16268 /* ASStackLayoutSpecUtilities.h in Headers */, diff --git a/AsyncDisplayKit/ASMultiplexImageNode.h b/AsyncDisplayKit/ASMultiplexImageNode.h index db10daa324..ce9f22f16e 100644 --- a/AsyncDisplayKit/ASMultiplexImageNode.h +++ b/AsyncDisplayKit/ASMultiplexImageNode.h @@ -195,7 +195,7 @@ didFinishDownloadingImageWithIdentifier:(id)imageIdentifier * @abstract An image URL for the specified identifier. * @param imageNode The sender. * @param imageIdentifier The identifier for the image that will be downloaded. - * @discussion Supported URLs include assets-library, Photo framework URLs (ph://), HTTP, HTTPS, and FTP URLs. If the + * @discussion Supported URLs include assets-library, URLs converted from ASPhotosImageRequest, HTTP, HTTPS, and FTP URLs. If the * image is already available to the data source, it should be provided via <[ASMultiplexImageNodeDataSource * multiplexImageNode:imageForImageIdentifier:]> instead. * @returns An NSURL for the image identified by `imageIdentifier`, or nil if none is available. diff --git a/AsyncDisplayKit/ASMultiplexImageNode.mm b/AsyncDisplayKit/ASMultiplexImageNode.mm index d32d3be061..987575929f 100644 --- a/AsyncDisplayKit/ASMultiplexImageNode.mm +++ b/AsyncDisplayKit/ASMultiplexImageNode.mm @@ -18,6 +18,7 @@ #import "ASBaseDefines.h" #import "ASDisplayNode+Subclasses.h" #import "ASLog.h" +#import "ASPhotosImageRequest.h" #if !AS_IOS8_SDK_OR_LATER #error ASMultiplexImageNode can be used on iOS 7, but must be linked against the iOS 8 SDK. @@ -26,8 +27,6 @@ NSString *const ASMultiplexImageNodeErrorDomain = @"ASMultiplexImageNodeErrorDomain"; static NSString *const kAssetsLibraryURLScheme = @"assets-library"; -static NSString *const kPHAssetURLScheme = @"ph"; -static NSString *const kPHAssetURLPrefix = @"ph://"; /** @abstract Signature for the block to be performed after an image has loaded. @@ -120,14 +119,14 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent - (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock; /** - @abstract Loads the image corresponding to the given assetURL from the Photos framework. + @abstract Loads the image corresponding to the given image request from the Photos framework. @param imageIdentifier The identifier for the image to be loaded. May not be nil. - @param assetURL The photos framework URL (e.g., "ph://identifier") of the image to load, from PHAsset. May not be nil. + @param request The photos image request to load. May not be nil. @param completionBlock The block to be performed when the image has been loaded, if possible. May not be nil. @param image The image that was loaded. May be nil if no image could be downloaded. @param error An error describing why the load failed, if it failed; nil otherwise. */ -- (void)_loadPHAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock; +- (void)_loadPHAssetWithRequest:(ASPhotosImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock; /** @abstract Downloads the image corresponding to the given imageIdentifier from the given URL. @@ -456,8 +455,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent }]; } // Likewise, if it's a iOS 8 Photo asset, we need to fetch it accordingly. - else if (AS_AT_LEAST_IOS8 && [[nextImageURL scheme] isEqualToString:kPHAssetURLScheme]) { - [self _loadPHAssetWithIdentifier:nextImageIdentifier URL:nextImageURL completion:^(UIImage *image, NSError *error) { + else if (ASPhotosImageRequest *request = nextImageURL.asyncdisplaykit_photosRequest) { + [self _loadPHAssetWithRequest:request identifier:nextImageIdentifier completion:^(UIImage *image, NSError *error) { ASMultiplexImageNodeCLogDebug(@"[%p] Acquired next image (%@) from Photos Framework", weakSelf, nextImageIdentifier); finishedLoadingBlock(image, nextImageIdentifier, error); }]; @@ -511,17 +510,15 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent }]; } -- (void)_loadPHAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock +- (void)_loadPHAssetWithRequest:(ASPhotosImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock { ASDisplayNodeAssert(AS_AT_LEAST_IOS8, @"PhotosKit is unavailable on iOS 7."); ASDisplayNodeAssertNotNil(imageIdentifier, @"imageIdentifier is required"); - ASDisplayNodeAssertNotNil(assetURL, @"assetURL is required"); + ASDisplayNodeAssertNotNil(request, @"request is required"); ASDisplayNodeAssertNotNil(completionBlock, @"completionBlock is required"); // Get the PHAsset itself. - ASDisplayNodeAssertTrue([[assetURL absoluteString] hasPrefix:kPHAssetURLPrefix]); - NSString *assetIdentifier = [[assetURL absoluteString] substringFromIndex:[kPHAssetURLPrefix length]]; - PHFetchResult *assetFetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetIdentifier] options:nil]; + PHFetchResult *assetFetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[request.assetIdentifier] options:nil]; if ([assetFetchResult count] == 0) { // Error. completionBlock(nil, nil); @@ -531,15 +528,10 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent // Get the best image we can. PHAsset *imageAsset = [assetFetchResult firstObject]; - PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init]; - requestOptions.version = PHImageRequestOptionsVersionCurrent; - requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; - requestOptions.resizeMode = PHImageRequestOptionsResizeModeNone; - [[PHImageManager defaultManager] requestImageForAsset:imageAsset - targetSize:CGSizeMake(2048.0, 2048.0) // Ideally we would use PHImageManagerMaximumSize and kill the options, but we get back nil when requesting images of video assets. rdar://18447788 - contentMode:PHImageContentModeDefault - options:requestOptions + targetSize:request.targetSize + contentMode:request.contentMode + options:request.options resultHandler:^(UIImage *image, NSDictionary *info) { completionBlock(image, info[PHImageErrorKey]); }]; diff --git a/AsyncDisplayKit/AsyncDisplayKit.h b/AsyncDisplayKit/AsyncDisplayKit.h index 6b2aa9ea9d..57fe043902 100644 --- a/AsyncDisplayKit/AsyncDisplayKit.h +++ b/AsyncDisplayKit/AsyncDisplayKit.h @@ -18,6 +18,7 @@ #import #import #import +#import #import #import diff --git a/AsyncDisplayKit/Details/ASPhotosImageRequest.h b/AsyncDisplayKit/Details/ASPhotosImageRequest.h index 92d9910924..45e34c9042 100644 --- a/AsyncDisplayKit/Details/ASPhotosImageRequest.h +++ b/AsyncDisplayKit/Details/ASPhotosImageRequest.h @@ -60,6 +60,7 @@ extern NSString *const ASPhotosURLScheme; @return `YES` if `object` is an equivalent image request, `NO` otherwise. */ - (BOOL)isEqual:(id)object; + @end @interface NSURL (ASPhotosRequestConverting)