Skip to content

Commit

Permalink
[tvOS] Fixes warnings related to @available guards in Xcode 9
Browse files Browse the repository at this point in the history
[ASMultiplexImageNode] Enables support for Photos framework on tvOS 10+

[ASMultiplexImageNode] Fixes comment depth

[ASAvailability] Adjust logic in AS_AVAILABLE_IOS_TVOS to account for
both versions
Adjusts API_AVAILABLE to minimum deployment target
  • Loading branch information
alexhillc committed Dec 28, 2017
1 parent b1b582a commit 7759cf7
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Source/ASCollectionView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ - (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionV
// Experiments done by Instagram show that this option being YES (default)
// when unused causes a significant hit to scroll performance.
// https://github.com/Instagram/IGListKit/issues/318
if (AS_AVAILABLE_IOS(10)) {
if (AS_AVAILABLE_IOS_TVOS(10, 10)) {
super.prefetchingEnabled = NO;
}

Expand Down
2 changes: 1 addition & 1 deletion Source/ASImageNode+AnimatedImage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ - (void)displayLinkFired:(CADisplayLink *)displayLink
CFTimeInterval timeBetweenLastFire;
if (self.lastDisplayLinkFire == 0) {
timeBetweenLastFire = 0;
} else if (AS_AVAILABLE_IOS(10)){
} else if (AS_AVAILABLE_IOS_TVOS(10, 10)) {
timeBetweenLastFire = displayLink.targetTimestamp - displayLink.timestamp;
} else {
timeBetweenLastFire = CACurrentMediaTime() - self.lastDisplayLinkFire;
Expand Down
14 changes: 4 additions & 10 deletions Source/ASMultiplexImageNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,12 @@ typedef NS_ENUM(NSUInteger, ASMultiplexImageNodeErrorCode) {
*/
@property (nonatomic, assign, readwrite) BOOL shouldRenderProgressImages;

#if TARGET_OS_IOS
/**
* @abstract The image manager that this image node should use when requesting images from the Photos framework. If this is `nil` (the default), then `PHImageManager.defaultManager` is used.
* @see `+[NSURL URLWithAssetLocalIdentifier:targetSize:contentMode:options:]` below.
*/
@property (nullable, nonatomic, strong) PHImageManager *imageManager;
#endif
@property (nullable, nonatomic, strong) PHImageManager *imageManager API_AVAILABLE(ios(9.0), tvos(10.0));
@end


Expand Down Expand Up @@ -245,7 +243,6 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier
*/
- (nullable NSURL *)multiplexImageNode:(ASMultiplexImageNode *)imageNode URLForImageIdentifier:(ASImageIdentifier)imageIdentifier;

#if TARGET_OS_IOS
/**
* @abstract A PHAsset for the specific asset local identifier
* @param imageNode The sender.
Expand All @@ -256,12 +253,10 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier
* @note This method may be called from any thread.
* @return A PHAsset corresponding to `assetLocalIdentifier`, or nil if none is available.
*/
- (nullable PHAsset *)multiplexImageNode:(ASMultiplexImageNode *)imageNode assetForLocalIdentifier:(NSString *)assetLocalIdentifier;
#endif
- (nullable PHAsset *)multiplexImageNode:(ASMultiplexImageNode *)imageNode assetForLocalIdentifier:(NSString *)assetLocalIdentifier API_AVAILABLE(ios(9.0), tvos(10.0));
@end

#pragma mark -
#if TARGET_OS_IOS
#pragma mark -
@interface NSURL (ASPhotosFrameworkURLs)

/**
Expand All @@ -275,9 +270,8 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier
+ (NSURL *)URLWithAssetLocalIdentifier:(NSString *)assetLocalIdentifier
targetSize:(CGSize)targetSize
contentMode:(PHImageContentMode)contentMode
options:(PHImageRequestOptions *)options AS_WARN_UNUSED_RESULT;
options:(PHImageRequestOptions *)options AS_WARN_UNUSED_RESULT API_AVAILABLE(ios(9.0), tvos(10.0));

@end
#endif

NS_ASSUME_NONNULL_END
97 changes: 52 additions & 45 deletions Source/ASMultiplexImageNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,16 @@ - (void)_fetchImageWithIdentifierFromCache:(id)imageIdentifier URL:(NSURL *)imag
@param completionBlock The block to be performed when the image has been loaded, if possible. May not be nil.
*/
- (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock;
#endif

/**
@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 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.
*/
- (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock;
#endif
- (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock API_AVAILABLE(ios(9.0), tvos(10.0));

/**
@abstract Downloads the image corresponding to the given imageIdentifier from the given URL.
@param imageIdentifier The identifier for the image to be downloaded. May not be nil.
Expand Down Expand Up @@ -348,9 +349,9 @@ - (void)setDataSource:(id <ASMultiplexImageNodeDataSource>)dataSource
_dataSource = dataSource;
_dataSourceFlags.image = [_dataSource respondsToSelector:@selector(multiplexImageNode:imageForImageIdentifier:)];
_dataSourceFlags.URL = [_dataSource respondsToSelector:@selector(multiplexImageNode:URLForImageIdentifier:)];
#if TARGET_OS_IOS
_dataSourceFlags.asset = [_dataSource respondsToSelector:@selector(multiplexImageNode:assetForLocalIdentifier:)];
#endif
if (AS_AVAILABLE_IOS_TVOS(8, 10)) {
_dataSourceFlags.asset = [_dataSource respondsToSelector:@selector(multiplexImageNode:assetForLocalIdentifier:)];
}
}


Expand Down Expand Up @@ -619,56 +620,62 @@ - (void)_loadNextImage
return;
}

#if TARGET_OS_IOS
#if TARGET_OS_IOS
// If it's an assets-library URL, we need to fetch it from the assets library.
if ([[nextImageURL scheme] isEqualToString:kAssetsLibraryURLScheme]) {
// Load the asset.
[self _loadALAssetWithIdentifier:nextImageIdentifier URL:nextImageURL completion:^(UIImage *downloadedImage, NSError *error) {
as_log_verbose(ASImageLoadingLog(), "Acquired image from assets library for %@ %@", weakSelf, nextImageIdentifier);
finishedLoadingBlock(downloadedImage, nextImageIdentifier, error);
}];

return;
}
// Likewise, if it's a iOS 8 Photo asset, we need to fetch it accordingly.
else if (ASPhotosFrameworkImageRequest *request = [ASPhotosFrameworkImageRequest requestWithURL:nextImageURL]) {
[self _loadPHAssetWithRequest:request identifier:nextImageIdentifier completion:^(UIImage *image, NSError *error) {
as_log_verbose(ASImageLoadingLog(), "Acquired image from Photos for %@ %@", weakSelf, nextImageIdentifier);
finishedLoadingBlock(image, nextImageIdentifier, error);
}];
#endif

if (AS_AVAILABLE_IOS_TVOS(8, 10)) {
// Likewise, if it's a iOS 8 Photo asset, we need to fetch it accordingly.
if (ASPhotosFrameworkImageRequest *request = [ASPhotosFrameworkImageRequest requestWithURL:nextImageURL]) {
[self _loadPHAssetWithRequest:request identifier:nextImageIdentifier completion:^(UIImage *image, NSError *error) {
as_log_verbose(ASImageLoadingLog(), "Acquired image from Photos for %@ %@", weakSelf, nextImageIdentifier);
finishedLoadingBlock(image, nextImageIdentifier, error);
}];

return;
}
}
#endif
else // Otherwise, it's a web URL that we can download.
{
// First, check the cache.
[self _fetchImageWithIdentifierFromCache:nextImageIdentifier URL:nextImageURL completion:^(UIImage *imageFromCache) {

// Otherwise, it's a web URL that we can download.
// First, check the cache.
[self _fetchImageWithIdentifierFromCache:nextImageIdentifier URL:nextImageURL completion:^(UIImage *imageFromCache) {
__typeof__(self) strongSelf = weakSelf;
if (!strongSelf)
return;

// If we had a cache-hit, we're done.
if (imageFromCache) {
as_log_verbose(ASImageLoadingLog(), "Acquired image from cache for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, imageFromCache);
finishedLoadingBlock(imageFromCache, nextImageIdentifier, nil);
return;
}

// If the next image to load has changed, bail.
if (!ASObjectIsEqual([strongSelf _nextImageIdentifierToDownload], nextImageIdentifier)) {
finishedLoadingBlock(nil, nil, [NSError errorWithDomain:ASMultiplexImageNodeErrorDomain code:ASMultiplexImageNodeErrorCodeBestImageIdentifierChanged userInfo:nil]);
return;
}

// Otherwise, we've got to download it.
[strongSelf _downloadImageWithIdentifier:nextImageIdentifier URL:nextImageURL completion:^(UIImage *downloadedImage, NSError *error) {
__typeof__(self) strongSelf = weakSelf;
if (!strongSelf)
return;

// If we had a cache-hit, we're done.
if (imageFromCache) {
as_log_verbose(ASImageLoadingLog(), "Acquired image from cache for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, imageFromCache);
finishedLoadingBlock(imageFromCache, nextImageIdentifier, nil);
return;
}

// If the next image to load has changed, bail.
if (!ASObjectIsEqual([strongSelf _nextImageIdentifierToDownload], nextImageIdentifier)) {
finishedLoadingBlock(nil, nil, [NSError errorWithDomain:ASMultiplexImageNodeErrorDomain code:ASMultiplexImageNodeErrorCodeBestImageIdentifierChanged userInfo:nil]);
return;
if (downloadedImage) {
as_log_verbose(ASImageLoadingLog(), "Acquired image from download for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, downloadedImage);
} else {
as_log_error(ASImageLoadingLog(), "Error downloading image for %@ id: %@ err: %@", strongSelf, nextImageIdentifier, error);
}

// Otherwise, we've got to download it.
[strongSelf _downloadImageWithIdentifier:nextImageIdentifier URL:nextImageURL completion:^(UIImage *downloadedImage, NSError *error) {
__typeof__(self) strongSelf = weakSelf;
if (downloadedImage) {
as_log_verbose(ASImageLoadingLog(), "Acquired image from download for %@ id: %@ img: %@", strongSelf, nextImageIdentifier, downloadedImage);
} else {
as_log_error(ASImageLoadingLog(), "Error downloading image for %@ id: %@ err: %@", strongSelf, nextImageIdentifier, error);
}
finishedLoadingBlock(downloadedImage, nextImageIdentifier, error);
}];
finishedLoadingBlock(downloadedImage, nextImageIdentifier, error);
}];
}
}];
}
#if TARGET_OS_IOS
- (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock
Expand All @@ -689,7 +696,7 @@ - (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL com
completionBlock(nil, error);
}];
}

#endif
- (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock
{
ASDisplayNodeAssertNotNil(imageIdentifier, @"imageIdentifier is required");
Expand Down Expand Up @@ -777,7 +784,7 @@ - (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identif
_phImageRequestOperation = newImageRequestOp;
[phImageRequestQueue addOperation:newImageRequestOp];
}
#endif

- (void)_fetchImageWithIdentifierFromCache:(id)imageIdentifier URL:(NSURL *)imageURL completion:(void (^)(UIImage *image))completionBlock
{
ASDisplayNodeAssertNotNil(imageIdentifier, @"imageIdentifier is required");
Expand Down
8 changes: 6 additions & 2 deletions Source/Base/ASAvailability.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@

// Use __builtin_available if we're on Xcode >= 9, AS_AT_LEAST otherwise.
#if __has_builtin(__builtin_available)
#define AS_AVAILABLE_IOS(ver) __builtin_available(iOS ver, *)
#define AS_AVAILABLE_IOS(ver) __builtin_available(iOS ver, *)
#define AS_AVAILABLE_TVOS(ver) __builtin_available(tvOS ver, *)
#define AS_AVAILABLE_IOS_TVOS(ver1, ver2) __builtin_available(iOS ver1, tvOS ver2, *)
#else
#define AS_AVAILABLE_IOS(ver) AS_AT_LEAST_IOS##ver
#define AS_AVAILABLE_IOS(ver) AS_AT_LEAST_IOS##ver
#define AS_AVAILABLE_TVOS(ver) AS_AT_LEAST_IOS##ver
#define AS_AVAILABLE_IOS_TVOS(ver1, ver2) AS_AT_LEAST_IOS##ver1 || AS_AT_LEAST_IOS##ver2
#endif

// If Yoga is available, make it available anywhere we use ASAvailability.
Expand Down
1 change: 1 addition & 0 deletions Source/Details/ASPhotosFrameworkImageRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ extern NSString *const ASPhotosURLScheme;
@abstract Use ASPhotosFrameworkImageRequest to encapsulate all the information needed to request an image from
the Photos framework and store it in a URL.
*/
API_AVAILABLE(ios(9.0), tvos(10.0))
@interface ASPhotosFrameworkImageRequest : NSObject <NSCopying>

- (instancetype)initWithAssetIdentifier:(NSString *)assetIdentifier NS_DESIGNATED_INITIALIZER;
Expand Down
4 changes: 2 additions & 2 deletions Source/Details/_ASDisplayViewAccessiblity.mm
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ + (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)containe
accessibilityElement.accessibilityValue = node.accessibilityValue;
accessibilityElement.accessibilityTraits = node.accessibilityTraits;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if (AS_AVAILABLE_IOS(11)) {
if (AS_AVAILABLE_IOS_TVOS(11, 11)) {
accessibilityElement.accessibilityAttributedLabel = node.accessibilityAttributedLabel;
accessibilityElement.accessibilityAttributedHint = node.accessibilityAttributedHint;
accessibilityElement.accessibilityAttributedValue = node.accessibilityAttributedValue;
Expand Down Expand Up @@ -179,7 +179,7 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, _
SortAccessibilityElements(labeledNodes);

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if (AS_AVAILABLE_IOS(11)) {
if (AS_AVAILABLE_IOS_TVOS(11, 11)) {
NSArray *attributedLabels = [labeledNodes valueForKey:@"accessibilityAttributedLabel"];
NSMutableAttributedString *attributedLabel = [NSMutableAttributedString new];
[attributedLabels enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
Expand Down
6 changes: 3 additions & 3 deletions Source/Private/ASDisplayNode+UIViewBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ - (void)setAccessibilityLabel:(NSString *)accessibilityLabel
_bridge_prologue_write;
_setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityLabel, accessibilityLabel, accessibilityLabel);
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if (AS_AVAILABLE_IOS(11)) {
if (AS_AVAILABLE_IOS_TVOS(11, 11)) {
NSAttributedString *accessibilityAttributedLabel = accessibilityLabel ? [[NSAttributedString alloc] initWithString:accessibilityLabel] : nil;
_setAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel);
}
Expand Down Expand Up @@ -973,7 +973,7 @@ - (void)setAccessibilityHint:(NSString *)accessibilityHint
_bridge_prologue_write;
_setAccessibilityToViewAndProperty(_accessibilityHint, accessibilityHint, accessibilityHint, accessibilityHint);
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if (AS_AVAILABLE_IOS(11)) {
if (AS_AVAILABLE_IOS_TVOS(11, 11)) {
NSAttributedString *accessibilityAttributedHint = accessibilityHint ? [[NSAttributedString alloc] initWithString:accessibilityHint] : nil;
_setAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint);
}
Expand Down Expand Up @@ -1007,7 +1007,7 @@ - (void)setAccessibilityValue:(NSString *)accessibilityValue
_bridge_prologue_write;
_setAccessibilityToViewAndProperty(_accessibilityValue, accessibilityValue, accessibilityValue, accessibilityValue);
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if (AS_AVAILABLE_IOS(11)) {
if (AS_AVAILABLE_IOS_TVOS(11, 11)) {
NSAttributedString *accessibilityAttributedValue = accessibilityValue ? [[NSAttributedString alloc] initWithString:accessibilityValue] : nil;
_setAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue);
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Private/_ASPendingState.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ + (_ASPendingState *)pendingViewStateFromView:(UIView *)view
pendingState.accessibilityHint = view.accessibilityHint;
pendingState.accessibilityValue = view.accessibilityValue;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if (AS_AVAILABLE_IOS(11)) {
if (AS_AVAILABLE_IOS_TVOS(11, 11)) {
pendingState.accessibilityAttributedLabel = view.accessibilityAttributedLabel;
pendingState.accessibilityAttributedHint = view.accessibilityAttributedHint;
pendingState.accessibilityAttributedValue = view.accessibilityAttributedValue;
Expand Down

0 comments on commit 7759cf7

Please sign in to comment.