diff --git a/Example/Podfile b/Example/Podfile index f4e1ab3..64ed92d 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -3,7 +3,7 @@ use_frameworks! target 'Zoomy_Example' do pod 'Zoomy', :path => '../' - pod "Texture" + pod "Texture", "~> 3.0" target 'Zoomy_Tests' do inherit! :search_paths diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 5683f92..6db8f21 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,50 +1,50 @@ PODS: - - InjectableLoggers (2.0.0) - - PINCache (3.0.1-beta.6): - - PINCache/Arc-exception-safe (= 3.0.1-beta.6) - - PINCache/Core (= 3.0.1-beta.6) - - PINCache/Arc-exception-safe (3.0.1-beta.6): + - InjectableLoggers (2.1.1) + - PINCache (3.0.3): + - PINCache/Arc-exception-safe (= 3.0.3) + - PINCache/Core (= 3.0.3) + - PINCache/Arc-exception-safe (3.0.3): - PINCache/Core - - PINCache/Core (3.0.1-beta.6): - - PINOperation (~> 1.1.0) - - PINOperation (1.1.2) - - PINRemoteImage/Core (3.0.0-beta.13): + - PINCache/Core (3.0.3): + - PINOperation (~> 1.2.1) + - PINOperation (1.2.1) + - PINRemoteImage/Core (3.0.3): - PINOperation - - PINRemoteImage/iOS (3.0.0-beta.13): + - PINRemoteImage/iOS (3.0.3): - PINRemoteImage/Core - - PINRemoteImage/PINCache (3.0.0-beta.13): - - PINCache (= 3.0.1-beta.6) + - PINRemoteImage/PINCache (3.0.3): + - PINCache (~> 3.0.3) - PINRemoteImage/Core - - Texture (2.8.1): - - Texture/AssetsLibrary (= 2.8.1) - - Texture/Core (= 2.8.1) - - Texture/MapKit (= 2.8.1) - - Texture/Photos (= 2.8.1) - - Texture/PINRemoteImage (= 2.8.1) - - Texture/Video (= 2.8.1) - - Texture/AssetsLibrary (2.8.1): + - Texture (3.0.0): + - Texture/AssetsLibrary (= 3.0.0) + - Texture/Core (= 3.0.0) + - Texture/MapKit (= 3.0.0) + - Texture/Photos (= 3.0.0) + - Texture/PINRemoteImage (= 3.0.0) + - Texture/Video (= 3.0.0) + - Texture/AssetsLibrary (3.0.0): - Texture/Core - - Texture/Core (2.8.1) - - Texture/MapKit (2.8.1): + - Texture/Core (3.0.0) + - Texture/MapKit (3.0.0): - Texture/Core - - Texture/Photos (2.8.1): + - Texture/Photos (3.0.0): - Texture/Core - - Texture/PINRemoteImage (2.8.1): - - PINRemoteImage/iOS (= 3.0.0-beta.13) + - Texture/PINRemoteImage (3.0.0): + - PINRemoteImage/iOS (~> 3.0.0) - PINRemoteImage/PINCache - Texture/Core - - Texture/Video (2.8.1): + - Texture/Video (3.0.0): - Texture/Core - Zoomy (4.0.0): - InjectableLoggers (~> 2.0) DEPENDENCIES: - InjectableLoggers (~> 2.0) - - Texture + - Texture (~> 3.0) - Zoomy (from `../`) SPEC REPOS: - https://github.com/cocoapods/specs.git: + trunk: - InjectableLoggers - PINCache - PINOperation @@ -56,13 +56,13 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - InjectableLoggers: a21d5df992e5c85533a9a5026152e1c8edef7bbe - PINCache: d195fdba255283f7e9900a55e3cced377f431f9b - PINOperation: 24b774353ca248fcf87d67b2d61eef42087c125a - PINRemoteImage: d6d51c5d2adda55f1ce30c96e850b6c4ebd2856a - Texture: 8ecf6984065a1e54f06bf97b349ecca28582acd7 - Zoomy: 598d7a6d52567e4f8bf2e557907bbd9d7e725664 + InjectableLoggers: 7bc1a68fb12d73785d3d50944a3f1744a8cea868 + PINCache: 7a8fc1a691173d21dbddbf86cd515de6efa55086 + PINOperation: 00c935935f1e8cf0d1e2d6b542e75b88fc3e5e20 + PINRemoteImage: f1295b29f8c5e640e25335a1b2bd9d805171bd01 + Texture: 2f109e937850d94d1d07232041c9c7313ccddb81 + Zoomy: 79ed8ebc515b980887b9dd5f1ffea4c2df46301e -PODFILE CHECKSUM: 1a98f060c4b54415ee310fe4312ff2c049357790 +PODFILE CHECKSUM: 77596a24c95a577618a66ed3d7d1eb864848691e -COCOAPODS: 1.7.5 +COCOAPODS: 1.10.1 diff --git a/Example/Pods/InjectableLoggers/InjectableLoggers/Classes/Structs/Logger.Formatter.swift b/Example/Pods/InjectableLoggers/InjectableLoggers/Classes/Structs/Logger.Formatter.swift index 2496910..9f31017 100644 --- a/Example/Pods/InjectableLoggers/InjectableLoggers/Classes/Structs/Logger.Formatter.swift +++ b/Example/Pods/InjectableLoggers/InjectableLoggers/Classes/Structs/Logger.Formatter.swift @@ -1,3 +1,5 @@ +import Foundation + public extension Logger { struct Formatter { diff --git a/Example/Pods/Local Podspecs/Zoomy.podspec.json b/Example/Pods/Local Podspecs/Zoomy.podspec.json index 7e95d89..0b1fb04 100644 --- a/Example/Pods/Local Podspecs/Zoomy.podspec.json +++ b/Example/Pods/Local Podspecs/Zoomy.podspec.json @@ -17,7 +17,7 @@ "tag": "4.0.0" }, "platforms": { - "ios": "8.0" + "ios": "9.0" }, "source_files": "Zoomy/Classes/**/*", "dependencies": { diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index 5683f92..6db8f21 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -1,50 +1,50 @@ PODS: - - InjectableLoggers (2.0.0) - - PINCache (3.0.1-beta.6): - - PINCache/Arc-exception-safe (= 3.0.1-beta.6) - - PINCache/Core (= 3.0.1-beta.6) - - PINCache/Arc-exception-safe (3.0.1-beta.6): + - InjectableLoggers (2.1.1) + - PINCache (3.0.3): + - PINCache/Arc-exception-safe (= 3.0.3) + - PINCache/Core (= 3.0.3) + - PINCache/Arc-exception-safe (3.0.3): - PINCache/Core - - PINCache/Core (3.0.1-beta.6): - - PINOperation (~> 1.1.0) - - PINOperation (1.1.2) - - PINRemoteImage/Core (3.0.0-beta.13): + - PINCache/Core (3.0.3): + - PINOperation (~> 1.2.1) + - PINOperation (1.2.1) + - PINRemoteImage/Core (3.0.3): - PINOperation - - PINRemoteImage/iOS (3.0.0-beta.13): + - PINRemoteImage/iOS (3.0.3): - PINRemoteImage/Core - - PINRemoteImage/PINCache (3.0.0-beta.13): - - PINCache (= 3.0.1-beta.6) + - PINRemoteImage/PINCache (3.0.3): + - PINCache (~> 3.0.3) - PINRemoteImage/Core - - Texture (2.8.1): - - Texture/AssetsLibrary (= 2.8.1) - - Texture/Core (= 2.8.1) - - Texture/MapKit (= 2.8.1) - - Texture/Photos (= 2.8.1) - - Texture/PINRemoteImage (= 2.8.1) - - Texture/Video (= 2.8.1) - - Texture/AssetsLibrary (2.8.1): + - Texture (3.0.0): + - Texture/AssetsLibrary (= 3.0.0) + - Texture/Core (= 3.0.0) + - Texture/MapKit (= 3.0.0) + - Texture/Photos (= 3.0.0) + - Texture/PINRemoteImage (= 3.0.0) + - Texture/Video (= 3.0.0) + - Texture/AssetsLibrary (3.0.0): - Texture/Core - - Texture/Core (2.8.1) - - Texture/MapKit (2.8.1): + - Texture/Core (3.0.0) + - Texture/MapKit (3.0.0): - Texture/Core - - Texture/Photos (2.8.1): + - Texture/Photos (3.0.0): - Texture/Core - - Texture/PINRemoteImage (2.8.1): - - PINRemoteImage/iOS (= 3.0.0-beta.13) + - Texture/PINRemoteImage (3.0.0): + - PINRemoteImage/iOS (~> 3.0.0) - PINRemoteImage/PINCache - Texture/Core - - Texture/Video (2.8.1): + - Texture/Video (3.0.0): - Texture/Core - Zoomy (4.0.0): - InjectableLoggers (~> 2.0) DEPENDENCIES: - InjectableLoggers (~> 2.0) - - Texture + - Texture (~> 3.0) - Zoomy (from `../`) SPEC REPOS: - https://github.com/cocoapods/specs.git: + trunk: - InjectableLoggers - PINCache - PINOperation @@ -56,13 +56,13 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - InjectableLoggers: a21d5df992e5c85533a9a5026152e1c8edef7bbe - PINCache: d195fdba255283f7e9900a55e3cced377f431f9b - PINOperation: 24b774353ca248fcf87d67b2d61eef42087c125a - PINRemoteImage: d6d51c5d2adda55f1ce30c96e850b6c4ebd2856a - Texture: 8ecf6984065a1e54f06bf97b349ecca28582acd7 - Zoomy: 598d7a6d52567e4f8bf2e557907bbd9d7e725664 + InjectableLoggers: 7bc1a68fb12d73785d3d50944a3f1744a8cea868 + PINCache: 7a8fc1a691173d21dbddbf86cd515de6efa55086 + PINOperation: 00c935935f1e8cf0d1e2d6b542e75b88fc3e5e20 + PINRemoteImage: f1295b29f8c5e640e25335a1b2bd9d805171bd01 + Texture: 2f109e937850d94d1d07232041c9c7313ccddb81 + Zoomy: 79ed8ebc515b980887b9dd5f1ffea4c2df46301e -PODFILE CHECKSUM: 1a98f060c4b54415ee310fe4312ff2c049357790 +PODFILE CHECKSUM: 77596a24c95a577618a66ed3d7d1eb864848691e -COCOAPODS: 1.7.5 +COCOAPODS: 1.10.1 diff --git a/Example/Pods/PINCache/README.md b/Example/Pods/PINCache/README.md index 6522640..aa81564 100644 --- a/Example/Pods/PINCache/README.md +++ b/Example/Pods/PINCache/README.md @@ -2,7 +2,7 @@ [![CocoaPods](https://img.shields.io/cocoapods/v/PINCache.svg)](http://cocoadocs.org/docsets/PINCache/) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -[![Build status](https://badge.buildkite.com/03e247305c96c3371f2ff2766e9c8c1efdd5fdb3a7eceaff43.svg?branch=master&style=flat)](https://buildkite.com/pinterest/pincache) +[![Build status](https://github.com/pinterest/PINCache/workflows/CI/badge.svg)](https://github.com/pinterest/PINCache/actions?query=workflow%3ACI+branch%3Amaster) ## Fast, non-deadlocking parallel object cache for iOS and OS X. @@ -82,7 +82,7 @@ Add the following line to your `Cartfile` and run `carthage update --platform io ## Requirements -__PINCache__ requires iOS 5.0, tvOS 9.0, watchOS 2.0 or OS X 10.7 and greater. +__PINCache__ requires iOS 8.0, tvOS 9.0, watchOS 2.0 or macOS 10.8 and greater. ## Contact diff --git a/Example/Pods/PINCache/Source/PINCache.h b/Example/Pods/PINCache/Source/PINCache.h index fa743a8..bfc9d85 100644 --- a/Example/Pods/PINCache/Source/PINCache.h +++ b/Example/Pods/PINCache/Source/PINCache.h @@ -4,10 +4,10 @@ #import -#import -#import -#import -#import +#import "PINCacheMacros.h" +#import "PINCaching.h" +#import "PINDiskCache.h" +#import "PINMemoryCache.h" NS_ASSUME_NONNULL_BEGIN @@ -103,6 +103,27 @@ PIN_SUBCLASSING_RESTRICTED serializer:(nullable PINDiskCacheSerializerBlock)serializer deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer; +/** + Multiple instances with the same name are *not* allowed and can *not* safely + access the same data on disk. Also used to create the . + Initializer allows you to override default NSKeyedArchiver/NSKeyedUnarchiver serialization for . + You must provide both serializer and deserializer, or opt-out to default implementation providing nil values. + + @see name + @param name The name of the cache. + @param rootPath The path of the cache on disk. + @param serializer A block used to serialize object before writing to disk. If nil provided, default NSKeyedArchiver serialized will be used. + @param deserializer A block used to deserialize object read from disk. If nil provided, default NSKeyedUnarchiver serialized will be used. + @param keyEncoder A block used to encode key(filename). If nil provided, default url encoder will be used + @param keyDecoder A block used to decode key(filename). If nil provided, default url decoder will be used + @result A new cache with the specified name. + */ +- (instancetype)initWithName:(nonnull NSString *)name + rootPath:(nonnull NSString *)rootPath + serializer:(nullable PINDiskCacheSerializerBlock)serializer + deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer + keyEncoder:(nullable PINDiskCacheKeyEncoderBlock)keyEncoder + keyDecoder:(nullable PINDiskCacheKeyDecoderBlock)keyDecoder; /** Multiple instances with the same name are *not* allowed and can *not* safely @@ -117,6 +138,7 @@ PIN_SUBCLASSING_RESTRICTED @param deserializer A block used to deserialize object read from disk. If nil provided, default NSKeyedUnarchiver serialized will be used. @param keyEncoder A block used to encode key(filename). If nil provided, default url encoder will be used @param keyDecoder A block used to decode key(filename). If nil provided, default url decoder will be used + @param ttlCache Whether or not the cache should behave as a TTL cache. @result A new cache with the specified name. */ - (instancetype)initWithName:(nonnull NSString *)name @@ -124,7 +146,8 @@ PIN_SUBCLASSING_RESTRICTED serializer:(nullable PINDiskCacheSerializerBlock)serializer deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer keyEncoder:(nullable PINDiskCacheKeyEncoderBlock)keyEncoder - keyDecoder:(nullable PINDiskCacheKeyDecoderBlock)keyDecoder NS_DESIGNATED_INITIALIZER; + keyDecoder:(nullable PINDiskCacheKeyDecoderBlock)keyDecoder + ttlCache:(BOOL)ttlCache NS_DESIGNATED_INITIALIZER; @end diff --git a/Example/Pods/PINCache/Source/PINCache.m b/Example/Pods/PINCache/Source/PINCache.m index 81c1564..b52f1f6 100644 --- a/Example/Pods/PINCache/Source/PINCache.m +++ b/Example/Pods/PINCache/Source/PINCache.m @@ -4,7 +4,11 @@ #import "PINCache.h" +#if SWIFT_PACKAGE +@import PINOperation; +#else #import +#endif static NSString * const PINCachePrefix = @"com.pinterest.PINCache"; static NSString * const PINCacheSharedName = @"PINCacheShared"; @@ -44,6 +48,17 @@ - (instancetype)initWithName:(NSString *)name deserializer:(PINDiskCacheDeserializerBlock)deserializer keyEncoder:(PINDiskCacheKeyEncoderBlock)keyEncoder keyDecoder:(PINDiskCacheKeyDecoderBlock)keyDecoder +{ + return [self initWithName:name rootPath:rootPath serializer:serializer deserializer:deserializer keyEncoder:keyEncoder keyDecoder:keyDecoder ttlCache:NO]; +} + +- (instancetype)initWithName:(NSString *)name + rootPath:(NSString *)rootPath + serializer:(PINDiskCacheSerializerBlock)serializer + deserializer:(PINDiskCacheDeserializerBlock)deserializer + keyEncoder:(PINDiskCacheKeyEncoderBlock)keyEncoder + keyDecoder:(PINDiskCacheKeyDecoderBlock)keyDecoder + ttlCache:(BOOL)ttlCache { if (!name) return nil; @@ -58,10 +73,11 @@ - (instancetype)initWithName:(NSString *)name rootPath:rootPath serializer:serializer deserializer:deserializer - keyEncoder:nil - keyDecoder:nil - operationQueue:_operationQueue]; - _memoryCache = [[PINMemoryCache alloc] initWithOperationQueue:_operationQueue]; + keyEncoder:keyEncoder + keyDecoder:keyDecoder + operationQueue:_operationQueue + ttlCache:ttlCache]; + _memoryCache = [[PINMemoryCache alloc] initWithName:_name operationQueue:_operationQueue ttlCache:ttlCache]; } return self; } @@ -106,7 +122,7 @@ - (void)objectForKeyAsync:(NSString *)key completion:(PINCacheObjectBlock)block return; [self.operationQueue scheduleOperation:^{ - [self->_memoryCache objectForKeyAsync:key completion:^(PINMemoryCache *memoryCache, NSString *memoryCacheKey, id memoryCacheObject) { + [self->_memoryCache objectForKeyAsync:key completion:^(id memoryCache, NSString *memoryCacheKey, id memoryCacheObject) { if (memoryCacheObject) { // Update file modification date. TODO: make this a separate method? [self->_diskCache fileURLForKeyAsync:memoryCacheKey completion:^(NSString * _Nonnull key, NSURL * _Nullable fileURL) {}]; @@ -134,7 +150,17 @@ - (void)setObjectAsync:(id )object forKey:(NSString *)key completion:( [self setObjectAsync:object forKey:key withCost:0 completion:block]; } +- (void)setObjectAsync:(id )object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(PINCacheObjectBlock)block +{ + [self setObjectAsync:object forKey:key withCost:0 ageLimit:ageLimit completion:block]; +} + - (void)setObjectAsync:(id )object forKey:(NSString *)key withCost:(NSUInteger)cost completion:(PINCacheObjectBlock)block +{ + [self setObjectAsync:object forKey:key withCost:cost ageLimit:0.0 completion:block]; +} + +- (void)setObjectAsync:(nonnull id)object forKey:(nonnull NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block { if (!key || !object) return; @@ -142,10 +168,10 @@ - (void)setObjectAsync:(id )object forKey:(NSString *)key withCost:(NS PINOperationGroup *group = [PINOperationGroup asyncOperationGroupWithQueue:_operationQueue]; [group addOperation:^{ - [_memoryCache setObject:object forKey:key withCost:cost]; + [self->_memoryCache setObject:object forKey:key withCost:cost ageLimit:ageLimit]; }]; [group addOperation:^{ - [_diskCache setObject:object forKey:key]; + [self->_diskCache setObject:object forKey:key withAgeLimit:ageLimit]; }]; if (block) { @@ -165,10 +191,10 @@ - (void)removeObjectForKeyAsync:(NSString *)key completion:(PINCacheObjectBlock) PINOperationGroup *group = [PINOperationGroup asyncOperationGroupWithQueue:_operationQueue]; [group addOperation:^{ - [_memoryCache removeObjectForKey:key]; + [self->_memoryCache removeObjectForKey:key]; }]; [group addOperation:^{ - [_diskCache removeObjectForKey:key]; + [self->_diskCache removeObjectForKey:key]; }]; if (block) { @@ -185,10 +211,10 @@ - (void)removeAllObjectsAsync:(PINCacheBlock)block PINOperationGroup *group = [PINOperationGroup asyncOperationGroupWithQueue:_operationQueue]; [group addOperation:^{ - [_memoryCache removeAllObjects]; + [self->_memoryCache removeAllObjects]; }]; [group addOperation:^{ - [_diskCache removeAllObjects]; + [self->_diskCache removeAllObjects]; }]; if (block) { @@ -208,10 +234,10 @@ - (void)trimToDateAsync:(NSDate *)date completion:(PINCacheBlock)block PINOperationGroup *group = [PINOperationGroup asyncOperationGroupWithQueue:_operationQueue]; [group addOperation:^{ - [_memoryCache trimToDate:date]; + [self->_memoryCache trimToDate:date]; }]; [group addOperation:^{ - [_diskCache trimToDate:date]; + [self->_diskCache trimToDate:date]; }]; if (block) { @@ -223,14 +249,34 @@ - (void)trimToDateAsync:(NSDate *)date completion:(PINCacheBlock)block [group start]; } +- (void)removeExpiredObjectsAsync:(PINCacheBlock)block +{ + PINOperationGroup *group = [PINOperationGroup asyncOperationGroupWithQueue:_operationQueue]; + + [group addOperation:^{ + [self->_memoryCache removeExpiredObjects]; + }]; + [group addOperation:^{ + [self->_diskCache removeExpiredObjects]; + }]; + + if (block) { + [group setCompletion:^{ + block(self); + }]; + } + + [group start]; +} + #pragma mark - Public Synchronous Accessors - - (NSUInteger)diskByteCount { __block NSUInteger byteCount = 0; - [_diskCache synchronouslyLockFileAccessWhileExecutingBlock:^(PINDiskCache *diskCache) { - byteCount = diskCache.byteCount; + [_diskCache synchronouslyLockFileAccessWhileExecutingBlock:^(id diskCache) { + byteCount = ((PINDiskCache *)diskCache).byteCount; }]; return byteCount; @@ -269,13 +315,23 @@ - (void)setObject:(id )object forKey:(NSString *)key [self setObject:object forKey:key withCost:0]; } +- (void)setObject:(id )object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit +{ + [self setObject:object forKey:key withCost:0 ageLimit:ageLimit]; +} + - (void)setObject:(id )object forKey:(NSString *)key withCost:(NSUInteger)cost +{ + [self setObject:object forKey:key withCost:cost ageLimit:0.0]; +} + +- (void)setObject:(nullable id)object forKey:(nonnull NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit { if (!key || !object) return; - [_memoryCache setObject:object forKey:key withCost:cost]; - [_diskCache setObject:object forKey:key]; + [_memoryCache setObject:object forKey:key withCost:cost ageLimit:ageLimit]; + [_diskCache setObject:object forKey:key withAgeLimit:ageLimit]; } - (nullable id)objectForKeyedSubscript:(NSString *)key @@ -310,6 +366,12 @@ - (void)trimToDate:(NSDate *)date [_diskCache trimToDate:date]; } +- (void)removeExpiredObjects +{ + [_memoryCache removeExpiredObjects]; + [_diskCache removeExpiredObjects]; +} + - (void)removeAllObjects { [_memoryCache removeAllObjects]; diff --git a/Example/Pods/PINCache/Source/PINCaching.h b/Example/Pods/PINCache/Source/PINCaching.h index 6b94136..326cd45 100644 --- a/Example/Pods/PINCache/Source/PINCaching.h +++ b/Example/Pods/PINCache/Source/PINCaching.h @@ -17,18 +17,18 @@ NS_ASSUME_NONNULL_BEGIN /** A callback block which provides only the cache as an argument */ -typedef void (^PINCacheBlock)(id cache); +typedef void (^PINCacheBlock)(__kindof id cache); /** A callback block which provides the cache, key and object as arguments */ -typedef void (^PINCacheObjectBlock)(id cache, NSString *key, id _Nullable object); +typedef void (^PINCacheObjectBlock)(__kindof id cache, NSString *key, id _Nullable object); /** A callback block used for enumeration which provides the cache, key and object as arguments plus a stop flag that may be flipped by the caller. */ -typedef void (^PINCacheObjectEnumerationBlock)(id cache, NSString *key, id _Nullable object, BOOL *stop); +typedef void (^PINCacheObjectEnumerationBlock)(__kindof id cache, NSString *key, id _Nullable object, BOOL *stop); /** A callback block which provides a BOOL value as argument @@ -78,6 +78,19 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject); */ - (void)setObjectAsync:(id)object forKey:(NSString *)key completion:(nullable PINCacheObjectBlock)block; +/** + Stores an object in the cache for the specified key and the specified age limit. This method returns immediately + and executes the passed block after the object has been stored, potentially in parallel with other blocks + on the . + + @param object An object to store in the cache. + @param key A key to associate with the object. This string will be copied. + @param ageLimit The age limit (in seconds) to associate with the object. An age limit <= 0 means there is no object-level age limit and the + cache-level TTL will be used for this object. + @param block A block to be executed concurrently after the object has been stored, or nil. + */ +- (void)setObjectAsync:(id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block; + /** Stores an object in the cache for the specified key and the specified memory cost. If the cost causes the total to go over the the cache is trimmed (oldest objects first). This method returns immediately @@ -91,6 +104,21 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject); */ - (void)setObjectAsync:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost completion:(nullable PINCacheObjectBlock)block; +/** + Stores an object in the cache for the specified key and the specified memory cost and age limit. If the cost causes the total + to go over the the cache is trimmed (oldest objects first). This method returns immediately + and executes the passed block after the object has been stored, potentially in parallel with other blocks + on the . + + @param object An object to store in the cache. + @param key A key to associate with the object. This string will be copied. + @param cost An amount to add to the . + @param ageLimit The age limit (in seconds) to associate with the object. An age limit <= 0 means there is no object-level age limit and the cache-level TTL will be + used for this object. + @param block A block to be executed concurrently after the object has been stored, or nil. + */ +- (void)setObjectAsync:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block; + /** Removes the object for the specified key. This method returns immediately and executes the passed block after the object has been removed, potentially in parallel with other blocks on the . @@ -109,6 +137,15 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject); */ - (void)trimToDateAsync:(NSDate *)date completion:(nullable PINCacheBlock)block; +/** + Removes all expired objects from the cache. This includes objects that are considered expired due to the cache-level ageLimit + as well as object-level ageLimits. This method returns immediately and executes the passed block after the objects have been removed, + potentially in parallel with other blocks on the . + + @param block A block to be executed concurrently after the objects have been removed, or nil. + */ +- (void)removeExpiredObjectsAsync:(nullable PINCacheBlock)block; + /** Removes all objects from the cache.This method returns immediately and executes the passed block after the cache has been cleared, potentially in parallel with other blocks on the . @@ -150,6 +187,18 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject); */ - (void)setObject:(nullable id)object forKey:(NSString *)key; +/** + Stores an object in the cache for the specified key and age limit. This method blocks the calling thread until the + object has been set. Uses a lock to achieve synchronicity on the disk cache. + + @see setObjectAsync:forKey:completion: + @param object An object to store in the cache. + @param key A key to associate with the object. This string will be copied. + @param ageLimit The age limit (in seconds) to associate with the object. An age limit <= 0 means there is no + object-level age limit and the cache-level TTL will be used for this object. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit; + /** Stores an object in the cache for the specified key and the specified memory cost. If the cost causes the total to go over the the cache is trimmed (oldest objects first). This method blocks the calling thread @@ -161,6 +210,19 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject); */ - (void)setObject:(nullable id)object forKey:(NSString *)key withCost:(NSUInteger)cost; +/** + Stores an object in the cache for the specified key and the specified memory cost and age limit. If the cost causes the total + to go over the the cache is trimmed (oldest objects first). This method blocks the calling thread + until the object has been stored. + + @param object An object to store in the cache. + @param key A key to associate with the object. This string will be copied. + @param cost An amount to add to the . + @param ageLimit The age limit (in seconds) to associate with the object. An age limit <= 0 means there is no object-level age + limit and the cache-level TTL will be used for this object. + */ +- (void)setObject:(nullable id)object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit; + /** Removes the object for the specified key. This method blocks the calling thread until the object has been removed. @@ -181,6 +243,13 @@ typedef void (^PINCacheObjectContainmentBlock)(BOOL containsObject); */ - (void)trimToDate:(NSDate *)date; +/** + Removes all expired objects from the cache. This includes objects that are considered expired due to the cache-level ageLimit + as well as object-level ageLimits. This method blocks the calling thread until the objects have been removed. + Uses a lock to achieve synchronicity on the disk cache. + */ +- (void)removeExpiredObjects; + /** Removes all objects from the cache. This method blocks the calling thread until the cache has been cleared. Uses a lock to achieve synchronicity on the disk cache. diff --git a/Example/Pods/PINCache/Source/PINDiskCache.h b/Example/Pods/PINCache/Source/PINDiskCache.h index 24e1d1b..81bb26a 100644 --- a/Example/Pods/PINCache/Source/PINDiskCache.h +++ b/Example/Pods/PINCache/Source/PINDiskCache.h @@ -4,21 +4,29 @@ #import -#import -#import -#import +#import "PINCacheMacros.h" +#import "PINCaching.h" +#import "PINCacheObjectSubscripting.h" NS_ASSUME_NONNULL_BEGIN @class PINDiskCache; @class PINOperationQueue; +extern NSString * const PINDiskCacheErrorDomain; +extern NSErrorUserInfoKey const PINDiskCacheErrorReadFailureCodeKey; +extern NSErrorUserInfoKey const PINDiskCacheErrorWriteFailureCodeKey; extern NSString * const PINDiskCachePrefix; +typedef NS_ENUM(NSInteger, PINDiskCacheError) { + PINDiskCacheErrorReadFailure = -1000, + PINDiskCacheErrorWriteFailure = -1001, +}; + /** A callback block which provides the cache, key and object as arguments */ -typedef void (^PINDiskCacheObjectBlock)(PINDiskCache *cache, NSString *key, id _Nullable object); +typedef void (^PINDiskCacheObjectBlock)(PINDiskCache *cache, NSString *key, id _Nullable object); /** A callback block which provides the key and fileURL of the object @@ -147,7 +155,7 @@ PIN_SUBCLASSING_RESTRICTED /** The maximum number of bytes allowed on disk. This value is checked every time an object is set, if the written - size exceeds the limit a trim call is queued. Defaults to `0.0`, meaning no practical limit. + size exceeds the limit a trim call is queued. Defaults to 50MB. */ @property (assign) NSUInteger byteLimit; @@ -155,7 +163,7 @@ PIN_SUBCLASSING_RESTRICTED /** The maximum number of seconds an object is allowed to exist in the cache. Setting this to a value greater than `0.0` will start a recurring GCD timer with the same period that calls . - Setting it back to `0.0` will stop the timer. Defaults to `0.0`, meaning no limit. + Setting it back to `0.0` will stop the timer. Defaults to 30 days. */ @property (assign) NSTimeInterval ageLimit; @@ -180,9 +188,13 @@ PIN_SUBCLASSING_RESTRICTED - Accessing an object in the cache does not extend that object's lifetime in the cache - When attempting to access an object in the cache that has lived longer than self.ageLimit, the cache will behave as if the object does not exist + + @note If an object-level age limit is set via one of the @c -setObject:forKey:withAgeLimit methods, + that age limit overrides self.ageLimit. The overridden object age limit could be greater or less + than self.agelimit but must be greater than zero. */ -@property (nonatomic, assign, getter=isTTLCache) BOOL ttlCache; +@property (nonatomic, readonly, getter=isTTLCache) BOOL ttlCache; #pragma mark - Event Blocks /// @name Event Blocks @@ -237,8 +249,8 @@ PIN_SUBCLASSING_RESTRICTED - (instancetype)init NS_UNAVAILABLE; /** - Multiple instances with the same name are allowed and can safely access - the same data on disk thanks to the magic of seriality. + Multiple instances with the same name are *not* allowed as they would conflict + with each other. @see name @param name The name of the cache. @@ -247,8 +259,8 @@ PIN_SUBCLASSING_RESTRICTED - (instancetype)initWithName:(nonnull NSString *)name; /** - Multiple instances with the same name are allowed and can safely access - the same data on disk thanks to the magic of seriality. + Multiple instances with the same name are *not* allowed as they would conflict + with each other. @see name @param name The name of the cache. @@ -267,9 +279,7 @@ PIN_SUBCLASSING_RESTRICTED */ - (instancetype)initWithName:(nonnull NSString *)name rootPath:(nonnull NSString *)rootPath serializer:(nullable PINDiskCacheSerializerBlock)serializer deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer; -/** - The designated initializer allowing you to override default NSKeyedArchiver/NSKeyedUnarchiver serialization. - +/** @see name @param name The name of the cache. @param rootPath The path of the cache. @@ -280,6 +290,27 @@ PIN_SUBCLASSING_RESTRICTED */ - (instancetype)initWithName:(nonnull NSString *)name rootPath:(nonnull NSString *)rootPath serializer:(nullable PINDiskCacheSerializerBlock)serializer deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer operationQueue:(nonnull PINOperationQueue *)operationQueue __attribute__((deprecated)); +/** + @see name + @param name The name of the cache. + @param prefix The prefix for the cache name. Defaults to com.pinterest.PINDiskCache + @param rootPath The path of the cache. + @param serializer A block used to serialize object. If nil provided, default NSKeyedArchiver serialized will be used. + @param deserializer A block used to deserialize object. If nil provided, default NSKeyedUnarchiver serialized will be used. + @param keyEncoder A block used to encode key(filename). If nil provided, default url encoder will be used + @param keyDecoder A block used to decode key(filename). If nil provided, default url decoder will be used + @param operationQueue A PINOperationQueue to run asynchronous operations + @result A new cache with the specified name. + */ +- (instancetype)initWithName:(nonnull NSString *)name + prefix:(nonnull NSString *)prefix + rootPath:(nonnull NSString *)rootPath + serializer:(nullable PINDiskCacheSerializerBlock)serializer + deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer + keyEncoder:(nullable PINDiskCacheKeyEncoderBlock)keyEncoder + keyDecoder:(nullable PINDiskCacheKeyDecoderBlock)keyDecoder + operationQueue:(nonnull PINOperationQueue *)operationQueue; + /** The designated initializer allowing you to override default NSKeyedArchiver/NSKeyedUnarchiver serialization. @@ -292,6 +323,7 @@ PIN_SUBCLASSING_RESTRICTED @param keyEncoder A block used to encode key(filename). If nil provided, default url encoder will be used @param keyDecoder A block used to decode key(filename). If nil provided, default url decoder will be used @param operationQueue A PINOperationQueue to run asynchronous operations + @param ttlCache Whether or not the cache should behave as a TTL cache. @result A new cache with the specified name. */ - (instancetype)initWithName:(nonnull NSString *)name @@ -301,7 +333,8 @@ PIN_SUBCLASSING_RESTRICTED deserializer:(nullable PINDiskCacheDeserializerBlock)deserializer keyEncoder:(nullable PINDiskCacheKeyEncoderBlock)keyEncoder keyDecoder:(nullable PINDiskCacheKeyDecoderBlock)keyDecoder - operationQueue:(nonnull PINOperationQueue *)operationQueue NS_DESIGNATED_INITIALIZER; + operationQueue:(nonnull PINOperationQueue *)operationQueue + ttlCache:(BOOL)ttlCache NS_DESIGNATED_INITIALIZER; #pragma mark - Asynchronous Methods /// @name Asynchronous Methods @@ -350,6 +383,18 @@ PIN_SUBCLASSING_RESTRICTED */ - (void)setObjectAsync:(id )object forKey:(NSString *)key completion:(nullable PINDiskCacheObjectBlock)block; +/** + Stores an object in the cache for the specified key and age limit. This method returns immediately and executes the + passed block as soon as the object has been stored. + + @param object An object to store in the cache. + @param key A key to associate with the object. This string will be copied. + @param ageLimit The age limit (in seconds) to associate with the object. An age limit <= 0 means there is no object-level age limit and the cache-level TTL + will be used for this object. + @param block A block to be executed serially after the object has been stored, or nil. + */ +- (void)setObjectAsync:(id )object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(nullable PINDiskCacheObjectBlock)block; + /** Stores an object in the cache for the specified key and the specified memory cost. If the cost causes the total to go over the the cache is trimmed (oldest objects first). This method returns immediately @@ -363,6 +408,21 @@ PIN_SUBCLASSING_RESTRICTED */ - (void)setObjectAsync:(id )object forKey:(NSString *)key withCost:(NSUInteger)cost completion:(nullable PINCacheObjectBlock)block; +/** + Stores an object in the cache for the specified key and the specified memory cost and age limit. If the cost causes the total + to go over the the cache is trimmed (oldest objects first). This method returns immediately + and executes the passed block after the object has been stored, potentially in parallel with other blocks + on the . + + @param object An object to store in the cache. + @param key A key to associate with the object. This string will be copied. + @param cost An amount to add to the . + @param ageLimit The age limit (in seconds) to associate with the object. An age limit <= 0 means there is no object-level age limit and the cache-level TTL will be used for + this object. + @param block A block to be executed concurrently after the object has been stored, or nil. + */ +- (void)setObjectAsync:(id )object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block; + /** Removes the object for the specified key. This method returns immediately and executes the passed block as soon as the object has been removed. @@ -388,6 +448,8 @@ PIN_SUBCLASSING_RESTRICTED @param byteCount The cache will be trimmed equal to or smaller than this size. @param block A block to be executed serially after the cache has been trimmed, or nil. + + @note This will not remove objects that have been added via one of the @c -setObject:forKey:withAgeLimit methods. */ - (void)trimToSizeByDateAsync:(NSUInteger)byteCount completion:(nullable PINCacheBlock)block; @@ -451,6 +513,18 @@ PIN_SUBCLASSING_RESTRICTED */ - (void)setObject:(nullable id )object forKey:(NSString *)key; +/** + Stores an object in the cache for the specified key and age limit. This method blocks the calling thread until + the object has been stored. + + @see setObjectAsync:forKey:completion: + @param object An object to store in the cache. + @param key A key to associate with the object. This string will be copied. + @param ageLimit The age limit (in seconds) to associate with the object. An age limit <= 0 means there is + no object-level age limit and the cache-level TTL will be used for this object. + */ +- (void)setObject:(nullable id )object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit; + /** Removes objects from the cache, largest first, until the cache is equal to or smaller than the specified byteCount. This method blocks the calling thread until the cache has been trimmed. @@ -466,6 +540,8 @@ PIN_SUBCLASSING_RESTRICTED @see trimToSizeByDateAsync: @param byteCount The cache will be trimmed equal to or smaller than this size. + + @note This will not remove objects that have been added via one of the @c -setObject:forKey:withAgeLimit methods. */ - (void)trimToSizeByDate:(NSUInteger)byteCount; @@ -510,6 +586,7 @@ typedef void (^PINDiskCacheBlock)(PINDiskCache *cache); - (void)trimToSizeByDate:(NSUInteger)byteCount block:(nullable PINDiskCacheBlock)block __attribute__((deprecated)); - (void)removeAllObjects:(nullable PINDiskCacheBlock)block __attribute__((deprecated)); - (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block completionBlock:(nullable PINDiskCacheBlock)completionBlock __attribute__((deprecated)); +- (void)setTtlCache:(BOOL)ttlCache DEPRECATED_MSG_ATTRIBUTE("ttlCache is no longer a settable property and must now be set via initializer."); @end NS_ASSUME_NONNULL_END diff --git a/Example/Pods/PINCache/Source/PINDiskCache.m b/Example/Pods/PINCache/Source/PINDiskCache.m index a5a8e27..f30a5ad 100644 --- a/Example/Pods/PINCache/Source/PINDiskCache.m +++ b/Example/Pods/PINCache/Source/PINDiskCache.m @@ -9,8 +9,13 @@ #endif #import +#import +#if SWIFT_PACKAGE +@import PINOperation; +#else #import +#endif #define PINDiskCacheError(error) if (error) { NSLog(@"%@ (%d) ERROR: %@", \ [[NSString stringWithUTF8String:__FILE__] lastPathComponent], \ @@ -18,6 +23,10 @@ #define PINDiskCacheException(exception) if (exception) { NSAssert(NO, [exception reason]); } +const char * PINDiskCacheAgeLimitAttributeName = "com.pinterest.PINDiskCache.ageLimit"; +NSString * const PINDiskCacheErrorDomain = @"com.pinterest.PINDiskCache"; +NSErrorUserInfoKey const PINDiskCacheErrorReadFailureCodeKey = @"PINDiskCacheErrorReadFailureCodeKey"; +NSErrorUserInfoKey const PINDiskCacheErrorWriteFailureCodeKey = @"PINDiskCacheErrorWriteFailureCodeKey"; NSString * const PINDiskCachePrefix = @"com.pinterest.PINDiskCache"; static NSString * const PINDiskCacheSharedName = @"PINDiskCacheShared"; @@ -40,9 +49,25 @@ typedef NS_ENUM(NSUInteger, PINDiskCacheCondition) { return (result == NSOrderedDescending) ? newDate : existingDate; }; +const char * PINDiskCacheFileSystemRepresentation(NSURL *url) +{ +#ifdef __MAC_10_13 // Xcode >= 9 + // -fileSystemRepresentation is available on macOS >= 10.9 + if (@available(macOS 10.9, iOS 7.0, watchOS 2.0, tvOS 9.0, *)) { + return url.fileSystemRepresentation; + } +#endif + return [url.path cStringUsingEncoding:NSUTF8StringEncoding]; +} + @interface PINDiskCacheMetadata : NSObject -@property (nonatomic, strong) NSDate *date; +// When the object was added to the disk cache +@property (nonatomic, strong) NSDate *createdDate; +// Last time the object was accessed +@property (nonatomic, strong) NSDate *lastModifiedDate; @property (nonatomic, strong) NSNumber *size; +// Age limit is used in conjuction with ttl +@property (nonatomic) NSTimeInterval ageLimit; @end @interface PINDiskCache () { @@ -63,6 +88,7 @@ @interface PINDiskCache () { @property (assign, nonatomic) BOOL diskWritable; @property (assign, nonatomic) pthread_cond_t diskStateKnownCondition; @property (assign, nonatomic) BOOL diskStateKnown; +@property (assign, nonatomic) BOOL writingProtectionOptionSet; @end @implementation PINDiskCache @@ -81,6 +107,7 @@ @implementation PINDiskCache #if TARGET_OS_IPHONE @synthesize writingProtectionOption = _writingProtectionOption; +@synthesize writingProtectionOptionSet = _writingProtectionOptionSet; #endif #pragma mark - Initialization - @@ -88,7 +115,7 @@ @implementation PINDiskCache - (void)dealloc { __unused int result = pthread_mutex_destroy(&_mutex); - NSCAssert(result == 0, @"Failed to destroy lock in PINMemoryCache %p. Code: %d", (void *)self, result); + NSCAssert(result == 0, @"Failed to destroy lock in PINDiskCache %p. Code: %d", (void *)self, result); pthread_cond_destroy(&_diskWritableCondition); pthread_cond_destroy(&_diskStateKnownCondition); } @@ -142,23 +169,44 @@ - (instancetype)initWithName:(NSString *)name keyDecoder:(PINDiskCacheKeyDecoderBlock)keyDecoder operationQueue:(PINOperationQueue *)operationQueue { - if (!name) + return [self initWithName:name prefix:prefix + rootPath:rootPath + serializer:serializer + deserializer:deserializer + keyEncoder:keyEncoder + keyDecoder:keyDecoder + operationQueue:operationQueue + ttlCache:NO]; +} + +- (instancetype)initWithName:(NSString *)name + prefix:(NSString *)prefix + rootPath:(NSString *)rootPath + serializer:(PINDiskCacheSerializerBlock)serializer + deserializer:(PINDiskCacheDeserializerBlock)deserializer + keyEncoder:(PINDiskCacheKeyEncoderBlock)keyEncoder + keyDecoder:(PINDiskCacheKeyDecoderBlock)keyDecoder + operationQueue:(PINOperationQueue *)operationQueue + ttlCache:(BOOL)ttlCache +{ + if (!name) { return nil; - + } NSAssert(((!serializer && !deserializer) || (serializer && deserializer)), @"PINDiskCache must be initialized with a serializer AND deserializer."); NSAssert(((!keyEncoder && !keyDecoder) || (keyEncoder && keyDecoder)), - @"PINDiskCache must be initialized with a encoder AND decoder."); + @"PINDiskCache must be initialized with an encoder AND decoder."); if (self = [super init]) { __unused int result = pthread_mutex_init(&_mutex, NULL); - NSAssert(result == 0, @"Failed to init lock in PINMemoryCache %@. Code: %d", self, result); + NSAssert(result == 0, @"Failed to init lock in PINDiskCache %@. Code: %d", self, result); _name = [name copy]; _prefix = [prefix copy]; _operationQueue = operationQueue; + _ttlCache = ttlCache; _willAddObjectBlock = nil; _willRemoveObjectBlock = nil; _willRemoveAllObjectsBlock = nil; @@ -174,7 +222,9 @@ - (instancetype)initWithName:(NSString *)name _ageLimit = 60 * 60 * 24 * 30; #if TARGET_OS_IPHONE - _writingProtectionOption = NSDataWritingFileProtectionNone; + _writingProtectionOptionSet = NO; + // This is currently the default for files, but we'd rather not write it if it's unspecified. + _writingProtectionOption = NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication; #endif _metadata = [[NSMutableDictionary alloc] init]; @@ -224,7 +274,7 @@ - (instancetype)initWithName:(NSString *)name - (NSString *)description { - return [[NSString alloc] initWithFormat:@"%@.%@.%p", PINDiskCachePrefix, _name, (void *)self]; + return [[NSString alloc] initWithFormat:@"%@.%@.%p", PINDiskCachePrefix, _name, (__bridge void *)self]; } + (PINDiskCache *)sharedCache @@ -279,7 +329,14 @@ - (NSString *)decodedString:(NSString *)string - (PINDiskCacheSerializerBlock)defaultSerializer { return ^NSData*(id object, NSString *key){ - return [NSKeyedArchiver archivedDataWithRootObject:object]; + if (@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) { + NSError *error = nil; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&error]; + PINDiskCacheError(error); + return data; + } else { + return [NSKeyedArchiver archivedDataWithRootObject:object]; + } }; } @@ -446,16 +503,72 @@ - (BOOL)_locked_createCacheDirectory return created; } ++ (NSArray *)resourceKeys +{ + static NSArray *resourceKeys = nil; + static dispatch_once_t predicate; + + dispatch_once(&predicate, ^{ + resourceKeys = @[ NSURLCreationDateKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey ]; + }); + + return resourceKeys; +} + +/** + * @return File size in bytes. + */ +- (NSUInteger)_locked_initializeDiskPropertiesForFile:(NSURL *)fileURL fileKey:(NSString *)fileKey +{ + NSError *error = nil; + + NSDictionary *dictionary = [fileURL resourceValuesForKeys:[PINDiskCache resourceKeys] error:&error]; + PINDiskCacheError(error); + + if (_metadata[fileKey] == nil) { + _metadata[fileKey] = [[PINDiskCacheMetadata alloc] init]; + } + + NSDate *createdDate = dictionary[NSURLCreationDateKey]; + if (createdDate && fileKey) + _metadata[fileKey].createdDate = createdDate; + + NSDate *lastModifiedDate = dictionary[NSURLContentModificationDateKey]; + if (lastModifiedDate && fileKey) + _metadata[fileKey].lastModifiedDate = lastModifiedDate; + + NSNumber *fileSize = dictionary[NSURLTotalFileAllocatedSizeKey]; + if (fileSize) { + _metadata[fileKey].size = fileSize; + } + + if (_ttlCache) { + NSTimeInterval ageLimit; + ssize_t res = getxattr(PINDiskCacheFileSystemRepresentation(fileURL), PINDiskCacheAgeLimitAttributeName, &ageLimit, sizeof(NSTimeInterval), 0, 0); + if(res > 0) { + _metadata[fileKey].ageLimit = ageLimit; + } else if (res == -1) { + // Ignore if the extended attribute was never recorded for this file. + if (errno != ENOATTR) { + NSDictionary *userInfo = @{ PINDiskCacheErrorReadFailureCodeKey : @(errno)}; + error = [NSError errorWithDomain:PINDiskCacheErrorDomain code:PINDiskCacheErrorReadFailure userInfo:userInfo]; + PINDiskCacheError(error); + } + } + } + + return [fileSize unsignedIntegerValue]; +} + - (void)initializeDiskProperties { NSUInteger byteCount = 0; - NSArray *keys = @[ NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey ]; - + NSError *error = nil; [self lock]; NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:_cacheURL - includingPropertiesForKeys:keys + includingPropertiesForKeys:[PINDiskCache resourceKeys] options:NSDirectoryEnumerationSkipsHiddenFiles error:&error]; [self unlock]; @@ -463,28 +576,12 @@ - (void)initializeDiskProperties PINDiskCacheError(error); for (NSURL *fileURL in files) { - NSString *key = [self keyForEncodedFileURL:fileURL]; - - error = nil; - + NSString *fileKey = [self keyForEncodedFileURL:fileURL]; // Continually grab and release lock while processing files to avoid contention [self lock]; - NSDictionary *dictionary = [fileURL resourceValuesForKeys:keys error:&error]; - PINDiskCacheError(error); - - if (_metadata[key] == nil) { - _metadata[key] = [[PINDiskCacheMetadata alloc] init]; - } - - NSDate *date = [dictionary objectForKey:NSURLContentModificationDateKey]; - if (date && key) - _metadata[key].date = date; - - NSNumber *fileSize = [dictionary objectForKey:NSURLTotalFileAllocatedSizeKey]; - if (fileSize) { - _metadata[key].size = fileSize; - byteCount += [fileSize unsignedIntegerValue]; - } + if (_metadata[fileKey] == nil) { + byteCount += [self _locked_initializeDiskPropertiesForFile:fileURL fileKey:fileKey]; + } [self unlock]; } @@ -494,6 +591,9 @@ - (void)initializeDiskProperties if (self->_byteLimit > 0 && self->_byteCount > self->_byteLimit) [self trimToSizeByDateAsync:self->_byteLimit completion:nil]; + + if (self->_ttlCache) + [self removeExpiredObjectsAsync:nil]; _diskStateKnown = YES; pthread_cond_broadcast(&_diskStateKnownCondition); @@ -521,28 +621,67 @@ - (BOOL)_locked_setFileModificationDate:(NSDate *)date forURL:(NSURL *)fileURL error:&error]; PINDiskCacheError(error); - if (success) { + return success; +} + +- (void)asynchronouslySetAgeLimit:(NSTimeInterval)ageLimit forURL:(NSURL *)fileURL +{ + [self.operationQueue scheduleOperation:^{ + [self lockForWriting]; + [self _locked_setAgeLimit:ageLimit forURL:fileURL]; + [self unlock]; + } withPriority:PINOperationQueuePriorityLow]; +} + +- (BOOL)_locked_setAgeLimit:(NSTimeInterval)ageLimit forURL:(NSURL *)fileURL +{ + if (!fileURL) { + return NO; + } + + NSError *error = nil; + if (ageLimit <= 0.0) { + if (removexattr(PINDiskCacheFileSystemRepresentation(fileURL), PINDiskCacheAgeLimitAttributeName, 0) != 0) { + // Ignore if the extended attribute was never recorded for this file. + if (errno != ENOATTR) { + NSDictionary *userInfo = @{ PINDiskCacheErrorWriteFailureCodeKey : @(errno)}; + error = [NSError errorWithDomain:PINDiskCacheErrorDomain code:PINDiskCacheErrorWriteFailure userInfo:userInfo]; + PINDiskCacheError(error); + } + } + } else { + if (setxattr(PINDiskCacheFileSystemRepresentation(fileURL), PINDiskCacheAgeLimitAttributeName, &ageLimit, sizeof(NSTimeInterval), 0, 0) != 0) { + NSDictionary *userInfo = @{ PINDiskCacheErrorWriteFailureCodeKey : @(errno)}; + error = [NSError errorWithDomain:PINDiskCacheErrorDomain code:PINDiskCacheErrorWriteFailure userInfo:userInfo]; + PINDiskCacheError(error); + } + } + + if (!error) { NSString *key = [self keyForEncodedFileURL:fileURL]; if (key) { - _metadata[key].date = date; + _metadata[key].ageLimit = ageLimit; } } - - return success; + + return !error; } - (BOOL)removeFileAndExecuteBlocksForKey:(NSString *)key { NSURL *fileURL = [self encodedFileURLForKey:key]; - + if (!fileURL) { + return NO; + } + // We only need to lock until writable at the top because once writable, always writable [self lockForWriting]; - if (!fileURL || ![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) { + if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) { [self unlock]; return NO; } - PINCacheObjectBlock willRemoveObjectBlock = _willRemoveObjectBlock; + PINDiskCacheObjectBlock willRemoveObjectBlock = _willRemoveObjectBlock; if (willRemoveObjectBlock) { [self unlock]; willRemoveObjectBlock(self, key, nil); @@ -563,7 +702,7 @@ - (BOOL)removeFileAndExecuteBlocksForKey:(NSString *)key [_metadata removeObjectForKey:key]; - PINCacheObjectBlock didRemoveObjectBlock = _didRemoveObjectBlock; + PINDiskCacheObjectBlock didRemoveObjectBlock = _didRemoveObjectBlock; if (didRemoveObjectBlock) { [self unlock]; _didRemoveObjectBlock(self, key, nil); @@ -577,74 +716,98 @@ - (BOOL)removeFileAndExecuteBlocksForKey:(NSString *)key - (void)trimDiskToSize:(NSUInteger)trimByteCount { + NSMutableArray *keysToRemove = nil; + [self lockForWriting]; if (_byteCount > trimByteCount) { + keysToRemove = [[NSMutableArray alloc] init]; + NSArray *keysSortedBySize = [_metadata keysSortedByValueUsingComparator:^NSComparisonResult(PINDiskCacheMetadata * _Nonnull obj1, PINDiskCacheMetadata * _Nonnull obj2) { return [obj1.size compare:obj2.size]; }]; + NSUInteger bytesSaved = 0; for (NSString *key in [keysSortedBySize reverseObjectEnumerator]) { // largest objects first - [self unlock]; - - //unlock, removeFileAndExecuteBlocksForKey handles locking itself - [self removeFileAndExecuteBlocksForKey:key]; - - [self lock]; - - if (_byteCount <= trimByteCount) + [keysToRemove addObject:key]; + NSNumber *byteSize = _metadata[key].size; + if (byteSize) { + bytesSaved += [byteSize unsignedIntegerValue]; + } + if (_byteCount - bytesSaved <= trimByteCount) { break; + } } } [self unlock]; + + for (NSString *key in keysToRemove) { + [self removeFileAndExecuteBlocksForKey:key]; + } } +// This is the default trimming method which happens automatically - (void)trimDiskToSizeByDate:(NSUInteger)trimByteCount { + if (self.isTTLCache) { + [self removeExpiredObjects]; + } + + NSMutableArray *keysToRemove = nil; + [self lockForWriting]; if (_byteCount > trimByteCount) { - NSArray *keysSortedByDate = [_metadata keysSortedByValueUsingComparator:^NSComparisonResult(PINDiskCacheMetadata * _Nonnull obj1, PINDiskCacheMetadata * _Nonnull obj2) { - return [obj1.date compare:obj2.date]; + keysToRemove = [[NSMutableArray alloc] init]; + + // last modified represents last access. + NSArray *keysSortedByLastModifiedDate = [_metadata keysSortedByValueUsingComparator:^NSComparisonResult(PINDiskCacheMetadata * _Nonnull obj1, PINDiskCacheMetadata * _Nonnull obj2) { + return [obj1.lastModifiedDate compare:obj2.lastModifiedDate]; }]; - for (NSString *key in keysSortedByDate) { // oldest objects first - [self unlock]; - - //unlock, removeFileAndExecuteBlocksForKey handles locking itself - [self removeFileAndExecuteBlocksForKey:key]; - - [self lock]; - - if (_byteCount <= trimByteCount) + NSUInteger bytesSaved = 0; + // objects accessed last first. + for (NSString *key in keysSortedByLastModifiedDate) { + [keysToRemove addObject:key]; + NSNumber *byteSize = _metadata[key].size; + if (byteSize) { + bytesSaved += [byteSize unsignedIntegerValue]; + } + if (_byteCount - bytesSaved <= trimByteCount) { break; + } } } [self unlock]; + + for (NSString *key in keysToRemove) { + [self removeFileAndExecuteBlocksForKey:key]; + } } - (void)trimDiskToDate:(NSDate *)trimDate { [self lockForWriting]; - NSArray *keysSortedByDate = [_metadata keysSortedByValueUsingComparator:^NSComparisonResult(PINDiskCacheMetadata * _Nonnull obj1, PINDiskCacheMetadata * _Nonnull obj2) { - return [obj1.date compare:obj2.date]; + NSArray *keysSortedByCreatedDate = [_metadata keysSortedByValueUsingComparator:^NSComparisonResult(PINDiskCacheMetadata * _Nonnull obj1, PINDiskCacheMetadata * _Nonnull obj2) { + return [obj1.createdDate compare:obj2.createdDate]; }]; + + NSMutableArray *keysToRemove = [[NSMutableArray alloc] init]; - for (NSString *key in keysSortedByDate) { // oldest files first - NSDate *accessDate = _metadata[key].date; - if (!accessDate) + for (NSString *key in keysSortedByCreatedDate) { // oldest files first + NSDate *createdDate = _metadata[key].createdDate; + if (!createdDate || _metadata[key].ageLimit > 0.0) continue; - if ([accessDate compare:trimDate] == NSOrderedAscending) { // older than trim date - [self unlock]; - - //unlock, removeFileAndExecuteBlocksForKey handles locking itself - [self removeFileAndExecuteBlocksForKey:key]; - - [self lock]; + if ([createdDate compare:trimDate] == NSOrderedAscending) { // older than trim date + [keysToRemove addObject:key]; } else { break; } } [self unlock]; + + for (NSString *key in keysToRemove) { + [self removeFileAndExecuteBlocksForKey:key]; + } } - (void)trimToAgeLimitRecursively @@ -656,13 +819,24 @@ - (void)trimToAgeLimitRecursively return; NSDate *date = [[NSDate alloc] initWithTimeIntervalSinceNow:-ageLimit]; - [self trimDiskToDate:date]; + [self trimToDateAsync:date completion:nil]; - dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_ageLimit * NSEC_PER_SEC)); + dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(ageLimit * NSEC_PER_SEC)); dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { - [self.operationQueue scheduleOperation:^{ - [self trimToAgeLimitRecursively]; - } withPriority:PINOperationQueuePriorityLow]; + // Ensure that ageLimit is the same as when we were scheduled, otherwise, we've been + // rescheduled (another dispatch_after was issued) and should cancel. + BOOL shouldReschedule = YES; + [self lock]; + if (ageLimit != self->_ageLimit) { + shouldReschedule = NO; + } + [self unlock]; + + if (shouldReschedule) { + [self.operationQueue scheduleOperation:^{ + [self trimToAgeLimitRecursively]; + } withPriority:PINOperationQueuePriorityLow]; + } }); } @@ -717,10 +891,15 @@ - (void)fileURLForKeyAsync:(NSString *)key completion:(PINDiskCacheFileURLBlock) } - (void)setObjectAsync:(id )object forKey:(NSString *)key completion:(PINDiskCacheObjectBlock)block +{ + [self setObjectAsync:object forKey:key withAgeLimit:0.0 completion:(PINDiskCacheObjectBlock)block]; +} + +- (void)setObjectAsync:(id )object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(nullable PINDiskCacheObjectBlock)block { [self.operationQueue scheduleOperation:^{ NSURL *fileURL = nil; - [self setObject:object forKey:key fileURL:&fileURL]; + [self setObject:object forKey:key withAgeLimit:ageLimit fileURL:&fileURL]; if (block) { block(self, key, object); @@ -733,6 +912,11 @@ - (void)setObjectAsync:(id )object forKey:(NSString *)key withCost:(NS [self setObjectAsync:object forKey:key completion:(PINDiskCacheObjectBlock)block]; } +- (void)setObjectAsync:(id )object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(nullable PINCacheObjectBlock)block +{ + [self setObjectAsync:object forKey:key withAgeLimit:ageLimit completion:(PINDiskCacheObjectBlock)block]; +} + - (void)removeObjectForKeyAsync:(NSString *)key completion:(PINDiskCacheObjectBlock)block { [self.operationQueue scheduleOperation:^{ @@ -808,6 +992,17 @@ - (void)trimToSizeByDateAsync:(NSUInteger)trimByteCount completion:(PINCacheBloc completion:completion]; } +- (void)removeExpiredObjectsAsync:(PINCacheBlock)block +{ + [self.operationQueue scheduleOperation:^{ + [self removeExpiredObjects]; + + if (block) { + block(self); + } + } withPriority:PINOperationQueuePriorityLow]; +} + - (void)removeAllObjectsAsync:(PINCacheBlock)block { [self.operationQueue scheduleOperation:^{ @@ -832,7 +1027,7 @@ - (void)enumerateObjectsWithBlockAsync:(PINDiskCacheFileURLEnumerationBlock)bloc #pragma mark - Public Synchronous Methods - -- (void)synchronouslyLockFileAccessWhileExecutingBlock:(PINCacheBlock)block +- (void)synchronouslyLockFileAccessWhileExecutingBlock:(PIN_NOESCAPE PINCacheBlock)block { if (block) { [self lockForWriting]; @@ -845,8 +1040,13 @@ - (BOOL)containsObjectForKey:(NSString *)key { [self lock]; if (_metadata[key] != nil || _diskStateKnown == NO) { + BOOL objectExpired = NO; + if (self->_ttlCache && _metadata[key].createdDate != nil) { + NSTimeInterval ageLimit = _metadata[key].ageLimit > 0.0 ? _metadata[key].ageLimit : self->_ageLimit; + objectExpired = ageLimit > 0 && fabs([_metadata[key].createdDate timeIntervalSinceDate:[NSDate date]]) > ageLimit; + } [self unlock]; - return ([self fileURLForKey:key updateFileModificationDate:NO] != nil); + return (!objectExpired && [self fileURLForKey:key updateFileModificationDate:NO] != nil); } [self unlock]; return NO; @@ -874,15 +1074,19 @@ - (id)objectForKeyedSubscript:(NSString *)key id object = nil; NSURL *fileURL = [self encodedFileURLForKey:key]; - NSDate *now = [[NSDate alloc] init]; + NSDate *now = [NSDate date]; [self lock]; if (self->_ttlCache) { - // We actually need to know the entire disk state if we're a TTL cache. - [self unlock]; - [self lockAndWaitForKnownState]; + if (!_diskStateKnown) { + if (_metadata[key] == nil) { + NSString *fileKey = [self keyForEncodedFileURL:fileURL]; + [self _locked_initializeDiskPropertiesForFile:fileURL fileKey:fileKey]; + } + } } - - if (!self->_ttlCache || self->_ageLimit <= 0 || fabs([_metadata[key].date timeIntervalSinceDate:now]) < self->_ageLimit) { + + NSTimeInterval ageLimit = _metadata[key].ageLimit > 0.0 ? _metadata[key].ageLimit : self->_ageLimit; + if (!self->_ttlCache || ageLimit <= 0 || fabs([_metadata[key].createdDate timeIntervalSinceDate:now]) < ageLimit) { // If the cache should behave like a TTL cache, then only fetch the object if there's a valid ageLimit and the object is still alive NSData *objectData = [[NSData alloc] initWithContentsOfFile:[fileURL path]]; @@ -903,7 +1107,8 @@ - (id)objectForKeyedSubscript:(NSString *)key } [self lock]; } - if (object && !self->_ttlCache) { + if (object) { + _metadata[key].lastModifiedDate = now; [self asynchronouslySetFileModificationDate:now forURL:fileURL]; } } @@ -929,12 +1134,13 @@ - (NSURL *)fileURLForKey:(NSString *)key updateFileModificationDate:(BOOL)update return nil; } - NSDate *now = [[NSDate alloc] init]; + NSDate *now = [NSDate date]; NSURL *fileURL = [self encodedFileURLForKey:key]; [self lockForWriting]; if (fileURL.path && [[NSFileManager defaultManager] fileExistsAtPath:fileURL.path]) { if (updateFileModificationDate) { + _metadata[key].lastModifiedDate = now; [self asynchronouslySetFileModificationDate:now forURL:fileURL]; } } else { @@ -946,7 +1152,17 @@ - (NSURL *)fileURLForKey:(NSString *)key updateFileModificationDate:(BOOL)update - (void)setObject:(id )object forKey:(NSString *)key { - [self setObject:object forKey:key fileURL:nil]; + [self setObject:object forKey:key withAgeLimit:0.0]; +} + +- (void)setObject:(id )object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit +{ + [self setObject:object forKey:key withAgeLimit:ageLimit fileURL:nil]; +} + +- (void)setObject:(id )object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit +{ + [self setObject:object forKey:key withAgeLimit:ageLimit]; } - (void)setObject:(id )object forKey:(NSString *)key withCost:(NSUInteger)cost @@ -963,15 +1179,18 @@ - (void)setObject:(id)object forKeyedSubscript:(NSString *)key } } -- (void)setObject:(id )object forKey:(NSString *)key fileURL:(NSURL **)outFileURL +- (void)setObject:(id )object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit fileURL:(NSURL **)outFileURL { + NSAssert(ageLimit <= 0.0 || (ageLimit > 0.0 && _ttlCache), @"ttlCache must be set to YES if setting an object-level age limit."); + if (!key || !object) return; + NSDataWritingOptions writeOptions = NSDataWritingAtomic; #if TARGET_OS_IPHONE - NSDataWritingOptions writeOptions = NSDataWritingAtomic | self.writingProtectionOption; - #else - NSDataWritingOptions writeOptions = NSDataWritingAtomic; + if (self.writingProtectionOptionSet) { + writeOptions |= self.writingProtectionOption; + } #endif // Remain unlocked here so that we're not locked while serializing. @@ -992,7 +1211,7 @@ - (void)setObject:(id )object forKey:(NSString *)key fileURL:(NSURL ** } [self lockForWriting]; - PINCacheObjectBlock willAddObjectBlock = self->_willAddObjectBlock; + PINDiskCacheObjectBlock willAddObjectBlock = self->_willAddObjectBlock; if (willAddObjectBlock) { [self unlock]; willAddObjectBlock(self, key, object); @@ -1009,7 +1228,7 @@ - (void)setObject:(id )object forKey:(NSString *)key fileURL:(NSURL ** } NSError *error = nil; - NSDictionary *values = [fileURL resourceValuesForKeys:@[ NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey ] error:&error]; + NSDictionary *values = [fileURL resourceValuesForKeys:@[ NSURLCreationDateKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey ] error:&error]; PINDiskCacheError(error); NSNumber *diskFileSize = [values objectForKey:NSURLTotalFileAllocatedSizeKey]; @@ -1021,18 +1240,22 @@ - (void)setObject:(id )object forKey:(NSString *)key fileURL:(NSURL ** self->_metadata[key].size = diskFileSize; self.byteCount = self->_byteCount + [diskFileSize unsignedIntegerValue]; // atomic } - NSDate *date = [values objectForKey:NSURLContentModificationDateKey]; - if (date) { - self->_metadata[key].date = date; + NSDate *createdDate = [values objectForKey:NSURLCreationDateKey]; + if (createdDate) { + self->_metadata[key].createdDate = createdDate; } - + NSDate *lastModifiedDate = [values objectForKey:NSURLContentModificationDateKey]; + if (lastModifiedDate) { + self->_metadata[key].lastModifiedDate = lastModifiedDate; + } + [self asynchronouslySetAgeLimit:ageLimit forURL:fileURL]; if (self->_byteLimit > 0 && self->_byteCount > self->_byteLimit) [self trimToSizeByDateAsync:self->_byteLimit completion:nil]; } else { fileURL = nil; } - PINCacheObjectBlock didAddObjectBlock = self->_didAddObjectBlock; + PINDiskCacheObjectBlock didAddObjectBlock = self->_didAddObjectBlock; if (didAddObjectBlock) { [self unlock]; didAddObjectBlock(self, key, object); @@ -1099,6 +1322,26 @@ - (void)trimToSizeByDate:(NSUInteger)trimByteCount [self trimDiskToSizeByDate:trimByteCount]; } +- (void)removeExpiredObjects +{ + [self lockForWriting]; + NSDate *now = [NSDate date]; + NSMutableArray *expiredObjectKeys = [NSMutableArray array]; + [_metadata enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, PINDiskCacheMetadata * _Nonnull obj, BOOL * _Nonnull stop) { + NSTimeInterval ageLimit = obj.ageLimit > 0.0 ? obj.ageLimit : self->_ageLimit; + NSDate *expirationDate = [obj.createdDate dateByAddingTimeInterval:ageLimit]; + if ([expirationDate compare:now] == NSOrderedAscending) { // Expiration date has passed + [expiredObjectKeys addObject:key]; + } + }]; + [self unlock]; + + for (NSString *key in expiredObjectKeys) { + //unlock, removeFileAndExecuteBlocksForKey handles locking itself + [self removeFileAndExecuteBlocksForKey:key]; + } +} + - (void)removeAllObjects { // We don't need to know the disk state since we're just going to remove everything. @@ -1128,7 +1371,7 @@ - (void)removeAllObjects [self unlock]; } -- (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLEnumerationBlock)block +- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINDiskCacheFileURLEnumerationBlock)block { if (!block) return; @@ -1139,8 +1382,9 @@ - (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLEnumerationBlock)block for (NSString *key in _metadata) { NSURL *fileURL = [self encodedFileURLForKey:key]; // If the cache should behave like a TTL cache, then only fetch the object if there's a valid ageLimit and the object is still alive - NSDate *date = _metadata[key].date; - if (!self->_ttlCache || self->_ageLimit <= 0 || (date && fabs([date timeIntervalSinceDate:now]) < self->_ageLimit)) { + NSDate *createdDate = _metadata[key].createdDate; + NSTimeInterval ageLimit = _metadata[key].ageLimit > 0.0 ? _metadata[key].ageLimit : self->_ageLimit; + if (!self->_ttlCache || ageLimit <= 0 || (createdDate && fabs([createdDate timeIntervalSinceDate:now]) < ageLimit)) { BOOL stop = NO; block(key, fileURL, &stop); if (stop) @@ -1313,11 +1557,14 @@ - (void)setAgeLimit:(NSTimeInterval)ageLimit self->_ageLimit = ageLimit; [self unlock]; - [self trimToAgeLimitRecursively]; + [self.operationQueue scheduleOperation:^{ + [self trimToAgeLimitRecursively]; + } withPriority:PINOperationQueuePriorityLow]; } withPriority:PINOperationQueuePriorityHigh]; } -- (BOOL)isTTLCache { +- (BOOL)isTTLCache +{ BOOL isTTLCache; [self lock]; @@ -1327,16 +1574,9 @@ - (BOOL)isTTLCache { return isTTLCache; } -- (void)setTtlCache:(BOOL)ttlCache { - [self.operationQueue scheduleOperation:^{ - [self lock]; - self->_ttlCache = ttlCache; - [self unlock]; - } withPriority:PINOperationQueuePriorityHigh]; -} - #if TARGET_OS_IPHONE -- (NSDataWritingOptions)writingProtectionOption { +- (NSDataWritingOptions)writingProtectionOption +{ NSDataWritingOptions option; [self lock]; @@ -1346,13 +1586,15 @@ - (NSDataWritingOptions)writingProtectionOption { return option; } -- (void)setWritingProtectionOption:(NSDataWritingOptions)writingProtectionOption { +- (void)setWritingProtectionOption:(NSDataWritingOptions)writingProtectionOption +{ [self.operationQueue scheduleOperation:^{ - NSDataWritingOptions option = NSDataWritingFileProtectionMask & writingProtectionOption; + NSDataWritingOptions option = NSDataWritingFileProtectionMask & writingProtectionOption; - [self lock]; - self->_writingProtectionOption = option; - [self unlock]; + [self lock]; + self->_writingProtectionOptionSet = YES; + self->_writingProtectionOption = option; + [self unlock]; } withPriority:PINOperationQueuePriorityHigh]; } #endif @@ -1361,7 +1603,7 @@ - (void)lockForWriting { [self lock]; - // spinlock if the disk isn't writable + // Lock if the disk isn't writable. if (_diskWritable == NO) { pthread_cond_wait(&_diskWritableCondition, &_mutex); } @@ -1371,7 +1613,7 @@ - (void)lockAndWaitForKnownState { [self lock]; - // spinlock if the disk state isn't known + // Lock if the disk state isn't known. if (_diskStateKnown == NO) { pthread_cond_wait(&_diskStateKnownCondition, &_mutex); } @@ -1425,29 +1667,58 @@ - (void)removeObjectForKey:(NSString *)key block:(nullable PINDiskCacheObjectBlo - (void)trimToDate:(NSDate *)date block:(nullable PINDiskCacheBlock)block { - [self trimToDateAsync:date completion:block]; + [self trimToDateAsync:date completion:^(id diskCache) { + if (block) { + block((PINDiskCache *)diskCache); + } + }]; } - (void)trimToSize:(NSUInteger)byteCount block:(nullable PINDiskCacheBlock)block { - [self trimToSizeAsync:byteCount completion:block]; + [self trimToSizeAsync:byteCount completion:^(id diskCache) { + if (block) { + block((PINDiskCache *)diskCache); + } + }]; } - (void)trimToSizeByDate:(NSUInteger)byteCount block:(nullable PINDiskCacheBlock)block { - [self trimToSizeAsync:byteCount completion:block]; + [self trimToSizeAsync:byteCount completion:^(id diskCache) { + if (block) { + block((PINDiskCache *)diskCache); + } + }]; } - (void)removeAllObjects:(nullable PINDiskCacheBlock)block { - [self removeAllObjectsAsync:block]; + [self removeAllObjectsAsync:^(id diskCache) { + if (block) { + block((PINDiskCache *)diskCache); + } + }]; } - (void)enumerateObjectsWithBlock:(PINDiskCacheFileURLBlock)block completionBlock:(nullable PINDiskCacheBlock)completionBlock { [self enumerateObjectsWithBlockAsync:^(NSString * _Nonnull key, NSURL * _Nullable fileURL, BOOL * _Nonnull stop) { block(key, fileURL); - } completionBlock:completionBlock]; + } completionBlock:^(id diskCache) { + if (completionBlock) { + completionBlock((PINDiskCache *)diskCache); + } + }]; +} + +- (void)setTtlCache:(BOOL)ttlCache +{ + [self.operationQueue scheduleOperation:^{ + [self lock]; + self->_ttlCache = ttlCache; + [self unlock]; + } withPriority:PINOperationQueuePriorityHigh]; } @end diff --git a/Example/Pods/PINCache/Source/PINMemoryCache.h b/Example/Pods/PINCache/Source/PINMemoryCache.h index 5eee26a..1cf9ff8 100644 --- a/Example/Pods/PINCache/Source/PINMemoryCache.h +++ b/Example/Pods/PINCache/Source/PINMemoryCache.h @@ -4,9 +4,9 @@ #import -#import -#import -#import +#import "PINCacheMacros.h" +#import "PINCaching.h" +#import "PINCacheObjectSubscripting.h" NS_ASSUME_NONNULL_BEGIN @@ -61,8 +61,11 @@ PIN_SUBCLASSING_RESTRICTED - When attempting to access an object in the cache that has lived longer than self.ageLimit, the cache will behave as if the object does not exist + @note If an object-level age limit is set via one of the @c -setObject:forKey:withAgeLimit methods, + that age limit overrides self.ageLimit. The overridden object age limit could be greater or + less than self.agelimit but must be greater than zero. */ -@property (nonatomic, assign, getter=isTTLCache) BOOL ttlCache; +@property (nonatomic, readonly, getter=isTTLCache) BOOL ttlCache; /** When `YES` on iOS the cache will remove all objects when the app receives a memory warning. @@ -145,7 +148,9 @@ PIN_SUBCLASSING_RESTRICTED - (instancetype)initWithOperationQueue:(PINOperationQueue *)operationQueue; -- (instancetype)initWithName:(NSString *)name operationQueue:(PINOperationQueue *)operationQueue NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithName:(NSString *)name operationQueue:(PINOperationQueue *)operationQueue; + +- (instancetype)initWithName:(NSString *)name operationQueue:(PINOperationQueue *)operationQueue ttlCache:(BOOL)ttlCache NS_DESIGNATED_INITIALIZER; #pragma mark - Asynchronous Methods /// @name Asynchronous Methods @@ -234,6 +239,7 @@ typedef void (^PINMemoryCacheContainmentBlock)(BOOL containsObject); - (void)trimToCostByDate:(NSUInteger)cost block:(nullable PINMemoryCacheBlock)block __attribute__((deprecated)); - (void)removeAllObjects:(nullable PINMemoryCacheBlock)block __attribute__((deprecated)); - (void)enumerateObjectsWithBlock:(PINMemoryCacheObjectBlock)block completionBlock:(nullable PINMemoryCacheBlock)completionBlock __attribute__((deprecated)); +- (void)setTtlCache:(BOOL)ttlCache DEPRECATED_MSG_ATTRIBUTE("ttlCache is no longer a settable property and must now be set via initializer."); @end NS_ASSUME_NONNULL_END diff --git a/Example/Pods/PINCache/Source/PINMemoryCache.m b/Example/Pods/PINCache/Source/PINMemoryCache.m index 21e4a60..85c45f5 100644 --- a/Example/Pods/PINCache/Source/PINMemoryCache.m +++ b/Example/Pods/PINCache/Source/PINMemoryCache.m @@ -5,7 +5,12 @@ #import "PINMemoryCache.h" #import + +#if SWIFT_PACKAGE +@import PINOperation; +#else #import +#endif #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0 #import @@ -19,8 +24,10 @@ @interface PINMemoryCache () @property (strong, nonatomic) PINOperationQueue *operationQueue; @property (assign, nonatomic) pthread_mutex_t mutex; @property (strong, nonatomic) NSMutableDictionary *dictionary; -@property (strong, nonatomic) NSMutableDictionary *dates; +@property (strong, nonatomic) NSMutableDictionary *createdDates; +@property (strong, nonatomic) NSMutableDictionary *accessDates; @property (strong, nonatomic) NSMutableDictionary *costs; +@property (strong, nonatomic) NSMutableDictionary *ageLimits; @end @implementation PINMemoryCache @@ -60,6 +67,11 @@ - (instancetype)initWithOperationQueue:(PINOperationQueue *)operationQueue } - (instancetype)initWithName:(NSString *)name operationQueue:(PINOperationQueue *)operationQueue +{ + return [self initWithName:name operationQueue:operationQueue ttlCache:NO]; +} + +- (instancetype)initWithName:(NSString *)name operationQueue:(PINOperationQueue *)operationQueue ttlCache:(BOOL)ttlCache { if (self = [super init]) { __unused int result = pthread_mutex_init(&_mutex, NULL); @@ -67,10 +79,13 @@ - (instancetype)initWithName:(NSString *)name operationQueue:(PINOperationQueue _name = [name copy]; _operationQueue = operationQueue; + _ttlCache = ttlCache; _dictionary = [[NSMutableDictionary alloc] init]; - _dates = [[NSMutableDictionary alloc] init]; + _createdDates = [[NSMutableDictionary alloc] init]; + _accessDates = [[NSMutableDictionary alloc] init]; _costs = [[NSMutableDictionary alloc] init]; + _ageLimits = [[NSMutableDictionary alloc] init]; _willAddObjectBlock = nil; _willRemoveObjectBlock = nil; @@ -120,8 +135,11 @@ + (PINMemoryCache *)sharedCache #pragma mark - Private Methods - - (void)didReceiveMemoryWarningNotification:(NSNotification *)notification { - if (self.removeAllObjectsOnMemoryWarning) + if (self.removeAllObjectsOnMemoryWarning) { [self removeAllObjectsAsync:nil]; + } else { + [self removeExpiredObjects]; + } [self.operationQueue scheduleOperation:^{ [self lock]; @@ -165,8 +183,10 @@ - (void)removeObjectAndExecuteBlocksForKey:(NSString *)key _totalCost -= [cost unsignedIntegerValue]; [_dictionary removeObjectForKey:key]; - [_dates removeObjectForKey:key]; + [_createdDates removeObjectForKey:key]; + [_accessDates removeObjectForKey:key]; [_costs removeObjectForKey:key]; + [_ageLimits removeObjectForKey:key]; [self unlock]; if (didRemoveObjectBlock) @@ -176,19 +196,39 @@ - (void)removeObjectAndExecuteBlocksForKey:(NSString *)key - (void)trimMemoryToDate:(NSDate *)trimDate { [self lock]; - NSArray *keysSortedByDate = [_dates keysSortedByValueUsingSelector:@selector(compare:)]; - NSDictionary *dates = [_dates copy]; + NSDictionary *createdDates = [_createdDates copy]; + NSDictionary *ageLimits = [_ageLimits copy]; [self unlock]; - for (NSString *key in keysSortedByDate) { // oldest objects first - NSDate *accessDate = dates[key]; - if (!accessDate) + [createdDates enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSDate * _Nonnull createdDate, BOOL * _Nonnull stop) { + NSTimeInterval ageLimit = [ageLimits[key] doubleValue]; + if (!createdDate || ageLimit > 0.0) { + return; + } + if ([createdDate compare:trimDate] == NSOrderedAscending) { // older than trim date + [self removeObjectAndExecuteBlocksForKey:key]; + } + }]; +} + +- (void)removeExpiredObjects +{ + [self lock]; + NSDictionary *createdDates = [_createdDates copy]; + NSDictionary *ageLimits = [_ageLimits copy]; + NSTimeInterval globalAgeLimit = self->_ageLimit; + [self unlock]; + + NSDate *now = [NSDate date]; + for (NSString *key in ageLimits) { + NSDate *createdDate = createdDates[key]; + NSTimeInterval ageLimit = [ageLimits[key] doubleValue] ?: globalAgeLimit; + if (!createdDate) continue; - - if ([accessDate compare:trimDate] == NSOrderedAscending) { // older than trim date + + NSDate *expirationDate = [createdDate dateByAddingTimeInterval:ageLimit]; + if ([expirationDate compare:now] == NSOrderedAscending) { // Expiration date has passed [self removeObjectAndExecuteBlocksForKey:key]; - } else { - break; } } } @@ -220,17 +260,21 @@ - (void)trimToCostLimit:(NSUInteger)limit - (void)trimToCostLimitByDate:(NSUInteger)limit { + if (self.isTTLCache) { + [self removeExpiredObjects]; + } + NSUInteger totalCost = 0; [self lock]; totalCost = _totalCost; - NSArray *keysSortedByDate = [_dates keysSortedByValueUsingSelector:@selector(compare:)]; + NSArray *keysSortedByAccessDate = [_accessDates keysSortedByValueUsingSelector:@selector(compare:)]; [self unlock]; if (totalCost <= limit) return; - for (NSString *key in keysSortedByDate) { // oldest objects first + for (NSString *key in keysSortedByAccessDate) { // oldest objects first [self removeObjectAndExecuteBlocksForKey:key]; [self lock]; @@ -256,9 +300,20 @@ - (void)trimToAgeLimitRecursively dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(ageLimit * NSEC_PER_SEC)); dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ - [self.operationQueue scheduleOperation:^{ - [self trimToAgeLimitRecursively]; - } withPriority:PINOperationQueuePriorityHigh]; + // Ensure that ageLimit is the same as when we were scheduled, otherwise, we've been + // rescheduled (another dispatch_after was issued) and should cancel. + BOOL shouldReschedule = YES; + [self lock]; + if (ageLimit != self->_ageLimit) { + shouldReschedule = NO; + } + [self unlock]; + + if (shouldReschedule) { + [self.operationQueue scheduleOperation:^{ + [self trimToAgeLimitRecursively]; + } withPriority:PINOperationQueuePriorityLow]; + } }); } @@ -294,10 +349,20 @@ - (void)setObjectAsync:(id)object forKey:(NSString *)key completion:(PINCacheObj [self setObjectAsync:object forKey:key withCost:0 completion:block]; } +- (void)setObjectAsync:(id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit completion:(PINCacheObjectBlock)block +{ + [self setObjectAsync:object forKey:key withCost:0 ageLimit:ageLimit completion:block]; +} + - (void)setObjectAsync:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost completion:(PINCacheObjectBlock)block +{ + [self setObjectAsync:object forKey:key withCost:cost ageLimit:0.0 completion:block]; +} + +- (void)setObjectAsync:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit completion:(PINCacheObjectBlock)block { [self.operationQueue scheduleOperation:^{ - [self setObject:object forKey:key withCost:cost]; + [self setObject:object forKey:key withCost:cost ageLimit:ageLimit]; if (block) block(self, key, object); @@ -311,7 +376,7 @@ - (void)removeObjectForKeyAsync:(NSString *)key completion:(PINCacheObjectBlock) if (block) block(self, key, nil); - } withPriority:PINOperationQueuePriorityHigh]; + } withPriority:PINOperationQueuePriorityLow]; } - (void)trimToDateAsync:(NSDate *)trimDate completion:(PINCacheBlock)block @@ -321,7 +386,7 @@ - (void)trimToDateAsync:(NSDate *)trimDate completion:(PINCacheBlock)block if (block) block(self); - } withPriority:PINOperationQueuePriorityHigh]; + } withPriority:PINOperationQueuePriorityLow]; } - (void)trimToCostAsync:(NSUInteger)cost completion:(PINCacheBlock)block @@ -331,7 +396,7 @@ - (void)trimToCostAsync:(NSUInteger)cost completion:(PINCacheBlock)block if (block) block(self); - } withPriority:PINOperationQueuePriorityHigh]; + } withPriority:PINOperationQueuePriorityLow]; } - (void)trimToCostByDateAsync:(NSUInteger)cost completion:(PINCacheBlock)block @@ -341,7 +406,17 @@ - (void)trimToCostByDateAsync:(NSUInteger)cost completion:(PINCacheBlock)block if (block) block(self); - } withPriority:PINOperationQueuePriorityHigh]; + } withPriority:PINOperationQueuePriorityLow]; +} + +- (void)removeExpiredObjectsAsync:(PINCacheBlock)block +{ + [self.operationQueue scheduleOperation:^{ + [self removeExpiredObjects]; + + if (block) + block(self); + } withPriority:PINOperationQueuePriorityLow]; } - (void)removeAllObjectsAsync:(PINCacheBlock)block @@ -351,7 +426,7 @@ - (void)removeAllObjectsAsync:(PINCacheBlock)block if (block) block(self); - } withPriority:PINOperationQueuePriorityHigh]; + } withPriority:PINOperationQueuePriorityLow]; } - (void)enumerateObjectsWithBlockAsync:(PINCacheObjectEnumerationBlock)block completionBlock:(PINCacheBlock)completionBlock @@ -361,7 +436,7 @@ - (void)enumerateObjectsWithBlockAsync:(PINCacheObjectEnumerationBlock)block com if (completionBlock) completionBlock(self); - } withPriority:PINOperationQueuePriorityHigh]; + } withPriority:PINOperationQueuePriorityLow]; } #pragma mark - Public Synchronous Methods - @@ -382,18 +457,19 @@ - (nullable id)objectForKey:(NSString *)key if (!key) return nil; - NSDate *now = [[NSDate alloc] init]; + NSDate *now = [NSDate date]; [self lock]; id object = nil; // If the cache should behave like a TTL cache, then only fetch the object if there's a valid ageLimit and the object is still alive - if (!self->_ttlCache || self->_ageLimit <= 0 || fabs([[_dates objectForKey:key] timeIntervalSinceDate:now]) < self->_ageLimit) { + NSTimeInterval ageLimit = [_ageLimits[key] doubleValue] ?: self->_ageLimit; + if (!self->_ttlCache || ageLimit <= 0 || fabs([[_createdDates objectForKey:key] timeIntervalSinceDate:now]) < ageLimit) { object = _dictionary[key]; } [self unlock]; if (object) { [self lock]; - _dates[key] = now; + _accessDates[key] = now; [self unlock]; } @@ -410,6 +486,11 @@ - (void)setObject:(id)object forKey:(NSString *)key [self setObject:object forKey:key withCost:0]; } +- (void)setObject:(id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit +{ + [self setObject:object forKey:key withCost:0 ageLimit:ageLimit]; +} + - (void)setObject:(id)object forKeyedSubscript:(NSString *)key { if (object == nil) { @@ -421,6 +502,13 @@ - (void)setObject:(id)object forKeyedSubscript:(NSString *)key - (void)setObject:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost { + [self setObject:object forKey:key withCost:cost ageLimit:0.0]; +} + +- (void)setObject:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost ageLimit:(NSTimeInterval)ageLimit +{ + NSAssert(ageLimit <= 0.0 || (ageLimit > 0.0 && _ttlCache), @"ttlCache must be set to YES if setting an object-level age limit."); + if (!key || !object) return; @@ -438,10 +526,18 @@ - (void)setObject:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost if (oldCost) _totalCost -= [oldCost unsignedIntegerValue]; + NSDate *now = [NSDate date]; _dictionary[key] = object; - _dates[key] = [[NSDate alloc] init]; + _createdDates[key] = now; + _accessDates[key] = now; _costs[key] = @(cost); - + + if (ageLimit > 0.0) { + _ageLimits[key] = @(ageLimit); + } else { + [_ageLimits removeObjectForKey:key]; + } + _totalCost += cost; [self unlock]; @@ -495,8 +591,10 @@ - (void)removeAllObjects [self lock]; [_dictionary removeAllObjects]; - [_dates removeAllObjects]; + [_createdDates removeAllObjects]; + [_accessDates removeAllObjects]; [_costs removeAllObjects]; + [_ageLimits removeAllObjects]; _totalCost = 0; [self unlock]; @@ -506,18 +604,19 @@ - (void)removeAllObjects } -- (void)enumerateObjectsWithBlock:(PINCacheObjectEnumerationBlock)block +- (void)enumerateObjectsWithBlock:(PIN_NOESCAPE PINCacheObjectEnumerationBlock)block { if (!block) return; [self lock]; - NSDate *now = [[NSDate alloc] init]; - NSArray *keysSortedByDate = [_dates keysSortedByValueUsingSelector:@selector(compare:)]; + NSDate *now = [NSDate date]; + NSArray *keysSortedByCreatedDate = [_createdDates keysSortedByValueUsingSelector:@selector(compare:)]; - for (NSString *key in keysSortedByDate) { + for (NSString *key in keysSortedByCreatedDate) { // If the cache should behave like a TTL cache, then only fetch the object if there's a valid ageLimit and the object is still alive - if (!self->_ttlCache || self->_ageLimit <= 0 || fabs([[_dates objectForKey:key] timeIntervalSinceDate:now]) < self->_ageLimit) { + NSTimeInterval ageLimit = [_ageLimits[key] doubleValue] ?: self->_ageLimit; + if (!self->_ttlCache || ageLimit <= 0 || fabs([[_createdDates objectForKey:key] timeIntervalSinceDate:now]) < ageLimit) { BOOL stop = NO; block(self, key, _dictionary[key], &stop); if (stop) @@ -713,13 +812,6 @@ - (BOOL)isTTLCache { return isTTLCache; } -- (void)setTtlCache:(BOOL)ttlCache { - [self lock]; - _ttlCache = ttlCache; - [self unlock]; -} - - - (void)lock { __unused int result = pthread_mutex_lock(&_mutex); @@ -746,42 +838,74 @@ - (void)containsObjectForKey:(NSString *)key block:(PINMemoryCacheContainmentBlo - (void)objectForKey:(NSString *)key block:(nullable PINMemoryCacheObjectBlock)block { - [self objectForKeyAsync:key completion:block]; + [self objectForKeyAsync:key completion:^(id memoryCache, NSString *memoryCacheKey, id memoryCacheObject) { + if (block) { + block((PINMemoryCache *)memoryCache, memoryCacheKey, memoryCacheObject); + } + }]; } - (void)setObject:(id)object forKey:(NSString *)key block:(nullable PINMemoryCacheObjectBlock)block { - [self setObjectAsync:object forKey:key completion:block]; + [self setObjectAsync:object forKey:key completion:^(id memoryCache, NSString *memoryCacheKey, id memoryCacheObject) { + if (block) { + block((PINMemoryCache *)memoryCache, memoryCacheKey, memoryCacheObject); + } + }]; } - (void)setObject:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost block:(nullable PINMemoryCacheObjectBlock)block { - [self setObjectAsync:object forKey:key withCost:cost completion:block]; + [self setObjectAsync:object forKey:key withCost:cost completion:^(id memoryCache, NSString *memoryCacheKey, id memoryCacheObject) { + if (block) { + block((PINMemoryCache *)memoryCache, memoryCacheKey, memoryCacheObject); + } + }]; } - (void)removeObjectForKey:(NSString *)key block:(nullable PINMemoryCacheObjectBlock)block { - [self removeObjectForKeyAsync:key completion:block]; + [self removeObjectForKeyAsync:key completion:^(id memoryCache, NSString *memoryCacheKey, id memoryCacheObject) { + if (block) { + block((PINMemoryCache *)memoryCache, memoryCacheKey, memoryCacheObject); + } + }]; } - (void)trimToDate:(NSDate *)date block:(nullable PINMemoryCacheBlock)block { - [self trimToDateAsync:date completion:block]; + [self trimToDateAsync:date completion:^(id memoryCache) { + if (block) { + block((PINMemoryCache *)memoryCache); + } + }]; } - (void)trimToCost:(NSUInteger)cost block:(nullable PINMemoryCacheBlock)block { - [self trimToCostAsync:cost completion:block]; + [self trimToCostAsync:cost completion:^(id memoryCache) { + if (block) { + block((PINMemoryCache *)memoryCache); + } + }]; } - (void)trimToCostByDate:(NSUInteger)cost block:(nullable PINMemoryCacheBlock)block { - [self trimToCostByDateAsync:cost completion:block]; + [self trimToCostByDateAsync:cost completion:^(id memoryCache) { + if (block) { + block((PINMemoryCache *)memoryCache); + } + }]; } - (void)removeAllObjects:(nullable PINMemoryCacheBlock)block { - [self removeAllObjectsAsync:block]; + [self removeAllObjectsAsync:^(id memoryCache) { + if (block) { + block((PINMemoryCache *)memoryCache); + } + }]; } - (void)enumerateObjectsWithBlock:(PINMemoryCacheObjectBlock)block completionBlock:(nullable PINMemoryCacheBlock)completionBlock @@ -791,7 +915,18 @@ - (void)enumerateObjectsWithBlock:(PINMemoryCacheObjectBlock)block completionBlo PINMemoryCache *memoryCache = (PINMemoryCache *)cache; block(memoryCache, key, object); } - } completionBlock:completionBlock]; + } completionBlock:^(id memoryCache) { + if (completionBlock) { + completionBlock((PINMemoryCache *)memoryCache); + } + }]; +} + +- (void)setTtlCache:(BOOL)ttlCache +{ + [self lock]; + _ttlCache = ttlCache; + [self unlock]; } @end diff --git a/Example/Pods/PINOperation/README.md b/Example/Pods/PINOperation/README.md index c705a1f..c7ac84e 100644 --- a/Example/Pods/PINOperation/README.md +++ b/Example/Pods/PINOperation/README.md @@ -2,7 +2,7 @@ [![CocoaPods](https://img.shields.io/cocoapods/v/PINOperation.svg)](http://cocoadocs.org/docsets/PINOperation/) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -[![Build status](https://badge.buildkite.com/665147e3b6852a9c1c3a3df3ced779c32bc6396ba69fee4b6e.svg?branch=master&style=flat)](https://buildkite.com/pinterest/pinoperation) +[![Build status](https://github.com/pinterest/PINOperation/workflows/CI/badge.svg)](https://github.com/pinterest/PINOperation/actions?query=workflow%3ACI+branch%3Amaster) ## Fast, concurrency-limited task queue for iOS and macOS. @@ -31,7 +31,7 @@ Add the following line to your `Cartfile` and run `carthage update --platform io ## Requirements -__PINOperation__ requires iOS 5.0 or OS X 10.8 and greater. +__PINOperation__ requires iOS 8.0, tvOS 9.0, macOS 10.8 or watchOS 2.0 and greater. ## Contact diff --git a/Example/Pods/PINOperation/Source/PINOperation.h b/Example/Pods/PINOperation/Source/PINOperation.h index 1f67472..68b074d 100644 --- a/Example/Pods/PINOperation/Source/PINOperation.h +++ b/Example/Pods/PINOperation/Source/PINOperation.h @@ -6,7 +6,7 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import -#import -#import -#import +#import "PINOperationMacros.h" +#import "PINOperationTypes.h" +#import "PINOperationQueue.h" +#import "PINOperationGroup.h" diff --git a/Example/Pods/PINOperation/Source/PINOperationQueue.m b/Example/Pods/PINOperation/Source/PINOperationQueue.m index d2a024e..5d0a38f 100644 --- a/Example/Pods/PINOperation/Source/PINOperationQueue.m +++ b/Example/Pods/PINOperation/Source/PINOperationQueue.m @@ -305,16 +305,10 @@ - (void)setMaxConcurrentOperations:(NSUInteger)maxConcurrentOperations - (BOOL)locked_cancelOperation:(id )operationReference { - BOOL success = NO; PINOperation *operation = [_referenceToOperations objectForKey:operationReference]; - if (operation) { - NSMutableOrderedSet *queue = [self operationQueueWithPriority:operation.priority]; - if ([queue containsObject:operation]) { - success = YES; - [queue removeObject:operation]; - [_queuedOperations removeObject:operation]; - dispatch_group_leave(_group); - } + BOOL success = [self locked_removeOperation:operation]; + if (success) { + dispatch_group_leave(_group); } return success; } @@ -448,13 +442,20 @@ - (void)waitUntilAllOperationsAreFinished } //Call with lock held -- (void)locked_removeOperation:(PINOperation *)operation +- (BOOL)locked_removeOperation:(PINOperation *)operation { if (operation) { NSMutableOrderedSet *priorityQueue = [self operationQueueWithPriority:operation.priority]; - [priorityQueue removeObject:operation]; - [_queuedOperations removeObject:operation]; + if ([priorityQueue containsObject:operation]) { + [priorityQueue removeObject:operation]; + [_queuedOperations removeObject:operation]; + if (operation.identifier) { + [_identifierToOperations removeObjectForKey:operation.identifier]; + } + return YES; + } } + return NO; } - (void)lock diff --git a/Example/Pods/PINRemoteImage/README.md b/Example/Pods/PINRemoteImage/README.md index 4748c10..d192821 100644 --- a/Example/Pods/PINRemoteImage/README.md +++ b/Example/Pods/PINRemoteImage/README.md @@ -4,18 +4,18 @@ [![CocoaPods compatible](https://img.shields.io/cocoapods/v/PINRemoteImage.svg?style=flat)](https://cocoapods.org/pods/PINRemoteImage) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -[![Build status](https://badge.buildkite.com/556f751bb6455e96687a5f8fb05a65f2df9db8b033121b8c3d.svg?branch=master&style=flat)](https://buildkite.com/pinterest/pinremoteimage) +[![Build status](https://github.com/pinterest/PINRemoteImage/workflows/CI/badge.svg)](https://github.com/pinterest/PINRemoteImage/actions?query=workflow%3ACI+branch%3Amaster) -[PINRemoteImageManager](Pod/Classes/PINRemoteImageManager.h) is an image downloading, processing and caching manager. It uses the concept of download and processing tasks to ensure that even if multiple calls to download or process an image are made, it only occurs one time (unless an item is no longer in the cache). PINRemoteImageManager is backed by **GCD** and safe to **access** from **multiple threads** simultaneously. It ensures that images are decoded off the main thread so that animation performance isn't affected. None of its exposed methods allow for synchronous access. However, it is optimized to call completions on the calling thread if an item is in its memory cache. +[PINRemoteImageManager](Source/Classes/PINRemoteImageManager.h) is an image downloading, processing and caching manager. It uses the concept of download and processing tasks to ensure that even if multiple calls to download or process an image are made, it only occurs one time (unless an item is no longer in the cache). PINRemoteImageManager is backed by **GCD** and safe to **access** from **multiple threads** simultaneously. It ensures that images are decoded off the main thread so that animation performance isn't affected. None of its exposed methods allow for synchronous access. However, it is optimized to call completions on the calling thread if an item is in its memory cache. -PINRemoteImage supports downloading many types of files. It, of course, **supports** both **PNGs** and **JPGs**. It also supports decoding **WebP** images if Google's library is available. It even supports **GIFs** via returning [FLAnimatedImages](https://github.com/Flipboard/FLAnimatedImage) if it's compiled in (though this can be disabled). +PINRemoteImage supports downloading many types of files. It, of course, **supports** both **PNGs** and **JPGs**. It also supports decoding **WebP** images if Google's library is available. It even supports **GIFs** and **Animated WebP** via PINAnimatedImageView. PINRemoteImage also has two methods to improve the experience of downloading images on slow network connections. The first is support for **progressive JPGs**. This isn't any old support for progressive JPGs though: PINRemoteImage adds an attractive blur to progressive scans before returning them. ![Progressive JPG with Blur](/progressive.gif "Looks better on device.") [PINRemoteImageCategoryManager](Pod/Classes/PINRemoteImageCategoryManager.h) defines a protocol which UIView subclasses can implement and provide easy access to -PINRemoteImageManager's methods. There are **built-in categories** on **UIImageView**, **FLAnimatedImageView** and **UIButton**, and it's very easy to implement a new category. See [UIImageView+PINRemoteImage](/Pod/Classes/Image Categories/UIImageView+PINRemoteImage.h) of the existing categories for reference. +PINRemoteImageManager's methods. There are **built-in categories** on **UIImageView**, **PINAnimatedImageView** and **UIButton**, and it's very easy to implement a new category. See [UIImageView+PINRemoteImage](/Pod/Classes/Image Categories/UIImageView+PINRemoteImage.h) of the existing categories for reference. ### Download an image and set it on an image view: @@ -62,17 +62,17 @@ let imageView = UIImageView() imageView.pin_setImage(from: URL(string: "https://pinterest.com/googleKitten.webp")!) ``` -### Download a GIF and display with FLAnimatedImageView +### Download a GIF and display with PINAnimatedImageView **Objective-C** ```objc -FLAnimatedImageView *animatedImageView = [[FLAnimatedImageView alloc] init]; +PINAnimatedImageView *animatedImageView = [[PINAnimatedImageView alloc] init]; [animatedImageView pin_setImageFromURL:[NSURL URLWithString:@"http://pinterest.com/flyingKitten.gif"]]; ``` **Swift** ```swift -let animatedImageView = FLAnimatedImageView() +let animatedImageView = PINAnimatedImageView() animatedImageView.pin_setImage(from: URL(string: "http://pinterest.com/flyingKitten.gif")!) ``` @@ -81,7 +81,7 @@ animatedImageView.pin_setImage(from: URL(string: "http://pinterest.com/flyingKit **Objective-C** ```objc UIImageView *imageView = [[UIImageView alloc] init]; -[self.imageView pin_setImageFromURL:[NSURL URLWithString:@"https://s-media-cache-ak0.pinimg.com/736x/5b/c6/c5/5bc6c5387ff6f104fd642f2b375efba3.jpg"] processorKey:@"rounded" processor:^UIImage *(PINRemoteImageManagerResult *result, NSUInteger *cost) +[self.imageView pin_setImageFromURL:[NSURL URLWithString:@"https://i.pinimg.com/736x/5b/c6/c5/5bc6c5387ff6f104fd642f2b375efba3.jpg"] processorKey:@"rounded" processor:^UIImage *(PINRemoteImageManagerResult *result, NSUInteger *cost) { CGSize targetSize = CGSizeMake(200, 300); CGRect imageRect = CGRectMake(0, 0, targetSize.width, targetSize.height); @@ -110,7 +110,7 @@ UIImageView *imageView = [[UIImageView alloc] init]; **Swift** ```swift let imageView = FLAnimatedImageView() -imageView.pin_setImage(from: URL(string: "https://s-media-cache-ak0.pinimg.com/736x/5b/c6/c5/5bc6c5387ff6f104fd642f2b375efba3.jpg")!, processorKey: "rounded") { (result, unsafePointer) -> UIImage? in +imageView.pin_setImage(from: URL(string: "https://i.pinimg.com/736x/5b/c6/c5/5bc6c5387ff6f104fd642f2b375efba3.jpg")!, processorKey: "rounded") { (result, unsafePointer) -> UIImage? in guard let image = result.image else { return nil } @@ -197,7 +197,7 @@ __weak UIImageView *weakImageView = self.imageView; // cache is an instance of PINCache as long as you haven't overridden defaultImageCache PINCache *cache = (PINCache *)[[PINRemoteImageManager sharedImageManager] cache]; // Max memory cost is based on number of pixels, we estimate the size of one hundred 600x600 images as our max memory image cache. -[[cache memoryCache] setCostLimit:600 * 600 * 100 * [[UIScreen mainScreen] scale]]; +[[cache memoryCache] setCostLimit:600 * [[UIScreen mainScreen] scale] * 600 * [[UIScreen mainScreen] scale] * 100]; // ~50 MB [[cache diskCache] setByteLimit:50 * 1024 * 1024]; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImage.m b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImage.m index 691b62b..9204b4e 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImage.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImage.m @@ -8,11 +8,9 @@ #import "PINAnimatedImage.h" -NSString *kPINAnimatedImageErrorDomain = @"kPINAnimatedImageErrorDomain"; +NSErrorDomain const kPINAnimatedImageErrorDomain = @"kPINAnimatedImageErrorDomain"; -const NSTimeInterval kPINAnimatedImageDisplayRefreshRate = 60.0; //http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser -const Float32 kPINAnimatedImageMinimumDuration = 1 / kPINAnimatedImageDisplayRefreshRate; const Float32 kPINAnimatedImageDefaultDuration = 0.1; @interface PINAnimatedImage () @@ -23,6 +21,26 @@ @interface PINAnimatedImage () @implementation PINAnimatedImage ++ (NSInteger)maximumFramesPerSecond +{ + static dispatch_once_t onceToken; + static NSInteger maximumFramesPerSecond = 60; + + dispatch_once(&onceToken, ^{ +#if PIN_TARGET_IOS + if (@available(iOS 10.3, tvOS 10.3, *)) { + maximumFramesPerSecond = 0; + for (UIScreen *screen in [UIScreen screens]) { + if ([screen maximumFramesPerSecond] > maximumFramesPerSecond) { + maximumFramesPerSecond = [screen maximumFramesPerSecond]; + } + } + } +#endif + }); + return maximumFramesPerSecond; +} + - (instancetype)init { if (self = [super init]) { @@ -58,19 +76,23 @@ - (CFTimeInterval)totalDuration - (NSUInteger)frameInterval { - return MAX(self.minimumFrameInterval * kPINAnimatedImageDisplayRefreshRate, 1); + return MAX(self.minimumFrameInterval * [PINAnimatedImage maximumFramesPerSecond], 1); } //Credit to FLAnimatedImage ( https://github.com/Flipboard/FLAnimatedImage ) for display link interval calculations - (NSTimeInterval)minimumFrameInterval { - const NSTimeInterval kGreatestCommonDivisorPrecision = 2.0 / kPINAnimatedImageMinimumDuration; + static dispatch_once_t onceToken; + static NSTimeInterval kGreatestCommonDivisorPrecision; + dispatch_once(&onceToken, ^{ + kGreatestCommonDivisorPrecision = 2.0 / (1.0 / [PINAnimatedImage maximumFramesPerSecond]); + }); // Scales the frame delays by `kGreatestCommonDivisorPrecision` // then converts it to an UInteger for in order to calculate the GCD. NSUInteger scaledGCD = lrint([self durationAtIndex:0] * kGreatestCommonDivisorPrecision); - for (NSUInteger durationIdx = 0; durationIdx < self.frameCount; durationIdx++) { - Float32 duration = [self durationAtIndex:durationIdx]; + for (NSUInteger durationIdx = 1; durationIdx < self.frameCount; durationIdx++) { + CFTimeInterval duration = [self durationAtIndex:durationIdx]; scaledGCD = gcd(lrint(duration * kGreatestCommonDivisorPrecision), scaledGCD); } @@ -78,24 +100,27 @@ - (NSTimeInterval)minimumFrameInterval return (scaledGCD / kGreatestCommonDivisorPrecision); } -//Credit to FLAnimatedImage ( https://github.com/Flipboard/FLAnimatedImage ) for display link interval calculations +// This likely isn't the most efficient but it's easy to reason about and we don't call it +// with super large numbers. static NSUInteger gcd(NSUInteger a, NSUInteger b) { // http://en.wikipedia.org/wiki/Greatest_common_divisor - if (a < b) { - return gcd(b, a); - } else if (a == b) { - return b; - } + NSCAssert(a > 0 && b > 0, @"A and B must be greater than 0"); - while (true) { - NSUInteger remainder = a % b; - if (remainder == 0) { - return b; + while (a != b) { + if (a > b) { + a = a - b; + } else { + b = b - a; } - a = b; - b = remainder; } + return a; +} + +// Used only in testing ++ (NSUInteger)greatestCommonDivisorOfA:(NSUInteger)a andB:(NSUInteger)b +{ + return gcd(a, b); } @end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImageView.m b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImageView.m new file mode 100644 index 0000000..e54fa7e --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImageView.m @@ -0,0 +1,443 @@ +// +// PINAnimatedImageView.m +// Pods +// +// Created by Garrett Moon on 4/17/18. +// + +#import "PINAnimatedImageView.h" + +#import "PINRemoteLock.h" +#import "PINDisplayLink.h" +#import "PINImage+DecodedImage.h" +#import "PINRemoteWeakProxy.h" + +@interface PINAnimatedImageView () +{ + CFTimeInterval _playHead; + NSUInteger _playedLoops; + NSUInteger _lastSuccessfulFrameIndex; + CFTimeInterval *_durations; +} + +@property (nonatomic, assign) CGImageRef frameImage; +@property (nonatomic, strong) PINDisplayLink *displayLink; + +@property (nonatomic, assign) CFTimeInterval lastDisplayLinkFire; + +@end + +@implementation PINAnimatedImageView + +@synthesize animatedImage = _animatedImage; +@synthesize displayLink = _displayLink; +@synthesize playbackPaused = _playbackPaused; +@synthesize animatedImageRunLoopMode = _animatedImageRunLoopMode; + +- (instancetype)initWithAnimatedImage:(PINCachedAnimatedImage *)animatedImage +{ + if (self = [super initWithFrame:CGRectZero]) { + [self commonInit:animatedImage]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + [self commonInit:nil]; + } + return self; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if (self = [super initWithCoder:aDecoder]) { + [self commonInit:nil]; + } + return self; +} + +- (void)commonInit:(PINCachedAnimatedImage *)animatedImage +{ + _animatedImage = animatedImage; + _animatedImageRunLoopMode = NSRunLoopCommonModes; + _durations = NULL; + + if (animatedImage) { + [self initializeAnimatedImage:animatedImage]; + } +} + +- (void)initializeAnimatedImage:(nonnull PINCachedAnimatedImage *)animatedImage +{ + PINWeakify(self); + animatedImage.coverImageReadyCallback = ^(PINImage *coverImage) { + dispatch_async(dispatch_get_main_queue(), ^{ + PINStrongify(self); + // In this case the lock is already gone we have to call the unlocked version therefore + [self coverImageCompleted:coverImage]; + }); + }; + + animatedImage.playbackReadyCallback = ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + // In this case the lock is already gone we have to call the unlocked version therefore + PINStrongify(self); + [self checkIfShouldAnimate]; + }); + }; + if (animatedImage.playbackReady) { + [self checkIfShouldAnimate]; + } + + [self resetDurationsWithAnimatedImage:animatedImage]; +} + +- (void)dealloc +{ + if (_frameImage) { + CGImageRelease(_frameImage); + } + if (_durations) { + free(_durations); + } +} + +#pragma mark - Public + +- (void)setAnimatedImage:(PINCachedAnimatedImage *)animatedImage +{ + PINAssertMain(); + if (_animatedImage == animatedImage && animatedImage.playbackReady) { + return; + } + + PINCachedAnimatedImage *previousAnimatedImage = _animatedImage; + + _animatedImage = animatedImage; + + if (animatedImage != nil) { + [self initializeAnimatedImage:animatedImage]; + } else { + // Clean up after ourselves. + self.layer.contents = nil; + [self setCoverImage:nil]; + } + + // Animated Image can take a while to dealloc, let's try and do it off main. + __block PINCachedAnimatedImage *strongAnimatedImage = previousAnimatedImage; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + strongAnimatedImage = nil; + }); +} + +- (PINCachedAnimatedImage *)animatedImage +{ + PINAssertMain(); + return _animatedImage; +} + +- (NSString *)animatedImageRunLoopMode +{ + PINAssertMain(); + return _animatedImageRunLoopMode; +} + +- (void)setAnimatedImageRunLoopMode:(NSString *)newRunLoopMode +{ + PINAssertMain(); + + NSString *runLoopMode = newRunLoopMode ?: NSRunLoopCommonModes; + + if (_displayLink != nil) { + [_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:_animatedImageRunLoopMode]; + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:runLoopMode]; + } + _animatedImageRunLoopMode = runLoopMode; +} + +- (BOOL)isPlaybackPaused +{ + PINAssertMain(); + return _playbackPaused; +} + +- (void)setPlaybackPaused:(BOOL)playbackPaused +{ + PINAssertMain(); + + _playbackPaused = playbackPaused; + [self checkIfShouldAnimate]; +} + +- (void)coverImageCompleted:(PINImage *)coverImage +{ + PINAssertMain(); + BOOL setCoverImage = (_displayLink == nil) || _displayLink.paused; + + if (setCoverImage) { + [self setCoverImage:coverImage]; + } +} + +- (void)setCoverImage:(PINImage *)coverImage +{ + PINAssertMain(); + if (_frameImage) { + CGImageRelease(_frameImage); + } + _frameImage = CGImageRetain([coverImage CGImage]); +} + +#pragma mark - Animating + +- (void)checkIfShouldAnimate +{ + PINAssertMain(); + BOOL shouldAnimate = _playbackPaused == NO && _animatedImage.playbackReady && [self canBeVisible]; + if (shouldAnimate) { + [self startAnimating]; + } else { + [self stopAnimating]; + } +} + +- (void)startAnimating +{ + PINAssertMain(); + + if (_playbackPaused) { + return; + } + + if (_animatedImage.playbackReady == NO) { + return; + } + + if ([self canBeVisible] == NO) { + return; + } + + NSUInteger frameInterval = self.animatedImage.frameInterval; + + if (_displayLink == nil) { + _playHead = 0; + _displayLink = [PINDisplayLink displayLinkWithTarget:[PINRemoteWeakProxy weakProxyWithTarget:self] selector:@selector(displayLinkFired:)]; +#if PIN_TARGET_IOS + if (@available(iOS 10.0, tvOS 10.0, *)) { + // Convert from display link fractional value to fps (note: frameInterval is always at least 1) + NSInteger frameRate = ceil([PINAnimatedImage maximumFramesPerSecond] / ((double) frameInterval)); + _displayLink.preferredFramesPerSecond = frameRate; + } else { +#endif + _displayLink.frameInterval = frameInterval; +#if PIN_TARGET_IOS + } +#endif + _lastSuccessfulFrameIndex = NSUIntegerMax; + + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:self.animatedImageRunLoopMode]; + } else { + _displayLink.paused = NO; + } +} + +- (void)stopAnimating +{ + PINAssertMain(); + + _displayLink.paused = YES; + _lastDisplayLinkFire = 0; + + [_animatedImage clearAnimatedImageCache]; +} + +#pragma mark - Overrides + +- (PINImage *)image +{ + PINAssertMain(); + if (_animatedImage) { + return [PINImage imageWithCGImage:_frameImage]; + } + return [super image]; +} + +- (CGImageRef)imageRef +{ + PINAssertMain(); + PINImage *underlyingImage = nil; + if (_animatedImage) { + return _frameImage; + } else if ((underlyingImage = [super image])) { + return (CGImageRef)CFAutorelease(CFRetain([underlyingImage CGImage])); + } + return nil; +} + +- (void)setImage:(PINImage *)image +{ + PINAssertMain(); + if (image) { + self.animatedImage = nil; + } + + super.image = image; +} + +- (void)displayLayer:(CALayer *)layer +{ + PINAssertMain(); + layer.contents = (__bridge id)[self imageRef]; +} + +#if PIN_TARGET_MAC + +- (void)_setImage:(PINImage *)image +{ + super.image = image; +} + +- (void)setAlphaValue:(CGFloat)alphaValue +{ + [super setAlphaValue:alphaValue]; + [self updateAnimationForPossibleVisibility]; +} + +- (void)viewDidMoveToWindow +{ + [super viewDidMoveToWindow]; + [self updateAnimationForPossibleVisibility]; +} + +- (void)viewDidMoveToSuperview +{ + [super viewDidMoveToSuperview]; + [self updateAnimationForPossibleVisibility]; +} +#else +- (void)setAlpha:(CGFloat)alpha +{ + [super setAlpha:alpha]; + [self updateAnimationForPossibleVisibility]; +} + +- (void)didMoveToWindow +{ + [super didMoveToWindow]; + [self updateAnimationForPossibleVisibility]; +} + +- (void)didMoveToSuperview +{ + [super didMoveToSuperview]; + [self updateAnimationForPossibleVisibility]; +} +#endif + +- (void)setHidden:(BOOL)hidden +{ + [super setHidden:hidden]; + [self updateAnimationForPossibleVisibility]; +} + +#pragma mark - Display Link Callbacks + +- (BOOL)canBeVisible +{ +#if PIN_TARGET_MAC + return self.window && self.superview && self.isHidden == NO && self.alphaValue > 0.0; +#else + return self.window && self.superview && self.isHidden == NO && self.alpha > 0.0; +#endif +} + +- (void)updateAnimationForPossibleVisibility +{ + [self checkIfShouldAnimate]; +} + +- (void)displayLinkFired:(PINDisplayLink *)displayLink +{ + PINAssertMain(); + CFTimeInterval timeBetweenLastFire; + if (_lastDisplayLinkFire == 0) { + timeBetweenLastFire = 0; + } else { + timeBetweenLastFire = CACurrentMediaTime() - self.lastDisplayLinkFire; + } + + self.lastDisplayLinkFire = CACurrentMediaTime(); + + _playHead += timeBetweenLastFire; + + while (_playHead > self.animatedImage.totalDuration) { + // Set playhead to zero to keep from showing different frames on different playthroughs + _playHead = 0; + _playedLoops++; + } + + if (self.animatedImage.loopCount > 0 && _playedLoops >= self.animatedImage.loopCount) { + [self stopAnimating]; + return; + } + + NSUInteger frameIndex = [self frameIndexAtPlayHeadPosition:_playHead]; + if (frameIndex == _lastSuccessfulFrameIndex) { + return; + } + CGImageRef frameImage = [self.animatedImage imageAtIndex:frameIndex]; + + if (frameImage == nil) { + //Pause the display link until we get a file ready notification + displayLink.paused = YES; + self.lastDisplayLinkFire = 0; + } else { + if (_frameImage) { + CGImageRelease(_frameImage); + } + _frameImage = CGImageRetain(frameImage); + _lastSuccessfulFrameIndex = frameIndex; +#if PIN_TARGET_MAC + [self _setImage:[NSImage imageWithCGImage:_frameImage]]; +#else + [self.layer setNeedsDisplay]; +#endif + } +} + +- (void)resetDurationsWithAnimatedImage:(PINCachedAnimatedImage *)animatedImage +{ + PINAssertMain(); + if (!animatedImage) { + return; + } + if (_durations) { + free(_durations); + } + _durations = malloc(sizeof(CFTimeInterval) * animatedImage.frameCount); + CFTimeInterval sum = 0.0f; + for (int i = 0; i < animatedImage.frameCount; i++) { + sum += [animatedImage durationAtIndex:i]; + _durations[i] = sum; + } +} + +- (NSUInteger)frameIndexAtPlayHeadPosition:(CFTimeInterval)playHead +{ + PINAssertMain(); + int low = 0, high = (int)_animatedImage.frameCount - 1; + + while (low <= high) { + int mid = low + (high - low) / 2; + if (_durations[mid] < playHead) { + low = mid + 1; + } else { + high = mid - 1; + } + } + return MAX(MIN(low, (int)_animatedImage.frameCount - 1), 0); +} + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m index 168bf30..8f41063 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m @@ -14,7 +14,12 @@ #import "PINWebPAnimatedImage.h" #endif -#import +#if SWIFT_PACKAGE +@import PINOperation; +#else +#import +#endif + #import "NSData+ImageDetectors.h" static const NSUInteger kFramesToRenderForLargeFrames = 4; @@ -29,14 +34,15 @@ @interface PINCachedAnimatedImage () { - // Since _animatedImage is set on init it is thread-safe + // Since _animatedImage is set on init it is thread-safe. id _animatedImage; PINImage *_coverImage; PINAnimatedImageInfoReady _coverImageReadyCallback; dispatch_block_t _playbackReadyCallback; NSMutableDictionary *_frameCache; - NSInteger _playbackReady; // Number of frames to cache until playback is ready + NSInteger _frameRenderCount; // Number of frames to cache until playback is ready. + BOOL _playbackReady; PINOperationQueue *_operationQueue; dispatch_queue_t _cachingQueue; @@ -44,10 +50,13 @@ @interface PINCachedAnimatedImage () BOOL _notifyOnReady; NSMutableIndexSet *_cachedOrCachingFrames; PINRemoteLock *_lock; + BOOL _cacheCleared; // Flag used to cancel any caching operations after clear cache is called. } @property (atomic, strong) NSDate *lastMemoryWarning; -@property (atomic, assign) BOOL weAreTheProblem; + +// Set to YES if we continually see memory warnings after ramping up the number of cached frames. +@property (atomic, assign) BOOL cachingFramesCausingMemoryWarnings; @end @@ -55,7 +64,7 @@ @implementation PINCachedAnimatedImage - (instancetype)initWithAnimatedImageData:(NSData *)animatedImageData { - if ([animatedImageData pin_isGIF]) { + if ([animatedImageData pin_isAnimatedGIF]) { return [self initWithAnimatedImage:[[PINGIFAnimatedImage alloc] initWithAnimatedImageData:animatedImageData]]; } #if PIN_WEBP @@ -71,7 +80,7 @@ - (instancetype)initWithAnimatedImage:(id )animatedImage if (self = [super init]) { _animatedImage = animatedImage; _frameCache = [[NSMutableDictionary alloc] init]; - _playbackReady = 0; + _frameRenderCount = 0; _playhead = 0; _notifyOnReady = YES; _cachedOrCachingFrames = [[NSMutableIndexSet alloc] init]; @@ -79,58 +88,108 @@ - (instancetype)initWithAnimatedImage:(id )animatedImage #if PIN_TARGET_IOS _lastMemoryWarning = [NSDate distantPast]; - PINWeakify(self); - [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { - PINStrongify(self); - NSDate *now = [NSDate date]; - if (-[self.lastMemoryWarning timeIntervalSinceDate:now] < kSecondsBetweenMemoryWarnings) { - self.weAreTheProblem = YES; - } - self.lastMemoryWarning = now; - [self cleanupFrames]; - }]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(didReceiveMemoryWarningNotification:) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; #endif _operationQueue = [[PINOperationQueue alloc] initWithMaxConcurrentOperations:kFramesToRenderForLargeFrames]; _cachingQueue = dispatch_queue_create("Caching Queue", DISPATCH_QUEUE_SERIAL); // dispatch later so that blocks can be set after init this runloop + PINWeakify(self); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + PINStrongify(self); [self imageAtIndex:0]; - if (self.coverImageReadyCallback) { - self.coverImageReadyCallback(self.coverImage); - } }); } return self; } +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#if PIN_TARGET_IOS +- (void)didReceiveMemoryWarningNotification:(NSNotification *)notification +{ + NSDate *now = [NSDate date]; + if (-[self.lastMemoryWarning timeIntervalSinceDate:now] < kSecondsBetweenMemoryWarnings) { + self.cachingFramesCausingMemoryWarnings = YES; + } + self.lastMemoryWarning = now; + [self cleanupFrames]; +} +#endif + - (PINImage *)coverImage { __block PINImage *coverImage = nil; + __block PINAnimatedImageInfoReady coverImageReadyCallback = nil; [_lock lockWithBlock:^{ - if (_coverImage == nil) { - CGImageRef coverImageRef = [_animatedImage imageAtIndex:0 cacheProvider:self]; - if (coverImageRef) { + if (self->_coverImage == nil) { + CGImageRef coverImageRef = [self->_animatedImage imageAtIndex:0 cacheProvider:self]; + BOOL notifyCallback = [self _locked_updateCoverImage:coverImageRef]; + coverImageReadyCallback = notifyCallback ? self->_coverImageReadyCallback : nil; + } + coverImage = self->_coverImage; + }]; + if (coverImageReadyCallback) { + coverImageReadyCallback(coverImage); + } + return coverImage; +} + +// Update _coverImage property and return if it should notify the callback +- (BOOL)_locked_updateCoverImage:(CGImageRef)coverImageRef +{ + BOOL notifyCallback = NO; + if (coverImageRef) { + notifyCallback = (_coverImage == nil && coverImageRef != nil); #if PIN_TARGET_IOS - _coverImage = [UIImage imageWithCGImage:coverImageRef]; + _coverImage = [UIImage imageWithCGImage:coverImageRef]; #elif PIN_TARGET_MAC - _coverImage = [[NSImage alloc] initWithCGImage:coverImageRef size:CGSizeMake(_animatedImage.width, _animatedImage.height)]; + _coverImage = [[NSImage alloc] initWithCGImage:coverImageRef size:CGSizeMake(_animatedImage.width, _animatedImage.height)]; #endif + } else { + _coverImage = nil; + } + return notifyCallback; +} + +- (BOOL)coverImageReady +{ + __block PINImage *coverImage = nil; + __block PINAnimatedImageInfoReady coverImageReadyCallback = nil; + [_lock lockWithBlock:^{ + if (self->_coverImage == nil) { + CGImageRef coverImageRef = (__bridge CGImageRef)[self->_frameCache objectForKey:@(0)]; + if (coverImageRef) { + BOOL notifyCallback = [self _locked_updateCoverImage:coverImageRef]; + coverImageReadyCallback = notifyCallback ? self->_coverImageReadyCallback : nil; } } - coverImage = _coverImage; + + coverImage = self->_coverImage; }]; - return coverImage; + if (coverImageReadyCallback) { + coverImageReadyCallback(coverImage); + } + return (coverImage != nil); } -- (BOOL)coverImageReady +#pragma mark - passthrough +- (CGSize)size { - // The cover image is always 'ready' - return YES; + return CGSizeMake(_animatedImage.width, _animatedImage.height); } -#pragma mark - passthrough +- (NSData *)data +{ + return _animatedImage.data; +} - (CFTimeInterval)totalDuration { @@ -162,16 +221,18 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index __block CGImageRef imageRef; __block BOOL cachingDisabled = NO; [_lock lockWithBlock:^{ - imageRef = (__bridge CGImageRef)[_frameCache objectForKey:@(index)]; + // Reset cache cleared flag if it's been set. + self->_cacheCleared = NO; + imageRef = (__bridge CGImageRef)[self->_frameCache objectForKey:@(index)]; - _playhead = index; + self->_playhead = index; if (imageRef == NULL) { if ([self framesToCache] == 0) { // We're not caching so we should just generate the frame. cachingDisabled = YES; } else { PINLog(@"cache miss, aww."); - _notifyOnReady = YES; + self->_notifyOnReady = YES; } } @@ -186,42 +247,54 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index if (cachingDisabled && imageRef == NULL) { imageRef = [_animatedImage imageAtIndex:index cacheProvider:self]; } else { - [self updateCache]; + PINWeakify(self); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + PINStrongify(self); + [self updateCache]; + }); } return imageRef; } +- (void)_updateCacheOnQueue +{ + // Kick off, in order, caching frames which need to be cached + NSRange endKeepRange; + NSRange beginningKeepRange; + + [self getKeepRanges:&endKeepRange beginningKeepRange:&beginningKeepRange]; + + [self->_lock lockWithBlock:^{ + for (NSUInteger idx = endKeepRange.location; idx < NSMaxRange(endKeepRange); idx++) { + if ([self->_cachedOrCachingFrames containsIndex:idx] == NO) { + [self _locked_cacheFrame:idx]; + } + } + + if (beginningKeepRange.location != NSNotFound) { + for (NSUInteger idx = beginningKeepRange.location; idx < NSMaxRange(beginningKeepRange); idx++) { + if ([self->_cachedOrCachingFrames containsIndex:idx] == NO) { + [self _locked_cacheFrame:idx]; + } + } + } + }]; +} + - (void)updateCache { + PINWeakify(self); // skip if we don't have any frames to cache if ([self framesToCache] > 0) { [_operationQueue scheduleOperation:^{ - // Kick off, in order, caching frames which need to be cached - NSRange endKeepRange; - NSRange beginningKeepRange; - - [self getKeepRanges:&endKeepRange beginningKeepRange:&beginningKeepRange]; - - [self->_lock lockWithBlock:^{ - for (NSUInteger idx = endKeepRange.location; idx < NSMaxRange(endKeepRange); idx++) { - if ([_cachedOrCachingFrames containsIndex:idx] == NO) { - [self l_cacheFrame:idx]; - } - } - - if (beginningKeepRange.location != NSNotFound) { - for (NSUInteger idx = beginningKeepRange.location; idx < NSMaxRange(beginningKeepRange); idx++) { - if ([_cachedOrCachingFrames containsIndex:idx] == NO) { - [self l_cacheFrame:idx]; - } - } - } - }]; + PINStrongify(self); + [self _updateCacheOnQueue]; }]; } [_operationQueue scheduleOperation:^{ + PINStrongify(self); [self cleanupFrames]; }]; } @@ -235,11 +308,11 @@ - (void)getKeepRanges:(nonnull out NSRange *)endKeepRangeIn beginningKeepRange:( [self->_lock lockWithBlock:^{ // find the range of frames we want to keep - endKeepRange = NSMakeRange(_playhead, framesToCache); + endKeepRange = NSMakeRange(self->_playhead, framesToCache); beginningKeepRange = NSMakeRange(NSNotFound, 0); - if (NSMaxRange(endKeepRange) > _animatedImage.frameCount) { - beginningKeepRange = NSMakeRange(0, NSMaxRange(endKeepRange) - _animatedImage.frameCount); - endKeepRange.length = _animatedImage.frameCount - _playhead; + if (NSMaxRange(endKeepRange) > self->_animatedImage.frameCount) { + beginningKeepRange = NSMakeRange(0, NSMaxRange(endKeepRange) - self->_animatedImage.frameCount); + endKeepRange.length = self->_animatedImage.frameCount - self->_playhead; } }]; @@ -260,7 +333,7 @@ - (void)cleanupFrames [_lock lockWithBlock:^{ NSMutableIndexSet *removedFrames = [[NSMutableIndexSet alloc] init]; PINLog(@"Checking if frames need removing: %lu", _cachedOrCachingFrames.count); - [_cachedOrCachingFrames enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { + [self->_cachedOrCachingFrames enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { BOOL shouldKeepFrame = NSLocationInRange(idx, endKeepRange); if (beginningKeepRange.location != NSNotFound) { shouldKeepFrame |= NSLocationInRange(idx, beginningKeepRange); @@ -271,41 +344,61 @@ - (void)cleanupFrames PINLog(@"Removing: %lu", (unsigned long)idx); } }]; - [_cachedOrCachingFrames removeIndexes:removedFrames]; + [self->_cachedOrCachingFrames removeIndexes:removedFrames]; }]; } -- (void)l_cacheFrame:(NSUInteger)frameIndex +- (void)_cacheWithFrameIndex:(NSUInteger)frameIndex { - if ([_cachedOrCachingFrames containsIndex:frameIndex] == NO) { + CGImageRef imageRef = [self->_animatedImage imageAtIndex:frameIndex cacheProvider:self]; + PINLog(@"Generating: %lu", (unsigned long)frameIndex); + + if (imageRef) { + __block PINImage *coverImage = nil; + __block PINAnimatedImageInfoReady coverImageReadyCallback = nil; + [self->_lock lockWithBlock:^{ + [self->_frameCache setObject:(__bridge id _Nonnull)(imageRef) forKey:@(frameIndex)]; + + // Update the cover image + if (frameIndex == 0) { + BOOL notifyCallback = [self _locked_updateCoverImage:imageRef]; + coverImageReadyCallback = notifyCallback ? self->_coverImageReadyCallback : nil; + coverImage = self->_coverImage; + } + + self->_frameRenderCount--; + NSAssert(self->_frameRenderCount >= 0, @"playback ready is less than zero, something is wrong :("); + + PINLog(@"Frames left: %ld", (long)_frameRenderCount); + + dispatch_block_t notify = nil; + if (self->_frameRenderCount == 0 && self->_notifyOnReady) { + self->_notifyOnReady = NO; + if (self->_playbackReadyCallback) { + notify = self->_playbackReadyCallback; + [self->_operationQueue scheduleOperation:^{ + notify(); + }]; + } + } + }]; + if (coverImageReadyCallback) { + coverImageReadyCallback(coverImage); + } + } +} + +- (void)_locked_cacheFrame:(NSUInteger)frameIndex +{ + if ([_cachedOrCachingFrames containsIndex:frameIndex] == NO && _cacheCleared == NO) { PINLog(@"Requesting: %lu", (unsigned long)frameIndex); [_cachedOrCachingFrames addIndex:frameIndex]; - _playbackReady++; + _frameRenderCount++; + PINWeakify(self); dispatch_async(_cachingQueue, ^{ - CGImageRef imageRef = [self->_animatedImage imageAtIndex:frameIndex cacheProvider:self]; - PINLog(@"Generating: %lu", (unsigned long)frameIndex); - - if (imageRef) { - [self->_lock lockWithBlock:^{ - [self->_frameCache setObject:(__bridge id _Nonnull)(imageRef) forKey:@(frameIndex)]; - self->_playbackReady--; - NSAssert(self->_playbackReady >= 0, @"playback ready is less than zero, something is wrong :("); - - PINLog(@"Frames left: %ld", (long)_playbackReady); - - dispatch_block_t notify = nil; - if (self->_playbackReady == 0 && self->_notifyOnReady) { - self->_notifyOnReady = NO; - if (self->_playbackReadyCallback) { - notify = self->_playbackReadyCallback; - [_operationQueue scheduleOperation:^{ - notify(); - }]; - } - } - }]; - } + PINStrongify(self); + [self _cacheWithFrameIndex:frameIndex]; }); } } @@ -333,7 +426,7 @@ - (NSUInteger)framesToCache // If it's been less than 5 seconds, we're not caching CFTimeInterval timeSinceLastWarning = -[self.lastMemoryWarning timeIntervalSinceNow]; - if (self.weAreTheProblem || timeSinceLastWarning < kSecondsAfterMemWarningToMinimumCache) { + if (self.cachingFramesCausingMemoryWarnings || timeSinceLastWarning < kSecondsAfterMemWarningToMinimumCache) { framesToCache = 0; } else if (timeSinceLastWarning < kSecondsAfterMemWarningToLargeCache) { framesToCache = MIN(framesToCache, kFramesToRenderMinimum); @@ -353,7 +446,10 @@ - (BOOL)playbackReady { __block BOOL playbackReady = NO; [_lock lockWithBlock:^{ - playbackReady = _playbackReady == 0; + if (self->_playbackReady == NO) { + self->_playbackReady = self->_frameRenderCount == 0; + } + playbackReady = self->_playbackReady; }]; return playbackReady; } @@ -362,7 +458,7 @@ - (dispatch_block_t)playbackReadyCallback { __block dispatch_block_t playbackReadyCallback = nil; [_lock lockWithBlock:^{ - playbackReadyCallback = _playbackReadyCallback; + playbackReadyCallback = self->_playbackReadyCallback; }]; return playbackReadyCallback; } @@ -370,7 +466,7 @@ - (dispatch_block_t)playbackReadyCallback - (void)setPlaybackReadyCallback:(dispatch_block_t)playbackReadyCallback { [_lock lockWithBlock:^{ - _playbackReadyCallback = playbackReadyCallback; + self->_playbackReadyCallback = playbackReadyCallback; }]; } @@ -378,7 +474,7 @@ - (PINAnimatedImageInfoReady)coverImageReadyCallback { __block PINAnimatedImageInfoReady coverImageReadyCallback; [_lock lockWithBlock:^{ - coverImageReadyCallback = _coverImageReadyCallback; + coverImageReadyCallback = self->_coverImageReadyCallback; }]; return coverImageReadyCallback; } @@ -386,7 +482,19 @@ - (PINAnimatedImageInfoReady)coverImageReadyCallback - (void)setCoverImageReadyCallback:(PINAnimatedImageInfoReady)coverImageReadyCallback { [_lock lockWithBlock:^{ - _coverImageReadyCallback = coverImageReadyCallback; + self->_coverImageReadyCallback = coverImageReadyCallback; + }]; +} + +- (void)_clearAnimatedImageCache +{ + [self->_lock lockWithBlock:^{ + self->_cacheCleared = YES; + self->_coverImage = nil; + [self->_cachedOrCachingFrames enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { + [self->_frameCache removeObjectForKey:@(idx)]; + }]; + [self->_cachedOrCachingFrames removeAllIndexes]; }]; } @@ -395,13 +503,11 @@ - (void)setCoverImageReadyCallback:(PINAnimatedImageInfoReady)coverImageReadyCal */ - (void)clearAnimatedImageCache { - [_lock lockWithBlock:^{ - _coverImage = nil; - [_cachedOrCachingFrames enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { - [_frameCache removeObjectForKey:@(idx)]; - }]; - [_cachedOrCachingFrames removeAllIndexes]; - }]; + PINWeakify(self); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + PINStrongify(self); + [self _clearAnimatedImageCache]; + }); } # pragma mark - PINCachedAnimatedFrameProvider @@ -410,7 +516,7 @@ - (CGImageRef)cachedFrameImageAtIndex:(NSUInteger)index { __block CGImageRef imageRef; [_lock lockWithBlock:^{ - imageRef = (__bridge CGImageRef)[_frameCache objectForKey:@(index)]; + imageRef = (__bridge CGImageRef)[self->_frameCache objectForKey:@(index)]; if (imageRef) { CGImageRetain(imageRef); CFAutorelease(imageRef); diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m index 9220667..2b5016f 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m @@ -16,6 +16,7 @@ #endif #import "PINImage+DecodedImage.h" +#import "NSData+ImageDetectors.h" @interface PINGIFAnimatedImage () { @@ -36,13 +37,14 @@ @implementation PINGIFAnimatedImage - (instancetype)initWithAnimatedImageData:(NSData *)animatedImageData { if (self = [super init]) { + _animatedImageData = animatedImageData; _imageSource = CGImageSourceCreateWithData((CFDataRef)animatedImageData, (CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceTypeIdentifierHint: (__bridge NSString *)kUTTypeGIF, (__bridge NSString *)kCGImageSourceShouldCache: (__bridge NSNumber *)kCFBooleanFalse}); - if (_imageSource) { + if (_imageSource && [animatedImageData pin_isGIF]) { _frameCount = (uint32_t)CGImageSourceGetCount(_imageSource); NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(_imageSource, nil); _loopCount = (uint32_t)[[[imageProperties objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary] @@ -59,6 +61,8 @@ - (instancetype)initWithAnimatedImageData:(NSData *)animatedImageData for (NSUInteger frameIdx = 0; frameIdx < _frameCount; frameIdx++) { _durations[frameIdx] = [PINGIFAnimatedImage frameDurationAtIndex:frameIdx source:_imageSource]; } + } else { + return nil; } } return self; @@ -79,7 +83,13 @@ + (Float32)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)sourc } } - if (frameDuration < kPINAnimatedImageMinimumDuration) { + static dispatch_once_t onceToken; + static Float32 maximumFrameDuration; + dispatch_once(&onceToken, ^{ + maximumFrameDuration = 1.0 / [PINAnimatedImage maximumFramesPerSecond]; + }); + + if (frameDuration < maximumFrameDuration) { frameDuration = kPINAnimatedImageDefaultDuration; } @@ -96,6 +106,11 @@ - (void)dealloc } } +- (NSData *)data +{ + return _animatedImageData; +} + - (size_t)frameCount { return _frameCount; @@ -118,7 +133,7 @@ - (uint32_t)height - (uint32_t)bytesPerFrame { - return _width * _height * 3; + return _width * _height * 4; } - (NSError *)error diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINMemMapAnimatedImage.h b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINMemMapAnimatedImage.h deleted file mode 100644 index de960d0..0000000 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINMemMapAnimatedImage.h +++ /dev/null @@ -1,111 +0,0 @@ -// -// PINMemMapAnimatedImage.h -// Pods -// -// Created by Garrett Moon on 3/18/16. -// -// - -#import - -#if PIN_TARGET_IOS -#import -#elif PIN_TARGET_MAC -#import -#endif - -#import "PINAnimatedImage.h" -#import "PINRemoteImageMacros.h" - -#define PINMemMapAnimatedImageDebug 0 - -/** - PINMemMapAnimatedImage is a class which decodes GIFs to memory mapped files on disk. Like PINRemoteImageManager, - it will only decode a GIF one time, regardless of the number of the number of PINMemMapAnimatedImages created with - the same NSData. - - PINMemMapAnimatedImage's are also decoded chunks at a time, writing each chunk to a separate file. This allows callback - and playback to start before the GIF is completely decoded. If a frame is requested beyond what has been processed, - nil will be returned. Because a fileReady is called on each chunk completion, you can pause playback if you hit a nil - frame until you receive another fileReady call. - - Internally, PINMemMapAnimatedImage attempts to keep only the files it needs open – the last file associated with the requested - frame and the one after (to prime). - - It's important to note that until infoCompletion is called, it is unsafe to access many of the methods on PINMemMapAnimatedImage. - */ -@interface PINMemMapAnimatedImage : PINAnimatedImage - -- (instancetype)initWithAnimatedImageData:(NSData *)animatedImageData NS_DESIGNATED_INITIALIZER; - -/** - A block to be called on when GIF info has been processed. Status will == PINAnimatedImageStatusInfoProcessed - */ -@property (nonatomic, strong, readwrite) PINAnimatedImageInfoReady infoCompletion; -/** - A block to be called whenever a new file is done being processed. You can start (or resume) playback when you - get this callback, though it's possible for playback to catch up to the decoding and you'll need to pause. - */ -@property (nonatomic, strong, readwrite) dispatch_block_t fileReady; -/** - A block to be called when the animated image is fully decoded and written to disk. - */ -@property (nonatomic, strong, readwrite) dispatch_block_t animatedImageReady; - -/** - The current status of the animated image. - */ -@property (nonatomic, assign, readwrite) PINAnimatedImageStatus status; - -/** - A helper function which references status to check if the coverImage is ready. - */ -@property (nonatomic, readonly) BOOL coverImageReady; -/** - A helper function which references status to check if playback is ready. - */ -@property (nonatomic, readonly) BOOL playbackReady; -/** - The first frame / cover image of the animated image. - @warning Access to this property before status == PINAnimatedImageStatusInfoProcessed is undefined. You can check coverImageReady too. - */ -@property (nonatomic, readonly) PINImage *coverImage; -/** - The total duration of one loop of playback. - @warning Access to this property before status == PINAnimatedImageStatusInfoProcessed is undefined. - */ -@property (nonatomic, readonly) CFTimeInterval totalDuration; -/** - The number of times to loop the animated image. Returns 0 if looping should occur infinitely. - @warning Access to this property before status == PINAnimatedImageStatusInfoProcessed is undefined. - */ -@property (nonatomic, readonly) size_t loopCount; -/** - The total number of frames in the animated image. - @warning Access to this property before status == PINAnimatedImageStatusInfoProcessed is undefined. - */ -@property (nonatomic, readonly) size_t frameCount; -/** - Any processing error that may have occured. - */ -@property (nonatomic, readonly) NSError *error; - -/** - The image at the frame index passed in. - @param index The index of the frame to retrieve. - @param cacheProvider An optional cache provider. Unneccesary to pass into this class. - @warning Access to this property before status == PINAnimatedImageStatusInfoProcessed is undefined. - */ -- (CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(id)cacheProvider; -/** - The duration of the frame of the passed in index. - @param index The index of the frame to retrieve the duration it should be shown for. - @warning Access to this property before status == PINAnimatedImageStatusInfoProcessed is undefined. - */ -- (CFTimeInterval)durationAtIndex:(NSUInteger)index; -/** - Clears out the strong references to any memory maps that are being held. - */ -- (void)clearAnimatedImageCache; - -@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINMemMapAnimatedImage.m b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINMemMapAnimatedImage.m deleted file mode 100644 index 272c9c6..0000000 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINMemMapAnimatedImage.m +++ /dev/null @@ -1,489 +0,0 @@ -// -// PINMemMapAnimatedImage.m -// Pods -// -// Created by Garrett Moon on 3/18/16. -// -// - -#import "PINMemMapAnimatedImage.h" - -#import "PINRemoteLock.h" -#import "PINGIFAnimatedImageManager.h" - -#import "NSData+ImageDetectors.h" - -static const size_t kPINAnimatedImageBitsPerComponent = 8; - -@class PINSharedAnimatedImage; - -@interface PINMemMapAnimatedImage () -{ - PINRemoteLock *_completionLock; - PINRemoteLock *_dataLock; - - NSData *_currentData; - NSData *_nextData; -} - -@property (atomic, strong, readwrite) PINSharedAnimatedImage *sharedAnimatedImage; -@property (atomic, assign, readwrite) BOOL infoCompleted; - -@end - -@implementation PINMemMapAnimatedImage - -- (instancetype)init -{ - return [self initWithAnimatedImageData:nil]; -} - -- (instancetype)initWithAnimatedImageData:(NSData *)animatedImageData -{ - if (self = [super init]) { - _completionLock = [[PINRemoteLock alloc] initWithName:@"PINMemMapAnimatedImage completion lock"]; - _dataLock = [[PINRemoteLock alloc] initWithName:@"PINMemMapAnimatedImage data lock"]; - - NSAssert(animatedImageData != nil, @"animatedImageData must not be nil."); - - [[PINGIFAnimatedImageManager sharedManager] animatedPathForImageData:animatedImageData infoCompletion:^(PINImage *coverImage, PINSharedAnimatedImage *shared) { - self.sharedAnimatedImage = shared; - self.infoCompleted = YES; - - [_completionLock lockWithBlock:^{ - if (_infoCompletion) { - _infoCompletion(coverImage); - _infoCompletion = nil; - } - }]; - } completion:^(BOOL completed, NSString *path, NSError *error) { - BOOL success = NO; - - if (completed && error == nil) { - success = YES; - } - - [_completionLock lockWithBlock:^{ - if (_fileReady) { - _fileReady(); - } - }]; - - if (success) { - [_completionLock lockWithBlock:^{ - if (_animatedImageReady) { - _animatedImageReady(); - _fileReady = nil; - _animatedImageReady = nil; - } - }]; - } - }]; - } - return self; -} - -- (void)setInfoCompletion:(PINAnimatedImageInfoReady)infoCompletion -{ - [_completionLock lockWithBlock:^{ - _infoCompletion = infoCompletion; - }]; -} - -- (void)setAnimatedImageReady:(dispatch_block_t)animatedImageReady -{ - [_completionLock lockWithBlock:^{ - _animatedImageReady = animatedImageReady; - }]; -} - -- (void)setFileReady:(dispatch_block_t)fileReady -{ - [_completionLock lockWithBlock:^{ - _fileReady = fileReady; - }]; -} - -- (PINImage *)coverImageWithMemoryMap:(NSData *)memoryMap width:(UInt32)width height:(UInt32)height bitsPerPixel:(UInt32)bitsPerPixel bitmapInfo:(CGBitmapInfo)bitmapInfo -{ - CGImageRef imageRef = [[self class] imageAtIndex:0 inMemoryMap:memoryMap width:width height:height bitsPerPixel:bitsPerPixel bitmapInfo:bitmapInfo]; -#if PIN_TARGET_IOS - return [UIImage imageWithCGImage:imageRef]; -#elif PIN_TARGET_MAC - return [[NSImage alloc] initWithCGImage:imageRef size:CGSizeMake(width, height)]; -#endif -} - -void releaseData(void *data, const void *imageData, size_t size); - -void releaseData(void *data, const void *imageData, size_t size) -{ - CFRelease(data); -} - -- (CGImageRef)imageAtIndex:(NSUInteger)index inSharedImageFiles:(NSArray *)imageFiles width:(UInt32)width height:(UInt32)height bitsPerPixel:(UInt32)bitsPerPixel bitmapInfo:(CGBitmapInfo)bitmapInfo -{ - if (self.status == PINAnimatedImageStatusError) { - return nil; - } - - for (NSUInteger fileIdx = 0; fileIdx < imageFiles.count; fileIdx++) { - PINSharedAnimatedImageFile *imageFile = imageFiles[fileIdx]; - if (index < imageFile.frameCount) { - __block NSData *memoryMappedData = nil; - [_dataLock lockWithBlock:^{ - memoryMappedData = imageFile.memoryMappedData; - _currentData = memoryMappedData; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [_dataLock lockWithBlock:^{ - _nextData = (fileIdx + 1 < imageFiles.count) ? imageFiles[fileIdx + 1].memoryMappedData : imageFiles[0].memoryMappedData; - }]; - }); - }]; - return [[self class] imageAtIndex:index inMemoryMap:memoryMappedData width:width height:height bitsPerPixel:bitsPerPixel bitmapInfo:bitmapInfo]; - } else { - index -= imageFile.frameCount; - } - } - //image file not done yet :( - return nil; -} - -- (CFTimeInterval)durationAtIndex:(NSUInteger)index -{ - return self.durations[index]; -} - -+ (CGImageRef)imageAtIndex:(NSUInteger)index inMemoryMap:(NSData *)memoryMap width:(UInt32)width height:(UInt32)height bitsPerPixel:(UInt32)bitsPerPixel bitmapInfo:(CGBitmapInfo)bitmapInfo -{ - if (memoryMap == nil) { - return nil; - } - - Float32 outDuration; - - const size_t imageLength = width * height * bitsPerPixel / 8; - - //frame duration + previous images - NSUInteger offset = sizeof(UInt32) + (index * (imageLength + sizeof(outDuration))); - - [memoryMap getBytes:&outDuration range:NSMakeRange(offset, sizeof(outDuration))]; - - BytePtr imageData = (BytePtr)[memoryMap bytes]; - imageData += offset + sizeof(outDuration); - - NSAssert(offset + sizeof(outDuration) + imageLength <= memoryMap.length, @"Requesting frame beyond data bounds"); - - //retain the memory map, it will be released when releaseData is called - CFRetain((CFDataRef)memoryMap); - CGDataProviderRef dataProvider = CGDataProviderCreateWithData((void *)memoryMap, imageData, imageLength, releaseData); - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef imageRef = CGImageCreate(width, - height, - kPINAnimatedImageBitsPerComponent, - bitsPerPixel, - bitsPerPixel / 8 * width, - colorSpace, - bitmapInfo, - dataProvider, - NULL, - NO, - kCGRenderingIntentDefault); - if (imageRef) { - CFAutorelease(imageRef); - } - - CGColorSpaceRelease(colorSpace); - CGDataProviderRelease(dataProvider); - - return imageRef; -} - -// Although the following methods are unused, they could be in the future for restoring decoded images off disk (they're cleared currently). -+ (UInt32)widthFromMemoryMap:(NSData *)memoryMap -{ - UInt32 width; - [memoryMap getBytes:&width range:NSMakeRange(2, sizeof(width))]; - return width; -} - -+ (UInt32)heightFromMemoryMap:(NSData *)memoryMap -{ - UInt32 height; - [memoryMap getBytes:&height range:NSMakeRange(6, sizeof(height))]; - return height; -} - -+ (UInt32)bitsPerPixelFromMemoryMap:(NSData *)memoryMap -{ - UInt32 bitsPerPixel; - [memoryMap getBytes:&bitsPerPixel range:NSMakeRange(10, sizeof(bitsPerPixel))]; - return bitsPerPixel; -} - -+ (UInt32)loopCountFromMemoryMap:(NSData *)memoryMap -{ - UInt32 loopCount; - [memoryMap getBytes:&loopCount range:NSMakeRange(14, sizeof(loopCount))]; - return loopCount; -} - -+ (UInt32)frameCountFromMemoryMap:(NSData *)memoryMap -{ - UInt32 frameCount; - [memoryMap getBytes:&frameCount range:NSMakeRange(18, sizeof(frameCount))]; - return frameCount; -} - -//durations should be a buffer of size Float32 * frameCount -+ (Float32 *)createDurations:(Float32 *)durations fromMemoryMap:(NSData *)memoryMap frameCount:(UInt32)frameCount frameSize:(NSUInteger)frameSize totalDuration:(nonnull CFTimeInterval *)totalDuration -{ - *totalDuration = 0; - [memoryMap getBytes:&durations range:NSMakeRange(22, sizeof(Float32) * frameCount)]; - - for (NSUInteger idx = 0; idx < frameCount; idx++) { - *totalDuration += durations[idx]; - } - - return durations; -} - -- (Float32 *)durations -{ - NSAssert([self infoReady], @"info must be ready"); - return self.sharedAnimatedImage.durations; -} - -- (CFTimeInterval)totalDuration -{ - NSAssert([self infoReady], @"info must be ready"); - return self.sharedAnimatedImage.totalDuration; -} - -- (size_t)loopCount -{ - NSAssert([self infoReady], @"info must be ready"); - return self.sharedAnimatedImage.loopCount; -} - -- (size_t)frameCount -{ - NSAssert([self infoReady], @"info must be ready"); - return self.sharedAnimatedImage.frameCount; -} - -- (uint32_t)width -{ - NSAssert([self infoReady], @"info must be ready"); - return self.sharedAnimatedImage.width; -} - -- (uint32_t)height -{ - NSAssert([self infoReady], @"info must be ready"); - return self.sharedAnimatedImage.height; -} - -- (uint32_t)bytesPerFrame -{ - NSAssert([self infoReady], @"info must be ready"); - return self.sharedAnimatedImage.width * self.sharedAnimatedImage.height * 3; -} - -- (NSError *)error -{ - return self.sharedAnimatedImage.error; -} - -- (PINAnimatedImageStatus)status -{ - if (self.sharedAnimatedImage == nil) { - return PINAnimatedImageStatusUnprocessed; - } - return self.sharedAnimatedImage.status; -} - -- (nullable CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(nullable id)cacheProvider -{ - return [self imageAtIndex:index - inSharedImageFiles:self.sharedAnimatedImage.maps - width:(UInt32)self.sharedAnimatedImage.width - height:(UInt32)self.sharedAnimatedImage.height - bitsPerPixel:(UInt32)self.sharedAnimatedImage.bitsPerPixel - bitmapInfo:self.sharedAnimatedImage.bitmapInfo]; -} - -- (PINImage *)coverImage -{ - NSAssert(self.coverImageReady, @"cover image must be ready."); - return self.sharedAnimatedImage.coverImage; -} - -- (BOOL)infoReady -{ - return self.infoCompleted; -} - -- (BOOL)coverImageReady -{ - return self.status == PINAnimatedImageStatusInfoProcessed || self.status == PINAnimatedImageStatusFirstFileProcessed || self.status == PINAnimatedImageStatusProcessed; -} - -- (BOOL)playbackReady -{ - return self.status == PINAnimatedImageStatusProcessed || self.status == PINAnimatedImageStatusFirstFileProcessed; -} - -- (void)clearAnimatedImageCache -{ - [_dataLock lockWithBlock:^{ - _currentData = nil; - _nextData = nil; - }]; -} - -@end - -@implementation PINSharedAnimatedImage - -- (instancetype)init -{ - if (self = [super init]) { - _coverImageLock = [[PINRemoteLock alloc] initWithName:@"PINSharedAnimatedImage cover image lock"]; - _completions = @[]; - _infoCompletions = @[]; - _maps = @[]; - } - return self; -} - -- (void)setInfoProcessedWithCoverImage:(PINImage *)coverImage UUID:(NSUUID *)UUID durations:(Float32 *)durations totalDuration:(CFTimeInterval)totalDuration loopCount:(size_t)loopCount frameCount:(size_t)frameCount width:(uint32_t)width height:(uint32_t)height bitsPerPixel:(size_t)bitsPerPixel bitmapInfo:(CGBitmapInfo)bitmapInfo -{ - NSAssert(_status == PINAnimatedImageStatusUnprocessed, @"Status should be unprocessed."); - [_coverImageLock lockWithBlock:^{ - _coverImage = coverImage; - }]; - _UUID = UUID; - _durations = (Float32 *)malloc(sizeof(Float32) * frameCount); - memcpy(_durations, durations, sizeof(Float32) * frameCount); - _totalDuration = totalDuration; - _loopCount = loopCount; - _frameCount = frameCount; - _width = width; - _height = height; - _bitsPerPixel = bitsPerPixel; - _bitmapInfo = bitmapInfo; - _status = PINAnimatedImageStatusInfoProcessed; -} - -- (void)dealloc -{ - NSAssert(self.completions.count == 0 && self.infoCompletions.count == 0, @"Shouldn't be dealloc'd if we have a completion or an infoCompletion"); - - //Clean up shared files. - - //Get references to maps and UUID so the below block doesn't reference self. - NSArray *maps = self.maps; - self.maps = nil; - NSUUID *UUID = self.UUID; - - if (maps.count > 0) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - //ignore errors - [[NSFileManager defaultManager] removeItemAtPath:[PINGIFAnimatedImageManager filePathWithTemporaryDirectory:[PINGIFAnimatedImageManager temporaryDirectory] UUID:UUID count:0] error:nil]; - for (PINSharedAnimatedImageFile *file in maps) { - [[NSFileManager defaultManager] removeItemAtPath:file.path error:nil]; - } - }); - } - free(_durations); -} - -- (PINImage *)coverImage -{ - __block PINImage *coverImage = nil; - [_coverImageLock lockWithBlock:^{ - if (_coverImage == nil) { - CGImageRef imageRef = [PINMemMapAnimatedImage imageAtIndex:0 inMemoryMap:self.maps[0].memoryMappedData width:(UInt32)self.width height:(UInt32)self.height bitsPerPixel:(UInt32)self.bitsPerPixel bitmapInfo:self.bitmapInfo]; -#if PIN_TARGET_IOS - coverImage = [UIImage imageWithCGImage:imageRef]; -#elif PIN_TARGET_MAC - coverImage = [[NSImage alloc] initWithCGImage:imageRef size:CGSizeMake(self.width, self.height)]; -#endif - _coverImage = coverImage; - } else { - coverImage = _coverImage; - } - }]; - - return coverImage; -} - -@end - -@implementation PINSharedAnimatedImageFile - -@synthesize memoryMappedData = _memoryMappedData; -@synthesize frameCount = _frameCount; - -- (instancetype)init -{ - NSAssert(NO, @"Call initWithPath:"); - return [self initWithPath:nil]; -} - -- (instancetype)initWithPath:(NSString *)path -{ - if (self = [super init]) { - _lock = [[PINRemoteLock alloc] initWithName:@"PINSharedAnimatedImageFile lock"]; - _path = path; - } - return self; -} - -- (UInt32)frameCount -{ - __block UInt32 frameCount; - [_lock lockWithBlock:^{ - if (_frameCount == 0) { - NSData *memoryMappedData = _memoryMappedData; - if (memoryMappedData == nil) { - memoryMappedData = [self loadMemoryMappedData]; - } - [memoryMappedData getBytes:&_frameCount range:NSMakeRange(0, sizeof(_frameCount))]; - } - frameCount = _frameCount; - }]; - - return frameCount; -} - -- (NSData *)memoryMappedData -{ - __block NSData *memoryMappedData; - [_lock lockWithBlock:^{ - memoryMappedData = _memoryMappedData; - if (memoryMappedData == nil) { - memoryMappedData = [self loadMemoryMappedData]; - } - }]; - return memoryMappedData; -} - -//must be called within lock -- (NSData *)loadMemoryMappedData -{ - NSError *error = nil; - //local variable shenanigans due to weak ivar _memoryMappedData - NSData *memoryMappedData = [NSData dataWithContentsOfFile:self.path options:NSDataReadingMappedAlways error:&error]; - if (error) { -#if PINMemMapAnimatedImageDebug - NSLog(@"Could not memory map data: %@", error); -#endif - } else { - _memoryMappedData = memoryMappedData; - } - return memoryMappedData; -} - -@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINWebPAnimatedImage.m b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINWebPAnimatedImage.m index 1c297d9..da13aa4 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINWebPAnimatedImage.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINWebPAnimatedImage.m @@ -12,7 +12,11 @@ #import "NSData+ImageDetectors.h" +#if SWIFT_PACKAGE +@import libwebp; +#else #import "webp/demux.h" +#endif @interface PINWebPAnimatedImage () { @@ -25,6 +29,7 @@ @interface PINWebPAnimatedImage () BOOL _hasAlpha; size_t _frameCount; size_t _loopCount; + CGColorRef _backgroundColor; CFTimeInterval *_durations; NSError *_error; } @@ -54,19 +59,36 @@ - (instancetype)initWithAnimatedImageData:(NSData *)animatedImageData uint32_t flags = WebPDemuxGetI(_demux, WEBP_FF_FORMAT_FLAGS); _hasAlpha = flags & ALPHA_FLAG; _durations = malloc(sizeof(CFTimeInterval) * _frameCount); + + uint32_t backgroundColorInt = WebPDemuxGetI(_demux, WEBP_FF_BACKGROUND_COLOR); + CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); + CGFloat components[4]; + components[0] = (CGFloat)(((backgroundColorInt & 0xFF000000) >> 24)/255.0); + components[1] = (CGFloat)(((backgroundColorInt & 0x00FF0000) >> 16)/255.0); + components[2] = (CGFloat)(((backgroundColorInt & 0x0000FF00) >> 8)/255.0); + components[3] = (CGFloat)((backgroundColorInt & 0x000000FF)/255.0); + _backgroundColor = CGColorCreate(rgbColorSpace, components); + CGColorSpaceRelease(rgbColorSpace); // Iterate over the frames to gather duration WebPIterator iter; if (WebPDemuxGetFrame(_demux, 1, &iter)) { do { CFTimeInterval duration = iter.duration / 1000.0; - if (duration < kPINAnimatedImageMinimumDuration) { + static dispatch_once_t onceToken; + static CFTimeInterval maximumDuration; + dispatch_once(&onceToken, ^{ + maximumDuration = 1.0 / [PINAnimatedImage maximumFramesPerSecond]; + }); + if (duration < maximumDuration) { duration = kPINAnimatedImageDefaultDuration; } _durations[iter.frame_num - 1] = duration; } while (WebPDemuxNextFrame(&iter)); WebPDemuxReleaseIterator(&iter); } + } else { + return nil; } } return self; @@ -80,6 +102,14 @@ - (void)dealloc if (_durations) { free(_durations); } + if (_backgroundColor) { + CGColorRelease(_backgroundColor); + } +} + +- (NSData *)data +{ + return _animatedImageData; } - (size_t)frameCount @@ -117,7 +147,13 @@ - (CFTimeInterval)durationAtIndex:(NSUInteger)index return _durations[index]; } -- (CGImageRef)canvasWithPreviousFrame:(CGImageRef)previousFrame image:(CGImageRef)image atRect:(CGRect)rect +- (CGImageRef)canvasWithPreviousFrame:(CGImageRef)previousFrame + previousFrameRect:(CGRect)previousFrameRect + clearPreviousFrame:(BOOL)clearPreviousFrame + backgroundColor:(CGColorRef)backgroundColor + image:(CGImageRef)image + clearCurrentFrame:(BOOL)clearCurrentFrame + atRect:(CGRect)rect { CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, @@ -127,13 +163,23 @@ - (CGImageRef)canvasWithPreviousFrame:(CGImageRef)previousFrame image:(CGImageRe 0, colorSpaceRef, _hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNone); + if (backgroundColor) { + CGContextSetFillColorWithColor(context, backgroundColor); + } if (previousFrame) { CGContextDrawImage(context, CGRectMake(0, 0, _width, _height), previousFrame); + if (clearPreviousFrame) { + CGContextFillRect(context, previousFrameRect); + } } if (image) { - CGContextDrawImage(context, CGRectMake(rect.origin.x, _height - rect.size.height - rect.origin.y, rect.size.width, rect.size.height), image); + CGRect currentRect = CGRectMake(rect.origin.x, _height - rect.size.height - rect.origin.y, rect.size.width, rect.size.height); + if (clearCurrentFrame) { + CGContextFillRect(context, currentRect); + } + CGContextDrawImage(context, currentRect, image); } CGImageRef canvas = CGBitmapContextCreateImage(context); @@ -161,7 +207,7 @@ - (CGImageRef)rawImageWithIterator:(WebPIterator)iterator } if (data) { - CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, _width * _height * pixelLength, releaseData); + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, iterator.width * iterator.height * pixelLength, releaseData); CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; @@ -224,13 +270,30 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(nullable id 0) { // Sadly, we need to draw *all* the frames from the previous key frame previousIterator to the current one :( CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); @@ -241,15 +304,32 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(nullable id= length) break; + +static inline BOOL advancePositionWithCount(NSUInteger *position, NSUInteger length, NSUInteger count) +{ + if (*position + count >= length) { + return NO; + } + *position = *position + count; + + return YES; +} + +static inline BOOL advancePositionWithBytes(NSUInteger *position, Byte *bytes, NSUInteger length, NSUInteger count) +{ + BOOL readAgain; + do { + readAgain = NO; + if (*position + count >= length ) { + return NO; + } + *position = *position + count; + NSUInteger bytesToAdvance = *(bytes + *position); + if (bytesToAdvance == 0xFF) { + readAgain = YES; + count = 0; + } + // Advance the byte read as well. + bytesToAdvance++; + + if (*position + bytesToAdvance >= length) { + return NO; + } + *position = *position + bytesToAdvance; + } while (readAgain); + + return YES; +} + +- (BOOL)pin_isAnimatedGIF +{ + if ([self pin_isGIF] == NO) { + return NO; + } + + Byte *bytes = (Byte *)self.bytes; + NSUInteger length = self.length; + NSUInteger position = 0; + NSUInteger GCECount = 0; + + while (bytes && position < length) { + // Look for Graphic Control Extension + if (*(bytes + position) == 0x21) { + if (!advancePositionWithCount(&position, length, 1)) break; + if (*(bytes + position) == 0xF9) { + GCECount++; + if (GCECount > 1) { + break; + } + // Found GCE, advance to image. Next byte is size of GCE + if (!advancePositionWithBytes(&position, bytes, length, 1)) break; + // Advance 1 for 00 at the end of GCE + if (!advancePositionWithCount(&position, length, 1)) break; + // Advance image descriptor + if (!advancePositionWithCount(&position, length, 11)) break; + // Advance image + if (!advancePositionWithBytes(&position, bytes, length, 0)) break; + // Advance 1 for 00 at the end of image + if (!advancePositionWithCount(&position, length, 1)) break; + } + continue; + } + if (!advancePositionWithCount(&position, length, 1)) break; + } + + return GCECount > 1; +} + #if PIN_WEBP - (BOOL)pin_isWebP { diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSHTTPURLResponse+MaxAge.h b/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSHTTPURLResponse+MaxAge.h new file mode 100644 index 0000000..a145372 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSHTTPURLResponse+MaxAge.h @@ -0,0 +1,14 @@ +// +// NSHTTPURLResponse+MaxAge.m +// +// Created by Kevin Smith on 6/15/18. +// +// + +#import + +@interface NSHTTPURLResponse (MaxAge) + +- (NSNumber *)findMaxAge; + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSHTTPURLResponse+MaxAge.m b/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSHTTPURLResponse+MaxAge.m new file mode 100644 index 0000000..6acdcc9 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSHTTPURLResponse+MaxAge.m @@ -0,0 +1,71 @@ +// +// NSHTTPURLResponse+MaxAge.m +// +// Created by Kevin Smith on 6/15/18. +// +// + +#import "NSHTTPURLResponse+MaxAge.h" + +@implementation NSHTTPURLResponse (MaxAge) + +static NSDateFormatter *sharedFormatter; +static dispatch_once_t sharedFormatterToken; + ++ (NSDateFormatter *)RFC7231PreferredDateFormatter +{ + dispatch_once(&sharedFormatterToken, ^{ + NSLocale *enUSPOSIXLocale; + + sharedFormatter = [[NSDateFormatter alloc] init]; + + enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + + [sharedFormatter setLocale:enUSPOSIXLocale]; + [sharedFormatter setDateFormat:@"E, d MMM yyyy HH:mm:ss Z"]; + + }); + return sharedFormatter; +} + +- (NSNumber *)findMaxAge +{ + NSDictionary * headerFields = [self allHeaderFields]; + NSNumber *maxAge = nil; + + for (NSString * component in [headerFields[@"Cache-Control"] componentsSeparatedByString:@","]) { + NSString * trimmed = [[component stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] lowercaseString]; + + if ([trimmed isEqualToString:@"no-store"] || [trimmed isEqualToString:@"must-revalidate"] || [trimmed isEqualToString:@"no-cache"]) { + maxAge = @(0); + break; + } else { + // max-age + NSArray * split = [trimmed componentsSeparatedByString:@"max-age="]; + if ([split count] == 2) { + // if the max-age provided is invalid (does not parse into an + // int), we wind up with 0 which will be treated as do-not-cache. + // This is the RFC defined behavior for a malformed "expires" header, + // and while I cannot find any explicit instruction of how to behave + // with a malformed "max-age" header, it seems like a reasonable approach. + maxAge = @([split[1] integerValue]); + } else if ([split count] > 2) { + // very weird case "maxage=maxage=123" + maxAge = @(0); + } + } + } + + // If there is a Cache-Control header with the "max-age" directive in the response, the Expires header is ignored. + if (!maxAge && headerFields[@"Expires"]) { + NSString * expires = headerFields[@"Expires"]; + NSDate * date = [[NSHTTPURLResponse RFC7231PreferredDateFormatter] dateFromString:expires]; + + // Invalid dates (notably "0") or dates in the past must not be cached (RFC7231 5.3) + maxAge = @((NSInteger) MAX(([date timeIntervalSinceNow]), 0)); + } + + return maxAge; +} + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.h b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.h index 657d94f..08d0e5a 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.h @@ -8,14 +8,14 @@ #import +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC #import #endif -#import "PINRemoteImageMacros.h" - #if !PIN_TARGET_IOS @interface NSImage (PINiOSMapping) diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.m b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.m index e7f9271..da75e5b 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+DecodedImage.m @@ -16,6 +16,49 @@ #import "NSData+ImageDetectors.h" +NS_INLINE BOOL pin_CGImageRefIsOpaque(CGImageRef imageRef) { + CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef); + switch (alpha) { + case kCGImageAlphaNone: + case kCGImageAlphaNoneSkipLast: + case kCGImageAlphaNoneSkipFirst: + return YES; + default: + return NO; + } +} + +#if PIN_TARGET_IOS +NS_INLINE void pin_degreesFromOrientation(UIImageOrientation orientation, void (^completion)(CGFloat degrees, BOOL horizontalFlip, BOOL verticalFlip)) { + switch (orientation) { + case UIImageOrientationUp: // default orientation + completion(0.0, NO, NO); + break; + case UIImageOrientationDown: // 180 deg rotation + completion(180.0, NO, NO); + break; + case UIImageOrientationLeft: + completion(270.0, NO, NO); // 90 deg CCW + break; + case UIImageOrientationRight: + completion(90.0, NO, NO); // 90 deg CW + break; + case UIImageOrientationUpMirrored: // as above but image mirrored along other axis. horizontal flip + completion(0.0, YES, NO); + break; + case UIImageOrientationDownMirrored: // horizontal flip + completion(180.0, YES, NO); + break; + case UIImageOrientationLeftMirrored: // vertical flip + completion(270.0, NO, YES); + break; + case UIImageOrientationRightMirrored: // vertical flip + completion(90.0, NO, YES); + break; + } +} +#endif + #if !PIN_TARGET_IOS @implementation NSImage (PINiOSMapping) @@ -79,9 +122,6 @@ + (PINImage *)pin_decodedImageWithData:(NSData *)data skipDecodeIfPossible:(BOOL return nil; } - if ([data pin_isGIF]) { - return [PINImage imageWithData:data]; - } #if PIN_WEBP if ([data pin_isWebP]) { return [PINImage pin_imageWithWebPData:data]; @@ -129,23 +169,76 @@ + (PINImage *)pin_decodedImageWithCGImageRef:(CGImageRef)imageRef orientation:(U { #endif #if PIN_TARGET_IOS - return [UIImage imageWithCGImage:[self pin_decodedImageRefWithCGImageRef:imageRef] scale:1.0 orientation:orientation]; + if (@available(iOS 10.0, tvOS 10.0, *)) { + return [self pin_decodedImageUsingGraphicsImageRendererRefWithCGImageRef:imageRef scale:1.0 orientation:orientation]; + } else { + return [UIImage imageWithCGImage:[self pin_decodedImageRefWithCGImageRef:imageRef] scale:1.0 orientation:orientation]; + } #elif PIN_TARGET_MAC return [[NSImage alloc] initWithCGImage:[self pin_decodedImageRefWithCGImageRef:imageRef] size:NSZeroSize]; #endif } -+ (CGImageRef)pin_decodedImageRefWithCGImageRef:(CGImageRef)imageRef -{ - BOOL opaque = YES; - CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef); - if (alpha == kCGImageAlphaFirst || alpha == kCGImageAlphaLast || alpha == kCGImageAlphaOnly || alpha == kCGImageAlphaPremultipliedFirst || alpha == kCGImageAlphaPremultipliedLast) { - opaque = NO; +#if PIN_TARGET_IOS ++ (PINImage *)pin_decodedImageUsingGraphicsImageRendererRefWithCGImageRef:(CGImageRef)imageRef + scale:(CGFloat)scale + orientation:(UIImageOrientation)orientation API_AVAILABLE(ios(10.0), tvos(10.0)) { + UIGraphicsImageRendererFormat *format = nil; + if (@available(iOS 11.0, tvOS 11.0, *)) { + format = [UIGraphicsImageRendererFormat preferredFormat]; + } else { + format = [UIGraphicsImageRendererFormat defaultFormat]; } + format.scale = scale; + format.opaque = pin_CGImageRefIsOpaque(imageRef); + + __block CGFloat radians = 0.0; + __block BOOL doHorizontalFlip = NO; + __block BOOL doVerticalFlip = NO; + + pin_degreesFromOrientation(orientation, ^(CGFloat degrees, BOOL horizontalFlip, BOOL verticalFlip) { + // Convert degrees to radians + radians = [[[NSMeasurement alloc] initWithDoubleValue:degrees + unit:[NSUnitAngle degrees]] + measurementByConvertingToUnit:[NSUnitAngle radians]].doubleValue; + doHorizontalFlip = horizontalFlip; + doVerticalFlip = verticalFlip; + }); + + // Create rotation out of radians + CGAffineTransform transform = CGAffineTransformMakeRotation(radians); + + // Grab image size + CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); + + // Rotate rect by transformation + CGRect rotatedRect = CGRectApplyAffineTransform(CGRectMake(0.0, 0.0, imageSize.width, imageSize.height), transform); + + // Use graphics renderer to render image + UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:rotatedRect.size format:format]; + + return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { + CGContextRef ctx = rendererContext.CGContext; + + // Flip the default coordinate system for iOS/tvOS: https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-CH14-SW4 + CGContextTranslateCTM(ctx, rotatedRect.size.width / 2.0, rotatedRect.size.height / 2.0); + CGContextScaleCTM(ctx, (doHorizontalFlip ? -1.0 : 1.0), (doVerticalFlip ? 1.0 : -1.0)); + + // Apply transformation + CGContextConcatCTM(ctx, transform); + + // Draw image + CGContextDrawImage(ctx, CGRectMake(-(imageSize.width / 2.0), -(imageSize.height / 2.0), imageSize.width, imageSize.height), imageRef); + }]; +} +#endif + ++ (CGImageRef)pin_decodedImageRefWithCGImageRef:(CGImageRef)imageRef +{ CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); - CGBitmapInfo info = opaque ? (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host) : (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); + CGBitmapInfo info = pin_CGImageRefIsOpaque(imageRef) ? (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host) : (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); //Use UIGraphicsBeginImageContext parameters from docs: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIGraphicsBeginImageContextWithOptions diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+ScaledImage.h b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+ScaledImage.h index 11e01a7..b82f931 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+ScaledImage.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+ScaledImage.h @@ -8,14 +8,14 @@ #import +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC #import #endif -#import "PINRemoteImageMacros.h" - @interface PINImage (PINScaledImage) - (PINImage *)pin_scaledImageForKey:(NSString *)key; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.h b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.h index 63df42b..8c38407 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.h @@ -6,6 +6,8 @@ // // +#import "PINRemoteImageMacros.h" + #if PIN_WEBP #if PIN_TARGET_IOS @@ -14,8 +16,6 @@ #import #endif -#import "PINRemoteImageMacros.h" - @interface PINImage (PINWebP) + (PINImage *)pin_imageWithWebPData:(NSData *)webPData; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.m b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.m index ce4503a..d2021d3 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/Categories/PINImage+WebP.m @@ -9,7 +9,12 @@ #import "PINImage+WebP.h" #if PIN_WEBP + +#if SWIFT_PACKAGE +@import libwebp; +#else #import "webp/decode.h" +#endif static void releaseData(void *info, const void *data, size_t size) { diff --git a/Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m b/Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m new file mode 100644 index 0000000..34edd84 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m @@ -0,0 +1,119 @@ +// +// PINAnimatedImageView+PINRemoteImage.m +// Pods +// +// Created by Garrett Moon on 4/19/18. +// + +#import "PINAnimatedImageView+PINRemoteImage.h" + +#import "PINAnimatedImage.h" + +@implementation PINAnimatedImageView (PINRemoteImage) + +- (void)pin_setImageFromURL:(NSURL *)url +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURL:url]; +} + +- (void)pin_setImageFromURL:(NSURL *)url placeholderImage:(PINImage *)placeholderImage +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURL:url placeholderImage:placeholderImage]; +} + +- (void)pin_setImageFromURL:(NSURL *)url completion:(PINRemoteImageManagerImageCompletion)completion +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURL:url completion:completion]; +} + +- (void)pin_setImageFromURL:(NSURL *)url placeholderImage:(PINImage *)placeholderImage completion:(PINRemoteImageManagerImageCompletion)completion +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURL:url placeholderImage:placeholderImage completion:completion]; +} + +- (void)pin_setImageFromURL:(NSURL *)url processorKey:(NSString *)processorKey processor:(PINRemoteImageManagerImageProcessor)processor +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURL:url processorKey:processorKey processor:processor]; +} + +- (void)pin_setImageFromURL:(NSURL *)url placeholderImage:(PINImage *)placeholderImage processorKey:(NSString *)processorKey processor:(PINRemoteImageManagerImageProcessor)processor +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURL:url placeholderImage:placeholderImage processorKey:processorKey processor:processor]; +} + +- (void)pin_setImageFromURL:(NSURL *)url processorKey:(NSString *)processorKey processor:(PINRemoteImageManagerImageProcessor)processor completion:(PINRemoteImageManagerImageCompletion)completion +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURL:url processorKey:processorKey processor:processor completion:completion]; +} + +- (void)pin_setImageFromURL:(NSURL *)url placeholderImage:(PINImage *)placeholderImage processorKey:(NSString *)processorKey processor:(PINRemoteImageManagerImageProcessor)processor completion:(PINRemoteImageManagerImageCompletion)completion +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURLs:@[url] placeholderImage:placeholderImage processorKey:processorKey processor:processor completion:completion]; +} + +- (void)pin_setImageFromURLs:(NSArray *)urls +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURLs:urls]; +} + +- (void)pin_setImageFromURLs:(NSArray *)urls placeholderImage:(PINImage *)placeholderImage +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURLs:urls placeholderImage:placeholderImage]; +} + +- (void)pin_setImageFromURLs:(NSArray *)urls placeholderImage:(PINImage *)placeholderImage completion:(PINRemoteImageManagerImageCompletion)completion +{ + [PINRemoteImageCategoryManager setImageOnView:self fromURLs:urls placeholderImage:placeholderImage completion:completion]; +} + +- (void)pin_cancelImageDownload +{ + [PINRemoteImageCategoryManager cancelImageDownloadOnView:self]; +} + +- (NSUUID *)pin_downloadImageOperationUUID +{ + return [PINRemoteImageCategoryManager downloadImageOperationUUIDOnView:self]; +} + +- (void)pin_setDownloadImageOperationUUID:(NSUUID *)downloadImageOperationUUID +{ + [PINRemoteImageCategoryManager setDownloadImageOperationUUID:downloadImageOperationUUID onView:self]; +} + +- (BOOL)pin_updateWithProgress +{ + return [PINRemoteImageCategoryManager updateWithProgressOnView:self]; +} + +- (void)setPin_updateWithProgress:(BOOL)updateWithProgress +{ + [PINRemoteImageCategoryManager setUpdateWithProgressOnView:updateWithProgress onView:self]; +} + +- (void)pin_setPlaceholderWithImage:(PINImage *)image +{ + self.image = image; +} + +- (void)pin_updateUIWithRemoteImageManagerResult:(PINRemoteImageManagerResult *)result +{ + if (result.alternativeRepresentation && [result.alternativeRepresentation isKindOfClass:[PINCachedAnimatedImage class]]) { + self.animatedImage = (PINCachedAnimatedImage *)result.alternativeRepresentation; + } else if (result.image) { + self.image = result.image; + } +} + +- (void)pin_clearImages +{ + self.animatedImage = nil; + self.image = nil; +} + +- (BOOL)pin_ignoreGIFs +{ + return NO; +} + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINAlternateRepresentationProvider.m b/Example/Pods/PINRemoteImage/Source/Classes/PINAlternateRepresentationProvider.m index 99c03ce..ea87911 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINAlternateRepresentationProvider.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINAlternateRepresentationProvider.m @@ -8,18 +8,20 @@ #import "PINAlternateRepresentationProvider.h" +#import "PINCachedAnimatedImage.h" #import "NSData+ImageDetectors.h" -#if USE_FLANIMATED_IMAGE -#import -#endif @implementation PINAlternateRepresentationProvider - (id)alternateRepresentationWithData:(NSData *)data options:(PINRemoteImageManagerDownloadOptions)options { -#if USE_FLANIMATED_IMAGE - if ([data pin_isGIF]) { - return [FLAnimatedImage animatedImageWithGIFData:data]; +#if PIN_WEBP + if ([data pin_isAnimatedGIF] || [data pin_isAnimatedWebP]) { + return [[PINCachedAnimatedImage alloc] initWithAnimatedImageData:data]; + } +#else + if ([data pin_isAnimatedGIF]) { + return [[PINCachedAnimatedImage alloc] initWithAnimatedImageData:data]; } #endif return nil; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m b/Example/Pods/PINRemoteImage/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m index fb32277..5641d78 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m @@ -13,12 +13,17 @@ @implementation PINCache (PINRemoteImageCaching) //****************************************************************************************************** // Memory cache methods //****************************************************************************************************** --(nullable id)objectFromMemoryForKey:(NSString *)key +- (nullable id)objectFromMemoryForKey:(NSString *)key { return [self.memoryCache objectForKey:key]; } --(void)setObjectInMemory:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost +- (void)setObjectInMemory:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost withAgeLimit:(NSTimeInterval)ageLimit +{ + [self.memoryCache setObject:object forKey:key withCost:cost ageLimit:ageLimit]; +} + +- (void)setObjectInMemory:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost { [self.memoryCache setObject:object forKey:key withCost:cost]; } @@ -31,12 +36,12 @@ - (void)removeObjectForKeyFromMemory:(NSString *)key //****************************************************************************************************** // Disk cache methods //****************************************************************************************************** --(nullable id)objectFromDiskForKey:(NSString *)key +- (nullable id)objectFromDiskForKey:(NSString *)key { return [self.diskCache objectForKey:key]; } --(void)objectFromDiskForKey:(NSString *)key completion:(PINRemoteImageCachingObjectBlock)completion +- (void)objectFromDiskForKey:(NSString *)key completion:(PINRemoteImageCachingObjectBlock)completion { __weak typeof(self) weakSelf = self; [self.diskCache objectForKeyAsync:key completion:^(PINDiskCache * _Nonnull cache, NSString * _Nonnull key, id _Nullable object) { @@ -47,9 +52,14 @@ -(void)objectFromDiskForKey:(NSString *)key completion:(PINRemoteImageCachingObj }]; } --(void)setObjectOnDisk:(id)object forKey:(NSString *)key +- (void)setObjectOnDisk:(id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit { - [self.diskCache setObject:object forKey:key]; + [self.diskCache setObject:object forKey:key withAgeLimit:ageLimit]; +} + +- (void)setObjectOnDisk:(id)object forKey:(NSString *)key +{ + [self.diskCache setObject:object forKey:key withAgeLimit:0]; } - (BOOL)objectExistsForKey:(NSString *)key @@ -63,16 +73,26 @@ - (BOOL)objectExistsForKey:(NSString *)key - (void)removeObjectForKey:(NSString *)key completion:(PINRemoteImageCachingObjectBlock)completion { if (completion) { - __weak typeof(self) weakSelf = self; - [self removeObjectForKeyAsync:key completion:^(PINCache * _Nonnull cache, NSString * _Nonnull key, id _Nullable object) { - typeof(self) strongSelf = weakSelf; - completion(strongSelf, key, object); - }]; + __weak typeof(self) weakSelf = self; + [self removeObjectForKeyAsync:key completion:^(id _Nonnull cache, NSString * _Nonnull key, id _Nullable object) { + typeof(self) strongSelf = weakSelf; + completion(strongSelf, key, object); + }]; } else { [self removeObjectForKeyAsync:key completion:nil]; } } +- (BOOL)diskCacheIsTTLCache +{ + return self.diskCache.isTTLCache; +} + +- (BOOL)memoryCacheIsTTLCache +{ + return self.memoryCache.isTTLCache; +} + @end @implementation PINRemoteImageManager (PINCache) diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINDisplayLink.h b/Example/Pods/PINRemoteImage/Source/Classes/PINDisplayLink.h new file mode 100644 index 0000000..0b43e7b --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINDisplayLink.h @@ -0,0 +1,25 @@ +// +// PINDisplayLink.h +// Pods +// +// Created by Garrett Moon on 4/23/18. +// + +#import + +#import "PINRemoteImageMacros.h" + +#if PIN_TARGET_IOS +#define PINDisplayLink CADisplayLink +#elif PIN_TARGET_MAC +@interface PINDisplayLink : NSObject + ++ (PINDisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel; +- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode; +- (void)removeFromRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode; + +@property(getter=isPaused, nonatomic) BOOL paused; +@property(nonatomic) NSInteger frameInterval; + +@end +#endif diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINDisplayLink.m b/Example/Pods/PINRemoteImage/Source/Classes/PINDisplayLink.m new file mode 100644 index 0000000..8235265 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINDisplayLink.m @@ -0,0 +1,133 @@ +// +// PINDisplayLink.m +// Pods +// +// Created by Garrett Moon on 4/23/18. +// + +#import "PINDisplayLink.h" + +#if PIN_TARGET_MAC + +#if SWIFT_PACKAGE +@import CoreVideo.CVDisplayLink; +#else +#import +#endif + +@interface PINDisplayLink () + +@property (nonatomic, readonly) id target; +@property (nonatomic, readonly) SEL selector; +@property (nonatomic, readonly) NSRunLoop *runloop; +@property (nonatomic, readonly) NSRunLoopMode mode; + +- (void)displayLinkFired; + +@end + +static CVReturn displayLinkFired (CVDisplayLinkRef displayLink, + const CVTimeStamp *inNow, + const CVTimeStamp *inOutputTime, + CVOptionFlags flagsIn, + CVOptionFlags *flagsOut, + void *displayLinkContext) +{ + PINDisplayLink *link = (__bridge PINDisplayLink *)displayLinkContext; + [link displayLinkFired]; + return kCVReturnSuccess; +} + +@implementation PINDisplayLink +{ + CVDisplayLinkRef _displayLinkRef; + + BOOL _paused; + NSInteger _frameInterval; +} + ++ (PINDisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel +{ + return [[PINDisplayLink alloc] initWithTarget:target selector:sel]; +} + +- (PINDisplayLink *)initWithTarget:(id)target selector:(SEL)sel +{ + if (self = [super init]) { + _target = target; + _selector = sel; + CVDisplayLinkCreateWithActiveCGDisplays(&_displayLinkRef); + CVDisplayLinkSetOutputCallback(_displayLinkRef, &displayLinkFired, (__bridge void * _Nullable)(self)); + } + return self; +} + +- (void)dealloc +{ + if (_displayLinkRef) { + CVDisplayLinkRelease(_displayLinkRef); + } +} + +- (void)displayLinkFired +{ + dispatch_async(dispatch_get_main_queue(), ^{ + [self.runloop performSelector:self.selector target:self.target argument:self order:NSUIntegerMax modes:@[self.mode]]; + }); +} + +- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode +{ + PINAssertMain(); + NSAssert(runloop && mode, @"Must set a runloop and a mode."); + _runloop = runloop; + _mode = mode; + if (_paused == NO) { + CVDisplayLinkStart(_displayLinkRef); + } +} + +- (void)removeFromRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode +{ + _runloop = nil; + _mode = nil; + if (_paused == NO) { + CVDisplayLinkStop(_displayLinkRef); + } +} + +- (BOOL)isPaused +{ + PINAssertMain(); + return _paused; +} + +- (void)setPaused:(BOOL)paused +{ + PINAssertMain(); + if (_paused == paused) { + return; + } + + _paused = paused; + if (paused) { + CVDisplayLinkStop(_displayLinkRef); + } else { + CVDisplayLinkStart(_displayLinkRef); + } +} + +- (NSInteger)frameInterval +{ + PINAssertMain(); + return _frameInterval; +} + +- (void)setFrameInterval:(NSInteger)frameInterval +{ + PINAssertMain(); + _frameInterval = frameInterval; +} + +@end +#endif diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINGIFAnimatedImageManager.h b/Example/Pods/PINRemoteImage/Source/Classes/PINGIFAnimatedImageManager.h deleted file mode 100644 index 50e3242..0000000 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINGIFAnimatedImageManager.h +++ /dev/null @@ -1,82 +0,0 @@ -// -// PINGIFAnimatedImageManager.h -// Pods -// -// Created by Garrett Moon on 4/5/16. -// -// - -#import - -#import "PINAnimatedImage.h" -#import "PINRemoteImageMacros.h" - -@class PINRemoteLock; -@class PINSharedAnimatedImage; -@class PINSharedAnimatedImageFile; - -typedef void(^PINAnimatedImageSharedReady)(PINImage *coverImage, PINSharedAnimatedImage *shared); -typedef void(^PINAnimatedImageDecodedPath)(BOOL finished, NSString *path, NSError *error); - -@interface PINGIFAnimatedImageManager : NSObject - -+ (instancetype)sharedManager; -+ (NSString *)temporaryDirectory; -+ (NSString *)filePathWithTemporaryDirectory:(NSString *)temporaryDirectory UUID:(NSUUID *)UUID count:(NSUInteger)count; - -- (void)animatedPathForImageData:(NSData *)animatedImageData infoCompletion:(PINAnimatedImageSharedReady)infoCompletion completion:(PINAnimatedImageDecodedPath)completion; - -@end - -@interface PINSharedAnimatedImage : NSObject -{ - PINRemoteLock *_coverImageLock; -} - -//This is intentionally atomic. PINGIFAnimatedImageManager must be able to add entries -//and clients must be able to read them concurrently. -@property (atomic, strong, readwrite) NSArray *maps; - -@property (nonatomic, strong, readwrite) NSArray *completions; -@property (nonatomic, strong, readwrite) NSArray *infoCompletions; -@property (nonatomic, weak, readwrite) PINImage *coverImage; - -//intentionally atomic -@property (atomic, strong, readwrite) NSError *error; -@property (atomic, assign, readwrite) PINAnimatedImageStatus status; - -- (void)setInfoProcessedWithCoverImage:(PINImage *)coverImage - UUID:(NSUUID *)UUID - durations:(Float32 *)durations - totalDuration:(CFTimeInterval)totalDuration - loopCount:(size_t)loopCount - frameCount:(size_t)frameCount - width:(uint32_t)width - height:(uint32_t)height - bitsPerPixel:(size_t)bitsPerPixel - bitmapInfo:(CGBitmapInfo)bitmapInfo; - -@property (nonatomic, readonly) NSUUID *UUID; -@property (nonatomic, readonly) Float32 *durations; -@property (nonatomic, readonly) CFTimeInterval totalDuration; -@property (nonatomic, readonly) size_t loopCount; -@property (nonatomic, readonly) size_t frameCount; -@property (nonatomic, readonly) uint32_t width; -@property (nonatomic, readonly) uint32_t height; -@property (nonatomic, readonly) size_t bitsPerPixel; -@property (nonatomic, readonly) CGBitmapInfo bitmapInfo; - -@end - -@interface PINSharedAnimatedImageFile : NSObject -{ - PINRemoteLock *_lock; -} - -@property (nonatomic, strong, readonly) NSString *path; -@property (nonatomic, assign, readonly) UInt32 frameCount; -@property (nonatomic, weak, readonly) NSData *memoryMappedData; - -- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER; - -@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINGIFAnimatedImageManager.m b/Example/Pods/PINRemoteImage/Source/Classes/PINGIFAnimatedImageManager.m deleted file mode 100644 index 62e1104..0000000 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINGIFAnimatedImageManager.m +++ /dev/null @@ -1,568 +0,0 @@ -// -// PINGIFAnimatedImageManager.m -// Pods -// -// Created by Garrett Moon on 4/5/16. -// -// - -#import "PINGIFAnimatedImageManager.h" - -#import -#if PIN_TARGET_IOS -#import -#elif PIN_TARGET_MAC -#import -#endif - -#import "PINRemoteLock.h" - -static const NSUInteger maxFileSize = 50000000; //max file size in bytes -static const Float32 maxFileDuration = 1; //max duration of a file in seconds -static const NSUInteger kCleanupAfterStartupDelay = 10; //clean up files after 10 seconds if it hasn't been done. - -typedef void(^PINAnimatedImageInfoProcessed)(PINImage *coverImage, NSUUID *UUID, Float32 *durations, CFTimeInterval totalDuration, size_t loopCount, size_t frameCount, UInt32 width, UInt32 height, size_t bitsPerPixel, UInt32 bitmapInfo); - -BOOL PINStatusCoverImageCompleted(PINAnimatedImageStatus status); -BOOL PINStatusCoverImageCompleted(PINAnimatedImageStatus status) { - return status == PINAnimatedImageStatusInfoProcessed || status == PINAnimatedImageStatusFirstFileProcessed || status == PINAnimatedImageStatusProcessed; -} - -typedef NS_ENUM(NSUInteger, PINAnimatedImageManagerCondition) { - PINAnimatedImageManagerConditionNotReady = 0, - PINAnimatedImageManagerConditionReady = 1, -}; - -@interface PINGIFAnimatedImageManager () -{ - NSConditionLock *_lock; -} - -+ (instancetype)sharedManager; - -@property (nonatomic, strong, readonly) NSMapTable *animatedImages; -@property (nonatomic, strong, readonly) dispatch_queue_t serialProcessingQueue; - -@end - -@implementation PINGIFAnimatedImageManager - -+ (void)load -{ - if (self == [PINGIFAnimatedImageManager class]) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kCleanupAfterStartupDelay * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - //This forces a cleanup of files - [PINGIFAnimatedImageManager sharedManager]; - }); - } -} - -+ (instancetype)sharedManager -{ - static dispatch_once_t onceToken; - static PINGIFAnimatedImageManager *sharedManager; - dispatch_once(&onceToken, ^{ - sharedManager = [[PINGIFAnimatedImageManager alloc] init]; - }); - return sharedManager; -} - -+ (NSString *)temporaryDirectory -{ - static dispatch_once_t onceToken; - static NSString *temporaryDirectory; - dispatch_once(&onceToken, ^{ - //On iOS temp directories are not shared between apps. This may not be safe on OS X or other systems - temporaryDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:@"ASAnimatedImageCache"]; - }); - return temporaryDirectory; -} - -- (instancetype)init -{ - if (self = [super init]) { - _lock = [[NSConditionLock alloc] initWithCondition:PINAnimatedImageManagerConditionNotReady]; - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [_lock lockWhenCondition:PINAnimatedImageManagerConditionNotReady]; - [PINGIFAnimatedImageManager cleanupFiles]; - if ([[NSFileManager defaultManager] fileExistsAtPath:[PINGIFAnimatedImageManager temporaryDirectory]] == NO) { - [[NSFileManager defaultManager] createDirectoryAtPath:[PINGIFAnimatedImageManager temporaryDirectory] withIntermediateDirectories:YES attributes:nil error:nil]; - } - [_lock unlockWithCondition:PINAnimatedImageManagerConditionReady]; - }); - - _animatedImages = [[NSMapTable alloc] initWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableWeakMemory capacity:1]; - _serialProcessingQueue = dispatch_queue_create("Serial animated image processing queue.", DISPATCH_QUEUE_SERIAL); - -#if PIN_TARGET_IOS - NSString * const notificationName = UIApplicationWillTerminateNotification; -#elif PIN_TARGET_MAC - NSString * const notificationName = NSApplicationWillTerminateNotification; -#endif - [[NSNotificationCenter defaultCenter] addObserverForName:notificationName - object:nil - queue:nil - usingBlock:^(NSNotification * _Nonnull note) { - [PINGIFAnimatedImageManager cleanupFiles]; - }]; - } - return self; -} - -+ (void)cleanupFiles -{ - [[NSFileManager defaultManager] removeItemAtPath:[PINGIFAnimatedImageManager temporaryDirectory] error:nil]; -} - -- (void)animatedPathForImageData:(NSData *)animatedImageData infoCompletion:(PINAnimatedImageSharedReady)infoCompletion completion:(PINAnimatedImageDecodedPath)completion -{ - __block BOOL startProcessing = NO; - __block PINSharedAnimatedImage *sharedAnimatedImage = nil; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [_lock lockWhenCondition:PINAnimatedImageManagerConditionReady]; - sharedAnimatedImage = [self.animatedImages objectForKey:animatedImageData]; - if (sharedAnimatedImage == nil) { - sharedAnimatedImage = [[PINSharedAnimatedImage alloc] init]; - [self.animatedImages setObject:sharedAnimatedImage forKey:animatedImageData]; - startProcessing = YES; - } - - if (PINStatusCoverImageCompleted(sharedAnimatedImage.status)) { - //Info is already processed, call infoCompletion immediately - if (infoCompletion) { - infoCompletion(sharedAnimatedImage.coverImage, sharedAnimatedImage); - } - } else { - //Add infoCompletion to sharedAnimatedImage - if (infoCompletion) { - //Since ASSharedAnimatedImages are stored weakly in our map, we need a strong reference in completions - PINAnimatedImageSharedReady capturingInfoCompletion = ^(PINImage *coverImage, PINSharedAnimatedImage *newShared) { - __unused PINSharedAnimatedImage *strongShared = sharedAnimatedImage; - infoCompletion(coverImage, newShared); - }; - sharedAnimatedImage.infoCompletions = [sharedAnimatedImage.infoCompletions arrayByAddingObject:capturingInfoCompletion]; - } - } - - if (sharedAnimatedImage.status == PINAnimatedImageStatusProcessed) { - //Animated image is already fully processed, call completion immediately - if (completion) { - completion(YES, nil, nil); - } - } else if (sharedAnimatedImage.status == PINAnimatedImageStatusError) { - if (completion) { - completion(NO, nil, sharedAnimatedImage.error); - } - } else { - //Add completion to sharedAnimatedImage - if (completion) { - //Since PINSharedAnimatedImages are stored weakly in our map, we need a strong reference in completions - PINAnimatedImageDecodedPath capturingCompletion = ^(BOOL finished, NSString *path, NSError *error) { - __unused PINSharedAnimatedImage *strongShared = sharedAnimatedImage; - completion(finished, path, error); - }; - sharedAnimatedImage.completions = [sharedAnimatedImage.completions arrayByAddingObject:capturingCompletion]; - } - } - [_lock unlockWithCondition:PINAnimatedImageManagerConditionReady]; - - if (startProcessing) { - dispatch_async(self.serialProcessingQueue, ^{ - [[self class] processAnimatedImage:animatedImageData temporaryDirectory:[PINGIFAnimatedImageManager temporaryDirectory] infoCompletion:^(PINImage *coverImage, NSUUID *UUID, Float32 *durations, CFTimeInterval totalDuration, size_t loopCount, size_t frameCount, UInt32 width, UInt32 height, size_t bitsPerPixel, UInt32 bitmapInfo) { - __block NSArray *infoCompletions = nil; - __block PINSharedAnimatedImage *sharedAnimatedImage = nil; - [_lock lockWhenCondition:PINAnimatedImageManagerConditionReady]; - sharedAnimatedImage = [self.animatedImages objectForKey:animatedImageData]; - [sharedAnimatedImage setInfoProcessedWithCoverImage:coverImage UUID:UUID durations:durations totalDuration:totalDuration loopCount:loopCount frameCount:frameCount width:width height:height bitsPerPixel:bitsPerPixel bitmapInfo:bitmapInfo]; - infoCompletions = sharedAnimatedImage.infoCompletions; - sharedAnimatedImage.infoCompletions = @[]; - [_lock unlockWithCondition:PINAnimatedImageManagerConditionReady]; - - for (PINAnimatedImageSharedReady infoCompletion in infoCompletions) { - infoCompletion(coverImage, sharedAnimatedImage); - } - } decodedPath:^(BOOL finished, NSString *path, NSError *error) { - __block NSArray *completions = nil; - { - [_lock lockWhenCondition:PINAnimatedImageManagerConditionReady]; - PINSharedAnimatedImage *sharedAnimatedImage = [self.animatedImages objectForKey:animatedImageData]; - - if (path && error == nil) { - sharedAnimatedImage.maps = [sharedAnimatedImage.maps arrayByAddingObject:[[PINSharedAnimatedImageFile alloc] initWithPath:path]]; - } - sharedAnimatedImage.error = error; - if (error) { - sharedAnimatedImage.status = PINAnimatedImageStatusError; - } - - completions = sharedAnimatedImage.completions; - if (finished || error) { - sharedAnimatedImage.completions = @[]; - } - - if (error == nil) { - if (finished) { - sharedAnimatedImage.status = PINAnimatedImageStatusProcessed; - } else { - sharedAnimatedImage.status = PINAnimatedImageStatusFirstFileProcessed; - } - } - [_lock unlockWithCondition:PINAnimatedImageManagerConditionReady]; - } - - for (PINAnimatedImageDecodedPath completion in completions) { - completion(finished, path, error); - } - }]; - }); - } - }); -} - -#define HANDLE_PROCESSING_ERROR(ERROR) \ -{ \ -if (ERROR != nil) { \ - [errorLock lockWithBlock:^{ \ - if (processingError == nil) { \ - processingError = ERROR; \ - } \ - }]; \ -\ -[fileHandle closeFile]; \ -[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; \ -} \ -} - -#define PROCESSING_ERROR \ -({__block NSError *ERROR; \ -[errorLock lockWithBlock:^{ \ - ERROR = processingError; \ -}]; \ -ERROR;}) \ - -+ (void)processAnimatedImage:(NSData *)animatedImageData - temporaryDirectory:(NSString *)temporaryDirectory - infoCompletion:(PINAnimatedImageInfoProcessed)infoCompletion - decodedPath:(PINAnimatedImageDecodedPath)completion -{ - NSUUID *UUID = [NSUUID UUID]; - __block NSError *processingError = nil; - PINRemoteLock *errorLock = [[PINRemoteLock alloc] initWithName:@"animatedImage processing lock"]; - NSString *filePath = nil; - //TODO Must handle file handle errors! Documentation says it throws exceptions on any errors :( - NSError *fileHandleError = nil; - NSFileHandle *fileHandle = [self fileHandle:&fileHandleError filePath:&filePath temporaryDirectory:temporaryDirectory UUID:UUID count:0]; - HANDLE_PROCESSING_ERROR(fileHandleError); - UInt32 width; - UInt32 height; - UInt32 bitsPerPixel; - UInt32 bitmapInfo; - NSUInteger fileCount = 0; - UInt32 frameCountForFile = 0; - Float32 *durations = NULL; - -#if PINMemMapAnimatedImageDebug - CFTimeInterval start = CACurrentMediaTime(); -#endif - - if (fileHandle && PROCESSING_ERROR == nil) { - dispatch_queue_t diskWriteQueue = dispatch_queue_create("PINGIFAnimatedImage disk write queue", DISPATCH_QUEUE_SERIAL); - dispatch_group_t diskGroup = dispatch_group_create(); - - CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)animatedImageData, - (CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceTypeIdentifierHint : (__bridge NSString *)kUTTypeGIF, - (__bridge NSString *)kCGImageSourceShouldCache : (__bridge NSNumber *)kCFBooleanFalse}); - - if (imageSource) { - UInt32 frameCount = (UInt32)CGImageSourceGetCount(imageSource); - NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(imageSource, nil); - UInt32 loopCount = (UInt32)[[[imageProperties objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary] - objectForKey:(__bridge NSString *)kCGImagePropertyGIFLoopCount] unsignedLongValue]; - - Float32 fileDuration = 0; - NSUInteger fileSize = 0; - durations = (Float32 *)malloc(sizeof(Float32) * frameCount); - CFTimeInterval totalDuration = 0; - PINImage *coverImage = nil; - - //Gather header file info - for (NSUInteger frameIdx = 0; frameIdx < frameCount; frameIdx++) { - if (frameIdx == 0) { - CGImageRef frameImage = CGImageSourceCreateImageAtIndex(imageSource, frameIdx, (CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceShouldCache : (__bridge NSNumber *)kCFBooleanFalse}); - if (frameImage == nil) { - NSError *frameError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorImageFrameError userInfo:nil]; - HANDLE_PROCESSING_ERROR(frameError); - break; - } - - bitmapInfo = CGImageGetBitmapInfo(frameImage); - - width = (UInt32)CGImageGetWidth(frameImage); - height = (UInt32)CGImageGetHeight(frameImage); - bitsPerPixel = (UInt32)CGImageGetBitsPerPixel(frameImage); - -#if PIN_TARGET_IOS - coverImage = [UIImage imageWithCGImage:frameImage]; -#elif PIN_TARGET_MAC - coverImage = [[NSImage alloc] initWithCGImage:frameImage size:CGSizeMake(width, height)]; -#endif - CGImageRelease(frameImage); - } - - Float32 duration = [[self class] frameDurationAtIndex:frameIdx source:imageSource]; - durations[frameIdx] = duration; - totalDuration += duration; - } - - if (PROCESSING_ERROR == nil) { - //Get size, write file header get coverImage - dispatch_group_async(diskGroup, diskWriteQueue, ^{ - NSError *fileHeaderError = [self writeFileHeader:fileHandle width:width height:height bitsPerPixel:bitsPerPixel loopCount:loopCount frameCount:frameCount bitmapInfo:bitmapInfo durations:durations]; - HANDLE_PROCESSING_ERROR(fileHeaderError); - if (fileHeaderError == nil) { - [fileHandle closeFile]; - - PINLog(@"notifying info"); - infoCompletion(coverImage, UUID, durations, totalDuration, loopCount, frameCount, width, height, bitsPerPixel, bitmapInfo); - } - }); - fileCount = 1; - NSError *fileHandleError = nil; - fileHandle = [self fileHandle:&fileHandleError filePath:&filePath temporaryDirectory:temporaryDirectory UUID:UUID count:fileCount]; - HANDLE_PROCESSING_ERROR(fileHandleError); - - dispatch_group_async(diskGroup, diskWriteQueue, ^{ - //write empty frame count - @try { - [fileHandle writeData:[NSData dataWithBytes:&frameCountForFile length:sizeof(frameCountForFile)]]; - } @catch (NSException *exception) { - NSError *frameCountError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileWrite userInfo:@{@"NSException" : exception}]; - HANDLE_PROCESSING_ERROR(frameCountError); - } @finally {} - }); - - //Process frames - for (NSUInteger frameIdx = 0; frameIdx < frameCount; frameIdx++) { - if (PROCESSING_ERROR != nil) { - break; - } - @autoreleasepool { - if (fileDuration > maxFileDuration || fileSize > maxFileSize) { - //create a new file - dispatch_group_async(diskGroup, diskWriteQueue, ^{ - //prepend file with frameCount - @try { - [fileHandle seekToFileOffset:0]; - [fileHandle writeData:[NSData dataWithBytes:&frameCountForFile length:sizeof(frameCountForFile)]]; - [fileHandle closeFile]; - } @catch (NSException *exception) { - NSError *frameCountError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileWrite userInfo:@{@"NSException" : exception}]; - HANDLE_PROCESSING_ERROR(frameCountError); - } @finally {} - }); - - dispatch_group_async(diskGroup, diskWriteQueue, ^{ - PINLog(@"notifying file: %@", filePath); - completion(NO, filePath, PROCESSING_ERROR); - }); - - diskGroup = dispatch_group_create(); - fileCount++; - NSError *fileHandleError = nil; - fileHandle = [self fileHandle:&fileHandleError filePath:&filePath temporaryDirectory:temporaryDirectory UUID:UUID count:fileCount]; - HANDLE_PROCESSING_ERROR(fileHandleError); - frameCountForFile = 0; - fileDuration = 0; - fileSize = 0; - //write empty frame count - dispatch_group_async(diskGroup, diskWriteQueue, ^{ - @try { - [fileHandle writeData:[NSData dataWithBytes:&frameCountForFile length:sizeof(frameCountForFile)]]; - } @catch (NSException *exception) { - NSError *frameCountError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileWrite userInfo:@{@"NSException" : exception}]; - HANDLE_PROCESSING_ERROR(frameCountError); - } @finally {} - }); - } - - Float32 duration = durations[frameIdx]; - fileDuration += duration; - - dispatch_group_async(diskGroup, diskWriteQueue, ^{ - if (PROCESSING_ERROR) { - return; - } - - CGImageRef frameImage = CGImageSourceCreateImageAtIndex(imageSource, frameIdx, (CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceShouldCache : (__bridge NSNumber *)kCFBooleanFalse}); - if (frameImage == nil) { - NSError *frameImageError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorImageFrameError userInfo:nil]; - HANDLE_PROCESSING_ERROR(frameImageError); - return; - } - - NSData *frameData = (__bridge_transfer NSData *)CGDataProviderCopyData(CGImageGetDataProvider(frameImage)); - NSAssert(frameData.length == width * height * bitsPerPixel / 8, @"data should be width * height * bytes per pixel"); - NSError *frameWriteError = [self writeFrameToFile:fileHandle duration:duration frameData:frameData]; - HANDLE_PROCESSING_ERROR(frameWriteError); - - CGImageRelease(frameImage); - }); - - frameCountForFile++; - } - } - } else { - completion(NO, nil, PROCESSING_ERROR); - } - } - - dispatch_group_wait(diskGroup, DISPATCH_TIME_FOREVER); - if (imageSource) { - CFRelease(imageSource); - } - - //close the file handle - PINLog(@"closing last file: %@", fileHandle); - @try { - [fileHandle seekToFileOffset:0]; - [fileHandle writeData:[NSData dataWithBytes:&frameCountForFile length:sizeof(frameCountForFile)]]; - [fileHandle closeFile]; - } @catch (NSException *exception) { - NSError *frameCountError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileWrite userInfo:@{@"NSException" : exception}]; - HANDLE_PROCESSING_ERROR(frameCountError); - } @finally {} - } - -#if PINMemMapAnimatedImageDebug - CFTimeInterval interval = CACurrentMediaTime() - start; - NSLog(@"Encoding and write time: %f", interval); -#endif - - if (durations) { - free(durations); - } - - completion(YES, filePath, PROCESSING_ERROR); -} - -//http://stackoverflow.com/questions/16964366/delaytime-or-unclampeddelaytime-for-gifs -+ (Float32)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source -{ - Float32 frameDuration = kPINAnimatedImageDefaultDuration; - NSDictionary *frameProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, index, nil); - // use unclamped delay time before delay time before default - NSNumber *unclamedDelayTime = frameProperties[(__bridge NSString *)kCGImagePropertyGIFDictionary][(__bridge NSString *)kCGImagePropertyGIFUnclampedDelayTime]; - if (unclamedDelayTime != nil) { - frameDuration = [unclamedDelayTime floatValue]; - } else { - NSNumber *delayTime = frameProperties[(__bridge NSString *)kCGImagePropertyGIFDictionary][(__bridge NSString *)kCGImagePropertyGIFDelayTime]; - if (delayTime != nil) { - frameDuration = [delayTime floatValue]; - } - } - - if (frameDuration < kPINAnimatedImageMinimumDuration) { - frameDuration = kPINAnimatedImageDefaultDuration; - } - - return frameDuration; -} - -+ (NSString *)filePathWithTemporaryDirectory:(NSString *)temporaryDirectory UUID:(NSUUID *)UUID count:(NSUInteger)count -{ - NSString *filePath = [temporaryDirectory stringByAppendingPathComponent:[UUID UUIDString]]; - if (count > 0) { - filePath = [filePath stringByAppendingString:[@(count) stringValue]]; - } - return filePath; -} - -+ (NSFileHandle *)fileHandle:(NSError **)error filePath:(NSString **)filePath temporaryDirectory:(NSString *)temporaryDirectory UUID:(NSUUID *)UUID count:(NSUInteger)count; -{ - NSString *outFilePath = [self filePathWithTemporaryDirectory:temporaryDirectory UUID:UUID count:count]; - NSError *outError = nil; - NSFileHandle *fileHandle = nil; - - if (outError == nil) { - BOOL success = [[NSFileManager defaultManager] createFileAtPath:outFilePath contents:nil attributes:nil]; - if (success == NO) { - outError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileCreationError userInfo:nil]; - } - } - - if (outError == nil) { - fileHandle = [NSFileHandle fileHandleForWritingAtPath:outFilePath]; - if (fileHandle == nil) { - outError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileHandleError userInfo:nil]; - } - } - - if (error) { - *error = outError; - } - - if (filePath) { - *filePath = outFilePath; - } - - return fileHandle; -} - -/** - PINGIFAnimatedImage file header - - Header: - [version] 2 bytes - [width] 4 bytes - [height] 4 bytes - [loop count] 4 bytes - [frame count] 4 bytes - [bitmap info] 4 bytes - [durations] 4 bytes * frame count - - */ - -+ (NSError *)writeFileHeader:(NSFileHandle *)fileHandle width:(UInt32)width height:(UInt32)height bitsPerPixel:(UInt32)bitsPerPixel loopCount:(UInt32)loopCount frameCount:(UInt32)frameCount bitmapInfo:(UInt32)bitmapInfo durations:(Float32*)durations -{ - NSError *error = nil; - @try { - UInt16 version = 2; - [fileHandle writeData:[NSData dataWithBytes:&version length:sizeof(version)]]; - [fileHandle writeData:[NSData dataWithBytes:&width length:sizeof(width)]]; - [fileHandle writeData:[NSData dataWithBytes:&height length:sizeof(height)]]; - [fileHandle writeData:[NSData dataWithBytes:&bitsPerPixel length:sizeof(bitsPerPixel)]]; - [fileHandle writeData:[NSData dataWithBytes:&loopCount length:sizeof(loopCount)]]; - [fileHandle writeData:[NSData dataWithBytes:&frameCount length:sizeof(frameCount)]]; - [fileHandle writeData:[NSData dataWithBytes:&bitmapInfo length:sizeof(bitmapInfo)]]; - //Since we can't get the length of the durations array from the pointer, we'll just calculate it based on the frameCount. - [fileHandle writeData:[NSData dataWithBytes:durations length:sizeof(Float32) * frameCount]]; - } @catch (NSException *exception) { - error = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileWrite userInfo:@{@"NSException" : exception}]; - } @finally {} - return error; -} - -/** - PINGIFAnimatedImage frame file - [frame count(in file)] 4 bytes - [frame(s)] - - Each frame: - [duration] 4 bytes - [frame data] width * height * 4 bytes - */ - -+ (NSError *)writeFrameToFile:(NSFileHandle *)fileHandle duration:(Float32)duration frameData:(NSData *)frameData -{ - NSError *error = nil; - @try { - [fileHandle writeData:[NSData dataWithBytes:&duration length:sizeof(duration)]]; - [fileHandle writeData:frameData]; - } @catch (NSException *exception) { - error = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorFileWrite userInfo:@{@"NSException" : exception}]; - } @finally {} - return error; -} - -@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.h b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.h index 7219e13..c669c3c 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.h @@ -11,7 +11,8 @@ /** * Simplistic wrapper based on NSCache. - * not persisting any data on disk + * + * No data is persisted on disk. The disk cache methods are no-op. */ @interface PINRemoteImageBasicCache : NSObject diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.m index 6ec6bcb..a3953ce 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageBasicCache.m @@ -46,7 +46,7 @@ - (void)removeObjectForKeyFromMemory:(NSString *)key //****************************************************************************************************** -(nullable id)objectFromDiskForKey:(NSString *)key { - return [self.cache objectForKey:key]; + return nil; } -(void)objectFromDiskForKey:(NSString *)key completion:(PINRemoteImageCachingObjectBlock)completion @@ -55,28 +55,29 @@ -(void)objectFromDiskForKey:(NSString *)key completion:(PINRemoteImageCachingObj dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (completion) { typeof(self) strongSelf = weakSelf; - completion(strongSelf, key, [strongSelf.cache objectForKey:key]); + completion(strongSelf, key, nil); } }); } -(void)setObjectOnDisk:(id)object forKey:(NSString *)key { - [self.cache setObject:object forKey:key]; + } +//****************************************************************************************************** +// Common methods, should apply to both in-memory and disk storage +//****************************************************************************************************** - (BOOL)objectExistsForKey:(NSString *)key { return [self.cache objectForKey:key] != nil; } -//****************************************************************************************************** -// Common methods, should apply to both in-memory and disk storage -//****************************************************************************************************** - (void)removeObjectForKey:(NSString *)key { [self.cache removeObjectForKey:key]; } + - (void)removeObjectForKey:(NSString *)key completion:(PINRemoteImageCachingObjectBlock)completion { __weak typeof(self) weakSelf = self; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.h b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.h index 6a13b6f..574a280 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.h @@ -18,7 +18,7 @@ typedef void (^PINRemoteImageDownloadCompletion)(NSURLResponse * _Nullable respo @interface PINRemoteImageDownloadQueue : NSObject -@property (nonatomic, assign) NSUInteger maxNumberOfConcurrentDownloads; +@property (atomic, assign) NSUInteger maxNumberOfConcurrentDownloads; - (instancetype)init NS_UNAVAILABLE; + (PINRemoteImageDownloadQueue *)queueWithMaxConcurrentDownloads:(NSUInteger)maxNumberOfConcurrentDownloads; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.m index 819fffe..07e70f2 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadQueue.m @@ -36,7 +36,7 @@ - (PINRemoteImageDownloadQueue *)initWithMaxConcurrentDownloads:(NSUInteger)maxN { if (self = [super init]) { _maxNumberOfConcurrentDownloads = maxNumberOfConcurrentDownloads; - + _lock = [[PINRemoteLock alloc] initWithName:@"PINRemoteImageDownloadQueue Lock"]; _highPriorityQueuedOperations = [[NSMutableOrderedSet alloc] init]; _defaultPriorityQueuedOperations = [[NSMutableOrderedSet alloc] init]; @@ -68,19 +68,21 @@ - (NSURLSessionDataTask *)addDownloadWithSessionManager:(PINURLSessionManager *) priority:(PINRemoteImageManagerPriority)priority completionHandler:(PINRemoteImageDownloadCompletion)completionHandler { - NSURLSessionDataTask *dataTask = [sessionManager dataTaskWithRequest:request completionHandler:^(NSURLSessionTask *task, NSError *error) { - completionHandler(task.response, error); - [self lock]; - [_runningTasks removeObject:task]; - [self unlock]; - - [self scheduleDownloadsIfNeeded]; - }]; - + NSURLSessionDataTask *dataTask = [sessionManager dataTaskWithRequest:request + priority:priority + completionHandler:^(NSURLSessionTask *task, NSError *error) { + completionHandler(task.response, error); + [self lock]; + [self->_runningTasks removeObject:task]; + [self unlock]; + + [self scheduleDownloadsIfNeeded]; + }]; + [self setQueuePriority:priority forTask:dataTask addIfNecessary:YES]; - + [self scheduleDownloadsIfNeeded]; - + return dataTask; } @@ -105,7 +107,6 @@ - (void)scheduleDownloadsIfNeeded [queue removeObjectAtIndex:0]; [task resume]; - [_runningTasks addObject:task]; } [self unlock]; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.h b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.h index 6434e64..bcd434d 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.h @@ -6,7 +6,11 @@ // // +#if SWIFT_PACKAGE +@import PINOperation; +#else #import +#endif #import "PINRemoteImageManager+Private.h" #import "PINRemoteImageTask.h" @@ -15,7 +19,7 @@ @interface PINRemoteImageDownloadTask : PINRemoteImageTask -@property (nonatomic, strong, nullable) NSURL *URL; +@property (nonatomic, strong, nullable, readonly) NSURL *URL; @property (nonatomic, copy, nullable) NSString *ifRange; @property (nonatomic, copy, readonly, nullable) NSData *data; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.m index de973b3..b1b261d 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageDownloadTask.m @@ -44,8 +44,8 @@ - (void)callProgressDownload __block int64_t totalBytes; [self.lock lockWithBlock:^{ - completedBytes = _progressImage.dataTask.countOfBytesReceived; - totalBytes = _progressImage.dataTask.countOfBytesExpectedToReceive; + completedBytes = self->_progressImage.dataTask.countOfBytesReceived; + totalBytes = self->_progressImage.dataTask.countOfBytesExpectedToReceive; }]; [callbackBlocks enumerateKeysAndObjectsUsingBlock:^(NSUUID *UUID, PINRemoteImageCallbacks *callback, BOOL *stop) { @@ -96,10 +96,10 @@ - (BOOL)cancelWithUUID:(NSUUID *)UUID resume:(PINResume **)resume BOOL hasResume = resume != nil; [self.lock lockWithBlock:^{ if (hasResume) { - //consider skipping cancelation if there's a request for resume data and the time to start the connection is greater than + //consider skipping cancellation if there's a request for resume data and the time to start the connection is greater than //the time remaining to download. - NSTimeInterval timeToFirstByte = [[PINSpeedRecorder sharedRecorder] weightedTimeToFirstByteForHost:_progressImage.dataTask.currentRequest.URL.host]; - if (_progressImage.estimatedRemainingTime <= timeToFirstByte) { + NSTimeInterval timeToFirstByte = [[PINSpeedRecorder sharedRecorder] weightedTimeToFirstByteForHost:self->_progressImage.dataTask.currentRequest.URL.host]; + if (self->_progressImage.estimatedRemainingTime <= timeToFirstByte) { noMoreCompletions = NO; return; } @@ -108,13 +108,13 @@ - (BOOL)cancelWithUUID:(NSUUID *)UUID resume:(PINResume **)resume noMoreCompletions = [super l_cancelWithUUID:UUID]; if (noMoreCompletions) { - [self.manager.urlSessionTaskQueue removeDownloadTaskFromQueue:_progressImage.dataTask]; - [_progressImage.dataTask cancel]; + [self.manager.urlSessionTaskQueue removeDownloadTaskFromQueue:self->_progressImage.dataTask]; + [self->_progressImage.dataTask cancel]; - if (hasResume && _ifRange && _progressImage.dataTask.countOfBytesExpectedToReceive > 0 && _progressImage.dataTask.countOfBytesExpectedToReceive != NSURLSessionTransferSizeUnknown) { - NSData *progressData = _progressImage.data; + if (hasResume && self->_ifRange && self->_progressImage.dataTask.countOfBytesExpectedToReceive > 0 && self->_progressImage.dataTask.countOfBytesExpectedToReceive != NSURLSessionTransferSizeUnknown) { + NSData *progressData = self->_progressImage.data; if (progressData.length > 0) { - strongResume = [PINResume resumeData:progressData ifRange:_ifRange totalBytes:_progressImage.dataTask.countOfBytesExpectedToReceive]; + strongResume = [PINResume resumeData:progressData ifRange:self->_ifRange totalBytes:self->_progressImage.dataTask.countOfBytesExpectedToReceive]; } } @@ -139,9 +139,10 @@ - (void)setPriority:(PINRemoteImageManagerPriority)priority [super setPriority:priority]; if (@available(iOS 8.0, macOS 10.10, tvOS 9.0, watchOS 2.0, *)) { [self.lock lockWithBlock:^{ - if (_progressImage.dataTask) { - _progressImage.dataTask.priority = dataTaskPriorityWithImageManagerPriority(priority); - [self.manager.urlSessionTaskQueue setQueuePriority:priority forTask:_progressImage.dataTask]; + NSURLSessionDataTask *dataTask = self->_progressImage.dataTask; + if (dataTask) { + dataTask.priority = dataTaskPriorityWithImageManagerPriority(priority); + [self.manager.urlSessionTaskQueue setQueuePriority:priority forTask:dataTask]; } }]; } @@ -151,7 +152,7 @@ - (NSURL *)URL { __block NSURL *url; [self.lock lockWithBlock:^{ - url = _progressImage.dataTask.originalRequest.URL; + url = self->_progressImage.dataTask.originalRequest.URL; }]; return url; } @@ -166,7 +167,7 @@ - (nonnull PINRemoteImageManagerResult *)imageResultWithImage:(nullable PINImage { __block NSUInteger bytesSavedByResuming; [self.lock lockWithBlock:^{ - bytesSavedByResuming = _resume.resumeData.length; + bytesSavedByResuming = self->_resume.resumeData.length; }]; return [PINRemoteImageManagerResult imageResultWithImage:image alternativeRepresentation:alternativeRepresentation @@ -184,7 +185,7 @@ - (void)didReceiveData:(NSData *_Nonnull)data __block int64_t expectedNumberOfBytes; [self.lock lockWithBlock:^{ - expectedNumberOfBytes = _progressImage.dataTask.countOfBytesExpectedToReceive; + expectedNumberOfBytes = self->_progressImage.dataTask.countOfBytesExpectedToReceive; }]; [self updateData:data isResume:NO expectedBytes:expectedNumberOfBytes]; @@ -195,7 +196,7 @@ - (void)updateData:(NSData *)data isResume:(BOOL)isResume expectedBytes:(int64_t __block PINProgressiveImage *progressImage; __block BOOL hasProgressBlocks = NO; [self.lock lockWithBlock:^{ - progressImage = _progressImage; + progressImage = self->_progressImage; [[self l_callbackBlocks] enumerateKeysAndObjectsUsingBlock:^(NSUUID *UUID, PINRemoteImageCallbacks *callback, BOOL *stop) { if (callback.progressImageBlock) { hasProgressBlocks = YES; @@ -228,14 +229,14 @@ - (void)didReceiveResponse:(nonnull NSURLResponse *)response if (httpResponse.statusCode == 206) { __block PINResume *resume; [self.lock lockWithBlock:^{ - resume = _resume; + resume = self->_resume; }]; [self updateData:resume.resumeData isResume:YES expectedBytes:resume.totalBytes]; } else { //Check if there's resume data and we didn't get back a 206, get rid of it [self.lock lockWithBlock:^{ - _resume = nil; + self->_resume = nil; }]; } @@ -254,7 +255,7 @@ - (void)didReceiveResponse:(nonnull NSURLResponse *)response if (ifRange.length > 0) { [self.lock lockWithBlock:^{ - _ifRange = ifRange; + self->_ifRange = ifRange; }]; } } @@ -278,25 +279,25 @@ - (void)scheduleDownloadWithRequest:(NSURLRequest *)request completionHandler:(PINRemoteImageManagerDataCompletion)completionHandler { [self.lock lockWithBlock:^{ - if (_progressImage != nil || [self l_callbackBlocks].count == 0 || (isRetry == NO && _retryStrategy.numberOfRetries > 0)) { + if (self->_progressImage != nil || [self l_callbackBlocks].count == 0 || (isRetry == NO && self->_retryStrategy.numberOfRetries > 0)) { return; } - _resume = resume; + self->_resume = resume; NSURLRequest *adjustedRequest = request; - if (_resume) { + if (self->_resume) { NSMutableURLRequest *mutableRequest = [request mutableCopy]; NSMutableDictionary *headers = [[mutableRequest allHTTPHeaderFields] mutableCopy]; - headers[@"If-Range"] = _resume.ifRange; - headers[@"Range"] = [NSString stringWithFormat:@"bytes=%tu-", _resume.resumeData.length]; + headers[@"If-Range"] = self->_resume.ifRange; + headers[@"Range"] = [NSString stringWithFormat:@"bytes=%tu-", self->_resume.resumeData.length]; mutableRequest.allHTTPHeaderFields = headers; adjustedRequest = mutableRequest; } - _progressImage = [[PINProgressiveImage alloc] initWithDataTask:[self.manager.urlSessionTaskQueue addDownloadWithSessionManager:self.manager.sessionManager - request:adjustedRequest - priority:priority - completionHandler:^(NSURLResponse * _Nonnull response, NSError * _Nonnull remoteError) + self->_progressImage = [[PINProgressiveImage alloc] initWithDataTask:[self.manager.urlSessionTaskQueue addDownloadWithSessionManager:self.manager.sessionManager + request:adjustedRequest + priority:priority + completionHandler:^(NSURLResponse * _Nonnull response, NSError * _Nonnull remoteError) { [self.manager.concurrentOperationQueue scheduleOperation:^{ NSError *error = remoteError; @@ -322,12 +323,12 @@ - (void)scheduleDownloadWithRequest:(NSURLRequest *)request __block BOOL retry = NO; __block int64_t delay = 0; [self.lock lockWithBlock:^{ - retry = skipRetry == NO && [_retryStrategy shouldRetryWithError:error]; + retry = skipRetry == NO && [self->_retryStrategy shouldRetryWithError:error]; if (retry) { - // Clear out the exsiting progress image or else new data from retry will be appended - _progressImage = nil; - [_retryStrategy incrementRetryCount]; - delay = [_retryStrategy nextDelay]; + // Clear out the existing progress image or else new data from retry will be appended + self->_progressImage = nil; + [self->_retryStrategy incrementRetryCount]; + delay = [self->_retryStrategy nextDelay]; } }]; if (retry) { @@ -342,10 +343,6 @@ - (void)scheduleDownloadWithRequest:(NSURLRequest *)request } }]; }]]; - - if (@available(iOS 8.0, macOS 10.10, tvOS 9.0, watchOS 2.0, *)) { - _progressImage.dataTask.priority = dataTaskPriorityWithImageManagerPriority(priority); - } }]; } @@ -353,7 +350,7 @@ - (PINProgressiveImage *)progressImage { __block PINProgressiveImage *progressImage = nil; [self.lock lockWithBlock:^{ - progressImage = _progressImage; + progressImage = self->_progressImage; }]; return progressImage; } diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager+Private.h b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager+Private.h index 0c673cc..39550e3 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager+Private.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager+Private.h @@ -13,7 +13,7 @@ typedef void (^PINRemoteImageManagerDataCompletion)(NSData *data, NSURLResponse *response, NSError *error); -@interface PINRemoteImageManager (private) +@interface PINRemoteImageManager (PrivateExtension) @property (nonatomic, strong, readonly) dispatch_queue_t callbackQueue; @property (nonatomic, strong, readonly) PINOperationQueue *concurrentOperationQueue; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager.m index a08c5a0..5ef8ac1 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager.m @@ -9,10 +9,18 @@ #import "PINRemoteImageManager.h" #import + +#if SWIFT_PACKAGE +@import PINOperation; +#else #import +#endif + +#import #import "PINAlternateRepresentationProvider.h" #import "PINRemoteImage.h" +#import "PINRemoteImageManagerConfiguration.h" #import "PINRemoteLock.h" #import "PINProgressiveImage.h" #import "PINRemoteImageCallbacks.h" @@ -31,6 +39,8 @@ #import "NSData+ImageDetectors.h" #import "PINImage+DecodedImage.h" #import "PINImage+ScaledImage.h" +#import "PINRemoteImageManager+Private.h" +#import "NSHTTPURLResponse+MaxAge.h" #if USE_PINCACHE #import "PINCache+PINRemoteImageCaching.h" @@ -39,8 +49,7 @@ #endif -#define PINRemoteImageManagerDefaultTimeout 30.0 -#define PINRemoteImageHTTPMaximumConnectionsPerHost UINT16_MAX +#define PINRemoteImageManagerDefaultTimeout 30.0 //A limit of 200 characters is chosen because PINDiskCache //may expand the length by encoding certain characters #define PINRemoteImageManagerCacheKeyMaxLength 200 @@ -78,11 +87,41 @@ float dataTaskPriorityWithImageManagerPriority(PINRemoteImageManagerPriority pri } } -NSString * const PINRemoteImageManagerErrorDomain = @"PINRemoteImageManagerErrorDomain"; -NSString * const PINRemoteImageCacheKey = @"cacheKey"; +// Reference: https://github.com/TextureGroup/Texture/blob/5dd5611/Source/Private/ASInternalHelpers.m#L60 +BOOL PINRemoteImageManagerSubclassOverridesSelector(Class subclass, SEL selector) +{ + Class superclass = [PINRemoteImageManager class]; + if (superclass == subclass) return NO; // Even if the class implements the selector, it doesn't override itself. + Method superclassMethod = class_getInstanceMethod(superclass, selector); + Method subclassMethod = class_getInstanceMethod(subclass, selector); + return (superclassMethod != subclassMethod); +} + +NSErrorDomain const PINRemoteImageManagerErrorDomain = @"PINRemoteImageManagerErrorDomain"; +NSString * const PINRemoteImageWeakTaskKey = @"PINRemoteImageWeakTaskKey"; NSString * const PINRemoteImageCacheKeyResumePrefix = @"R-"; typedef void (^PINRemoteImageManagerDataCompletion)(NSData *data, NSURLResponse *response, NSError *error); +@interface PINRemoteImageWeakTask : NSObject + +@property (nonatomic, readonly, weak) PINRemoteImageTask *task; + +- (instancetype)initWithTask:(PINRemoteImageTask *)task; + +@end + +@implementation PINRemoteImageWeakTask + +- (instancetype)initWithTask:(PINRemoteImageTask *)task +{ + if (self = [super init]) { + _task = task; + } + return self; +} + +@end + @interface PINRemoteImageManager () { dispatch_queue_t _callbackQueue; @@ -90,7 +129,7 @@ @interface PINRemoteImageManager () PINOperationQueue *_concurrentOperationQueue; PINRemoteImageDownloadQueue *_urlSessionTaskQueue; - // Necesarry to have a strong reference to _defaultAlternateRepresentationProvider because _alternateRepProvider is __weak + // Necessary to have a strong reference to _defaultAlternateRepresentationProvider because _alternateRepProvider is __weak PINAlternateRepresentationProvider *_defaultAlternateRepresentationProvider; __weak PINAlternateRepresentationProvider *_alternateRepProvider; NSURLSessionConfiguration *_sessionConfiguration; @@ -101,6 +140,7 @@ @interface PINRemoteImageManager () @property (nonatomic, strong) PINURLSessionManager *sessionManager; @property (nonatomic, strong) NSMutableDictionary *tasks; @property (nonatomic, strong) NSHashTable *canceledTasks; +@property (nonatomic, strong) NSMapTable *UUIDToTask; @property (nonatomic, strong) NSArray *progressThresholds; @property (nonatomic, assign) BOOL shouldBlurProgressive; @property (nonatomic, assign) CGSize maxProgressiveRenderSize; @@ -111,10 +151,13 @@ @interface PINRemoteImageManager () @property (nonatomic, assign) float highQualityBPSThreshold; @property (nonatomic, assign) float lowQualityBPSThreshold; @property (nonatomic, assign) BOOL shouldUpgradeLowQualityImages; +@property (nonatomic, strong) PINRemoteImageManagerMetrics metricsCallback API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); @property (nonatomic, copy) PINRemoteImageManagerAuthenticationChallenge authenticationChallengeHandler; @property (nonatomic, copy) id (^retryStrategyCreationBlock)(void); @property (nonatomic, copy) PINRemoteImageManagerRequestConfigurationHandler requestConfigurationHandler; @property (nonatomic, strong) NSMutableDictionary *httpHeaderFields; +@property (nonatomic, readonly) BOOL diskCacheTTLIsEnabled; +@property (nonatomic, readonly) BOOL memoryCacheTTLIsEnabled; #if DEBUG @property (nonatomic, assign) NSUInteger totalDownloads; #endif @@ -150,53 +193,80 @@ - (instancetype)init return [self initWithSessionConfiguration:nil]; } -- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration +- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration { - return [self initWithSessionConfiguration:configuration alternativeRepresentationProvider:nil]; + return [self initWithSessionConfiguration:sessionConfiguration alternativeRepresentationProvider:nil]; } -- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration alternativeRepresentationProvider:(id )alternateRepProvider +- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration alternativeRepresentationProvider:(id )alternateRepProvider { - return [self initWithSessionConfiguration:configuration alternativeRepresentationProvider:alternateRepProvider imageCache:nil]; + return [self initWithSessionConfiguration:sessionConfiguration alternativeRepresentationProvider:alternateRepProvider imageCache:nil managerConfiguration:nil]; } -- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration - alternativeRepresentationProvider:(nullable id )alternateRepProvider - imageCache:(nullable id)imageCache +- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)sessionConfiguration + alternativeRepresentationProvider:(nullable id )alternateRepDelegate + imageCache:(nullable id)imageCache { + return [self initWithSessionConfiguration:sessionConfiguration alternativeRepresentationProvider:alternateRepDelegate imageCache:imageCache managerConfiguration:nil]; +} + +-(nonnull instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration + alternativeRepresentationProvider:(id)alternateRepProvider + imageCache:(id)imageCache + managerConfiguration:(nullable PINRemoteImageManagerConfiguration *)managerConfiguration { if (self = [super init]) { + PINRemoteImageManagerConfiguration *configuration = managerConfiguration; + if (!configuration) { + configuration = [[PINRemoteImageManagerConfiguration alloc] init]; + } if (imageCache) { self.cache = imageCache; - } else { + } else if (PINRemoteImageManagerSubclassOverridesSelector([self class], @selector(defaultImageCache))) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" self.cache = [self defaultImageCache]; +#pragma clang diagnostic pop + } else { + self.cache = [[self class] defaultImageCache]; + } + + if ([self.cache respondsToSelector:@selector(setObjectOnDisk:forKey:withAgeLimit:)] && + [self.cache respondsToSelector:@selector(setObjectInMemory:forKey:withCost:withAgeLimit:)] && + [self.cache respondsToSelector:@selector(diskCacheIsTTLCache)] && + [self.cache respondsToSelector:@selector(memoryCacheIsTTLCache)]) { + _diskCacheTTLIsEnabled = [self.cache diskCacheIsTTLCache]; + _memoryCacheTTLIsEnabled = [self.cache memoryCacheIsTTLCache]; } - _sessionConfiguration = [configuration copy]; + _sessionConfiguration = [sessionConfiguration copy]; if (!_sessionConfiguration) { _sessionConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; _sessionConfiguration.timeoutIntervalForRequest = PINRemoteImageManagerDefaultTimeout; + _sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; + _sessionConfiguration.URLCache = nil; + _sessionConfiguration.HTTPMaximumConnectionsPerHost = PINRemoteImageHTTPMaximumConnectionsPerHost; } - _sessionConfiguration.HTTPMaximumConnectionsPerHost = PINRemoteImageHTTPMaximumConnectionsPerHost; _callbackQueue = dispatch_queue_create("PINRemoteImageManagerCallbackQueue", DISPATCH_QUEUE_CONCURRENT); _lock = [[PINRemoteLock alloc] initWithName:@"PINRemoteImageManager"]; - - _concurrentOperationQueue = [[PINOperationQueue alloc] initWithMaxConcurrentOperations:[[NSProcessInfo processInfo] activeProcessorCount] * 2]; - _urlSessionTaskQueue = [PINRemoteImageDownloadQueue queueWithMaxConcurrentDownloads:10]; - self.sessionManager = [[PINURLSessionManager alloc] initWithSessionConfiguration:configuration]; + _concurrentOperationQueue = [[PINOperationQueue alloc] initWithMaxConcurrentOperations: configuration.maxConcurrentOperations]; + _urlSessionTaskQueue = [PINRemoteImageDownloadQueue queueWithMaxConcurrentDownloads:configuration.maxConcurrentDownloads]; + + self.sessionManager = [[PINURLSessionManager alloc] initWithSessionConfiguration:_sessionConfiguration]; self.sessionManager.delegate = self; - self.estimatedRemainingTimeThreshold = 0.1; - - _highQualityBPSThreshold = 500000; - _lowQualityBPSThreshold = 50000; // approximately edge speeds - _shouldUpgradeLowQualityImages = NO; - _shouldBlurProgressive = YES; - _maxProgressiveRenderSize = CGSizeMake(1024, 1024); + self.estimatedRemainingTimeThreshold = configuration.estimatedRemainingTimeThreshold; + + _highQualityBPSThreshold = configuration.highQualityBPSThreshold; + _lowQualityBPSThreshold = configuration.lowQualityBPSThreshold; + _shouldUpgradeLowQualityImages = configuration.shouldUpgradeLowQualityImages; + _shouldBlurProgressive = configuration.shouldBlurProgressive; + _maxProgressiveRenderSize = configuration.maxProgressiveRenderSize; self.tasks = [[NSMutableDictionary alloc] init]; self.canceledTasks = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:5]; + self.UUIDToTask = [NSMapTable weakToWeakObjectsMapTable]; if (alternateRepProvider == nil) { _defaultAlternateRepresentationProvider = [[PINAlternateRepresentationProvider alloc] init]; @@ -216,7 +286,24 @@ - (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfi return [[PINRequestExponentialRetryStrategy alloc] initWithRetryMaxCount:3 delayBase:4]; } -- (id)defaultImageCache +- (void)dealloc +{ + [self.sessionManager invalidateSessionAndCancelTasks]; +} + +- (id)defaultImageCache { + return [PINRemoteImageManager defaultImageCache]; +} + ++ (id)defaultImageCache { + return [PINRemoteImageManager defaultImageCacheEnablingTtl:NO]; +} + ++ (id)defaultImageTtlCache { + return [PINRemoteImageManager defaultImageCacheEnablingTtl:YES]; +} + ++ (id)defaultImageCacheEnablingTtl:(BOOL)enableTtl { #if USE_PINCACHE NSString * const kPINRemoteImageDiskCacheName = @"PINRemoteImageManagerCache"; @@ -237,8 +324,8 @@ - (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfi }); [pinDefaults setInteger:kPINRemoteImageDiskCacheVersion forKey:kPINRemoteImageDiskCacheVersionKey]; } - - return [[PINCache alloc] initWithName:kPINRemoteImageDiskCacheName rootPath:cacheURLRoot serializer:^NSData * _Nonnull(id _Nonnull object, NSString * _Nonnull key) { + + PINCache *pinCache = [[PINCache alloc] initWithName:kPINRemoteImageDiskCacheName rootPath:cacheURLRoot serializer:^NSData * _Nonnull(id _Nonnull object, NSString * _Nonnull key) { id obj = (id )object; if ([key hasPrefix:PINRemoteImageCacheKeyResumePrefix]) { return [NSKeyedArchiver archivedDataWithRootObject:obj]; @@ -249,7 +336,9 @@ - (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfi return [NSKeyedUnarchiver unarchiveObjectWithData:data]; } return data; - }]; + } keyEncoder:nil keyDecoder:nil ttlCache:enableTtl]; + + return pinCache; #else return [[PINRemoteImageBasicCache alloc] init]; #endif @@ -431,6 +520,20 @@ - (void)setShouldUpgradeLowQualityImages:(BOOL)shouldUpgradeLowQualityImages com }); } +- (void)setMetricsCallback:(nullable PINRemoteImageManagerMetrics)metricsCallback completion:(nullable dispatch_block_t)completion +{ + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + typeof(self) strongSelf = weakSelf; + [self lock]; + strongSelf.metricsCallback = metricsCallback; + [self unlock]; + if (completion) { + completion(); + } + }); +} + - (NSUUID *)downloadImageWithURL:(NSURL *)url completion:(PINRemoteImageManagerImageCompletion)completion { @@ -456,13 +559,9 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url { return [self downloadImageWithURL:url options:options - priority:PINRemoteImageManagerPriorityDefault - processorKey:nil - processor:nil progressImage:progressImage progressDownload:nil - completion:completion - inputUUID:nil]; + completion:completion]; } - (NSUUID *)downloadImageWithURL:(NSURL *)url @@ -472,13 +571,9 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url { return [self downloadImageWithURL:url options:options - priority:PINRemoteImageManagerPriorityDefault - processorKey:nil - processor:nil progressImage:nil progressDownload:progressDownload - completion:completion - inputUUID:nil]; + completion:completion]; } - (NSUUID *)downloadImageWithURL:(NSURL *)url @@ -490,6 +585,21 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url return [self downloadImageWithURL:url options:options priority:PINRemoteImageManagerPriorityDefault + progressImage:progressImage + progressDownload:progressDownload + completion:completion]; +} + +- (nullable NSUUID *)downloadImageWithURL:(nonnull NSURL *)url + options:(PINRemoteImageManagerDownloadOptions)options + priority:(PINRemoteImageManagerPriority)priority + progressImage:(PINRemoteImageManagerImageCompletion)progressImage + progressDownload:(nullable PINRemoteImageManagerProgressDownload)progressDownload + completion:(nullable PINRemoteImageManagerImageCompletion)completion; +{ + return [self downloadImageWithURL:url + options:options + priority:priority processorKey:nil processor:nil progressImage:progressImage @@ -523,14 +633,14 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url completion:(PINRemoteImageManagerImageCompletion)completion { return [self downloadImageWithURL:url - options:options - priority:PINRemoteImageManagerPriorityDefault - processorKey:processorKey - processor:processor - progressImage:nil - progressDownload:progressDownload - completion:completion - inputUUID:nil]; + options:options + priority:PINRemoteImageManagerPriorityDefault + processorKey:processorKey + processor:processor + progressImage:nil + progressDownload:progressDownload + completion:completion + inputUUID:nil]; } - (NSUUID *)downloadImageWithURL:(NSURL *)url @@ -603,15 +713,15 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url if (task == nil) { task = [[taskClass alloc] initWithManager:self]; PINLog(@"Task does not exist creating with key: %@, URL: %@, UUID: %@, task: %p", key, url, UUID, task); - #if PINRemoteImageLogging task.key = key; - #endif } else { taskExisted = YES; PINLog(@"Task exists, attaching with key: %@, URL: %@, UUID: %@, task: %@", key, url, UUID, task); } [task addCallbacksWithCompletionBlock:completion progressImageBlock:progressImage progressDownloadBlock:progressDownload withUUID:UUID]; [self.tasks setObject:task forKey:key]; + // Relax :), task retain the UUID for us, it's ok to have a weak reference to UUID here. + [self.UUIDToTask setObject:task forKey:UUID]; NSAssert(taskClass == [task class], @"Task class should be the same!"); [self unlock]; @@ -759,24 +869,32 @@ - (void)downloadImageWithURL:(NSURL *)url PINRemoteImageDownloadTask *task = [self.tasks objectForKey:key]; [self unlock]; - [task scheduleDownloadWithRequest:[self requestWithURL:url key:key] + [task scheduleDownloadWithRequest:[self requestWithURL:url task:task] resume:resume skipRetry:(options & PINRemoteImageManagerDownloadOptionsSkipRetry) priority:priority completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - [_concurrentOperationQueue scheduleOperation:^ + [self->_concurrentOperationQueue scheduleOperation:^ { NSError *remoteImageError = error; PINImage *image = nil; id alternativeRepresentation = nil; - + NSNumber *maxAge = nil; if (remoteImageError == nil) { - //stores the object in the caches - [self materializeAndCacheObject:data cacheInDisk:data additionalCost:0 url:url key:key options:options outImage:&image outAltRep:&alternativeRepresentation]; + BOOL ignoreHeaders = (options & PINRemoteImageManagerDownloadOptionsIgnoreCacheControlHeaders) != 0; + if ((self.diskCacheTTLIsEnabled || self.memoryCacheTTLIsEnabled) && !ignoreHeaders) { + // examine Cache-Control headers (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; + maxAge = [httpResponse findMaxAge]; + } + } + // Stores the object in the cache. + [self materializeAndCacheObject:data cacheInDisk:data additionalCost:0 maxAge:maxAge url:url key:key options:options outImage:&image outAltRep:&alternativeRepresentation]; } - if (error == nil && image == nil && alternativeRepresentation == nil) { + if (error == nil && image == nil && alternativeRepresentation == nil) { remoteImageError = [NSError errorWithDomain:PINRemoteImageManagerErrorDomain code:PINRemoteImageManagerErrorFailedToDecodeImage userInfo:nil]; @@ -796,7 +914,7 @@ -(BOOL)insertImageDataIntoCache:(nonnull NSData*)data if (url != nil) { NSString *key = [self cacheKeyForURL:url processorKey:processorKey]; - PINRemoteImageManagerDownloadOptions options = PINRemoteImageManagerDownloadOptionsSkipDecode & PINRemoteImageManagerDownloadOptionsSkipEarlyCheck; + PINRemoteImageManagerDownloadOptions options = PINRemoteImageManagerDownloadOptionsSkipDecode | PINRemoteImageManagerDownloadOptionsSkipEarlyCheck; PINRemoteImageMemoryContainer *container = [[PINRemoteImageMemoryContainer alloc] init]; container.data = data; @@ -846,12 +964,10 @@ - (BOOL)earlyReturnWithOptions:(PINRemoteImageManagerDownloadOptions)options url return NO; } -- (NSURLRequest *)requestWithURL:(NSURL *)url key:(NSString *)key +- (NSURLRequest *)requestWithURL:(NSURL *)url task:(PINRemoteImageTask *)task { - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url - cachePolicy:NSURLRequestReloadIgnoringLocalCacheData - timeoutInterval:_sessionConfiguration.timeoutIntervalForRequest]; - + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + NSMutableDictionary *headers = [self.httpHeaderFields mutableCopy]; if (headers.count > 0) { @@ -862,7 +978,8 @@ - (NSURLRequest *)requestWithURL:(NSURL *)url key:(NSString *)key request = [_requestConfigurationHandler(request) mutableCopy]; } - [NSURLProtocol setProperty:key forKey:PINRemoteImageCacheKey inRequest:request]; + PINRemoteImageWeakTask *weakTask = [[PINRemoteImageWeakTask alloc] initWithTask:task]; + [NSURLProtocol setProperty:weakTask forKey:PINRemoteImageWeakTaskKey inRequest:request]; return request; } @@ -892,10 +1009,15 @@ - (void)callCompletionsWithKey:(NSString *)key } - (NSArray *)prefetchImagesWithURLs:(NSArray *)urls options:(PINRemoteImageManagerDownloadOptions)options +{ + return [self prefetchImagesWithURLs:urls options:options priority:PINRemoteImageManagerPriorityLow]; +} + +- (NSArray *)prefetchImagesWithURLs:(NSArray *)urls options:(PINRemoteImageManagerDownloadOptions)options priority:(PINRemoteImageManagerPriority)priority { NSMutableArray *tasks = [NSMutableArray arrayWithCapacity:urls.count]; for (NSURL *url in urls) { - NSUUID *task = [self prefetchImageWithURL:url options:options]; + NSUUID *task = [self prefetchImageWithURL:url options:options priority:priority]; if (task != nil) { [tasks addObject:task]; } @@ -909,10 +1031,15 @@ - (NSUUID *)prefetchImageWithURL:(NSURL *)url } - (NSUUID *)prefetchImageWithURL:(NSURL *)url options:(PINRemoteImageManagerDownloadOptions)options +{ + return [self prefetchImageWithURL:url options:options priority:PINRemoteImageManagerPriorityLow]; +} + +- (NSUUID *)prefetchImageWithURL:(NSURL *)url options:(PINRemoteImageManagerDownloadOptions)options priority:(PINRemoteImageManagerPriority)priority { return [self downloadImageWithURL:url options:options - priority:PINRemoteImageManagerPriorityLow + priority:priority processorKey:nil processor:nil progressImage:nil @@ -921,7 +1048,7 @@ - (NSUUID *)prefetchImageWithURL:(NSURL *)url options:(PINRemoteImageManagerDown inputUUID:nil]; } -#pragma mark - Cancelation & Priority +#pragma mark - Cancellation & Priority - (void)cancelTaskWithUUID:(NSUUID *)UUID { @@ -937,9 +1064,7 @@ - (void)cancelTaskWithUUID:(nonnull NSUUID *)UUID storeResumeData:(BOOL)storeRes [_concurrentOperationQueue scheduleOperation:^{ PINResume *resume = nil; [self lock]; - NSString *taskKey = nil; - PINRemoteImageTask *taskToEvaluate = [self _locked_taskForUUID:UUID key:&taskKey]; - + PINRemoteImageTask *taskToEvaluate = [self.UUIDToTask objectForKey:UUID]; if (taskToEvaluate == nil) { //maybe task hasn't been added to task list yet, add it to canceled tasks. //there's no need to ever remove a UUID from canceledTasks because it is weak. @@ -947,7 +1072,7 @@ - (void)cancelTaskWithUUID:(nonnull NSUUID *)UUID storeResumeData:(BOOL)storeRes } if ([taskToEvaluate cancelWithUUID:UUID resume:storeResumeData ? &resume : NULL]) { - [self.tasks removeObjectForKey:taskKey]; + [self.tasks removeObjectForKey:taskToEvaluate.key]; } [self unlock]; @@ -958,6 +1083,24 @@ - (void)cancelTaskWithUUID:(nonnull NSUUID *)UUID storeResumeData:(BOOL)storeRes } withPriority:PINOperationQueuePriorityHigh]; } +- (void)cancelAllTasks +{ + [self cancelAllTasksAndStoreResumeData:NO]; +} + +- (void)cancelAllTasksAndStoreResumeData:(BOOL)storeResumeData +{ + [_concurrentOperationQueue scheduleOperation:^{ + [self lock]; + NSMapTable *uuidToTask = [self.UUIDToTask copy]; + [self unlock]; + + for (NSUUID *uuid in uuidToTask) { + [self cancelTaskWithUUID:uuid storeResumeData:storeResumeData]; + } + } withPriority:PINOperationQueuePriorityHigh]; +} + - (void)setPriority:(PINRemoteImageManagerPriority)priority ofTaskWithUUID:(NSUUID *)UUID { if (UUID == nil) { @@ -966,7 +1109,7 @@ - (void)setPriority:(PINRemoteImageManagerPriority)priority ofTaskWithUUID:(NSUU PINLog(@"Setting priority of UUID: %@ priority: %lu", UUID, (unsigned long)priority); [_concurrentOperationQueue scheduleOperation:^{ [self lock]; - PINRemoteImageTask *task = [self _locked_taskForUUID:UUID key:NULL]; + PINRemoteImageTask *task = [self.UUIDToTask objectForKey:UUID]; [task setPriority:priority]; [self unlock]; } withPriority:PINOperationQueuePriorityHigh]; @@ -981,7 +1124,7 @@ - (void)setProgressImageCallback:(nullable PINRemoteImageManagerImageCompletion) PINLog(@"setting progress block of UUID: %@ progressBlock: %@", UUID, progressImageCallback); [_concurrentOperationQueue scheduleOperation:^{ [self lock]; - PINRemoteImageTask *task = [self _locked_taskForUUID:UUID key:NULL]; + PINRemoteImageTask *task = [self.UUIDToTask objectForKey:UUID]; if ([task isKindOfClass:[PINRemoteImageDownloadTask class]]) { PINRemoteImageCallbacks *callbacks = task.callbackBlocks[UUID]; callbacks.progressImageBlock = progressImageCallback; @@ -993,7 +1136,7 @@ - (void)setProgressImageCallback:(nullable PINRemoteImageManagerImageCompletion) - (void)setRetryStrategyCreationBlock:(id (^)(void))retryStrategyCreationBlock { [_concurrentOperationQueue scheduleOperation:^{ [self lock]; - _retryStrategyCreationBlock = retryStrategyCreationBlock; + self->_retryStrategyCreationBlock = retryStrategyCreationBlock; [self unlock]; } withPriority:PINOperationQueuePriorityHigh]; } @@ -1114,8 +1257,8 @@ - (void)didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challe - (void)didReceiveResponse:(nonnull NSURLResponse *)response forTask:(nonnull NSURLSessionTask *)dataTask { [self lock]; - NSString *cacheKey = [NSURLProtocol propertyForKey:PINRemoteImageCacheKey inRequest:dataTask.originalRequest]; - PINRemoteImageDownloadTask *task = [self.tasks objectForKey:cacheKey]; + PINRemoteImageWeakTask *weakTask = [NSURLProtocol propertyForKey:PINRemoteImageWeakTaskKey inRequest:dataTask.originalRequest]; + PINRemoteImageDownloadTask *task = (PINRemoteImageDownloadTask *)weakTask.task; [self unlock]; [task didReceiveResponse:response]; } @@ -1123,12 +1266,21 @@ - (void)didReceiveResponse:(nonnull NSURLResponse *)response forTask:(nonnull NS - (void)didReceiveData:(NSData *)data forTask:(NSURLSessionTask *)dataTask { [self lock]; - NSString *cacheKey = [NSURLProtocol propertyForKey:PINRemoteImageCacheKey inRequest:dataTask.originalRequest]; - PINRemoteImageDownloadTask *task = [self.tasks objectForKey:cacheKey]; + PINRemoteImageWeakTask *weakTask = [NSURLProtocol propertyForKey:PINRemoteImageWeakTaskKey inRequest:dataTask.originalRequest]; + PINRemoteImageDownloadTask *task = (PINRemoteImageDownloadTask *)weakTask.task; [self unlock]; [task didReceiveData:data]; } +- (void)didCollectMetrics:(nonnull NSURLSessionTaskMetrics *)metrics forURL:(nonnull NSURL *)url API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) +{ + [self lock]; + if (self.metricsCallback) { + self.metricsCallback(url, metrics); + } + [self unlock]; +} + #pragma mark - QOS - (NSUUID *)downloadImageWithURLs:(NSArray *)urls @@ -1245,11 +1397,23 @@ - (BOOL)materializeAndCacheObject:(id)object return [self materializeAndCacheObject:object cacheInDisk:nil additionalCost:0 url:url key:key options:options outImage:outImage outAltRep:outAlternateRepresentation]; } +- (BOOL)materializeAndCacheObject:(id)object + cacheInDisk:(NSData *)diskData + additionalCost:(NSUInteger)additionalCost + url:(NSURL *)url + key:(NSString *)key + options:(PINRemoteImageManagerDownloadOptions)options + outImage:(PINImage **)outImage + outAltRep:(id *)outAlternateRepresentation { + return [self materializeAndCacheObject:object cacheInDisk:diskData additionalCost:additionalCost maxAge:nil url:url key:key options:options outImage:outImage outAltRep:outAlternateRepresentation]; +} + //takes the object from the cache and returns an image or animated image. //if it's a non-alternative representation and skipDecode is not set it also decompresses the image. - (BOOL)materializeAndCacheObject:(id)object cacheInDisk:(NSData *)diskData additionalCost:(NSUInteger)additionalCost + maxAge:(NSNumber *)maxAge url:(NSURL *)url key:(NSString *)key options:(PINRemoteImageManagerDownloadOptions)options @@ -1318,22 +1482,40 @@ - (BOOL)materializeAndCacheObject:(id)object } } } - - if (updateMemoryCache) { - [container.lock lockWithBlock:^{ - NSUInteger cacheCost = additionalCost; - cacheCost += [container.data length]; - CGImageRef imageRef = container.image.CGImage; - NSAssert(container.image == nil || imageRef != NULL, @"We only cache a decompressed image if we decompressed it ourselves. In that case, it should be backed by a CGImageRef."); - if (imageRef) { - cacheCost += CGImageGetHeight(imageRef) * CGImageGetBytesPerRow(imageRef); + + // maxAge set to 0 means that images should not be stored at all. + BOOL doNotCache = (maxAge != nil && [maxAge integerValue] == 0); + + // There is no HTTP header that can be sent to indicate "infinite". However not setting a value at all, which in + // our case is represented by maxAge == nil, effectively means that. + BOOL cacheIndefinitely = (maxAge == nil); + + if (!doNotCache) { + if (updateMemoryCache) { + [container.lock lockWithBlock:^{ + NSUInteger cacheCost = additionalCost; + cacheCost += [container.data length]; + CGImageRef imageRef = container.image.CGImage; + NSAssert(container.image == nil || imageRef != NULL, @"We only cache a decompressed image if we decompressed it ourselves. In that case, it should be backed by a CGImageRef."); + if (imageRef) { + cacheCost += CGImageGetHeight(imageRef) * CGImageGetBytesPerRow(imageRef); + } + if (!self.memoryCacheTTLIsEnabled || cacheIndefinitely) { + [self.cache setObjectInMemory:container forKey:key withCost:cacheCost]; + } else { + [self.cache setObjectInMemory:container forKey:key withCost:cacheCost withAgeLimit:[maxAge integerValue]]; + } + }]; + } + + if (diskData) { + if (!self.diskCacheTTLIsEnabled || cacheIndefinitely) { + // with an unset (nil) maxAge, or a cache that is not _isTtlCache, behave as before (will use cache global behavior) + [self.cache setObjectOnDisk:diskData forKey:key]; + } else { + [self.cache setObjectOnDisk:diskData forKey:key withAgeLimit:[maxAge integerValue]]; } - [self.cache setObjectInMemory:container forKey:key withCost:cacheCost]; - }]; - } - - if (diskData) { - [self.cache setObjectOnDisk:diskData forKey:key]; + } } if (outImage) { @@ -1455,30 +1637,6 @@ - (void)storeResumeData:(PINResume *)resume forURL:(NSURL *)URL [self.cache setObjectOnDisk:resume forKey:resumeKey]; } -/// Attempt to find the task with the callbacks for the given uuid -- (nullable PINRemoteImageTask *)_locked_taskForUUID:(NSUUID *)uuid key:(NSString * __strong *)outKey -{ - __block PINRemoteImageTask *result = nil; - __block NSString *strongKey = nil; - - [self.tasks enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, __kindof PINRemoteImageTask * _Nonnull task, BOOL * _Nonnull stop) { - // If this isn't our task, just return. - if (task.callbackBlocks[uuid] == nil) { - return; - } - - // Found it! Save our results and end enumeration - result = task; - strongKey = key; - *stop = YES; - }]; - - if (outKey != nil) { - *outKey = strongKey; - } - return result; -} - #if DEBUG - (NSUInteger)totalDownloads { diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerConfiguration.h b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerConfiguration.h new file mode 100644 index 0000000..b150903 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerConfiguration.h @@ -0,0 +1,46 @@ +// +// PINRemoteImageManagerConfiguration.h +// Pods +// +// Created by Ryan Quan on 2/22/19. +// +// + +#import + +#import "PINRemoteImageMacros.h" + +#if PIN_TARGET_IOS +#import +#elif PIN_TARGET_MAC +#import +#endif + +/** A configuration object used to customize a PINRemoteImageManager instance **/ +@interface PINRemoteImageManagerConfiguration : NSObject + +/** The maximum number of concurrent operations. Defaults to NSOperationQueueDefaultMaxConcurrentOperationCount. */ +@property (nonatomic, readwrite, assign) NSUInteger maxConcurrentOperations; + +/** The maximum number of concurrent downloads. Defaults to 10, maximum 65535. */ +@property (nonatomic, readwrite, assign) NSUInteger maxConcurrentDownloads; + +/** The estimated remaining time threshold used to decide to skip progressive rendering. Defaults to 0.1. */ +@property (nonatomic, readwrite, assign) NSTimeInterval estimatedRemainingTimeThreshold; + +/** A bool value indicating whether PINRemoteImage should blur progressive render results */ +@property (nonatomic, readwrite, assign) BOOL shouldBlurProgressive; + +/** A CGSize which indicates the max size PINRemoteImage will render a progressive image. If an image is larger in either dimension, progressive rendering will be skipped */ +@property (nonatomic, readwrite, assign) CGSize maxProgressiveRenderSize; + +/** The minimum BPS to download the highest quality image in a set. */ +@property (nonatomic, readwrite, assign) float highQualityBPSThreshold; + +/** The maximum BPS to download the lowest quality image in a set. */ +@property (nonatomic, readwrite, assign) float lowQualityBPSThreshold; + +/** Whether high quality images should be downloaded when a low quality image is cached if network connectivity has improved. */ +@property (nonatomic, readwrite, assign) BOOL shouldUpgradeLowQualityImages; + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerConfiguration.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerConfiguration.m new file mode 100644 index 0000000..ecdad94 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerConfiguration.m @@ -0,0 +1,36 @@ +// +// PINRemoteImageManagerConfiguration.m +// Pods +// +// Created by Ryan Quan on 2/22/19. +// +// + +#import "PINRemoteImageManagerConfiguration.h" + +#import "PINRemoteImageManager.h" + +@implementation PINRemoteImageManagerConfiguration + +- (nonnull instancetype)init { + if (self = [super init]) { + _maxConcurrentOperations = [[NSProcessInfo processInfo] activeProcessorCount] * 2; + _maxConcurrentDownloads = 10; + _estimatedRemainingTimeThreshold = 0.1; + _shouldBlurProgressive = YES; + _maxProgressiveRenderSize = CGSizeMake(1024, 1024); + _highQualityBPSThreshold = 500000; + _lowQualityBPSThreshold = 50000; // approximately edge speed + _shouldUpgradeLowQualityImages = NO; + } + return self; +} + +#pragma mark - Setters + +- (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads { + NSAssert(maxConcurrentDownloads <= PINRemoteImageHTTPMaximumConnectionsPerHost, @"maxNumberOfConcurrentDownloads must be less than or equal to %d", PINRemoteImageHTTPMaximumConnectionsPerHost); + _maxConcurrentDownloads = maxConcurrentDownloads; +} + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageProcessorTask.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageProcessorTask.m index a24b07d..2f95022 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageProcessorTask.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageProcessorTask.m @@ -16,9 +16,9 @@ - (BOOL)cancelWithUUID:(NSUUID *)UUID resume:(PINResume **)resume { BOOL noMoreCompletions = [super cancelWithUUID:UUID resume:resume]; [self.lock lockWithBlock:^{ - if (noMoreCompletions && _downloadTaskUUID) { - [self.manager cancelTaskWithUUID:_downloadTaskUUID]; - _downloadTaskUUID = nil; + if (noMoreCompletions && self->_downloadTaskUUID) { + [self.manager cancelTaskWithUUID:self->_downloadTaskUUID]; + self->_downloadTaskUUID = nil; } }]; return noMoreCompletions; @@ -27,8 +27,8 @@ - (BOOL)cancelWithUUID:(NSUUID *)UUID resume:(PINResume **)resume - (void)setDownloadTaskUUID:(NSUUID *)downloadTaskUUID { [self.lock lockWithBlock:^{ - NSAssert(_downloadTaskUUID == nil, @"downloadTaskUUID should be nil"); - _downloadTaskUUID = downloadTaskUUID; + NSAssert(self->_downloadTaskUUID == nil, @"downloadTaskUUID should be nil"); + self->_downloadTaskUUID = downloadTaskUUID; }]; } @@ -36,7 +36,7 @@ - (NSUUID *)downloadTaskUUID { __block NSUUID *downloadTaskUUID; [self.lock lockWithBlock:^{ - downloadTaskUUID = _downloadTaskUUID; + downloadTaskUUID = self->_downloadTaskUUID; }]; return downloadTaskUUID; } diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.h b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.h index 486a2d6..8026bfd 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.h @@ -7,7 +7,12 @@ // #import + +#if SWIFT_PACKAGE +@import PINOperation; +#else #import +#endif #import "PINRemoteImageCallbacks.h" #import "PINRemoteImageManager.h" @@ -24,9 +29,8 @@ @property (nonatomic, weak, nullable) PINRemoteImageManager *manager; @property (nonatomic, strong, nullable) id retryStrategy; -#if PINRemoteImageLogging + @property (nonatomic, copy, nullable) NSString *key; -#endif - (_Nonnull instancetype)init NS_UNAVAILABLE; - (_Nonnull instancetype)initWithManager:(nonnull PINRemoteImageManager *)manager NS_DESIGNATED_INITIALIZER; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.m index 0a4002c..043a628 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageTask.m @@ -13,7 +13,7 @@ @interface PINRemoteImageTask () { - NSMutableDictionary *_callbackBlocks; + NSMutableDictionary *_callbackBlocks; // We need to copy/retain `NSUUID`, because `PINRemoteImageManager` has a weak table `UUIDs` to store all UUIDs. } @end @@ -48,7 +48,7 @@ - (void)addCallbacksWithCompletionBlock:(PINRemoteImageManagerImageCompletion)co completion.progressDownloadBlock = progressDownloadBlock; [self.lock lockWithBlock:^{ - [_callbackBlocks setObject:completion forKey:UUID]; + [self->_callbackBlocks setObject:completion forKey:UUID]; }]; } @@ -68,7 +68,7 @@ - (void)l_removeCallbackWithUUID:(NSUUID *)UUID { __block NSDictionary *callbackBlocks; [self.lock lockWithBlock:^{ - callbackBlocks = [_callbackBlocks copy]; + callbackBlocks = [self->_callbackBlocks copy]; }]; return callbackBlocks; } diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteWeakProxy.h b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteWeakProxy.h new file mode 100644 index 0000000..b0abc22 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteWeakProxy.h @@ -0,0 +1,16 @@ +// +// PINRemoteWeakProxy.h +// PINRemoteImage +// +// Created by Garrett Moon on 4/24/18. +// Copyright © 2018 Pinterest. All rights reserved. +// + +#import + +@interface PINRemoteWeakProxy : NSProxy + ++ (PINRemoteWeakProxy *)weakProxyWithTarget:(id)target; +- (instancetype)initWithTarget:(id)target; + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteWeakProxy.m b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteWeakProxy.m new file mode 100644 index 0000000..a704932 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteWeakProxy.m @@ -0,0 +1,59 @@ +// +// PINRemoteWeakProxy.m +// PINRemoteImage +// +// Created by Garrett Moon on 4/24/18. +// Copyright © 2018 Pinterest. All rights reserved. +// + +#import "PINRemoteWeakProxy.h" + +@interface PINRemoteWeakProxy () +{ + __weak id _target; + Class _targetClass; +} +@end + +@implementation PINRemoteWeakProxy + ++ (PINRemoteWeakProxy *)weakProxyWithTarget:(id)target +{ + return [[PINRemoteWeakProxy alloc] initWithTarget:target]; +} + +- (instancetype)initWithTarget:(id)target +{ + if (self) { + _target = target; + _targetClass = [target class]; + } + return self; +} + +- (BOOL)respondsToSelector:(SEL)aSelector +{ + return [_target respondsToSelector:aSelector]; +} + +- (BOOL)conformsToProtocol:(Protocol *)aProtocol +{ + return [_target conformsToProtocol:aProtocol]; +} + +- (id)forwardingTargetForSelector:(SEL)aSelector +{ + return _target; +} + +- (void)forwardInvocation:(NSInvocation *)invocation +{ + // Drop it since we shouldn't get here if _target is nil +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel +{ + return _target ? [_target methodSignatureForSelector:sel] : [_targetClass instanceMethodSignatureForSelector:sel]; +} + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.h b/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.h index 27fc8f8..bee5813 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.h @@ -21,12 +21,12 @@ typedef enum : NSUInteger { lowQualityQPSThreshold:(float)lowQualityQPSThreshold highQualityQPSThreshold:(float)highQualityQPSThreshold; -- (void)processMetrics:(NSURLSessionTaskMetrics *)metrics forTask:(NSURLSessionTask *)task NS_AVAILABLE(10_12, 10_0); +- (void)processMetrics:(NSURLSessionTaskMetrics *)metrics forTask:(NSURLSessionTask *)task API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); /* Returns a weighted average of the bytes per second of a transfer with the time to first byte subtracted. More specifically, we get the time to first byte for every task that completes, - subtract it from the total transfer time, calulate bytes per second + subtract it from the total transfer time, calculate bytes per second and add it to an existing average using exponential weighted average and adjusting for starting bias. This is all done on a per host basis. diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.m b/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.m index eb0d432..8e02fb2 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINSpeedRecorder.m @@ -98,21 +98,21 @@ - (void)processMetrics:(NSURLSessionTaskMetrics *)metrics forTask:(NSURLSessionT - (void)resetMeasurements { [self.lock lockWithBlock:^{ - [_speedMeasurements removeAllObjects]; + [self->_speedMeasurements removeAllObjects]; }]; } - (void)updateSpeedsForHost:(NSString *)host bytesPerSecond:(float)bytesPerSecond startAdjustedBytesPerSecond:(float)startAdjustedBytesPerSecond timeToFirstByte:(float)timeToFirstByte { [self.lock lockWithBlock:^{ - PINSpeedMeasurement *measurement = [_speedMeasurements objectForKey:host]; + PINSpeedMeasurement *measurement = [self->_speedMeasurements objectForKey:host]; if (measurement == nil) { measurement = [[PINSpeedMeasurement alloc] init]; measurement.count = 0; measurement.bytesPerSecond = bytesPerSecond; measurement.startAdjustedBytesPerSecond = startAdjustedBytesPerSecond; measurement.timeToFirstByte = timeToFirstByte; - [_speedMeasurements setObject:measurement forKey:host]; + [self->_speedMeasurements setObject:measurement forKey:host]; } else { const double bpsBeta = 0.8; const double ttfbBeta = 0.8; @@ -129,12 +129,12 @@ - (float)weightedAdjustedBytesPerSecondForHost:(NSString *)host __block float startAdjustedBytesPerSecond = -1; [self.lock lockWithBlock:^{ #if DEBUG - if (_overrideBPS) { - startAdjustedBytesPerSecond = _currentBPS; + if (self->_overrideBPS) { + startAdjustedBytesPerSecond = self->_currentBPS; return; } #endif - PINSpeedMeasurement *measurement = [_speedMeasurements objectForKey:host]; + PINSpeedMeasurement *measurement = [self->_speedMeasurements objectForKey:host]; if (measurement == 0) { startAdjustedBytesPerSecond = -1; return; @@ -148,7 +148,7 @@ - (NSTimeInterval)weightedTimeToFirstByteForHost:(NSString *)host { __block NSTimeInterval timeToFirstByte = 0; [self.lock lockWithBlock:^{ - PINSpeedMeasurement *measurement = [_speedMeasurements objectForKey:host]; + PINSpeedMeasurement *measurement = [self->_speedMeasurements objectForKey:host]; timeToFirstByte = measurement.timeToFirstByte; }]; return timeToFirstByte; @@ -159,11 +159,11 @@ - (void)setCurrentBytesPerSecond:(float)currentBPS { [self.lock lockWithBlock:^{ if (currentBPS == -1) { - _overrideBPS = NO; + self->_overrideBPS = NO; } else { - _overrideBPS = YES; + self->_overrideBPS = YES; } - _currentBPS = currentBPS; + self->_currentBPS = currentBPS; }]; } #endif diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINURLSessionManager.m b/Example/Pods/PINRemoteImage/Source/Classes/PINURLSessionManager.m index 32552df..e83601c 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINURLSessionManager.m +++ b/Example/Pods/PINRemoteImage/Source/Classes/PINURLSessionManager.m @@ -10,7 +10,7 @@ #import "PINSpeedRecorder.h" -NSString * const PINURLErrorDomain = @"PINURLErrorDomain"; +NSErrorDomain const PINURLErrorDomain = @"PINURLErrorDomain"; @interface PINURLSessionManager () @@ -48,10 +48,23 @@ - (void)invalidateSessionAndCancelTasks [self unlock]; } -- (nonnull NSURLSessionDataTask *)dataTaskWithRequest:(nonnull NSURLRequest *)request completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler +- (nonnull NSURLSessionDataTask *)dataTaskWithRequest:(nonnull NSURLRequest *)request + completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler +{ + return [self dataTaskWithRequest:request + priority:PINRemoteImageManagerPriorityDefault + completionHandler:completionHandler]; +} + +- (nonnull NSURLSessionDataTask *)dataTaskWithRequest:(nonnull NSURLRequest *)request + priority:(PINRemoteImageManagerPriority)priority + completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler { [self lock]; NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request]; + if (@available(iOS 8.0, macOS 10.10, tvOS 9.0, watchOS 2.0, *)) { + dataTask.priority = dataTaskPriorityWithImageManagerPriority(priority); + } if (completionHandler) { [self.completions setObject:completionHandler forKey:@(dataTask.taskIdentifier)]; } @@ -188,6 +201,10 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didComp if (completionHandler) { completionHandler(task, error); } + + if ([strongSelf.delegate respondsToSelector:@selector(didCompleteTask:withError:)]) { + [strongSelf.delegate didCompleteTask:task withError:error]; + } }); } @@ -197,6 +214,23 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFini { if (@available(iOS 10.0, macOS 10.12, *)) { [[PINSpeedRecorder sharedRecorder] processMetrics:metrics forTask:task]; + + [self lock]; + dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)]; + [self unlock]; + + NSAssert(delegateQueue != nil, @"There seems to be an issue in iOS 9 where this can be nil. If you can reliably reproduce hitting this, *please* open an issue: https://github.com/pinterest/PINRemoteImage/issues"); + if (delegateQueue == nil) { + return; + } + + __weak typeof(self) weakSelf = self; + dispatch_async(delegateQueue, ^{ + typeof(self) strongSelf = weakSelf; + if ([strongSelf.delegate respondsToSelector:@selector(didCollectMetrics:forURL:)]) { + [strongSelf.delegate didCollectMetrics:metrics forURL:task.originalRequest.URL]; + } + }); } } @@ -209,9 +243,18 @@ - (BOOL)responseRecoverableFrom404:(NSHTTPURLResponse*)response #if DEBUG - (void)concurrentDownloads:(void (^_Nullable)(NSUInteger concurrentDownloads))concurrentDownloadsCompletion { - [self.session getAllTasksWithCompletionHandler:^(NSArray<__kindof NSURLSessionTask *> * _Nonnull tasks) { - concurrentDownloadsCompletion(tasks.count); - }]; + if (@available(macos 10.11, iOS 9.0, watchOS 2.0, tvOS 9.0, *)) { + [self.session getAllTasksWithCompletionHandler:^(NSArray<__kindof NSURLSessionTask *> * _Nonnull tasks) { + concurrentDownloadsCompletion(tasks.count); + }]; + } else { + [self.session getTasksWithCompletionHandler:^(NSArray * _Nonnull dataTasks, + NSArray * _Nonnull uploadTasks, + NSArray * _Nonnull downloadTasks) { + NSUInteger total = dataTasks.count + uploadTasks.count + downloadTasks.count; + concurrentDownloadsCompletion(total); + }]; + } } #endif diff --git a/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSData+ImageDetectors.h b/Example/Pods/PINRemoteImage/Source/Classes/include/NSData+ImageDetectors.h similarity index 80% rename from Example/Pods/PINRemoteImage/Source/Classes/Categories/NSData+ImageDetectors.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/NSData+ImageDetectors.h index 7582afe..b5d91d9 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/Categories/NSData+ImageDetectors.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/NSData+ImageDetectors.h @@ -8,9 +8,12 @@ #import +#import "PINRemoteImageMacros.h" + @interface NSData (PINImageDetectors) - (BOOL)pin_isGIF; +- (BOOL)pin_isAnimatedGIF; #if PIN_WEBP - (BOOL)pin_isWebP; - (BOOL)pin_isAnimatedWebP; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINAlternateRepresentationProvider.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINAlternateRepresentationProvider.h similarity index 100% rename from Example/Pods/PINRemoteImage/Source/Classes/PINAlternateRepresentationProvider.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINAlternateRepresentationProvider.h diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImage.h similarity index 88% rename from Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImage.h index 41ab378..4f96b15 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINAnimatedImage.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImage.h @@ -7,6 +7,7 @@ // #import +#import "PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -14,14 +15,14 @@ #import #endif -#import "PINRemoteImageMacros.h" +NS_ASSUME_NONNULL_BEGIN -extern NSString * _Nonnull kPINAnimatedImageErrorDomain; +extern NSErrorDomain const kPINAnimatedImageErrorDomain; /** PINAnimatedImage decoding and processing errors. */ -typedef NS_ENUM(NSUInteger, PINAnimatedImageError) { +typedef NS_ERROR_ENUM(kPINAnimatedImageErrorDomain, PINAnimatedImageErrorCode) { /** No error, yay! */ PINAnimatedImageErrorNoError = 0, /** Could not create a necessary file. */ @@ -55,8 +56,6 @@ typedef NS_ENUM(NSUInteger, PINAnimatedImageStatus) { }; extern const Float32 kPINAnimatedImageDefaultDuration; -extern const Float32 kPINAnimatedImageMinimumDuration; -extern const NSTimeInterval kPINAnimatedImageDisplayRefreshRate; /** Called when the cover image of an animatedImage is ready. @@ -67,6 +66,11 @@ typedef void(^PINAnimatedImageInfoReady)(PINImage * _Nonnull coverImage); @interface PINAnimatedImage : NSObject +/** + @abstract The maximum number of frames per second supported. + */ ++ (NSInteger)maximumFramesPerSecond; + /** @abstract Return the duration at a given index. @@ -105,6 +109,11 @@ typedef void(^PINAnimatedImageInfoReady)(PINImage * _Nonnull coverImage); @protocol PINAnimatedImage +/** + @abstract the underlying data of the animated image if available. + */ +@property (nonatomic, readonly) NSData *data; + /** @abstract the native width of the animated image. */ @@ -137,7 +146,7 @@ typedef void(^PINAnimatedImageInfoReady)(PINImage * _Nonnull coverImage); */ @property (nonatomic, readonly) size_t frameCount; /** - @abstract Return any error that has occured. Playback will be paused if this returns non-nil. + @abstract Return any error that has occurred. Playback will be paused if this returns non-nil. */ @property (nonatomic, readonly, nullable) NSError *error; @@ -152,3 +161,5 @@ typedef void(^PINAnimatedImageInfoReady)(PINImage * _Nonnull coverImage); - (CFTimeInterval)durationAtIndex:(NSUInteger)index; @end + +NS_ASSUME_NONNULL_END diff --git a/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h new file mode 100644 index 0000000..9dbfbc9 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h @@ -0,0 +1,14 @@ +// +// PINAnimatedImageView+PINRemoteImage.h +// Pods +// +// Created by Garrett Moon on 4/19/18. +// + +#import "PINAnimatedImageView.h" + +#import "PINRemoteImageCategoryManager.h" + +@interface PINAnimatedImageView (PINRemoteImage) + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImageView.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImageView.h new file mode 100644 index 0000000..b224f02 --- /dev/null +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINAnimatedImageView.h @@ -0,0 +1,28 @@ +// +// PINAnimatedImageView.h +// Pods +// +// Created by Garrett Moon on 4/17/18. +// + +#import "PINRemoteImageMacros.h" + +#if PIN_TARGET_IOS +#import +#elif PIN_TARGET_MAC +#import +#endif + +#import "PINCachedAnimatedImage.h" + +@interface PINAnimatedImageView : PINImageView + +- (nonnull instancetype)initWithAnimatedImage:(nonnull PINCachedAnimatedImage *)animatedImage NS_DESIGNATED_INITIALIZER; +- (nonnull instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; + +@property (nullable, nonatomic, strong) PINCachedAnimatedImage *animatedImage; +@property (nullable, nonatomic, strong) NSString *animatedImageRunLoopMode; +@property (nonatomic, assign, getter=isPlaybackPaused) BOOL playbackPaused; + +@end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINButton+PINRemoteImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINButton+PINRemoteImage.h similarity index 90% rename from Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINButton+PINRemoteImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINButton+PINRemoteImage.h index 95964b1..1659db9 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINButton+PINRemoteImage.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINButton+PINRemoteImage.h @@ -6,6 +6,8 @@ // // +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINCache+PINRemoteImageCaching.h similarity index 89% rename from Example/Pods/PINRemoteImage/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINCache+PINRemoteImageCaching.h index 907b352..f8a5eb1 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINCache+PINRemoteImageCaching.h @@ -6,7 +6,11 @@ // // +#if SWIFT_PACKAGE +@import PINCache; +#else #import +#endif #import "PINRemoteImageCaching.h" #import "PINRemoteImageManager.h" diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINCachedAnimatedImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINCachedAnimatedImage.h similarity index 86% rename from Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINCachedAnimatedImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINCachedAnimatedImage.h index 58ea7a2..b3b6681 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINCachedAnimatedImage.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINCachedAnimatedImage.h @@ -8,6 +8,7 @@ #import +#import "PINRemoteImageMacros.h" #import "PINAnimatedImage.h" @interface PINCachedAnimatedImage : NSObject @@ -37,6 +38,10 @@ @abstract Return the interval at which playback should occur. Will be set to a CADisplayLink's frame interval. */ @property (nonatomic, readonly) NSUInteger frameInterval; +/** + @abstract Return the size of the underlying animated image. + */ +@property (nonatomic, readonly) CGSize size; /** @abstract Return the total number of loops the animated image should play or 0 to loop infinitely. */ @@ -45,12 +50,16 @@ @abstract Return the total number of frames in the animated image. */ @property (nonatomic, readonly) size_t frameCount; +/** + @abstract Return the underlying data if available; + */ +@property (nonatomic, readonly) NSData *data; /** @abstract Return YES when playback is ready to occur. */ @property (nonatomic, readonly) BOOL playbackReady; /** - @abstract Return any error that has occured. Playback will be paused if this returns non-nil. + @abstract Return any error that has occurred. Playback will be paused if this returns non-nil. */ @property (nonatomic, readonly) NSError *error; /** diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINGIFAnimatedImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINGIFAnimatedImage.h similarity index 100% rename from Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINGIFAnimatedImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINGIFAnimatedImage.h diff --git a/Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINImageView+PINRemoteImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINImageView+PINRemoteImage.h similarity index 90% rename from Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINImageView+PINRemoteImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINImageView+PINRemoteImage.h index f2b262b..f5c4b7e 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/ImageCategories/PINImageView+PINRemoteImage.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINImageView+PINRemoteImage.h @@ -6,6 +6,8 @@ // // +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINProgressiveImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINProgressiveImage.h similarity index 100% rename from Example/Pods/PINRemoteImage/Source/Classes/PINProgressiveImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINProgressiveImage.h index 28b5937..1c68b1a 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINProgressiveImage.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINProgressiveImage.h @@ -8,14 +8,14 @@ #import +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC #import #endif -#import "PINRemoteImageMacros.h" - @class PINRemoteImageDownloadTask; /** An object which store the data of a downloading image and vends progressive scans **/ diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImage.h similarity index 100% rename from Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImage.h diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageCaching.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageCaching.h similarity index 84% rename from Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageCaching.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageCaching.h index 455ba1d..bfafbdf 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageCaching.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageCaching.h @@ -8,7 +8,6 @@ #import - NS_ASSUME_NONNULL_BEGIN @protocol PINRemoteImageCaching; @@ -42,6 +41,10 @@ typedef void (^PINRemoteImageCachingObjectBlock)(id cache @optional - (void)removeObjectForKeyFromMemory:(NSString *)key; +- (void)setObjectInMemory:(id)object forKey:(NSString *)key withCost:(NSUInteger)cost withAgeLimit:(NSTimeInterval)ageLimit; +- (void)setObjectOnDisk:(id)object forKey:(NSString *)key withAgeLimit:(NSTimeInterval)ageLimit; +- (BOOL)memoryCacheIsTTLCache; +- (BOOL)diskCacheIsTTLCache; @end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageCategoryManager.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageCategoryManager.h similarity index 99% rename from Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageCategoryManager.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageCategoryManager.h index aad5688..ec94124 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageCategoryManager.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageCategoryManager.h @@ -6,6 +6,8 @@ // // +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageMacros.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageMacros.h similarity index 85% rename from Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageMacros.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageMacros.h index 3d9e5ed..5f5dd8e 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageMacros.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageMacros.h @@ -3,13 +3,13 @@ // PINRemoteImage // -#import +#import #ifndef PINRemoteImageMacros_h #define PINRemoteImageMacros_h #define PIN_TARGET_IOS (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR || TARGET_OS_TV) -#define PIN_TARGET_MAC (TARGET_OS_MAC) +#define PIN_TARGET_MAC TARGET_OS_OSX #define PINRemoteImageLogging 0 #if PINRemoteImageLogging @@ -18,15 +18,8 @@ #define PINLog(args...) #endif -#if __has_include() -#define USE_FLANIMATED_IMAGE 1 -#else -#define USE_FLANIMATED_IMAGE 0 -#define FLAnimatedImage NSObject -#endif - #ifndef USE_PINCACHE - #if __has_include() + #if __has_include() || __has_include("PINCache.h") #define USE_PINCACHE 1 #else #define USE_PINCACHE 0 @@ -34,7 +27,7 @@ #endif #ifndef PIN_WEBP - #if __has_include("webp/decode.h") + #if __has_include() || __has_include() #define PIN_WEBP 1 #else #define PIN_WEBP 0 @@ -72,4 +65,6 @@ lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \ __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \ } while(0); +#define PINAssertMain() NSAssert([NSThread isMainThread], @"Expected to be on the main thread."); + #endif /* PINRemoteImageMacros_h */ diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageManager.h similarity index 77% rename from Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageManager.h index f73b6c3..8390707 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManager.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageManager.h @@ -8,28 +8,31 @@ #import +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC #import #endif -@protocol PINRequestRetryStrategy; -#import "PINRemoteImageMacros.h" - #import "PINRemoteImageManagerResult.h" +#define PINRemoteImageHTTPMaximumConnectionsPerHost UINT16_MAX + @protocol PINRemoteImageManagerAlternateRepresentationProvider; @protocol PINRemoteImageCaching; +@protocol PINRequestRetryStrategy; +@class PINRemoteImageManagerConfiguration; @class PINRemoteImageManagerResult; -extern NSString * __nonnull const PINRemoteImageManagerErrorDomain; +extern NSErrorDomain _Nonnull const PINRemoteImageManagerErrorDomain; /** Error codes returned by PINRemoteImage */ -typedef NS_ENUM(NSUInteger, PINRemoteImageManagerError) { +typedef NS_ERROR_ENUM(PINRemoteImageManagerErrorDomain, PINRemoteImageManagerError) { /** The image failed to decode */ PINRemoteImageManagerErrorFailedToDecodeImage = 1, /** The image could not be downloaded and therefore could not be processed */ @@ -48,7 +51,7 @@ typedef NS_ENUM(NSUInteger, PINRemoteImageManagerError) { typedef NS_OPTIONS(NSUInteger, PINRemoteImageManagerDownloadOptions) { /** Download and process with default options (no other options set) */ PINRemoteImageManagerDownloadOptionsNone = 0, - /** Set to disallow any alternate representations such as FLAnimatedImage */ + /** Set to disallow any alternate representations such as Animated Images */ PINRemoteImageManagerDisallowAlternateRepresentations = 1, /** Skip decoding the image before returning. This means smaller images returned, but images will be decoded on the main thread when set on an image view */ PINRemoteImageManagerDownloadOptionsSkipDecode = 1 << 1, @@ -60,6 +63,16 @@ typedef NS_OPTIONS(NSUInteger, PINRemoteImageManagerDownloadOptions) { PINRemoteImageManagerDownloadOptionsIgnoreCache = 1 << 4, /** Skip download retry */ PINRemoteImageManagerDownloadOptionsSkipRetry = 1 << 5, + /** + * Do not honor HTTP Cache-Control headers + * By default, PINRemoteImage will by default respect 'no-store', 'no-cache', 'max-age', + * 'Expires', and 'must-revalidate'. Set this flag to ignore those headers. + * TODO: Currently PINRemoteImage will re-download images that only must be re-validated. In the + * future this could be improved with revalidation behavior that stores ETag or Last-Modified + * values and only makes HEAD requests to see if these headers are unchanged. + * see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control and + * https://tools.ietf.org/html/rfc7234*/ + PINRemoteImageManagerDownloadOptionsIgnoreCacheControlHeaders = 1 << 6 }; /** @@ -98,7 +111,7 @@ typedef PINImage * _Nullable(^PINRemoteImageManagerImageProcessor)(PINRemoteIma /** PINRemoteImageManager is the main workhorse of PINRemoteImage. It is unnecessary to access directly if you simply - wish to download images and have them rendered in a UIImageView, UIButton or FLAnimatedImageView. + wish to download images and have them rendered in a UIImageView, UIButton or PINAnimatedImageView. However, if you wish to download images directly, this class is your guy / gal. @@ -140,6 +153,12 @@ typedef NSURLRequest * _Nonnull(^PINRemoteImageManagerRequestConfigurationHandle */ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int64_t totalBytes); +/** + Reports NSURLSessionTaskMetrics for download requests + + */ +typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSessionTaskMetrics * __nonnull metrics) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); + /** An image downloading, processing and caching manager. It uses the concept of download and processing tasks to ensure that even if multiple calls to download or process an image are made, it only occurs one time (unless an item is no longer in the cache). PINRemoteImageManager is backed by GCD and safe to access from multiple threads simultaneously. It ensures that images are decoded off the main thread so that animation performance isn't affected. None of its exposed methods allow for synchronous access. However, it is optimized to call completions on the calling thread if an item is in its memory cache. **/ @interface PINRemoteImageManager : NSObject @@ -147,31 +166,47 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int /** Create and return a PINRemoteImageManager created with the specified configuration. If configuration is nil, [NSURLSessionConfiguration defaultConfiguration] is used. Specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. - @param configuration The configuration used to create the PINRemoteImageManager. + @param sessionConfiguration The session configuration used to create the PINRemoteImageManager. @return A PINRemoteImageManager with the specified configuration. + @note If you provide your own `sessionConfiguration`, please attention `HTTPMaximumConnectionsPerHost` property, it may causes timeout when in conjunction with `maxNumberOfConcurrentDownloads` if you set a larger number to `maxNumberOfConcurrentDownloads` but smaller number to `HTTPMaximumConnectionsPerHost`. */ -- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration; +- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)sessionConfiguration; /** - Create and return a PINRemoteImageManager with the specified configuration and alternative representation delegate. If configuration is nil, [NSURLSessionConfiguration defaultConfiguration] is used. Specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. If alternativeRepresentationProvider is nil, the default is used (and supports FLAnimatedImage). - @param configuration The configuration used to create the PINRemoteImageManager. - @param alternativeRepresentationProvider a delegate which conforms to the PINRemoteImageManagerAlternateRepresentationProvider protocol. Provide a delegate if you want to have non image results. @see PINRemoteImageManagerAlternateRepresentationProvider for an example. + Create and return a PINRemoteImageManager with the specified configuration and alternative representation delegate. If configuration is nil, [NSURLSessionConfiguration defaultConfiguration] is used. Specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. If alternativeRepresentationProvider is nil, the default is used (and supports PINAnimatedImageView). + @param sessionConfiguration The session configuration used to create the PINRemoteImageManager. + @param alternativeRepresentationProvider a delegate which conforms to the PINRemoteImageManagerAlternateRepresentationProvider protocol. Provide a delegate if you want to have non image results. The manager maintains a weak reference to the delegate. @see PINRemoteImageManagerAlternateRepresentationProvider for an example. @return A PINRemoteImageManager with the specified configuration. + @note If you provide your own `sessionConfiguration`, please attention `HTTPMaximumConnectionsPerHost` property, it may causes timeout when in conjunction with `maxNumberOfConcurrentDownloads` if you set a larger number to `maxNumberOfConcurrentDownloads` but smaller number to `HTTPMaximumConnectionsPerHost`. */ -- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration +- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)sessionConfiguration alternativeRepresentationProvider:(nullable id )alternativeRepresentationProvider; /** - Create and return a PINRemoteImageManager with the specified configuration and alternative representation delegate. If configuration is nil, [NSURLSessionConfiguration defaultConfiguration] is used. Specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. If alternativeRepresentationProvider is nil, the default is used (and supports FLAnimatedImage). - @param configuration The configuration used to create the PINRemoteImageManager. - @param alternateRepDelegate a delegate which conforms to the PINRemoteImageManagerAlternateRepresentationProvider protocol. Provide a delegate if you want to have non image results. @see PINRemoteImageManagerAlternateRepresentationProvider for an example. + Create and return a PINRemoteImageManager with the specified configuration and alternative representation delegate. If configuration is nil, [NSURLSessionConfiguration defaultConfiguration] is used. Specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. If alternativeRepresentationProvider is nil, the default is used (and supports PINAnimatedImageView). + @param sessionConfiguration The session configuration used to create the PINRemoteImageManager. + @param alternateRepDelegate a delegate which conforms to the PINRemoteImageManagerAlternateRepresentationProvider protocol. Provide a delegate if you want to have non image results. The manager maintains a weak reference to the delegate. @see PINRemoteImageManagerAlternateRepresentationProvider for an example. @param imageCache Optional delegate which conforms to the PINRemoteImageCaching protocol. Provide a delegate if you want to control image caching. By default, image manager will use most appropriate implementation available (based on PINCache or NSCache, depending on subspec)@see PINRemoteImageBasicCache for an example. @return A PINRemoteImageManager with the specified configuration. + @note If you provide your own `sessionConfiguration`, please attention `HTTPMaximumConnectionsPerHost` property, it may causes timeout when in conjunction with `maxNumberOfConcurrentDownloads` if you set a larger number to `maxNumberOfConcurrentDownloads` but smaller number to `HTTPMaximumConnectionsPerHost`. */ -- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration +- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)sessionConfiguration alternativeRepresentationProvider:(nullable id )alternateRepDelegate - imageCache:(nullable id)imageCache NS_DESIGNATED_INITIALIZER; + imageCache:(nullable id)imageCache; +/** + Create and return a PINRemoteImageManager with the specified configuration and alternative representation delegate. If configuration is nil, [NSURLSessionConfiguration defaultConfiguration] is used. Specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. If alternativeRepresentationProvider is nil, the default is used (and supports PINAnimatedImageView). + @param sessionConfiguration The session configuration used to create the PINRemoteImageManager. + @param alternateRepDelegate a delegate which conforms to the PINRemoteImageManagerAlternateRepresentationProvider protocol. Provide a delegate if you want to have non image results. The manager maintains a weak reference to the delegate. @see PINRemoteImageManagerAlternateRepresentationProvider for an example. + @param imageCache Optional delegate which conforms to the PINRemoteImageCaching protocol. Provide a delegate if you want to control image caching. By default, image manager will use most appropriate implementation available (based on PINCache or NSCache, depending on subspec)@see PINRemoteImageBasicCache for an example. + @param managerConfiguration The configuration used to create the PINRemoteImageManager. + @return A PINRemoteImageManager with the specified configuration. + @note If you provide your own `sessionConfiguration`, please attention `HTTPMaximumConnectionsPerHost` property, it may causes timeout when in conjunction with `maxNumberOfConcurrentDownloads` if you set a larger number to `maxNumberOfConcurrentDownloads` but smaller number to `HTTPMaximumConnectionsPerHost`. + */ +- (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)sessionConfiguration + alternativeRepresentationProvider:(nullable id )alternateRepDelegate + imageCache:(nullable id)imageCache + managerConfiguration:(nullable PINRemoteImageManagerConfiguration *)managerConfiguration NS_DESIGNATED_INITIALIZER; /** Get the shared instance of PINRemoteImageManager @@ -184,16 +219,31 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int Sets the shared instance of PINRemoteImageManager to an instance with the supplied configuration. If configuration is nil, [NSURLSessionConfiguration ephemeralSessionConfiguration] is used. You specify a custom configuration if you need to configure timeout values, cookie policies, additional HTTP headers, etc. This method should not be used if the shared instance has already been created. @param configuration The configuration used to create the PINRemoteImageManager. + @note If you provide your own `sessionConfiguration`, please attention `HTTPMaximumConnectionsPerHost` property, it may causes timeout when in conjunction with `maxNumberOfConcurrentDownloads` if you set a larger number to `maxNumberOfConcurrentDownloads` but smaller number to `HTTPMaximumConnectionsPerHost`. */ + (void)setSharedImageManagerWithConfiguration:(nullable NSURLSessionConfiguration *)configuration; +/** + The result of this method is assigned to self.cache in init. If you wish to provide a customized cache to the manager you can subclass PINRemoteImageManager and return a custom object, implementing PINRemoteImageCaching protocol from this method. Same effect could be achieved by using initWithSessionConfiguration:alternativeRepresentationProvider:imageCache: initializer. + @deprecated Use the class method +defaultImageCache + @warning This method is meant only for override. It will be called *once* by an instance of PINRemoteImageManager. The default implementation creates a new cache on every call. If you're looking to access the cache being used by an instance of PINRemoteImageManager, @c cache. + @return An instance of a object, implementing PINRemoteImageCaching protocol. + */ +- (nonnull id)defaultImageCache __attribute__((deprecated)); + /** The result of this method is assigned to self.cache in init. If you wish to provide a customized cache to the manager you can subclass PINRemoteImageManager and return a custom object, implementing PINRemoteImageCaching protocol from this method. Same effect could be achieved by using initWithSessionConfiguration:alternativeRepresentationProvider:imageCache: initializer. @warning This method is meant only for override. It will be called *once* by an instance of PINRemoteImageManager. The default implementation creates a new cache on every call. If you're looking to access the cache being used by an instance of PINRemoteImageManager, @c cache. @return An instance of a object, implementing PINRemoteImageCaching protocol. */ -- (nonnull id)defaultImageCache; ++ (nonnull id)defaultImageCache; + +/** + * If you want a Ttl (maxAge) image cache, you can pass the result of this method explicitly into the initWithSessionConfiguration:alternativeRepresentationProvider:imageCache: initializer. + * @return An instance of a object, implementing PINRemoteImageCaching protocol. + */ ++ (nonnull id)defaultImageTtlCache; /** * Sets a custom header to be included in every request. Headers set from this method will override any header from NSURLSessionConfiguration. @@ -300,7 +350,15 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int @param completion Completion to be called once maxProgressiveRenderSize is set. */ - (void)setProgressiveRendersMaxProgressiveRenderSize:(CGSize)maxProgressiveRenderSize - completion:(nullable dispatch_block_t)completion; + completion:(nullable dispatch_block_t)completion; + +/** + Sets a metrics callback block to be called when NSURLSessionTaskMetrics are reported for downloads. + + @warning PINRemoteImageManager will hold a strong reference to metricsCallback. Avoid retain cycles by using weak references in the block! + */ +- (void)setMetricsCallback:(nullable PINRemoteImageManagerMetrics)metricsCallback + completion:(nullable dispatch_block_t)completion API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); /** Prefetch an image at the given URL. @@ -317,6 +375,15 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int */ - (nullable NSUUID *)prefetchImageWithURL:(nonnull NSURL *)url options:(PINRemoteImageManagerDownloadOptions)options; +/** + Prefetch an image at the given URL with given options. + + @param url NSURL where the image to prefetch resides. + @param options PINRemoteImageManagerDownloadOptions options with which to prefetch the image. + @param priority PINRemoteImageManagerPriority priority of the operation when to prefetch the image. + */ +- (nullable NSUUID *)prefetchImageWithURL:(nonnull NSURL *)url options:(PINRemoteImageManagerDownloadOptions)options priority:(PINRemoteImageManagerPriority)priority; + /** Prefetch images at the given URLs. @@ -332,6 +399,15 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int */ - (nonnull NSArray *)prefetchImagesWithURLs:(nonnull NSArray *)urls options:(PINRemoteImageManagerDownloadOptions)options; +/** + Prefetch images at the given URLs with given options. + + @param urls An array of NSURLs where the images to prefetch reside. + @param options PINRemoteImageManagerDownloadOptions options with which to pefetch the image. + @param priority PINRemoteImageManagerPriority priority of the operation to prefetch the image. + */ +- (nonnull NSArray *)prefetchImagesWithURLs:(nonnull NSArray *)urls options:(PINRemoteImageManagerDownloadOptions)options priority:(PINRemoteImageManagerPriority)priority; + /** Download or retrieve from cache the image found at the url. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). @@ -400,6 +476,25 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int progressDownload:(nullable PINRemoteImageManagerProgressDownload)progressDownload completion:(nullable PINRemoteImageManagerImageCompletion)completion; +/** + Download or retrieve from cache the image found at the url and process it before calling completion. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). + + @param url NSURL where the image to download resides. + @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. + @param priority PINRemoteImageManagerPriority which indicates the priority of the download task. + @param progressImage PINRemoteImageManagerImageCompletion block which will be called to update progress of the image download. + @param progressDownload PINRemoteImageManagerDownloadProgress block which will be called to update progress in bytes of the image download. NOTE: For performance reasons, this block is not called on the main thread every time, if you need to update your UI ensure that you dispatch to the main thread first. + @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. + + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). + */ +- (nullable NSUUID *)downloadImageWithURL:(nonnull NSURL *)url + options:(PINRemoteImageManagerDownloadOptions)options + priority:(PINRemoteImageManagerPriority)priority + progressImage:(nullable PINRemoteImageManagerImageCompletion)progressImage + progressDownload:(nullable PINRemoteImageManagerProgressDownload)progressDownload + completion:(nullable PINRemoteImageManagerImageCompletion)completion; + /** Download or retrieve from cache the image found at the url and process it before calling completion. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). @@ -513,7 +608,7 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int @deprecated @param cacheKey NSString key to look up image in the cache. - @param options options will be used to determine if the cached image should be decompressed or FLAnimatedImages should be returned. + @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache. */ - (void)imageFromCacheWithCacheKey:(nonnull NSString *)cacheKey options:(PINRemoteImageManagerDownloadOptions)options completion:(nonnull PINRemoteImageManagerImageCompletion)completion __attribute__((deprecated)); @@ -523,7 +618,7 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int @param url NSURL that was used to download image @param processorKey An optional key to uniquely identify the processor used to post-process the downloaded image. - @param options options will be used to determine if the cached image should be decompressed or FLAnimatedImages should be returned. + @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache. */ - (void)imageFromCacheWithURL:(nonnull NSURL *)url processorKey:(nullable NSString *)processorKey options:(PINRemoteImageManagerDownloadOptions)options completion:(nonnull PINRemoteImageManagerImageCompletion)completion; @@ -533,7 +628,7 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int @see synchronousImageFromCacheWithURL:processorKey:options: @param cacheKey NSString obtained from @c cacheKeyForURL:processorKey - @param options options will be used to determine if the cached image should be decompressed or FLAnimatedImages should be returned. + @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. @return A PINRemoteImageManagerResult */ @@ -544,7 +639,7 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int @param url NSURL that was used to download image @param processorKey An optional key to uniquely identify the processor used to post-process the downloaded image. - @param options options will be used to determine if the cached image should be decompressed or FLAnimatedImages should be returned. + @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. @return A PINRemoteImageManagerResult */ @@ -564,11 +659,22 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int Cancel a download. Canceling will only cancel the download if all other downloads are also canceled with their associated UUIDs. Canceling *does not* guarantee that your completion will not be called. You can use the UUID provided on the result object to verify the completion you want called is being called. - @param storeResumeData if YES and the server indicates it supports resuming downloads, downloaded data will be stored in the memory + @param storeResumeData if YES and the server indicates it supports resuming downloads, downloaded data will be stored in the disk cache and used to resume the download if the same URL is attempted to be downloaded in the future. + PINRemoteImageBasicCache does not support disk caching, use PINCache. */ - (void)cancelTaskWithUUID:(nonnull NSUUID *)UUID storeResumeData:(BOOL)storeResumeData; +/** + Cancel all tasks. + */ +- (void)cancelAllTasks; + +/** + Cancel all tasks and store resume data if any task has. + */ +- (void)cancelAllTasksAndStoreResumeData:(BOOL)storeResumeData; + /** Set the priority of a download task. Since there is only one task per download, the priority of the download task will always be the last priority this method was called with. @@ -594,5 +700,4 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int @property (nonatomic, readonly) _Nonnull id (^_Nonnull retryStrategyCreationBlock)(void); - @end diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerResult.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageManagerResult.h similarity index 97% rename from Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerResult.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageManagerResult.h index b2769f1..41ff8c5 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINRemoteImageManagerResult.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRemoteImageManagerResult.h @@ -8,17 +8,14 @@ #import +#import "PINRemoteImageMacros.h" + #if PIN_TARGET_IOS #import #elif PIN_TARGET_MAC #import #endif -#import "PINRemoteImageMacros.h" -#if USE_FLANIMATED_IMAGE -#import -#endif - /** How the image was fetched. */ typedef NS_ENUM(NSUInteger, PINRemoteImageResultType) { /** Returned if no image is returned */ diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINRequestRetryStrategy.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINRequestRetryStrategy.h similarity index 100% rename from Example/Pods/PINRemoteImage/Source/Classes/PINRequestRetryStrategy.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINRequestRetryStrategy.h diff --git a/Example/Pods/PINRemoteImage/Source/Classes/PINURLSessionManager.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINURLSessionManager.h similarity index 61% rename from Example/Pods/PINRemoteImage/Source/Classes/PINURLSessionManager.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINURLSessionManager.h index 8b3cfe2..5b25ff1 100644 --- a/Example/Pods/PINRemoteImage/Source/Classes/PINURLSessionManager.h +++ b/Example/Pods/PINRemoteImage/Source/Classes/include/PINURLSessionManager.h @@ -8,7 +8,9 @@ #import -extern NSString * __nonnull const PINURLErrorDomain; +#import "PINRemoteImageManager.h" + +extern NSErrorDomain _Nonnull const PINURLErrorDomain; @protocol PINURLSessionManagerDelegate @@ -16,9 +18,10 @@ extern NSString * __nonnull const PINURLErrorDomain; - (void)didReceiveData:(nonnull NSData *)data forTask:(nonnull NSURLSessionTask *)task; @optional +- (void)didCollectMetrics:(nonnull NSURLSessionTaskMetrics *)metrics forURL:(nonnull NSURL *)url API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); - (void)didReceiveResponse:(nonnull NSURLResponse *)response forTask:(nonnull NSURLSessionTask *)task; - (void)didReceiveAuthenticationChallenge:(nonnull NSURLAuthenticationChallenge *)challenge forTask:(nullable NSURLSessionTask *)task completionHandler:(nonnull void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler; - +- (void)didCompleteTask:(nonnull NSURLSessionTask *)task withError:(nullable NSError *)error; @end @@ -28,11 +31,16 @@ typedef void (^PINURLSessionDataTaskCompletion)(NSURLSessionTask * _Nonnull task - (nonnull instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration; -- (nonnull NSURLSessionDataTask *)dataTaskWithRequest:(nonnull NSURLRequest *)request completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler; +- (nonnull NSURLSessionDataTask *)dataTaskWithRequest:(nonnull NSURLRequest *)request + completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler; + +- (nonnull NSURLSessionDataTask *)dataTaskWithRequest:(nonnull NSURLRequest *)request + priority:(PINRemoteImageManagerPriority)priority + completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler; - (void)invalidateSessionAndCancelTasks; -- (void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didFinishCollectingMetrics:(nonnull NSURLSessionTaskMetrics *)metrics NS_AVAILABLE(10_12, 11_0); +- (void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didFinishCollectingMetrics:(nonnull NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); @property (atomic, weak, nullable) id delegate; diff --git a/Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINWebPAnimatedImage.h b/Example/Pods/PINRemoteImage/Source/Classes/include/PINWebPAnimatedImage.h similarity index 100% rename from Example/Pods/PINRemoteImage/Source/Classes/AnimatedImages/PINWebPAnimatedImage.h rename to Example/Pods/PINRemoteImage/Source/Classes/include/PINWebPAnimatedImage.h diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 67be035..3cc1c0d 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,675 +7,680 @@ objects = { /* Begin PBXBuildFile section */ - 002F3F0490AA55AD66EDB40E8B51A4A6 /* CanProvideAnimatorForEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1649C9B28814A0E5C609ACCC9D4BFEA /* CanProvideAnimatorForEvent.swift */; }; - 00391BEF007FBA57A883F62A58C0ABEC /* ASRunLoopQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 780AEE0E9559677F32F78674DB2BBC5A /* ASRunLoopQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0059D15A6BCB46E90F712F915EE11B82 /* ASTextKitCoreTextAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = E5B9950A1BB7AB4BB4F981109C561078 /* ASTextKitCoreTextAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 00AAF4C9D0B7869478DE156A538755F1 /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 15C1333DEA8E11B47C507085AA30FC6F /* ASLayoutElement.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 01A3D7BB0E63D3A900D0A0865A2D547B /* ASTextNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F207CE79ECE5ADC0BED3DD0D8B7B83B /* ASTextNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 01DB863C9D13E9599D5D77F7F2B36D1D /* CGPoint+maximumAbsoluteValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBE5E3D5558488FDEAE33619126F1513 /* CGPoint+maximumAbsoluteValue.swift */; }; - 01EB60D21A8130AF1CA4BEFEAB97AAE0 /* ASMutableElementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 504B06FD3DACEEAFDEA8D5E809A7095B /* ASMutableElementMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 0243198C0934549E3873E32EF8E14B1D /* ASStackLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E08232F3108F02C86EA8BAD407FEBB6 /* ASStackLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 025BA0BDF87BC89E358481C5C60C4EAB /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8155FA2A18B7EFC15B8F6773207514EE /* Logger.swift */; }; - 027F6D0B71B1C122F3DB0C889E14362D /* PINRemoteImageManager+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 056F5351D15FECFF550FF001A1172E9C /* PINRemoteImageManager+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 02A6DB9492DDC5300BC18FB2FD203B06 /* ASDisplayNode+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6490DDA9673AE60693B85E2B708DC4D8 /* ASDisplayNode+FrameworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 045B3BAABA7A144648846AEB06F8D093 /* ASTipProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 8300AF8B7A5E55E071CE2BBFFC6404B9 /* ASTipProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 04B103CAF019243ADC4DC9D3DD90A5CF /* ASTextAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0ADDD0546EE438CB2D70AE96914E0431 /* ASTextAttribute.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 04B5B722F581E8F3CBA1AA87C19D36AE /* UIViewController+HasImageZoomControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA043EEB04C16347822B57BAA117E2E /* UIViewController+HasImageZoomControllers.swift */; }; - 0579970DD7F65FFC5ED5B3403CFE1D69 /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = D9ACB6B0A84C9EC8F26624BCE6B949FF /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0640D451C48BDD8858DA1EFA09998318 /* ASDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = 88E78B612E8360D5296AEE501054F09A /* ASDimension.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 06B6D4A109D383F87DB87E9B94F5AA73 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1033543310C731B9BF398A69B3587CE4 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift */; }; - 071C5AE6A74A0CBFEE0A5E02D0ED5AEE /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E59B54071C5A06019DE422E434D54C4 /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0725BBB7407A94716CE1B783F29AB8E4 /* ASResponderChainEnumerator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35E06328EC3399B7E3571D2B013A22CD /* ASResponderChainEnumerator.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 083D3FC1CE6C10C882D9D0C710C3DC7A /* ASRelativeLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = D5DDD9B2DE79EA31E77C347CB177062F /* ASRelativeLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0849CFDCCA9EBB766739F0123AC2B0A6 /* PINImageView+PINRemoteImage.h in Headers */ = {isa = PBXBuildFile; fileRef = AB0C309D246B1C8BAD0377A6A1815153 /* PINImageView+PINRemoteImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 08608B2879CDB2B1F99FA21A85C0C43E /* ASTabBarController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5062F79F55E2B3E2E71540B5210A7541 /* ASTabBarController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 0926F72040D685FA90F0E1D0E63E236E /* PINImage+ScaledImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 385E6F060FBF7CFBD72B759FD50D0667 /* PINImage+ScaledImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 09E1B26CCFAD9C7A295BB181DCCC0BB4 /* _ASDisplayLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 093258A51C5A055B7D4487D97D048C02 /* _ASDisplayLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0A1D927875C8CDD62209FA3521CBEBF3 /* PINRemoteImageBasicCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B1E4BAAE8A86601C8C6B97DEFE47E4 /* PINRemoteImageBasicCache.m */; }; - 0A2B6E66AB8561876A5B7961CBAE6B2F /* ImageZoomControllerActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114F5E4FAA06F5EB193F8331FF581260 /* ImageZoomControllerActions.swift */; }; - 0B269BCCD0EB4A0324303CF2EBF429BB /* PINCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 31182033736429F714F11A99D15B5A37 /* PINCache.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 0B909629DF48FCFF4BC16D2166703D9E /* Logger.Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8550F0BE91A5EAD479CBC31C1CC9D2E /* Logger.Settings.swift */; }; - 0BD4C7C6A2EB249987586F5444AAD546 /* ASAbstractLayoutController+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FDE745A011DD537BF75CF20625D7C2E /* ASAbstractLayoutController+FrameworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0D31219B5DC9333FDE2110ED1E4377B2 /* ASCollectionViewLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = C745ABE5CF7074BDCB56E1DF0CE7481C /* ASCollectionViewLayoutController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 0D6395EA2227BAA083EA3F045E165EC5 /* ASImageNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CA1EEA85B1AB08A62240A714B72B51CD /* ASImageNode+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0D73C8C9DC543315F1B17E1815A3D2F1 /* ASImageNode+AnimatedImagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = ED7A7B2E8EC994618EEA9CF500126C01 /* ASImageNode+AnimatedImagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0DB7D0EE591B6FA31F1EA8AD52435873 /* ASCollectionLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 34B72E8FAB374BBB6BA3BC734730D1B8 /* ASCollectionLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0DD653DC248232E3421B2BDAA665EE07 /* ASLayoutElementPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = B1257D21990FE33E970249DA587E24A9 /* ASLayoutElementPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0E1DD80748781A950EE5F94272757B5E /* ASTipNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 82B5FE5440AD8C2D32D0905139420FC0 /* ASTipNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 0E2B3A5B6C9DA77C2A1843CEA33101D2 /* ASBasicImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 47887C414E19B0A79D466E48240E56AF /* ASBasicImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0F4AED0CA7EECB3C56C6888C3F836480 /* ImageZoomController.Factory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49405BF411A045F9971308FAA95292D5 /* ImageZoomController.Factory.swift */; }; - 0F8E467E705C3E5BF72DD363595CA32D /* ASTextKitEntityAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 44F8BC427F71546D5619B405BCE1DD36 /* ASTextKitEntityAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 10098F7134E99EF773535B6E07CB11C0 /* PINRemoteImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 601C1AF391DB366A2C1A19B86C26DEFA /* PINRemoteImageManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 103E27C248EE7B173C0C64AC5390317C /* InjectableLoggers-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C04BAB749055606D3946777030990DE3 /* InjectableLoggers-dummy.m */; }; - 1064084DBDBC4D7B2C58F56C50F973A6 /* PINOperationGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = EA5FD6837C3BC283BCEAE16603AE8BA9 /* PINOperationGroup.m */; }; - 10D685AF3B1C113F3E459C939ABDF7F1 /* ASPagerFlowLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E6ACA3ECDEAADA5D85338D020179D6EC /* ASPagerFlowLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 10D745D19BDB05D784DA5ED816193FCA /* ASIGListAdapterBasedDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5C0CFFB06A4F703B26E2CB912988F77 /* ASIGListAdapterBasedDataSource.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 10DBE461D8A06CE975D03AE020106808 /* ASNetworkImageLoadInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A70B3A34B45D1967D684671ED89E5B6 /* ASNetworkImageLoadInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 11499C360C83931E8E9F51425561E58B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - 11D7CF9506912DAADBA5ABF214E50103 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 843DB650E83C835994FAEF2C6A66B8CC /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 11E4083FE5D92B1DC32D1165F97915D6 /* ASSectionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = C107CFBED03119CB9FB979B38275EFDE /* ASSectionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 11EC62A0043EF4EE18B0D99DA444B8E9 /* _ASCollectionGalleryLayoutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6808266211BF925459BF96812FD61642 /* _ASCollectionGalleryLayoutInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 12225A320709A7FE471FBED2E9BC6F4F /* ASTipsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 04FE1FDDBACAF8709FBAB591EA6C2155 /* ASTipsController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1322EE221856557E83837888D63E3906 /* ASTip.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1EF3A863F3C8E076FC078D3A85201FE2 /* ASTip.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 134CD958011333FAD509D1BD3F5D56F0 /* ASTextNode2.mm in Sources */ = {isa = PBXBuildFile; fileRef = 722AB0BD59691CFBC5D191DD68CDC635 /* ASTextNode2.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 136841D83902F016BF8DAC289E1E3E71 /* ASCollectionViewFlowLayoutInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = E19DB721C1C7526CC7059B683149A992 /* ASCollectionViewFlowLayoutInspector.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1491813C6D4E5F79AE48C2007F6D31A2 /* PINRemoteImageProcessorTask.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9B0F0A3D14749D0C88E4093EF353C9 /* PINRemoteImageProcessorTask.m */; }; - 14B16D82223A9415B11A0158A2D627B9 /* UIView+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACA70DF8BDDEF5677F2ADD9A82261E8 /* UIView+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 15160F9217A3745BD8A1EAEA1FC121E5 /* PINCache-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 78C0E5FE49415C26C04C9F48071F9E03 /* PINCache-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 154078E295CEF73049CC0E6EA4E894BF /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49091F146299E5C296CCD271B6BCF996 /* Photos.framework */; }; - 159B31B50A5D17400CDE79FE85A619B5 /* PINButton+PINRemoteImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FC68EA45CF88CEF4344C5649820AC99 /* PINButton+PINRemoteImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 15CED60EDCFC60450E0BCB2A798D3D22 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81225F64FFCB713D06102F384EE235EC /* Animator.swift */; }; - 16642C1D32032DBB54C485753C29E3A9 /* ASPageTable.h in Headers */ = {isa = PBXBuildFile; fileRef = F23780FCB6ACAED58B9318C15C8B0DE8 /* ASPageTable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1687E1405D8B76F297F6D9853BAB346E /* ASTip.h in Headers */ = {isa = PBXBuildFile; fileRef = C513C2D2192061E27F0D119FF031C017 /* ASTip.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 16B7CFBB89DD8CBF96D4210337038E52 /* PINDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 860C40113A4C6ADD6363A09B97EB2272 /* PINDiskCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1739373E24C91A75D0D20FEC8170563E /* ASRangeManagingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DA0C325BE2C19C06990097FF199548F0 /* ASRangeManagingNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 178246C79CE61DF43CC5578F9CC506B3 /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EBD106F17D31DCE3ACD608207D0124 /* ASCollectionViewLayoutFacilitatorProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 186BF255034FDE286A120E832E0A8988 /* PINOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 64BFE2FB5FD0C114FE30D1443B38097B /* PINOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 189DFEFB1A0130E9E4C859D5908032CC /* PINCacheObjectSubscripting.h in Headers */ = {isa = PBXBuildFile; fileRef = FA100E34969B2131C471F94030FF7F28 /* PINCacheObjectSubscripting.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1A4F82222C3795E4CE2A87A593619A35 /* _ASPendingState.h in Headers */ = {isa = PBXBuildFile; fileRef = ED8FA0390861FE0DF8871CD7F10DABFA /* _ASPendingState.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 1A5F8D66D71A2AB8F4A5D7153246EFA4 /* ASDimensionInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 124148AADE44AC741CFADC231F551605 /* ASDimensionInternal.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1AC4A7DBD54618D6F1CBA4699C513313 /* CGRect+Difference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437A7EB85DC2C2F59274B60DA2238D0B /* CGRect+Difference.swift */; }; - 1B382A91CB2301F2D4F0A493820CFDED /* SimpleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEAC1BDFD6524223CCD83E5EDC23DEE1 /* SimpleLogger.swift */; }; - 1B97AAE188468779CE6CE48E9942428D /* ASDisplayNodeExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9716B558FD71C638448F6241417C5707 /* ASDisplayNodeExtras.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1C687D3F4D8F67B2032CF289BB9AB025 /* ASControlNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 01E4661F07305554D5DE06D73578BF89 /* ASControlNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1D6AFE79A5A65E81A6FCCB54DCD48D67 /* PINRemoteImageProcessorTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 96BE75919B287F89A7548E608DFC243C /* PINRemoteImageProcessorTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1DC39F3F4F72437DE712C602F5AE4190 /* ASTextKitComponents.mm in Sources */ = {isa = PBXBuildFile; fileRef = BDF8134E8543067B3399A8AFC359C859 /* ASTextKitComponents.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1E1C0ACF37949DE482591B7149C6EBD9 /* ASDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1DEFE7301FC80CCC24CC61198C436845 /* ASDispatch.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1E65D5EB0BF41F25B9CEDFDB08A30624 /* ASControlNode+tvOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA013F86E55F43BBBB8A8C7596DE700A /* ASControlNode+tvOS.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1EA7BAB3BE0B0B5D2BC7C24F5E81786A /* MockLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0BAAC0ACC1784F708C88E5C8EBCC43 /* MockLogger.swift */; }; - 1ECA3D2CAA1C10E287A264E15ADB5C55 /* PINRemoteImageCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8BCDD05FFF87F653DF293D126D9292 /* PINRemoteImageCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1EE6187046660F0B4B75F24D41C394F1 /* Pods-Zoomy_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 97917796797A60F0392794674DAFD64E /* Pods-Zoomy_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1F08CA3527039D1F70D90D8F2953B616 /* PINGIFAnimatedImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 688A39228B8F3C56FD32EA204F9A9FEC /* PINGIFAnimatedImageManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1F70E930F9B87CC562271891712E24FF /* ASTextRunDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 717574B35CF1E6D3F744307CCE00121F /* ASTextRunDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 1F7ED5B3492CAD695B3A869203CF7E5C /* PINRemoteLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 01D61BF0A499F5857CF17E32798585EE /* PINRemoteLock.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1FDCAB680F4DB300A4CF17EBD4960E8E /* PINRemoteImageCategoryManager.h in Headers */ = {isa = PBXBuildFile; fileRef = FC8926956354A9BB50C3BB8FFD5A07D9 /* PINRemoteImageCategoryManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2078DCF8E2791B2FD569971DD6641BD8 /* PINRemoteImageCategoryManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 38C81F994E42B0DB94073425D99DAC06 /* PINRemoteImageCategoryManager.m */; }; - 20DA623C76E1F8309F402CDECC5B9B42 /* ASNetworkImageNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 53BF6FEFB38F9EA8AE1B2C5E3FE6DD85 /* ASNetworkImageNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 2137C3377BF2B235A0BA017C04B5AB2E /* ASRangeController.h in Headers */ = {isa = PBXBuildFile; fileRef = C7CDB77E762DB5C99E6306652B4B6947 /* ASRangeController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 22C6082EA35CCB6F3608CE0C9631A6EF /* PINOperationMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 8601A38169596B1A8B21A3BA548AA1E4 /* PINOperationMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 23BE55E8E6410B8D54D6F9C2D40BD16D /* ASTraitCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B7C5313BA0D58DED056D33BC4538443 /* ASTraitCollection.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 23D397D9E8853F04EDDA3D79FC58B312 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - 240BADF0416FB59ACD5D0102D73EC8E4 /* NSMutableAttributedString+TextKitAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07A5F3EBB5DB5D888DFCF04CA861A73F /* NSMutableAttributedString+TextKitAdditions.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 249C5B2AFC9EA963597A509989F8AA6C /* PINWebPAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF08A0A062F57E0ABEE60019B8BFE6A /* PINWebPAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 250D19DEB99FD549897E6B9C20A5CAAA /* ASDisplayNode+Ancestry.h in Headers */ = {isa = PBXBuildFile; fileRef = DD7FED1C7830F32AA3BC824803FC338C /* ASDisplayNode+Ancestry.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 253FC2EE7D347619C895A80B6C0A1A3D /* ASTextKitEntityAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E8220DCF4A5EA772D044B1A50261387 /* ASTextKitEntityAttribute.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 25CF24BA0C6AAF9ED814A06492F5D70D /* NSParagraphStyle+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FE925E84A281D06546AD497ECF45514 /* NSParagraphStyle+ASText.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2790D1518B5518A127BF3AA6A3067804 /* ASConfigurationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 745BC45253F7B8CB5026E5AE52813E82 /* ASConfigurationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 27A3884796954EA8D1329687A8137FD9 /* ASRunLoopQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = D34150625D2DF5F1674579F01ACAEA54 /* ASRunLoopQueue.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 27F239354D9946FFCD3A1128E1A361DC /* ASTextRunDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = CFEE3F2F5FCAF0F3908A81163FD68D8D /* ASTextRunDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 280708CDEBF58DAADAE72928157A82CD /* PINURLSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8625D5C81FCFE2B385A4DD440C2B9EBA /* PINURLSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2823B4A72F9BBA7D501A89E6EBDB81BE /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = EC5266FA08A00D7A1C2EB5B60A5CF66A /* ASLayoutSpec+Subclasses.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 2872FE27D5885A9FB8CB020F330AB19A /* ASTextLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C30E737EC48CE6BA7BA08E469B40F7E /* ASTextLine.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 289B94828460A43B11C67396FA7A9AF4 /* ASBatchContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FD73543F8F59FA39EB762F129AC023EF /* ASBatchContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2A15AB6DF134AD6043C18E6CC95B3C94 /* PINCache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 406975D5F17381231A901E0D62D7A138 /* PINCache.framework */; }; - 2B65580877A4771FF00AB1120636E94F /* ASTableView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4AE2CCC6E863F878281B34B30F6FFC /* ASTableView+Undeprecated.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2BA8083637ADC46C06E7E4AE82EA4C18 /* ASImageNode+CGExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 00F0D9E4494E6E4440167C3B132C83CA /* ASImageNode+CGExtras.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 2BC37AF342E9A5BDCC9D7294EAFC1EB2 /* UIGestureRecognizerState+CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 577ABC84D61A466B9DC126551BCA72E8 /* UIGestureRecognizerState+CustomStringConvertible.swift */; }; - 2BF72546F7877287B909A3110DD68986 /* ASVideoPlayerNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = A78AFDF66148881309B4E97383CA01DC /* ASVideoPlayerNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 2C05B30FFB36608D359F1608EC16875A /* PINAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BF91A7594887570D0581A2292B69202 /* PINAnimatedImage.m */; }; - 2C489D68B1A024EFF3E7364EC82D8126 /* ASDisplayNodeLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 734D5D9C89E717418FCAA7185ED7E02B /* ASDisplayNodeLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2CAE4CE007DCB8DBE3151C63D0741D5C /* ASScrollNode.h in Headers */ = {isa = PBXBuildFile; fileRef = EF0AED795C713127D4F67E01AAC3B788 /* ASScrollNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2D782F36DA488D371DF71775675CAA6A /* PINCacheMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DEA1E8382A2B2C35A6C1A9EAC3A087E /* PINCacheMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2DB1908538DE1243A6131530A62FDA54 /* ASCollectionLayoutState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 05641F15444EBE2BE289D9C02E82E530 /* ASCollectionLayoutState.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 2F3EA1FD73E0904E3966BF1FE94E5264 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - 3005777C0CE73129A6B810B3555D2F2D /* ASControlNode+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = C187236A999EC1D588BFDC6A9269C806 /* ASControlNode+Subclasses.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 31592827D033C5045F36B35D5235CD2C /* ASCollectionLayoutDefines.mm in Sources */ = {isa = PBXBuildFile; fileRef = 06679FB2C6525803A57E1ABF62E2AE5B /* ASCollectionLayoutDefines.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 315D377B615593093071B69214134A03 /* Pods-Zoomy_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 995ACD99A6A9DAE10AB6D1FD8C20BA35 /* Pods-Zoomy_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 317E4E8B93A75823613C601DFFCF3B4E /* ASLayoutRangeType.h in Headers */ = {isa = PBXBuildFile; fileRef = DBBFE01B8675C3711CF07D2843B07D0F /* ASLayoutRangeType.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 321436AC03A174B345BAB91AC4555A36 /* UIImageView+Zoomable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0347E82F5AE84656ECD2CB86F0972084 /* UIImageView+Zoomable.swift */; }; - 3239D33A632969DE1D916FF47EDC2323 /* ASHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D4271F88523068290159A5B308C26DE /* ASHashing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 32755CD2F36CBBDD8493829C91DC192A /* ASMapNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 23C2025A1786911B195905E0D5D2B2FC /* ASMapNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3297888C20BE64DE5ECC7C2ED5D2C39F /* ImageZoomControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1BF56DC2832DD482B008CA61701A5B /* ImageZoomControllerDelegate.swift */; }; - 3306C0DFD430ED8ACDA69D3A648D30B3 /* ASPagerFlowLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2CF418803B52917B4CDEEFEECE88DF2D /* ASPagerFlowLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 336CCF0C26845D984B5884EDFB29E3EA /* PINRemoteImageDownloadQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 29423EDA573890D6CA0D528B6D1D3269 /* PINRemoteImageDownloadQueue.m */; }; - 337CDAF5180D8D774C75895165C67D49 /* ASExperimentalFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = 0496BFF0C5BC4DE37E77097EBE8DAA21 /* ASExperimentalFeatures.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 341FC0D3130F9D9AF4B060B02921A8BB /* ASLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF3ECB29AFF0D004E804019BA456BAF /* ASLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 342A6850D79799714A72A1CB4A398F4D /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = A953839D36FAD7AB1C3B310EA76073D0 /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 346F86D4ACD926D29B1D76D58B494FC9 /* PINImage+DecodedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DE6DADB18EAD43910351907C8EAB45 /* PINImage+DecodedImage.m */; }; - 351525A5E2172EF827DED5472494B3E4 /* PINMemMapAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = F8876372AC72ABDE78438AC6901D6A2C /* PINMemMapAnimatedImage.m */; }; - 36575619B625EF1C5E621DDE0F9E99EB /* ASEditableTextNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = B283A07DE6907D817AC983307646ED4C /* ASEditableTextNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 369C1DD571DE019562ADE66655FE36D3 /* ASDisplayNode+Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A590B674BD9CFE88538617C0FE64948 /* ASDisplayNode+Yoga.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 37CA83359712F5584386382793206669 /* ASTableView.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD9985360CAA99C3433E43A198C9C8C4 /* ASTableView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 37F0A65D271A4278C9D59169D03F8A8F /* PINRemoteImageMemoryContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 92540F298A1CABBD995289FDD9759F69 /* PINRemoteImageMemoryContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 38E99CD9A2904EBF5DBB0F33BBED2CC6 /* ASTextUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 994BF7579A66B53B1E474D7F2E06A292 /* ASTextUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3904433E32284DB84884CDD1B6E1ABED /* ASCollectionLayoutCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = C47D135FDC8D2FF911DEA2FC755D8C75 /* ASCollectionLayoutCache.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 3A4C3C416115B6811876A290B0E3F9A9 /* ASGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCAAB9B73EF8F3432A4345B9A9A25A2D /* ASGraphicsContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 3B5CF4A5E8DD242D99FAE2464626184F /* ASDisplayNode+Yoga.mm in Sources */ = {isa = PBXBuildFile; fileRef = E01A5CAF748172FE038684764702EF61 /* ASDisplayNode+Yoga.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 3BF659B8C25F5BF3A88F50E2405EDAC7 /* ASYogaUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A8933680D912A0075750162CB15EF9F /* ASYogaUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3C28F730FA7B9B85C19031FAFC4500FE /* ASCornerLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = B10A8EE0FA86A85383E48A756A391C24 /* ASCornerLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3C5906F9B284E443F5CA74151CE89DF4 /* ASAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D05F80B69A6CAAC89037EC81A01CAE8 /* ASAvailability.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3CA21E403D8E0004E59088033CBCDD2E /* ASCollectionNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 22D04588E915CA87458FE8343D2779A2 /* ASCollectionNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 3CA7DA2DB852372F0CDCE063EC8BE397 /* ASViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = C2F3FAB56ABA986E779429D2637559C7 /* ASViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3D030866F9597CB3CA56ACCFE037BA10 /* ASPagerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B6A6531A377911E1EFE834A1B541072D /* ASPagerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3E3D581B1E51870675E23BD99BF7A65A /* CanLogMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1337D073335F7331614C588A0EEAAB54 /* CanLogMessage.swift */; }; - 3E7A0FCCEA205520EDA2161B19BA9299 /* ASImageNode+AnimatedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 609E9C43163ADCB8E907714C5FFF8826 /* ASImageNode+AnimatedImage.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 3EBC79D53650CCC93262B12DB26403BD /* HasDefaultLoglevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FB154DB28A1272A40CA2071CA41E71 /* HasDefaultLoglevel.swift */; }; - 3EDC0AACE3405379DDFBE2E35F8B0193 /* ASControlNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 998892452F748ECC73ACD89183345341 /* ASControlNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 403C3B83126978396F209A3E5B7F6E7B /* ASDefaultPlaybackButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = C54C9862069FBA457D7E8F2CAC1BEDEF /* ASDefaultPlaybackButton.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 413452835A420243CD07E4FAC1D0B3B1 /* ASDisplayNodeInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EFD085094FB76099386A32CCCDDB062 /* ASDisplayNodeInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 418AB08FFDAE36CF2098EC8C0000E462 /* ASHighlightOverlayLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 771C739307382FB3BE6C97B81D92D604 /* ASHighlightOverlayLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 418C29E0B1D31105C9F3F09AD392AC67 /* _ASAsyncTransactionContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB14945CFEBAC7BB06C3931211F933FB /* _ASAsyncTransactionContainer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 41A0BD05412EE95BC6D3FCF8D948FFE9 /* UIImage+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C13FE60D14FB69B42CF62FDDB8882EF /* UIImage+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4251732D573F5FDD6CC34108977CEC1C /* PINOperation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DF75328C738F4C8E40C3924A1C776D6 /* PINOperation.framework */; }; - 430B85802BE09219C878C986B07EFE52 /* ImageZoomController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C957DCA2DFAE3DE735CBF4FF71F8C79 /* ImageZoomController.swift */; }; - 43CEE1A4B055933A0CB57409BDD51592 /* ASNodeController+Beta.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26245E1F996E74C2E922A30F3ED2D3E9 /* ASNodeController+Beta.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 441D77CEBE2C3B8D28B5866F90374B50 /* ASDisplayNodeTipState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8C4C2353FF592E40999EFBD5AB3AE15C /* ASDisplayNodeTipState.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 45112E474BA6016E05CED490D795AEC5 /* InjectableLoggers-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 639031EEB8C0E0780319C2E1B91EC177 /* InjectableLoggers-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4645B27FF433ED2750B4309F2489FC50 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = E062EE8439098EF20D02C7338C975C52 /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 469C351BC6D64602B1742D5F0045BD29 /* ASConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BD044C71694B82FE5978E510C75CBA /* ASConfigurationInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 46AA07F4FBF287F956D146C0008A9A3F /* PINCachedAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B4568266DA1D977E83A8C75D4C2C35E /* PINCachedAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 46DB5F02CE4430EA881B21A9D3CEE370 /* ASControlTargetAction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6A8C7D884197F26D73FBA82D4A4132C5 /* ASControlTargetAction.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 470A8F20E14325DF2B2928FD8FE214F5 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A2517A7943CC5A852D4396DD7B89109 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift */; }; - 471BC5ABB7D0E3B32E5C3F43F461F256 /* ASDefaultPlaybackButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DDC011BFAD764B9FB35A1A1F6280062 /* ASDefaultPlaybackButton.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 47244AD1C3D2DD40C6276E0E2B10C2F8 /* CoreGraphics+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EEF9D9818AB62929E90309B6F369ED2 /* CoreGraphics+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4762888C778D64B38AC1EE35F4D73F95 /* UIImage+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = 067CAA9F4FC781E023BDE479666C0EBF /* UIImage+ASConvenience.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 4779B0E0D89E2A8468BCDDB30AFA1373 /* InjectableLoggers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DAEC71D283EFA4FCB50A3E29F51370A /* InjectableLoggers.framework */; }; - 47F6AA826F870066399AADCB7180A7AE /* HasImageZoomControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95405DC3767380B72AF31549E659FCF7 /* HasImageZoomControllers.swift */; }; - 4885AC283DC3BCEE21F90AE65106A0E3 /* ASMutableAttributedStringBuilder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29ADC9D575218E44CB3B4434E2C47BEA /* ASMutableAttributedStringBuilder.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 492AA2B3092756B8366B5069063130CE /* ASConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = E327F711FFD756BD667AD6AC61D3C660 /* ASConfiguration.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 4995DFDD8EC929DD86E170B882E3296B /* ASRecursiveUnfairLock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 860B39EE6BB8A3966AF1259098EEB687 /* ASRecursiveUnfairLock.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 49A75566AFB4BA6F389C3D26415B1C69 /* PINOperation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DF75328C738F4C8E40C3924A1C776D6 /* PINOperation.framework */; }; - 49D95BC71BDB81CF58A39ACF9704F2D2 /* ASAsciiArtBoxCreator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 20F81D70DF5D1073C6720482B6C22D53 /* ASAsciiArtBoxCreator.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 4A25794D6B189477201E5B59C041EC84 /* ASInsetLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 617A1C88184B4FC6BD7DF6B8D9D96833 /* ASInsetLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4A34BCF888B15A35B4C5723EE20BFE16 /* ASAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = F7B197008C37795CA80DA38516F408A2 /* ASAssert.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4A430940C462FDD1F79386EC5F75C1D1 /* PINOperationGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B19F9A89A433337404373E49907CF9 /* PINOperationGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4C23EF2E6893AA838D689B28DC1F13E4 /* _ASDisplayLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 74903A67A4FAF9B14E31F4D571B27DFB /* _ASDisplayLayer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 4C480FDD8ADE120B5B9CDE009485248C /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB52888B23BC72D0EC9DE977B805591 /* NSIndexSet+ASHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4C5031DC1938A816B9BC7DE205504AC6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - 4D2DDBFD3EE5709B5674F7949EFB3FAF /* _ASCollectionGalleryLayoutItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4BBF35A5BFF3C8055E41FF8D16E77F /* _ASCollectionGalleryLayoutItem.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4D894BF22B604E122139AD67FBD8129B /* ASCenterLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99E23194CF8E8F54AF09B96E09EFE9FD /* ASCenterLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 4E441B704883F919B3E9E7B053EB1582 /* ASLayoutSpecUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = BB82EEF6CD35EC54E853AD4070BB9F25 /* ASLayoutSpecUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 4E5D73F550952F377F7DFEF867C27DF5 /* ASWeakSet.h in Headers */ = {isa = PBXBuildFile; fileRef = D804DC3A2743336B5C1C7F72579362A6 /* ASWeakSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4F00CB06B21669120C987F32487A9730 /* ASBatchFetchingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1993B19AB3BDE5C6993A436E9862ED6C /* ASBatchFetchingDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4F8327C406F433956A1A6A2AA46625B7 /* ASDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = BEC9D1A35829C776E86C1943567228B3 /* ASDataController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 4FB8C73D7379AE01AE0D167CB8CF75C6 /* PINRemoteImageTask+Subclassing.h in Headers */ = {isa = PBXBuildFile; fileRef = 821867185C05134187FCADAB598C7AFB /* PINRemoteImageTask+Subclassing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 508B94D0F4CDBB448A79FE70A11A36E2 /* ASDefaultPlayButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = B093FB7C9D3A95FC8A8BA9F203EF0987 /* ASDefaultPlayButton.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 5138A2E0796CC66D12A85C04920FA8C3 /* ASCollectionLayoutContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8BF6A75BC54E75526F8E7A07BDED4AD6 /* ASCollectionLayoutContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 51CD3CA60054DAA0FFCD9DF88D973559 /* ASBatchContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = ADEAF002D779FE80DA13FE31725E5FCA /* ASBatchContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 520EA1553E617D6F84D57E6EAC9B5636 /* ASPageTable.mm in Sources */ = {isa = PBXBuildFile; fileRef = EF4FFFABB7BE54C6BCBF9A61F17A6A98 /* ASPageTable.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 52F16FA44A76E4C5D48734B43A537E5C /* _ASTransitionContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5834B039278C6686064003CC4DF97395 /* _ASTransitionContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 553D516A845355E9AE7C6643C71D5C20 /* NSObject+AsociatedKeyForImageZoomControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E52B15796BB4A915D828880D8E9AA75 /* NSObject+AsociatedKeyForImageZoomControllers.swift */; }; - 55BFE808912342EEC873F1E2393786E1 /* Pods-Zoomy_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2ECAB2D10463A515B8622C35649FE2A5 /* Pods-Zoomy_Tests-dummy.m */; }; - 55DD95F28848F04D481771EC1EDC5BE3 /* ASStackUnpositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = D7BCDD0C9A3A1E746B9F1E99D158C91E /* ASStackUnpositionedLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 55FC8B0BB41DD8D17143B6983BAAB8E3 /* ASTextKitRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 6641DA3D150545A95436CF794C0CBE48 /* ASTextKitRenderer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5720B9A487E2CA3174F80DD0C547F608 /* ASRatioLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F6250F9BD3F49B51499B90504EE1D5C /* ASRatioLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 572D032B835BAB720EBFBA6A18908948 /* SpringAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CFD9BC7AF69EDB01B34D77788E7A4F /* SpringAnimator.swift */; }; - 5780A5A1818821D7645F46D8748C35AA /* ASImageContainerProtocolCategories.mm in Sources */ = {isa = PBXBuildFile; fileRef = C635F17EAEE4E59A1CE2F6202E5247EE /* ASImageContainerProtocolCategories.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 58753E1516397F4D04341782B8D6A9CB /* ASAbsoluteLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 041B4A598ADB602F7DCCBC8D326BBE3B /* ASAbsoluteLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 58965593EE5EAB075D49BC808361B2C1 /* PINRemoteImageCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 682AC42FFA98ABE6BB66417D133D425D /* PINRemoteImageCallbacks.m */; }; - 595C704E7A256F3C67296B5DA2903F5F /* PINWebPAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FF0F8D6BD0C7F366D8BCA8064C2636D /* PINWebPAnimatedImage.m */; }; - 5A8461D5F903DF711A276BE04577F79A /* ASCollectionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B678E30769470CE9F5F7EB95D5A260 /* ASCollectionElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5B6BD09559DC9FD1598F007FACFDDF4A /* ASLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B8A34FE38ED02DDC1550A4B16A33A3B /* ASLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5C364041B76A92A144283D38876524E9 /* ASStackLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 54E63B392FE4A4F0BA38E50DB0D4ECD5 /* ASStackLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5CB479B0FEE291255662867DE7FD8399 /* ASTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B303C567292DC11F1B0DAACE614A6AC /* ASTableView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5D0E890EC641AAFB45DFF527CF1C7137 /* PINCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B8B564BFF8B5501803B1A4631A19657 /* PINCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5D1565CA4B17BCB9FDDF642A8C002A4F /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 67F4D61E91F117DC2FA2C8092679E51A /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5D1948F6FC9E5CBD8CFB861BDF22FED3 /* NSData+ImageDetectors.m in Sources */ = {isa = PBXBuildFile; fileRef = 30A7CAD63165CA3F03F1EB41082C5271 /* NSData+ImageDetectors.m */; }; - 5D309A8ABE8407419521CEACEC94444E /* ASControlTargetAction.h in Headers */ = {isa = PBXBuildFile; fileRef = CAF24DC1C17849451322FD125AD2E70C /* ASControlTargetAction.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5D52196BA79E4B7319FDE3B3C945A1E7 /* ASPendingStateController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2640238F95E8A009DD6CFE7B65C34E9B /* ASPendingStateController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 5D982019D9EC96DFD1889874B1BA2500 /* ASCollectionFlowLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 67D1F9A6121EE2D97F3C6002FB464798 /* ASCollectionFlowLayoutDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 5DBA02868B801D2A716CF9CA8E92AE81 /* _ASAsyncTransactionGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B02FDCFBF0D352D4CCC5ACF96478DF5 /* _ASAsyncTransactionGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5DC3958D6527253CDDE5F8B2D00273B6 /* PINOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 069772F35BA6AC6B783EA915D5DABFC2 /* PINOperationQueue.m */; }; - 5F061989BF79A51FCBBA78724355A15E /* CGPoint+dominantDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF935CFCE349E367CFD3CFE312B4EFD /* CGPoint+dominantDirection.swift */; }; - 5F5D9D949369EB06621D08D716C5BE04 /* ASCenterLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 999ABCA7921CDF37F8B7B19411E1084D /* ASCenterLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5FA9B797FDB867D05726693E35AE0C35 /* PINRequestRetryStrategy.h in Headers */ = {isa = PBXBuildFile; fileRef = 31E8320921F753F72E16B6995A77EBF3 /* PINRequestRetryStrategy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6041607BC6CEC6D5727CD75BD44F0CE1 /* ASCollectionLayoutState+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = A98A5F46B2F5435F186701CCADD6D4CD /* ASCollectionLayoutState+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 60B2952345981538EAF69C458EB663FE /* _ASAsyncTransaction.mm in Sources */ = {isa = PBXBuildFile; fileRef = F77132454B2BB691E5070FA6A0E46957 /* _ASAsyncTransaction.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 60E8314B695F682FCF6706C3255FF541 /* ASCollectionLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 47BEA003F98AF411A6A7DF57679996D9 /* ASCollectionLayoutDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6166FF001AC0578634672DB77A6C693C /* PINSpeedRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = FA55D18353B91480033D3AC52439C4BF /* PINSpeedRecorder.m */; }; - 617A7C4C9D2B12CE7A2F34F71D69DA86 /* PINURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 15EF4E25B85DD21D7F9FDD4BF7B1AB46 /* PINURLSessionManager.m */; }; - 61818283679C6B38C94B9FB8B0AD55D6 /* AsyncDisplayKit+Tips.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46AB7C0E0E8242F41B205E4DBD3C10E3 /* AsyncDisplayKit+Tips.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 61C78F3D284DB41CBB280CBEC4AB47F4 /* ASDimensionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = F74E2E2EDB48C048F9F569CFC937193E /* ASDimensionInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 62F3B4506E471EA184D4CB38CFA626B2 /* ZoomyLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C587DED2BBD35B19E135E0E1AC63BC /* ZoomyLogger.swift */; }; - 6377CEF639BB89C5C48555D177F4F34D /* NSAttributedString+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4DE06937FCEE16FB4B9F13D19D95CF74 /* NSAttributedString+ASText.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 65E418C3F2B732069D641B3CAA82D3C5 /* ASTableNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 46F73ED5DBD4B0E2A039193D5663B7A5 /* ASTableNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 65F6D9099F2E3EDA63CC4FA2232374A5 /* ImageZoomControllerSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20F56D2D244CECF2FAD0815934D1751 /* ImageZoomControllerSettings.swift */; }; - 660F62E7D7AF5375CE4C1B230AE46A9A /* UIImage+Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 417957CD232E64384DA98C2BA8ED91D2 /* UIImage+Color.swift */; }; - 66597F792DE7AB95DA3BE159B891FA16 /* ASCollectionFlowLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4738C3EE9ADB91DAF08960FDEDE3D702 /* ASCollectionFlowLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 66AA299AFB2C6722FBFA8D31B8E7D980 /* ASLayerBackingTipProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = E8DDE817DC02BCD96ACFB1094843BFC0 /* ASLayerBackingTipProvider.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 66B67B26FAC73CCF9514B8C3468BF19D /* ASLayoutManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 77DB577F26D2B45960B5B6BFA0762A2E /* ASLayoutManager.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 66E9B6C804D7C61BA4314762F68ECB5B /* ASTextKitRenderer+TextChecking.mm in Sources */ = {isa = PBXBuildFile; fileRef = B88ACF20E41D2246608FEA823AC77B13 /* ASTextKitRenderer+TextChecking.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 68AF0FADD42ACAC71C4E009A0F8A8E45 /* ASCGImageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 97E41C83A55213B5CA3787B8C3A4CA01 /* ASCGImageBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 68F351CE7440322DC392C7236A6FE2E1 /* ASLayout+IGListKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D29A4225F3A3D743A92285D5F23D9CEA /* ASLayout+IGListKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 69E72A894605CAF7EF193A72D998F405 /* ASOverlayLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 02E082F190CD64742376FA1DCF16D316 /* ASOverlayLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6AA9E27C2D6FEF10A9C0C6F1EE05A171 /* ASTipNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FE37FFD7EF2429C10029089C508EBC /* ASTipNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6B593EFF0D07AB7A2869146C13130987 /* CGPoint+valueInDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7433465CCEDABF6373CF6FC715F02577 /* CGPoint+valueInDirection.swift */; }; - 6B7F558A8833FBC4915598ED230F8A48 /* ASTextKitRenderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D13214627B0CA8A7BE823B9652281FB /* ASTextKitRenderer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 6C45BAC40C71D9DAB390C432E290917B /* PINRemoteImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = EBEA00E447337E1023D98C0AC23E2C42 /* PINRemoteImage-dummy.m */; }; - 6D05E87535103228054BD3C4EF5B3A2C /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 76D2AC89B328615BB7546EA1E9E047D5 /* ASButtonNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 6D6B4B4263CD5E493A3CDC6871E5C71F /* _ASCollectionGalleryLayoutInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = D48173B3E33DB97A878FAA3E003BCE42 /* _ASCollectionGalleryLayoutInfo.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 6DF19AC2B068CB4D76C669934D5DA485 /* ASPendingStateController.h in Headers */ = {isa = PBXBuildFile; fileRef = 7541B18A6C986C3B141071F12EC8AA87 /* ASPendingStateController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6E4633B4A34D4DC1FA0D5CBAEB4220A8 /* ASScrollNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = C065EA4E96480B78158007EA06DE3DA7 /* ASScrollNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 6E469EDA3A2AAB5BBE24305DA7F1248D /* PINResume.m in Sources */ = {isa = PBXBuildFile; fileRef = EAC8AE04C6D624912867C7AF28B45A3F /* PINResume.m */; }; - 6E5F58395286B921136BD6E9895978D3 /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = E9297A4D9C730E526E63A5654A200E28 /* ASBatchFetching.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 6EC39DA7EF570831DDD7333E862B683F /* ASTableLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = C34BD2D317CCDC7344BEA22900C93E20 /* ASTableLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6F38B3364F5E8E7CFAE3F75665C6680A /* ASTextKitComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = BE5BE38429E1421B25B26E3F778B6388 /* ASTextKitComponents.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6F6E88826C13843A8DC1B91ACAE2F01F /* ASDisplayNode+Layout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3BF2212F3A7D876C37A5DD2521386AF8 /* ASDisplayNode+Layout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 6F98B53F8BD238D23C4FB3A1A984E831 /* ASTextNodeCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 2566ED78C35450BA5FD2005C76B64425 /* ASTextNodeCommon.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 70981CA6A1DD10570E34DB778400D44E /* Logger.FormatSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06A281B1005F95408C915408AFB29679 /* Logger.FormatSettings.swift */; }; - 7263DE605516B38C4FA0F16E3FD4D981 /* ASVideoPlayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 64C1E527A330B58A62D7FBCC27451933 /* ASVideoPlayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 72A60D282E9C26F5EF2C0AB2908818C1 /* ASTableLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = D43741DA796D220E39698D245C0C7FD0 /* ASTableLayoutController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 72D59D32A599A93C75D4FDAB7DC9737B /* ASYogaUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2B07470A9306150D188132273127CF31 /* ASYogaUtilities.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 72F6F0CC202391378422014A75933647 /* ASDisplayNodeExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = B73C16ED725233597781AD592DEAE342 /* ASDisplayNodeExtras.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 75B6AB3A7B5AF53467B25C45DF3B96C4 /* _ASCoreAnimationExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3728B36A01891C41B0E5AAC664EC09FE /* _ASCoreAnimationExtras.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 75CF1C3C6791888DDF1C73573D7D5509 /* SimpleLogger.Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCADF277F8E0FE040B220E44C2285265 /* SimpleLogger.Settings.swift */; }; - 75EA6D8C949888CECFDE996ACBCC7E1C /* PINOperationTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = D66AD00BCB9A19991B9EE09548F16733 /* PINOperationTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 76486E3D71D10617BF6F2AE87460B3CA /* ASLayout+IGListKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE1FE096C913D8F624564FE170A0B4B1 /* ASLayout+IGListKit.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 76769BF5A866CADF8435A5C3398B69BC /* PINImage+ScaledImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A26326A1EC4D60A6D350C454C89D29D /* PINImage+ScaledImage.m */; }; - 76D6E43BB3212A93FE99A96B8FC61A54 /* ASCollectionElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = C77B159A3B34D6119258725CE283719C /* ASCollectionElement.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 77B4529FD12983A4B2E36A8B27A7FA69 /* ASTextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1029CE67DEA0959BCCAA7D9F534FEC84 /* ASTextInput.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 77B666155C44BA2A2F1C2A5850970505 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - 7845B815BDBA490E7BE225C43E9AD527 /* IGListAdapter+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = BD47532762609FE8FD8106735ABFB4FB /* IGListAdapter+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7938644E140C00A37AEE202C0D91E0F2 /* ASLayoutTransition.mm in Sources */ = {isa = PBXBuildFile; fileRef = B5D733DA59C42F85C9420CC9D53FD100 /* ASLayoutTransition.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 798E0F169582BD5816A770931B6BFBC6 /* ASTextLine.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6168D2B373231D675211F9910C528C7 /* ASTextLine.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 799110AB6B3B61159954AD7212E849B6 /* ASCGImageBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = B34887E975D5A8E86DCAEB7D3EC54B38 /* ASCGImageBuffer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 79CBD53F1BA8489870E7D07145984BEC /* ASDisplayNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAF9BF2152AEE816BD4063566927C2C7 /* ASDisplayNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 7A8F02BCDCA7BED9E86546B9B8D10C9B /* ASGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DE74719B84443664ED5311A61911759A /* ASGraphicsContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7AA2F6576E76A4BFA98EB7CAC8B544EA /* PINProgressiveImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 90D1F9DA550B0E716C6CB4EF9EA9DAE5 /* PINProgressiveImage.m */; }; - 7AD6ADCCC8C353495C934B8A5283D300 /* _ASCollectionViewCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = E8EE8E285A79E86E91454D38BAA31F49 /* _ASCollectionViewCell.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 7B238AA4B05D561D86DE8F678AEE6FC6 /* ASAbsoluteLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 6471DAF51E7A7C9B6CA4B243EA9D399E /* ASAbsoluteLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7B40EFBACF7283D118A018C64DB5D334 /* PINAlternateRepresentationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = E3B0B3833F78F5202AE6A4EDAACABE40 /* PINAlternateRepresentationProvider.m */; }; - 7B57B12F9FEE2321D4984D5E697DB396 /* _ASCoreAnimationExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = CA6C4621E433A72E826090B170427229 /* _ASCoreAnimationExtras.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7C27E5F68E9EB61979B1E88841500324 /* ASCollectionView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DA44FE89D4C0FCD5F37208DB3FA170E /* ASCollectionView+Undeprecated.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7CC5C2375A5EC03117CA2CA5B9C5F76D /* ASLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 004EEF67B238D8D591FAA3567F4B1D67 /* ASLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 7D209077CBCD22897C437A088B0F716A /* ASDimension.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0B739A419D028F8BC409ADB9AD9CA527 /* ASDimension.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 7DB2B68B4C0E8B6D2D778243D7942375 /* ASStackPositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07729A9F499A036868ED6B53393E7A5C /* ASStackPositionedLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 7DFC26E0B67DF88BBBE9AC332F6B8DF5 /* ASStackLayoutSpecUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A522E2430B709898EF722555E8A4DDB /* ASStackLayoutSpecUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7EAC704B0234A558A7C1651A2A48F970 /* ASBlockTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A492A5EDB688BCE2C833245EA50EE8 /* ASBlockTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7F87B587FCD817B1468A6D518458999E /* Zoomy-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E68C5787A7BC6FABD14F34D978338E /* Zoomy-dummy.m */; }; - 7FCBE3CFACCF27A81091AC9F96E7A026 /* ASCollectionViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B8177727C674D026E37566A26B57945 /* ASCollectionViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 800B28591DEE42878E61A0CE4479B452 /* ASTextKitContext.h in Headers */ = {isa = PBXBuildFile; fileRef = C1B5279955DCE765725B542C20DC2C37 /* ASTextKitContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 802BB286EA6040319B686BCA471CBE2D /* ASLayoutElementStylePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 675E0F7FDD409F8A77A5C35C201C300D /* ASLayoutElementStylePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 81166544D68BCBBB67F86AAB363EA440 /* AsyncDisplayKit+Debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D768DA83B418CA0C1CC710850566A92 /* AsyncDisplayKit+Debug.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 81D8CB5489749AD323DCC8FF7B5DA738 /* ASTextKitTruncating.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E7536DF5C436E513BCB94280E7CFD70 /* ASTextKitTruncating.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 82E1F9883A68CC966B271D7AA1914358 /* Texture-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6B00F5DCBD9D92902113D39B1EE973 /* Texture-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 82FAA5D094671D3E80C780F797E706E9 /* ASTextAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = D13C42FAFFDAA633F5D53CA57A8C1683 /* ASTextAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 82FF8E0FA9C51316D0724EF1CC430FCF /* PINCache+PINRemoteImageCaching.m in Sources */ = {isa = PBXBuildFile; fileRef = A038B802D8F0C0EC85498DA10C1EC1F5 /* PINCache+PINRemoteImageCaching.m */; }; - 83008984A17DE638809E3C6791924A01 /* ASImageNode+CGExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 75F5EC2D6BBD57314094328D47EFA189 /* ASImageNode+CGExtras.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 836F172786359578E36859CC821D68A1 /* UIViewController+CanManageZoomBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7B857F48C145A0BB64AE203A20EAEA /* UIViewController+CanManageZoomBehavior.swift */; }; - 8370E1B3198D380C3BFE9CA9F112F34C /* ASTipsWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBCF740EBE5DE3C173D4E8439D0DFF36 /* ASTipsWindow.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 83BD8B38847B9C96FBA4418A4C6F394F /* CanManageZoomBehaviors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C6AC42AE8AC5B546767B472AC3D4143 /* CanManageZoomBehaviors.swift */; }; - 84F093402374686E873B5F8F4F1603E5 /* ASObjectDescriptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 836EA6D72B4490C73AF0C525C6876D37 /* ASObjectDescriptionHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8663349419F69078AD6A1478F4BCF3CE /* PINCache+PINRemoteImageCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = B763F6804A576872367A393D9228CA2E /* PINCache+PINRemoteImageCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8705C173FB3E22334E41089FCD1D6338 /* PINRemoteImage.h in Headers */ = {isa = PBXBuildFile; fileRef = A396339D2FC678CBF9BBF4141C6E3AED /* PINRemoteImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8875D45F4D5B2ACA819F1C5BD2B64E35 /* CanLogAtLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18EF9DB92D4E1F229060F5B5B0DDF41E /* CanLogAtLevel.swift */; }; - 8883D817E3D5C322CD723CADF2B0589D /* PINMemMapAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 18516CDF6334CB04ECD67DD6C9994D10 /* PINMemMapAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 88DEFDC0E299F801BC7656503D7264E2 /* ASTraceEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 023744D1EB94358EFF5B46ED666E1A78 /* ASTraceEvent.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 892242FD73E991B08D538460AEECC49B /* ASWeakSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = 739717630BB5AE208463BF141B4995DA /* ASWeakSet.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 89D81BC4E48F24D79618C79FC465EB02 /* AsyncDisplayKit+Tips.h in Headers */ = {isa = PBXBuildFile; fileRef = A7DB14A5844AB9D9843C0B181E42BE46 /* AsyncDisplayKit+Tips.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 89FCE49736568D9D968ACBA85F4E8FE1 /* ASDisplayNode+Convenience.h in Headers */ = {isa = PBXBuildFile; fileRef = CEFCD08353CEB062A616617D7CB0E38D /* ASDisplayNode+Convenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8A0627E70FCA5146143FC7BEC7C39309 /* DefaultAnimators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE0C290967EDFE3B12512326F5BFD16 /* DefaultAnimators.swift */; }; - 8A246297882AF4DC93926DC6E8C21371 /* ASBatchFetching.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1FBE0A2E9ED2D152CC1D9833F6C7A9C6 /* ASBatchFetching.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 8A286D7016BB48224320C686C39D2224 /* CanPerformAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05EBA3BEF494A23D32FC5023A4303A8F /* CanPerformAction.swift */; }; - 8C18DF4B9574971AA7D619FBB11B6C64 /* CGAffineTransform+transformWithScaleTranslationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC547208CC428C4630ADEBFBA2A2BDAD /* CGAffineTransform+transformWithScaleTranslationCenter.swift */; }; - 8C1C4738C8EDA4CC19C0E3DEB0AC6DB5 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 42ADB8EFEEAEEBFE11A460E7A0B67630 /* ASEqualityHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8C320C32AB123F86A86770E7E82E4043 /* ASCollectionGalleryLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = EB5705798083744EEEEB7CE058B58C09 /* ASCollectionGalleryLayoutDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 8C3FFBD6AF1E1EE9E8B2638A90E65636 /* ASAbstractLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 162A36187E75CC621EFD3DAA504D4BA1 /* ASAbstractLayoutController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 8C846B6A703E78ED3479D656EE086558 /* ASDisplayNode+DebugTiming.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F0AFD63DC30E3247C4918C6BEA9A0AE /* ASDisplayNode+DebugTiming.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 8C97E12E8495FCF40CFFAE2D8D49AA26 /* NSData+ImageDetectors.h in Headers */ = {isa = PBXBuildFile; fileRef = C479D571D3825B10ECABE5FE1938450E /* NSData+ImageDetectors.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8CC8BAD4EE5B282E015D339880FD4CED /* CanLogMessageAtLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CDAA8013007AE7BA76340E480145741 /* CanLogMessageAtLevel.swift */; }; - 8CCD7C47780AEB7679C85CEE040DFD38 /* ASCellNode+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B2C8E75862CFCA96FB97B2D340B2600 /* ASCellNode+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8CD5FC51F562381181973EDBA13A4133 /* ASVisibilityProtocols.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B2B7A0F27A1B1C961C4EA3C16175B81 /* ASVisibilityProtocols.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 8CE679AB1CE25AD3CB3BE134A206DB26 /* ASCollectionLayoutContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 34264FCFBCD166A0BE6E3B41DBF13876 /* ASCollectionLayoutContext+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 8D266BD043026CFD80471BC9149FF30E /* ASMainThreadDeallocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 44265DBCB67F313E59BFA3FCE8D51190 /* ASMainThreadDeallocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8D9FD022C6378039CE5ABDC733C96157 /* ASTableViewInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 36B6B10464BF4A4C825532E2CC503B37 /* ASTableViewInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8DCCACCBADEC4FFCAE7F8CFA17843F6F /* ASTableNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4AEA21345119E8A9D19E256F0B3EA1C0 /* ASTableNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 8E6B862A8628615589A2419BA04372A7 /* ASElementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0D5AA6B6BFFB0F4BA2616154920180D8 /* ASElementMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 8F9E256B8EABE696443FC7ABFE7631D7 /* ASThread.h in Headers */ = {isa = PBXBuildFile; fileRef = B25D491B0A31A845AF0339A0BEA95052 /* ASThread.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 902BAA1256D27B4392C7348AFB5E562E /* ASImageNode+tvOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF54AE29F0904364F8BAB4731C2B61F5 /* ASImageNode+tvOS.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 90F4FA9213433356D089C0DF1F71F12E /* _ASCollectionViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = B42F164AEA1DD630EF5DB88F3E6546A1 /* _ASCollectionViewCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 912D70FE36FF86469754897249570AFF /* ASTextNodeWordKerner.h in Headers */ = {isa = PBXBuildFile; fileRef = 833117E1C1902A1A1262B53ADA674BD0 /* ASTextNodeWordKerner.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9132BC4491E756E7A4233BAB58C923B7 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 383761BD6584FEC55E5C246F77B1B93A /* Accelerate.framework */; }; - 91EFE7EF1EC22F6738D99690A572D007 /* ASCollectionLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C8C5E2FFC7D7BAB935A72ACA952F4B7 /* ASCollectionLayoutContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 91FBB18FC6B78968CD3790576B1D791C /* UIResponder+AsyncDisplayKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4AD6A102FE402E0C21F9D0C9B94E7115 /* UIResponder+AsyncDisplayKit.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 92710081F9E7141F2E165E6A5CD30818 /* ASCellNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9534DB6C12F7A203D038C860278C69B2 /* ASCellNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 927F14D8D5513C8096D98B5A6ACFFA7B /* ASTextKitCoreTextAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = FDA847AF8B056A3AC9A65250377F027C /* ASTextKitCoreTextAdditions.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 93A2714B5C617D45BA9E4D8460B29357 /* ASCollectionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EE6623F7681F2A64EA741D31CCF2563 /* ASCollectionNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 945CECD5F856F8152BC44D08FE852CCF /* NSMutableAttributedString+TextKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 286CD9D4C899902427554B69AEB67772 /* NSMutableAttributedString+TextKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 94E4C0B68327D60B4DF469FEB4CA440A /* ASRatioLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = E3B9A8B07F628C3AF0B0565D94907370 /* ASRatioLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 95B3312084D6FC4F8156EA5103367891 /* ASSupplementaryNodeSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E372AA815D2A151D2CBA8ACF92FC280 /* ASSupplementaryNodeSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 95D84CF91CAA6D321C2648DD47068800 /* ASBasicImageDownloaderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 02074016ADB05CBAFE0127B2661EB0AC /* ASBasicImageDownloaderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 96C54E25711BFD7A16443DE074CCF6A6 /* ASDisplayNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 4376ADF353DC2577C335D8807B54245F /* ASDisplayNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 970512FB1DD0042DDD5D9DFA7C75B74C /* _ASTransitionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C0888B5BCFB99062C58EB43E8AD7554 /* _ASTransitionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9717C51CEB89E213E78999453DC842BD /* ASElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FEC161E352AF6BAEC084E513C5C48D /* ASElementMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 97685CD14F9FC6EC714BF57A8285B3DC /* ASSection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CCAD733BD22B89DD6EDFD49B0683A7D /* ASSection.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 980BF8E99DA73B6A3668CF91ECA47EDF /* ASOverlayLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 784EF6F897319AE9C0047B80A777FE72 /* ASOverlayLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 983AED1C4422A62162CF7C8BD8C68EC4 /* PINRemoteImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 28253AD44028A9D310E9A7C4E2F34231 /* PINRemoteImageManager.m */; }; - 98AA250E903BA51AD650001A279AE9DA /* PINRemoteImageTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 538A265EC6AEC4BBC85EC2796FB9D3BE /* PINRemoteImageTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 992ABABCE0CD2DA9F69174880AA167E2 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95722285F0E34655A8452709EE3B6E55 /* AVFoundation.framework */; }; - 9A2F048A751AB4B164480B5DB8BFAE5A /* PINOperation-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AB585F9D4AB7A266D774F3A142704648 /* PINOperation-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9ACCEA9EC6A16D4B1FF719E2ED3895ED /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - 9B2EE65ED8B007D4C344FEC6F768C9B4 /* ASTipProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 947A438B776425860B7954368A814273 /* ASTipProvider.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 9BF312C74933239A9980BCC85427F4D1 /* PINRemoteImageMemoryContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB779A3A6B164BAAA0959C229254646 /* PINRemoteImageMemoryContainer.m */; }; - 9C2BB387083631012EB5C1EC1F8EE729 /* PINCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = DB46CE9E8985343894F642F0878128C5 /* PINCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9C60DBF2ABB6A7BCB9E90131D77D1DD5 /* PINRemoteImageBasicCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 640CE1206037C85BD667C306F05F33BB /* PINRemoteImageBasicCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9CC2B88E26F683FE73C473A17936AB65 /* ASLayerBackingTipProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = EFB4F1B82C208BE59AA0898C1479B48F /* ASLayerBackingTipProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9D0817112AF21F39E12B9728BD57C178 /* PINImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 164865052A57263BCC5A5D2DD47E2FE9 /* PINImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D5AED0578E631788B8D9895C1B949E4 /* ASLayoutSpec+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DA500C380D603BFBE1C536274B05AAC /* ASLayoutSpec+Subclasses.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D62D32EB5AE2F7884B5E616F40FA296 /* ASEventLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BB3F630C68C3A5DFB13F24E7FCAD25A /* ASEventLog.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D92116AFE6C294869B1C2FFB0F9961B /* ASWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A62DAA92B3EEF14B2EBFA714FFF6B6D7 /* ASWeakMap.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9DB1B4681E1BD5B5180D5F5A74EAC1A7 /* ASCollectionNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = E13F304F25BDA4F5138C786C6D8541C3 /* ASCollectionNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9EA768EAC7DD105D55C6E0ADE5C11A44 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 23695E05ACF79219EBCDE5C2958F0D74 /* ASDispatch.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9EB5736C9607BD9049A4133F20594F65 /* ASScrollDirection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8EE240ED270F427A2A20035145E4E12D /* ASScrollDirection.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - 9F970FCFAD7D3A9D6E6C8DD64D8BE519 /* ASTextLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9981AC172C1B313D4AFDF736B83E76DD /* ASTextLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 9FFC4ED0B295E09FAF76E7892F457C62 /* _ASDisplayView.mm in Sources */ = {isa = PBXBuildFile; fileRef = EFBD7E465FF5839A50DEEEE7A6A8AEE3 /* _ASDisplayView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - A033E8E58BF2B79C8DEFE5D940E041F5 /* ASDisplayNode+LayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CFB3A1E5D6B29DCDD26302D3E775DC1 /* ASDisplayNode+LayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A12A3B1598439F5E521304D01DD71980 /* ASNetworkImageNode.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E479AD6CC4807738F653AF75B351CB /* ASNetworkImageNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A1387BF912438142526E1346D8ED55A8 /* ASCellNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FF0E128FF2A7195FA58FADEB2B67B78 /* ASCellNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A16C3DA62CC6E9362A34AB89F8981591 /* ASTextKitTailTruncater.mm in Sources */ = {isa = PBXBuildFile; fileRef = F33ACD58C957BAAC992E6CFFB0F23696 /* ASTextKitTailTruncater.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - A17158F8FEBD7F5199C031A6BE661B41 /* ASImageNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 58F66FB0AEB4E161B98EEC0563AAAA83 /* ASImageNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - A2A08FD631849349183CE1B5B2A0B1FF /* TypeAliasses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F0BD0EDE0ED2F616D20EF4F8324DBE4 /* TypeAliasses.swift */; }; - A2CE68BDBED902622AF5A34FDDF7FF78 /* ASTextNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 11C0D27698278E492EDF141A99066C51 /* ASTextNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A3DCB42D23A31F02C36CD9FB4AD19186 /* ASCollections.h in Headers */ = {isa = PBXBuildFile; fileRef = 8612405434DF8846A00ADCFE8E364394 /* ASCollections.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A43975A29E7120EAD986F334818BB97F /* ASDefaultPlayButton.h in Headers */ = {isa = PBXBuildFile; fileRef = CC192131041D44BC2AB4EA73128B108E /* ASDefaultPlayButton.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A48232B6EDFE017E0E343845B96EDDDB /* AsyncDisplayKit+IGListKitMethods.mm in Sources */ = {isa = PBXBuildFile; fileRef = B8965C6AC7D32CBE8AB47BD3DD1AA7D1 /* AsyncDisplayKit+IGListKitMethods.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - A4B3C475BEB8068C0B51A528C7C4F949 /* AsyncDisplayKit+IGListKitMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = CB5EA34046D5FB220392F961B785A319 /* AsyncDisplayKit+IGListKitMethods.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A4C3B774A642CA7364A1DFB058721A68 /* _ASAsyncTransactionGroup.mm in Sources */ = {isa = PBXBuildFile; fileRef = 79619D75C2722640361977842EF8C593 /* _ASAsyncTransactionGroup.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - A4D739A03F6C168A7A30A212D7560C68 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1C23264DA61204A0B428A18A76C774A /* ImageIO.framework */; }; - A4DBE34A6E4132DCE5CAE57D60456641 /* ImageZoomControllerIsNotPresentingOverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CFAF1E8969912E3093CDAE51ABFB670 /* ImageZoomControllerIsNotPresentingOverlayState.swift */; }; - A5B267BEACDBCAEF2D1908F170D38A68 /* PINOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = C4000565ABB42B463A834CB1F2577D74 /* PINOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A5F9BA06922BEC0C77A87D10E3369359 /* ASLocking.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D45CA8A0CD161A2FD16B69E7A3F23C4 /* ASLocking.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A6CE791214EA7B272BDBD2A8FB34CD56 /* ASMutableAttributedStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2586BBD79ACE8F25C2855963C00306 /* ASMutableAttributedStringBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7B0A20917692E0E5AF687E882D1D042 /* PINRemoteImageManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 75B8ACE26E3AB8DC3A77EAF33F43FB07 /* PINRemoteImageManagerResult.m */; }; - A90DD763EC5DCE3CCC51D4B4D817FF0B /* ASRelativeLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 31C3C3A510E1FC44FB2F8FBE5BD8C95F /* ASRelativeLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - A9F53C282E93B0FB9FBEEE518FD295EF /* ASTraceEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B02A8C5EF0BFB03017CAE2C8D4303F /* ASTraceEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA5B44790F97B6CDA6F650E1028456EB /* ASDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = CF0DDADC13D1CF8AB42051D93B8555C1 /* ASDataController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AAAE1A514D5EF921A3B3F2DF7FFEA117 /* ASWeakProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = ECE0D92D4EC523A9855D1F722186A1E5 /* ASWeakProxy.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - AADB3FB272AF788B501CA83C13A04256 /* ASLayoutElementExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C3E8E8DF87C3112F7930C4F95399416 /* ASLayoutElementExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AB8430F07EEF189ACB7237DC3ADF73C8 /* CanBetriggered.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B2040AC217069203B2EA5F3FF24FE3C /* CanBetriggered.swift */; }; - AB8598927B43148CE5839F78DF6019B3 /* ASPagerNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 5960F0BD04B70C94B98548918A2C94EA /* ASPagerNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - ABC2CC3E9F276C53711D53CD969E5E1A /* ASWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = D62BAA7299811C6007375660954B85C9 /* ASWeakProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - ABD2F42F5CA66A0DF0CB77FD77ECE5FF /* ASControlNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 73DC94ADF25673F66DD319923A0E77FD /* ASControlNode+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AC24A47998913E653B537670122C8776 /* PINProgressiveImage.h in Headers */ = {isa = PBXBuildFile; fileRef = A70EC583D74B1259AF4D563FB225D45C /* PINProgressiveImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - ACD14DC8F6B89D7AD9E4047D89D7D5DE /* ASTwoDimensionalArrayUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE71255C1FCB63798369B1B61543897 /* ASTwoDimensionalArrayUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; - ACF8783CAC2A000FD0C6466582F4181B /* ASTextKitContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6972254463A4E42E119C4C796390CFF9 /* ASTextKitContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - AD229AEA4A55B61BFAD9F9520B4AA43E /* LogLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF0FE47D3163C04184775EB308246232 /* LogLevel.swift */; }; - AD4C26854C3F360B75A93F838BABA6AF /* ASDisplayNodeCornerLayerDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = AF8951F6130635C32B10D41798AA0F40 /* ASDisplayNodeCornerLayerDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - AE1391BE88B7BC0556E20AFB8A2E151F /* ASCollectionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4787675C54E05A8E87785A4179A5048 /* ASCollectionInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AF58796BAFCDA0138554EF6F8C388EA7 /* ASCollectionLayoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 9698D9EA7BD19EB23AB3EAB57A993843 /* ASCollectionLayoutState.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B0584D12CE37583826F48C67E9F319C4 /* Side.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFD881480973960CF3694AFEA4B9513A /* Side.swift */; }; - B078D55EE106C5BFF41BFFDE043A00C0 /* PINRemoteImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FB6F534B1401FE906AEF92CCF6A339D /* PINRemoteImage.framework */; }; - B0C54A106E41470E67AE2D2581DE4D27 /* ASViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3622A7B1520B6EA76FA4B4AFEA470CE0 /* ASViewController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B11A06E34C796B6318E52F991C3A3FE8 /* PINRemoteImageDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FE9A85EBB7C7832A0718380B6834F01 /* PINRemoteImageDownloadTask.m */; }; - B15A3220207A7B9906FAC195E58C28A5 /* ASSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3606305E249E94F9CB41FE90831B0107 /* ASSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B1EAE30D3FCDFED9AD5D90D251EA0A34 /* AnimationEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C90099C4B69F62EA096A7F273C971 /* AnimationEvent.swift */; }; - B2FF0B3F9E98DB9D32AC6F1FB4AF5973 /* _ASCollectionReusableView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5249F6990C1876E77A173D504374E85A /* _ASCollectionReusableView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B314498ED96D2F0129A1A368118CD09C /* ASRangeController.mm in Sources */ = {isa = PBXBuildFile; fileRef = D2C7409FD631FBD85594A03B3F0C598D /* ASRangeController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B318E6FB4194F6FE456852556DF10B32 /* ASCollectionGalleryLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A32221AE94CD1425D9F2E1F183BBC001 /* ASCollectionGalleryLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B31BEFBD1D6436910AE45F3F52856703 /* ImageZoomControllerSettings+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D982B7DE0FA01AF1D3A98523B0AD71B /* ImageZoomControllerSettings+Equatable.swift */; }; - B363D99E3B2358D13561DFAA81BD9573 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 70D4BAD9DE5E975D5E04B308B0B3BE07 /* ASMainSerialQueue.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B3D52B59EC16AFE4E5C3EF3AD2F4606F /* PINCache-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CFEB1F047D58C0F0393C41C23A4A4F88 /* PINCache-dummy.m */; }; - B3D909D651548CA9F2796677F470DD13 /* Zoomable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C830822319FA08CBD72F6C6A234F64F /* Zoomable.swift */; }; - B3EC6CC66DCD0E7C779CCE05A52FCA16 /* ASEditableTextNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 443574802076FB68086CBFC32F215FC9 /* ASEditableTextNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B3EF3DC901FEA39B0E0C790BC28A8A6D /* ASHashing.mm in Sources */ = {isa = PBXBuildFile; fileRef = B2F4A9B3C994EF9CD4EE8D995926F08B /* ASHashing.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B495074A8740E49AEA57A4C35888D585 /* ImageZoomControllerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27C5BA4CCAE91E983D7C8C9D067168C9 /* ImageZoomControllerState.swift */; }; - B4D223471AAEA86D04DB96D70D2F2466 /* PINRemoteImageTask.m in Sources */ = {isa = PBXBuildFile; fileRef = BF28046FF0FAA13D619A64DAA2D048C1 /* PINRemoteImageTask.m */; }; - B4DA513CE3CDFB3203AE2B5598D59137 /* ASObjectDescriptionHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = FF34E71B804FA873D12D62187CBBB9BC /* ASObjectDescriptionHelpers.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B5332B7972E79B05B5E0EE2DDD0935DE /* ASVideoNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 64BF78B27F9F9D6D702EEDC1DDB09901 /* ASVideoNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B556BFF1FE33E6C7E520CD0441F86555 /* ASNetworkImageLoadInfo+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D038D5D65D25E6B9A55A199B3C5E4C72 /* ASNetworkImageLoadInfo+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B62ABD16DB7DF5FE2F5E1B40E523CFDA /* ASStackLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = D98D4102DE5D0527079F24439B32B5AE /* ASStackLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B62DD4DFA44285E33BE86A99104E7CFA /* ASTextKitTailTruncater.h in Headers */ = {isa = PBXBuildFile; fileRef = DF5B20F75E416F1C307A219C5A41109B /* ASTextKitTailTruncater.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B657E5107351084226E67342A4616E78 /* ASTextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = DD90D4DE2B4C773B25DE461741FCE6BE /* ASTextInput.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B70DC15A7BF4D41B8A2DA1C20C646285 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 31959479D3789CFC54BD384F0D0E20A0 /* CoreMedia.framework */; }; - B7192267427214D14ED60D794277A00F /* PINRemoteImageCallbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = AD44715CD9D5542D3941D58B4A413098 /* PINRemoteImageCallbacks.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B7E91ABE499B6733517D33FE1E4C1502 /* AsyncDisplayKit+Debug.mm in Sources */ = {isa = PBXBuildFile; fileRef = FD0555E6007F93E7AB71B7AC7A643894 /* AsyncDisplayKit+Debug.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B86DF2CD8EDE86C19772343D0B2945FE /* _ASAsyncTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = D23FE5069CB05E377F270A620883B989 /* _ASAsyncTransaction.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B8C0C60FA8A8D1523B5E966079559F1F /* ASLayoutTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0678905DA353A09C60572A337DEF943B /* ASLayoutTransition.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B91877FE183B4921AC6F3DD06246EBA7 /* ASDisplayNode+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 007B9E9F13C247C344FE3DC65E2AB901 /* ASDisplayNode+Subclasses.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B94E437AD7533B455340EE6D9A4B6463 /* ASCollections.mm in Sources */ = {isa = PBXBuildFile; fileRef = A38C44A24E481D727A9C07A5CA684514 /* ASCollections.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - B9F5A92FBE728D489778375486C724F1 /* PINAlternateRepresentationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD6A1C78C243ABC82E24C0705F1F667 /* PINAlternateRepresentationProvider.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BA991D5B0D15C90393E182370ED3F7E3 /* NSIndexSet+ASHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = F10A7F445C73E4B81EB75D2B1FAC1888 /* NSIndexSet+ASHelpers.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - BABCA75A40E66297E498280E1D393E26 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 10CD2F8A82E752D0F5290FF3DBFC0BE6 /* AssetsLibrary.framework */; }; - BABF973B5B192D51D6C4F7456103BE75 /* ASDisplayNode+DebugTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = A184C7A5B0B71E080B56514AB7E8A425 /* ASDisplayNode+DebugTiming.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BB5681D14586A11A9AD8EB98441AF89C /* PINAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = DA268B7E44D38BCD77321FABC32B31D0 /* PINAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BBB7FB02F6F6557968A0F8B614A3F917 /* ASTextDebugOption.mm in Sources */ = {isa = PBXBuildFile; fileRef = 66025E37962CFCFF58E31BD4B8B8AE1F /* ASTextDebugOption.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - BCAC5BA9D845AB51148932B5EB3A5C4E /* logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1BC0617843927EBC5E65D973264D1FC /* logger.swift */; }; - BCAEECEBCD2631F3331DABAA79A5EF45 /* ASStackUnpositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3CFDC315D163384B2F7024695124BD /* ASStackUnpositionedLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BCB657CBC4EF85FDD1F4F441C82D2A1D /* PINMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B8FC2C1E24D7F7723065F7C02EDB1715 /* PINMemoryCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BCB68BB3E16B87F0C927313DC119424E /* ASNodeController+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = BAC3EE3B34E6F03D24161D8B69B10D48 /* ASNodeController+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BCE1BD0B7DCCEC19DB489FD3BB67EE62 /* ASRecursiveUnfairLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C7A16ABC9185C93FB35F8D1A38EE48 /* ASRecursiveUnfairLock.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BD71AB07F2DAD99A050F4B20FCA710F4 /* ASSignpost.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6960CA476D12BC3E1596C094F2BFAD /* ASSignpost.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BDB2A5F0E63D0488D81945B048C8E6B8 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751A5BF60BC5A9847C0C9673E8CF01D8 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift */; }; - BDCA468F44DD0877EBE9ED4A2FBDD578 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - BDCEA7D86EF5EAA1D0132FA11A8C7679 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD60A2E7EE5CFF2D707B5995C946BC1 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BE0308C81B8EB5C5854C50AFE4EC5F05 /* NSAttributedString+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = DB05D8F15693818ED24FF6BAF2F27166 /* NSAttributedString+ASText.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BE343ADDB5FC9F09B811B65C34577B96 /* PINRemoteImageMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = FA02D2C56C599E247CA011F6D621AA3A /* PINRemoteImageMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BE59001D9DB09B6CD705182FDAD54849 /* ASCollectionViewLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 264EC3CABA35458466AEC4B4DACC46AA /* ASCollectionViewLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BF479ECC5281CC06975C21B7E4B2689B /* ASSection.h in Headers */ = {isa = PBXBuildFile; fileRef = E8154B80F3BF383F5EB574E1497B614C /* ASSection.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BF7A2BE0EDC947CA0B96A79A0E8A85B0 /* ASTextKitAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 18777AD77F0E97539ACAD1F9141F38DA /* ASTextKitAttributes.h */; settings = {ATTRIBUTES = (Project, ); }; }; - BFBF2B9AE08BE7EE2104716D4DAEBEAB /* ASImageNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7135BADF9C0B4425CC0C0126CB809820 /* ASImageNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C0086BD4E33E2BA653D4017DE6496C75 /* ASTraitCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = E1B40F69DFD16A71ACDCF95E5D218731 /* ASTraitCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C00B0DE199AEFE459F4BA1046560AAC5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2D9B780803CCE87983E460EF683910E /* UIKit.framework */; }; - C00C342DC14DCF42B6BA31F3A62611E6 /* PINImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 59FBECE43ADC1822C1BFB2AF4CC30D0B /* PINImage+WebP.m */; }; - C0A756D0CF5C0FA0BC67C0913192242D /* ASDisplayNode+AsyncDisplay.mm in Sources */ = {isa = PBXBuildFile; fileRef = FC678FBD26515FC0EEA585EC6DE85663 /* ASDisplayNode+AsyncDisplay.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - C11E6D5E0CB6B45942374FC4161D0EFB /* ASTextLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 583C97D8927B51E6485A4BAD1EE6C61D /* ASTextLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - C1C72D17FE7705F75F7D4A489C7FA901 /* ASDisplayNode+Ancestry.mm in Sources */ = {isa = PBXBuildFile; fileRef = C3A340B8DECFEA34B858E29D8A3B6860 /* ASDisplayNode+Ancestry.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - C3D0D54F1D4AC76E5159ADE76A4BF3E5 /* ASLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 21328B9DF462AD6B1267E304A81AB8FD /* ASLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C3D2774B53014573A099E87AA4C0CED8 /* ASIntegerMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A0720ADCEE5EA7E1BF10055515487F0 /* ASIntegerMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C4A841122A1500C4F97A8D7C9E9D74BE /* ASDisplayNode+Convenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = B5CA33263F85C6E21A268F342F079528 /* ASDisplayNode+Convenience.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - C4BEE12FE70FC9F48E1178A70756AA0A /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = F8E01445D32DABC80642FEC5993BD8A7 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C5314BB868384564ECF4372C0175B34E /* ASTextNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = B54D5C75E76CBA98DF5873350D8E1932 /* ASTextNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - C5CEB80D72E251F94F35D3B6FB3EBAA8 /* UICollectionViewLayout+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 1402CF84CB36E6A58305FC9A07AE9A7E /* UICollectionViewLayout+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C6739911713F8557CF19854FEEBF1F7B /* ASTipsWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = E144F57F0B8D28515331682DD09E32BA /* ASTipsWindow.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C68FF971E5ADEAA4FC8C82CEFA83FCAE /* ASMainSerialQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C4D6B95F7D6F2215E963E83CE181D37 /* ASMainSerialQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C6BB719F1B9AEEA25559EC0A0A8B1EF6 /* ASContextTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 956EDCF688E51E9B81CC568337DB6AF1 /* ASContextTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C6DC15608E4521CB5D4580A4EB9E80A5 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AFD059D7D4CBEA0213433EBCFF64EA2 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C7EA3CF590053B0DF7B361B0BE896FE4 /* NSParagraphStyle+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = DFD6F206B8FFE0C84A6A76F86D80AD38 /* NSParagraphStyle+ASText.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - C94CBEE8592258E9711DFAF7033F1EFD /* _ASDisplayView.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECAAA631B9C5458137845A17153DE7 /* _ASDisplayView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CA38ACE37FA6D3346953C102DC0CF417 /* ASAbsoluteLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3159FFF68D91838D2CC5D7DAA07DD14A /* ASAbsoluteLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - CABC9E83A17F030D6B854E7BE681F79E /* ASNetworkImageLoadInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0846880D85E50BD74D66583A3F4D4CC /* ASNetworkImageLoadInfo.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - CABFD58E0EC8F3FBC7C7BAFB0EE3D814 /* ASBackgroundLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AA4FC6584F3CD6AEA868108B7CA6DAB /* ASBackgroundLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CAD0F1279420E3AB6FE9053ACE0052AE /* ASTwoDimensionalArrayUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = A0C4D1E5B3896EEE58F2719BD330AE3D /* ASTwoDimensionalArrayUtils.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - CB8FAB30E0D91EDBB367D698A9BDFB36 /* ASInternalHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF1D4FA61A9EBACC795AA678AB81D0CA /* ASInternalHelpers.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - CBA83C25D3648F8445A0FE102057E32C /* PINRemoteImage-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 843527DDA67E9C01B757C84DADBE0839 /* PINRemoteImage-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCC6E16B2EBA80F74ADB96FB4A0321C1 /* ASIntegerMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF9CAE59564D99FB78072D06EBB3E37B /* ASIntegerMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - CCE160B0B53C129CB762ABEA9C679306 /* ASAsciiArtBoxCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5929816D10F8DFF27EA0E163D3AF6351 /* ASAsciiArtBoxCreator.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCEB9E6D89EA304ABF7D2ECF466B81D1 /* Zoomy-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A83CB18A0AFD9B76C70CFE0F7189A01 /* Zoomy-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CD29B7448A3BBED8D9D3DA42FE2C689A /* ASCollectionViewLayoutInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 879C8B32AAE6359D599F78BC16CBB13F /* ASCollectionViewLayoutInspector.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - CD7F69C88C619060BBC6A59FFF61C639 /* _ASAsyncTransactionContainer+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = EA4F56FDA7A6B32FF3A7DB0EA0E30D9C /* _ASAsyncTransactionContainer+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CDDB2859AD81C0BF3798E6E4B11D7EEB /* ASEventLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6DBD0F18AD2C048A15C6E508350FE156 /* ASEventLog.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - CDE7A698F923984D4536BF034E55EBC0 /* Pods-Zoomy_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6786AB9FCA35EEE185C0A027621E7653 /* Pods-Zoomy_Example-dummy.m */; }; - CE2A06018735F6148FC6DE9E101DD198 /* PINImage+DecodedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 93858681644872716A52C7FA30FF1F36 /* PINImage+DecodedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CE5C0993A786119367F5B72F4B039CF9 /* PINRemoteLock.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D861E5A7BB213F7BDA5A3E68863582E /* PINRemoteLock.m */; }; - CEB7EF76375F2C1474F4197F4D56BB32 /* CanLogMessageInFileInFunctionAtLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3521512E9AA05650F6F76700EC1D65D9 /* CanLogMessageInFileInFunctionAtLine.swift */; }; - D0B4B61F2B2E6DFAA1B9720D57FB36E0 /* ConfigurableUsingClosure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C2261536A1F390C347C83BE1AA59011 /* ConfigurableUsingClosure.swift */; }; - D12FEAC2B168519EA04F32F80A1A6C26 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1303302AFAE1A1492C119553EB9326C0 /* CoreLocation.framework */; }; - D151AD5C0614B9CD096813DA5583792E /* ASTextKitShadower.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0EAFE70C30090A5CF72DE2F7415578D1 /* ASTextKitShadower.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D1A7903C6CEDB9F9CA80C296D81651CF /* ASCollectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 937DE4AA07CF005B3D3E13301EDEDDAF /* ASCollectionView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D1C2B6C9B28D974F10C233EC059377C7 /* PINMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 3208DEBA29C56FF8EBA5563EFAB53B48 /* PINMemoryCache.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - D2217169217657E37C514D6DB2D0CF05 /* ImageZoomControllerContentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 675C60B5C42D6C1F553B1698D747A649 /* ImageZoomControllerContentState.swift */; }; - D25038080560B83F9B92E9F473DB10D8 /* ASDisplayNode+LayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = E68F514908D5394AA86EBEA208E47A04 /* ASDisplayNode+LayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D2D96C2A2312008724BC4C55BD130768 /* Texture-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C601CF5677E9413D7D662DCBFF8A420B /* Texture-dummy.m */; }; - D2F6B3F151EE8B106C6E6105EC1739CE /* ASInsetLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 607041B6536208E2F64B565D46764939 /* ASInsetLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D31960D7801C8096710BC1E5BA45D3BC /* IGListAdapter+AsyncDisplayKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 157FB8FE619F3FCDFB26DECF132232C3 /* IGListAdapter+AsyncDisplayKit.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D33347049E4B7BF7ABC7E8674A2B74FB /* PINGIFAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F85E0F87EC16039F8621F5162F9270 /* PINGIFAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D35D3F99EDC15ED140F016F880FF37ED /* ASMapNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 285A45E26308C77E98740CEB3DA1101E /* ASMapNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D45F1A1B99E2307710FB21A12E7CEA47 /* ASTableViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = FCBF961C99AB6BE3B67E1A5D49BD0FBA /* ASTableViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D4D187C5502D1B6BE469EB84707455CD /* ASTextKitShadower.h in Headers */ = {isa = PBXBuildFile; fileRef = 899757F2A351E6C05F6A5A3EE1B687CC /* ASTextKitShadower.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D51D44504EF0A8D760929A136FC580FA /* ASCollectionViewLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C216819A1D5BC5B2AFC924E6C9858A2 /* ASCollectionViewLayoutInspector.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D61DF2CD8BEA2617F8A666D0F3828466 /* ASTextUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0DB18754F7DBD5680043B023D3924CDD /* ASTextUtilities.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D75E18202ECDB1208F5EAA0AFC37D058 /* Logger.Formatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 911A2B69447A9FA80318E2B59EBEE264 /* Logger.Formatter.swift */; }; - D76D435FF64CAC593C30BE295C7D45F1 /* PINImageView+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 91ECE220C50CE0A538355C0A14CA578F /* PINImageView+PINRemoteImage.m */; }; - D7B81994873CE58FC1520DA0AC804398 /* ASDisplayNodeTipState.h in Headers */ = {isa = PBXBuildFile; fileRef = 2352CE5ABD68B97D2C20A75FE2B8F448 /* ASDisplayNodeTipState.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D80EA33818CC22A16D38B466350CED22 /* ASInternalHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFE143F7C05931041DA6DF354DE63CC /* ASInternalHelpers.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D8764C01C83F047859F91BD38CF46998 /* ASBasicImageDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83079A844C816FE05A93291E7FA5196B /* ASBasicImageDownloader.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - D8E28917CF1DBA136BE47898774C4AFC /* ASTextDebugOption.h in Headers */ = {isa = PBXBuildFile; fileRef = 501BF04BC8D41B8C49F2412A7F6EA9E5 /* ASTextDebugOption.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D91C82DAF9D9C5D5338B154770E5CDBA /* ASTabBarController.h in Headers */ = {isa = PBXBuildFile; fileRef = E729BFF861BF80E417AA7161ED356A47 /* ASTabBarController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D98D4D50645DBEC555A76768B120960F /* ASTextKitRenderer+Positioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 67980F51D8D7857FD5DF2B3CFD94B2DC /* ASTextKitRenderer+Positioning.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DA0B2AAB4F5383AB91442800F650D264 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */; }; - DA24A30C9DEDAA65BF82D23DBF1E18CC /* ASScrollDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 37BFD09009E1CA2D06CA1E0299275DFD /* ASScrollDirection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DA26D97E545E9A37D918D1B674D02F23 /* PINGIFAnimatedImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C9B91A2092075DF22A0BDCB1A1EEBCA /* PINGIFAnimatedImageManager.m */; }; - DA53E5B9E93222ADBC1F715CCFAA7213 /* ASAbstractLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = A566D0D02EDF7ADE78AD3563AC231EF8 /* ASAbstractLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DA6B7135D9C9052FD7BC1B108F3B28DD /* ASLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDBFF3393C31CD709ECF615266088C91 /* ASLog.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DA9D9E86E8AE00381E6236E38FE48D48 /* ASBackgroundLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 03C015688FA02187BD871480FC999411 /* ASBackgroundLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DAC47FBAC82155097731E61283236AC2 /* ASPINRemoteImageDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = AECD5C2F25705D0D88F3CBD2374C4F9B /* ASPINRemoteImageDownloader.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DAC9BD448D1FBD574287D47F09E8BFFA /* ConsoleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D5664BB8FDFB48A12DED4645631583 /* ConsoleLogger.swift */; }; - DB0B0877719D949A31200A8EDE68CC81 /* ASBaseDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 846F36BAF3041EB8ED21F54F6B9DE07B /* ASBaseDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DB83DB23211033F5D5A49DD39823CBEA /* _ASDisplayViewAccessiblity.mm in Sources */ = {isa = PBXBuildFile; fileRef = D10C816C7692C03BB6F3FC1DB50EA606 /* _ASDisplayViewAccessiblity.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DBBE66619BE131AAB0ED29B21F4C0782 /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 04B46B85C03FC5CC066ED7F633FEC888 /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC709A9A173411EDA887B60009912C0B /* ASMutableElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = E6581AA58586EF122B4A7935CF2A0838 /* ASMutableElementMap.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DC8601FE08234A9822B7C2514E1D1BC0 /* UIResponder+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D2F12F4DBC147ABBFF5EBB4E003AD04 /* UIResponder+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCD1424C14D939C036F742ADAB03DEA2 /* _ASAsyncTransactionContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 45732382F06CCCBEF2548090FD84E0FE /* _ASAsyncTransactionContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCDBE3F8533C0A3F52DD885C8F3961D8 /* PINCachedAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 29AEC841809838E1FBD4FB000000901E /* PINCachedAnimatedImage.m */; }; - DD8AE4A94D416EF6C0388BBC6C92493A /* ASMultiplexImageNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44B1FF984C74EB2DBF074043ABBA4F0F /* ASMultiplexImageNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DE53B395CDF47347AD2A31FE6F1F1DF5 /* _ASScopeTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C2E7C5F0F15FD412B6E90CE66616C6 /* _ASScopeTimer.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DE5647C516D1BFDA0500E66F88A9114F /* ASDisplayNodeCornerLayerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = EB97330F8020838EA2C835F2D5E380A1 /* ASDisplayNodeCornerLayerDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DEC3A15E298F0EF0A5E9FDA37836D85E /* PINRequestRetryStrategy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3472C9C5C5A1BC89A55AC74BFCC7B1 /* PINRequestRetryStrategy.m */; }; - DEC3B69E096361E51BB678635ED78D1F /* _ASPendingState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 74F6A7ADB0BD1789A4271467B0355510 /* _ASPendingState.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DF84A4991B37EECA24F294A6CB489AD5 /* ASDelegateProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3435983882FBE500A5D5F17D35799084 /* ASDelegateProxy.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DF9D78163203047F4A090E5E5A83034D /* ASResponderChainEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 74A617AD6A6D696D3F0296CD7F204CA1 /* ASResponderChainEnumerator.h */; settings = {ATTRIBUTES = (Project, ); }; }; - DFB6860FBD6FBDCC6A3F1F6B4D96D78D /* ASHighlightOverlayLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4EC82CF26F151D3049C9FF32F22AF94D /* ASHighlightOverlayLayer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - DFBC058FFFAFAB5171AAB6050B29E4C0 /* PINRemoteImageManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 58DF4723F4C3C47CA4B7F675A4BA05FF /* PINRemoteImageManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DFCB49429811C4C90DB5A12826D22904 /* ASCornerLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 162E6601E2398E3D0F75F647411164AA /* ASCornerLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E05B0B1D8724CCCB6E7F7B3843FB8884 /* ASLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2BF44023A1917C6A267664CDCC906D27 /* ASLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E05DDD2C31BAE9AFECC32980200EE627 /* _ASHierarchyChangeSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2DA07ACA67D6E241C85078FE67F857E /* _ASHierarchyChangeSet.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E084D2A81E75E3034A7C08B8B3E6006C /* PINGIFAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 88BB970C61F10199085A0DDA55F977CB /* PINGIFAnimatedImage.m */; }; - E1018F5B00E75731D029ADA8F9428D59 /* ASExperimentalFeatures.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9D593D3251E3CB76916473892474B96F /* ASExperimentalFeatures.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E12D16B7BE97678712A0209876969023 /* PINOperation-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ADFA05F60AA04316A5BB156A0555D0B /* PINOperation-dummy.m */; }; - E144FAB97090ABE2509D521A107C550A /* ASDisplayNode+InterfaceState.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EBBCA9827ECA85C255F6F5B58D251 /* ASDisplayNode+InterfaceState.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E18E5E71D76E5D16380523D37653E3BE /* _ASDisplayViewAccessiblity.h in Headers */ = {isa = PBXBuildFile; fileRef = C9579AF5CF380A430E2296E21C0498ED /* _ASDisplayViewAccessiblity.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E22741A4AFDACFD4EFA1796CD566D9A0 /* ASIGListAdapterBasedDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E4321DB363EC82D6737D7BD0179F660 /* ASIGListAdapterBasedDataSource.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E23A7BFDFD83FB3EF705AE91EDE800C0 /* ASTextNode2.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D4DA64813A14F793D42CFE74070D648 /* ASTextNode2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E324F8907100F01247139C4AE582F80F /* CGRect+transformedByTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D9DB88CFA4413907F47AD1A71EAE35D /* CGRect+transformedByTransform.swift */; }; - E4DA68854AE8AEF318DD2002495169AF /* ASConfigurationInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 63C9ACDEAE8A9552A325796A234F79AC /* ASConfigurationInternal.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E562E9196F87EB8868D5D150A50A4A0F /* ASWeakMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B63699EFB4C341DDCA0160947E19395 /* ASWeakMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E594B2023EDA296EB759343493CCC0B1 /* ASLog.h in Headers */ = {isa = PBXBuildFile; fileRef = E7B49D7AC5C2C0142D862EFD6D43B2B5 /* ASLog.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E5CCE08E7214C14DAF86AFE27769D7C7 /* ASCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = D49499B1B65785F2A7C1C4CD99765E4D /* ASCollectionLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E5E0315BC7724AC94FFC07D5A26A491C /* PINDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F0FE57A14FE3D7B4120DEFA866E5A6 /* PINDiskCache.m */; settings = {COMPILER_FLAGS = "-fobjc-arc-exceptions -DOS_OBJECT_USE_OBJC=0 -DOS_OBJECT_USE_OBJC=0"; }; }; - E7431794E12712C34829C882DA2C3E84 /* UICollectionViewLayout+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEDBB3F3DD47B161C406D03FF3A9BCC5 /* UICollectionViewLayout+ASConvenience.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E763AAE38EA62B4F77B25AD8CC2A8219 /* ASTextKitAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = D18419ABCCABCA2F165BA42ED0301C18 /* ASTextKitAttributes.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E86A4F5E18F02F6D89A404F499A916E9 /* ASTextNodeWordKerner.mm in Sources */ = {isa = PBXBuildFile; fileRef = 19BD6E57E86CCDA20DCA33B5615D6479 /* ASTextNodeWordKerner.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - E931910D623E887EE1B3E9635BEA0906 /* ASTextNodeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 053572BA7FE13DAC5CA8C9ED6FF7310D /* ASTextNodeTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E9445389569C3B57DC6184A48247CA17 /* ASConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8669BDD150909EC0BEE733EFBE3F7E6 /* ASConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E9C4997FA9B5ECCCD2CDF876A2370BAC /* PINRemoteImageDownloadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AEE3B05A5D034B14D96235552DAB8A1 /* PINRemoteImageDownloadQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E9DAD8B9BFF1BC7B4AF531B0630DE2A4 /* PINResume.h in Headers */ = {isa = PBXBuildFile; fileRef = 098428E42955EF96D87FE1C354E8AD9D /* PINResume.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E9FDE332EF4FB89FBF5865A984B4E650 /* ASCollectionViewFlowLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = DE70B4985D2139726F4E0BC1FE545A58 /* ASCollectionViewFlowLayoutInspector.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EB7F659A9B5091F89DEC4A342B81B4F6 /* PINSpeedRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = F751A2E0A0D199939EFC0DF626CE0957 /* PINSpeedRecorder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EBF6479922ED01E185419A2FDE61454C /* ASTipsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 551ECA207D97BC65B3FF2EC1D0187E25 /* ASTipsController.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EC1BB835D45773A0FFC8211C6BDC7DD3 /* _ASCollectionGalleryLayoutItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = AA3875A1795ED07E509FDD997F948597 /* _ASCollectionGalleryLayoutItem.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - EC2BCD8F8DA759BB81C550F90BA144E6 /* PINRemoteImageDownloadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 444CA15EA0AAE68E84B2D0D2BF11BF8D /* PINRemoteImageDownloadTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EDD39001F5CEE1894315A687A3BBB54F /* ASTextKitRenderer+Positioning.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6901B23BFB9DC7E4D4147AA505777EA5 /* ASTextKitRenderer+Positioning.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - EE9826EAD4013D63E0102D26BDD5E460 /* ASCollectionLayoutCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5725152FA9CBD3409857DF7D14892C1D /* ASCollectionLayoutCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EEC8FA0CF9FC6D0865029B43A2DA1579 /* ASLayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CD72B567F111E9E3EDFE39E0620500FA /* ASLayoutManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - EF4C0AB9A764F1E676C064BB9BFF41BA /* ASDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = F77355B911C772EB2AD735BF076E4CFD /* ASDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EF79F88DE3DEBC770852C44680868FC6 /* ASPagerNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FF46F97C823C0B402802B311E54781C /* ASPagerNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - F0B1C782468C4E0A2D8EEF0C75AF7503 /* ASStackPositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B50F73FC9907B3B5250EDDF7ED1B18E /* ASStackPositionedLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F226556F01BEFDF2DE085670133A3149 /* ASTextKitRenderer+TextChecking.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E4CBF6674EF31AA91520974C6E01BD9 /* ASTextKitRenderer+TextChecking.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F251373834CB3561F540AD2FFF148685 /* UIView+layoutHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53EB558A5AE8A80267886C93479C1753 /* UIView+layoutHelpers.swift */; }; - F259DE3E21154420D8C2D9C786100761 /* ASLayoutSpecPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 445246B3B756F5F96B99AEF7BBA3F014 /* ASLayoutSpecPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; - F26DBA07E4395641FAE0F387285C6DAD /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92F9025F046A5B8CD0B0A7FBF4C53383 /* MapKit.framework */; }; - F285BAE9B392AE3FDEE0859C9C61B2B1 /* _ASCollectionReusableView.h in Headers */ = {isa = PBXBuildFile; fileRef = D31A98FCF7B961D3A00D60EA1953837E /* _ASCollectionReusableView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F40D3A0927A12DC0CA8E02FBD4A98AC7 /* ASCollectionLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = F378A66FF19F87E754731A02F1D8352E /* ASCollectionLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F636F0AC9D61B6CEE7356E35A1B21F98 /* ASTextKitFontSizeAdjuster.mm in Sources */ = {isa = PBXBuildFile; fileRef = E778EA8770ABFA8D712897C593624C1B /* ASTextKitFontSizeAdjuster.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - F69C784A2AA9D039BDF1CDBB521025BB /* NSArray+Diffing.h in Headers */ = {isa = PBXBuildFile; fileRef = 32E1A5A62805A96755862D0EA25E6BA4 /* NSArray+Diffing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F6AAE4F5995235A0EE8ED3007BB228B2 /* PINButton+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F618C832DC0906460A5823141B80889 /* PINButton+PINRemoteImage.m */; }; - F6F5A0CCAB6863529C1717F73562EECB /* ASAssert.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD3CADDF86084740EAE1184277C790BA /* ASAssert.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - F75371474DC31912DFEABE144AD8C134 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC4DA700D665D4C0D110ACE8AAED6FB4 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift */; }; - F7936E3687857A615BB7E330C12081B0 /* ASMultiplexImageNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DF8DF606941FFEEC9EE31E1353EF53A6 /* ASMultiplexImageNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F7B128017791AC59B7F495BFBDEDF46C /* ASLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = ED741FEC7CF39C7B0B4271C1A6C33182 /* ASLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F87387A8B2056D3EC40A154A8CB46F02 /* CanAnimate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBFC51734B70A5463EA74EE6AA9EB96 /* CanAnimate.swift */; }; - F8A91671AB39F8109480C3A72D69D689 /* BounceOffsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D67F8257B9EA483BC03A079926677DF /* BounceOffsets.swift */; }; - F8ACA480E6D150199FE448D7993F5494 /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BCA78334AF16808277D2FAC66F02BD /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift */; }; - F8CD2CEBEBC1919F3E0F582F4CDF026D /* ASDisplayNode+UIViewBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = A867957DE758B3752902421CE4EA0DF8 /* ASDisplayNode+UIViewBridge.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - F90417F58EC71BEE267F22B71CDD3A42 /* ASNavigationController.mm in Sources */ = {isa = PBXBuildFile; fileRef = C35693DA8C2E5A82EBA0F056580C2534 /* ASNavigationController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - FB5EEFB759CCDAC5A4D34FF8BC26A5C8 /* ASVideoNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = A23F94511B338FE277EC2BCFEC053F24 /* ASVideoNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - FCD292D043C501CF54E50BC83FB553E4 /* NSArray+Diffing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86803184503140C2A4F07DFFED434615 /* NSArray+Diffing.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - FDF5877D38A81924C6A93138F33E3550 /* ASVisibilityProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = FEEE1F4CD0EBD604CAB288E054835B9B /* ASVisibilityProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; - FE7DAF6410C68A5F2E2049B56FD4C2BD /* ASPhotosFrameworkImageRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 19E53513494050AA573FBF57F1E0B64F /* ASPhotosFrameworkImageRequest.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - FE8F1F18D987E1C044013CC987939B11 /* CanLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854C0BA85C5EBE5FC30BE62E6B85A1A1 /* CanLog.swift */; }; - FF1496139C9609A42E5571CD9A20D40E /* ASTextKitFontSizeAdjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = 4633B6D7E44B708326E2E31CBFD78C9D /* ASTextKitFontSizeAdjuster.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FF854CA6EAEA89511D244275C9E22617 /* _ASHierarchyChangeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 77352767819B3F1506BB79361E5199A9 /* _ASHierarchyChangeSet.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FF965E8D91F7AE6511721F23130A8ACF /* ASMainThreadDeallocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = DDD6A5FCBA65371A45826CB1728A0F7A /* ASMainThreadDeallocation.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions -Wno-implicit-retain-self"; }; }; - FFBF9735C8C5AA11E62017EB58440E8A /* ASTableNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF7B14A070E69EF1B3DCDCDC5341299 /* ASTableNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - FFEAD4B42A1A5B7C625A65F682BDC889 /* ASDisplayNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E6A03617F6864E29B9A5454452C1AE3 /* ASDisplayNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 02131FDD47626B3DCE579DFFC4E44CC2 /* PINRemoteImageProcessorTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 30D28688CC6CE710EEF7F4DBA6B1C90C /* PINRemoteImageProcessorTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 025BA0BDF87BC89E358481C5C60C4EAB /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72E63BB89BB4648998A676175AA7FCFE /* Logger.swift */; }; + 0284D979FE5030B1BBE20318DFF83407 /* ASAsciiArtBoxCreator.mm in Sources */ = {isa = PBXBuildFile; fileRef = D017BE463D6FA4889B4C3BBCB7F0058C /* ASAsciiArtBoxCreator.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 030C344EB05992E778CC730E39FB7709 /* AnimationEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 921BD97807EB0DDC435B8194E258EA9F /* AnimationEvent.swift */; }; + 03177DA0581846B708D9C1B4C69AF5B4 /* ASConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2F5C8DE6CFB8EC60F48B06A6985E2BB5 /* ASConfiguration.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 0337373CAC9908A374853CDFC3B00A31 /* Pods-Zoomy_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2ECAB2D10463A515B8622C35649FE2A5 /* Pods-Zoomy_Tests-dummy.m */; }; + 0368A0C1EE4DCCF63368E227AABF90FA /* _ASHierarchyChangeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7381EDB33C4C063714E18E447DF8D /* _ASHierarchyChangeSet.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 04543BFEF8F8F32EE2B4A3304471A5F4 /* PINRemoteImageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6489C428B7BF38CBF9D3B664F3057F20 /* PINRemoteImageManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 047062E4C55AF0E9668F0D8A5210D4FA /* PINRemoteImageProcessorTask.m in Sources */ = {isa = PBXBuildFile; fileRef = BB3F1F87F50F1A78B7D2377AA4249147 /* PINRemoteImageProcessorTask.m */; }; + 065EC5AD7B86716183B6C6F10214ECE9 /* ASAbsoluteLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CC29518FB41642415C151CB182BC02A /* ASAbsoluteLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 0671472257D854CBC8F14A6460CBD70A /* ASMainThreadDeallocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = B0C21DADF77FC6BC3F01C866041F4B12 /* ASMainThreadDeallocation.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 06B6D4A109D383F87DB87E9B94F5AA73 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 927D9DECBCACA5CF8DBD67DACE505DC2 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift */; }; + 070ABBECB4EDE07A98B7B8194C7653F1 /* ASInternalHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DADF593FC3453A7056F179131A40785 /* ASInternalHelpers.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0731FF1F4C72E85A9CF8BC8FA403E7CE /* ASBatchFetching.mm in Sources */ = {isa = PBXBuildFile; fileRef = 357620DEBE7E9C5DCAAB4AFEDA157938 /* ASBatchFetching.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 07DA5777E40B8C2671D3103F8E76F969 /* PINProgressiveImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 94FA6A0CED36425F79643AE9E44BDD3B /* PINProgressiveImage.m */; }; + 095EAC3436164EBB3B0DA2704BEE8D7A /* ASDimension.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2FC73F1B141C088A7A71E3189F506E9 /* ASDimension.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 09650E825B735144A1D66BFD8E55DE4A /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E362247576ABDCAC95FD27020FA954B /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 09D5CC75390536E1FD6F02F5AE3862AE /* ASTwoDimensionalArrayUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = F2E4639A35242C5823DACB52A5054354 /* ASTwoDimensionalArrayUtils.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 0A1A2CA05738BF97386132DC453056D3 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = AF56F95269473FF68D4A9F83950E1E15 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0A8BEE494BB1DFA8A3711444D6CF5728 /* ASDKViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = ADDB82741AD2FBDEE3C9C44C84A11380 /* ASDKViewController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 0AB37573CCCB26C65FBC953E9DE6E3CA /* ASPendingStateController.h in Headers */ = {isa = PBXBuildFile; fileRef = D6EBCABE6BBB30D4231E0B246B73ECE8 /* ASPendingStateController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0B909629DF48FCFF4BC16D2166703D9E /* Logger.Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377942A736134FFDA949F494767752F1 /* Logger.Settings.swift */; }; + 0BA46D04026103E69FEDDCECB4C092F8 /* UIViewController+CanManageZoomBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 695B0EF784C58FAC0A0A0275CFA6385A /* UIViewController+CanManageZoomBehavior.swift */; }; + 0BE5326613B0772676696939B028455F /* ASTextNodeWordKerner.h in Headers */ = {isa = PBXBuildFile; fileRef = DA4E05471B629E5426D5E5F9A38C11FF /* ASTextNodeWordKerner.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0C8AFCED476D2CA82A33B9A602B7806E /* ASDisplayNode+UIViewBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 092BA4C0B35FCC3C7EDF8A310EADD496 /* ASDisplayNode+UIViewBridge.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 0D1AFB17D23CD14FEF004D8F753E170F /* PINImageView+PINRemoteImage.h in Headers */ = {isa = PBXBuildFile; fileRef = EDBF575B54A123E2694047C8C6894AB7 /* PINImageView+PINRemoteImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0D1E926C7BD4DECD45A42036400EB261 /* ImageZoomControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4012AE46C9AA9C1919E2A94BD8460C38 /* ImageZoomControllerDelegate.swift */; }; + 0D6962F9248D95D9655C562687D377DD /* PINRemoteImageCategoryManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A6608A16D83A6A25E6DD589D4FF08DB9 /* PINRemoteImageCategoryManager.m */; }; + 0DB894195A40459248365D08C82C0BC5 /* ASNodeController+Beta.mm in Sources */ = {isa = PBXBuildFile; fileRef = 288309C0A0B85677861ECC27CE99504A /* ASNodeController+Beta.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 0DCE1ED366ED82607C1A1BE2C822852A /* NSParagraphStyle+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2800D748DA8B5242EEFED6AC2283901D /* NSParagraphStyle+ASText.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0ECB1E4D8FA0F073DC3CF9E5EBCA4370 /* ASTextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 152968521F92B8C3F6F5427C21D3C73C /* ASTextInput.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 0FEFBFB43ACCE25E8F4A6A699FA9D8B8 /* ConfigurableUsingClosure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4281A047ADE807364869D0EC4C706EF6 /* ConfigurableUsingClosure.swift */; }; + 0FFDB747E5756746172DD89CAC9073A5 /* _ASCollectionGalleryLayoutItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1563E54ED0D8EAADD8B23DD9E695A4C0 /* _ASCollectionGalleryLayoutItem.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 101880381147AEAF37111DAC551649D3 /* ASTextUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 806DDF999DDE3AAC2ABC6FF9CE3E5B8A /* ASTextUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 103E27C248EE7B173C0C64AC5390317C /* InjectableLoggers-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D1B0B1E3406CFE376B8C7A053A6D027A /* InjectableLoggers-dummy.m */; }; + 118F802C5199A586B39872DA5C5D70F9 /* ImageZoomControllerSettings+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1618D9D9C78605F98FD056F93E140550 /* ImageZoomControllerSettings+Equatable.swift */; }; + 11F5542BE8045A9068A57312EA5A028B /* ImageZoomControllerIsNotPresentingOverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51135E999C9B63A3A146C9EC1CD3D0CE /* ImageZoomControllerIsNotPresentingOverlayState.swift */; }; + 12037D088DDA51D83DAED06FB069D79D /* ASLayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = EBBC13C1697AD5A79814942839EB3BE6 /* ASLayoutManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 128159D60F5F30A14FFA7E2216B689A8 /* ASCollectionLayoutContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFEFAA3AC9FF06B1F868CF0C07B6C39 /* ASCollectionLayoutContext+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 12BD7A4EE714789DE378364B25BC681F /* ASCollectionViewFlowLayoutInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34E1BFF37B6AB67835029387BC31D4C3 /* ASCollectionViewFlowLayoutInspector.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 1414F0DF56982DFC65C6E01ECE6A4374 /* ASTextUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 738C0D498805A7D7930418DE87AC4F5E /* ASTextUtilities.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 14B7A03552B6697528E765E9DD51F34F /* ASPagerNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 40FF8F46258CC48006CE98E0E8C827FD /* ASPagerNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 1563756D23089B763B4317FAC682C06A /* ASDisplayNodeExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = F2C1DB9479499FE9B70BDD375E242A22 /* ASDisplayNodeExtras.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 15AB102788E5371031F010FB3494FDC4 /* ASDisplayNode+Convenience.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0B6D34284EEEC294A8BB6750F6173E /* ASDisplayNode+Convenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 15F5D45FBEC8A2C1AB621B8C2A4FED33 /* Side.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240A9BD4EECE73A564FCDC42E7A35203 /* Side.swift */; }; + 162A11E39B08B85FD0E61EAB7E1FF9E0 /* ASElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 51712480D4DC2E936F5A74EB8E97FF76 /* ASElementMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 16ABB0CB811745D54DC052D21166EF81 /* ASVisibilityProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C83426449CBC7979380EE2EC7A48D /* ASVisibilityProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17514581F08C4029877D4B19982B1AB0 /* ASControlNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 39AAA51020546A6E36D2E221A7CFEAA4 /* ASControlNode+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 179E80830E414D876BAE96A5E9D033B1 /* ASTextKitComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F713CCF7949E74D4E972F737A6788BE /* ASTextKitComponents.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17ADD23D4835CB144BC6CD354844FF50 /* ASPagerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = EED6E5D64A260BBC73D89EAC4EE5A380 /* ASPagerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17EE7FE8DDF79CAF395E4A3080D7B035 /* ASTextKitCoreTextAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = E00E407AA304E669975F496CDE757534 /* ASTextKitCoreTextAdditions.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 18395D9552702EEA995F3EBDE3DDF009 /* ASWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 424205752E50C0BA7AD6C7C527C90AD1 /* ASWeakMap.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1B05E3D885BC93FAC2F5D2007A888386 /* ASTextKitRenderer+TextChecking.h in Headers */ = {isa = PBXBuildFile; fileRef = D2D0DD2A8BC4A91FDFB94D2232DC0252 /* ASTextKitRenderer+TextChecking.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1B264109896A02DB437B7C2FF68DF711 /* PINResume.m in Sources */ = {isa = PBXBuildFile; fileRef = BE7C4386005ED1B9320FCC1D31C621CC /* PINResume.m */; }; + 1B2A0A4681935DC95834481F21759220 /* _ASAsyncTransaction.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8E316AF000D6A307AFFBFC59E27FCB2 /* _ASAsyncTransaction.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 1B382A91CB2301F2D4F0A493820CFDED /* SimpleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0091DD8DF08F9D4D4FED8A7FAECB171C /* SimpleLogger.swift */; }; + 1B3BD47E66BBC5F931984D74A3E0047A /* ASMapNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC76142E2ECD50C70F0A3150606B27D0 /* ASMapNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 1B7F2F9ABEC6E2EF28D4200AAA0EA967 /* _ASPendingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 90589B54C0040F9F2E141D6205FB3F95 /* _ASPendingState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1BC79FE7F10E5A56EBBB646BCA6A2974 /* ASExperimentalFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = A4E31B166F2E3EE17BA52F79751D6ED5 /* ASExperimentalFeatures.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1C085C8ED0685A8CE4B5B5735C7F7EF6 /* UICollectionViewLayout+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4227E8F62083D39A853A5913213842 /* UICollectionViewLayout+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1C8C87AA0418AAB89B67CEB269819488 /* ASInsetLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08C5161AA3E2ED418F8D43129A259B24 /* ASInsetLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 1D0CD1F6962F538225CE1E3DD8275C0D /* ASCollectionViewLayoutInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 953AD4EF877BF93E174279ECC0B1D89F /* ASCollectionViewLayoutInspector.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 1D31956E47A1667E4ED78EDBCF63657F /* ASDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 923B449EB1487E6024A361F239600946 /* ASDataController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1D503DFE241AA255DA1D05DB8E0DAEFD /* ASLayoutElementExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 42EC66579E3600DB1C45F90542FFCF49 /* ASLayoutElementExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1E5042D00F802CC758E27A3DFFA27413 /* ASBasicImageDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = F0FDFF2101834ADCDD23AA9D3985EC49 /* ASBasicImageDownloader.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 1EA7BAB3BE0B0B5D2BC7C24F5E81786A /* MockLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787A46EF98C950C390FA42BB039DA0EC /* MockLogger.swift */; }; + 1F51595178FA581C9FA84C59AAC0ADF2 /* ASDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = A52E2451F6B76F104A42C6B6EBABAC0E /* ASDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1FF802E6BAC65A931C00BE18248620DC /* ASIGListAdapterBasedDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = BA36FE7BA8C83C8B594E50029C928965 /* ASIGListAdapterBasedDataSource.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2045F583C05F550162C635C56DB9F44E /* ASTextNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A1161DF44833F8207702FDDDADDC190 /* ASTextNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 218E0CCCF87BB42550E157E145C6F584 /* CanAnimate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 734F9C74F82633188225C4CC9C72FDAD /* CanAnimate.swift */; }; + 21B002B49EA6268FD714728C7E464A7F /* ZoomyLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EACF1E5973F81B5B80D4AEC7EEA6F72 /* ZoomyLogger.swift */; }; + 22AF64923BA5C136C59879B167617CA0 /* HasImageZoomControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F7A8AFC48B5338B1D11FBEEE473EC8 /* HasImageZoomControllers.swift */; }; + 238353CE094AADDB351A5AE7D730F8F0 /* ASPagerFlowLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = E3D2C16A2AE576BAE4EEE64B5C6ED5FD /* ASPagerFlowLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 23E0F25169AB9190135651F5D06E8AFE /* PINWebPAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 677CD4785FE892E11D23DB575EF58964 /* PINWebPAnimatedImage.m */; }; + 23E59691FBD46D8ACF53E02745593028 /* PINRemoteImageMemoryContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = EDC1F1D124388ACE2413346CB3B8CEB2 /* PINRemoteImageMemoryContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2490B901F64B7A71103C5BACBBC14195 /* ASRangeController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F3CBC9D77FD5B66D00BA89359E50FE7 /* ASRangeController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 24E9D62BB1AEE5FC221F92CA8AFCBEC4 /* ASSupplementaryNodeSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CFFF44F0A0757458B152AA0C8E5E1AA /* ASSupplementaryNodeSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 25153085368DA21ADFDAAD6DA0EFCCC9 /* ASTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = BE54CB3D9126A0A4E84D9DA6BD4293D0 /* ASTableView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 25252F72502AA588EBB17EFDC7B915A1 /* CanProvideAnimatorForEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE7B568EE5763387E9FD7DA97625EA1 /* CanProvideAnimatorForEvent.swift */; }; + 25283CF364080FF8D8C86F0B9D4936DE /* ASScrollNode.h in Headers */ = {isa = PBXBuildFile; fileRef = A546884224C6ED423FD4E6E7883B3077 /* ASScrollNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 25950726ACAF3C2B3EF3B24499F05921 /* ASButtonNode+Yoga.mm in Sources */ = {isa = PBXBuildFile; fileRef = DE98C566C001F35E47A53562D425064B /* ASButtonNode+Yoga.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 25B46F5BF00AFAE8A15CC01AE4E5A643 /* ASPageTable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0319B8963465C591687AFFE645BC7C4 /* ASPageTable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 25BDEB129E29246C4BB4044B849B90D6 /* ASPageTable.mm in Sources */ = {isa = PBXBuildFile; fileRef = 48DDC75CC866EBE491AD3724F92861C6 /* ASPageTable.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 25D87433F8998220C56DEB0CDDA167CA /* PINURLSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 529107AAD032EC80C54BE9CDC8EC94AB /* PINURLSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 25F7C6715BCCB73CAA6C20FAE292CF9B /* ASWeakMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 24D8C47FE0E7DA22CB28B45FF4DED726 /* ASWeakMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 26509BF34207E046B32367284B9E8DFA /* ImageZoomControllerContentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA08AA67D939C3E23A4D3312A8ACA70 /* ImageZoomControllerContentState.swift */; }; + 26880973B4644E87C380BBB5E861951E /* ASCollectionViewLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CEA532B0E1FFE30D664CFBE7878662F9 /* ASCollectionViewLayoutController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 26B3AD7B5C5ED0A014DEFA3AA5CBD94A /* ASLayoutSpecPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C7EB412042D3B0B82DDB17C56280EA20 /* ASLayoutSpecPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26CC1A88B18BCEFF176989DDF566FEF2 /* ASDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1B5474379A62711C3A3090973FF8C323 /* ASDispatch.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 2718C849A663ADF0E69B40FFC1C5443E /* ASCollectionNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 19F6B2C5C172044761158C11A9A96621 /* ASCollectionNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 2730E2AB0DF38DB833EF6AD02E788C2D /* _ASCollectionGalleryLayoutItem.h in Headers */ = {isa = PBXBuildFile; fileRef = CB3CC8A51469A1A050DF9202D4ABD37C /* _ASCollectionGalleryLayoutItem.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2799C7F1375B432E35F44F6B2011315E /* PINImage+ScaledImage.m in Sources */ = {isa = PBXBuildFile; fileRef = BDD93100C2924931FBF3E404B81576D0 /* PINImage+ScaledImage.m */; }; + 285F918F7A4896FA40D130FD5F6955EA /* PINCache+PINRemoteImageCaching.m in Sources */ = {isa = PBXBuildFile; fileRef = 574D0A0487078EFBFCF4F03C47469787 /* PINCache+PINRemoteImageCaching.m */; }; + 28A9C06F97CB780536F2C2405DF1E4CA /* ASBackgroundLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AF60023FF5645E71160109652BDEE4D3 /* ASBackgroundLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 28F61DD0EBC89532FF28A6F967B0DBC7 /* _ASCollectionGalleryLayoutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FC078748D3AA3E0CB9EABB51A9790BA9 /* _ASCollectionGalleryLayoutInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 292C3F25A497C5764E033ABE3491999B /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = CBA1CDFAC330F024F79F55928AF761B0 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2984AD51F86779E093DBAF2C5DA6CB67 /* PINAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = A6349CF71BFAF7D4A5704EB8D83E462E /* PINAnimatedImageView.m */; }; + 29CAF11CD62CCBDC701E051CBF424C23 /* ASNetworkImageNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8C41426A4CB5C87B270CAB6661B145AE /* ASNetworkImageNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 2BC2B38EA553A533961723CECFC08DA2 /* PINImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 2075A4B105A9E0F67B8A3420DFBA3ED7 /* PINImage+WebP.m */; }; + 2BEBC2DFEDD5845C56E21A6463822B63 /* ASLayoutElementStylePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 368616C4DF8B8A2508BCA3C152DE6171 /* ASLayoutElementStylePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2BF1C444606DA73A783706F748051F54 /* ASTextNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DA27E6D1F06A57F16EC910BF9212642 /* ASTextNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2C3EE7C1BE5D6BDB615ABD6589CC1A1F /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = BEB872092B992DC253680FAA0499FE5C /* ASLayoutSpec+Subclasses.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 2D9E8318C4E63140067B52E62DFF4B5B /* ASRecursiveUnfairLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 153CDAA7E2893700C4226503B3F7E0CF /* ASRecursiveUnfairLock.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2E1B3B900BECDFD697A94397EB3208A8 /* ASAbsoluteLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D501F0E961A620207729EC46BD2A385 /* ASAbsoluteLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2E4E16EEF78B38EA1F4977CF1EC63511 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + 2E7753DD0798320C098D6F97215F4EDA /* ASDisplayNodeTipState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 796DC49204A7543AA048026D7A6B67AF /* ASDisplayNodeTipState.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 2E8CD8DDE7442B3C033B24194762F66B /* PINRemoteImageDownloadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 301AA79FF07CF4C0F6E48120A66F49CC /* PINRemoteImageDownloadTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2EF0DBBD698C43C660D5C52D387762C3 /* ASImageNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 370CE66493F16C4B60162BC899D50685 /* ASImageNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2FB492957D10701BDFECCA77C563479B /* ASTipProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = A32CFB4D17BCD23C29D1D5787CE32EF3 /* ASTipProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2FD93AFDC2A9F0BE1EEF74E89B5AD84B /* ASMutableAttributedStringBuilder.mm in Sources */ = {isa = PBXBuildFile; fileRef = C250DF90BD78A3A463AF8A46C191D656 /* ASMutableAttributedStringBuilder.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 3013DDB20CC86DBA1FBD4BF107C9EE76 /* ASTip.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A25DDB1BFA6A6D466803A5137028A77 /* ASTip.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 30B53366BF7622BC324BBC3286D51EDA /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A4DCB09556D8E69491C29B81F6717E /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 30E321C7F2B2528CC0DEFA81FEE5020E /* ASHashing.mm in Sources */ = {isa = PBXBuildFile; fileRef = A7E2AFAFBC59C4434EA0F452218F8C42 /* ASHashing.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 30E5220AF082397668D8FBDB2BB4AD6F /* PINOperationGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 523240EAB47539D12567510B8F883DC8 /* PINOperationGroup.m */; }; + 311EEE0E05EAB3E5D744F65588D8FDDB /* UIImage+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 444483F0B2D3A9B3C7257762F9297D60 /* UIImage+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 319FBFD5A5F8BB64B085C15007F1A250 /* CanManageZoomBehaviors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BDB8103640F2CC1D67C9C58171A5E8D /* CanManageZoomBehaviors.swift */; }; + 31E23F58653E80531A771415273BECDC /* PINMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E8C9DEC2483B11E8B516171B7AE19CB7 /* PINMemoryCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3213C2AD15E9B0CEA5DF4C1BAF3B2684 /* logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C263605C9675F6111B10DC6EBA561 /* logger.swift */; }; + 326E08CB331794AD3AC0332E7B4F5DC0 /* ASDelegateProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 220D778DF6D3BB45E14EF18549516AF7 /* ASDelegateProxy.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 329730AC1D8EB74370375033D89CAA04 /* PINRemoteImage-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C9E659D0C8C2D9712FEC2736A469A090 /* PINRemoteImage-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 32E39D4168AA61D28735332214FD7A68 /* PINRemoteImageCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 0836BBF553616112912E10DCA57993A6 /* PINRemoteImageCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 32F74F879E223DC924F2D377B0E0438A /* ASControlNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 803B09D806B71B6D194635CE75C342F9 /* ASControlNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 331FEDE9B0C941A741D0076745ECE9F4 /* PINImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 022D02D7B64CA9E34BA2086AF7BDF23F /* PINImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3364AEA7B40321356FE24B945F836C81 /* PINCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA1804B20C4BA59B74A32AC511B1713 /* PINCache.m */; }; + 33A58AB76D5143C6639B180900E8A4AB /* PINRemoteImageManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 107ECA26011E51E00F0FB2B12FFC1711 /* PINRemoteImageManagerConfiguration.m */; }; + 33AE74DEA0304E22B4B020C037BB4E8D /* ASBlockTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = D50F83AD1942253690114023E7CE92B4 /* ASBlockTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33AFC02D1DDFBFD1EEC47AFD8134C5F2 /* ASMutableAttributedStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = DDEF3F1193C7C7E6815D0965E430ACFD /* ASMutableAttributedStringBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33EBCAF7E4942B6C1E978213D1046FAF /* ASLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 714C8766D214CF2BDDCA14DB63D82CC2 /* ASLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 34529C466F5F797A6DE9080771A0427B /* Zoomy-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B2004AC400F42335B666DAB0028739F9 /* Zoomy-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 34854853C570C98D6E3ACCAA4C7DD1DE /* ASRelativeLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 47D53418A1AF4E0E9F8A9A6A6E85FE2F /* ASRelativeLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 34ADECC6CF4DB77F274F6ED5178FA3FF /* ASResponderChainEnumerator.mm in Sources */ = {isa = PBXBuildFile; fileRef = BEA709AB9B51E31AB78426C3BC827746 /* ASResponderChainEnumerator.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 350592582D2BEEAD29989D3C406D296E /* ASHighlightOverlayLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 97E777762D92CC607C25F3EF65BEA975 /* ASHighlightOverlayLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 354D5F302A89E5FA56123389EE9EF229 /* PINCacheObjectSubscripting.h in Headers */ = {isa = PBXBuildFile; fileRef = D49A19FBB24B7F8EE96F2736AD1B740B /* PINCacheObjectSubscripting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 35F73FFF5EC9D38FFF161D8CC64E5218 /* ASTextKitTruncating.h in Headers */ = {isa = PBXBuildFile; fileRef = 11243C7D597D928BACF6593432FFCF01 /* ASTextKitTruncating.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 36C8E40A9B88DEE0CDE6738E6CE9B613 /* PINRemoteImageDownloadQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = E758EA4E1865DE8FB11FE7DF08146477 /* PINRemoteImageDownloadQueue.m */; }; + 37163A6F77A6128EA54B197A1B6E2AF3 /* _ASCoreAnimationExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 007EA24CB3D0521364C550D47F1E4C56 /* _ASCoreAnimationExtras.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 379C8AD0CBCD05F0AC0AAD83E05058A5 /* ASSection.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC85FED712EC5B803BB64410FA1944AF /* ASSection.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 37BBB02A7D765725890D32944453EB98 /* _ASAsyncTransactionGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B0113958F688610CF771535C447AA8F /* _ASAsyncTransactionGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 383FAE52A9550C9936D6237F7A959AEB /* ASScrollDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 90697248975C12C20D265C8FC2F89492 /* ASScrollDirection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3843A5FD95EEDC8984B03B4AB0872139 /* ASTextNodeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7096E0A9B680A32ABA967518D12A789E /* ASTextNodeTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 386D4195994F9806D03777081DAEADC4 /* PINRemoteImageBasicCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 95FEC909C32BFD96EB1F86C86CAAD03D /* PINRemoteImageBasicCache.m */; }; + 38B66488888B06F1D215DD4E907C8613 /* ASTextAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1E3FE85A4B2BCDA182B605CDB5DBB8DB /* ASTextAttribute.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 39441BD56324DADDA1A7387A039B11B4 /* ASAsciiArtBoxCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2609443EEA2A32EE403E707D0572F9D7 /* ASAsciiArtBoxCreator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 397CBCED265CEF9B598462C78FB412DD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + 3B4BDFF8FC2D4FC9050E5A18F96634F2 /* PINRemoteImageDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 764D542477B60E5C299092AEEED074EC /* PINRemoteImageDownloadTask.m */; }; + 3BC85D01305C01A02D674354EA81231E /* ASAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = BDA4460D90E3CCCCDF6A594AC96AB183 /* ASAssert.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3C31CF98F49970F19686DB9430000254 /* NSAttributedString+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = 53BF3551C5EE1DC95729A01E0E1632BF /* NSAttributedString+ASText.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3C3358F8891B4D0EEC5DBF01934EE2F4 /* ASLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13E6CB8779192BAEF893B4437244A36A /* ASLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 3C5A9FE3D7C7FE22A922753CA96E5C12 /* ASDefaultPlaybackButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7CB9C9311AA6D37B9C029A0C12C4B4E7 /* ASDefaultPlaybackButton.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 3D204BC922D2A57C4467B506DA458873 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + 3D2C49C67BE979EADC17D22BF706D324 /* BounceOffsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27990D3C91F8BA9D332FBE68E2775751 /* BounceOffsets.swift */; }; + 3DD4626268615851397E19A6D6F5E48A /* ASScrollDirection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08256B415C39B30BF9ECE1264B713481 /* ASScrollDirection.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 3E0ADF4FFBF1AEE2AFF6ADACAEFE3FA2 /* ASDKViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = DD1CF1EC74DC9F3B2DB54518639BCC57 /* ASDKViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3E0B594F11B1375A55CC7FB1BE1E7DA7 /* ASTextAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B000E5335F1D299484CA411EAD77450 /* ASTextAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3E3D581B1E51870675E23BD99BF7A65A /* CanLogMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8572FDFE5D32A555792D8D264EBEC9C4 /* CanLogMessage.swift */; }; + 3E66AC6AE52437F25DB9C77B405BF072 /* _ASAsyncTransactionContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = D084ECEB354EC79F4F4DB811D3C5B611 /* _ASAsyncTransactionContainer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 3EBC79D53650CCC93262B12DB26403BD /* HasDefaultLoglevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E130B5861ABC920DB5C7C130B2CD5F8 /* HasDefaultLoglevel.swift */; }; + 3EDE54BDA1749D9AA3F967EEE4C819A4 /* ASTableNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5D5C12E5C2E7EDA156BB9B2EE42C1683 /* ASTableNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 3F032BD5B92DB1386DD5F553C335D2AF /* PINAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF24D2130002A993A0633A50C598F0F /* PINAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3FA2661EC4B4764F8A0BAA3B6911CE07 /* _ASDisplayView.mm in Sources */ = {isa = PBXBuildFile; fileRef = D1FB03D4F024FA0F361CB89A886A04E6 /* _ASDisplayView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 3FF4BD5B4A904AB6FDC3BFA4A77764EA /* ASControlNode+tvOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CBF1A501D9D01565FC9A9FA7C2F0260 /* ASControlNode+tvOS.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 40AE1EFE7405EB78CE80A1AAF989AA95 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + 40F7A9A1246007960D1C10A328562B85 /* ASTextKitShadower.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C8F79D8FCF9015BF86D560DE3589B65 /* ASTextKitShadower.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 4107EE649411835E2A9403AA3E75395E /* ASCollectionLayoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 17C0F831AF0AD17DC6B683449FD9CC26 /* ASCollectionLayoutState.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 41572627C786146E95259AC42812892C /* ASTextKitContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A9434A1F46A9E3864CE96A3F43924782 /* ASTextKitContext.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 41BE5BD614270839466666BEAC31B4F7 /* NSObject+AsociatedKeyForImageZoomControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06DDD98B42182B137D220784A22E6697 /* NSObject+AsociatedKeyForImageZoomControllers.swift */; }; + 423FABDE3A20680EE138D3803DD6F2DC /* ImageZoomControllerIsPresentingImageViewOverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D73CD563E03400418EBC0A4784D1C1 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift */; }; + 42C788E3094CBAAA03EC39561D7181DF /* ASLayout+IGListDiffKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 5018A23014FEB83B19C3753F33FFEFC0 /* ASLayout+IGListDiffKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4404103D44CA3218F025DA315D800010 /* ASRecursiveUnfairLock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D7E831DD0A378B5BBA9E3EB6ACC1B49 /* ASRecursiveUnfairLock.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 44231872CA5D99230474B02A713D193C /* PINRemoteImageManagerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 67744A952643A0AB3D672202110107F4 /* PINRemoteImageManagerConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 445A2C4091D5EB91003D00CA744F69C8 /* ASAssert.mm in Sources */ = {isa = PBXBuildFile; fileRef = 11FC95FCA7AA02C819434E619DB2974B /* ASAssert.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 44F5E8EAAFC519B827079C21092A3110 /* _ASPendingState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 02B7FAE0B0A89921AA60FCD1B1A628AB /* _ASPendingState.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 45051BE690707C36628E0A3162A6655C /* ASDefaultPlaybackButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 306C52DBD27D295784295FD504964C94 /* ASDefaultPlaybackButton.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 45112E474BA6016E05CED490D795AEC5 /* InjectableLoggers-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 4717228A634CE28E966300DE88992C3A /* InjectableLoggers-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 454EC213F2ABCFC7C51C7BC1B2976F9D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + 458959AD13E6AC3374E81F6487F13B21 /* ASDisplayNodeCornerLayerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = D4E478F22E41312C2EE4D3F570D425EF /* ASDisplayNodeCornerLayerDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 45F21A0B56EC7B9577BC185A9ED007C4 /* PINResume.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B342DA9EE3B882BD437A5542477B69D /* PINResume.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 46602671A46883556573D357D8D58179 /* ASCollectionLayoutDefines.mm in Sources */ = {isa = PBXBuildFile; fileRef = 468BEF0C99D14026C3FCCE9045D3FE0B /* ASCollectionLayoutDefines.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 46A6E2A05E106239C6D1B2429E6363CE /* ASBasicImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = E706D8361E42669B2765F7B815C532A3 /* ASBasicImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4775D60B018E3B4BA0C456FCC93A3489 /* ASStackUnpositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 631EFD7F1F37EB5DE9EBBFE915A49FEE /* ASStackUnpositionedLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 4863D9CFD8DF00F75537FC81AC2C1B9A /* ASBatchContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 24C95280DDBF1B216647DC50DD8E35F5 /* ASBatchContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 48AB83373950DF31804839DF7317AEB2 /* ASDisplayNode+DebugTiming.mm in Sources */ = {isa = PBXBuildFile; fileRef = 90EA83CDB56F528D679D861D7FADF2DC /* ASDisplayNode+DebugTiming.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 48FB2FA1183990E558E429461CDF77F4 /* ASImageNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0813AB2B539FBB3C7172EC17D1183DD9 /* ASImageNode+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4916347FD174C3002BE32C86D01422E3 /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 52594DD4EB49DC177D64B179999D001B /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 49175285DAE0F984B215CA4FE269EB09 /* ASMutableElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A98596125EEEC4B752CF6D26D39B317 /* ASMutableElementMap.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4A5D639EB330216C5E0486C9CA40550A /* ASEditableTextNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BBE389DE054D871BA72D30EF0A95A02 /* ASEditableTextNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4A7C54E9E3062AE28473631F67C4A6A3 /* ASTextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 238638299CCBABB2A4FA0768A080732E /* ASTextInput.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4B16631D2EC2D5D065CBB55DC8881D0D /* ASCollectionLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C2812E8C508184CDBAF31A4379A5723 /* ASCollectionLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4B8E788E590ABA95BD8CC4573D0EBFC0 /* ASLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B0C5AF838B291A38952B93A37CA6D83 /* ASLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 4D1738F72E511D8788C448223DFF74C7 /* ASCollectionFlowLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2BA01D0006D36A0A50DA88B677CAC904 /* ASCollectionFlowLayoutDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 4D6326702D2E5445867EDF0CB51981B7 /* Texture-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A73CB612A2B88D87EABFAA2E231091B4 /* Texture-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4FEC6809913A309C1BB3AE70C9CD1856 /* ASCollections.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2C3E4D9221467A6AE8193D74B696E4BF /* ASCollections.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 503122D8D65C663AE2CFCBFD675521F9 /* CGRect+transformedByTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3DC378C69742B7E1C2A8D1B02460DB0 /* CGRect+transformedByTransform.swift */; }; + 50EDFDEBF7240CDF4671942722897557 /* _ASCoreAnimationExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = CEB22121B395ED735216159F1CA578D8 /* _ASCoreAnimationExtras.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 50EEFB8254EAF126BDAF9F4BB2F41EC1 /* ASObjectDescriptionHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3B5DD44288F18DA76B04EEA1C33CB9D3 /* ASObjectDescriptionHelpers.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 51B91F5F6C099C23A0C0BADC9B435BC7 /* ASVideoNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 73AC4D83CEDD69BA236A57352337FD54 /* ASVideoNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 533DDBAE6B86634DC5AC964324AFBE5A /* ASCollectionGalleryLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E5CD5480F273CCD7018C4EFA617514 /* ASCollectionGalleryLayoutDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5367E1DE5A0A1BAB05B32E3C6BD4B9F2 /* ASWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D192702C0F63552D3A3479AC17225A /* ASWeakProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 53C40C404A29C9D36C39EFC2A41CE743 /* ASTableViewInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E621B2AEB638A986D4D7B368348FB9F /* ASTableViewInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5415B24BFD37F00BB5D405BCD49555EA /* ASLayerBackingTipProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = A2CAEDFAB34F305AE5494D35EA368453 /* ASLayerBackingTipProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5458596C6EE471CD495C661E92AA7788 /* ImageZoomController.Factory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40161622AE9EB7912BC3BF1CBBC09039 /* ImageZoomController.Factory.swift */; }; + 55489F9E2C84ABA1DF343520666B7980 /* ASDisplayNode+Ancestry.h in Headers */ = {isa = PBXBuildFile; fileRef = A09FF82F01D38B1FBEA2718AEE09F391 /* ASDisplayNode+Ancestry.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 55DA22DDE15CDE86C6A4157789744B72 /* ASTextKitRenderer+Positioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C1ADF815AD1AC88EAD0E635BB938B9 /* ASTextKitRenderer+Positioning.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 55F66909D00D87259EB4D88697ADF17F /* ASDisplayNode+LayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9DADFC8D98A3FEE0083A1D8E2A124F0B /* ASDisplayNode+LayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5614B5D3B2DD1F30555A9233B65A2393 /* ASLayoutRangeType.h in Headers */ = {isa = PBXBuildFile; fileRef = CE226A57A895770566512D114E6BFEB6 /* ASLayoutRangeType.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 588F5E132A531BF1B16C0FE24359FDA2 /* PINRemoteImageTask+Subclassing.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C4FA8380ADD141C97EB7236C2AF9B27 /* PINRemoteImageTask+Subclassing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5934C09B5C2A178ADD7D0D585AD36037 /* ASDisplayNode+Yoga.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3A0D3879E96DD88097B82C514252031F /* ASDisplayNode+Yoga.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 59ACDCDC7DDCA5D20DB4A8F2BB1D132B /* ASDisplayNode+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 168588F383395609A225C17729EADFE8 /* ASDisplayNode+FrameworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5A5D5F0390336EF5FB4E0C7E3A250AA0 /* ASYogaUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2E1EDF37D5C7392BCBCBC2626230325 /* ASYogaUtilities.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5AA521195197A5269FE3C52EE1F612FC /* PINDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 89CFBF3A3B10B6EDE93CCE993C1D33E3 /* PINDisplayLink.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5B2D3DF94C9F82AB1317E69DB48E8372 /* ASTextKitRenderer+TextChecking.mm in Sources */ = {isa = PBXBuildFile; fileRef = 15E4F72EFEDBF482E6EA7FC3C9B045BC /* ASTextKitRenderer+TextChecking.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5BFC4E12BD19E6A80D098D6A1288A43D /* PINSpeedRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF1C172FB6FEB6970604804FE237F4D /* PINSpeedRecorder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5C4DD97A03493777545E355D09A8903E /* ASCollectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1697C102E28F0ADF18FC253681444445 /* ASCollectionView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5D1C395E767F467B00623F3B9EF05B22 /* ASIntegerMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D754AB94C11E710749C06408EC6AD11 /* ASIntegerMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5D596E9F8BA6D87E1ADD712A13F131CF /* PINRemoteImageTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 89AD76C27E390A5F98261196C2496BC8 /* PINRemoteImageTask.m */; }; + 5E6DD54DC1FCC7FA938B7BDBFA6653AA /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 326EBDBAEB04836A41AA1E86991F8885 /* ASMainSerialQueue.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5EAA850D67988DBDD6DCBE0F03D51DF5 /* UIImage+Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27B7C9717F02B14FD5F36AA14557AB11 /* UIImage+Color.swift */; }; + 5F0259FB38017633D98701913A2EF502 /* ASDisplayNode+Convenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = AF1305A2D3148FEB652C18D895431362 /* ASDisplayNode+Convenience.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5F4662B7E3B0E1B0B9F9C445EFE5FDEF /* ASCollectionLayoutCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3F1C5EEC6A9FC7250D38B875AF12D067 /* ASCollectionLayoutCache.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 5F4B683A5C8770F9092E0F839DC279B8 /* ASButtonNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = C18764D310DCB6C30034EB3C014E0109 /* ASButtonNode+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5F8115BA11746D390E7FE2DA8B4E195F /* ASLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6FA0AF584416D60BE3C121B151A81600 /* ASLog.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 60DE96D7E222EE4EE01E6DDF4710C78C /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03DB36FBE1545B64BB23CA4E02BDE1E5 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift */; }; + 625D5BDB7DC6971A04C2F0CC04E78316 /* ASDisplayNodeInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DF6BA3DB4965D0F13E4DF91222F3D9E4 /* ASDisplayNodeInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 62642C50110C9B6D29E7CEBAD2B33BBC /* ASCornerLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DF39BEE8B1A3AA7DE7BF57F9E71C5EB /* ASCornerLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 63585E8148886E80CB182E3920C51A11 /* PINRemoteImageDownloadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 60F2D5EB7FDFCC0BE3CB468C0D60DAB6 /* PINRemoteImageDownloadQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 641B4519AF9A061FA679FD64B3CB984B /* AsyncDisplayKit+Tips.mm in Sources */ = {isa = PBXBuildFile; fileRef = 303F4D4B9D072C75B58EF0D2D7630454 /* AsyncDisplayKit+Tips.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 6549266D127F7CF008B8120024AD1826 /* UIImage+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = C463CC735CC90CC6C36E6AF98D671B2A /* UIImage+ASConvenience.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 65EFFF712403A158D18F39A945B66278 /* ASNetworkImageLoadInfo+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DDDD167A6A9C02AB6892A227DA6B537C /* ASNetworkImageLoadInfo+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 665AFE433398FCE3DEF4DA527D3835EF /* AsyncDisplayKit+IGListKitMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = B9A1585DD0E56306F2329498432F63E9 /* AsyncDisplayKit+IGListKitMethods.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 667DE3D4FCA166D984EB80E3BD949F8E /* ASImageNode+CGExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = EE7A1B087B94691BF730791439BE3281 /* ASImageNode+CGExtras.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 66B9FA66EDE6CD8FD3B1C5823155167C /* ASCellNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBE5E5CF4C0125FBD1052D5DA0FA70CF /* ASCellNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 66F58E36376855ADDBF863373C4D15A9 /* ASTabBarController.h in Headers */ = {isa = PBXBuildFile; fileRef = C6EEB10F62EB74DDAFD182C55A257738 /* ASTabBarController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 675811F894E8250FD70813BE06DF5E80 /* ASTextKitContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8C92A50FED85091B4E69170C3E055C0C /* ASTextKitContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 681352C165A0A0DE357DFC95EF35D7ED /* PINCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = D2E37F15D53DA5704377A7D5836636C9 /* PINCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 68158F620B989CD7611B3AEA782A5EEC /* ASGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3967FE11381864148284469B3951BC /* ASGraphicsContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6835DC954F0CF2CDF87AF3D95EF3604F /* SpringAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A9EECB4E20FA3E0A3CC8F611CA69F56 /* SpringAnimator.swift */; }; + 6851E1AB040073EBF7F89AE04AF025F4 /* IGListAdapter+AsyncDisplayKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = C1269DFD61BDAA9D7616E24B0189FA96 /* IGListAdapter+AsyncDisplayKit.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 68C7FCDF3699122D51BBB8D181CE2A4F /* ASCollectionFlowLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D4F5A26F434E2EAAE82328C892FBD1F /* ASCollectionFlowLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 690EAE385194D53B290B805C46BA4EF6 /* ASCellNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 142E661BE19C27497AF8807710A34D02 /* ASCellNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 693AD7C903CD68AA67FAD2DF0D3F676A /* ASTextNode2.h in Headers */ = {isa = PBXBuildFile; fileRef = 614DA3C78C8C5DFC5E9D4AE0CE7BFF7C /* ASTextNode2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6966F6D5921F4FAF58B42833254B0CF3 /* CGPoint+maximumAbsoluteValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D66F0C5F3D4DD3B7CA386D3563C254 /* CGPoint+maximumAbsoluteValue.swift */; }; + 6A4E81CDAE9421C4389B34E66572AEAA /* ASDisplayNode+DebugTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 40D046AE2D842A61F6773318B2AED5EF /* ASDisplayNode+DebugTiming.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6A837AB4E8BB2D3161A42C4BE819519E /* ASTextNodeCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D800D50130BA0F8D82C5558F54DDF7B /* ASTextNodeCommon.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6AFFA660CBFFBF81A6DC1F34AC2B9E39 /* _ASCollectionReusableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EB5231AD49D7544AA0B2B2C57B47080 /* _ASCollectionReusableView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C83627E6FAA6773A8F7CF351CAFB99F /* ASAbstractLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 365171A2F8B907C0ABA54E5D81DEC78F /* ASAbstractLayoutController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 6D342FAAF97311745F7FF709965F8273 /* ASLocking.h in Headers */ = {isa = PBXBuildFile; fileRef = 738E3C383FCEEEA646A90093F39D90DD /* ASLocking.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D6BB69C4FAC4FC632BA75AD97D7D2AD /* ASLayoutElementPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = E8A9CD8D77D91D235463968FC1DAEDE0 /* ASLayoutElementPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6DA1B9D0492B013012EC140F453A9C89 /* ASCollectionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4511DC1ED7A4174E351EB4F214894AC1 /* ASCollectionElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6E1760E30C9461F00BEA1F9E0C678A81 /* UIResponder+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D1D44D0CB5735DF9E0EF1C2ABCB9D3A4 /* UIResponder+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6E4E5512E8EC803F48F6D04561EA0A2B /* PINOperation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DF75328C738F4C8E40C3924A1C776D6 /* PINOperation.framework */; }; + 6EE514FBAD36F14E9DB7670A1A371419 /* ASResponderChainEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E7883E00BE5AA81AAE8BD1C5407224B2 /* ASResponderChainEnumerator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6F0D7C379DAA9767920055697FA3B94C /* ASDisplayNode+AsyncDisplay.mm in Sources */ = {isa = PBXBuildFile; fileRef = 82F2FC1618232C6338E87A6A00200C50 /* ASDisplayNode+AsyncDisplay.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 6F310E7B5C2D8AF7297A422F050BFDB9 /* ASYogaUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = C61A4B82B4BA5097E9F686A1948C1EFC /* ASYogaUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 70981CA6A1DD10570E34DB778400D44E /* Logger.FormatSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EADEF54394FEF3203A0D14FB0FBB32E /* Logger.FormatSettings.swift */; }; + 70FFE5752D7735FF6DA612721FAF1AD4 /* ASThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 23A34852D7571C40B1F57F6978C437C4 /* ASThread.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 713DAEE94040383AD0A64FE5E1C6E0D0 /* PINRemoteImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FB6F534B1401FE906AEF92CCF6A339D /* PINRemoteImage.framework */; }; + 715A56F9131273D746C866720B84F7FF /* NSArray+Diffing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 56E6B6A59DD9BAA9AF2C4608AB94F0C1 /* NSArray+Diffing.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 7185AD0B6E50617EB5B063D049F7381E /* ASNetworkImageLoadInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 848FD9809F9E6E909227DBA5454D0642 /* ASNetworkImageLoadInfo.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 71C78052823AEF756093D47135DFD7E9 /* PINOperationGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DB890B5C2AB3082392D9AB6F63D1103 /* PINOperationGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 725A23DC02BF12DAEFD17D9DD1C19537 /* ASDefaultPlayButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6F57D723495FFB4BA8278626AE81835B /* ASDefaultPlayButton.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 7367521E016788B60D3B821852CC1D49 /* ASControlNode+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 3827902523392E04E0D92EE4073D9308 /* ASControlNode+Subclasses.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 74242DB7DEB36F897B59CC95AED2BDAE /* PINImageView+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 695CBAFD35269D7D30D7126BA1A9FE5C /* PINImageView+PINRemoteImage.m */; }; + 742E9673AF159AE10F13506C910DA072 /* CGPoint+valueInDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2A96E21690DBA5F5E4DD8C744A598A8 /* CGPoint+valueInDirection.swift */; }; + 743030AC14DFBE803BDE5EC37D25C31C /* PINCache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 406975D5F17381231A901E0D62D7A138 /* PINCache.framework */; }; + 744967C02A56404990BC6E88C01BA548 /* PINAnimatedImageView+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C602B3BA1E2B5E8FC405E54B8C10F5E /* PINAnimatedImageView+PINRemoteImage.m */; }; + 7485A8427B78F4D0D38AF63015919793 /* ASElementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52202AAAF785699FB3C841AAEB80C544 /* ASElementMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 74A2F87A0316F3AACB1B416593D49D4B /* Pods-Zoomy_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 995ACD99A6A9DAE10AB6D1FD8C20BA35 /* Pods-Zoomy_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 74E1593D7726C6250595B3640FC6908B /* ASTextKitEntityAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8326C4C67628C534D2FB0AC51B6CA084 /* ASTextKitEntityAttribute.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 75CF1C3C6791888DDF1C73573D7D5509 /* SimpleLogger.Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1123D4B16476D633BF2D6511A5A81017 /* SimpleLogger.Settings.swift */; }; + 7615B92004681A1F0CE6E7F61389AC91 /* PINImage+ScaledImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BAD4FB41EAFF0AE7B2153EF48C5BB88 /* PINImage+ScaledImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7662C10817C380C0792B383089502CAE /* PINDiskCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 677EEE3656D43FF4C34D547EC105A5AB /* PINDiskCache.m */; settings = {COMPILER_FLAGS = "-fobjc-arc-exceptions"; }; }; + 766AFE24E8D800787DBAAF4EFA1C86D8 /* ASVideoPlayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F66832F49B3C0B4A07085F98189176 /* ASVideoPlayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7682DDBF21A55C03731203EDCBDFF27B /* ASCollectionView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = BC90C657CBDF1FAC23AE4269E0F58A3F /* ASCollectionView+Undeprecated.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 781DA851FF46FF8A30B48C5E8115FE1B /* ASTextRunDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = DCB893AAFE47BD80E8CC7CC44A00CD56 /* ASTextRunDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 78832930615717444B99AF06239A0497 /* ASTipsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2C042B669A64064D7FC3E52DEBA0E071 /* ASTipsController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 789C7B17F586529CFB16874F11D0612E /* ASTipProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7B1FFF4BE75E530F7F98CC130B827756 /* ASTipProvider.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 78EA95A196E301CABCA9B8EF56972FE5 /* PINRemoteImageMemoryContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A338D2C7BECE0973CC5A926E046FBF5 /* PINRemoteImageMemoryContainer.m */; }; + 792C265DC6709DF747E801A984353998 /* PINRemoteImageCallbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = B4877B07FDD3DFF09B753FA5D3BB2FD9 /* PINRemoteImageCallbacks.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79D79C15A67C285A4FE840C164A61EAD /* ASPINRemoteImageDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 97CD5B552AABAF73943AE088CCB7BAFA /* ASPINRemoteImageDownloader.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 79DEAF233C0FDF9487841F3A5226FE89 /* PINRemoteImageCategoryManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 7303F3582F8703C93C9B86724B41E492 /* PINRemoteImageCategoryManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7A541079985175ED988475511FE5F2DC /* PINCache-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B451A50AAD10F605219DFD5A70CE2156 /* PINCache-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7B226EB7B088CECD2ECA145103392D56 /* ASControlNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = BE7824C8E50170F8A0526B9205882F3B /* ASControlNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 7BAB8B3B6369EDFA0C7D13F60FBC6794 /* _ASCollectionViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 08A05187C58CF3FEFE6C3FD04038BFD7 /* _ASCollectionViewCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7C9889D2309D0F679BEFAEF035704D5B /* PINRequestRetryStrategy.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E2F80499CEA6B33FF927221C7377BC /* PINRequestRetryStrategy.m */; }; + 7DF36B3FA296898C2CE708F7A547929A /* NSIndexSet+ASHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = F06F5857985D77588F3293CCCB51FC40 /* NSIndexSet+ASHelpers.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 7E51B87E055DF9E8C348B479D57C9E5B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + 7FD4280D0F3552F62182C2797740B7FA /* ASConfigurationInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57A3175B4809F18AD11501B59B1C4D9B /* ASConfigurationInternal.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 80C24E482ED0EC7870E04616ECCD439A /* ASTextKitTailTruncater.mm in Sources */ = {isa = PBXBuildFile; fileRef = 59576C4206771C56B34C93A2DD701D91 /* ASTextKitTailTruncater.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 82E0F28243DC81433820662B2BEA008C /* ASTextKitFontSizeAdjuster.mm in Sources */ = {isa = PBXBuildFile; fileRef = EE6B4FA98E3B71705FE19CC355592CD3 /* ASTextKitFontSizeAdjuster.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 835F0D17D2FD72B5C75AB3C73665B952 /* _ASAsyncTransactionGroup.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0B82A3E466AAE96E03B8609312FAF2F6 /* _ASAsyncTransactionGroup.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 850F458B09973351610ABDB656D8B509 /* PINOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 298080512F81BC540FE52192C678D1FC /* PINOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 85CA625022EC17DE0631D5B55F084FB7 /* ASConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = FA82910B21B45CA35C2E513D8126CBA5 /* ASConfigurationInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 85F06D91CFD3730D46459D65E5BABCE8 /* UIView+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 11F9C53368EC8719F7CD5EDC99DCD3B4 /* UIView+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 861967ACB77A0D10A198A15478A9FE5F /* PINButton+PINRemoteImage.m in Sources */ = {isa = PBXBuildFile; fileRef = F5AB42EA0047BCD585B5B0401C2E88B3 /* PINButton+PINRemoteImage.m */; }; + 869A0AFC6E446D9559F81B9DE55339BB /* ASCollections.h in Headers */ = {isa = PBXBuildFile; fileRef = CDDA219ED517C33E1056E0948A145ECB /* ASCollections.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 882C68A56DB9AAA11032882286153B46 /* ASDisplayNodeExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 67856706A15072A489163BBFBED7EF43 /* ASDisplayNodeExtras.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 8875D45F4D5B2ACA819F1C5BD2B64E35 /* CanLogAtLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAB7AEB454892E87F9B1C2F04DCFE0D0 /* CanLogAtLevel.swift */; }; + 89C8791BCA6D98034A61A54E5FD9D4AE /* ASDisplayNode+InterfaceState.h in Headers */ = {isa = PBXBuildFile; fileRef = 21431E3065B17D68BBAC5602987EEF90 /* ASDisplayNode+InterfaceState.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 89CCF29068794758917D5BC53196B619 /* ASButtonNode+Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 9088145837DA903D0C458572E6EF9C58 /* ASButtonNode+Yoga.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8A2E0B626887AF013A7F84103DA0A836 /* ASDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = FC6C539347674A43A36A914B13136CF0 /* ASDimension.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8AB6AEE4DF780E7CAA39A698FA4E7634 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27A91CE2CB94BB7B3F82B020DC588A81 /* CoreMedia.framework */; }; + 8B886D15BFD525FDF4FC0FD05C4E352F /* ASCollectionLayoutState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86164D80FD547DBCDC04ACDD06E541B5 /* ASCollectionLayoutState.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 8BB520FB3735FF2ED6F041EB6BD6EE0D /* ASStackPositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = FA621A2A3717016D8818217BBCE87FF4 /* ASStackPositionedLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8BE298408DCAF8348629CC2FD95B8883 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA7C2CD848FACF3605201842A31CAE94 /* ImageIO.framework */; }; + 8C31797394C8EC3AA2597206372419D9 /* ASCollectionLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = CC905E638224A0B0E664476444B10514 /* ASCollectionLayoutContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8C59DA4CCC93CE415C2A15348CBFC83D /* PINRemoteImageBasicCache.h in Headers */ = {isa = PBXBuildFile; fileRef = CF3F18E47D07B321917AC4271C1ED51B /* PINRemoteImageBasicCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8C871044D0661199D892CAA1A56975A8 /* ASImageNode+AnimatedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 760CAD4BE95145071691BD6C8BEAA67D /* ASImageNode+AnimatedImage.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 8CC8BAD4EE5B282E015D339880FD4CED /* CanLogMessageAtLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E805F69FFCA26465321093F9D504AC2C /* CanLogMessageAtLevel.swift */; }; + 8CF2DBA98444B46D088E8FC193E26B9D /* ASAbstractLayoutController+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F56C6B1FEAADDD67177C4FC528C76323 /* ASAbstractLayoutController+FrameworkPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8D1C38CA2C15929280CC6482BFB46216 /* ASWeakSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9E2503BEFEB4448C0FA1DA31215EB7C1 /* ASWeakSet.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 8D5273A0FC56233E209A44A5FB5FC15B /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 19C46A1F5BE9058D1B31FEFC6B3EEC63 /* ASCollectionViewLayoutFacilitatorProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8D5C3CB94A4EDD4BD08D8A18A9BD7356 /* PINImage+DecodedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A6A497EE4715107B9947A54E6593162 /* PINImage+DecodedImage.m */; }; + 8D8DB918AAA7B2598B2A1633502471E2 /* ASTextKitEntityAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = C158E5545E3BD2D22EB64B23FBED2C7E /* ASTextKitEntityAttribute.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8DC6B9827D1C470510DC8F6E2F8B7086 /* PINAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = FF1C4282E2564807E444F007450542C7 /* PINAnimatedImage.m */; }; + 8DE9CA21A7082FC2A937E3DBF78E3A0F /* _ASAsyncTransactionContainer+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 65133D87AEBB73F5FF7A1A7CC904EE8A /* _ASAsyncTransactionContainer+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8DF538949C4DC97E959103D2208F3C69 /* ASCollectionViewFlowLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 761330E4F43F9ADCCDA54B430683FEE6 /* ASCollectionViewFlowLayoutInspector.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8E1A6C378C8BAAE59B60B4F9FB24AA7E /* PINOperationTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = E4BE922521021592DF0960FC9290CA4D /* PINOperationTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8E2EEA6890AA83F0C1689F5273B37B8F /* ASMultiplexImageNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 41FA311245598CBA5457902CA98F6E61 /* ASMultiplexImageNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 8E50095CB420ADE04A0C30481174C03B /* ASMapNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 9445659F6DDC49F7C027607DDB4B67FB /* ASMapNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8EDB472A1578F25B749BE234A65CAB68 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B2FC7355BCE92FE29D5BE9B82EA04A2 /* ASEqualityHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8F3296AA6F7126C161055219C1D70548 /* ASTextKitCoreTextAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 915AA3BE58BFD111EC7114C0CB67E360 /* ASTextKitCoreTextAdditions.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8FB8E71EDEEC0BAF253697B14D1A562D /* ASTipsWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = FE5C5EA569981CB127DA87B026FAE639 /* ASTipsWindow.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 901059B0F79E50EA1BDACFD9B1A9D5CF /* PINDiskCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B067FDE9BD6960EBEA76FECAE06AA589 /* PINDiskCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 905B6202C6ACB27DA5B734CD0EF6923B /* ASObjectDescriptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A639AABF7D211E360C74CE4CC936E311 /* ASObjectDescriptionHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 90A83F1084AF8045B4B8EB567B188C4A /* ASScrollNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46CD0F5DE0D2F59A5681151F4D1EDBC1 /* ASScrollNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 912138EAA142AB646C0AB9E4CDDFC505 /* ASLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 13B363B9CC87A3361E75819CA2B9289F /* ASLog.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 914D6D51178B6E7DC511BBFBCE5B8C60 /* ASTextLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EFB738992A1ADC2BE3751D558350E17 /* ASTextLine.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 918B6F04B2ED6C34247F3355BB118462 /* PINRemoteImageMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 1431CB6DD8433797E27E18B00DA74313 /* PINRemoteImageMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 925401BD47D7A9AB180C1B3630BC0980 /* ASRangeController.h in Headers */ = {isa = PBXBuildFile; fileRef = C74FC41E348067EE93ED92F12742298D /* ASRangeController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9268301826042884BD37C81E02D6AA0C /* ASTextNodeWordKerner.mm in Sources */ = {isa = PBXBuildFile; fileRef = A3824C2887A3C7EC685E7EF3070F9A4E /* ASTextNodeWordKerner.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 92B7317ED317260E96CC6D658EFAA5F0 /* ASCollectionLayoutContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C22693BC29DF70A295F36C2C6CE01D4 /* ASCollectionLayoutContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 92DD534C4085F25142F0ACFD4B930719 /* ASMainSerialQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FD5B4CECF91B0EEB87A10C231F414D2B /* ASMainSerialQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 938190A76B28D4FBC6FBD6EE39D3D21B /* PINAnimatedImageView+PINRemoteImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B088323CEDD9CEA3BE4A747A5B7678 /* PINAnimatedImageView+PINRemoteImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 93B61C99B25B247897629D42186F02AB /* ASPhotosFrameworkImageRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E886463829E8179D30A3CC87E9F971C /* ASPhotosFrameworkImageRequest.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 942B48F3549901BB482B4861CE2FF178 /* ImageZoomController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7553FE85837FFE5E024123DA400A5BB6 /* ImageZoomController.swift */; }; + 9481A617FEFD1628356CBB00160C2FC0 /* _ASDisplayLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B5DFABF4BDE70BA28458B972B220A13 /* _ASDisplayLayer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 94E0E3DE8E35A8EE40E20D8A0B253561 /* PINOperation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DF75328C738F4C8E40C3924A1C776D6 /* PINOperation.framework */; }; + 9572408CB866579D8EEFA59F946EC4C5 /* ASLayoutTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = E9206743DCC6A30DA6327E9E79F04B39 /* ASLayoutTransition.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 95B92DA06C709481C8E996BE378BAF05 /* ASTableNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DAE31B940FABACE013CA45FF2FDC046B /* ASTableNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95D49A06D8AAB718A13FFF1A29B6F6FE /* ASImageNode+CGExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D3E8FFD05B04AEC48C46759AA2FC4E3 /* ASImageNode+CGExtras.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 96941E07E408BDF2122A01A926C0D52A /* CGRect+Difference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 276AB991EAC927FD7C3D0F3175E37042 /* CGRect+Difference.swift */; }; + 9798396EB28775D2D47B9AB4E5D761A6 /* Pods-Zoomy_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6786AB9FCA35EEE185C0A027621E7653 /* Pods-Zoomy_Example-dummy.m */; }; + 97B21F896732B315973456E97591AA04 /* Pods-Zoomy_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 97917796797A60F0392794674DAFD64E /* Pods-Zoomy_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 982632D85E47F99F7181D8F921276FC8 /* ASWeakProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 64331C191E00E170739F31033B58DE07 /* ASWeakProxy.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 98DF10C729D708E8B23CC3DE227AC5BE /* ASImageContainerProtocolCategories.mm in Sources */ = {isa = PBXBuildFile; fileRef = 340A9CEE164056E549AB70B491ABB841 /* ASImageContainerProtocolCategories.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 9A7E5CC0B063C1F1B56B4864E262C508 /* ASTextRunDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6950A957CBC973B8CCDA5898C7B8DA83 /* ASTextRunDelegate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9A7F2B5821CB7EA9AD72F2FA5B67D152 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + 9ABA4A11DE428613126DA887698C5770 /* ASDefaultPlayButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 595AC5EED6C4EC88217327C18B6CAC62 /* ASDefaultPlayButton.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9AD75CD02E114BE9834EF4E9DCF8FD35 /* _ASCollectionGalleryLayoutInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E86488B04A57D96057DE295100FCB4F /* _ASCollectionGalleryLayoutInfo.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 9BB40B9E5A27F0D228FDA2654B90A0C6 /* ASCenterLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 7001D920A126D34017D9904AFB7E7953 /* ASCenterLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9BB8B7D153A17A4341454EB34059F2D9 /* PINRemoteImageManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BB21D41481E7275F0290AEC1A3596C4 /* PINRemoteImageManagerResult.m */; }; + 9BED2B15E515CF1FC8DA1779587024AC /* ASPagerNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = D0B846671C568323E113112E28C84E3A /* ASPagerNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D2156F8882790A1A11AB12D4CE15B63 /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E360A0A97628D2F2F2CA7508A2A54DC /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D3FF8DEE22B8C7BFB7A66C333F45B92 /* ASImageNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6A7F6539EFE7A2DEBB6CFE6B7C4F7BE5 /* ASImageNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 9DB3E03C376FC722E70B094C2DF85DC2 /* ASStackPositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0B89AC0CDBA02149E8DFBB8ACEAF0CB /* ASStackPositionedLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 9DDDBA392098C8E92D303321246E4A15 /* IGListAdapter+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = A2C7DF35D1B0CC4FC09821434405BCEF /* IGListAdapter+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9DF12A4EA63E693047BC33E9E9FB3458 /* ASLayoutSpecUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 85C3AB3ED77627F864E584556D9B3B4C /* ASLayoutSpecUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9E03D7C1EB8441DA4301C7E83D9A81FC /* ASStackLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DC49CAEDA64A6918B1C646A7903EE50 /* ASStackLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E3882ED3E01A3E7A88E9667C0A0636E /* ASTextLine.mm in Sources */ = {isa = PBXBuildFile; fileRef = DDCD3C215394710BFCE24A682B80FD0F /* ASTextLine.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + 9E6C79BB56B41FFA1665D1E22479ADA2 /* ASMainThreadDeallocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FFBC5C72774055D3AC41F455A190BA47 /* ASMainThreadDeallocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9ED8020DA12D0C5DBB23C41412BC265B /* ASDisplayNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EEE47F5587BC9E53C27A71C7BE04F1F /* ASDisplayNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9F8BD0381058FDEDA5F0671FA6B3A02B /* ASStackLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3A7A6660529033C8FB462698E66D5056 /* ASStackLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A050FC9032EB0721F865B1DC6AACECE7 /* ASNetworkImageLoadInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BF5302E3309861B195B9B558D3E4869F /* ASNetworkImageLoadInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A1879D2E926B3B4D0434F59C3CFEA7E4 /* _ASCollectionViewCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4915512699D90A7C7C29F8F493235B79 /* _ASCollectionViewCell.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A23A686BD3E5A1A45732474F086E5108 /* ASExperimentalFeatures.mm in Sources */ = {isa = PBXBuildFile; fileRef = A85BDA95A647F56CD7259E121D6FA99A /* ASExperimentalFeatures.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A247EE1D278372734D41DA53BCC96820 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A8E2F46E8351A43B40AFBB4C8BEF3AE /* UIKit.framework */; }; + A248291B4CDBC90A07C1BCD8726C6CBC /* ASCollectionViewLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 18F1BEAE413D70F9613D56431D07F05C /* ASCollectionViewLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A27474180106AAAB41F2871304AC64CC /* UIResponder+AsyncDisplayKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 721C9415CD678F2601E830BE4F543FBE /* UIResponder+AsyncDisplayKit.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A3F4FE270937507D945DC440C5B3926E /* ImageZoomControllerSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50A604616BEE784281355A14AB4924B /* ImageZoomControllerSettings.swift */; }; + A418F40185DE480BA18D77831E3C9FCB /* ASTextKitRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8DE6B6E689A78CB6F2E92F79BEC7E0 /* ASTextKitRenderer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A42EC5DE809DA43B92C0A1FB1591A823 /* ASTextLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = C8AF5F4BB16D9D38E6011A150CF1DC25 /* ASTextLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A43B3297E738E64DFE93D4CE2C81D24A /* ASIGListAdapterBasedDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = A3139E8FDADE2AA15C6B526F491D387D /* ASIGListAdapterBasedDataSource.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A468E4B8A47DCEC32494D8A69DAD4F2D /* PINCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 19CFFC5B9E6CC2B79A757940780E4809 /* PINCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A616785B7772BEEE063DDDCC1A5C06B6 /* PINButton+PINRemoteImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 2321BFDF7A7BF190C1DCE0E4D175DF36 /* PINButton+PINRemoteImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A62703EF376B85BECA85A817C34DAEF3 /* ASTipNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 550B11CBF85493C4523215E0EA060AAD /* ASTipNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A655F6C0A8C3CE5A1554C2CCDE7AC866 /* ASLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = A289C7402C699BD2D20E8279A1D473D7 /* ASLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A6DFC86F9D280E7B7F2E025EFCE9EC91 /* ASStackLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AE225CFAAB0B6186AECCF6530A1C315 /* ASStackLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A72A2291E3F8C3EA7163E6C3AE2EA377 /* PINOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E5A50B85249AF7029C56D5811BF80F3 /* PINOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A7319DA9AD51B4B7EA19086A54DD05DB /* NSMutableAttributedString+TextKitAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 30A71EB2149D0A7CDCA3CA7E9039E3AA /* NSMutableAttributedString+TextKitAdditions.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A731B930111DDE6D8923FBB8664602BE /* ASTextKitAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8645412BECF2A0A622A033A39E216975 /* ASTextKitAttributes.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A7D8E709A23130883C176E7E6572C392 /* ASRelativeLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = A6C94B27A14D01BA956D86F321DBFF8F /* ASRelativeLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A86B4CF5B6E0E90E2002EFD6ECA2E74A /* PINDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F70B8787ECCD2A332EB261E7189325E /* PINDisplayLink.m */; }; + A8DEB1E7C5738E83B9EB996DF3B6B780 /* _ASTransitionContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = BF015D61C4F514CD102521B65306C0DE /* _ASTransitionContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + A93E5D1247E109BF74D6E0E0C56A1CA2 /* ASAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = C9B95674F1A017DABD24226712B9D591 /* ASAvailability.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AA08E3A01738ABED66294CFED9B6232E /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3518A0BB390B2AA90F7647C5B8E71E30 /* NSIndexSet+ASHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AA177091C108492974D400BDB1A1CD62 /* ASCellNode+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D233C7E013C07D0389984F3466CB2AE /* ASCellNode+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AA32E52485890D5826877152E1486D18 /* PINOperationMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A3E448B9053C61DFE2DFCF6CBA4ACA7 /* PINOperationMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AA38AD6092975ECEEE385AE0E53A830C /* ASImageNode+AnimatedImagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 43DCE70B2460DEDE2FD73D6A661057E2 /* ASImageNode+AnimatedImagePrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AB100DDB742EE0376A45715B42344509 /* _ASScopeTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = B92BC147B759930674C603C4E1C3555E /* _ASScopeTimer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AB48ADC61226FB5C1BC8D659EAF750F6 /* ASNetworkImageNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 17739224B8FFBBFD4A919676A9DB5B99 /* ASNetworkImageNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + ABEA1AED8D9E7FE95885384AAF7786A6 /* ASIntegerMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 88F59C80E030B1D3C2C1D47FFBB972AA /* ASIntegerMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + AC2E392B90F75B9B0B877513955A123D /* ASDimensionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC0FF9654DDE91AD4E6B491A1132129 /* ASDimensionInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AD229AEA4A55B61BFAD9F9520B4AA43E /* LogLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8935CD3A0EBC471E7D637DB30BA926B /* LogLevel.swift */; }; + AE00B7F987BD71B5EFD51D405455D667 /* ASCollectionLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 89EA7BCC1CA29B222E7DC77185E5C1CA /* ASCollectionLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AF55C78E39FBB0158FDD1F04874978C2 /* ASAbsoluteLayoutElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9ABD6F3FC6B368A8ADD0AA7A57D95A2F /* ASAbsoluteLayoutElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B04D1648CEB49BF9A215EB68F782E66F /* ASDisplayNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = B68757212BC40EE9FAA2CCF6917D014D /* ASDisplayNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + B0917E444B1352AF7285C09EF420028D /* _ASAsyncTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C20F8B4080DCC6F47FE97ECA3E5486 /* _ASAsyncTransaction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B0E599A3B72EBA636823B6322F4CBF36 /* ASTipsWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6FAD6EA5CF728CE7EC0668E10C7324 /* ASTipsWindow.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B1103DF2D4C2767291DD23DFCEA33024 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D4435A927BF442E68357226A04D7421 /* Photos.framework */; }; + B12E5975BB9E7CB69C0C0E40564ABAFB /* ASCornerLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 12FC3E52F0ECF3D85BF407DE1BA0C960 /* ASCornerLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + B137969B8A651DA1148DEF66C0E26F73 /* ASHashing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F11697E2E11491618C74B039E70FF8D /* ASHashing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B1EEE6908F5B5C8DF426C37C012EA033 /* ASTableLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F754CCB8549BBB25671573986F6C65 /* ASTableLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B205161CC6B478855EF36E244F0B2DA8 /* ASContextTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = C6F40F1552ED00CC77D7799621E479C8 /* ASContextTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B2E9AB96E82BA908122E38CABFFC981C /* CGAffineTransform+transformWithScaleTranslationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABEAEBF38D032F544B343E700443A9D /* CGAffineTransform+transformWithScaleTranslationCenter.swift */; }; + B4419404D375692A51B0D095CAB19B67 /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC31EF58C1CD0626B658B072A7EBAF8 /* ASBatchFetching.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B487EEBAEBECA362C0EC6EE162A99EC3 /* ASControlTargetAction.mm in Sources */ = {isa = PBXBuildFile; fileRef = E998BC7957EE5F98E6C31919CCAE829B /* ASControlTargetAction.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + B53BAD4FEA26F027B02C817B0D56B03F /* ASCollectionLayoutCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D30461653DA6AAEF282297EADDE6C6D /* ASCollectionLayoutCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B5563B5BB14EBE69B0684B4C5A96F51A /* PINRemoteWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = D8AEF5A40C43AB90E6B7ED37BB01E1F8 /* PINRemoteWeakProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B62E2950A573C90432FB3A213E455B47 /* PINOperation-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA7F456BF4EFB86CEC78435D24C3393 /* PINOperation-dummy.m */; }; + B6FCFB22B26A8AD8B89DFAEAC29E0712 /* ASStackLayoutSpecUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EAF61F88391C9B13AB0AE7D2ABB1CDF /* ASStackLayoutSpecUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B70B74682AA34996E8CB2D683505E107 /* ASTableNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 39628548B97DE9F4CF62A1084EFDC199 /* ASTableNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B74E2B68A0C6A8E73F27F0EB5B7695D1 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 92C807BC6495BAE35DE79649C8299695 /* ASButtonNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + B77EF1662C95CF840BD1498F309E8FFC /* ASDisplayNode+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = A49EDF562F5CD661061E25A7EC26B58C /* ASDisplayNode+Subclasses.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B878FFB40DC743FA707E282E2F66C060 /* _ASDisplayLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = FBFD8FA4FCE93DB01B5963643900A267 /* _ASDisplayLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B9D87848BB35AC1F9280D3035D0E2BA4 /* ASCollectionNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F45FF692CB5E624BFFD980CA029E126 /* ASCollectionNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BCFF513947E0A3BA88E07AF5CE09F292 /* UIImageView+Zoomable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C638CF5711825D56D2E5DF07B0F1D6D /* UIImageView+Zoomable.swift */; }; + BE96104ACD0169003A3A222039106C33 /* ASVisibilityProtocols.mm in Sources */ = {isa = PBXBuildFile; fileRef = E47C6BB78AA408F7C35EF60421326F79 /* ASVisibilityProtocols.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + BE9C538F9315DBDF8511D7B1C143276F /* ASBasicImageDownloaderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 03ADCD0D9AD000A2C92CBC5FFF6E8F97 /* ASBasicImageDownloaderInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BEB3FA36F7395B27F36C4784927C3CFE /* ASBaseDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B385DAAFF0820A00FF000415C6DF6A /* ASBaseDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BF2296DF6290E9C557FF126C8EBBAA7F /* ASTableView.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2AFE0C39F1F92051B063681E2F546D3 /* ASTableView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + BF6DF4769ECC4026C46285CB77452357 /* PINGIFAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 19BEACB67CAFEBFC1ED66A82A7CEAC6C /* PINGIFAnimatedImage.m */; }; + BF793A7E0F25CED19582524BD92EA327 /* ASInternalHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 372E2B51845B9764F1568E5E09EF43FC /* ASInternalHelpers.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + BF8095C5CC9C0A19DB54653A650E6DB3 /* CGPoint+dominantDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA3C2F847A27247611C3DBD2ADB2A71F /* CGPoint+dominantDirection.swift */; }; + C0A4A044D33E54CF070FA523D6FFA5AC /* ASDisplayNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 31504EBDF705C4C91C4E481E42167F36 /* ASDisplayNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C1D9DF1192508FC8B1DB84C55D1E7E98 /* ASTextDebugOption.h in Headers */ = {isa = PBXBuildFile; fileRef = 012FFB5866BEDA74EBFDE3FF86B46104 /* ASTextDebugOption.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C1E1845DA59006D300466D68C4A6F56F /* Texture-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E8547225274D91482FA087FFCE18E18 /* Texture-dummy.m */; }; + C25457E2BE17FD066A98C816D2752261 /* ASStackUnpositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E68C30C5EACF8A5292490A67CA0F259 /* ASStackUnpositionedLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C2B195B9AEF986D33CFF546944B10CDA /* PINRequestRetryStrategy.h in Headers */ = {isa = PBXBuildFile; fileRef = B7DEDDDAA6240649B443BDBFF9429D77 /* PINRequestRetryStrategy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C2C213FC002E05563E7A5E1688008092 /* ASTip.mm in Sources */ = {isa = PBXBuildFile; fileRef = CEA675A20EAE7B49521E742D5681B170 /* ASTip.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + C48CA75F831753B49D4987E98DCAD48E /* ASTraitCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F59C6A23784A24F14DF9A84E27DE123 /* ASTraitCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C499B5868927409608468028A8408838 /* ASWeakSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 43869A044BD5D3313051C1FB0FA1CC40 /* ASWeakSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C49B74B05E2ECF40545BE26D82908D69 /* NSArray+Diffing.h in Headers */ = {isa = PBXBuildFile; fileRef = 27CF84EEF4ECAF9F8FDB5259AB280B10 /* NSArray+Diffing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C4AD7C4F531DA9DD921A1218FEECE798 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8577C9C2A1140AD10A4FAB08CFA88B0 /* Animator.swift */; }; + C54D1790AEDE01C590686294934A1E13 /* ASRatioLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 91BFC03CE4B616D14105ACD4A4486EC1 /* ASRatioLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C5F8FA0CB5BB90D56C13A44180EE8329 /* NSParagraphStyle+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = F53D4B6F4C18BE99E9336EAE1707A8DE /* NSParagraphStyle+ASText.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + C5F9B33244F7F718765BD17232268474 /* PINMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CA0EDA238063FF0C538D31F2961EAA5 /* PINMemoryCache.m */; }; + C6280E10614BA6CF600C8A80BC1C426E /* ASVideoNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA716F6CEBD4B6202124CCF837017B5 /* ASVideoNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + C75C96A4CB5497109200277BC3B826AC /* ASTextKitAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = DE1F7FC0245A875D45AC0863A15BD969 /* ASTextKitAttributes.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + C779ACC80C0E385B487DD2AF73C7B629 /* ASDisplayNode+Ancestry.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9556208FA82CB1183791FB5EB2A58D5F /* ASDisplayNode+Ancestry.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + C782835223517924A26F0EBFEA0C00DF /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD6B76E7CC9E6D168E1CA155B92BD27F /* AssetsLibrary.framework */; }; + C7B9FC1B5CFDD47203D8019533E52F0B /* ASPendingStateController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F701E64DB403DD2CAF9D8004138DF2E6 /* ASPendingStateController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + C819EBDDE5B4938A862427E81C9B66E9 /* ASCollectionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5DB655C78F3CA1A91002A40F883065 /* ASCollectionInternal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C8CF437ABF283BBC35D39F66A92F7895 /* ASLayerBackingTipProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED6036BDF81C2EFDD33A26E96FF6AFF2 /* ASLayerBackingTipProvider.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + C959FB55033C5DE24B6B14315BCD441B /* AsyncDisplayKit+Debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E96667745230EA660158A21EACF1E3F /* AsyncDisplayKit+Debug.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C9C824BB23E3DE352523EC1811E6C2CF /* CanBetriggered.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE75587CBB8EE0DA0491F98A06B0181 /* CanBetriggered.swift */; }; + CA5853666CACFF05F38A33B2E5DA1949 /* ASOverlayLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 56F9B8B1351E3504AA1167C5A3F2B8E5 /* ASOverlayLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CB6EF8043EBA5C2100A53E6547E7FBD5 /* ASDisplayNodeLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 371B020D432D68BA6D7638A16BE2D91A /* ASDisplayNodeLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CB74C471FCDF99CE778F9F12A435D480 /* ASTextLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 633114E3879F0F946FFC6622C69D9C57 /* ASTextLayout.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CBEBD4CC5E49C32325142632AF551934 /* PINRemoteImageTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 612B944990F6D2B3032C498585070523 /* PINRemoteImageTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CC2E10F3DE5A2E0DEF91BF948FE2E06C /* _ASAsyncTransactionContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9EC45975D0A70E685883A6EE402012D1 /* _ASAsyncTransactionContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CC40F97A1370E500B10B5536F9149E88 /* ASRangeManagingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C49FC0A2F8D7B1D6EA3AF666E636C296 /* ASRangeManagingNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CC9C25D74EAD02331BA2CB002D9B20E3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */; }; + CCF02EB012ED66CDE4DCEFE3C6731517 /* AsyncDisplayKit+Debug.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2D83E80452A02F4E51C53E14432A3AF /* AsyncDisplayKit+Debug.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + CD2A3263FA9B3629F7D373E5D898B530 /* ASOverlayLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96D07D4CC3912A46A18D147E14F42FBF /* ASOverlayLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + CD3FBB0BBE384A5810065C4D88D035A4 /* ASLayoutTransition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B22A6ED73746F28404AF31C57E32E29 /* ASLayoutTransition.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + CD68FB8439266630F7BEB187F7449BA3 /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = AC262B220308DD0BE3539DADEF6A984D /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CD731F1BB5013903E2DF3A6BFF044E3B /* ASTextKitFontSizeAdjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = 36E00A3E64E6BBD8E773493B48077674 /* ASTextKitFontSizeAdjuster.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CDCC96FDBA67CD248AA13D4552D08B6F /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70C3A4BA56751CA33F52C2D0C4B7517 /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift */; }; + CE2FBCFCF10B33851635AE494E68C29D /* ASMutableElementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9F1B1FC6DB693AE9866C6A07C199E430 /* ASMutableElementMap.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + CEB7EF76375F2C1474F4197F4D56BB32 /* CanLogMessageInFileInFunctionAtLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B7C2C62F443A5228AC674A23FCCD87 /* CanLogMessageInFileInFunctionAtLine.swift */; }; + CEC0B7603A9B1CD378F02F1618FDB8D1 /* UIViewController+HasImageZoomControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05091C81B06DA14E3F1E22B5438F6079 /* UIViewController+HasImageZoomControllers.swift */; }; + CEDB3EE3AAF87289B735602105E6FCEB /* DefaultAnimators.swift in Sources */ = {isa = PBXBuildFile; fileRef = F772F99383F940F834E7E84E4E1CADA3 /* DefaultAnimators.swift */; }; + CF887DB488D89F9D6C22E641C34E37E5 /* ASCollectionViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB0436DEE011645CA194E623E6C08C5 /* ASCollectionViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CFCAA590EA07C323370BBF4B05D775A5 /* ImageZoomControllerActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEF2AB20596EBB5D41C0C30CDE3733FA /* ImageZoomControllerActions.swift */; }; + D0D844293600CC08BA0440D086DF6F31 /* PINRemoteLock.m in Sources */ = {isa = PBXBuildFile; fileRef = A7604C8C65BB4E702C08E6E64DCF64CF /* PINRemoteLock.m */; }; + D20712489CC62AD1D69DE3D4F067CC6D /* ASDimensionInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1556D6D5C310D21F1F6570B9AAA70140 /* ASDimensionInternal.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + D22F83E790D592BF6759A38C4001B050 /* PINRemoteLock.h in Headers */ = {isa = PBXBuildFile; fileRef = F0C1A4032113C581DBC652A5D1C30293 /* PINRemoteLock.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D263AAA51D764356CED7F375B1536628 /* AsyncDisplayKit+Tips.h in Headers */ = {isa = PBXBuildFile; fileRef = 924DB1E2EBFF6B95672DC515046ACE58 /* AsyncDisplayKit+Tips.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2663A7660C2B444D8DFD65C341C210D /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 409C4A8ACE8739BE0634656BDA26878E /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D27BEF1A0F0747FE98EF2B4AC76297BA /* PINGIFAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 38CDE6D0609F3155BF724C4A383D3D69 /* PINGIFAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D511B3184C8CA22900E8CF81946472FA /* ASCollectionGalleryLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = D3E3CB0CBCFA59CE439FF53F8006C3D4 /* ASCollectionGalleryLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D55227D66C8BD0B9EF66806624057C53 /* PINImage+DecodedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BAB278C37D8CD0A78E57EBDAFFD703 /* PINImage+DecodedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D567696E69F612CCD04A8B52C6AE69FD /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF97BCE466D911620708CE0E0D8EEA45 /* ASLayoutElement.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + D5741B35FAD5625327DB7740816490EF /* ASGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 19013B6B61D3353D8B1996BC41ED22EF /* ASGraphicsContext.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + D58F5F325475C2FA76B7A2C6D6DEBA08 /* _ASCollectionReusableView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2AE87F010BB241641A5655B985A653C6 /* _ASCollectionReusableView.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + D5C26BE5B56878BE80E4E358D01505BF /* PINProgressiveImage.h in Headers */ = {isa = PBXBuildFile; fileRef = B0ED94615CE6CEC319F06AACF1CEB800 /* PINProgressiveImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D5F9094AB618823BE2D258D83450ACF8 /* ASRatioLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 773C92C3B53030CCB6156F70AC47231C /* ASRatioLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + D65BE49AD19B4ED6FCCA1987CDFEAA81 /* ASRunLoopQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 7194F334C486D84103D8B7F489484B85 /* ASRunLoopQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D6FBD69E5AC966E364870F3BC89AE40B /* ASDisplayNodeCornerLayerDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = AD9ABC06E9F1438A47B1B873A9BF1FC9 /* ASDisplayNodeCornerLayerDelegate.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + D75E18202ECDB1208F5EAA0AFC37D058 /* Logger.Formatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 049DEE219089C56A9FF4D8DB4DE90C83 /* Logger.Formatter.swift */; }; + D792C77237A52B9B995A8A2E9FD39B2C /* PINRemoteImageManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 5275A3C1B1BB261CE7A641E5F1A4AE10 /* PINRemoteImageManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D7B3E1598EAA524245035481CFA22A9A /* ASNodeController+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 4503752DE626CEFFDC467B93D6760868 /* ASNodeController+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D83ADCEE529736987678A5E5678C3EF4 /* PINCache+PINRemoteImageCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B81CEBEEA110B801B201B7E31584FD2 /* PINCache+PINRemoteImageCaching.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D8B254AD7AE2D4AD795D0F0D24A9DC63 /* ASConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FBDA1D7FC21A68B8185A1567B2052E0 /* ASConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D8CDE83FC5F7BB9CBDDEF662EA434A76 /* ASHighlightOverlayLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DA54E673A5C3F5C8521C04A015E4A9C /* ASHighlightOverlayLayer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + D9554845DD1077123FC15B6F5FCD3050 /* UIGestureRecognizerState+CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BAB84DDE20C8E79F0FFC7E5B015EDC /* UIGestureRecognizerState+CustomStringConvertible.swift */; }; + D9E389EF92E5B549EA600E659E8CD045 /* ASTipsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 411BC26AEB991FC58D93C8947E77F4BE /* ASTipsController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DAC9BD448D1FBD574287D47F09E8BFFA /* ConsoleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A5BE4F496799AB427B7E02D30B8550C /* ConsoleLogger.swift */; }; + DADB3AD2B89E46C6A114C733FCCFFCCF /* PINRemoteImageManager+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 21EE2773F3C79088F0071460CD0433C7 /* PINRemoteImageManager+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC9252B91D454E933573D0F02CD34A48 /* ASDisplayNodeTipState.h in Headers */ = {isa = PBXBuildFile; fileRef = A0F896E241CC0E46B053F5953BCCC504 /* ASDisplayNodeTipState.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DCA67BCF11BB08C4CC754BAB7DE9700F /* ASDisplayNode+Layout.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA697F21425C3FDC3FD77AF6CA5A1E37 /* ASDisplayNode+Layout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + DCBB463A435F0BA2AA998D91A821BD63 /* ASDisplayNode+Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 7406A55AE2F314560B18CF0D1F166146 /* ASDisplayNode+Yoga.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DCC0959800E3EC695210D0372765FBFA /* NSData+ImageDetectors.m in Sources */ = {isa = PBXBuildFile; fileRef = E4D3DCB3C009FD5D8659089E34B277D3 /* NSData+ImageDetectors.m */; }; + DD25CE53DC082769F959AC1EA39B47E1 /* ASSection.h in Headers */ = {isa = PBXBuildFile; fileRef = AAE59626849BEF2264FC9EB98B2EBDB3 /* ASSection.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DD519256677113580497A433745E2AA5 /* PINCachedAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = A12D2284A307229BE1FCA6C56606D464 /* PINCachedAnimatedImage.m */; }; + DDABD6DDE99C201E518E277995C4C3F7 /* ASTableViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = CAA9D4CFE9C5A4813A54148D6F1BEB6C /* ASTableViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DDBE0B9C33CFF36A689113FB2148B8ED /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A5C0BBAAA11ABB306A67D1CE1F475FB /* MapKit.framework */; }; + DE1FBD64E727449DFEB41D8CC0B764E4 /* PINCacheMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = FD6F468C17D5D55709E1A98E64A9A77E /* PINCacheMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DE2B62E460FBD72E703EC2EB8F0EF54D /* Zoomable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 594FEB1CE4589393B0B4FCA53EDA995C /* Zoomable.swift */; }; + DE43FB61D54CA4D4683A2976E2C4B17A /* ASBatchContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D28E1FDF6AF4C8EA76A2E6B04468EFF3 /* ASBatchContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DE51CF9E4A5474D3988D1BB66EF7618D /* PINRemoteWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 22AB87EEF08419D87CD7B63869817E1D /* PINRemoteWeakProxy.m */; }; + DEB64B74E02E6B5A3942813C4B0AA43A /* PINAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 3781AD18516F84156D9A016E7EF16502 /* PINAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DF3EC03998606F8C6B59E9B8FA250DE1 /* NSData+ImageDetectors.h in Headers */ = {isa = PBXBuildFile; fileRef = DCDFEDEA0B238450F5F65B65C2CD9079 /* NSData+ImageDetectors.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DFB3623B8303E1732A2DE7866457BFA5 /* ASRunLoopQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6AA80045BD16B35CDB5DE468DF1034F6 /* ASRunLoopQueue.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + DFCF371994649A26AB2793A1539FDE27 /* CoreGraphics+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = D0162762B4A4C18C34AF7BDF70585D4E /* CoreGraphics+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DFEDDB04D68B8A713D24FAB88F55988B /* _ASDisplayViewAccessiblity.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FBE47550DB37A88FC7CFE0100233D15 /* _ASDisplayViewAccessiblity.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E028DD17CB226563694AD3E644DA0E8A /* ASCollectionLayoutState+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D5AB57FF552FD673BCFA9C23733069E1 /* ASCollectionLayoutState+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E061922DF3A631DE569DEC0B02A0E55C /* _ASDisplayView.h in Headers */ = {isa = PBXBuildFile; fileRef = 310BD706DB638309D39CAFB2E12E51E8 /* _ASDisplayView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E0A675EB8187301FBECDFEFDDF256FB5 /* CanPerformAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABB94274587D4AB055B0098469B62741 /* CanPerformAction.swift */; }; + E0B5B77C3B206FBB576000E18BF9C56A /* ASVideoPlayerNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = B5A3F7221807630DE3D0449E1D30FC1F /* ASVideoPlayerNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E13C6028A12C4D85EBAAAA04C96FF536 /* ASTableLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55325CF18F732FB37081F750E0577E4 /* ASTableLayoutController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E192EDBF272B1EF298F8FE2FA6DDAF25 /* NSAttributedString+ASText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6E1443385934C571269E9950D816D792 /* NSAttributedString+ASText.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E2580439ED32A4AC27DF6CD05B69B472 /* ASMultiplexImageNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 017310D7700BEE6573A7BA14FD8BDCD1 /* ASMultiplexImageNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E3B60613FB36F520EAA02E7C405B4B10 /* ASTextKitRenderer+Positioning.mm in Sources */ = {isa = PBXBuildFile; fileRef = D37EA35A7EC92AF0C4C89CB9055045D9 /* ASTextKitRenderer+Positioning.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E3DBA9B2AD2B13F98ABC7894743C5FF1 /* _ASTransitionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 626C3FFAA488C3DD09D53C2E75C9CF17 /* _ASTransitionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E49A788AD2790861B385BA2E084BFEF2 /* ASDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 38DCEAAC959C2F8E5E2B80424211C42A /* ASDataController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E4AFCBB6059FC3C56FCE281FE6B88A14 /* ASLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = C032C2C59E35E90D29510094FA3BAF62 /* ASLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E66C56441574428F0E6319DD42712F00 /* NSHTTPURLResponse+MaxAge.h in Headers */ = {isa = PBXBuildFile; fileRef = 51DDB8C289581DFC7295DF13B2B679A4 /* NSHTTPURLResponse+MaxAge.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E74676FCA35F49AB90084F9D6A133BEC /* ASEditableTextNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = C14B8C1CB8961F309BF9D6412F088BAD /* ASEditableTextNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E7F75D0551F60AC1E0FAAE389E0E48EE /* ASLayoutManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 898DCAC1CFAD91697899114511875124 /* ASLayoutManager.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E80626C7D668DB07B848BEC6AAE711A4 /* ASControlTargetAction.h in Headers */ = {isa = PBXBuildFile; fileRef = E3F88046DBCA3A2EA1314244D40E4317 /* ASControlTargetAction.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E81BA6B935A20C3C5AF436FD1097A607 /* ASCollectionElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = B34FE789AA0085844B00920EA8ABD869 /* ASCollectionElement.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E8261A6238D988688A11ECD8B35A479C /* ASDisplayNode+LayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = B3C8F3A4509640386CCC3F9E5A843E10 /* ASDisplayNode+LayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E83BD30C134DC77082910C65567F529D /* NSHTTPURLResponse+MaxAge.m in Sources */ = {isa = PBXBuildFile; fileRef = 31A38BD86467F4397BAAE01B7769BEC5 /* NSHTTPURLResponse+MaxAge.m */; }; + E85CBF5F58F5FF76148975C11E38F27E /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = E8FFDB3A91E0FACEF3DDB279AD37CF30 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E977832761EAFD3D2EF100FB74A57717 /* UICollectionViewLayout+ASConvenience.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16A94C3E9D1D354B1FA7BFB225090329 /* UICollectionViewLayout+ASConvenience.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E97E10031318F97C13605A4E7C6C241D /* ASCollectionLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 75555F5FF44B7570151D3E07C14B9091 /* ASCollectionLayout.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E99888C1284FD4BA652BFCCBA42A69D0 /* AsyncDisplayKit+IGListKitMethods.mm in Sources */ = {isa = PBXBuildFile; fileRef = 628632B58BF8798C5B49581ECE1D5BD1 /* AsyncDisplayKit+IGListKitMethods.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + E9BF9E31DBD24F528DC4BE7EC406F7F1 /* ASPagerFlowLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C976C49525F404BB47056D7ABA4E4ED /* ASPagerFlowLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EA86861420C58AAFFBDD4FE8B05A90F8 /* _ASDisplayViewAccessiblity.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4CD4A80CBB44F35AB6DC6F1CD500C93C /* _ASDisplayViewAccessiblity.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + EAAACE6B4C88D9F0E4E8EC5CD698212C /* PINWebPAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = B68441AB82FA9337F6184B4FC8706C89 /* PINWebPAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EB472359A2A67364B3578253C8C4ABC3 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 832B4AE6E6704ADC13BF1022950A7A6F /* CoreLocation.framework */; }; + EB5CB15BE4021AEEE889E49C99751359 /* ASTraitCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8BD494C55125932909BE35FA36C3C97B /* ASTraitCollection.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + EBB22015243AF51E4A657BEB9377011D /* PINRemoteImageCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 3961C9750DE5B388A186362677458C58 /* PINRemoteImageCallbacks.m */; }; + EBB98BADBF34A5832DC9812C4D45C02F /* ASBatchFetchingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2729346235A1EF46585A750ACC6F4126 /* ASBatchFetchingDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EC5DD146A3413EF265E41C662ACFEA4B /* PINCache-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9912693AC1AD6E93BC00EDC6E1E48E91 /* PINCache-dummy.m */; }; + EC86C6197A99F375E5FF8034604630EA /* InjectableLoggers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DAEC71D283EFA4FCB50A3E29F51370A /* InjectableLoggers.framework */; }; + EC8A4029FDCEAEEB3810CF75685F7878 /* PINAlternateRepresentationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = EBDEAAC4C345279ED09C50CF3BF09B7B /* PINAlternateRepresentationProvider.m */; }; + ECB48648B7061F5DA13D61BF35E9E675 /* PINRemoteImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 229924D8EAEEC020747355F7941265D7 /* PINRemoteImageManager.m */; }; + ED7E794ADD340BEFFC80FC75837CFBBC /* PINURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AC1D2A9DBE44C85842578B7376D7A5C /* PINURLSessionManager.m */; }; + EDAA17A17F102B0684848D7F2243EEF0 /* Zoomy-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C5B4CDB31225A9BF38BCC18B506CBC /* Zoomy-dummy.m */; }; + EE30A346E8E2989D4D8A1E2A60608C5D /* _ASHierarchyChangeSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = DB9FBBC1EF5AF543DA86EBF741B82694 /* _ASHierarchyChangeSet.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + EE5B2A3F1514028E9756AAB7326B8ABC /* TypeAliasses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15C80D074046D9ED56A3DFB11E613D9D /* TypeAliasses.swift */; }; + EF3997132E45070F8934DFEF9D904A41 /* UIView+layoutHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA4D69598D7C62D33AEA4FBDE19BCC2 /* UIView+layoutHelpers.swift */; }; + EF68CE5C31FA5D353DFA4536D85E7067 /* ASTextKitRenderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A3377EFCA934EA4647740466F62D987 /* ASTextKitRenderer.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + EFA0B7147CDDF2C33019191E9E492CDB /* ASTableView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = F8B91C4F2D81045D14D0886080099732 /* ASTableView+Undeprecated.h */; settings = {ATTRIBUTES = (Project, ); }; }; + EFD256412FBB95F43A7114D1A0846301 /* ImageZoomControllerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A40BCD8285FC1DEF12569A10100C4C1 /* ImageZoomControllerState.swift */; }; + EFEBFE9D117F31C3EFBCFF03E4F374B8 /* ASImageNode+tvOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = E936B1B04FFAF35C7B129A8753B7710D /* ASImageNode+tvOS.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + F01A56AD8FC4D13459E7A4088437DD60 /* ASTextNode2.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84CB3A49900E50746B7BBE91B3975FA8 /* ASTextNode2.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + F0CE14EDC70238AE475B95C1E92AB258 /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 6ABCC1E22FDEC639E66D76B27F1C5922 /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F1852DD8600E8B26A90C21441ED9FAF8 /* ASCollectionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 22D109FC09C04222622A33E7750D7643 /* ASCollectionNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F1B69EBD630EA9C41E76FAF9B4878266 /* ASTextNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = EA0B213E1618F546074778126A6A7EBA /* ASTextNode.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + F1CD75754D06FFE6667055828402AC19 /* ASCenterLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 47B21A7594492D19411EB2B50736A93B /* ASCenterLayoutSpec.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + F1E44CF8A9BDBF622C310A0A52FC9069 /* ASSectionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D0D3B5F98B76FBBF66FBC689B55B7F /* ASSectionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F28CAD5ABEDD987D9FDBD0C75C1E22D5 /* ASTextKitShadower.h in Headers */ = {isa = PBXBuildFile; fileRef = CC9F7354BB576AE97ADD36345C6980E2 /* ASTextKitShadower.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F3457FE949B058184A4FB77C6AE576AE /* ASLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 265855D3D2AF279E97701DA7779E70A3 /* ASLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F345BC25FC253D5C7A7F12837DA555FA /* PINOperation-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3405A596EC79FF405C0EBA48F483F456 /* PINOperation-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F37A13201EAD5DDD51A3D7F7BA82C840 /* ASConfigurationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A48A5E4ED7ED7758E6885FF2C6A8189 /* ASConfigurationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F39F51D473548ECD4D257BF5CDF965CD /* ASTipNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B11BD730349E9A6BC10FD9485AABFE8 /* ASTipNode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F3E0A225E531BB32262D7D9E6BCCCC43 /* ASInsetLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 2948BC247C32FEAEBBD7ABDF5868196D /* ASInsetLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F40F8AD0FB1CAA4C367596C50912AF95 /* ASTextDebugOption.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CB12185681B73727DC1273F336BFD9D /* ASTextDebugOption.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + F5108C9C22403076681B80297719B820 /* PINOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = F3E440CADA5070BE3D563D05B491DE62 /* PINOperationQueue.m */; }; + F60818A3F394E384B349C7F3FD8896D1 /* ASTabBarController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4CD3F57888B836CD8BBDEE5A0761834F /* ASTabBarController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + F71109526514F1B3E7A8F233DE070559 /* ASTextKitTailTruncater.h in Headers */ = {isa = PBXBuildFile; fileRef = 780C4053DCDEF3BE175B88490A56D53D /* ASTextKitTailTruncater.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F75371474DC31912DFEABE144AD8C134 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D1DFA6C99F765607130031AF14FE7C9 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift */; }; + F7DCF358D078332CEB3F7AD5AAAC4530 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BE1A9D7E289850DE3E3703B8B59B2E /* ASDispatch.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F7E577DBB5E622CF4B9BE7D057FB7860 /* ASSignpost.h in Headers */ = {isa = PBXBuildFile; fileRef = E70BC18B679C8A3330AAB74EC44E137B /* ASSignpost.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F803EDD45DA76E8392546A43BD223D8F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76F317BA0E076D34E8461D2E6827CD8E /* Accelerate.framework */; }; + F806F7F37B84AEC1C0AEE5C7000E0466 /* ASSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = F2C21DD7FDAD82793DA6912B527CCA8A /* ASSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F80827ADB4E39BC74D92F18ABD8F92A8 /* NSMutableAttributedString+TextKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30DD3DAFDA45E1C0E7B07DC0F2E7F0D3 /* NSMutableAttributedString+TextKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F8D6DE5B1A9935A9B5C53769624F1C53 /* PINCachedAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 8585E737744727C5F5FFFE96D84A234F /* PINCachedAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FA09956C6A65F04B260B032B19C3C408 /* PINAlternateRepresentationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 3696C349E675BB987AA159ECE86A472A /* PINAlternateRepresentationProvider.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FA3B40D2C4CB095BE4314E8F1FF7000C /* PINRemoteImage-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 72993BC01B036B4DF85688844D2A00C3 /* PINRemoteImage-dummy.m */; }; + FAACAA3FAADE3A8D89DCE1E374BECEA7 /* ASAbstractLayoutController.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BFA9B4CE54E1E697CA67579BE312597 /* ASAbstractLayoutController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FB849B4B080AD99E6AA582A08D0B136D /* ASLayoutSpec+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 9265300B5E28071C901DCD8848EDAF35 /* ASLayoutSpec+Subclasses.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FC11F6DB1023A426B9D6DEC5FEAFEA20 /* ASCollectionLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 408A5ACE5EC400AE7CEBD7C6338B76F5 /* ASCollectionLayoutDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FC78F578F793BE2AACE996A785F1C6A5 /* ASCollectionViewLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 12980397AA04450775600F72E475AD3C /* ASCollectionViewLayoutInspector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FDA5B5348C842BAC45AE14D72B2E2782 /* ASBackgroundLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = C57821E88CDD7886ACE86068E06D5B34 /* ASBackgroundLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FE31388AFA377EF837E0D80C74351FD7 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A12A3705DF38020F5B68418E190D0109 /* AVFoundation.framework */; }; + FE4EC78B53C49C251ADA8964979013D8 /* ASTwoDimensionalArrayUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = CD82409E784C5B82AFCB8E3B4B899B32 /* ASTwoDimensionalArrayUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FE8F1F18D987E1C044013CC987939B11 /* CanLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DED5930F943F0D3748F0B68C9814C9A /* CanLog.swift */; }; + FEC35A85C255EC1E831E29A8A6A3280C /* ASLayout+IGListDiffKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = B21D04D0712E0F8DFD37114AD104DB83 /* ASLayout+IGListDiffKit.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + FF156CB786C29B397B3A97686DDDA057 /* PINSpeedRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 327665699F63693627351B86322A4BBC /* PINSpeedRecorder.m */; }; + FF15EAE598D7123397737DBC37BE77A0 /* ASNavigationController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3FB144D267D64DAD5769709D3C613A09 /* ASNavigationController.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + FF4F84E904D5B54DD1E596BB8BB3C4B2 /* ASTextKitComponents.mm in Sources */ = {isa = PBXBuildFile; fileRef = B86953550C8475069C247A7C7039CC61 /* ASTextKitComponents.mm */; settings = {COMPILER_FLAGS = "-fno-exceptions"; }; }; + FFA03ECBF831BCB7A9BB9D3AB5168587 /* PINRemoteImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E60EF003F598F328ED07D1336D1290D /* PINRemoteImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 169FD5948F5CB9A3377EEF131586648E /* PBXContainerItemProxy */ = { + 01DE0E6C033F494AC9CC06606A613C27 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 87C901210314C5B33D0D156EB4065E80; - remoteInfo = InjectableLoggers; + remoteGlobalIDString = 43C46F311E654020969485F1CE2D78DB; + remoteInfo = "Pods-Zoomy_Example"; }; - 1E70EA43018D6325FA41D3E82A15D5DF /* PBXContainerItemProxy */ = { + 294AA6C335A6198807ABE2448FD36FF3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 159BCD99AC1F7CE7112319E6C584776F; - remoteInfo = Zoomy; + remoteGlobalIDString = 87C901210314C5B33D0D156EB4065E80; + remoteInfo = InjectableLoggers; }; - 20B5B114E7838256053942AF687637AB /* PBXContainerItemProxy */ = { + 40E3E8573F082241997ECCFEF682F7E2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A927C3CD51C30012080D6CA07959B246; - remoteInfo = PINCache; + remoteGlobalIDString = 87C901210314C5B33D0D156EB4065E80; + remoteInfo = InjectableLoggers; }; - 26FB0FC8B00E1240DBA6330BF8A55D6A /* PBXContainerItemProxy */ = { + 4A1FF4606E130E18880D0B3CB0B1EF70 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 87C901210314C5B33D0D156EB4065E80; - remoteInfo = InjectableLoggers; + remoteGlobalIDString = E2A8B2A28D2EAB2E4CCF3B69E6792851; + remoteInfo = PINRemoteImage; }; - 286B04891C620D5D4606E8D738CF47C7 /* PBXContainerItemProxy */ = { + 6ACADBBD59E8392C283BEA6CF9C7D7DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = DB66E43BC980D741F3C7C5CF3ACEEFA4; - remoteInfo = Texture; + remoteGlobalIDString = E2A8B2A28D2EAB2E4CCF3B69E6792851; + remoteInfo = PINRemoteImage; }; - 35AA28F7C7A889F1E5AA1095A517A762 /* PBXContainerItemProxy */ = { + 968D982A4D792D95D7B48D57197BC2C2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 57310B016450E63387C9D64F4933E995; remoteInfo = PINOperation; }; - 42F6296AE51CECA420F6AE0EB1ABCCE3 /* PBXContainerItemProxy */ = { + 9799295E8AC30B9C0E603876C70AF87E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 43C46F311E654020969485F1CE2D78DB; - remoteInfo = "Pods-Zoomy_Example"; + remoteGlobalIDString = 159BCD99AC1F7CE7112319E6C584776F; + remoteInfo = Zoomy; }; - 4BA479BF33A3CF04FB4ED9C34E802892 /* PBXContainerItemProxy */ = { + B305929B6D1BE593C753A90B2510AB4C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 57310B016450E63387C9D64F4933E995; - remoteInfo = PINOperation; + remoteGlobalIDString = 87C901210314C5B33D0D156EB4065E80; + remoteInfo = InjectableLoggers; }; - 792DE55ABEE686D3376FF845FEB09BB3 /* PBXContainerItemProxy */ = { + CCEB932B145C2CDB5CC5204860193914 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = A927C3CD51C30012080D6CA07959B246; - remoteInfo = PINCache; + remoteGlobalIDString = 57310B016450E63387C9D64F4933E995; + remoteInfo = PINOperation; }; - 9E69C729BDC147DE35E03D350C945696 /* PBXContainerItemProxy */ = { + D418FB2567353AF5C24F0A6D9A5BC2F5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E2A8B2A28D2EAB2E4CCF3B69E6792851; - remoteInfo = PINRemoteImage; + remoteGlobalIDString = DB66E43BC980D741F3C7C5CF3ACEEFA4; + remoteInfo = Texture; }; - AF99DF2C5B1DE9BD3877F13581C78F63 /* PBXContainerItemProxy */ = { + DF609D3EB5027804B8EF35F3F458C97C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = E2A8B2A28D2EAB2E4CCF3B69E6792851; - remoteInfo = PINRemoteImage; + remoteGlobalIDString = A927C3CD51C30012080D6CA07959B246; + remoteInfo = PINCache; }; - CE9CC00963D6260A8B8E7E760172A397 /* PBXContainerItemProxy */ = { + DF7FE2683D059AC70D93B977B69C42BD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 87C901210314C5B33D0D156EB4065E80; - remoteInfo = InjectableLoggers; + remoteGlobalIDString = A927C3CD51C30012080D6CA07959B246; + remoteInfo = PINCache; }; - FF30B81F9789B64937FC47064BE2F2FE /* PBXContainerItemProxy */ = { + FEF46F416F93AF95E6C9635F25355BF9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; @@ -685,707 +690,717 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 004EEF67B238D8D591FAA3567F4B1D67 /* ASLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASLayout.mm; path = Source/Layout/ASLayout.mm; sourceTree = ""; }; - 007B9E9F13C247C344FE3DC65E2AB901 /* ASDisplayNode+Subclasses.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Subclasses.h"; path = "Source/ASDisplayNode+Subclasses.h"; sourceTree = ""; }; - 00B19F9A89A433337404373E49907CF9 /* PINOperationGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationGroup.h; path = Source/PINOperationGroup.h; sourceTree = ""; }; - 00F0D9E4494E6E4440167C3B132C83CA /* ASImageNode+CGExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASImageNode+CGExtras.mm"; path = "Source/Private/ASImageNode+CGExtras.mm"; sourceTree = ""; }; - 0169698F1001B64F149CDB5D6DD08CF9 /* PINRemoteImage-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINRemoteImage-prefix.pch"; sourceTree = ""; }; - 01D61BF0A499F5857CF17E32798585EE /* PINRemoteLock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteLock.h; path = Source/Classes/PINRemoteLock.h; sourceTree = ""; }; - 01E4661F07305554D5DE06D73578BF89 /* ASControlNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASControlNode.h; path = Source/ASControlNode.h; sourceTree = ""; }; - 02074016ADB05CBAFE0127B2661EB0AC /* ASBasicImageDownloaderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBasicImageDownloaderInternal.h; path = Source/Private/ASBasicImageDownloaderInternal.h; sourceTree = ""; }; - 023744D1EB94358EFF5B46ED666E1A78 /* ASTraceEvent.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTraceEvent.mm; path = Source/Details/ASTraceEvent.mm; sourceTree = ""; }; - 02E082F190CD64742376FA1DCF16D316 /* ASOverlayLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASOverlayLayoutSpec.h; path = Source/Layout/ASOverlayLayoutSpec.h; sourceTree = ""; }; - 0347E82F5AE84656ECD2CB86F0972084 /* UIImageView+Zoomable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIImageView+Zoomable.swift"; sourceTree = ""; }; - 03C015688FA02187BD871480FC999411 /* ASBackgroundLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASBackgroundLayoutSpec.mm; path = Source/Layout/ASBackgroundLayoutSpec.mm; sourceTree = ""; }; - 041B4A598ADB602F7DCCBC8D326BBE3B /* ASAbsoluteLayoutElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAbsoluteLayoutElement.h; path = Source/Layout/ASAbsoluteLayoutElement.h; sourceTree = ""; }; - 0496BFF0C5BC4DE37E77097EBE8DAA21 /* ASExperimentalFeatures.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASExperimentalFeatures.h; path = Source/ASExperimentalFeatures.h; sourceTree = ""; }; - 04B46B85C03FC5CC066ED7F633FEC888 /* ASImageProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASImageProtocols.h; path = Source/Details/ASImageProtocols.h; sourceTree = ""; }; - 04FE1FDDBACAF8709FBAB591EA6C2155 /* ASTipsController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTipsController.mm; path = Source/Private/ASTipsController.mm; sourceTree = ""; }; - 053572BA7FE13DAC5CA8C9ED6FF7310D /* ASTextNodeTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNodeTypes.h; path = Source/TextKit/ASTextNodeTypes.h; sourceTree = ""; }; - 05641F15444EBE2BE289D9C02E82E530 /* ASCollectionLayoutState.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionLayoutState.mm; path = Source/Details/ASCollectionLayoutState.mm; sourceTree = ""; }; - 056F5351D15FECFF550FF001A1172E9C /* PINRemoteImageManager+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINRemoteImageManager+Private.h"; path = "Source/Classes/PINRemoteImageManager+Private.h"; sourceTree = ""; }; - 05EBA3BEF494A23D32FC5023A4303A8F /* CanPerformAction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanPerformAction.swift; sourceTree = ""; }; - 06679FB2C6525803A57E1ABF62E2AE5B /* ASCollectionLayoutDefines.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionLayoutDefines.mm; path = Source/Private/ASCollectionLayoutDefines.mm; sourceTree = ""; }; - 0678905DA353A09C60572A337DEF943B /* ASLayoutTransition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutTransition.h; path = Source/Private/ASLayoutTransition.h; sourceTree = ""; }; - 067CAA9F4FC781E023BDE479666C0EBF /* UIImage+ASConvenience.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "UIImage+ASConvenience.mm"; path = "Source/UIImage+ASConvenience.mm"; sourceTree = ""; }; - 069772F35BA6AC6B783EA915D5DABFC2 /* PINOperationQueue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINOperationQueue.m; path = Source/PINOperationQueue.m; sourceTree = ""; }; - 06A281B1005F95408C915408AFB29679 /* Logger.FormatSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.FormatSettings.swift; path = InjectableLoggers/Classes/Structs/Logger.FormatSettings.swift; sourceTree = ""; }; - 073F5156FDFEF3B8AA6981CD17F054AE /* Texture.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Texture.xcconfig; sourceTree = ""; }; - 07729A9F499A036868ED6B53393E7A5C /* ASStackPositionedLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASStackPositionedLayout.mm; path = Source/Private/Layout/ASStackPositionedLayout.mm; sourceTree = ""; }; - 07A5F3EBB5DB5D888DFCF04CA861A73F /* NSMutableAttributedString+TextKitAdditions.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "NSMutableAttributedString+TextKitAdditions.mm"; path = "Source/Details/NSMutableAttributedString+TextKitAdditions.mm"; sourceTree = ""; }; - 0805474ED89380D8B81280D3F8AB1044 /* Zoomy-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Zoomy-Info.plist"; sourceTree = ""; }; + 007EA24CB3D0521364C550D47F1E4C56 /* _ASCoreAnimationExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCoreAnimationExtras.h; path = Source/Private/_ASCoreAnimationExtras.h; sourceTree = ""; }; + 0091DD8DF08F9D4D4FED8A7FAECB171C /* SimpleLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SimpleLogger.swift; path = InjectableLoggers/Classes/Classes/SimpleLogger.swift; sourceTree = ""; }; + 012FFB5866BEDA74EBFDE3FF86B46104 /* ASTextDebugOption.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextDebugOption.h; path = Source/Private/TextExperiment/Component/ASTextDebugOption.h; sourceTree = ""; }; + 017310D7700BEE6573A7BA14FD8BDCD1 /* ASMultiplexImageNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMultiplexImageNode.h; path = Source/ASMultiplexImageNode.h; sourceTree = ""; }; + 022D02D7B64CA9E34BA2086AF7BDF23F /* PINImage+WebP.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImage+WebP.h"; path = "Source/Classes/Categories/PINImage+WebP.h"; sourceTree = ""; }; + 02B7FAE0B0A89921AA60FCD1B1A628AB /* _ASPendingState.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASPendingState.mm; path = Source/Private/_ASPendingState.mm; sourceTree = ""; }; + 03ADCD0D9AD000A2C92CBC5FFF6E8F97 /* ASBasicImageDownloaderInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBasicImageDownloaderInternal.h; path = Source/Private/ASBasicImageDownloaderInternal.h; sourceTree = ""; }; + 03DB36FBE1545B64BB23CA4E02BDE1E5 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift; sourceTree = ""; }; + 049DEE219089C56A9FF4D8DB4DE90C83 /* Logger.Formatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.Formatter.swift; path = InjectableLoggers/Classes/Structs/Logger.Formatter.swift; sourceTree = ""; }; + 05091C81B06DA14E3F1E22B5438F6079 /* UIViewController+HasImageZoomControllers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIViewController+HasImageZoomControllers.swift"; sourceTree = ""; }; + 0558DFDA007EDF0D1EFF53A5B7F6F4D2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 06DDD98B42182B137D220784A22E6697 /* NSObject+AsociatedKeyForImageZoomControllers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "NSObject+AsociatedKeyForImageZoomControllers.swift"; sourceTree = ""; }; + 0813AB2B539FBB3C7172EC17D1183DD9 /* ASImageNode+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASImageNode+Private.h"; path = "Source/Private/ASImageNode+Private.h"; sourceTree = ""; }; + 08256B415C39B30BF9ECE1264B713481 /* ASScrollDirection.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASScrollDirection.mm; path = Source/Details/ASScrollDirection.mm; sourceTree = ""; }; + 0836BBF553616112912E10DCA57993A6 /* PINRemoteImageCaching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageCaching.h; path = Source/Classes/include/PINRemoteImageCaching.h; sourceTree = ""; }; + 08A05187C58CF3FEFE6C3FD04038BFD7 /* _ASCollectionViewCell.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionViewCell.h; path = Source/Details/_ASCollectionViewCell.h; sourceTree = ""; }; + 08C5161AA3E2ED418F8D43129A259B24 /* ASInsetLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASInsetLayoutSpec.mm; path = Source/Layout/ASInsetLayoutSpec.mm; sourceTree = ""; }; 08FAA55FB0053B36E2D4836258EBEEC4 /* Pods-Zoomy_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Zoomy_Example.release.xcconfig"; sourceTree = ""; }; - 093258A51C5A055B7D4487D97D048C02 /* _ASDisplayLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASDisplayLayer.h; path = Source/Details/_ASDisplayLayer.h; sourceTree = ""; }; - 098428E42955EF96D87FE1C354E8AD9D /* PINResume.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINResume.h; path = Source/Classes/PINResume.h; sourceTree = ""; }; - 09A492A5EDB688BCE2C833245EA50EE8 /* ASBlockTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBlockTypes.h; path = Source/ASBlockTypes.h; sourceTree = ""; }; - 0ADDD0546EE438CB2D70AE96914E0431 /* ASTextAttribute.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextAttribute.mm; path = Source/Private/TextExperiment/String/ASTextAttribute.mm; sourceTree = ""; }; - 0AEE3B05A5D034B14D96235552DAB8A1 /* PINRemoteImageDownloadQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageDownloadQueue.h; path = Source/Classes/PINRemoteImageDownloadQueue.h; sourceTree = ""; }; - 0B739A419D028F8BC409ADB9AD9CA527 /* ASDimension.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDimension.mm; path = Source/Layout/ASDimension.mm; sourceTree = ""; }; - 0C2261536A1F390C347C83BE1AA59011 /* ConfigurableUsingClosure.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConfigurableUsingClosure.swift; sourceTree = ""; }; - 0C6AC42AE8AC5B546767B472AC3D4143 /* CanManageZoomBehaviors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanManageZoomBehaviors.swift; sourceTree = ""; }; - 0CDAA8013007AE7BA76340E480145741 /* CanLogMessageAtLevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessageAtLevel.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLogMessageAtLevel.swift; sourceTree = ""; }; - 0CFAF1E8969912E3093CDAE51ABFB670 /* ImageZoomControllerIsNotPresentingOverlayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsNotPresentingOverlayState.swift; sourceTree = ""; }; - 0D4C2A2B7E38D7C5569ED910C53B3B97 /* Zoomy-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Zoomy-prefix.pch"; sourceTree = ""; }; - 0D5AA6B6BFFB0F4BA2616154920180D8 /* ASElementMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASElementMap.mm; path = Source/Details/ASElementMap.mm; sourceTree = ""; }; - 0D9DB88CFA4413907F47AD1A71EAE35D /* CGRect+transformedByTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGRect+transformedByTransform.swift"; sourceTree = ""; }; - 0DA500C380D603BFBE1C536274B05AAC /* ASLayoutSpec+Subclasses.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASLayoutSpec+Subclasses.h"; path = "Source/Layout/ASLayoutSpec+Subclasses.h"; sourceTree = ""; }; - 0DB18754F7DBD5680043B023D3924CDD /* ASTextUtilities.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextUtilities.mm; path = Source/Private/TextExperiment/Utility/ASTextUtilities.mm; sourceTree = ""; }; - 0EAFE70C30090A5CF72DE2F7415578D1 /* ASTextKitShadower.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitShadower.mm; path = Source/TextKit/ASTextKitShadower.mm; sourceTree = ""; }; - 0F0BD0EDE0ED2F616D20EF4F8324DBE4 /* TypeAliasses.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TypeAliasses.swift; sourceTree = ""; }; - 0F618C832DC0906460A5823141B80889 /* PINButton+PINRemoteImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINButton+PINRemoteImage.m"; path = "Source/Classes/ImageCategories/PINButton+PINRemoteImage.m"; sourceTree = ""; }; - 0FD60A2E7EE5CFF2D707B5995C946BC1 /* ASButtonNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASButtonNode.h; path = Source/ASButtonNode.h; sourceTree = ""; }; - 0FD6A1C78C243ABC82E24C0705F1F667 /* PINAlternateRepresentationProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINAlternateRepresentationProvider.h; path = Source/Classes/PINAlternateRepresentationProvider.h; sourceTree = ""; }; - 1029CE67DEA0959BCCAA7D9F534FEC84 /* ASTextInput.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextInput.mm; path = Source/Private/TextExperiment/Component/ASTextInput.mm; sourceTree = ""; }; - 1033543310C731B9BF398A69B3587CE4 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessageAtLevelInFileInFunctionAtLine.swift; path = InjectableLoggers/Classes/Protocols/CanLogMessageAtLevelInFileInFunctionAtLine.swift; sourceTree = ""; }; - 10CD2F8A82E752D0F5290FF3DBFC0BE6 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/AssetsLibrary.framework; sourceTree = DEVELOPER_DIR; }; + 092BA4C0B35FCC3C7EDF8A310EADD496 /* ASDisplayNode+UIViewBridge.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+UIViewBridge.mm"; path = "Source/Private/ASDisplayNode+UIViewBridge.mm"; sourceTree = ""; }; + 0A25DDB1BFA6A6D466803A5137028A77 /* ASTip.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTip.h; path = Source/Private/ASTip.h; sourceTree = ""; }; + 0A8E2F46E8351A43B40AFBB4C8BEF3AE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 0ABEAEBF38D032F544B343E700443A9D /* CGAffineTransform+transformWithScaleTranslationCenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGAffineTransform+transformWithScaleTranslationCenter.swift"; sourceTree = ""; }; + 0AC1D2A9DBE44C85842578B7376D7A5C /* PINURLSessionManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINURLSessionManager.m; path = Source/Classes/PINURLSessionManager.m; sourceTree = ""; }; + 0AE75587CBB8EE0DA0491F98A06B0181 /* CanBetriggered.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanBetriggered.swift; sourceTree = ""; }; + 0B11BD730349E9A6BC10FD9485AABFE8 /* ASTipNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipNode.h; path = Source/Private/ASTipNode.h; sourceTree = ""; }; + 0B82A3E466AAE96E03B8609312FAF2F6 /* _ASAsyncTransactionGroup.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASAsyncTransactionGroup.mm; path = Source/Details/Transactions/_ASAsyncTransactionGroup.mm; sourceTree = ""; }; + 0C38088EF6E60B8FD72EFC5E2DDE25C1 /* PINOperation-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PINOperation-Info.plist"; sourceTree = ""; }; + 0C4FA8380ADD141C97EB7236C2AF9B27 /* PINRemoteImageTask+Subclassing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINRemoteImageTask+Subclassing.h"; path = "Source/Classes/Categories/PINRemoteImageTask+Subclassing.h"; sourceTree = ""; }; + 0D6CDE01C9407A307C0579A9C1D7B913 /* PINOperation.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PINOperation.modulemap; sourceTree = ""; }; + 0D754AB94C11E710749C06408EC6AD11 /* ASIntegerMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASIntegerMap.h; path = Source/Details/ASIntegerMap.h; sourceTree = ""; }; + 0D800D50130BA0F8D82C5558F54DDF7B /* ASTextNodeCommon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNodeCommon.h; path = Source/ASTextNodeCommon.h; sourceTree = ""; }; + 0DA4D69598D7C62D33AEA4FBDE19BCC2 /* UIView+layoutHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIView+layoutHelpers.swift"; sourceTree = ""; }; + 0DC49CAEDA64A6918B1C646A7903EE50 /* ASStackLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutSpec.h; path = Source/Layout/ASStackLayoutSpec.h; sourceTree = ""; }; + 0E8547225274D91482FA087FFCE18E18 /* Texture-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Texture-dummy.m"; sourceTree = ""; }; + 0F4227E8F62083D39A853A5913213842 /* UICollectionViewLayout+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UICollectionViewLayout+ASConvenience.h"; path = "Source/Details/UICollectionViewLayout+ASConvenience.h"; sourceTree = ""; }; + 0F59C6A23784A24F14DF9A84E27DE123 /* ASTraitCollection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTraitCollection.h; path = Source/Details/ASTraitCollection.h; sourceTree = ""; }; + 107ECA26011E51E00F0FB2B12FFC1711 /* PINRemoteImageManagerConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageManagerConfiguration.m; path = Source/Classes/PINRemoteImageManagerConfiguration.m; sourceTree = ""; }; + 10C285230E7CFFE2A19F1963D1321A46 /* PINOperation.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINOperation.release.xcconfig; sourceTree = ""; }; 111894EB439810DFC0AFE88E845A722F /* Pods-Zoomy_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Zoomy_Tests.modulemap"; sourceTree = ""; }; - 114F5E4FAA06F5EB193F8331FF581260 /* ImageZoomControllerActions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerActions.swift; sourceTree = ""; }; - 115A4FCB2A03922EC10B633F15359653 /* PINRemoteImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = PINRemoteImage.framework; path = PINRemoteImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 11C0D27698278E492EDF141A99066C51 /* ASTextNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNode.h; path = Source/ASTextNode.h; sourceTree = ""; }; - 124148AADE44AC741CFADC231F551605 /* ASDimensionInternal.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDimensionInternal.mm; path = Source/Layout/ASDimensionInternal.mm; sourceTree = ""; }; - 1303302AFAE1A1492C119553EB9326C0 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/CoreLocation.framework; sourceTree = DEVELOPER_DIR; }; - 1337D073335F7331614C588A0EEAAB54 /* CanLogMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessage.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLogMessage.swift; sourceTree = ""; }; - 1402CF84CB36E6A58305FC9A07AE9A7E /* UICollectionViewLayout+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UICollectionViewLayout+ASConvenience.h"; path = "Source/Details/UICollectionViewLayout+ASConvenience.h"; sourceTree = ""; }; - 14D5664BB8FDFB48A12DED4645631583 /* ConsoleLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConsoleLogger.swift; path = InjectableLoggers/Classes/Structs/ConsoleLogger.swift; sourceTree = ""; }; + 1123D4B16476D633BF2D6511A5A81017 /* SimpleLogger.Settings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SimpleLogger.Settings.swift; path = InjectableLoggers/Classes/Structs/SimpleLogger.Settings.swift; sourceTree = ""; }; + 11243C7D597D928BACF6593432FFCF01 /* ASTextKitTruncating.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitTruncating.h; path = Source/TextKit/ASTextKitTruncating.h; sourceTree = ""; }; + 115A4FCB2A03922EC10B633F15359653 /* PINRemoteImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PINRemoteImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 11F9C53368EC8719F7CD5EDC99DCD3B4 /* UIView+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+ASConvenience.h"; path = "Source/Details/UIView+ASConvenience.h"; sourceTree = ""; }; + 11FC95FCA7AA02C819434E619DB2974B /* ASAssert.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASAssert.mm; path = Source/Base/ASAssert.mm; sourceTree = ""; }; + 12980397AA04450775600F72E475AD3C /* ASCollectionViewLayoutInspector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewLayoutInspector.h; path = Source/Details/ASCollectionViewLayoutInspector.h; sourceTree = ""; }; + 12FC3E52F0ECF3D85BF407DE1BA0C960 /* ASCornerLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCornerLayoutSpec.mm; path = Source/Layout/ASCornerLayoutSpec.mm; sourceTree = ""; }; + 13B363B9CC87A3361E75819CA2B9289F /* ASLog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLog.h; path = Source/Base/ASLog.h; sourceTree = ""; }; + 13E6CB8779192BAEF893B4437244A36A /* ASLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutSpec.mm; path = Source/Layout/ASLayoutSpec.mm; sourceTree = ""; }; + 142E661BE19C27497AF8807710A34D02 /* ASCellNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCellNode.h; path = Source/ASCellNode.h; sourceTree = ""; }; + 1431CB6DD8433797E27E18B00DA74313 /* PINRemoteImageMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageMacros.h; path = Source/Classes/include/PINRemoteImageMacros.h; sourceTree = ""; }; + 152968521F92B8C3F6F5427C21D3C73C /* ASTextInput.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextInput.mm; path = Source/Private/TextExperiment/Component/ASTextInput.mm; sourceTree = ""; }; 1531CA83CB9C05EF4C041F43CBF4BE7F /* Pods-Zoomy_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Zoomy_Example-acknowledgements.markdown"; sourceTree = ""; }; - 157FB8FE619F3FCDFB26DECF132232C3 /* IGListAdapter+AsyncDisplayKit.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "IGListAdapter+AsyncDisplayKit.mm"; path = "Source/IGListAdapter+AsyncDisplayKit.mm"; sourceTree = ""; }; - 15C1333DEA8E11B47C507085AA30FC6F /* ASLayoutElement.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASLayoutElement.mm; path = Source/Layout/ASLayoutElement.mm; sourceTree = ""; }; - 15EF4E25B85DD21D7F9FDD4BF7B1AB46 /* PINURLSessionManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINURLSessionManager.m; path = Source/Classes/PINURLSessionManager.m; sourceTree = ""; }; - 162A36187E75CC621EFD3DAA504D4BA1 /* ASAbstractLayoutController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASAbstractLayoutController.mm; path = Source/Details/ASAbstractLayoutController.mm; sourceTree = ""; }; - 162E6601E2398E3D0F75F647411164AA /* ASCornerLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCornerLayoutSpec.mm; path = Source/Layout/ASCornerLayoutSpec.mm; sourceTree = ""; }; - 164865052A57263BCC5A5D2DD47E2FE9 /* PINImage+WebP.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImage+WebP.h"; path = "Source/Classes/Categories/PINImage+WebP.h"; sourceTree = ""; }; - 17D2ABE499E151BD596D45D813CB5E23 /* Texture-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Texture-prefix.pch"; sourceTree = ""; }; - 18516CDF6334CB04ECD67DD6C9994D10 /* PINMemMapAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINMemMapAnimatedImage.h; path = Source/Classes/AnimatedImages/PINMemMapAnimatedImage.h; sourceTree = ""; }; - 18777AD77F0E97539ACAD1F9141F38DA /* ASTextKitAttributes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitAttributes.h; path = Source/TextKit/ASTextKitAttributes.h; sourceTree = ""; }; - 18EF9DB92D4E1F229060F5B5B0DDF41E /* CanLogAtLevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogAtLevel.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLogAtLevel.swift; sourceTree = ""; }; - 1993B19AB3BDE5C6993A436E9862ED6C /* ASBatchFetchingDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBatchFetchingDelegate.h; path = Source/Details/ASBatchFetchingDelegate.h; sourceTree = ""; }; - 19BD6E57E86CCDA20DCA33B5615D6479 /* ASTextNodeWordKerner.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextNodeWordKerner.mm; path = Source/TextKit/ASTextNodeWordKerner.mm; sourceTree = ""; }; - 19E53513494050AA573FBF57F1E0B64F /* ASPhotosFrameworkImageRequest.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASPhotosFrameworkImageRequest.mm; path = Source/Details/ASPhotosFrameworkImageRequest.mm; sourceTree = ""; }; - 1B878D70C0CE606BFEBFD094B59CFADD /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; - 1C957DCA2DFAE3DE735CBF4FF71F8C79 /* ImageZoomController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomController.swift; sourceTree = ""; }; - 1D13214627B0CA8A7BE823B9652281FB /* ASTextKitRenderer.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitRenderer.mm; path = Source/TextKit/ASTextKitRenderer.mm; sourceTree = ""; }; - 1D861E5A7BB213F7BDA5A3E68863582E /* PINRemoteLock.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteLock.m; path = Source/Classes/PINRemoteLock.m; sourceTree = ""; }; - 1D982B7DE0FA01AF1D3A98523B0AD71B /* ImageZoomControllerSettings+Equatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "ImageZoomControllerSettings+Equatable.swift"; sourceTree = ""; }; - 1DEFE7301FC80CCC24CC61198C436845 /* ASDispatch.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDispatch.mm; path = Source/Private/ASDispatch.mm; sourceTree = ""; }; - 1EF3A863F3C8E076FC078D3A85201FE2 /* ASTip.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTip.mm; path = Source/Private/ASTip.mm; sourceTree = ""; }; - 1FBE0A2E9ED2D152CC1D9833F6C7A9C6 /* ASBatchFetching.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASBatchFetching.mm; path = Source/Private/ASBatchFetching.mm; sourceTree = ""; }; - 20F81D70DF5D1073C6720482B6C22D53 /* ASAsciiArtBoxCreator.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASAsciiArtBoxCreator.mm; path = Source/Layout/ASAsciiArtBoxCreator.mm; sourceTree = ""; }; - 212B04CD850FD5C27BB5A749200F1C38 /* PINRemoteImage.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PINRemoteImage.modulemap; sourceTree = ""; }; - 21328B9DF462AD6B1267E304A81AB8FD /* ASLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayout.h; path = Source/Layout/ASLayout.h; sourceTree = ""; }; + 153CDAA7E2893700C4226503B3F7E0CF /* ASRecursiveUnfairLock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRecursiveUnfairLock.h; path = Source/Details/ASRecursiveUnfairLock.h; sourceTree = ""; }; + 1556D6D5C310D21F1F6570B9AAA70140 /* ASDimensionInternal.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDimensionInternal.mm; path = Source/Layout/ASDimensionInternal.mm; sourceTree = ""; }; + 1563E54ED0D8EAADD8B23DD9E695A4C0 /* _ASCollectionGalleryLayoutItem.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASCollectionGalleryLayoutItem.mm; path = Source/Private/_ASCollectionGalleryLayoutItem.mm; sourceTree = ""; }; + 15C80D074046D9ED56A3DFB11E613D9D /* TypeAliasses.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TypeAliasses.swift; sourceTree = ""; }; + 15E4F72EFEDBF482E6EA7FC3C9B045BC /* ASTextKitRenderer+TextChecking.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASTextKitRenderer+TextChecking.mm"; path = "Source/TextKit/ASTextKitRenderer+TextChecking.mm"; sourceTree = ""; }; + 1618D9D9C78605F98FD056F93E140550 /* ImageZoomControllerSettings+Equatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "ImageZoomControllerSettings+Equatable.swift"; sourceTree = ""; }; + 168588F383395609A225C17729EADFE8 /* ASDisplayNode+FrameworkPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+FrameworkPrivate.h"; path = "Source/Private/ASDisplayNode+FrameworkPrivate.h"; sourceTree = ""; }; + 1697C102E28F0ADF18FC253681444445 /* ASCollectionView.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionView.mm; path = Source/ASCollectionView.mm; sourceTree = ""; }; + 16A94C3E9D1D354B1FA7BFB225090329 /* UICollectionViewLayout+ASConvenience.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "UICollectionViewLayout+ASConvenience.mm"; path = "Source/Details/UICollectionViewLayout+ASConvenience.mm"; sourceTree = ""; }; + 17739224B8FFBBFD4A919676A9DB5B99 /* ASNetworkImageNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASNetworkImageNode.h; path = Source/ASNetworkImageNode.h; sourceTree = ""; }; + 17C0F831AF0AD17DC6B683449FD9CC26 /* ASCollectionLayoutState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutState.h; path = Source/Details/ASCollectionLayoutState.h; sourceTree = ""; }; + 18B0AE685477C6FF35E804AEB5CC74FB /* InjectableLoggers-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "InjectableLoggers-prefix.pch"; sourceTree = ""; }; + 18F1BEAE413D70F9613D56431D07F05C /* ASCollectionViewLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewLayoutController.h; path = Source/Details/ASCollectionViewLayoutController.h; sourceTree = ""; }; + 19013B6B61D3353D8B1996BC41ED22EF /* ASGraphicsContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASGraphicsContext.mm; path = Source/Details/ASGraphicsContext.mm; sourceTree = ""; }; + 19BEACB67CAFEBFC1ED66A82A7CEAC6C /* PINGIFAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINGIFAnimatedImage.m; path = Source/Classes/AnimatedImages/PINGIFAnimatedImage.m; sourceTree = ""; }; + 19C46A1F5BE9058D1B31FEFC6B3EEC63 /* ASCollectionViewLayoutFacilitatorProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewLayoutFacilitatorProtocol.h; path = Source/ASCollectionViewLayoutFacilitatorProtocol.h; sourceTree = ""; }; + 19CFFC5B9E6CC2B79A757940780E4809 /* PINCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCache.h; path = Source/PINCache.h; sourceTree = ""; }; + 19F6B2C5C172044761158C11A9A96621 /* ASCollectionNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionNode.mm; path = Source/ASCollectionNode.mm; sourceTree = ""; }; + 1AA1804B20C4BA59B74A32AC511B1713 /* PINCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINCache.m; path = Source/PINCache.m; sourceTree = ""; }; + 1AB0436DEE011645CA194E623E6C08C5 /* ASCollectionViewProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewProtocols.h; path = Source/ASCollectionViewProtocols.h; sourceTree = ""; }; + 1B000E5335F1D299484CA411EAD77450 /* ASTextAttribute.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextAttribute.h; path = Source/Private/TextExperiment/String/ASTextAttribute.h; sourceTree = ""; }; + 1B461C264744B763F9716CED13E8304C /* InjectableLoggers-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "InjectableLoggers-Info.plist"; sourceTree = ""; }; + 1B5474379A62711C3A3090973FF8C323 /* ASDispatch.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDispatch.mm; path = Source/Private/ASDispatch.mm; sourceTree = ""; }; + 1C2812E8C508184CDBAF31A4379A5723 /* ASCollectionLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayout.h; path = Source/Private/ASCollectionLayout.h; sourceTree = ""; }; + 1D30461653DA6AAEF282297EADDE6C6D /* ASCollectionLayoutCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutCache.h; path = Source/Private/ASCollectionLayoutCache.h; sourceTree = ""; }; + 1E3FE85A4B2BCDA182B605CDB5DBB8DB /* ASTextAttribute.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextAttribute.mm; path = Source/Private/TextExperiment/String/ASTextAttribute.mm; sourceTree = ""; }; + 1EFB738992A1ADC2BE3751D558350E17 /* ASTextLine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextLine.h; path = Source/Private/TextExperiment/Component/ASTextLine.h; sourceTree = ""; }; + 1F3CBC9D77FD5B66D00BA89359E50FE7 /* ASRangeController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRangeController.mm; path = Source/Details/ASRangeController.mm; sourceTree = ""; }; + 2075A4B105A9E0F67B8A3420DFBA3ED7 /* PINImage+WebP.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImage+WebP.m"; path = "Source/Classes/Categories/PINImage+WebP.m"; sourceTree = ""; }; + 21431E3065B17D68BBAC5602987EEF90 /* ASDisplayNode+InterfaceState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+InterfaceState.h"; path = "Source/ASDisplayNode+InterfaceState.h"; sourceTree = ""; }; 214924C9F0E2FAC0CB4EAEEAC304F1BB /* Pods-Zoomy_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Zoomy_Tests.release.xcconfig"; sourceTree = ""; }; - 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 22C347595B1851A1E5B0A3762BB18EC9 /* PINOperation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = PINOperation.framework; path = PINOperation.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 22C7A16ABC9185C93FB35F8D1A38EE48 /* ASRecursiveUnfairLock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRecursiveUnfairLock.h; path = Source/Details/ASRecursiveUnfairLock.h; sourceTree = ""; }; - 22D04588E915CA87458FE8343D2779A2 /* ASCollectionNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionNode.mm; path = Source/ASCollectionNode.mm; sourceTree = ""; }; - 2352CE5ABD68B97D2C20A75FE2B8F448 /* ASDisplayNodeTipState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeTipState.h; path = Source/Private/ASDisplayNodeTipState.h; sourceTree = ""; }; - 23695E05ACF79219EBCDE5C2958F0D74 /* ASDispatch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDispatch.h; path = Source/Private/ASDispatch.h; sourceTree = ""; }; - 23C2025A1786911B195905E0D5D2B2FC /* ASMapNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMapNode.h; path = Source/ASMapNode.h; sourceTree = ""; }; - 252EBBCA9827ECA85C255F6F5B58D251 /* ASDisplayNode+InterfaceState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+InterfaceState.h"; path = "Source/ASDisplayNode+InterfaceState.h"; sourceTree = ""; }; - 2566ED78C35450BA5FD2005C76B64425 /* ASTextNodeCommon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNodeCommon.h; path = Source/ASTextNodeCommon.h; sourceTree = ""; }; - 26245E1F996E74C2E922A30F3ED2D3E9 /* ASNodeController+Beta.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASNodeController+Beta.mm"; path = "Source/ASNodeController+Beta.mm"; sourceTree = ""; }; - 2640238F95E8A009DD6CFE7B65C34E9B /* ASPendingStateController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASPendingStateController.mm; path = Source/Private/ASPendingStateController.mm; sourceTree = ""; }; - 264EC3CABA35458466AEC4B4DACC46AA /* ASCollectionViewLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewLayoutController.h; path = Source/Details/ASCollectionViewLayoutController.h; sourceTree = ""; }; - 27C5BA4CCAE91E983D7C8C9D067168C9 /* ImageZoomControllerState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerState.swift; sourceTree = ""; }; - 28253AD44028A9D310E9A7C4E2F34231 /* PINRemoteImageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageManager.m; path = Source/Classes/PINRemoteImageManager.m; sourceTree = ""; }; - 285A45E26308C77E98740CEB3DA1101E /* ASMapNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASMapNode.mm; path = Source/ASMapNode.mm; sourceTree = ""; }; - 286CD9D4C899902427554B69AEB67772 /* NSMutableAttributedString+TextKitAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSMutableAttributedString+TextKitAdditions.h"; path = "Source/Details/NSMutableAttributedString+TextKitAdditions.h"; sourceTree = ""; }; - 29423EDA573890D6CA0D528B6D1D3269 /* PINRemoteImageDownloadQueue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageDownloadQueue.m; path = Source/Classes/PINRemoteImageDownloadQueue.m; sourceTree = ""; }; - 29ADC9D575218E44CB3B4434E2C47BEA /* ASMutableAttributedStringBuilder.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASMutableAttributedStringBuilder.mm; path = Source/Details/ASMutableAttributedStringBuilder.mm; sourceTree = ""; }; - 29AEC841809838E1FBD4FB000000901E /* PINCachedAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINCachedAnimatedImage.m; path = Source/Classes/AnimatedImages/PINCachedAnimatedImage.m; sourceTree = ""; }; - 29C587DED2BBD35B19E135E0E1AC63BC /* ZoomyLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ZoomyLogger.swift; sourceTree = ""; }; - 2ACA70DF8BDDEF5677F2ADD9A82261E8 /* UIView+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+ASConvenience.h"; path = "Source/Details/UIView+ASConvenience.h"; sourceTree = ""; }; - 2B07470A9306150D188132273127CF31 /* ASYogaUtilities.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASYogaUtilities.mm; path = Source/Layout/ASYogaUtilities.mm; sourceTree = ""; }; - 2BF44023A1917C6A267664CDCC906D27 /* ASLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASLayoutSpec.mm; path = Source/Layout/ASLayoutSpec.mm; sourceTree = ""; }; - 2CF418803B52917B4CDEEFEECE88DF2D /* ASPagerFlowLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASPagerFlowLayout.mm; path = Source/ASPagerFlowLayout.mm; sourceTree = ""; }; - 2DEA1E8382A2B2C35A6C1A9EAC3A087E /* PINCacheMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCacheMacros.h; path = Source/PINCacheMacros.h; sourceTree = ""; }; - 2E4AE2CCC6E863F878281B34B30F6FFC /* ASTableView+Undeprecated.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTableView+Undeprecated.h"; path = "Source/Private/ASTableView+Undeprecated.h"; sourceTree = ""; }; + 21EE2773F3C79088F0071460CD0433C7 /* PINRemoteImageManager+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINRemoteImageManager+Private.h"; path = "Source/Classes/PINRemoteImageManager+Private.h"; sourceTree = ""; }; + 220D778DF6D3BB45E14EF18549516AF7 /* ASDelegateProxy.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDelegateProxy.mm; path = Source/Details/ASDelegateProxy.mm; sourceTree = ""; }; + 229924D8EAEEC020747355F7941265D7 /* PINRemoteImageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageManager.m; path = Source/Classes/PINRemoteImageManager.m; sourceTree = ""; }; + 22AB87EEF08419D87CD7B63869817E1D /* PINRemoteWeakProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteWeakProxy.m; path = Source/Classes/PINRemoteWeakProxy.m; sourceTree = ""; }; + 22C347595B1851A1E5B0A3762BB18EC9 /* PINOperation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PINOperation.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 22D109FC09C04222622A33E7750D7643 /* ASCollectionNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionNode.h; path = Source/ASCollectionNode.h; sourceTree = ""; }; + 2321BFDF7A7BF190C1DCE0E4D175DF36 /* PINButton+PINRemoteImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINButton+PINRemoteImage.h"; path = "Source/Classes/include/PINButton+PINRemoteImage.h"; sourceTree = ""; }; + 238638299CCBABB2A4FA0768A080732E /* ASTextInput.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextInput.h; path = Source/Private/TextExperiment/Component/ASTextInput.h; sourceTree = ""; }; + 23A34852D7571C40B1F57F6978C437C4 /* ASThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASThread.h; path = Source/Details/ASThread.h; sourceTree = ""; }; + 240A9BD4EECE73A564FCDC42E7A35203 /* Side.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Side.swift; sourceTree = ""; }; + 24C95280DDBF1B216647DC50DD8E35F5 /* ASBatchContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASBatchContext.mm; path = Source/Details/ASBatchContext.mm; sourceTree = ""; }; + 24D8C47FE0E7DA22CB28B45FF4DED726 /* ASWeakMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASWeakMap.mm; path = Source/Private/ASWeakMap.mm; sourceTree = ""; }; + 2609443EEA2A32EE403E707D0572F9D7 /* ASAsciiArtBoxCreator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAsciiArtBoxCreator.h; path = Source/Layout/ASAsciiArtBoxCreator.h; sourceTree = ""; }; + 265855D3D2AF279E97701DA7779E70A3 /* ASLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutController.h; path = Source/Details/ASLayoutController.h; sourceTree = ""; }; + 2729346235A1EF46585A750ACC6F4126 /* ASBatchFetchingDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBatchFetchingDelegate.h; path = Source/Details/ASBatchFetchingDelegate.h; sourceTree = ""; }; + 276AB991EAC927FD7C3D0F3175E37042 /* CGRect+Difference.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGRect+Difference.swift"; sourceTree = ""; }; + 27990D3C91F8BA9D332FBE68E2775751 /* BounceOffsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BounceOffsets.swift; sourceTree = ""; }; + 27A91CE2CB94BB7B3F82B020DC588A81 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CoreMedia.framework; sourceTree = DEVELOPER_DIR; }; + 27B7C9717F02B14FD5F36AA14557AB11 /* UIImage+Color.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIImage+Color.swift"; sourceTree = ""; }; + 27CF84EEF4ECAF9F8FDB5259AB280B10 /* NSArray+Diffing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSArray+Diffing.h"; path = "Source/Details/NSArray+Diffing.h"; sourceTree = ""; }; + 27CFDDA4A05FD078952636CF1BA4BE40 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 2800D748DA8B5242EEFED6AC2283901D /* NSParagraphStyle+ASText.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSParagraphStyle+ASText.h"; path = "Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.h"; sourceTree = ""; }; + 288309C0A0B85677861ECC27CE99504A /* ASNodeController+Beta.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASNodeController+Beta.mm"; path = "Source/ASNodeController+Beta.mm"; sourceTree = ""; }; + 2948BC247C32FEAEBBD7ABDF5868196D /* ASInsetLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASInsetLayoutSpec.h; path = Source/Layout/ASInsetLayoutSpec.h; sourceTree = ""; }; + 298080512F81BC540FE52192C678D1FC /* PINOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperation.h; path = Source/PINOperation.h; sourceTree = ""; }; + 2AC31EF58C1CD0626B658B072A7EBAF8 /* ASBatchFetching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBatchFetching.h; path = Source/Private/ASBatchFetching.h; sourceTree = ""; }; + 2AE87F010BB241641A5655B985A653C6 /* _ASCollectionReusableView.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASCollectionReusableView.mm; path = Source/Details/_ASCollectionReusableView.mm; sourceTree = ""; }; + 2BA01D0006D36A0A50DA88B677CAC904 /* ASCollectionFlowLayoutDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionFlowLayoutDelegate.mm; path = Source/Details/ASCollectionFlowLayoutDelegate.mm; sourceTree = ""; }; + 2BDB8103640F2CC1D67C9C58171A5E8D /* CanManageZoomBehaviors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanManageZoomBehaviors.swift; sourceTree = ""; }; + 2BFA9B4CE54E1E697CA67579BE312597 /* ASAbstractLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAbstractLayoutController.h; path = Source/Details/ASAbstractLayoutController.h; sourceTree = ""; }; + 2C042B669A64064D7FC3E52DEBA0E071 /* ASTipsController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTipsController.mm; path = Source/Private/ASTipsController.mm; sourceTree = ""; }; + 2C3E4D9221467A6AE8193D74B696E4BF /* ASCollections.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollections.mm; path = Source/ASCollections.mm; sourceTree = ""; }; + 2D4435A927BF442E68357226A04D7421 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; }; + 2DADF593FC3453A7056F179131A40785 /* ASInternalHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASInternalHelpers.h; path = Source/Private/ASInternalHelpers.h; sourceTree = ""; }; + 2DED5930F943F0D3748F0B68C9814C9A /* CanLog.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLog.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLog.swift; sourceTree = ""; }; + 2EACF1E5973F81B5B80D4AEC7EEA6F72 /* ZoomyLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ZoomyLogger.swift; sourceTree = ""; }; 2ECAB2D10463A515B8622C35649FE2A5 /* Pods-Zoomy_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Zoomy_Tests-dummy.m"; sourceTree = ""; }; - 2FE925E84A281D06546AD497ECF45514 /* NSParagraphStyle+ASText.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSParagraphStyle+ASText.h"; path = "Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.h"; sourceTree = ""; }; - 2FF0E128FF2A7195FA58FADEB2B67B78 /* ASCellNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCellNode.h; path = Source/ASCellNode.h; sourceTree = ""; }; - 30A7CAD63165CA3F03F1EB41082C5271 /* NSData+ImageDetectors.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+ImageDetectors.m"; path = "Source/Classes/Categories/NSData+ImageDetectors.m"; sourceTree = ""; }; - 31182033736429F714F11A99D15B5A37 /* PINCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINCache.m; path = Source/PINCache.m; sourceTree = ""; }; - 3159FFF68D91838D2CC5D7DAA07DD14A /* ASAbsoluteLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASAbsoluteLayoutSpec.mm; path = Source/Layout/ASAbsoluteLayoutSpec.mm; sourceTree = ""; }; - 31959479D3789CFC54BD384F0D0E20A0 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/CoreMedia.framework; sourceTree = DEVELOPER_DIR; }; - 31C3C3A510E1FC44FB2F8FBE5BD8C95F /* ASRelativeLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASRelativeLayoutSpec.mm; path = Source/Layout/ASRelativeLayoutSpec.mm; sourceTree = ""; }; - 31E8320921F753F72E16B6995A77EBF3 /* PINRequestRetryStrategy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRequestRetryStrategy.h; path = Source/Classes/PINRequestRetryStrategy.h; sourceTree = ""; }; - 3208DEBA29C56FF8EBA5563EFAB53B48 /* PINMemoryCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINMemoryCache.m; path = Source/PINMemoryCache.m; sourceTree = ""; }; - 32E1A5A62805A96755862D0EA25E6BA4 /* NSArray+Diffing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSArray+Diffing.h"; path = "Source/Details/NSArray+Diffing.h"; sourceTree = ""; }; - 34264FCFBCD166A0BE6E3B41DBF13876 /* ASCollectionLayoutContext+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionLayoutContext+Private.h"; path = "Source/Private/ASCollectionLayoutContext+Private.h"; sourceTree = ""; }; - 3435983882FBE500A5D5F17D35799084 /* ASDelegateProxy.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDelegateProxy.mm; path = Source/Details/ASDelegateProxy.mm; sourceTree = ""; }; - 34B72E8FAB374BBB6BA3BC734730D1B8 /* ASCollectionLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayout.h; path = Source/Private/ASCollectionLayout.h; sourceTree = ""; }; - 34C2E7C5F0F15FD412B6E90CE66616C6 /* _ASScopeTimer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASScopeTimer.h; path = Source/Private/_ASScopeTimer.h; sourceTree = ""; }; - 3521512E9AA05650F6F76700EC1D65D9 /* CanLogMessageInFileInFunctionAtLine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessageInFileInFunctionAtLine.swift; path = InjectableLoggers/Classes/Protocols/CanLogMessageInFileInFunctionAtLine.swift; sourceTree = ""; }; - 35E06328EC3399B7E3571D2B013A22CD /* ASResponderChainEnumerator.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASResponderChainEnumerator.mm; path = Source/Private/ASResponderChainEnumerator.mm; sourceTree = ""; }; - 3606305E249E94F9CB41FE90831B0107 /* ASSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSectionController.h; path = Source/ASSectionController.h; sourceTree = ""; }; - 3622A7B1520B6EA76FA4B4AFEA470CE0 /* ASViewController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASViewController.mm; path = Source/ASViewController.mm; sourceTree = ""; }; - 36B6B10464BF4A4C825532E2CC503B37 /* ASTableViewInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableViewInternal.h; path = Source/ASTableViewInternal.h; sourceTree = ""; }; - 3728B36A01891C41B0E5AAC664EC09FE /* _ASCoreAnimationExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASCoreAnimationExtras.mm; path = Source/Private/_ASCoreAnimationExtras.mm; sourceTree = ""; }; - 37BFD09009E1CA2D06CA1E0299275DFD /* ASScrollDirection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASScrollDirection.h; path = Source/Details/ASScrollDirection.h; sourceTree = ""; }; - 383761BD6584FEC55E5C246F77B1B93A /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = DEVELOPER_DIR; }; - 385E6F060FBF7CFBD72B759FD50D0667 /* PINImage+ScaledImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImage+ScaledImage.h"; path = "Source/Classes/Categories/PINImage+ScaledImage.h"; sourceTree = ""; }; - 38C81F994E42B0DB94073425D99DAC06 /* PINRemoteImageCategoryManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageCategoryManager.m; path = Source/Classes/PINRemoteImageCategoryManager.m; sourceTree = ""; }; - 39AAC467404002DC03ECB50462243558 /* InjectableLoggers.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = InjectableLoggers.xcconfig; sourceTree = ""; }; - 3A590B674BD9CFE88538617C0FE64948 /* ASDisplayNode+Yoga.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Yoga.h"; path = "Source/ASDisplayNode+Yoga.h"; sourceTree = ""; }; - 3B8177727C674D026E37566A26B57945 /* ASCollectionViewProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewProtocols.h; path = Source/ASCollectionViewProtocols.h; sourceTree = ""; }; - 3B8A34FE38ED02DDC1550A4B16A33A3B /* ASLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutSpec.h; path = Source/Layout/ASLayoutSpec.h; sourceTree = ""; }; - 3BF2212F3A7D876C37A5DD2521386AF8 /* ASDisplayNode+Layout.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+Layout.mm"; path = "Source/ASDisplayNode+Layout.mm"; sourceTree = ""; }; - 3BF7B14A070E69EF1B3DCDCDC5341299 /* ASTableNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableNode.h; path = Source/ASTableNode.h; sourceTree = ""; }; - 3CE549225FFDA099F6B291DEA1171623 /* PINOperation.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PINOperation.modulemap; sourceTree = ""; }; - 3D4DA64813A14F793D42CFE74070D648 /* ASTextNode2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNode2.h; path = Source/ASTextNode2.h; sourceTree = ""; }; + 2F5C8DE6CFB8EC60F48B06A6985E2BB5 /* ASConfiguration.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASConfiguration.mm; path = Source/ASConfiguration.mm; sourceTree = ""; }; + 2FBDA1D7FC21A68B8185A1567B2052E0 /* ASConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASConfiguration.h; path = Source/ASConfiguration.h; sourceTree = ""; }; + 301AA79FF07CF4C0F6E48120A66F49CC /* PINRemoteImageDownloadTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageDownloadTask.h; path = Source/Classes/PINRemoteImageDownloadTask.h; sourceTree = ""; }; + 303F4D4B9D072C75B58EF0D2D7630454 /* AsyncDisplayKit+Tips.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "AsyncDisplayKit+Tips.mm"; path = "Source/Debug/AsyncDisplayKit+Tips.mm"; sourceTree = ""; }; + 306C52DBD27D295784295FD504964C94 /* ASDefaultPlaybackButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDefaultPlaybackButton.h; path = Source/Private/ASDefaultPlaybackButton.h; sourceTree = ""; }; + 30A71EB2149D0A7CDCA3CA7E9039E3AA /* NSMutableAttributedString+TextKitAdditions.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "NSMutableAttributedString+TextKitAdditions.mm"; path = "Source/Details/NSMutableAttributedString+TextKitAdditions.mm"; sourceTree = ""; }; + 30D28688CC6CE710EEF7F4DBA6B1C90C /* PINRemoteImageProcessorTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageProcessorTask.h; path = Source/Classes/PINRemoteImageProcessorTask.h; sourceTree = ""; }; + 30DD3DAFDA45E1C0E7B07DC0F2E7F0D3 /* NSMutableAttributedString+TextKitAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSMutableAttributedString+TextKitAdditions.h"; path = "Source/Details/NSMutableAttributedString+TextKitAdditions.h"; sourceTree = ""; }; + 310BD706DB638309D39CAFB2E12E51E8 /* _ASDisplayView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASDisplayView.h; path = Source/Details/_ASDisplayView.h; sourceTree = ""; }; + 31504EBDF705C4C91C4E481E42167F36 /* ASDisplayNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Beta.h"; path = "Source/ASDisplayNode+Beta.h"; sourceTree = ""; }; + 31A38BD86467F4397BAAE01B7769BEC5 /* NSHTTPURLResponse+MaxAge.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSHTTPURLResponse+MaxAge.m"; path = "Source/Classes/Categories/NSHTTPURLResponse+MaxAge.m"; sourceTree = ""; }; + 326EBDBAEB04836A41AA1E86991F8885 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASMainSerialQueue.mm; path = Source/Details/ASMainSerialQueue.mm; sourceTree = ""; }; + 327665699F63693627351B86322A4BBC /* PINSpeedRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINSpeedRecorder.m; path = Source/Classes/PINSpeedRecorder.m; sourceTree = ""; }; + 3405A596EC79FF405C0EBA48F483F456 /* PINOperation-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINOperation-umbrella.h"; sourceTree = ""; }; + 340A9CEE164056E549AB70B491ABB841 /* ASImageContainerProtocolCategories.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASImageContainerProtocolCategories.mm; path = Source/Details/ASImageContainerProtocolCategories.mm; sourceTree = ""; }; + 34E1BFF37B6AB67835029387BC31D4C3 /* ASCollectionViewFlowLayoutInspector.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionViewFlowLayoutInspector.mm; path = Source/Private/ASCollectionViewFlowLayoutInspector.mm; sourceTree = ""; }; + 3518A0BB390B2AA90F7647C5B8E71E30 /* NSIndexSet+ASHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSIndexSet+ASHelpers.h"; path = "Source/Details/NSIndexSet+ASHelpers.h"; sourceTree = ""; }; + 357620DEBE7E9C5DCAAB4AFEDA157938 /* ASBatchFetching.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASBatchFetching.mm; path = Source/Private/ASBatchFetching.mm; sourceTree = ""; }; + 365171A2F8B907C0ABA54E5D81DEC78F /* ASAbstractLayoutController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASAbstractLayoutController.mm; path = Source/Details/ASAbstractLayoutController.mm; sourceTree = ""; }; + 368616C4DF8B8A2508BCA3C152DE6171 /* ASLayoutElementStylePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElementStylePrivate.h; path = Source/Private/Layout/ASLayoutElementStylePrivate.h; sourceTree = ""; }; + 3696C349E675BB987AA159ECE86A472A /* PINAlternateRepresentationProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINAlternateRepresentationProvider.h; path = Source/Classes/include/PINAlternateRepresentationProvider.h; sourceTree = ""; }; + 36E00A3E64E6BBD8E773493B48077674 /* ASTextKitFontSizeAdjuster.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitFontSizeAdjuster.h; path = Source/TextKit/ASTextKitFontSizeAdjuster.h; sourceTree = ""; }; + 370CE66493F16C4B60162BC899D50685 /* ASImageNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASImageNode.h; path = Source/ASImageNode.h; sourceTree = ""; }; + 371B020D432D68BA6D7638A16BE2D91A /* ASDisplayNodeLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeLayout.h; path = Source/Private/ASDisplayNodeLayout.h; sourceTree = ""; }; + 372E2B51845B9764F1568E5E09EF43FC /* ASInternalHelpers.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASInternalHelpers.mm; path = Source/Private/ASInternalHelpers.mm; sourceTree = ""; }; + 377942A736134FFDA949F494767752F1 /* Logger.Settings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.Settings.swift; path = InjectableLoggers/Classes/Structs/Logger.Settings.swift; sourceTree = ""; }; + 3781AD18516F84156D9A016E7EF16502 /* PINAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINAnimatedImage.h; path = Source/Classes/include/PINAnimatedImage.h; sourceTree = ""; }; + 37E5CD5480F273CCD7018C4EFA617514 /* ASCollectionGalleryLayoutDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionGalleryLayoutDelegate.mm; path = Source/Details/ASCollectionGalleryLayoutDelegate.mm; sourceTree = ""; }; + 3827902523392E04E0D92EE4073D9308 /* ASControlNode+Subclasses.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASControlNode+Subclasses.h"; path = "Source/ASControlNode+Subclasses.h"; sourceTree = ""; }; + 38CDE6D0609F3155BF724C4A383D3D69 /* PINGIFAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINGIFAnimatedImage.h; path = Source/Classes/include/PINGIFAnimatedImage.h; sourceTree = ""; }; + 38DCEAAC959C2F8E5E2B80424211C42A /* ASDataController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDataController.mm; path = Source/Details/ASDataController.mm; sourceTree = ""; }; + 3961C9750DE5B388A186362677458C58 /* PINRemoteImageCallbacks.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageCallbacks.m; path = Source/Classes/PINRemoteImageCallbacks.m; sourceTree = ""; }; + 39628548B97DE9F4CF62A1084EFDC199 /* ASTableNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTableNode+Beta.h"; path = "Source/ASTableNode+Beta.h"; sourceTree = ""; }; + 39AAA51020546A6E36D2E221A7CFEAA4 /* ASControlNode+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASControlNode+Private.h"; path = "Source/Private/ASControlNode+Private.h"; sourceTree = ""; }; + 3A0D3879E96DD88097B82C514252031F /* ASDisplayNode+Yoga.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+Yoga.mm"; path = "Source/ASDisplayNode+Yoga.mm"; sourceTree = ""; }; + 3A1161DF44833F8207702FDDDADDC190 /* ASTextNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNode.h; path = Source/ASTextNode.h; sourceTree = ""; }; + 3A7A6660529033C8FB462698E66D5056 /* ASStackLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStackLayoutSpec.mm; path = Source/Layout/ASStackLayoutSpec.mm; sourceTree = ""; }; + 3B342DA9EE3B882BD437A5542477B69D /* PINResume.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINResume.h; path = Source/Classes/PINResume.h; sourceTree = ""; }; + 3B5DD44288F18DA76B04EEA1C33CB9D3 /* ASObjectDescriptionHelpers.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASObjectDescriptionHelpers.mm; path = Source/Details/ASObjectDescriptionHelpers.mm; sourceTree = ""; }; + 3BA08AA67D939C3E23A4D3312A8ACA70 /* ImageZoomControllerContentState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerContentState.swift; sourceTree = ""; }; + 3BAD4FB41EAFF0AE7B2153EF48C5BB88 /* PINImage+ScaledImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImage+ScaledImage.h"; path = "Source/Classes/Categories/PINImage+ScaledImage.h"; sourceTree = ""; }; + 3CA0EDA238063FF0C538D31F2961EAA5 /* PINMemoryCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINMemoryCache.m; path = Source/PINMemoryCache.m; sourceTree = ""; }; + 3CC29518FB41642415C151CB182BC02A /* ASAbsoluteLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASAbsoluteLayoutSpec.mm; path = Source/Layout/ASAbsoluteLayoutSpec.mm; sourceTree = ""; }; + 3D3E8FFD05B04AEC48C46759AA2FC4E3 /* ASImageNode+CGExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASImageNode+CGExtras.mm"; path = "Source/Private/ASImageNode+CGExtras.mm"; sourceTree = ""; }; + 3DB890B5C2AB3082392D9AB6F63D1103 /* PINOperationGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationGroup.h; path = Source/PINOperationGroup.h; sourceTree = ""; }; 3DF75328C738F4C8E40C3924A1C776D6 /* PINOperation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PINOperation.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 3E08232F3108F02C86EA8BAD407FEBB6 /* ASStackLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASStackLayoutSpec.mm; path = Source/Layout/ASStackLayoutSpec.mm; sourceTree = ""; }; - 3E4CBF6674EF31AA91520974C6E01BD9 /* ASTextKitRenderer+TextChecking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTextKitRenderer+TextChecking.h"; path = "Source/TextKit/ASTextKitRenderer+TextChecking.h"; sourceTree = ""; }; - 3E8220DCF4A5EA772D044B1A50261387 /* ASTextKitEntityAttribute.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitEntityAttribute.mm; path = Source/TextKit/ASTextKitEntityAttribute.mm; sourceTree = ""; }; - 3EE6623F7681F2A64EA741D31CCF2563 /* ASCollectionNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionNode.h; path = Source/ASCollectionNode.h; sourceTree = ""; }; + 3E886463829E8179D30A3CC87E9F971C /* ASPhotosFrameworkImageRequest.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASPhotosFrameworkImageRequest.mm; path = Source/Details/ASPhotosFrameworkImageRequest.mm; sourceTree = ""; }; + 3EADEF54394FEF3203A0D14FB0FBB32E /* Logger.FormatSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.FormatSettings.swift; path = InjectableLoggers/Classes/Structs/Logger.FormatSettings.swift; sourceTree = ""; }; + 3EAF61F88391C9B13AB0AE7D2ABB1CDF /* ASStackLayoutSpecUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutSpecUtilities.h; path = Source/Private/Layout/ASStackLayoutSpecUtilities.h; sourceTree = ""; }; + 3EEE47F5587BC9E53C27A71C7BE04F1F /* ASDisplayNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNode.h; path = Source/ASDisplayNode.h; sourceTree = ""; }; + 3F1C5EEC6A9FC7250D38B875AF12D067 /* ASCollectionLayoutCache.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionLayoutCache.mm; path = Source/Private/ASCollectionLayoutCache.mm; sourceTree = ""; }; 3F8B2B31B3B3251BB3A7793A29507A9F /* Pods-Zoomy_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Zoomy_Tests-acknowledgements.markdown"; sourceTree = ""; }; - 3FE9A85EBB7C7832A0718380B6834F01 /* PINRemoteImageDownloadTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageDownloadTask.m; path = Source/Classes/PINRemoteImageDownloadTask.m; sourceTree = ""; }; + 3FB144D267D64DAD5769709D3C613A09 /* ASNavigationController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASNavigationController.mm; path = Source/ASNavigationController.mm; sourceTree = ""; }; + 3FBE47550DB37A88FC7CFE0100233D15 /* _ASDisplayViewAccessiblity.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASDisplayViewAccessiblity.h; path = Source/Details/_ASDisplayViewAccessiblity.h; sourceTree = ""; }; + 4012AE46C9AA9C1919E2A94BD8460C38 /* ImageZoomControllerDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerDelegate.swift; sourceTree = ""; }; + 40161622AE9EB7912BC3BF1CBBC09039 /* ImageZoomController.Factory.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomController.Factory.swift; sourceTree = ""; }; 406975D5F17381231A901E0D62D7A138 /* PINCache.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PINCache.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 417957CD232E64384DA98C2BA8ED91D2 /* UIImage+Color.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIImage+Color.swift"; sourceTree = ""; }; - 42ADB8EFEEAEEBFE11A460E7A0B67630 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASEqualityHelpers.h; path = Source/Base/ASEqualityHelpers.h; sourceTree = ""; }; - 4376ADF353DC2577C335D8807B54245F /* ASDisplayNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Beta.h"; path = "Source/ASDisplayNode+Beta.h"; sourceTree = ""; }; - 437A7EB85DC2C2F59274B60DA2238D0B /* CGRect+Difference.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGRect+Difference.swift"; sourceTree = ""; }; - 44265DBCB67F313E59BFA3FCE8D51190 /* ASMainThreadDeallocation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMainThreadDeallocation.h; path = Source/ASMainThreadDeallocation.h; sourceTree = ""; }; - 443574802076FB68086CBFC32F215FC9 /* ASEditableTextNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASEditableTextNode.h; path = Source/ASEditableTextNode.h; sourceTree = ""; }; - 444CA15EA0AAE68E84B2D0D2BF11BF8D /* PINRemoteImageDownloadTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageDownloadTask.h; path = Source/Classes/PINRemoteImageDownloadTask.h; sourceTree = ""; }; - 445246B3B756F5F96B99AEF7BBA3F014 /* ASLayoutSpecPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutSpecPrivate.h; path = Source/Private/Layout/ASLayoutSpecPrivate.h; sourceTree = ""; }; - 44B1FF984C74EB2DBF074043ABBA4F0F /* ASMultiplexImageNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASMultiplexImageNode.mm; path = Source/ASMultiplexImageNode.mm; sourceTree = ""; }; - 44F8BC427F71546D5619B405BCE1DD36 /* ASTextKitEntityAttribute.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitEntityAttribute.h; path = Source/TextKit/ASTextKitEntityAttribute.h; sourceTree = ""; }; - 45732382F06CCCBEF2548090FD84E0FE /* _ASAsyncTransactionContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASAsyncTransactionContainer.h; path = Source/Details/Transactions/_ASAsyncTransactionContainer.h; sourceTree = ""; }; - 4633B6D7E44B708326E2E31CBFD78C9D /* ASTextKitFontSizeAdjuster.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitFontSizeAdjuster.h; path = Source/TextKit/ASTextKitFontSizeAdjuster.h; sourceTree = ""; }; - 46613995C9582C0CA35A0AA88C407A51 /* Zoomy.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = Zoomy.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 46AB7C0E0E8242F41B205E4DBD3C10E3 /* AsyncDisplayKit+Tips.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "AsyncDisplayKit+Tips.mm"; path = "Source/Debug/AsyncDisplayKit+Tips.mm"; sourceTree = ""; }; - 46F73ED5DBD4B0E2A039193D5663B7A5 /* ASTableNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTableNode+Beta.h"; path = "Source/ASTableNode+Beta.h"; sourceTree = ""; }; - 4738C3EE9ADB91DAF08960FDEDE3D702 /* ASCollectionFlowLayoutDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionFlowLayoutDelegate.h; path = Source/Details/ASCollectionFlowLayoutDelegate.h; sourceTree = ""; }; - 47887C414E19B0A79D466E48240E56AF /* ASBasicImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBasicImageDownloader.h; path = Source/Details/ASBasicImageDownloader.h; sourceTree = ""; }; - 47BEA003F98AF411A6A7DF57679996D9 /* ASCollectionLayoutDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutDefines.h; path = Source/Private/ASCollectionLayoutDefines.h; sourceTree = ""; }; - 49091F146299E5C296CCD271B6BCF996 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; }; - 49405BF411A045F9971308FAA95292D5 /* ImageZoomController.Factory.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomController.Factory.swift; sourceTree = ""; }; - 49E96E5D11156E2C12B0FF6F8ACD6B3D /* PINOperation.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINOperation.xcconfig; sourceTree = ""; }; - 4A2517A7943CC5A852D4396DD7B89109 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsPresentingImageViewOverlayState.swift; sourceTree = ""; }; - 4A522E2430B709898EF722555E8A4DDB /* ASStackLayoutSpecUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutSpecUtilities.h; path = Source/Private/Layout/ASStackLayoutSpecUtilities.h; sourceTree = ""; }; - 4A70B3A34B45D1967D684671ED89E5B6 /* ASNetworkImageLoadInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASNetworkImageLoadInfo.h; path = Source/ASNetworkImageLoadInfo.h; sourceTree = ""; }; - 4A8933680D912A0075750162CB15EF9F /* ASYogaUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASYogaUtilities.h; path = Source/Layout/ASYogaUtilities.h; sourceTree = ""; }; - 4AA4FC6584F3CD6AEA868108B7CA6DAB /* ASBackgroundLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBackgroundLayoutSpec.h; path = Source/Layout/ASBackgroundLayoutSpec.h; sourceTree = ""; }; - 4AD6A102FE402E0C21F9D0C9B94E7115 /* UIResponder+AsyncDisplayKit.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "UIResponder+AsyncDisplayKit.mm"; path = "Source/UIResponder+AsyncDisplayKit.mm"; sourceTree = ""; }; - 4ADFA05F60AA04316A5BB156A0555D0B /* PINOperation-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PINOperation-dummy.m"; sourceTree = ""; }; - 4AE0C290967EDFE3B12512326F5BFD16 /* DefaultAnimators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DefaultAnimators.swift; sourceTree = ""; }; - 4AEA21345119E8A9D19E256F0B3EA1C0 /* ASTableNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTableNode.mm; path = Source/ASTableNode.mm; sourceTree = ""; }; - 4B2586BBD79ACE8F25C2855963C00306 /* ASMutableAttributedStringBuilder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMutableAttributedStringBuilder.h; path = Source/Details/ASMutableAttributedStringBuilder.h; sourceTree = ""; }; - 4B50F73FC9907B3B5250EDDF7ED1B18E /* ASStackPositionedLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackPositionedLayout.h; path = Source/Private/Layout/ASStackPositionedLayout.h; sourceTree = ""; }; - 4BF08A0A062F57E0ABEE60019B8BFE6A /* PINWebPAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINWebPAnimatedImage.h; path = Source/Classes/AnimatedImages/PINWebPAnimatedImage.h; sourceTree = ""; }; - 4C3E8E8DF87C3112F7930C4F95399416 /* ASLayoutElementExtensibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElementExtensibility.h; path = Source/Layout/ASLayoutElementExtensibility.h; sourceTree = ""; }; - 4C4D6B95F7D6F2215E963E83CE181D37 /* ASMainSerialQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMainSerialQueue.h; path = Source/Details/ASMainSerialQueue.h; sourceTree = ""; }; - 4D45CA8A0CD161A2FD16B69E7A3F23C4 /* ASLocking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLocking.h; path = Source/ASLocking.h; sourceTree = ""; }; - 4DDC011BFAD764B9FB35A1A1F6280062 /* ASDefaultPlaybackButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDefaultPlaybackButton.h; path = Source/Private/ASDefaultPlaybackButton.h; sourceTree = ""; }; - 4DE06937FCEE16FB4B9F13D19D95CF74 /* NSAttributedString+ASText.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "NSAttributedString+ASText.mm"; path = "Source/Private/TextExperiment/Utility/NSAttributedString+ASText.mm"; sourceTree = ""; }; - 4E52B15796BB4A915D828880D8E9AA75 /* NSObject+AsociatedKeyForImageZoomControllers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "NSObject+AsociatedKeyForImageZoomControllers.swift"; sourceTree = ""; }; - 4E6A03617F6864E29B9A5454452C1AE3 /* ASDisplayNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNode.h; path = Source/ASDisplayNode.h; sourceTree = ""; }; - 4EC82CF26F151D3049C9FF32F22AF94D /* ASHighlightOverlayLayer.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASHighlightOverlayLayer.mm; path = Source/Details/ASHighlightOverlayLayer.mm; sourceTree = ""; }; - 4EFD085094FB76099386A32CCCDDB062 /* ASDisplayNodeInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeInternal.h; path = Source/Private/ASDisplayNodeInternal.h; sourceTree = ""; }; - 4F0AFD63DC30E3247C4918C6BEA9A0AE /* ASDisplayNode+DebugTiming.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+DebugTiming.mm"; path = "Source/Private/ASDisplayNode+DebugTiming.mm"; sourceTree = ""; }; - 4FF0F8D6BD0C7F366D8BCA8064C2636D /* PINWebPAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINWebPAnimatedImage.m; path = Source/Classes/AnimatedImages/PINWebPAnimatedImage.m; sourceTree = ""; }; - 4FF46F97C823C0B402802B311E54781C /* ASPagerNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASPagerNode.mm; path = Source/ASPagerNode.mm; sourceTree = ""; }; - 501BF04BC8D41B8C49F2412A7F6EA9E5 /* ASTextDebugOption.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextDebugOption.h; path = Source/Private/TextExperiment/Component/ASTextDebugOption.h; sourceTree = ""; }; - 504B06FD3DACEEAFDEA8D5E809A7095B /* ASMutableElementMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASMutableElementMap.mm; path = Source/Private/ASMutableElementMap.mm; sourceTree = ""; }; - 5062F79F55E2B3E2E71540B5210A7541 /* ASTabBarController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTabBarController.mm; path = Source/ASTabBarController.mm; sourceTree = ""; }; - 50FE37FFD7EF2429C10029089C508EBC /* ASTipNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipNode.h; path = Source/Private/ASTipNode.h; sourceTree = ""; }; - 513C72B75C74E39500ECC94B59716DC5 /* Pods_Zoomy_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Zoomy_Tests.framework; path = "Pods-Zoomy_Tests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - 514733900AE2783243A60B99D2A1009B /* PINOperation-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINOperation-prefix.pch"; sourceTree = ""; }; - 5249F6990C1876E77A173D504374E85A /* _ASCollectionReusableView.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASCollectionReusableView.mm; path = Source/Details/_ASCollectionReusableView.mm; sourceTree = ""; }; - 538A265EC6AEC4BBC85EC2796FB9D3BE /* PINRemoteImageTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageTask.h; path = Source/Classes/PINRemoteImageTask.h; sourceTree = ""; }; - 53BF6FEFB38F9EA8AE1B2C5E3FE6DD85 /* ASNetworkImageNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASNetworkImageNode.mm; path = Source/ASNetworkImageNode.mm; sourceTree = ""; }; - 53EB558A5AE8A80267886C93479C1753 /* UIView+layoutHelpers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIView+layoutHelpers.swift"; sourceTree = ""; }; - 54E63B392FE4A4F0BA38E50DB0D4ECD5 /* ASStackLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutSpec.h; path = Source/Layout/ASStackLayoutSpec.h; sourceTree = ""; }; - 551ECA207D97BC65B3FF2EC1D0187E25 /* ASTipsController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipsController.h; path = Source/Private/ASTipsController.h; sourceTree = ""; }; - 56E68C5787A7BC6FABD14F34D978338E /* Zoomy-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Zoomy-dummy.m"; sourceTree = ""; }; - 5725152FA9CBD3409857DF7D14892C1D /* ASCollectionLayoutCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutCache.h; path = Source/Private/ASCollectionLayoutCache.h; sourceTree = ""; }; - 577ABC84D61A466B9DC126551BCA72E8 /* UIGestureRecognizerState+CustomStringConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizerState+CustomStringConvertible.swift"; sourceTree = ""; }; - 5834B039278C6686064003CC4DF97395 /* _ASTransitionContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASTransitionContext.mm; path = Source/_ASTransitionContext.mm; sourceTree = ""; }; - 583C97D8927B51E6485A4BAD1EE6C61D /* ASTextLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextLayout.mm; path = Source/Private/TextExperiment/Component/ASTextLayout.mm; sourceTree = ""; }; + 408A5ACE5EC400AE7CEBD7C6338B76F5 /* ASCollectionLayoutDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutDefines.h; path = Source/Private/ASCollectionLayoutDefines.h; sourceTree = ""; }; + 409C4A8ACE8739BE0634656BDA26878E /* ASCollectionView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionView.h; path = Source/ASCollectionView.h; sourceTree = ""; }; + 40D046AE2D842A61F6773318B2AED5EF /* ASDisplayNode+DebugTiming.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+DebugTiming.h"; path = "Source/Private/ASDisplayNode+DebugTiming.h"; sourceTree = ""; }; + 40FF8F46258CC48006CE98E0E8C827FD /* ASPagerNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASPagerNode.mm; path = Source/ASPagerNode.mm; sourceTree = ""; }; + 411BC26AEB991FC58D93C8947E77F4BE /* ASTipsController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipsController.h; path = Source/Private/ASTipsController.h; sourceTree = ""; }; + 41FA311245598CBA5457902CA98F6E61 /* ASMultiplexImageNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASMultiplexImageNode.mm; path = Source/ASMultiplexImageNode.mm; sourceTree = ""; }; + 424205752E50C0BA7AD6C7C527C90AD1 /* ASWeakMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASWeakMap.h; path = Source/Private/ASWeakMap.h; sourceTree = ""; }; + 4281A047ADE807364869D0EC4C706EF6 /* ConfigurableUsingClosure.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConfigurableUsingClosure.swift; sourceTree = ""; }; + 42BE1A9D7E289850DE3E3703B8B59B2E /* ASDispatch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDispatch.h; path = Source/Private/ASDispatch.h; sourceTree = ""; }; + 42EC66579E3600DB1C45F90542FFCF49 /* ASLayoutElementExtensibility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElementExtensibility.h; path = Source/Layout/ASLayoutElementExtensibility.h; sourceTree = ""; }; + 43869A044BD5D3313051C1FB0FA1CC40 /* ASWeakSet.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASWeakSet.h; path = Source/Details/ASWeakSet.h; sourceTree = ""; }; + 43C20F8B4080DCC6F47FE97ECA3E5486 /* _ASAsyncTransaction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASAsyncTransaction.h; path = Source/Details/Transactions/_ASAsyncTransaction.h; sourceTree = ""; }; + 43DCE70B2460DEDE2FD73D6A661057E2 /* ASImageNode+AnimatedImagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASImageNode+AnimatedImagePrivate.h"; path = "Source/Private/ASImageNode+AnimatedImagePrivate.h"; sourceTree = ""; }; + 444483F0B2D3A9B3C7257762F9297D60 /* UIImage+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+ASConvenience.h"; path = "Source/UIImage+ASConvenience.h"; sourceTree = ""; }; + 4503752DE626CEFFDC467B93D6760868 /* ASNodeController+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASNodeController+Beta.h"; path = "Source/ASNodeController+Beta.h"; sourceTree = ""; }; + 4511DC1ED7A4174E351EB4F214894AC1 /* ASCollectionElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionElement.h; path = Source/Details/ASCollectionElement.h; sourceTree = ""; }; + 46310E5AB97B1359090388D99D9A9CD0 /* Texture.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Texture.release.xcconfig; sourceTree = ""; }; + 468BEF0C99D14026C3FCCE9045D3FE0B /* ASCollectionLayoutDefines.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionLayoutDefines.mm; path = Source/Private/ASCollectionLayoutDefines.mm; sourceTree = ""; }; + 46BAB278C37D8CD0A78E57EBDAFFD703 /* PINImage+DecodedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImage+DecodedImage.h"; path = "Source/Classes/Categories/PINImage+DecodedImage.h"; sourceTree = ""; }; + 46C1ADF815AD1AC88EAD0E635BB938B9 /* ASTextKitRenderer+Positioning.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTextKitRenderer+Positioning.h"; path = "Source/TextKit/ASTextKitRenderer+Positioning.h"; sourceTree = ""; }; + 46CD0F5DE0D2F59A5681151F4D1EDBC1 /* ASScrollNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASScrollNode.mm; path = Source/ASScrollNode.mm; sourceTree = ""; }; + 4717228A634CE28E966300DE88992C3A /* InjectableLoggers-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "InjectableLoggers-umbrella.h"; sourceTree = ""; }; + 47B21A7594492D19411EB2B50736A93B /* ASCenterLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCenterLayoutSpec.mm; path = Source/Layout/ASCenterLayoutSpec.mm; sourceTree = ""; }; + 47D53418A1AF4E0E9F8A9A6A6E85FE2F /* ASRelativeLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRelativeLayoutSpec.h; path = Source/Layout/ASRelativeLayoutSpec.h; sourceTree = ""; }; + 48DDC75CC866EBE491AD3724F92861C6 /* ASPageTable.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASPageTable.mm; path = Source/Details/ASPageTable.mm; sourceTree = ""; }; + 4915512699D90A7C7C29F8F493235B79 /* _ASCollectionViewCell.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASCollectionViewCell.mm; path = Source/Details/_ASCollectionViewCell.mm; sourceTree = ""; }; + 49A30867A82786A03C25B75416C6A599 /* InjectableLoggers.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = InjectableLoggers.modulemap; sourceTree = ""; }; + 4A3E448B9053C61DFE2DFCF6CBA4ACA7 /* PINOperationMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationMacros.h; path = Source/PINOperationMacros.h; sourceTree = ""; }; + 4A5C0BBAAA11ABB306A67D1CE1F475FB /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; }; + 4A9EECB4E20FA3E0A3CC8F611CA69F56 /* SpringAnimator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SpringAnimator.swift; sourceTree = ""; }; + 4AF1C172FB6FEB6970604804FE237F4D /* PINSpeedRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINSpeedRecorder.h; path = Source/Classes/PINSpeedRecorder.h; sourceTree = ""; }; + 4BF24D2130002A993A0633A50C598F0F /* PINAnimatedImageView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINAnimatedImageView.h; path = Source/Classes/include/PINAnimatedImageView.h; sourceTree = ""; }; + 4C602B3BA1E2B5E8FC405E54B8C10F5E /* PINAnimatedImageView+PINRemoteImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINAnimatedImageView+PINRemoteImage.m"; path = "Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m"; sourceTree = ""; }; + 4CD3F57888B836CD8BBDEE5A0761834F /* ASTabBarController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTabBarController.mm; path = Source/ASTabBarController.mm; sourceTree = ""; }; + 4CD4A80CBB44F35AB6DC6F1CD500C93C /* _ASDisplayViewAccessiblity.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASDisplayViewAccessiblity.mm; path = Source/Details/_ASDisplayViewAccessiblity.mm; sourceTree = ""; }; + 4D501F0E961A620207729EC46BD2A385 /* ASAbsoluteLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAbsoluteLayoutSpec.h; path = Source/Layout/ASAbsoluteLayoutSpec.h; sourceTree = ""; }; + 4DF39BEE8B1A3AA7DE7BF57F9E71C5EB /* ASCornerLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCornerLayoutSpec.h; path = Source/Layout/ASCornerLayoutSpec.h; sourceTree = ""; }; + 4E68C30C5EACF8A5292490A67CA0F259 /* ASStackUnpositionedLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackUnpositionedLayout.h; path = Source/Private/Layout/ASStackUnpositionedLayout.h; sourceTree = ""; }; + 4EB5231AD49D7544AA0B2B2C57B47080 /* _ASCollectionReusableView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionReusableView.h; path = Source/Details/_ASCollectionReusableView.h; sourceTree = ""; }; + 4F70B8787ECCD2A332EB261E7189325E /* PINDisplayLink.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINDisplayLink.m; path = Source/Classes/PINDisplayLink.m; sourceTree = ""; }; + 5018A23014FEB83B19C3753F33FFEFC0 /* ASLayout+IGListDiffKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASLayout+IGListDiffKit.h"; path = "Source/Layout/ASLayout+IGListDiffKit.h"; sourceTree = ""; }; + 50E2F80499CEA6B33FF927221C7377BC /* PINRequestRetryStrategy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRequestRetryStrategy.m; path = Source/Classes/PINRequestRetryStrategy.m; sourceTree = ""; }; + 51135E999C9B63A3A146C9EC1CD3D0CE /* ImageZoomControllerIsNotPresentingOverlayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsNotPresentingOverlayState.swift; sourceTree = ""; }; + 513C72B75C74E39500ECC94B59716DC5 /* Pods_Zoomy_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Zoomy_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 51712480D4DC2E936F5A74EB8E97FF76 /* ASElementMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASElementMap.h; path = Source/Details/ASElementMap.h; sourceTree = ""; }; + 51DDB8C289581DFC7295DF13B2B679A4 /* NSHTTPURLResponse+MaxAge.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSHTTPURLResponse+MaxAge.h"; path = "Source/Classes/Categories/NSHTTPURLResponse+MaxAge.h"; sourceTree = ""; }; + 52202AAAF785699FB3C841AAEB80C544 /* ASElementMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASElementMap.mm; path = Source/Details/ASElementMap.mm; sourceTree = ""; }; + 522F7194EE4805844AF8037C5D463760 /* PINOperation.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINOperation.debug.xcconfig; sourceTree = ""; }; + 523240EAB47539D12567510B8F883DC8 /* PINOperationGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINOperationGroup.m; path = Source/PINOperationGroup.m; sourceTree = ""; }; + 52594DD4EB49DC177D64B179999D001B /* ASNavigationController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASNavigationController.h; path = Source/ASNavigationController.h; sourceTree = ""; }; + 5275A3C1B1BB261CE7A641E5F1A4AE10 /* PINRemoteImageManagerResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageManagerResult.h; path = Source/Classes/include/PINRemoteImageManagerResult.h; sourceTree = ""; }; + 529107AAD032EC80C54BE9CDC8EC94AB /* PINURLSessionManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINURLSessionManager.h; path = Source/Classes/include/PINURLSessionManager.h; sourceTree = ""; }; + 53BF3551C5EE1DC95729A01E0E1632BF /* NSAttributedString+ASText.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSAttributedString+ASText.h"; path = "Source/Private/TextExperiment/Utility/NSAttributedString+ASText.h"; sourceTree = ""; }; + 53F754CCB8549BBB25671573986F6C65 /* ASTableLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableLayoutController.h; path = Source/Details/ASTableLayoutController.h; sourceTree = ""; }; + 540D079F51C83D244C9ED5EB1C961001 /* PINRemoteImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINRemoteImage.debug.xcconfig; sourceTree = ""; }; + 550B11CBF85493C4523215E0EA060AAD /* ASTipNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTipNode.mm; path = Source/Private/ASTipNode.mm; sourceTree = ""; }; + 55B088323CEDD9CEA3BE4A747A5B7678 /* PINAnimatedImageView+PINRemoteImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINAnimatedImageView+PINRemoteImage.h"; path = "Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h"; sourceTree = ""; }; + 56A4DCB09556D8E69491C29B81F6717E /* ASPINRemoteImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPINRemoteImageDownloader.h; path = Source/Details/ASPINRemoteImageDownloader.h; sourceTree = ""; }; + 56E6B6A59DD9BAA9AF2C4608AB94F0C1 /* NSArray+Diffing.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "NSArray+Diffing.mm"; path = "Source/Details/NSArray+Diffing.mm"; sourceTree = ""; }; + 56F9B8B1351E3504AA1167C5A3F2B8E5 /* ASOverlayLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASOverlayLayoutSpec.h; path = Source/Layout/ASOverlayLayoutSpec.h; sourceTree = ""; }; + 574D0A0487078EFBFCF4F03C47469787 /* PINCache+PINRemoteImageCaching.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINCache+PINRemoteImageCaching.m"; path = "Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m"; sourceTree = ""; }; + 57A3175B4809F18AD11501B59B1C4D9B /* ASConfigurationInternal.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASConfigurationInternal.mm; path = Source/ASConfigurationInternal.mm; sourceTree = ""; }; 5890A515AFECE99E61E339D0ED33E228 /* Pods-Zoomy_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Zoomy_Example-frameworks.sh"; sourceTree = ""; }; - 58DF4723F4C3C47CA4B7F675A4BA05FF /* PINRemoteImageManagerResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageManagerResult.h; path = Source/Classes/PINRemoteImageManagerResult.h; sourceTree = ""; }; - 58F66FB0AEB4E161B98EEC0563AAAA83 /* ASImageNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASImageNode.mm; path = Source/ASImageNode.mm; sourceTree = ""; }; - 5929816D10F8DFF27EA0E163D3AF6351 /* ASAsciiArtBoxCreator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAsciiArtBoxCreator.h; path = Source/Layout/ASAsciiArtBoxCreator.h; sourceTree = ""; }; - 5960F0BD04B70C94B98548918A2C94EA /* ASPagerNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASPagerNode+Beta.h"; path = "Source/ASPagerNode+Beta.h"; sourceTree = ""; }; - 59FBECE43ADC1822C1BFB2AF4CC30D0B /* PINImage+WebP.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImage+WebP.m"; path = "Source/Classes/Categories/PINImage+WebP.m"; sourceTree = ""; }; - 5A26326A1EC4D60A6D350C454C89D29D /* PINImage+ScaledImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImage+ScaledImage.m"; path = "Source/Classes/Categories/PINImage+ScaledImage.m"; sourceTree = ""; }; - 5A4BBF35A5BFF3C8055E41FF8D16E77F /* _ASCollectionGalleryLayoutItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionGalleryLayoutItem.h; path = Source/Private/_ASCollectionGalleryLayoutItem.h; sourceTree = ""; }; - 5B2B7A0F27A1B1C961C4EA3C16175B81 /* ASVisibilityProtocols.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASVisibilityProtocols.mm; path = Source/ASVisibilityProtocols.mm; sourceTree = ""; }; - 5C216819A1D5BC5B2AFC924E6C9858A2 /* ASCollectionViewLayoutInspector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewLayoutInspector.h; path = Source/Details/ASCollectionViewLayoutInspector.h; sourceTree = ""; }; - 5CCAD733BD22B89DD6EDFD49B0683A7D /* ASSection.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASSection.mm; path = Source/Private/ASSection.mm; sourceTree = ""; }; - 5CE71255C1FCB63798369B1B61543897 /* ASTwoDimensionalArrayUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTwoDimensionalArrayUtils.h; path = Source/Private/ASTwoDimensionalArrayUtils.h; sourceTree = ""; }; - 5D2F12F4DBC147ABBFF5EBB4E003AD04 /* UIResponder+AsyncDisplayKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIResponder+AsyncDisplayKit.h"; path = "Source/UIResponder+AsyncDisplayKit.h"; sourceTree = ""; }; - 5DB52888B23BC72D0EC9DE977B805591 /* NSIndexSet+ASHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSIndexSet+ASHelpers.h"; path = "Source/Details/NSIndexSet+ASHelpers.h"; sourceTree = ""; }; - 5E4321DB363EC82D6737D7BD0179F660 /* ASIGListAdapterBasedDataSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASIGListAdapterBasedDataSource.h; path = Source/Private/ASIGListAdapterBasedDataSource.h; sourceTree = ""; }; - 5F3472C9C5C5A1BC89A55AC74BFCC7B1 /* PINRequestRetryStrategy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRequestRetryStrategy.m; path = Source/Classes/PINRequestRetryStrategy.m; sourceTree = ""; }; + 594FEB1CE4589393B0B4FCA53EDA995C /* Zoomable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Zoomable.swift; sourceTree = ""; }; + 59576C4206771C56B34C93A2DD701D91 /* ASTextKitTailTruncater.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitTailTruncater.mm; path = Source/TextKit/ASTextKitTailTruncater.mm; sourceTree = ""; }; + 595AC5EED6C4EC88217327C18B6CAC62 /* ASDefaultPlayButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDefaultPlayButton.h; path = Source/Private/ASDefaultPlayButton.h; sourceTree = ""; }; + 5A338D2C7BECE0973CC5A926E046FBF5 /* PINRemoteImageMemoryContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageMemoryContainer.m; path = Source/Classes/PINRemoteImageMemoryContainer.m; sourceTree = ""; }; + 5A6A497EE4715107B9947A54E6593162 /* PINImage+DecodedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImage+DecodedImage.m"; path = "Source/Classes/Categories/PINImage+DecodedImage.m"; sourceTree = ""; }; + 5A6FAD6EA5CF728CE7EC0668E10C7324 /* ASTipsWindow.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipsWindow.h; path = Source/Private/ASTipsWindow.h; sourceTree = ""; }; + 5B81CEBEEA110B801B201B7E31584FD2 /* PINCache+PINRemoteImageCaching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINCache+PINRemoteImageCaching.h"; path = "Source/Classes/include/PINCache+PINRemoteImageCaching.h"; sourceTree = ""; }; + 5C0472B406D8D5A2FB7D3CC3DC5B85B8 /* PINCache-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINCache-prefix.pch"; sourceTree = ""; }; + 5CBF1A501D9D01565FC9A9FA7C2F0260 /* ASControlNode+tvOS.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASControlNode+tvOS.mm"; path = "Source/tvOS/ASControlNode+tvOS.mm"; sourceTree = ""; }; + 5D5C12E5C2E7EDA156BB9B2EE42C1683 /* ASTableNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTableNode.mm; path = Source/ASTableNode.mm; sourceTree = ""; }; + 5DA54E673A5C3F5C8521C04A015E4A9C /* ASHighlightOverlayLayer.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASHighlightOverlayLayer.mm; path = Source/Details/ASHighlightOverlayLayer.mm; sourceTree = ""; }; + 5E621B2AEB638A986D4D7B368348FB9F /* ASTableViewInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableViewInternal.h; path = Source/ASTableViewInternal.h; sourceTree = ""; }; + 5E86488B04A57D96057DE295100FCB4F /* _ASCollectionGalleryLayoutInfo.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASCollectionGalleryLayoutInfo.mm; path = Source/Private/_ASCollectionGalleryLayoutInfo.mm; sourceTree = ""; }; + 5F11697E2E11491618C74B039E70FF8D /* ASHashing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASHashing.h; path = Source/Details/ASHashing.h; sourceTree = ""; }; + 5F45FF692CB5E624BFFD980CA029E126 /* ASCollectionNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionNode+Beta.h"; path = "Source/ASCollectionNode+Beta.h"; sourceTree = ""; }; 5FB6F534B1401FE906AEF92CCF6A339D /* PINRemoteImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PINRemoteImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 601C1AF391DB366A2C1A19B86C26DEFA /* PINRemoteImageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageManager.h; path = Source/Classes/PINRemoteImageManager.h; sourceTree = ""; }; - 607041B6536208E2F64B565D46764939 /* ASInsetLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASInsetLayoutSpec.mm; path = Source/Layout/ASInsetLayoutSpec.mm; sourceTree = ""; }; - 609E9C43163ADCB8E907714C5FFF8826 /* ASImageNode+AnimatedImage.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASImageNode+AnimatedImage.mm"; path = "Source/ASImageNode+AnimatedImage.mm"; sourceTree = ""; }; - 617A1C88184B4FC6BD7DF6B8D9D96833 /* ASInsetLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASInsetLayoutSpec.h; path = Source/Layout/ASInsetLayoutSpec.h; sourceTree = ""; }; - 6320170E5A5A268B11CAE15D4EF6A9E3 /* PINCache.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = PINCache.framework; path = PINCache.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 638BCD02FE611C5776A63C02551D7ED6 /* PINRemoteImage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINRemoteImage.xcconfig; sourceTree = ""; }; - 639031EEB8C0E0780319C2E1B91EC177 /* InjectableLoggers-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "InjectableLoggers-umbrella.h"; sourceTree = ""; }; - 63C9ACDEAE8A9552A325796A234F79AC /* ASConfigurationInternal.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASConfigurationInternal.mm; path = Source/ASConfigurationInternal.mm; sourceTree = ""; }; - 640CE1206037C85BD667C306F05F33BB /* PINRemoteImageBasicCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageBasicCache.h; path = Source/Classes/PINRemoteImageBasicCache.h; sourceTree = ""; }; - 6471DAF51E7A7C9B6CA4B243EA9D399E /* ASAbsoluteLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAbsoluteLayoutSpec.h; path = Source/Layout/ASAbsoluteLayoutSpec.h; sourceTree = ""; }; - 6490DDA9673AE60693B85E2B708DC4D8 /* ASDisplayNode+FrameworkPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+FrameworkPrivate.h"; path = "Source/Private/ASDisplayNode+FrameworkPrivate.h"; sourceTree = ""; }; - 64BF78B27F9F9D6D702EEDC1DDB09901 /* ASVideoNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASVideoNode.h; path = Source/ASVideoNode.h; sourceTree = ""; }; - 64BFE2FB5FD0C114FE30D1443B38097B /* PINOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperation.h; path = Source/PINOperation.h; sourceTree = ""; }; - 64C1E527A330B58A62D7FBCC27451933 /* ASVideoPlayerNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASVideoPlayerNode.h; path = Source/ASVideoPlayerNode.h; sourceTree = ""; }; - 66025E37962CFCFF58E31BD4B8B8AE1F /* ASTextDebugOption.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextDebugOption.mm; path = Source/Private/TextExperiment/Component/ASTextDebugOption.mm; sourceTree = ""; }; - 6641DA3D150545A95436CF794C0CBE48 /* ASTextKitRenderer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitRenderer.h; path = Source/TextKit/ASTextKitRenderer.h; sourceTree = ""; }; - 66EAE704190CA358DB4856F26E0607E6 /* Texture-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Texture-Info.plist"; sourceTree = ""; }; - 6700B1B2756EB1F11759EBDE0E513D51 /* InjectableLoggers-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "InjectableLoggers-prefix.pch"; sourceTree = ""; }; - 675C60B5C42D6C1F553B1698D747A649 /* ImageZoomControllerContentState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerContentState.swift; sourceTree = ""; }; - 675E0F7FDD409F8A77A5C35C201C300D /* ASLayoutElementStylePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElementStylePrivate.h; path = Source/Private/Layout/ASLayoutElementStylePrivate.h; sourceTree = ""; }; + 60F2D5EB7FDFCC0BE3CB468C0D60DAB6 /* PINRemoteImageDownloadQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageDownloadQueue.h; path = Source/Classes/PINRemoteImageDownloadQueue.h; sourceTree = ""; }; + 612B944990F6D2B3032C498585070523 /* PINRemoteImageTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageTask.h; path = Source/Classes/PINRemoteImageTask.h; sourceTree = ""; }; + 614DA3C78C8C5DFC5E9D4AE0CE7BFF7C /* ASTextNode2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNode2.h; path = Source/ASTextNode2.h; sourceTree = ""; }; + 626C3FFAA488C3DD09D53C2E75C9CF17 /* _ASTransitionContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASTransitionContext.h; path = Source/_ASTransitionContext.h; sourceTree = ""; }; + 628632B58BF8798C5B49581ECE1D5BD1 /* AsyncDisplayKit+IGListKitMethods.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "AsyncDisplayKit+IGListKitMethods.mm"; path = "Source/AsyncDisplayKit+IGListKitMethods.mm"; sourceTree = ""; }; + 631EFD7F1F37EB5DE9EBBFE915A49FEE /* ASStackUnpositionedLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStackUnpositionedLayout.mm; path = Source/Private/Layout/ASStackUnpositionedLayout.mm; sourceTree = ""; }; + 6320170E5A5A268B11CAE15D4EF6A9E3 /* PINCache.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PINCache.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 633114E3879F0F946FFC6622C69D9C57 /* ASTextLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextLayout.h; path = Source/Private/TextExperiment/Component/ASTextLayout.h; sourceTree = ""; }; + 64331C191E00E170739F31033B58DE07 /* ASWeakProxy.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASWeakProxy.mm; path = Source/Details/ASWeakProxy.mm; sourceTree = ""; }; + 6489C428B7BF38CBF9D3B664F3057F20 /* PINRemoteImageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageManager.h; path = Source/Classes/include/PINRemoteImageManager.h; sourceTree = ""; }; + 65133D87AEBB73F5FF7A1A7CC904EE8A /* _ASAsyncTransactionContainer+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "_ASAsyncTransactionContainer+Private.h"; path = "Source/Details/Transactions/_ASAsyncTransactionContainer+Private.h"; sourceTree = ""; }; + 67744A952643A0AB3D672202110107F4 /* PINRemoteImageManagerConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageManagerConfiguration.h; path = Source/Classes/PINRemoteImageManagerConfiguration.h; sourceTree = ""; }; + 677CD4785FE892E11D23DB575EF58964 /* PINWebPAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINWebPAnimatedImage.m; path = Source/Classes/AnimatedImages/PINWebPAnimatedImage.m; sourceTree = ""; }; + 677EEE3656D43FF4C34D547EC105A5AB /* PINDiskCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINDiskCache.m; path = Source/PINDiskCache.m; sourceTree = ""; }; + 67856706A15072A489163BBFBED7EF43 /* ASDisplayNodeExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDisplayNodeExtras.mm; path = Source/ASDisplayNodeExtras.mm; sourceTree = ""; }; 6786AB9FCA35EEE185C0A027621E7653 /* Pods-Zoomy_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Zoomy_Example-dummy.m"; sourceTree = ""; }; - 67980F51D8D7857FD5DF2B3CFD94B2DC /* ASTextKitRenderer+Positioning.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTextKitRenderer+Positioning.h"; path = "Source/TextKit/ASTextKitRenderer+Positioning.h"; sourceTree = ""; }; - 67D1F9A6121EE2D97F3C6002FB464798 /* ASCollectionFlowLayoutDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionFlowLayoutDelegate.mm; path = Source/Details/ASCollectionFlowLayoutDelegate.mm; sourceTree = ""; }; - 67F4D61E91F117DC2FA2C8092679E51A /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASRangeControllerUpdateRangeProtocol+Beta.h"; path = "Source/Details/ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = ""; }; - 6808266211BF925459BF96812FD61642 /* _ASCollectionGalleryLayoutInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionGalleryLayoutInfo.h; path = Source/Private/_ASCollectionGalleryLayoutInfo.h; sourceTree = ""; }; - 682AC42FFA98ABE6BB66417D133D425D /* PINRemoteImageCallbacks.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageCallbacks.m; path = Source/Classes/PINRemoteImageCallbacks.m; sourceTree = ""; }; - 688A39228B8F3C56FD32EA204F9A9FEC /* PINGIFAnimatedImageManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINGIFAnimatedImageManager.h; path = Source/Classes/PINGIFAnimatedImageManager.h; sourceTree = ""; }; - 68B678E30769470CE9F5F7EB95D5A260 /* ASCollectionElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionElement.h; path = Source/Details/ASCollectionElement.h; sourceTree = ""; }; - 68EBD106F17D31DCE3ACD608207D0124 /* ASCollectionViewLayoutFacilitatorProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewLayoutFacilitatorProtocol.h; path = Source/ASCollectionViewLayoutFacilitatorProtocol.h; sourceTree = ""; }; - 6901B23BFB9DC7E4D4147AA505777EA5 /* ASTextKitRenderer+Positioning.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASTextKitRenderer+Positioning.mm"; path = "Source/TextKit/ASTextKitRenderer+Positioning.mm"; sourceTree = ""; }; - 6972254463A4E42E119C4C796390CFF9 /* ASTextKitContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitContext.mm; path = Source/TextKit/ASTextKitContext.mm; sourceTree = ""; }; - 6A8C7D884197F26D73FBA82D4A4132C5 /* ASControlTargetAction.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASControlTargetAction.mm; path = Source/Private/ASControlTargetAction.mm; sourceTree = ""; }; - 6B2040AC217069203B2EA5F3FF24FE3C /* CanBetriggered.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanBetriggered.swift; sourceTree = ""; }; - 6C830822319FA08CBD72F6C6A234F64F /* Zoomable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Zoomable.swift; sourceTree = ""; }; - 6DBD0F18AD2C048A15C6E508350FE156 /* ASEventLog.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASEventLog.mm; path = Source/Details/ASEventLog.mm; sourceTree = ""; }; - 6E59B54071C5A06019DE422E434D54C4 /* ASNavigationController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASNavigationController.h; path = Source/ASNavigationController.h; sourceTree = ""; }; - 70D4BAD9DE5E975D5E04B308B0B3BE07 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASMainSerialQueue.mm; path = Source/Details/ASMainSerialQueue.mm; sourceTree = ""; }; - 70ECAAA631B9C5458137845A17153DE7 /* _ASDisplayView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASDisplayView.h; path = Source/Details/_ASDisplayView.h; sourceTree = ""; }; - 7135BADF9C0B4425CC0C0126CB809820 /* ASImageNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASImageNode.h; path = Source/ASImageNode.h; sourceTree = ""; }; - 717574B35CF1E6D3F744307CCE00121F /* ASTextRunDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextRunDelegate.mm; path = Source/Private/TextExperiment/String/ASTextRunDelegate.mm; sourceTree = ""; }; - 71B1E4BAAE8A86601C8C6B97DEFE47E4 /* PINRemoteImageBasicCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageBasicCache.m; path = Source/Classes/PINRemoteImageBasicCache.m; sourceTree = ""; }; - 722AB0BD59691CFBC5D191DD68CDC635 /* ASTextNode2.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextNode2.mm; path = Source/ASTextNode2.mm; sourceTree = ""; }; - 724D27438A0502C29D8A0A72E0248013 /* Zoomy.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Zoomy.xcconfig; sourceTree = ""; }; - 734D5D9C89E717418FCAA7185ED7E02B /* ASDisplayNodeLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeLayout.h; path = Source/Private/ASDisplayNodeLayout.h; sourceTree = ""; }; - 739717630BB5AE208463BF141B4995DA /* ASWeakSet.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASWeakSet.mm; path = Source/Details/ASWeakSet.mm; sourceTree = ""; }; - 73DC94ADF25673F66DD319923A0E77FD /* ASControlNode+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASControlNode+Private.h"; path = "Source/Private/ASControlNode+Private.h"; sourceTree = ""; }; - 7433465CCEDABF6373CF6FC715F02577 /* CGPoint+valueInDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGPoint+valueInDirection.swift"; sourceTree = ""; }; - 745BC45253F7B8CB5026E5AE52813E82 /* ASConfigurationDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASConfigurationDelegate.h; path = Source/ASConfigurationDelegate.h; sourceTree = ""; }; - 74903A67A4FAF9B14E31F4D571B27DFB /* _ASDisplayLayer.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASDisplayLayer.mm; path = Source/Details/_ASDisplayLayer.mm; sourceTree = ""; }; - 74A617AD6A6D696D3F0296CD7F204CA1 /* ASResponderChainEnumerator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASResponderChainEnumerator.h; path = Source/Private/ASResponderChainEnumerator.h; sourceTree = ""; }; - 74F6A7ADB0BD1789A4271467B0355510 /* _ASPendingState.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASPendingState.mm; path = Source/Private/_ASPendingState.mm; sourceTree = ""; }; - 751A5BF60BC5A9847C0C9673E8CF01D8 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift; sourceTree = ""; }; - 7541B18A6C986C3B141071F12EC8AA87 /* ASPendingStateController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPendingStateController.h; path = Source/Private/ASPendingStateController.h; sourceTree = ""; }; - 75800818748B9EDEDA0DF1E0F708AB70 /* PINCache-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINCache-prefix.pch"; sourceTree = ""; }; - 75B8ACE26E3AB8DC3A77EAF33F43FB07 /* PINRemoteImageManagerResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageManagerResult.m; path = Source/Classes/PINRemoteImageManagerResult.m; sourceTree = ""; }; - 75F5EC2D6BBD57314094328D47EFA189 /* ASImageNode+CGExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASImageNode+CGExtras.h"; path = "Source/Private/ASImageNode+CGExtras.h"; sourceTree = ""; }; - 76D2AC89B328615BB7546EA1E9E047D5 /* ASButtonNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASButtonNode.mm; path = Source/ASButtonNode.mm; sourceTree = ""; }; - 771C739307382FB3BE6C97B81D92D604 /* ASHighlightOverlayLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASHighlightOverlayLayer.h; path = Source/Details/ASHighlightOverlayLayer.h; sourceTree = ""; }; - 77352767819B3F1506BB79361E5199A9 /* _ASHierarchyChangeSet.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASHierarchyChangeSet.h; path = Source/Private/_ASHierarchyChangeSet.h; sourceTree = ""; }; - 77DB577F26D2B45960B5B6BFA0762A2E /* ASLayoutManager.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASLayoutManager.mm; path = Source/TextKit/ASLayoutManager.mm; sourceTree = ""; }; - 780AEE0E9559677F32F78674DB2BBC5A /* ASRunLoopQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRunLoopQueue.h; path = Source/ASRunLoopQueue.h; sourceTree = ""; }; - 784EF6F897319AE9C0047B80A777FE72 /* ASOverlayLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASOverlayLayoutSpec.mm; path = Source/Layout/ASOverlayLayoutSpec.mm; sourceTree = ""; }; - 78C0E5FE49415C26C04C9F48071F9E03 /* PINCache-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINCache-umbrella.h"; sourceTree = ""; }; - 79619D75C2722640361977842EF8C593 /* _ASAsyncTransactionGroup.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASAsyncTransactionGroup.mm; path = Source/Details/Transactions/_ASAsyncTransactionGroup.mm; sourceTree = ""; }; - 79CFD9BC7AF69EDB01B34D77788E7A4F /* SpringAnimator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SpringAnimator.swift; sourceTree = ""; }; - 7A0720ADCEE5EA7E1BF10055515487F0 /* ASIntegerMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASIntegerMap.h; path = Source/Details/ASIntegerMap.h; sourceTree = ""; }; - 7B2C8E75862CFCA96FB97B2D340B2600 /* ASCellNode+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCellNode+Internal.h"; path = "Source/Private/ASCellNode+Internal.h"; sourceTree = ""; }; - 7B8B564BFF8B5501803B1A4631A19657 /* PINCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCache.h; path = Source/PINCache.h; sourceTree = ""; }; - 7BF91A7594887570D0581A2292B69202 /* PINAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINAnimatedImage.m; path = Source/Classes/AnimatedImages/PINAnimatedImage.m; sourceTree = ""; }; - 7C30E737EC48CE6BA7BA08E469B40F7E /* ASTextLine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextLine.h; path = Source/Private/TextExperiment/Component/ASTextLine.h; sourceTree = ""; }; + 6824D67D89E086ACB941848B24C0DF26 /* Zoomy-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Zoomy-Info.plist"; sourceTree = ""; }; + 6950A957CBC973B8CCDA5898C7B8DA83 /* ASTextRunDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextRunDelegate.h; path = Source/Private/TextExperiment/String/ASTextRunDelegate.h; sourceTree = ""; }; + 695B0EF784C58FAC0A0A0275CFA6385A /* UIViewController+CanManageZoomBehavior.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIViewController+CanManageZoomBehavior.swift"; sourceTree = ""; }; + 695CBAFD35269D7D30D7126BA1A9FE5C /* PINImageView+PINRemoteImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImageView+PINRemoteImage.m"; path = "Source/Classes/ImageCategories/PINImageView+PINRemoteImage.m"; sourceTree = ""; }; + 6A5BE4F496799AB427B7E02D30B8550C /* ConsoleLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConsoleLogger.swift; path = InjectableLoggers/Classes/Structs/ConsoleLogger.swift; sourceTree = ""; }; + 6A7F6539EFE7A2DEBB6CFE6B7C4F7BE5 /* ASImageNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASImageNode.mm; path = Source/ASImageNode.mm; sourceTree = ""; }; + 6AA80045BD16B35CDB5DE468DF1034F6 /* ASRunLoopQueue.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRunLoopQueue.mm; path = Source/ASRunLoopQueue.mm; sourceTree = ""; }; + 6ABCC1E22FDEC639E66D76B27F1C5922 /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASRangeControllerUpdateRangeProtocol+Beta.h"; path = "Source/Details/ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = ""; }; + 6B0113958F688610CF771535C447AA8F /* _ASAsyncTransactionGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASAsyncTransactionGroup.h; path = Source/Details/Transactions/_ASAsyncTransactionGroup.h; sourceTree = ""; }; + 6B22A6ED73746F28404AF31C57E32E29 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutTransition.mm; path = Source/Private/ASLayoutTransition.mm; sourceTree = ""; }; + 6B5DFABF4BDE70BA28458B972B220A13 /* _ASDisplayLayer.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASDisplayLayer.mm; path = Source/Details/_ASDisplayLayer.mm; sourceTree = ""; }; + 6BA7F456BF4EFB86CEC78435D24C3393 /* PINOperation-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PINOperation-dummy.m"; sourceTree = ""; }; + 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 6CFFF44F0A0757458B152AA0C8E5E1AA /* ASSupplementaryNodeSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSupplementaryNodeSource.h; path = Source/ASSupplementaryNodeSource.h; sourceTree = ""; }; + 6D233C7E013C07D0389984F3466CB2AE /* ASCellNode+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCellNode+Internal.h"; path = "Source/Private/ASCellNode+Internal.h"; sourceTree = ""; }; + 6D7E831DD0A378B5BBA9E3EB6ACC1B49 /* ASRecursiveUnfairLock.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRecursiveUnfairLock.mm; path = Source/Details/ASRecursiveUnfairLock.mm; sourceTree = ""; }; + 6E1443385934C571269E9950D816D792 /* NSAttributedString+ASText.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "NSAttributedString+ASText.mm"; path = "Source/Private/TextExperiment/Utility/NSAttributedString+ASText.mm"; sourceTree = ""; }; + 6F57D723495FFB4BA8278626AE81835B /* ASDefaultPlayButton.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDefaultPlayButton.mm; path = Source/Private/ASDefaultPlayButton.mm; sourceTree = ""; }; + 6FA0AF584416D60BE3C121B151A81600 /* ASLog.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLog.mm; path = Source/Base/ASLog.mm; sourceTree = ""; }; + 7001D920A126D34017D9904AFB7E7953 /* ASCenterLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCenterLayoutSpec.h; path = Source/Layout/ASCenterLayoutSpec.h; sourceTree = ""; }; + 7096E0A9B680A32ABA967518D12A789E /* ASTextNodeTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNodeTypes.h; path = Source/TextKit/ASTextNodeTypes.h; sourceTree = ""; }; + 714C8766D214CF2BDDCA14DB63D82CC2 /* ASLayoutElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElement.h; path = Source/Layout/ASLayoutElement.h; sourceTree = ""; }; + 717054082F77141CEA737C820EDA3693 /* Texture.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Texture.modulemap; sourceTree = ""; }; + 7194F334C486D84103D8B7F489484B85 /* ASRunLoopQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRunLoopQueue.h; path = Source/ASRunLoopQueue.h; sourceTree = ""; }; + 721C9415CD678F2601E830BE4F543FBE /* UIResponder+AsyncDisplayKit.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "UIResponder+AsyncDisplayKit.mm"; path = "Source/UIResponder+AsyncDisplayKit.mm"; sourceTree = ""; }; + 72993BC01B036B4DF85688844D2A00C3 /* PINRemoteImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PINRemoteImage-dummy.m"; sourceTree = ""; }; + 72E63BB89BB4648998A676175AA7FCFE /* Logger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.swift; path = InjectableLoggers/Classes/Classes/Logger.swift; sourceTree = ""; }; + 7303F3582F8703C93C9B86724B41E492 /* PINRemoteImageCategoryManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageCategoryManager.h; path = Source/Classes/include/PINRemoteImageCategoryManager.h; sourceTree = ""; }; + 734F9C74F82633188225C4CC9C72FDAD /* CanAnimate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanAnimate.swift; sourceTree = ""; }; + 738C0D498805A7D7930418DE87AC4F5E /* ASTextUtilities.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextUtilities.mm; path = Source/Private/TextExperiment/Utility/ASTextUtilities.mm; sourceTree = ""; }; + 738E3C383FCEEEA646A90093F39D90DD /* ASLocking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLocking.h; path = Source/ASLocking.h; sourceTree = ""; }; + 73AC4D83CEDD69BA236A57352337FD54 /* ASVideoNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASVideoNode.h; path = Source/ASVideoNode.h; sourceTree = ""; }; + 7406A55AE2F314560B18CF0D1F166146 /* ASDisplayNode+Yoga.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Yoga.h"; path = "Source/ASDisplayNode+Yoga.h"; sourceTree = ""; }; + 7553FE85837FFE5E024123DA400A5BB6 /* ImageZoomController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomController.swift; sourceTree = ""; }; + 75555F5FF44B7570151D3E07C14B9091 /* ASCollectionLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionLayout.mm; path = Source/Private/ASCollectionLayout.mm; sourceTree = ""; }; + 760CAD4BE95145071691BD6C8BEAA67D /* ASImageNode+AnimatedImage.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASImageNode+AnimatedImage.mm"; path = "Source/ASImageNode+AnimatedImage.mm"; sourceTree = ""; }; + 761330E4F43F9ADCCDA54B430683FEE6 /* ASCollectionViewFlowLayoutInspector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewFlowLayoutInspector.h; path = Source/Private/ASCollectionViewFlowLayoutInspector.h; sourceTree = ""; }; + 764D542477B60E5C299092AEEED074EC /* PINRemoteImageDownloadTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageDownloadTask.m; path = Source/Classes/PINRemoteImageDownloadTask.m; sourceTree = ""; }; + 76F317BA0E076D34E8461D2E6827CD8E /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = DEVELOPER_DIR; }; + 773C92C3B53030CCB6156F70AC47231C /* ASRatioLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRatioLayoutSpec.mm; path = Source/Layout/ASRatioLayoutSpec.mm; sourceTree = ""; }; + 780C4053DCDEF3BE175B88490A56D53D /* ASTextKitTailTruncater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitTailTruncater.h; path = Source/TextKit/ASTextKitTailTruncater.h; sourceTree = ""; }; + 787A46EF98C950C390FA42BB039DA0EC /* MockLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MockLogger.swift; path = InjectableLoggers/Classes/Classes/MockLogger.swift; sourceTree = ""; }; + 7948440DC9755B2496424FB9E4AE8E15 /* PINRemoteImage.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PINRemoteImage.modulemap; sourceTree = ""; }; + 796DC49204A7543AA048026D7A6B67AF /* ASDisplayNodeTipState.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDisplayNodeTipState.mm; path = Source/Private/ASDisplayNodeTipState.mm; sourceTree = ""; }; + 7A48A5E4ED7ED7758E6885FF2C6A8189 /* ASConfigurationDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASConfigurationDelegate.h; path = Source/ASConfigurationDelegate.h; sourceTree = ""; }; + 7AF0970735CEF05D54172A8598F05F00 /* InjectableLoggers.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = InjectableLoggers.release.xcconfig; sourceTree = ""; }; + 7B1FFF4BE75E530F7F98CC130B827756 /* ASTipProvider.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTipProvider.mm; path = Source/Private/ASTipProvider.mm; sourceTree = ""; }; + 7BBE389DE054D871BA72D30EF0A95A02 /* ASEditableTextNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASEditableTextNode.h; path = Source/ASEditableTextNode.h; sourceTree = ""; }; + 7C638CF5711825D56D2E5DF07B0F1D6D /* UIImageView+Zoomable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIImageView+Zoomable.swift"; sourceTree = ""; }; + 7C8F79D8FCF9015BF86D560DE3589B65 /* ASTextKitShadower.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitShadower.mm; path = Source/TextKit/ASTextKitShadower.mm; sourceTree = ""; }; + 7CB9C9311AA6D37B9C029A0C12C4B4E7 /* ASDefaultPlaybackButton.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDefaultPlaybackButton.mm; path = Source/Private/ASDefaultPlaybackButton.mm; sourceTree = ""; }; 7CDD66BA0EC3AF548D39EAEAC861844F /* Pods-Zoomy_Tests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Zoomy_Tests-Info.plist"; sourceTree = ""; }; - 7D05F80B69A6CAAC89037EC81A01CAE8 /* ASAvailability.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAvailability.h; path = Source/Base/ASAvailability.h; sourceTree = ""; }; - 7D4271F88523068290159A5B308C26DE /* ASHashing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASHashing.h; path = Source/Details/ASHashing.h; sourceTree = ""; }; - 7DA44FE89D4C0FCD5F37208DB3FA170E /* ASCollectionView+Undeprecated.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionView+Undeprecated.h"; path = "Source/Private/ASCollectionView+Undeprecated.h"; sourceTree = ""; }; - 7E372AA815D2A151D2CBA8ACF92FC280 /* ASSupplementaryNodeSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSupplementaryNodeSource.h; path = Source/ASSupplementaryNodeSource.h; sourceTree = ""; }; - 7EEF9D9818AB62929E90309B6F369ED2 /* CoreGraphics+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "CoreGraphics+ASConvenience.h"; path = "Source/Details/CoreGraphics+ASConvenience.h"; sourceTree = ""; }; - 81225F64FFCB713D06102F384EE235EC /* Animator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Animator.swift; sourceTree = ""; }; - 8155FA2A18B7EFC15B8F6773207514EE /* Logger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.swift; path = InjectableLoggers/Classes/Classes/Logger.swift; sourceTree = ""; }; - 821867185C05134187FCADAB598C7AFB /* PINRemoteImageTask+Subclassing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINRemoteImageTask+Subclassing.h"; path = "Source/Classes/Categories/PINRemoteImageTask+Subclassing.h"; sourceTree = ""; }; - 82B5FE5440AD8C2D32D0905139420FC0 /* ASTipNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTipNode.mm; path = Source/Private/ASTipNode.mm; sourceTree = ""; }; - 8300AF8B7A5E55E071CE2BBFFC6404B9 /* ASTipProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipProvider.h; path = Source/Private/ASTipProvider.h; sourceTree = ""; }; - 83079A844C816FE05A93291E7FA5196B /* ASBasicImageDownloader.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASBasicImageDownloader.mm; path = Source/Details/ASBasicImageDownloader.mm; sourceTree = ""; }; - 833117E1C1902A1A1262B53ADA674BD0 /* ASTextNodeWordKerner.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNodeWordKerner.h; path = Source/TextKit/ASTextNodeWordKerner.h; sourceTree = ""; }; - 836EA6D72B4490C73AF0C525C6876D37 /* ASObjectDescriptionHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASObjectDescriptionHelpers.h; path = Source/Details/ASObjectDescriptionHelpers.h; sourceTree = ""; }; - 843527DDA67E9C01B757C84DADBE0839 /* PINRemoteImage-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINRemoteImage-umbrella.h"; sourceTree = ""; }; - 843DB650E83C835994FAEF2C6A66B8CC /* AsyncDisplayKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AsyncDisplayKit.h; path = Source/AsyncDisplayKit.h; sourceTree = ""; }; - 846F36BAF3041EB8ED21F54F6B9DE07B /* ASBaseDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBaseDefines.h; path = Source/Base/ASBaseDefines.h; sourceTree = ""; }; - 84BCA78334AF16808277D2FAC66F02BD /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsPresentingScrollViewOverlayState.swift; sourceTree = ""; }; - 854C0BA85C5EBE5FC30BE62E6B85A1A1 /* CanLog.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLog.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLog.swift; sourceTree = ""; }; - 8601A38169596B1A8B21A3BA548AA1E4 /* PINOperationMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationMacros.h; path = Source/PINOperationMacros.h; sourceTree = ""; }; - 860B39EE6BB8A3966AF1259098EEB687 /* ASRecursiveUnfairLock.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASRecursiveUnfairLock.mm; path = Source/Details/ASRecursiveUnfairLock.mm; sourceTree = ""; }; - 860C40113A4C6ADD6363A09B97EB2272 /* PINDiskCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINDiskCache.h; path = Source/PINDiskCache.h; sourceTree = ""; }; - 8612405434DF8846A00ADCFE8E364394 /* ASCollections.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollections.h; path = Source/ASCollections.h; sourceTree = ""; }; - 8625D5C81FCFE2B385A4DD440C2B9EBA /* PINURLSessionManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINURLSessionManager.h; path = Source/Classes/PINURLSessionManager.h; sourceTree = ""; }; - 86803184503140C2A4F07DFFED434615 /* NSArray+Diffing.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "NSArray+Diffing.mm"; path = "Source/Details/NSArray+Diffing.mm"; sourceTree = ""; }; - 86BD044C71694B82FE5978E510C75CBA /* ASConfigurationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASConfigurationInternal.h; path = Source/ASConfigurationInternal.h; sourceTree = ""; }; - 86F85E0F87EC16039F8621F5162F9270 /* PINGIFAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINGIFAnimatedImage.h; path = Source/Classes/AnimatedImages/PINGIFAnimatedImage.h; sourceTree = ""; }; - 879C8B32AAE6359D599F78BC16CBB13F /* ASCollectionViewLayoutInspector.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionViewLayoutInspector.mm; path = Source/Details/ASCollectionViewLayoutInspector.mm; sourceTree = ""; }; - 88BB970C61F10199085A0DDA55F977CB /* PINGIFAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINGIFAnimatedImage.m; path = Source/Classes/AnimatedImages/PINGIFAnimatedImage.m; sourceTree = ""; }; - 88E78B612E8360D5296AEE501054F09A /* ASDimension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDimension.h; path = Source/Layout/ASDimension.h; sourceTree = ""; }; - 899757F2A351E6C05F6A5A3EE1B687CC /* ASTextKitShadower.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitShadower.h; path = Source/TextKit/ASTextKitShadower.h; sourceTree = ""; }; - 8AFD059D7D4CBEA0213433EBCFF64EA2 /* ASImageContainerProtocolCategories.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASImageContainerProtocolCategories.h; path = Source/Details/ASImageContainerProtocolCategories.h; sourceTree = ""; }; - 8B02FDCFBF0D352D4CCC5ACF96478DF5 /* _ASAsyncTransactionGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASAsyncTransactionGroup.h; path = Source/Details/Transactions/_ASAsyncTransactionGroup.h; sourceTree = ""; }; - 8B303C567292DC11F1B0DAACE614A6AC /* ASTableView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableView.h; path = Source/ASTableView.h; sourceTree = ""; }; - 8B4568266DA1D977E83A8C75D4C2C35E /* PINCachedAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCachedAnimatedImage.h; path = Source/Classes/AnimatedImages/PINCachedAnimatedImage.h; sourceTree = ""; }; - 8B63699EFB4C341DDCA0160947E19395 /* ASWeakMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASWeakMap.mm; path = Source/Private/ASWeakMap.mm; sourceTree = ""; }; - 8BF6A75BC54E75526F8E7A07BDED4AD6 /* ASCollectionLayoutContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionLayoutContext.mm; path = Source/Details/ASCollectionLayoutContext.mm; sourceTree = ""; }; - 8C0888B5BCFB99062C58EB43E8AD7554 /* _ASTransitionContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASTransitionContext.h; path = Source/_ASTransitionContext.h; sourceTree = ""; }; - 8C13FE60D14FB69B42CF62FDDB8882EF /* UIImage+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+ASConvenience.h"; path = "Source/UIImage+ASConvenience.h"; sourceTree = ""; }; - 8C4C2353FF592E40999EFBD5AB3AE15C /* ASDisplayNodeTipState.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDisplayNodeTipState.mm; path = Source/Private/ASDisplayNodeTipState.mm; sourceTree = ""; }; - 8D67F8257B9EA483BC03A079926677DF /* BounceOffsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BounceOffsets.swift; sourceTree = ""; }; + 803B09D806B71B6D194635CE75C342F9 /* ASControlNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASControlNode.h; path = Source/ASControlNode.h; sourceTree = ""; }; + 806DDF999DDE3AAC2ABC6FF9CE3E5B8A /* ASTextUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextUtilities.h; path = Source/Private/TextExperiment/Utility/ASTextUtilities.h; sourceTree = ""; }; + 82F2FC1618232C6338E87A6A00200C50 /* ASDisplayNode+AsyncDisplay.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+AsyncDisplay.mm"; path = "Source/Private/ASDisplayNode+AsyncDisplay.mm"; sourceTree = ""; }; + 8326C4C67628C534D2FB0AC51B6CA084 /* ASTextKitEntityAttribute.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitEntityAttribute.mm; path = Source/TextKit/ASTextKitEntityAttribute.mm; sourceTree = ""; }; + 832B4AE6E6704ADC13BF1022950A7A6F /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CoreLocation.framework; sourceTree = DEVELOPER_DIR; }; + 848FD9809F9E6E909227DBA5454D0642 /* ASNetworkImageLoadInfo.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASNetworkImageLoadInfo.mm; path = Source/ASNetworkImageLoadInfo.mm; sourceTree = ""; }; + 84CB3A49900E50746B7BBE91B3975FA8 /* ASTextNode2.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextNode2.mm; path = Source/ASTextNode2.mm; sourceTree = ""; }; + 8572FDFE5D32A555792D8D264EBEC9C4 /* CanLogMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessage.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLogMessage.swift; sourceTree = ""; }; + 8585E737744727C5F5FFFE96D84A234F /* PINCachedAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCachedAnimatedImage.h; path = Source/Classes/include/PINCachedAnimatedImage.h; sourceTree = ""; }; + 85C3AB3ED77627F864E584556D9B3B4C /* ASLayoutSpecUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutSpecUtilities.h; path = Source/Private/Layout/ASLayoutSpecUtilities.h; sourceTree = ""; }; + 86164D80FD547DBCDC04ACDD06E541B5 /* ASCollectionLayoutState.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionLayoutState.mm; path = Source/Details/ASCollectionLayoutState.mm; sourceTree = ""; }; + 8645412BECF2A0A622A033A39E216975 /* ASTextKitAttributes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitAttributes.h; path = Source/TextKit/ASTextKitAttributes.h; sourceTree = ""; }; + 86B385DAAFF0820A00FF000415C6DF6A /* ASBaseDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBaseDefines.h; path = Source/Base/ASBaseDefines.h; sourceTree = ""; }; + 8861C945B300C693E14494F50424D783 /* PINCache.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PINCache.modulemap; sourceTree = ""; }; + 88F59C80E030B1D3C2C1D47FFBB972AA /* ASIntegerMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASIntegerMap.mm; path = Source/Details/ASIntegerMap.mm; sourceTree = ""; }; + 898DCAC1CFAD91697899114511875124 /* ASLayoutManager.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutManager.mm; path = Source/TextKit/ASLayoutManager.mm; sourceTree = ""; }; + 89AD76C27E390A5F98261196C2496BC8 /* PINRemoteImageTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageTask.m; path = Source/Classes/PINRemoteImageTask.m; sourceTree = ""; }; + 89CFBF3A3B10B6EDE93CCE993C1D33E3 /* PINDisplayLink.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINDisplayLink.h; path = Source/Classes/PINDisplayLink.h; sourceTree = ""; }; + 89EA7BCC1CA29B222E7DC77185E5C1CA /* ASCollectionLayoutDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutDelegate.h; path = Source/Details/ASCollectionLayoutDelegate.h; sourceTree = ""; }; + 8A3377EFCA934EA4647740466F62D987 /* ASTextKitRenderer.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitRenderer.mm; path = Source/TextKit/ASTextKitRenderer.mm; sourceTree = ""; }; + 8A40BCD8285FC1DEF12569A10100C4C1 /* ImageZoomControllerState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerState.swift; sourceTree = ""; }; + 8A98596125EEEC4B752CF6D26D39B317 /* ASMutableElementMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMutableElementMap.h; path = Source/Private/ASMutableElementMap.h; sourceTree = ""; }; + 8AE225CFAAB0B6186AECCF6530A1C315 /* ASStackLayoutElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutElement.h; path = Source/Layout/ASStackLayoutElement.h; sourceTree = ""; }; + 8B652808CFCA8AB41B6DAE371EEDFFB4 /* PINRemoteImage-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PINRemoteImage-Info.plist"; sourceTree = ""; }; + 8BD494C55125932909BE35FA36C3C97B /* ASTraitCollection.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTraitCollection.mm; path = Source/Details/ASTraitCollection.mm; sourceTree = ""; }; + 8C41426A4CB5C87B270CAB6661B145AE /* ASNetworkImageNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASNetworkImageNode.mm; path = Source/ASNetworkImageNode.mm; sourceTree = ""; }; + 8C92A50FED85091B4E69170C3E055C0C /* ASTextKitContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitContext.mm; path = Source/TextKit/ASTextKitContext.mm; sourceTree = ""; }; + 8D2B6528B911C7F2F567D3505C788ED9 /* PINCache.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINCache.debug.xcconfig; sourceTree = ""; }; 8DAEC71D283EFA4FCB50A3E29F51370A /* InjectableLoggers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = InjectableLoggers.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 8E7536DF5C436E513BCB94280E7CFD70 /* ASTextKitTruncating.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitTruncating.h; path = Source/TextKit/ASTextKitTruncating.h; sourceTree = ""; }; - 8EE240ED270F427A2A20035145E4E12D /* ASScrollDirection.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASScrollDirection.mm; path = Source/Details/ASScrollDirection.mm; sourceTree = ""; }; - 8F207CE79ECE5ADC0BED3DD0D8B7B83B /* ASTextNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTextNode+Beta.h"; path = "Source/ASTextNode+Beta.h"; sourceTree = ""; }; - 8F6250F9BD3F49B51499B90504EE1D5C /* ASRatioLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRatioLayoutSpec.h; path = Source/Layout/ASRatioLayoutSpec.h; sourceTree = ""; }; - 8FC68EA45CF88CEF4344C5649820AC99 /* PINButton+PINRemoteImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINButton+PINRemoteImage.h"; path = "Source/Classes/ImageCategories/PINButton+PINRemoteImage.h"; sourceTree = ""; }; - 8FDE745A011DD537BF75CF20625D7C2E /* ASAbstractLayoutController+FrameworkPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASAbstractLayoutController+FrameworkPrivate.h"; path = "Source/Private/ASAbstractLayoutController+FrameworkPrivate.h"; sourceTree = ""; }; - 90D1F9DA550B0E716C6CB4EF9EA9DAE5 /* PINProgressiveImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINProgressiveImage.m; path = Source/Classes/PINProgressiveImage.m; sourceTree = ""; }; - 911A2B69447A9FA80318E2B59EBEE264 /* Logger.Formatter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.Formatter.swift; path = InjectableLoggers/Classes/Structs/Logger.Formatter.swift; sourceTree = ""; }; - 91ECE220C50CE0A538355C0A14CA578F /* PINImageView+PINRemoteImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImageView+PINRemoteImage.m"; path = "Source/Classes/ImageCategories/PINImageView+PINRemoteImage.m"; sourceTree = ""; }; - 92540F298A1CABBD995289FDD9759F69 /* PINRemoteImageMemoryContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageMemoryContainer.h; path = Source/Classes/PINRemoteImageMemoryContainer.h; sourceTree = ""; }; - 92F9025F046A5B8CD0B0A7FBF4C53383 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; }; - 937DE4AA07CF005B3D3E13301EDEDDAF /* ASCollectionView.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionView.mm; path = Source/ASCollectionView.mm; sourceTree = ""; }; - 93858681644872716A52C7FA30FF1F36 /* PINImage+DecodedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImage+DecodedImage.h"; path = "Source/Classes/Categories/PINImage+DecodedImage.h"; sourceTree = ""; }; - 947A438B776425860B7954368A814273 /* ASTipProvider.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTipProvider.mm; path = Source/Private/ASTipProvider.mm; sourceTree = ""; }; - 9534DB6C12F7A203D038C860278C69B2 /* ASCellNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCellNode.mm; path = Source/ASCellNode.mm; sourceTree = ""; }; - 95405DC3767380B72AF31549E659FCF7 /* HasImageZoomControllers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = HasImageZoomControllers.swift; sourceTree = ""; }; - 956EDCF688E51E9B81CC568337DB6AF1 /* ASContextTransitioning.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASContextTransitioning.h; path = Source/ASContextTransitioning.h; sourceTree = ""; }; - 95722285F0E34655A8452709EE3B6E55 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; - 9698D9EA7BD19EB23AB3EAB57A993843 /* ASCollectionLayoutState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutState.h; path = Source/Details/ASCollectionLayoutState.h; sourceTree = ""; }; - 96BE75919B287F89A7548E608DFC243C /* PINRemoteImageProcessorTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageProcessorTask.h; path = Source/Classes/PINRemoteImageProcessorTask.h; sourceTree = ""; }; - 9716B558FD71C638448F6241417C5707 /* ASDisplayNodeExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDisplayNodeExtras.mm; path = Source/ASDisplayNodeExtras.mm; sourceTree = ""; }; + 8DDCCA94D499BCBA2318214BADCD72DF /* Zoomy.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = Zoomy.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 8E130B5861ABC920DB5C7C130B2CD5F8 /* HasDefaultLoglevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HasDefaultLoglevel.swift; path = InjectableLoggers/Classes/Protocols/HasDefaultLoglevel.swift; sourceTree = ""; }; + 8E8DE6B6E689A78CB6F2E92F79BEC7E0 /* ASTextKitRenderer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitRenderer.h; path = Source/TextKit/ASTextKitRenderer.h; sourceTree = ""; }; + 8E96667745230EA660158A21EACF1E3F /* AsyncDisplayKit+Debug.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "AsyncDisplayKit+Debug.h"; path = "Source/Debug/AsyncDisplayKit+Debug.h"; sourceTree = ""; }; + 8FB1B03C5E645FDFD3FACFBDACA87DB9 /* Zoomy.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Zoomy.release.xcconfig; sourceTree = ""; }; + 90589B54C0040F9F2E141D6205FB3F95 /* _ASPendingState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASPendingState.h; path = Source/Private/_ASPendingState.h; sourceTree = ""; }; + 90697248975C12C20D265C8FC2F89492 /* ASScrollDirection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASScrollDirection.h; path = Source/Details/ASScrollDirection.h; sourceTree = ""; }; + 9088145837DA903D0C458572E6EF9C58 /* ASButtonNode+Yoga.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASButtonNode+Yoga.h"; path = "Source/ASButtonNode+Yoga.h"; sourceTree = ""; }; + 90EA83CDB56F528D679D861D7FADF2DC /* ASDisplayNode+DebugTiming.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+DebugTiming.mm"; path = "Source/Private/ASDisplayNode+DebugTiming.mm"; sourceTree = ""; }; + 915AA3BE58BFD111EC7114C0CB67E360 /* ASTextKitCoreTextAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitCoreTextAdditions.h; path = Source/TextKit/ASTextKitCoreTextAdditions.h; sourceTree = ""; }; + 91BFC03CE4B616D14105ACD4A4486EC1 /* ASRatioLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRatioLayoutSpec.h; path = Source/Layout/ASRatioLayoutSpec.h; sourceTree = ""; }; + 921BD97807EB0DDC435B8194E258EA9F /* AnimationEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AnimationEvent.swift; sourceTree = ""; }; + 923B449EB1487E6024A361F239600946 /* ASDataController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDataController.h; path = Source/Details/ASDataController.h; sourceTree = ""; }; + 924DB1E2EBFF6B95672DC515046ACE58 /* AsyncDisplayKit+Tips.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "AsyncDisplayKit+Tips.h"; path = "Source/Debug/AsyncDisplayKit+Tips.h"; sourceTree = ""; }; + 9265300B5E28071C901DCD8848EDAF35 /* ASLayoutSpec+Subclasses.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASLayoutSpec+Subclasses.h"; path = "Source/Layout/ASLayoutSpec+Subclasses.h"; sourceTree = ""; }; + 927D9DECBCACA5CF8DBD67DACE505DC2 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessageAtLevelInFileInFunctionAtLine.swift; path = InjectableLoggers/Classes/Protocols/CanLogMessageAtLevelInFileInFunctionAtLine.swift; sourceTree = ""; }; + 92C807BC6495BAE35DE79649C8299695 /* ASButtonNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASButtonNode.mm; path = Source/ASButtonNode.mm; sourceTree = ""; }; + 93D192702C0F63552D3A3479AC17225A /* ASWeakProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASWeakProxy.h; path = Source/Details/ASWeakProxy.h; sourceTree = ""; }; + 9445659F6DDC49F7C027607DDB4B67FB /* ASMapNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMapNode.h; path = Source/ASMapNode.h; sourceTree = ""; }; + 94FA6A0CED36425F79643AE9E44BDD3B /* PINProgressiveImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINProgressiveImage.m; path = Source/Classes/PINProgressiveImage.m; sourceTree = ""; }; + 953AD4EF877BF93E174279ECC0B1D89F /* ASCollectionViewLayoutInspector.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionViewLayoutInspector.mm; path = Source/Details/ASCollectionViewLayoutInspector.mm; sourceTree = ""; }; + 9556208FA82CB1183791FB5EB2A58D5F /* ASDisplayNode+Ancestry.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+Ancestry.mm"; path = "Source/Base/ASDisplayNode+Ancestry.mm"; sourceTree = ""; }; + 95FEC909C32BFD96EB1F86C86CAAD03D /* PINRemoteImageBasicCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageBasicCache.m; path = Source/Classes/PINRemoteImageBasicCache.m; sourceTree = ""; }; + 96B7C2C62F443A5228AC674A23FCCD87 /* CanLogMessageInFileInFunctionAtLine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessageInFileInFunctionAtLine.swift; path = InjectableLoggers/Classes/Protocols/CanLogMessageInFileInFunctionAtLine.swift; sourceTree = ""; }; + 96BAB84DDE20C8E79F0FFC7E5B015EDC /* UIGestureRecognizerState+CustomStringConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizerState+CustomStringConvertible.swift"; sourceTree = ""; }; + 96D07D4CC3912A46A18D147E14F42FBF /* ASOverlayLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASOverlayLayoutSpec.mm; path = Source/Layout/ASOverlayLayoutSpec.mm; sourceTree = ""; }; 97917796797A60F0392794674DAFD64E /* Pods-Zoomy_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Zoomy_Tests-umbrella.h"; sourceTree = ""; }; - 97E41C83A55213B5CA3787B8C3A4CA01 /* ASCGImageBuffer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCGImageBuffer.h; path = Source/ASCGImageBuffer.h; sourceTree = ""; }; - 994BF7579A66B53B1E474D7F2E06A292 /* ASTextUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextUtilities.h; path = Source/Private/TextExperiment/Utility/ASTextUtilities.h; sourceTree = ""; }; + 97CD5B552AABAF73943AE088CCB7BAFA /* ASPINRemoteImageDownloader.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASPINRemoteImageDownloader.mm; path = Source/Details/ASPINRemoteImageDownloader.mm; sourceTree = ""; }; + 97E777762D92CC607C25F3EF65BEA975 /* ASHighlightOverlayLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASHighlightOverlayLayer.h; path = Source/Details/ASHighlightOverlayLayer.h; sourceTree = ""; }; + 9912693AC1AD6E93BC00EDC6E1E48E91 /* PINCache-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PINCache-dummy.m"; sourceTree = ""; }; 995ACD99A6A9DAE10AB6D1FD8C20BA35 /* Pods-Zoomy_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Zoomy_Example-umbrella.h"; sourceTree = ""; }; - 9981AC172C1B313D4AFDF736B83E76DD /* ASTextLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextLayout.h; path = Source/Private/TextExperiment/Component/ASTextLayout.h; sourceTree = ""; }; - 998892452F748ECC73ACD89183345341 /* ASControlNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASControlNode.mm; path = Source/ASControlNode.mm; sourceTree = ""; }; - 99944E9365C1EDE2071B715261BF6FD9 /* Texture.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Texture.modulemap; sourceTree = ""; }; - 999ABCA7921CDF37F8B7B19411E1084D /* ASCenterLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCenterLayoutSpec.h; path = Source/Layout/ASCenterLayoutSpec.h; sourceTree = ""; }; - 99E23194CF8E8F54AF09B96E09EFE9FD /* ASCenterLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCenterLayoutSpec.mm; path = Source/Layout/ASCenterLayoutSpec.mm; sourceTree = ""; }; - 9A3CFDC315D163384B2F7024695124BD /* ASStackUnpositionedLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackUnpositionedLayout.h; path = Source/Private/Layout/ASStackUnpositionedLayout.h; sourceTree = ""; }; - 9A83CB18A0AFD9B76C70CFE0F7189A01 /* Zoomy-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Zoomy-umbrella.h"; sourceTree = ""; }; - 9B7C5313BA0D58DED056D33BC4538443 /* ASTraitCollection.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTraitCollection.mm; path = Source/Details/ASTraitCollection.mm; sourceTree = ""; }; - 9BB3F630C68C3A5DFB13F24E7FCAD25A /* ASEventLog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASEventLog.h; path = Source/Details/ASEventLog.h; sourceTree = ""; }; - 9C6960CA476D12BC3E1596C094F2BFAD /* ASSignpost.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSignpost.h; path = Source/Base/ASSignpost.h; sourceTree = ""; }; - 9C8C5E2FFC7D7BAB935A72ACA952F4B7 /* ASCollectionLayoutContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutContext.h; path = Source/Details/ASCollectionLayoutContext.h; sourceTree = ""; }; - 9C9B91A2092075DF22A0BDCB1A1EEBCA /* PINGIFAnimatedImageManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINGIFAnimatedImageManager.m; path = Source/Classes/PINGIFAnimatedImageManager.m; sourceTree = ""; }; - 9CF3ECB29AFF0D004E804019BA456BAF /* ASLayoutElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElement.h; path = Source/Layout/ASLayoutElement.h; sourceTree = ""; }; - 9CFB3A1E5D6B29DCDD26302D3E775DC1 /* ASDisplayNode+LayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+LayoutSpec.h"; path = "Source/ASDisplayNode+LayoutSpec.h"; sourceTree = ""; }; - 9D593D3251E3CB76916473892474B96F /* ASExperimentalFeatures.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASExperimentalFeatures.mm; path = Source/ASExperimentalFeatures.mm; sourceTree = ""; }; - 9D768DA83B418CA0C1CC710850566A92 /* AsyncDisplayKit+Debug.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "AsyncDisplayKit+Debug.h"; path = "Source/Debug/AsyncDisplayKit+Debug.h"; sourceTree = ""; }; - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - A038B802D8F0C0EC85498DA10C1EC1F5 /* PINCache+PINRemoteImageCaching.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINCache+PINRemoteImageCaching.m"; path = "Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m"; sourceTree = ""; }; - A0C4D1E5B3896EEE58F2719BD330AE3D /* ASTwoDimensionalArrayUtils.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTwoDimensionalArrayUtils.mm; path = Source/Private/ASTwoDimensionalArrayUtils.mm; sourceTree = ""; }; - A184C7A5B0B71E080B56514AB7E8A425 /* ASDisplayNode+DebugTiming.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+DebugTiming.h"; path = "Source/Private/ASDisplayNode+DebugTiming.h"; sourceTree = ""; }; - A23F94511B338FE277EC2BCFEC053F24 /* ASVideoNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASVideoNode.mm; path = Source/ASVideoNode.mm; sourceTree = ""; }; - A2D9B780803CCE87983E460EF683910E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - A2DA07ACA67D6E241C85078FE67F857E /* _ASHierarchyChangeSet.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASHierarchyChangeSet.mm; path = Source/Private/_ASHierarchyChangeSet.mm; sourceTree = ""; }; - A32221AE94CD1425D9F2E1F183BBC001 /* ASCollectionGalleryLayoutDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionGalleryLayoutDelegate.h; path = Source/Details/ASCollectionGalleryLayoutDelegate.h; sourceTree = ""; }; - A38C44A24E481D727A9C07A5CA684514 /* ASCollections.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollections.mm; path = Source/ASCollections.mm; sourceTree = ""; }; - A396339D2FC678CBF9BBF4141C6E3AED /* PINRemoteImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImage.h; path = Source/Classes/PINRemoteImage.h; sourceTree = ""; }; - A566D0D02EDF7ADE78AD3563AC231EF8 /* ASAbstractLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAbstractLayoutController.h; path = Source/Details/ASAbstractLayoutController.h; sourceTree = ""; }; - A5C0CFFB06A4F703B26E2CB912988F77 /* ASIGListAdapterBasedDataSource.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASIGListAdapterBasedDataSource.mm; path = Source/Private/ASIGListAdapterBasedDataSource.mm; sourceTree = ""; }; - A62DAA92B3EEF14B2EBFA714FFF6B6D7 /* ASWeakMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASWeakMap.h; path = Source/Private/ASWeakMap.h; sourceTree = ""; }; - A70EC583D74B1259AF4D563FB225D45C /* PINProgressiveImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINProgressiveImage.h; path = Source/Classes/PINProgressiveImage.h; sourceTree = ""; }; - A78AFDF66148881309B4E97383CA01DC /* ASVideoPlayerNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASVideoPlayerNode.mm; path = Source/ASVideoPlayerNode.mm; sourceTree = ""; }; - A7DB14A5844AB9D9843C0B181E42BE46 /* AsyncDisplayKit+Tips.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "AsyncDisplayKit+Tips.h"; path = "Source/Debug/AsyncDisplayKit+Tips.h"; sourceTree = ""; }; - A867957DE758B3752902421CE4EA0DF8 /* ASDisplayNode+UIViewBridge.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+UIViewBridge.mm"; path = "Source/Private/ASDisplayNode+UIViewBridge.mm"; sourceTree = ""; }; - A953839D36FAD7AB1C3B310EA76073D0 /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = Source/Layout/ASStackLayoutDefines.h; sourceTree = ""; }; - A98A5F46B2F5435F186701CCADD6D4CD /* ASCollectionLayoutState+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionLayoutState+Private.h"; path = "Source/Private/ASCollectionLayoutState+Private.h"; sourceTree = ""; }; - A9E479AD6CC4807738F653AF75B351CB /* ASNetworkImageNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASNetworkImageNode.h; path = Source/ASNetworkImageNode.h; sourceTree = ""; }; - AA3875A1795ED07E509FDD997F948597 /* _ASCollectionGalleryLayoutItem.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASCollectionGalleryLayoutItem.mm; path = Source/Private/_ASCollectionGalleryLayoutItem.mm; sourceTree = ""; }; - AB0C309D246B1C8BAD0377A6A1815153 /* PINImageView+PINRemoteImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImageView+PINRemoteImage.h"; path = "Source/Classes/ImageCategories/PINImageView+PINRemoteImage.h"; sourceTree = ""; }; - AB585F9D4AB7A266D774F3A142704648 /* PINOperation-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINOperation-umbrella.h"; sourceTree = ""; }; - AD44715CD9D5542D3941D58B4A413098 /* PINRemoteImageCallbacks.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageCallbacks.h; path = Source/Classes/PINRemoteImageCallbacks.h; sourceTree = ""; }; - AD83B8B951B27AA22FAEEA2F1531D940 /* PINRemoteImage-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PINRemoteImage-Info.plist"; sourceTree = ""; }; - ADEAF002D779FE80DA13FE31725E5FCA /* ASBatchContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASBatchContext.mm; path = Source/Details/ASBatchContext.mm; sourceTree = ""; }; - AE1FE096C913D8F624564FE170A0B4B1 /* ASLayout+IGListKit.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASLayout+IGListKit.mm"; path = "Source/Layout/ASLayout+IGListKit.mm"; sourceTree = ""; }; - AECD5C2F25705D0D88F3CBD2374C4F9B /* ASPINRemoteImageDownloader.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASPINRemoteImageDownloader.mm; path = Source/Details/ASPINRemoteImageDownloader.mm; sourceTree = ""; }; - AEFE143F7C05931041DA6DF354DE63CC /* ASInternalHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASInternalHelpers.h; path = Source/Private/ASInternalHelpers.h; sourceTree = ""; }; - AF8951F6130635C32B10D41798AA0F40 /* ASDisplayNodeCornerLayerDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDisplayNodeCornerLayerDelegate.mm; path = Source/Private/ASDisplayNodeCornerLayerDelegate.mm; sourceTree = ""; }; - B093FB7C9D3A95FC8A8BA9F203EF0987 /* ASDefaultPlayButton.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDefaultPlayButton.mm; path = Source/Private/ASDefaultPlayButton.mm; sourceTree = ""; }; - B10A8EE0FA86A85383E48A756A391C24 /* ASCornerLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCornerLayoutSpec.h; path = Source/Layout/ASCornerLayoutSpec.h; sourceTree = ""; }; - B1257D21990FE33E970249DA587E24A9 /* ASLayoutElementPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElementPrivate.h; path = Source/Layout/ASLayoutElementPrivate.h; sourceTree = ""; }; - B1649C9B28814A0E5C609ACCC9D4BFEA /* CanProvideAnimatorForEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanProvideAnimatorForEvent.swift; sourceTree = ""; }; - B1ED2112DB2D51FF25BF173D7BA39B1B /* Zoomy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Zoomy.framework; path = Zoomy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B25D491B0A31A845AF0339A0BEA95052 /* ASThread.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASThread.h; path = Source/Details/ASThread.h; sourceTree = ""; }; - B283A07DE6907D817AC983307646ED4C /* ASEditableTextNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASEditableTextNode.mm; path = Source/ASEditableTextNode.mm; sourceTree = ""; }; - B2F4A9B3C994EF9CD4EE8D995926F08B /* ASHashing.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASHashing.mm; path = Source/Details/ASHashing.mm; sourceTree = ""; }; - B34887E975D5A8E86DCAEB7D3EC54B38 /* ASCGImageBuffer.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCGImageBuffer.mm; path = Source/ASCGImageBuffer.mm; sourceTree = ""; }; - B42F164AEA1DD630EF5DB88F3E6546A1 /* _ASCollectionViewCell.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionViewCell.h; path = Source/Details/_ASCollectionViewCell.h; sourceTree = ""; }; - B54D5C75E76CBA98DF5873350D8E1932 /* ASTextNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextNode.mm; path = Source/ASTextNode.mm; sourceTree = ""; }; - B5CA33263F85C6E21A268F342F079528 /* ASDisplayNode+Convenience.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+Convenience.mm"; path = "Source/ASDisplayNode+Convenience.mm"; sourceTree = ""; }; - B5D733DA59C42F85C9420CC9D53FD100 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASLayoutTransition.mm; path = Source/Private/ASLayoutTransition.mm; sourceTree = ""; }; - B5DE6DADB18EAD43910351907C8EAB45 /* PINImage+DecodedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImage+DecodedImage.m"; path = "Source/Classes/Categories/PINImage+DecodedImage.m"; sourceTree = ""; }; - B6A6531A377911E1EFE834A1B541072D /* ASPagerNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPagerNode.h; path = Source/ASPagerNode.h; sourceTree = ""; }; - B73C16ED725233597781AD592DEAE342 /* ASDisplayNodeExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeExtras.h; path = Source/ASDisplayNodeExtras.h; sourceTree = ""; }; - B763F6804A576872367A393D9228CA2E /* PINCache+PINRemoteImageCaching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINCache+PINRemoteImageCaching.h"; path = "Source/Classes/PINCache/PINCache+PINRemoteImageCaching.h"; sourceTree = ""; }; - B88ACF20E41D2246608FEA823AC77B13 /* ASTextKitRenderer+TextChecking.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASTextKitRenderer+TextChecking.mm"; path = "Source/TextKit/ASTextKitRenderer+TextChecking.mm"; sourceTree = ""; }; - B8965C6AC7D32CBE8AB47BD3DD1AA7D1 /* AsyncDisplayKit+IGListKitMethods.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "AsyncDisplayKit+IGListKitMethods.mm"; path = "Source/AsyncDisplayKit+IGListKitMethods.mm"; sourceTree = ""; }; - B8FC2C1E24D7F7723065F7C02EDB1715 /* PINMemoryCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINMemoryCache.h; path = Source/PINMemoryCache.h; sourceTree = ""; }; - B9FB154DB28A1272A40CA2071CA41E71 /* HasDefaultLoglevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HasDefaultLoglevel.swift; path = InjectableLoggers/Classes/Protocols/HasDefaultLoglevel.swift; sourceTree = ""; }; - BA4B0255BD9DE24340698FC805C07449 /* PINCache.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINCache.xcconfig; sourceTree = ""; }; - BAC3EE3B34E6F03D24161D8B69B10D48 /* ASNodeController+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASNodeController+Beta.h"; path = "Source/ASNodeController+Beta.h"; sourceTree = ""; }; - BB14945CFEBAC7BB06C3931211F933FB /* _ASAsyncTransactionContainer.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASAsyncTransactionContainer.mm; path = Source/Details/Transactions/_ASAsyncTransactionContainer.mm; sourceTree = ""; }; - BB82EEF6CD35EC54E853AD4070BB9F25 /* ASLayoutSpecUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutSpecUtilities.h; path = Source/Private/Layout/ASLayoutSpecUtilities.h; sourceTree = ""; }; - BC4DA700D665D4C0D110ACE8AAED6FB4 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanFormatMessageInFileInFunctionAtLineWithSettings.swift; path = InjectableLoggers/Classes/Protocols/CanFormatMessageInFileInFunctionAtLineWithSettings.swift; sourceTree = ""; }; - BC8BCDD05FFF87F653DF293D126D9292 /* PINRemoteImageCaching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageCaching.h; path = Source/Classes/PINRemoteImageCaching.h; sourceTree = ""; }; - BCAAB9B73EF8F3432A4345B9A9A25A2D /* ASGraphicsContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASGraphicsContext.mm; path = Source/Details/ASGraphicsContext.mm; sourceTree = ""; }; - BD47532762609FE8FD8106735ABFB4FB /* IGListAdapter+AsyncDisplayKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "IGListAdapter+AsyncDisplayKit.h"; path = "Source/IGListAdapter+AsyncDisplayKit.h"; sourceTree = ""; }; - BDF8134E8543067B3399A8AFC359C859 /* ASTextKitComponents.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitComponents.mm; path = Source/TextKit/ASTextKitComponents.mm; sourceTree = ""; }; - BE5BE38429E1421B25B26E3F778B6388 /* ASTextKitComponents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitComponents.h; path = Source/TextKit/ASTextKitComponents.h; sourceTree = ""; }; - BEAC1BDFD6524223CCD83E5EDC23DEE1 /* SimpleLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SimpleLogger.swift; path = InjectableLoggers/Classes/Classes/SimpleLogger.swift; sourceTree = ""; }; - BEC9D1A35829C776E86C1943567228B3 /* ASDataController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDataController.mm; path = Source/Details/ASDataController.mm; sourceTree = ""; }; - BF28046FF0FAA13D619A64DAA2D048C1 /* PINRemoteImageTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageTask.m; path = Source/Classes/PINRemoteImageTask.m; sourceTree = ""; }; - BF5E1C8959ABF12DB3C62716FE084307 /* InjectableLoggers.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = InjectableLoggers.modulemap; sourceTree = ""; }; - C04BAB749055606D3946777030990DE3 /* InjectableLoggers-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "InjectableLoggers-dummy.m"; sourceTree = ""; }; - C065EA4E96480B78158007EA06DE3DA7 /* ASScrollNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASScrollNode.mm; path = Source/ASScrollNode.mm; sourceTree = ""; }; - C107CFBED03119CB9FB979B38275EFDE /* ASSectionContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSectionContext.h; path = Source/Details/ASSectionContext.h; sourceTree = ""; }; - C187236A999EC1D588BFDC6A9269C806 /* ASControlNode+Subclasses.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASControlNode+Subclasses.h"; path = "Source/ASControlNode+Subclasses.h"; sourceTree = ""; }; - C1B5279955DCE765725B542C20DC2C37 /* ASTextKitContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitContext.h; path = Source/TextKit/ASTextKitContext.h; sourceTree = ""; }; - C1BC0617843927EBC5E65D973264D1FC /* logger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = logger.swift; sourceTree = ""; }; - C2F3FAB56ABA986E779429D2637559C7 /* ASViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASViewController.h; path = Source/ASViewController.h; sourceTree = ""; }; - C2FEC161E352AF6BAEC084E513C5C48D /* ASElementMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASElementMap.h; path = Source/Details/ASElementMap.h; sourceTree = ""; }; - C34BD2D317CCDC7344BEA22900C93E20 /* ASTableLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableLayoutController.h; path = Source/Details/ASTableLayoutController.h; sourceTree = ""; }; - C35693DA8C2E5A82EBA0F056580C2534 /* ASNavigationController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASNavigationController.mm; path = Source/ASNavigationController.mm; sourceTree = ""; }; - C3A340B8DECFEA34B858E29D8A3B6860 /* ASDisplayNode+Ancestry.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+Ancestry.mm"; path = "Source/Base/ASDisplayNode+Ancestry.mm"; sourceTree = ""; }; - C4000565ABB42B463A834CB1F2577D74 /* PINOperationQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationQueue.h; path = Source/PINOperationQueue.h; sourceTree = ""; }; - C479D571D3825B10ECABE5FE1938450E /* NSData+ImageDetectors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+ImageDetectors.h"; path = "Source/Classes/Categories/NSData+ImageDetectors.h"; sourceTree = ""; }; - C47D135FDC8D2FF911DEA2FC755D8C75 /* ASCollectionLayoutCache.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionLayoutCache.mm; path = Source/Private/ASCollectionLayoutCache.mm; sourceTree = ""; }; - C4F0FE57A14FE3D7B4120DEFA866E5A6 /* PINDiskCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINDiskCache.m; path = Source/PINDiskCache.m; sourceTree = ""; }; - C513C2D2192061E27F0D119FF031C017 /* ASTip.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTip.h; path = Source/Private/ASTip.h; sourceTree = ""; }; - C54C9862069FBA457D7E8F2CAC1BEDEF /* ASDefaultPlaybackButton.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDefaultPlaybackButton.mm; path = Source/Private/ASDefaultPlaybackButton.mm; sourceTree = ""; }; - C601CF5677E9413D7D662DCBFF8A420B /* Texture-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Texture-dummy.m"; sourceTree = ""; }; - C6168D2B373231D675211F9910C528C7 /* ASTextLine.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextLine.mm; path = Source/Private/TextExperiment/Component/ASTextLine.mm; sourceTree = ""; }; - C635F17EAEE4E59A1CE2F6202E5247EE /* ASImageContainerProtocolCategories.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASImageContainerProtocolCategories.mm; path = Source/Details/ASImageContainerProtocolCategories.mm; sourceTree = ""; }; - C745ABE5CF7074BDCB56E1DF0CE7481C /* ASCollectionViewLayoutController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionViewLayoutController.mm; path = Source/Details/ASCollectionViewLayoutController.mm; sourceTree = ""; }; - C77B159A3B34D6119258725CE283719C /* ASCollectionElement.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionElement.mm; path = Source/Details/ASCollectionElement.mm; sourceTree = ""; }; - C7CDB77E762DB5C99E6306652B4B6947 /* ASRangeController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRangeController.h; path = Source/Details/ASRangeController.h; sourceTree = ""; }; - C8550F0BE91A5EAD479CBC31C1CC9D2E /* Logger.Settings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Logger.Settings.swift; path = InjectableLoggers/Classes/Structs/Logger.Settings.swift; sourceTree = ""; }; - C9579AF5CF380A430E2296E21C0498ED /* _ASDisplayViewAccessiblity.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASDisplayViewAccessiblity.h; path = Source/Details/_ASDisplayViewAccessiblity.h; sourceTree = ""; }; + 9ABD6F3FC6B368A8ADD0AA7A57D95A2F /* ASAbsoluteLayoutElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAbsoluteLayoutElement.h; path = Source/Layout/ASAbsoluteLayoutElement.h; sourceTree = ""; }; + 9B0C5AF838B291A38952B93A37CA6D83 /* ASLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayout.mm; path = Source/Layout/ASLayout.mm; sourceTree = ""; }; + 9B2FC7355BCE92FE29D5BE9B82EA04A2 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASEqualityHelpers.h; path = Source/Base/ASEqualityHelpers.h; sourceTree = ""; }; + 9BB21D41481E7275F0290AEC1A3596C4 /* PINRemoteImageManagerResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageManagerResult.m; path = Source/Classes/PINRemoteImageManagerResult.m; sourceTree = ""; }; + 9C22693BC29DF70A295F36C2C6CE01D4 /* ASCollectionLayoutContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionLayoutContext.mm; path = Source/Details/ASCollectionLayoutContext.mm; sourceTree = ""; }; + 9C5DB655C78F3CA1A91002A40F883065 /* ASCollectionInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionInternal.h; path = Source/Details/ASCollectionInternal.h; sourceTree = ""; }; + 9C976C49525F404BB47056D7ABA4E4ED /* ASPagerFlowLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPagerFlowLayout.h; path = Source/ASPagerFlowLayout.h; sourceTree = ""; }; + 9CB12185681B73727DC1273F336BFD9D /* ASTextDebugOption.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextDebugOption.mm; path = Source/Private/TextExperiment/Component/ASTextDebugOption.mm; sourceTree = ""; }; + 9D1DFA6C99F765607130031AF14FE7C9 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanFormatMessageInFileInFunctionAtLineWithSettings.swift; path = InjectableLoggers/Classes/Protocols/CanFormatMessageInFileInFunctionAtLineWithSettings.swift; sourceTree = ""; }; + 9D4F5A26F434E2EAAE82328C892FBD1F /* ASCollectionFlowLayoutDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionFlowLayoutDelegate.h; path = Source/Details/ASCollectionFlowLayoutDelegate.h; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9DA27E6D1F06A57F16EC910BF9212642 /* ASTextNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTextNode+Beta.h"; path = "Source/ASTextNode+Beta.h"; sourceTree = ""; }; + 9DADFC8D98A3FEE0083A1D8E2A124F0B /* ASDisplayNode+LayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+LayoutSpec.mm"; path = "Source/ASDisplayNode+LayoutSpec.mm"; sourceTree = ""; }; + 9E2503BEFEB4448C0FA1DA31215EB7C1 /* ASWeakSet.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASWeakSet.mm; path = Source/Details/ASWeakSet.mm; sourceTree = ""; }; + 9E360A0A97628D2F2F2CA7508A2A54DC /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPhotosFrameworkImageRequest.h; path = Source/Details/ASPhotosFrameworkImageRequest.h; sourceTree = ""; }; + 9E362247576ABDCAC95FD27020FA954B /* ASImageProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASImageProtocols.h; path = Source/Details/ASImageProtocols.h; sourceTree = ""; }; + 9E5A50B85249AF7029C56D5811BF80F3 /* PINOperationQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationQueue.h; path = Source/PINOperationQueue.h; sourceTree = ""; }; + 9E60EF003F598F328ED07D1336D1290D /* PINRemoteImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImage.h; path = Source/Classes/include/PINRemoteImage.h; sourceTree = ""; }; + 9EC45975D0A70E685883A6EE402012D1 /* _ASAsyncTransactionContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASAsyncTransactionContainer.h; path = Source/Details/Transactions/_ASAsyncTransactionContainer.h; sourceTree = ""; }; + 9F1B1FC6DB693AE9866C6A07C199E430 /* ASMutableElementMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASMutableElementMap.mm; path = Source/Private/ASMutableElementMap.mm; sourceTree = ""; }; + 9F713CCF7949E74D4E972F737A6788BE /* ASTextKitComponents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitComponents.h; path = Source/TextKit/ASTextKitComponents.h; sourceTree = ""; }; + A0126269F7621AA924B3EA6B12F43F45 /* Zoomy.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Zoomy.debug.xcconfig; sourceTree = ""; }; + A09FF82F01D38B1FBEA2718AEE09F391 /* ASDisplayNode+Ancestry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Ancestry.h"; path = "Source/Base/ASDisplayNode+Ancestry.h"; sourceTree = ""; }; + A0D66F0C5F3D4DD3B7CA386D3563C254 /* CGPoint+maximumAbsoluteValue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGPoint+maximumAbsoluteValue.swift"; sourceTree = ""; }; + A0F896E241CC0E46B053F5953BCCC504 /* ASDisplayNodeTipState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeTipState.h; path = Source/Private/ASDisplayNodeTipState.h; sourceTree = ""; }; + A12A3705DF38020F5B68418E190D0109 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; + A12D2284A307229BE1FCA6C56606D464 /* PINCachedAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINCachedAnimatedImage.m; path = Source/Classes/AnimatedImages/PINCachedAnimatedImage.m; sourceTree = ""; }; + A1D0D3B5F98B76FBBF66FBC689B55B7F /* ASSectionContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSectionContext.h; path = Source/Details/ASSectionContext.h; sourceTree = ""; }; + A289C7402C699BD2D20E8279A1D473D7 /* ASLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayout.h; path = Source/Layout/ASLayout.h; sourceTree = ""; }; + A2C7DF35D1B0CC4FC09821434405BCEF /* IGListAdapter+AsyncDisplayKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "IGListAdapter+AsyncDisplayKit.h"; path = "Source/IGListAdapter+AsyncDisplayKit.h"; sourceTree = ""; }; + A2CAEDFAB34F305AE5494D35EA368453 /* ASLayerBackingTipProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayerBackingTipProvider.h; path = Source/Private/ASLayerBackingTipProvider.h; sourceTree = ""; }; + A2D83E80452A02F4E51C53E14432A3AF /* AsyncDisplayKit+Debug.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "AsyncDisplayKit+Debug.mm"; path = "Source/Debug/AsyncDisplayKit+Debug.mm"; sourceTree = ""; }; + A2FC73F1B141C088A7A71E3189F506E9 /* ASDimension.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDimension.mm; path = Source/Layout/ASDimension.mm; sourceTree = ""; }; + A3139E8FDADE2AA15C6B526F491D387D /* ASIGListAdapterBasedDataSource.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASIGListAdapterBasedDataSource.mm; path = Source/Private/ASIGListAdapterBasedDataSource.mm; sourceTree = ""; }; + A32CFB4D17BCD23C29D1D5787CE32EF3 /* ASTipProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipProvider.h; path = Source/Private/ASTipProvider.h; sourceTree = ""; }; + A3824C2887A3C7EC685E7EF3070F9A4E /* ASTextNodeWordKerner.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextNodeWordKerner.mm; path = Source/TextKit/ASTextNodeWordKerner.mm; sourceTree = ""; }; + A49EDF562F5CD661061E25A7EC26B58C /* ASDisplayNode+Subclasses.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Subclasses.h"; path = "Source/ASDisplayNode+Subclasses.h"; sourceTree = ""; }; + A4E31B166F2E3EE17BA52F79751D6ED5 /* ASExperimentalFeatures.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASExperimentalFeatures.h; path = Source/ASExperimentalFeatures.h; sourceTree = ""; }; + A50A604616BEE784281355A14AB4924B /* ImageZoomControllerSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerSettings.swift; sourceTree = ""; }; + A52E2451F6B76F104A42C6B6EBABAC0E /* ASDelegateProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDelegateProxy.h; path = Source/Details/ASDelegateProxy.h; sourceTree = ""; }; + A546884224C6ED423FD4E6E7883B3077 /* ASScrollNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASScrollNode.h; path = Source/ASScrollNode.h; sourceTree = ""; }; + A6260ECA1905AD096C8931DC364B024D /* InjectableLoggers.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = InjectableLoggers.debug.xcconfig; sourceTree = ""; }; + A6349CF71BFAF7D4A5704EB8D83E462E /* PINAnimatedImageView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINAnimatedImageView.m; path = Source/Classes/AnimatedImages/PINAnimatedImageView.m; sourceTree = ""; }; + A639AABF7D211E360C74CE4CC936E311 /* ASObjectDescriptionHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASObjectDescriptionHelpers.h; path = Source/Details/ASObjectDescriptionHelpers.h; sourceTree = ""; }; + A6608A16D83A6A25E6DD589D4FF08DB9 /* PINRemoteImageCategoryManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageCategoryManager.m; path = Source/Classes/PINRemoteImageCategoryManager.m; sourceTree = ""; }; + A6C94B27A14D01BA956D86F321DBFF8F /* ASRelativeLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRelativeLayoutSpec.mm; path = Source/Layout/ASRelativeLayoutSpec.mm; sourceTree = ""; }; + A73CB612A2B88D87EABFAA2E231091B4 /* Texture-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Texture-umbrella.h"; sourceTree = ""; }; + A7604C8C65BB4E702C08E6E64DCF64CF /* PINRemoteLock.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteLock.m; path = Source/Classes/PINRemoteLock.m; sourceTree = ""; }; + A7A7381EDB33C4C063714E18E447DF8D /* _ASHierarchyChangeSet.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASHierarchyChangeSet.h; path = Source/Private/_ASHierarchyChangeSet.h; sourceTree = ""; }; + A7E2AFAFBC59C4434EA0F452218F8C42 /* ASHashing.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASHashing.mm; path = Source/Details/ASHashing.mm; sourceTree = ""; }; + A85BDA95A647F56CD7259E121D6FA99A /* ASExperimentalFeatures.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASExperimentalFeatures.mm; path = Source/ASExperimentalFeatures.mm; sourceTree = ""; }; + A8B619F8704EE467BAD027D7B3D78A8B /* Zoomy-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Zoomy-prefix.pch"; sourceTree = ""; }; + A8C5B4CDB31225A9BF38BCC18B506CBC /* Zoomy-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Zoomy-dummy.m"; sourceTree = ""; }; + A9434A1F46A9E3864CE96A3F43924782 /* ASTextKitContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitContext.h; path = Source/TextKit/ASTextKitContext.h; sourceTree = ""; }; + A96C263605C9675F6111B10DC6EBA561 /* logger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = logger.swift; sourceTree = ""; }; + AAE59626849BEF2264FC9EB98B2EBDB3 /* ASSection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSection.h; path = Source/Private/ASSection.h; sourceTree = ""; }; + ABB94274587D4AB055B0098469B62741 /* CanPerformAction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanPerformAction.swift; sourceTree = ""; }; + AC262B220308DD0BE3539DADEF6A984D /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = Source/Layout/ASStackLayoutDefines.h; sourceTree = ""; }; + AC76142E2ECD50C70F0A3150606B27D0 /* ASMapNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASMapNode.mm; path = Source/ASMapNode.mm; sourceTree = ""; }; + AD9ABC06E9F1438A47B1B873A9BF1FC9 /* ASDisplayNodeCornerLayerDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDisplayNodeCornerLayerDelegate.mm; path = Source/Private/ASDisplayNodeCornerLayerDelegate.mm; sourceTree = ""; }; + ADDB82741AD2FBDEE3C9C44C84A11380 /* ASDKViewController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDKViewController.mm; path = Source/ASDKViewController.mm; sourceTree = ""; }; + AEFEFAA3AC9FF06B1F868CF0C07B6C39 /* ASCollectionLayoutContext+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionLayoutContext+Private.h"; path = "Source/Private/ASCollectionLayoutContext+Private.h"; sourceTree = ""; }; + AF1305A2D3148FEB652C18D895431362 /* ASDisplayNode+Convenience.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+Convenience.mm"; path = "Source/ASDisplayNode+Convenience.mm"; sourceTree = ""; }; + AF56F95269473FF68D4A9F83950E1E15 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AsyncDisplayKit.h; path = Source/AsyncDisplayKit.h; sourceTree = ""; }; + AF60023FF5645E71160109652BDEE4D3 /* ASBackgroundLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASBackgroundLayoutSpec.mm; path = Source/Layout/ASBackgroundLayoutSpec.mm; sourceTree = ""; }; + B067FDE9BD6960EBEA76FECAE06AA589 /* PINDiskCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINDiskCache.h; path = Source/PINDiskCache.h; sourceTree = ""; }; + B0C21DADF77FC6BC3F01C866041F4B12 /* ASMainThreadDeallocation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASMainThreadDeallocation.mm; path = Source/ASMainThreadDeallocation.mm; sourceTree = ""; }; + B0ED94615CE6CEC319F06AACF1CEB800 /* PINProgressiveImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINProgressiveImage.h; path = Source/Classes/include/PINProgressiveImage.h; sourceTree = ""; }; + B1ED2112DB2D51FF25BF173D7BA39B1B /* Zoomy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Zoomy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B1FBF5272BEF80A065086982B71E6AD2 /* Texture-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Texture-Info.plist"; sourceTree = ""; }; + B2004AC400F42335B666DAB0028739F9 /* Zoomy-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Zoomy-umbrella.h"; sourceTree = ""; }; + B21D04D0712E0F8DFD37114AD104DB83 /* ASLayout+IGListDiffKit.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASLayout+IGListDiffKit.mm"; path = "Source/Layout/ASLayout+IGListDiffKit.mm"; sourceTree = ""; }; + B34FE789AA0085844B00920EA8ABD869 /* ASCollectionElement.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionElement.mm; path = Source/Details/ASCollectionElement.mm; sourceTree = ""; }; + B3C8F3A4509640386CCC3F9E5A843E10 /* ASDisplayNode+LayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+LayoutSpec.h"; path = "Source/ASDisplayNode+LayoutSpec.h"; sourceTree = ""; }; + B451A50AAD10F605219DFD5A70CE2156 /* PINCache-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINCache-umbrella.h"; sourceTree = ""; }; + B4877B07FDD3DFF09B753FA5D3BB2FD9 /* PINRemoteImageCallbacks.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageCallbacks.h; path = Source/Classes/PINRemoteImageCallbacks.h; sourceTree = ""; }; + B5A3F7221807630DE3D0449E1D30FC1F /* ASVideoPlayerNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASVideoPlayerNode.mm; path = Source/ASVideoPlayerNode.mm; sourceTree = ""; }; + B68441AB82FA9337F6184B4FC8706C89 /* PINWebPAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINWebPAnimatedImage.h; path = Source/Classes/include/PINWebPAnimatedImage.h; sourceTree = ""; }; + B68757212BC40EE9FAA2CCF6917D014D /* ASDisplayNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDisplayNode.mm; path = Source/ASDisplayNode.mm; sourceTree = ""; }; + B70C3A4BA56751CA33F52C2D0C4B7517 /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsPresentingScrollViewOverlayState.swift; sourceTree = ""; }; + B7DEDDDAA6240649B443BDBFF9429D77 /* PINRequestRetryStrategy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRequestRetryStrategy.h; path = Source/Classes/include/PINRequestRetryStrategy.h; sourceTree = ""; }; + B86953550C8475069C247A7C7039CC61 /* ASTextKitComponents.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitComponents.mm; path = Source/TextKit/ASTextKitComponents.mm; sourceTree = ""; }; + B92BC147B759930674C603C4E1C3555E /* _ASScopeTimer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASScopeTimer.h; path = Source/Private/_ASScopeTimer.h; sourceTree = ""; }; + B9A1585DD0E56306F2329498432F63E9 /* AsyncDisplayKit+IGListKitMethods.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "AsyncDisplayKit+IGListKitMethods.h"; path = "Source/AsyncDisplayKit+IGListKitMethods.h"; sourceTree = ""; }; + BA36FE7BA8C83C8B594E50029C928965 /* ASIGListAdapterBasedDataSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASIGListAdapterBasedDataSource.h; path = Source/Private/ASIGListAdapterBasedDataSource.h; sourceTree = ""; }; + BAF321EC18304D2D7018D41AE15755A2 /* PINCache.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINCache.release.xcconfig; sourceTree = ""; }; + BB3F1F87F50F1A78B7D2377AA4249147 /* PINRemoteImageProcessorTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageProcessorTask.m; path = Source/Classes/PINRemoteImageProcessorTask.m; sourceTree = ""; }; + BC90C657CBDF1FAC23AE4269E0F58A3F /* ASCollectionView+Undeprecated.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionView+Undeprecated.h"; path = "Source/Private/ASCollectionView+Undeprecated.h"; sourceTree = ""; }; + BDA4460D90E3CCCCDF6A594AC96AB183 /* ASAssert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAssert.h; path = Source/Base/ASAssert.h; sourceTree = ""; }; + BDD93100C2924931FBF3E404B81576D0 /* PINImage+ScaledImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINImage+ScaledImage.m"; path = "Source/Classes/Categories/PINImage+ScaledImage.m"; sourceTree = ""; }; + BE54CB3D9126A0A4E84D9DA6BD4293D0 /* ASTableView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableView.h; path = Source/ASTableView.h; sourceTree = ""; }; + BE7824C8E50170F8A0526B9205882F3B /* ASControlNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASControlNode.mm; path = Source/ASControlNode.mm; sourceTree = ""; }; + BE7C4386005ED1B9320FCC1D31C621CC /* PINResume.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINResume.m; path = Source/Classes/PINResume.m; sourceTree = ""; }; + BEA709AB9B51E31AB78426C3BC827746 /* ASResponderChainEnumerator.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASResponderChainEnumerator.mm; path = Source/Private/ASResponderChainEnumerator.mm; sourceTree = ""; }; + BEB872092B992DC253680FAA0499FE5C /* ASLayoutSpec+Subclasses.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASLayoutSpec+Subclasses.mm"; path = "Source/Layout/ASLayoutSpec+Subclasses.mm"; sourceTree = ""; }; + BF015D61C4F514CD102521B65306C0DE /* _ASTransitionContext.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASTransitionContext.mm; path = Source/_ASTransitionContext.mm; sourceTree = ""; }; + BF5302E3309861B195B9B558D3E4869F /* ASNetworkImageLoadInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASNetworkImageLoadInfo.h; path = Source/ASNetworkImageLoadInfo.h; sourceTree = ""; }; + C032C2C59E35E90D29510094FA3BAF62 /* ASLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutSpec.h; path = Source/Layout/ASLayoutSpec.h; sourceTree = ""; }; + C1269DFD61BDAA9D7616E24B0189FA96 /* IGListAdapter+AsyncDisplayKit.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "IGListAdapter+AsyncDisplayKit.mm"; path = "Source/IGListAdapter+AsyncDisplayKit.mm"; sourceTree = ""; }; + C14B8C1CB8961F309BF9D6412F088BAD /* ASEditableTextNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASEditableTextNode.mm; path = Source/ASEditableTextNode.mm; sourceTree = ""; }; + C158E5545E3BD2D22EB64B23FBED2C7E /* ASTextKitEntityAttribute.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitEntityAttribute.h; path = Source/TextKit/ASTextKitEntityAttribute.h; sourceTree = ""; }; + C18764D310DCB6C30034EB3C014E0109 /* ASButtonNode+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASButtonNode+Private.h"; path = "Source/ASButtonNode+Private.h"; sourceTree = ""; }; + C250DF90BD78A3A463AF8A46C191D656 /* ASMutableAttributedStringBuilder.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASMutableAttributedStringBuilder.mm; path = Source/Details/ASMutableAttributedStringBuilder.mm; sourceTree = ""; }; + C2A96E21690DBA5F5E4DD8C744A598A8 /* CGPoint+valueInDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGPoint+valueInDirection.swift"; sourceTree = ""; }; + C2AFE0C39F1F92051B063681E2F546D3 /* ASTableView.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTableView.mm; path = Source/ASTableView.mm; sourceTree = ""; }; + C2E1EDF37D5C7392BCBCBC2626230325 /* ASYogaUtilities.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASYogaUtilities.mm; path = Source/Layout/ASYogaUtilities.mm; sourceTree = ""; }; + C463CC735CC90CC6C36E6AF98D671B2A /* UIImage+ASConvenience.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "UIImage+ASConvenience.mm"; path = "Source/UIImage+ASConvenience.mm"; sourceTree = ""; }; + C49FC0A2F8D7B1D6EA3AF666E636C296 /* ASRangeManagingNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRangeManagingNode.h; path = Source/ASRangeManagingNode.h; sourceTree = ""; }; + C57821E88CDD7886ACE86068E06D5B34 /* ASBackgroundLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBackgroundLayoutSpec.h; path = Source/Layout/ASBackgroundLayoutSpec.h; sourceTree = ""; }; + C61A4B82B4BA5097E9F686A1948C1EFC /* ASYogaUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASYogaUtilities.h; path = Source/Layout/ASYogaUtilities.h; sourceTree = ""; }; + C6EEB10F62EB74DDAFD182C55A257738 /* ASTabBarController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTabBarController.h; path = Source/ASTabBarController.h; sourceTree = ""; }; + C6F40F1552ED00CC77D7799621E479C8 /* ASContextTransitioning.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASContextTransitioning.h; path = Source/ASContextTransitioning.h; sourceTree = ""; }; + C74FC41E348067EE93ED92F12742298D /* ASRangeController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRangeController.h; path = Source/Details/ASRangeController.h; sourceTree = ""; }; + C7EB412042D3B0B82DDB17C56280EA20 /* ASLayoutSpecPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutSpecPrivate.h; path = Source/Private/Layout/ASLayoutSpecPrivate.h; sourceTree = ""; }; + C8AF5F4BB16D9D38E6011A150CF1DC25 /* ASTextLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextLayout.mm; path = Source/Private/TextExperiment/Component/ASTextLayout.mm; sourceTree = ""; }; + C8E316AF000D6A307AFFBFC59E27FCB2 /* _ASAsyncTransaction.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASAsyncTransaction.mm; path = Source/Details/Transactions/_ASAsyncTransaction.mm; sourceTree = ""; }; + C9B95674F1A017DABD24226712B9D591 /* ASAvailability.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAvailability.h; path = Source/Base/ASAvailability.h; sourceTree = ""; }; C9CF14625B5BE3A51972C13D0270C842 /* Pods-Zoomy_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Zoomy_Example-acknowledgements.plist"; sourceTree = ""; }; - CA013F86E55F43BBBB8A8C7596DE700A /* ASControlNode+tvOS.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASControlNode+tvOS.mm"; path = "Source/tvOS/ASControlNode+tvOS.mm"; sourceTree = ""; }; - CA1EEA85B1AB08A62240A714B72B51CD /* ASImageNode+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASImageNode+Private.h"; path = "Source/Private/ASImageNode+Private.h"; sourceTree = ""; }; - CA6C4621E433A72E826090B170427229 /* _ASCoreAnimationExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCoreAnimationExtras.h; path = Source/Private/_ASCoreAnimationExtras.h; sourceTree = ""; }; - CAA043EEB04C16347822B57BAA117E2E /* UIViewController+HasImageZoomControllers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIViewController+HasImageZoomControllers.swift"; sourceTree = ""; }; + C9D73CD563E03400418EBC0A4784D1C1 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerIsPresentingImageViewOverlayState.swift; sourceTree = ""; }; + C9E659D0C8C2D9712FEC2736A469A090 /* PINRemoteImage-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINRemoteImage-umbrella.h"; sourceTree = ""; }; + C9F7A8AFC48B5338B1D11FBEEE473EC8 /* HasImageZoomControllers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = HasImageZoomControllers.swift; sourceTree = ""; }; + CA3C2F847A27247611C3DBD2ADB2A71F /* CGPoint+dominantDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGPoint+dominantDirection.swift"; sourceTree = ""; }; + CA697F21425C3FDC3FD77AF6CA5A1E37 /* ASDisplayNode+Layout.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASDisplayNode+Layout.mm"; path = "Source/ASDisplayNode+Layout.mm"; sourceTree = ""; }; + CAA9D4CFE9C5A4813A54148D6F1BEB6C /* ASTableViewProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableViewProtocols.h; path = Source/ASTableViewProtocols.h; sourceTree = ""; }; + CAB7AEB454892E87F9B1C2F04DCFE0D0 /* CanLogAtLevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogAtLevel.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLogAtLevel.swift; sourceTree = ""; }; CADDCC912439D00D2D010CFA70629127 /* Pods-Zoomy_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Zoomy_Tests.debug.xcconfig"; sourceTree = ""; }; - CAF24DC1C17849451322FD125AD2E70C /* ASControlTargetAction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASControlTargetAction.h; path = Source/Private/ASControlTargetAction.h; sourceTree = ""; }; - CB0BAAC0ACC1784F708C88E5C8EBCC43 /* MockLogger.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MockLogger.swift; path = InjectableLoggers/Classes/Classes/MockLogger.swift; sourceTree = ""; }; - CB1BF56DC2832DD482B008CA61701A5B /* ImageZoomControllerDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerDelegate.swift; sourceTree = ""; }; - CB5EA34046D5FB220392F961B785A319 /* AsyncDisplayKit+IGListKitMethods.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "AsyncDisplayKit+IGListKitMethods.h"; path = "Source/AsyncDisplayKit+IGListKitMethods.h"; sourceTree = ""; }; - CB60A8A3396F3A5EDA46BDEAD37CC792 /* Pods_Zoomy_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Zoomy_Example.framework; path = "Pods-Zoomy_Example.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - CB9B0F0A3D14749D0C88E4093EF353C9 /* PINRemoteImageProcessorTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageProcessorTask.m; path = Source/Classes/PINRemoteImageProcessorTask.m; sourceTree = ""; }; - CBF30FE548E806618E1A450023D31620 /* PINOperation-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PINOperation-Info.plist"; sourceTree = ""; }; - CC192131041D44BC2AB4EA73128B108E /* ASDefaultPlayButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDefaultPlayButton.h; path = Source/Private/ASDefaultPlayButton.h; sourceTree = ""; }; + CB3CC8A51469A1A050DF9202D4ABD37C /* _ASCollectionGalleryLayoutItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionGalleryLayoutItem.h; path = Source/Private/_ASCollectionGalleryLayoutItem.h; sourceTree = ""; }; + CB60A8A3396F3A5EDA46BDEAD37CC792 /* Pods_Zoomy_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Zoomy_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CBA1CDFAC330F024F79F55928AF761B0 /* ASImageContainerProtocolCategories.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASImageContainerProtocolCategories.h; path = Source/Details/ASImageContainerProtocolCategories.h; sourceTree = ""; }; + CC85FED712EC5B803BB64410FA1944AF /* ASSection.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASSection.mm; path = Source/Private/ASSection.mm; sourceTree = ""; }; + CC905E638224A0B0E664476444B10514 /* ASCollectionLayoutContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutContext.h; path = Source/Details/ASCollectionLayoutContext.h; sourceTree = ""; }; + CC9F7354BB576AE97ADD36345C6980E2 /* ASTextKitShadower.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitShadower.h; path = Source/TextKit/ASTextKitShadower.h; sourceTree = ""; }; CD1FE7E96A5E345D913F7FF58A0CCFE0 /* Pods-Zoomy_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Zoomy_Example.debug.xcconfig"; sourceTree = ""; }; - CD72B567F111E9E3EDFE39E0620500FA /* ASLayoutManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutManager.h; path = Source/TextKit/ASLayoutManager.h; sourceTree = ""; }; - CD9985360CAA99C3433E43A198C9C8C4 /* ASTableView.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTableView.mm; path = Source/ASTableView.mm; sourceTree = ""; }; - CEFCD08353CEB062A616617D7CB0E38D /* ASDisplayNode+Convenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Convenience.h"; path = "Source/ASDisplayNode+Convenience.h"; sourceTree = ""; }; - CF0DDADC13D1CF8AB42051D93B8555C1 /* ASDataController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDataController.h; path = Source/Details/ASDataController.h; sourceTree = ""; }; - CF54AE29F0904364F8BAB4731C2B61F5 /* ASImageNode+tvOS.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASImageNode+tvOS.mm"; path = "Source/tvOS/ASImageNode+tvOS.mm"; sourceTree = ""; }; - CFEB1F047D58C0F0393C41C23A4A4F88 /* PINCache-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PINCache-dummy.m"; sourceTree = ""; }; - CFEE3F2F5FCAF0F3908A81163FD68D8D /* ASTextRunDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextRunDelegate.h; path = Source/Private/TextExperiment/String/ASTextRunDelegate.h; sourceTree = ""; }; - D038D5D65D25E6B9A55A199B3C5E4C72 /* ASNetworkImageLoadInfo+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASNetworkImageLoadInfo+Private.h"; path = "Source/Private/ASNetworkImageLoadInfo+Private.h"; sourceTree = ""; }; - D10C816C7692C03BB6F3FC1DB50EA606 /* _ASDisplayViewAccessiblity.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASDisplayViewAccessiblity.mm; path = Source/Details/_ASDisplayViewAccessiblity.mm; sourceTree = ""; }; - D13C42FAFFDAA633F5D53CA57A8C1683 /* ASTextAttribute.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextAttribute.h; path = Source/Private/TextExperiment/String/ASTextAttribute.h; sourceTree = ""; }; - D18419ABCCABCA2F165BA42ED0301C18 /* ASTextKitAttributes.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitAttributes.mm; path = Source/TextKit/ASTextKitAttributes.mm; sourceTree = ""; }; - D23FE5069CB05E377F270A620883B989 /* _ASAsyncTransaction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASAsyncTransaction.h; path = Source/Details/Transactions/_ASAsyncTransaction.h; sourceTree = ""; }; - D29A4225F3A3D743A92285D5F23D9CEA /* ASLayout+IGListKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASLayout+IGListKit.h"; path = "Source/Layout/ASLayout+IGListKit.h"; sourceTree = ""; }; - D2C7409FD631FBD85594A03B3F0C598D /* ASRangeController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASRangeController.mm; path = Source/Details/ASRangeController.mm; sourceTree = ""; }; - D31A98FCF7B961D3A00D60EA1953837E /* _ASCollectionReusableView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionReusableView.h; path = Source/Details/_ASCollectionReusableView.h; sourceTree = ""; }; - D34150625D2DF5F1674579F01ACAEA54 /* ASRunLoopQueue.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASRunLoopQueue.mm; path = Source/ASRunLoopQueue.mm; sourceTree = ""; }; - D43741DA796D220E39698D245C0C7FD0 /* ASTableLayoutController.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTableLayoutController.mm; path = Source/Details/ASTableLayoutController.mm; sourceTree = ""; }; - D48173B3E33DB97A878FAA3E003BCE42 /* _ASCollectionGalleryLayoutInfo.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASCollectionGalleryLayoutInfo.mm; path = Source/Private/_ASCollectionGalleryLayoutInfo.mm; sourceTree = ""; }; - D49499B1B65785F2A7C1C4CD99765E4D /* ASCollectionLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionLayout.mm; path = Source/Private/ASCollectionLayout.mm; sourceTree = ""; }; - D53C635281133902C9689B13271D8B8F /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; - D5DDD9B2DE79EA31E77C347CB177062F /* ASRelativeLayoutSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRelativeLayoutSpec.h; path = Source/Layout/ASRelativeLayoutSpec.h; sourceTree = ""; }; - D62BAA7299811C6007375660954B85C9 /* ASWeakProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASWeakProxy.h; path = Source/Details/ASWeakProxy.h; sourceTree = ""; }; - D66AD00BCB9A19991B9EE09548F16733 /* PINOperationTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationTypes.h; path = Source/PINOperationTypes.h; sourceTree = ""; }; - D7BCDD0C9A3A1E746B9F1E99D158C91E /* ASStackUnpositionedLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASStackUnpositionedLayout.mm; path = Source/Private/Layout/ASStackUnpositionedLayout.mm; sourceTree = ""; }; - D804DC3A2743336B5C1C7F72579362A6 /* ASWeakSet.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASWeakSet.h; path = Source/Details/ASWeakSet.h; sourceTree = ""; }; - D8669BDD150909EC0BEE733EFBE3F7E6 /* ASConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASConfiguration.h; path = Source/ASConfiguration.h; sourceTree = ""; }; - D98D4102DE5D0527079F24439B32B5AE /* ASStackLayoutElement.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutElement.h; path = Source/Layout/ASStackLayoutElement.h; sourceTree = ""; }; - D9ACB6B0A84C9EC8F26624BCE6B949FF /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPhotosFrameworkImageRequest.h; path = Source/Details/ASPhotosFrameworkImageRequest.h; sourceTree = ""; }; - DA0C325BE2C19C06990097FF199548F0 /* ASRangeManagingNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASRangeManagingNode.h; path = Source/ASRangeManagingNode.h; sourceTree = ""; }; - DA268B7E44D38BCD77321FABC32B31D0 /* PINAnimatedImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINAnimatedImage.h; path = Source/Classes/AnimatedImages/PINAnimatedImage.h; sourceTree = ""; }; - DA6B00F5DCBD9D92902113D39B1EE973 /* Texture-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Texture-umbrella.h"; sourceTree = ""; }; - DB05D8F15693818ED24FF6BAF2F27166 /* NSAttributedString+ASText.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSAttributedString+ASText.h"; path = "Source/Private/TextExperiment/Utility/NSAttributedString+ASText.h"; sourceTree = ""; }; - DB46CE9E8985343894F642F0878128C5 /* PINCaching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCaching.h; path = Source/PINCaching.h; sourceTree = ""; }; - DB7A4C80B73F575C450CE21218D11C15 /* InjectableLoggers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = InjectableLoggers.framework; path = InjectableLoggers.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - DB7B857F48C145A0BB64AE203A20EAEA /* UIViewController+CanManageZoomBehavior.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIViewController+CanManageZoomBehavior.swift"; sourceTree = ""; }; - DBBFC51734B70A5463EA74EE6AA9EB96 /* CanAnimate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanAnimate.swift; sourceTree = ""; }; - DBBFE01B8675C3711CF07D2843B07D0F /* ASLayoutRangeType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutRangeType.h; path = Source/Details/ASLayoutRangeType.h; sourceTree = ""; }; - DC03C8D323C8A2C573128340067B2BEC /* Zoomy.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Zoomy.modulemap; sourceTree = ""; }; - DCADF277F8E0FE040B220E44C2285265 /* SimpleLogger.Settings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SimpleLogger.Settings.swift; path = InjectableLoggers/Classes/Structs/SimpleLogger.Settings.swift; sourceTree = ""; }; - DCB779A3A6B164BAAA0959C229254646 /* PINRemoteImageMemoryContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageMemoryContainer.m; path = Source/Classes/PINRemoteImageMemoryContainer.m; sourceTree = ""; }; - DD3CADDF86084740EAE1184277C790BA /* ASAssert.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASAssert.mm; path = Source/Base/ASAssert.mm; sourceTree = ""; }; - DD7FED1C7830F32AA3BC824803FC338C /* ASDisplayNode+Ancestry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Ancestry.h"; path = "Source/Base/ASDisplayNode+Ancestry.h"; sourceTree = ""; }; - DD90D4DE2B4C773B25DE461741FCE6BE /* ASTextInput.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextInput.h; path = Source/Private/TextExperiment/Component/ASTextInput.h; sourceTree = ""; }; - DDD6A5FCBA65371A45826CB1728A0F7A /* ASMainThreadDeallocation.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASMainThreadDeallocation.mm; path = Source/ASMainThreadDeallocation.mm; sourceTree = ""; }; - DE70B4985D2139726F4E0BC1FE545A58 /* ASCollectionViewFlowLayoutInspector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionViewFlowLayoutInspector.h; path = Source/Private/ASCollectionViewFlowLayoutInspector.h; sourceTree = ""; }; - DE74719B84443664ED5311A61911759A /* ASGraphicsContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASGraphicsContext.h; path = Source/Details/ASGraphicsContext.h; sourceTree = ""; }; - DF0FE47D3163C04184775EB308246232 /* LogLevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LogLevel.swift; path = InjectableLoggers/Classes/Enums/LogLevel.swift; sourceTree = ""; }; - DF1D4FA61A9EBACC795AA678AB81D0CA /* ASInternalHelpers.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASInternalHelpers.mm; path = Source/Private/ASInternalHelpers.mm; sourceTree = ""; }; - DF5B20F75E416F1C307A219C5A41109B /* ASTextKitTailTruncater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitTailTruncater.h; path = Source/TextKit/ASTextKitTailTruncater.h; sourceTree = ""; }; - DF8DF606941FFEEC9EE31E1353EF53A6 /* ASMultiplexImageNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMultiplexImageNode.h; path = Source/ASMultiplexImageNode.h; sourceTree = ""; }; - DF9CAE59564D99FB78072D06EBB3E37B /* ASIntegerMap.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASIntegerMap.mm; path = Source/Details/ASIntegerMap.mm; sourceTree = ""; }; - DFD6F206B8FFE0C84A6A76F86D80AD38 /* NSParagraphStyle+ASText.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "NSParagraphStyle+ASText.mm"; path = "Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.mm"; sourceTree = ""; }; - DFD881480973960CF3694AFEA4B9513A /* Side.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Side.swift; sourceTree = ""; }; - E01A5CAF748172FE038684764702EF61 /* ASDisplayNode+Yoga.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+Yoga.mm"; path = "Source/ASDisplayNode+Yoga.mm"; sourceTree = ""; }; + CD82409E784C5B82AFCB8E3B4B899B32 /* ASTwoDimensionalArrayUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTwoDimensionalArrayUtils.h; path = Source/Private/ASTwoDimensionalArrayUtils.h; sourceTree = ""; }; + CDDA219ED517C33E1056E0948A145ECB /* ASCollections.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollections.h; path = Source/ASCollections.h; sourceTree = ""; }; + CE226A57A895770566512D114E6BFEB6 /* ASLayoutRangeType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutRangeType.h; path = Source/Details/ASLayoutRangeType.h; sourceTree = ""; }; + CEA532B0E1FFE30D664CFBE7878662F9 /* ASCollectionViewLayoutController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCollectionViewLayoutController.mm; path = Source/Details/ASCollectionViewLayoutController.mm; sourceTree = ""; }; + CEA675A20EAE7B49521E742D5681B170 /* ASTip.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTip.mm; path = Source/Private/ASTip.mm; sourceTree = ""; }; + CEB22121B395ED735216159F1CA578D8 /* _ASCoreAnimationExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASCoreAnimationExtras.mm; path = Source/Private/_ASCoreAnimationExtras.mm; sourceTree = ""; }; + CF3F18E47D07B321917AC4271C1ED51B /* PINRemoteImageBasicCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageBasicCache.h; path = Source/Classes/PINRemoteImageBasicCache.h; sourceTree = ""; }; + CF97BCE466D911620708CE0E0D8EEA45 /* ASLayoutElement.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutElement.mm; path = Source/Layout/ASLayoutElement.mm; sourceTree = ""; }; + D0162762B4A4C18C34AF7BDF70585D4E /* CoreGraphics+ASConvenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "CoreGraphics+ASConvenience.h"; path = "Source/Details/CoreGraphics+ASConvenience.h"; sourceTree = ""; }; + D017BE463D6FA4889B4C3BBCB7F0058C /* ASAsciiArtBoxCreator.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASAsciiArtBoxCreator.mm; path = Source/Layout/ASAsciiArtBoxCreator.mm; sourceTree = ""; }; + D0319B8963465C591687AFFE645BC7C4 /* ASPageTable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPageTable.h; path = Source/Details/ASPageTable.h; sourceTree = ""; }; + D084ECEB354EC79F4F4DB811D3C5B611 /* _ASAsyncTransactionContainer.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASAsyncTransactionContainer.mm; path = Source/Details/Transactions/_ASAsyncTransactionContainer.mm; sourceTree = ""; }; + D0B846671C568323E113112E28C84E3A /* ASPagerNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASPagerNode+Beta.h"; path = "Source/ASPagerNode+Beta.h"; sourceTree = ""; }; + D1B0B1E3406CFE376B8C7A053A6D027A /* InjectableLoggers-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "InjectableLoggers-dummy.m"; sourceTree = ""; }; + D1D44D0CB5735DF9E0EF1C2ABCB9D3A4 /* UIResponder+AsyncDisplayKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIResponder+AsyncDisplayKit.h"; path = "Source/UIResponder+AsyncDisplayKit.h"; sourceTree = ""; }; + D1FB03D4F024FA0F361CB89A886A04E6 /* _ASDisplayView.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASDisplayView.mm; path = Source/Details/_ASDisplayView.mm; sourceTree = ""; }; + D28E1FDF6AF4C8EA76A2E6B04468EFF3 /* ASBatchContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBatchContext.h; path = Source/Details/ASBatchContext.h; sourceTree = ""; }; + D2D0DD2A8BC4A91FDFB94D2232DC0252 /* ASTextKitRenderer+TextChecking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTextKitRenderer+TextChecking.h"; path = "Source/TextKit/ASTextKitRenderer+TextChecking.h"; sourceTree = ""; }; + D2E37F15D53DA5704377A7D5836636C9 /* PINCaching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCaching.h; path = Source/PINCaching.h; sourceTree = ""; }; + D37EA35A7EC92AF0C4C89CB9055045D9 /* ASTextKitRenderer+Positioning.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASTextKitRenderer+Positioning.mm"; path = "Source/TextKit/ASTextKitRenderer+Positioning.mm"; sourceTree = ""; }; + D3E3CB0CBCFA59CE439FF53F8006C3D4 /* ASCollectionGalleryLayoutDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionGalleryLayoutDelegate.h; path = Source/Details/ASCollectionGalleryLayoutDelegate.h; sourceTree = ""; }; + D49A19FBB24B7F8EE96F2736AD1B740B /* PINCacheObjectSubscripting.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCacheObjectSubscripting.h; path = Source/PINCacheObjectSubscripting.h; sourceTree = ""; }; + D4CC5A8855E96D7657A8163FB9889C8E /* PINRemoteImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PINRemoteImage.release.xcconfig; sourceTree = ""; }; + D4E478F22E41312C2EE4D3F570D425EF /* ASDisplayNodeCornerLayerDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeCornerLayerDelegate.h; path = Source/Private/ASDisplayNodeCornerLayerDelegate.h; sourceTree = ""; }; + D50F83AD1942253690114023E7CE92B4 /* ASBlockTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBlockTypes.h; path = Source/ASBlockTypes.h; sourceTree = ""; }; + D5AB57FF552FD673BCFA9C23733069E1 /* ASCollectionLayoutState+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionLayoutState+Private.h"; path = "Source/Private/ASCollectionLayoutState+Private.h"; sourceTree = ""; }; + D6EBCABE6BBB30D4231E0B246B73ECE8 /* ASPendingStateController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPendingStateController.h; path = Source/Private/ASPendingStateController.h; sourceTree = ""; }; + D8577C9C2A1140AD10A4FAB08CFA88B0 /* Animator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Animator.swift; sourceTree = ""; }; + D8935CD3A0EBC471E7D637DB30BA926B /* LogLevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LogLevel.swift; path = InjectableLoggers/Classes/Enums/LogLevel.swift; sourceTree = ""; }; + D8AEF5A40C43AB90E6B7ED37BB01E1F8 /* PINRemoteWeakProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteWeakProxy.h; path = Source/Classes/PINRemoteWeakProxy.h; sourceTree = ""; }; + DA4E05471B629E5426D5E5F9A38C11FF /* ASTextNodeWordKerner.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextNodeWordKerner.h; path = Source/TextKit/ASTextNodeWordKerner.h; sourceTree = ""; }; + DAE31B940FABACE013CA45FF2FDC046B /* ASTableNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableNode.h; path = Source/ASTableNode.h; sourceTree = ""; }; + DB7A4C80B73F575C450CE21218D11C15 /* InjectableLoggers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = InjectableLoggers.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DB9FBBC1EF5AF543DA86EBF741B82694 /* _ASHierarchyChangeSet.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = _ASHierarchyChangeSet.mm; path = Source/Private/_ASHierarchyChangeSet.mm; sourceTree = ""; }; + DBE5E5CF4C0125FBD1052D5DA0FA70CF /* ASCellNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCellNode.mm; path = Source/ASCellNode.mm; sourceTree = ""; }; + DC0B6D34284EEEC294A8BB6750F6173E /* ASDisplayNode+Convenience.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Convenience.h"; path = "Source/ASDisplayNode+Convenience.h"; sourceTree = ""; }; + DC3967FE11381864148284469B3951BC /* ASGraphicsContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASGraphicsContext.h; path = Source/Details/ASGraphicsContext.h; sourceTree = ""; }; + DC8FE4D97CE0DAE7FA9E101ADC4714F8 /* Zoomy.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Zoomy.modulemap; sourceTree = ""; }; + DC9C83426449CBC7979380EE2EC7A48D /* ASVisibilityProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASVisibilityProtocols.h; path = Source/ASVisibilityProtocols.h; sourceTree = ""; }; + DCB893AAFE47BD80E8CC7CC44A00CD56 /* ASTextRunDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextRunDelegate.mm; path = Source/Private/TextExperiment/String/ASTextRunDelegate.mm; sourceTree = ""; }; + DCDFEDEA0B238450F5F65B65C2CD9079 /* NSData+ImageDetectors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+ImageDetectors.h"; path = "Source/Classes/include/NSData+ImageDetectors.h"; sourceTree = ""; }; + DD1CF1EC74DC9F3B2DB54518639BCC57 /* ASDKViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDKViewController.h; path = Source/ASDKViewController.h; sourceTree = ""; }; + DD6B76E7CC9E6D168E1CA155B92BD27F /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/AssetsLibrary.framework; sourceTree = DEVELOPER_DIR; }; + DDCD3C215394710BFCE24A682B80FD0F /* ASTextLine.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextLine.mm; path = Source/Private/TextExperiment/Component/ASTextLine.mm; sourceTree = ""; }; + DDDD167A6A9C02AB6892A227DA6B537C /* ASNetworkImageLoadInfo+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASNetworkImageLoadInfo+Private.h"; path = "Source/Private/ASNetworkImageLoadInfo+Private.h"; sourceTree = ""; }; + DDEF3F1193C7C7E6815D0965E430ACFD /* ASMutableAttributedStringBuilder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMutableAttributedStringBuilder.h; path = Source/Details/ASMutableAttributedStringBuilder.h; sourceTree = ""; }; + DE1F7FC0245A875D45AC0863A15BD969 /* ASTextKitAttributes.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitAttributes.mm; path = Source/TextKit/ASTextKitAttributes.mm; sourceTree = ""; }; + DE98C566C001F35E47A53562D425064B /* ASButtonNode+Yoga.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASButtonNode+Yoga.mm"; path = "Source/ASButtonNode+Yoga.mm"; sourceTree = ""; }; + DF6BA3DB4965D0F13E4DF91222F3D9E4 /* ASDisplayNodeInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeInternal.h; path = Source/Private/ASDisplayNodeInternal.h; sourceTree = ""; }; + E00E407AA304E669975F496CDE757534 /* ASTextKitCoreTextAdditions.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitCoreTextAdditions.mm; path = Source/TextKit/ASTextKitCoreTextAdditions.mm; sourceTree = ""; }; E0601C0FFFF745CD3A8DAD53CDEE63BC /* Pods-Zoomy_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Zoomy_Example.modulemap"; sourceTree = ""; }; - E062EE8439098EF20D02C7338C975C52 /* ASPINRemoteImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPINRemoteImageDownloader.h; path = Source/Details/ASPINRemoteImageDownloader.h; sourceTree = ""; }; - E0846880D85E50BD74D66583A3F4D4CC /* ASNetworkImageLoadInfo.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASNetworkImageLoadInfo.mm; path = Source/ASNetworkImageLoadInfo.mm; sourceTree = ""; }; - E13F304F25BDA4F5138C786C6D8541C3 /* ASCollectionNode+Beta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASCollectionNode+Beta.h"; path = "Source/ASCollectionNode+Beta.h"; sourceTree = ""; }; - E144F57F0B8D28515331682DD09E32BA /* ASTipsWindow.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTipsWindow.h; path = Source/Private/ASTipsWindow.h; sourceTree = ""; }; - E19DB721C1C7526CC7059B683149A992 /* ASCollectionViewFlowLayoutInspector.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionViewFlowLayoutInspector.mm; path = Source/Private/ASCollectionViewFlowLayoutInspector.mm; sourceTree = ""; }; - E1B40F69DFD16A71ACDCF95E5D218731 /* ASTraitCollection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTraitCollection.h; path = Source/Details/ASTraitCollection.h; sourceTree = ""; }; - E1C23264DA61204A0B428A18A76C774A /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/ImageIO.framework; sourceTree = DEVELOPER_DIR; }; + E0B89AC0CDBA02149E8DFBB8ACEAF0CB /* ASStackPositionedLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStackPositionedLayout.mm; path = Source/Private/Layout/ASStackPositionedLayout.mm; sourceTree = ""; }; E1C8DA0CF2093266E6F33BB205F9761C /* Pods-Zoomy_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Zoomy_Tests-frameworks.sh"; sourceTree = ""; }; - E20F56D2D244CECF2FAD0815934D1751 /* ImageZoomControllerSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerSettings.swift; sourceTree = ""; }; - E327F711FFD756BD667AD6AC61D3C660 /* ASConfiguration.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASConfiguration.mm; path = Source/ASConfiguration.mm; sourceTree = ""; }; - E3B02A8C5EF0BFB03017CAE2C8D4303F /* ASTraceEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTraceEvent.h; path = Source/Details/ASTraceEvent.h; sourceTree = ""; }; - E3B0B3833F78F5202AE6A4EDAACABE40 /* PINAlternateRepresentationProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINAlternateRepresentationProvider.m; path = Source/Classes/PINAlternateRepresentationProvider.m; sourceTree = ""; }; - E3B9A8B07F628C3AF0B0565D94907370 /* ASRatioLayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASRatioLayoutSpec.mm; path = Source/Layout/ASRatioLayoutSpec.mm; sourceTree = ""; }; - E4787675C54E05A8E87785A4179A5048 /* ASCollectionInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionInternal.h; path = Source/Details/ASCollectionInternal.h; sourceTree = ""; }; - E5B9950A1BB7AB4BB4F981109C561078 /* ASTextKitCoreTextAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTextKitCoreTextAdditions.h; path = Source/TextKit/ASTextKitCoreTextAdditions.h; sourceTree = ""; }; - E6581AA58586EF122B4A7935CF2A0838 /* ASMutableElementMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMutableElementMap.h; path = Source/Private/ASMutableElementMap.h; sourceTree = ""; }; - E68F514908D5394AA86EBEA208E47A04 /* ASDisplayNode+LayoutSpec.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+LayoutSpec.mm"; path = "Source/ASDisplayNode+LayoutSpec.mm"; sourceTree = ""; }; + E3D2C16A2AE576BAE4EEE64B5C6ED5FD /* ASPagerFlowLayout.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASPagerFlowLayout.mm; path = Source/ASPagerFlowLayout.mm; sourceTree = ""; }; + E3DC378C69742B7E1C2A8D1B02460DB0 /* CGRect+transformedByTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGRect+transformedByTransform.swift"; sourceTree = ""; }; + E3F88046DBCA3A2EA1314244D40E4317 /* ASControlTargetAction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASControlTargetAction.h; path = Source/Private/ASControlTargetAction.h; sourceTree = ""; }; + E47C6BB78AA408F7C35EF60421326F79 /* ASVisibilityProtocols.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASVisibilityProtocols.mm; path = Source/ASVisibilityProtocols.mm; sourceTree = ""; }; + E4BE922521021592DF0960FC9290CA4D /* PINOperationTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINOperationTypes.h; path = Source/PINOperationTypes.h; sourceTree = ""; }; + E4D3DCB3C009FD5D8659089E34B277D3 /* NSData+ImageDetectors.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+ImageDetectors.m"; path = "Source/Classes/Categories/NSData+ImageDetectors.m"; sourceTree = ""; }; + E55325CF18F732FB37081F750E0577E4 /* ASTableLayoutController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTableLayoutController.mm; path = Source/Details/ASTableLayoutController.mm; sourceTree = ""; }; E69D3842B05724A857AFCDC239C981C7 /* Pods-Zoomy_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Zoomy_Tests-acknowledgements.plist"; sourceTree = ""; }; - E6ACA3ECDEAADA5D85338D020179D6EC /* ASPagerFlowLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPagerFlowLayout.h; path = Source/ASPagerFlowLayout.h; sourceTree = ""; }; - E729BFF861BF80E417AA7161ED356A47 /* ASTabBarController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTabBarController.h; path = Source/ASTabBarController.h; sourceTree = ""; }; - E778EA8770ABFA8D712897C593624C1B /* ASTextKitFontSizeAdjuster.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitFontSizeAdjuster.mm; path = Source/TextKit/ASTextKitFontSizeAdjuster.mm; sourceTree = ""; }; - E7B49D7AC5C2C0142D862EFD6D43B2B5 /* ASLog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLog.h; path = Source/Base/ASLog.h; sourceTree = ""; }; - E8154B80F3BF383F5EB574E1497B614C /* ASSection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSection.h; path = Source/Private/ASSection.h; sourceTree = ""; }; - E8DDE817DC02BCD96ACFB1094843BFC0 /* ASLayerBackingTipProvider.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASLayerBackingTipProvider.mm; path = Source/Private/ASLayerBackingTipProvider.mm; sourceTree = ""; }; - E8EE8E285A79E86E91454D38BAA31F49 /* _ASCollectionViewCell.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASCollectionViewCell.mm; path = Source/Details/_ASCollectionViewCell.mm; sourceTree = ""; }; - E9297A4D9C730E526E63A5654A200E28 /* ASBatchFetching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBatchFetching.h; path = Source/Private/ASBatchFetching.h; sourceTree = ""; }; + E706D8361E42669B2765F7B815C532A3 /* ASBasicImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBasicImageDownloader.h; path = Source/Details/ASBasicImageDownloader.h; sourceTree = ""; }; + E70BC18B679C8A3330AAB74EC44E137B /* ASSignpost.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSignpost.h; path = Source/Base/ASSignpost.h; sourceTree = ""; }; + E758EA4E1865DE8FB11FE7DF08146477 /* PINRemoteImageDownloadQueue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINRemoteImageDownloadQueue.m; path = Source/Classes/PINRemoteImageDownloadQueue.m; sourceTree = ""; }; + E7883E00BE5AA81AAE8BD1C5407224B2 /* ASResponderChainEnumerator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASResponderChainEnumerator.h; path = Source/Private/ASResponderChainEnumerator.h; sourceTree = ""; }; + E7F66832F49B3C0B4A07085F98189176 /* ASVideoPlayerNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASVideoPlayerNode.h; path = Source/ASVideoPlayerNode.h; sourceTree = ""; }; + E805F69FFCA26465321093F9D504AC2C /* CanLogMessageAtLevel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CanLogMessageAtLevel.swift; path = InjectableLoggers/Classes/ExtendedProtocols/CanLogMessageAtLevel.swift; sourceTree = ""; }; + E8A9CD8D77D91D235463968FC1DAEDE0 /* ASLayoutElementPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutElementPrivate.h; path = Source/Layout/ASLayoutElementPrivate.h; sourceTree = ""; }; + E8C9DEC2483B11E8B516171B7AE19CB7 /* PINMemoryCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINMemoryCache.h; path = Source/PINMemoryCache.h; sourceTree = ""; }; + E8FFDB3A91E0FACEF3DDB279AD37CF30 /* ASButtonNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASButtonNode.h; path = Source/ASButtonNode.h; sourceTree = ""; }; + E9206743DCC6A30DA6327E9E79F04B39 /* ASLayoutTransition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutTransition.h; path = Source/Private/ASLayoutTransition.h; sourceTree = ""; }; + E936B1B04FFAF35C7B129A8753B7710D /* ASImageNode+tvOS.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASImageNode+tvOS.mm"; path = "Source/tvOS/ASImageNode+tvOS.mm"; sourceTree = ""; }; + E998BC7957EE5F98E6C31919CCAE829B /* ASControlTargetAction.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASControlTargetAction.mm; path = Source/Private/ASControlTargetAction.mm; sourceTree = ""; }; + EA0B213E1618F546074778126A6A7EBA /* ASTextNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextNode.mm; path = Source/ASTextNode.mm; sourceTree = ""; }; EA3DD85A2196BDDC13057481647564E8 /* Pods-Zoomy_Example-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Zoomy_Example-Info.plist"; sourceTree = ""; }; - EA4F56FDA7A6B32FF3A7DB0EA0E30D9C /* _ASAsyncTransactionContainer+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "_ASAsyncTransactionContainer+Private.h"; path = "Source/Details/Transactions/_ASAsyncTransactionContainer+Private.h"; sourceTree = ""; }; - EA5FD6837C3BC283BCEAE16603AE8BA9 /* PINOperationGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINOperationGroup.m; path = Source/PINOperationGroup.m; sourceTree = ""; }; - EAC8AE04C6D624912867C7AF28B45A3F /* PINResume.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINResume.m; path = Source/Classes/PINResume.m; sourceTree = ""; }; - EAF935CFCE349E367CFD3CFE312B4EFD /* CGPoint+dominantDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGPoint+dominantDirection.swift"; sourceTree = ""; }; - EB5705798083744EEEEB7CE058B58C09 /* ASCollectionGalleryLayoutDelegate.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASCollectionGalleryLayoutDelegate.mm; path = Source/Details/ASCollectionGalleryLayoutDelegate.mm; sourceTree = ""; }; - EB97330F8020838EA2C835F2D5E380A1 /* ASDisplayNodeCornerLayerDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeCornerLayerDelegate.h; path = Source/Private/ASDisplayNodeCornerLayerDelegate.h; sourceTree = ""; }; - EBE5E3D5558488FDEAE33619126F1513 /* CGPoint+maximumAbsoluteValue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGPoint+maximumAbsoluteValue.swift"; sourceTree = ""; }; - EBEA00E447337E1023D98C0AC23E2C42 /* PINRemoteImage-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PINRemoteImage-dummy.m"; sourceTree = ""; }; - EC5266FA08A00D7A1C2EB5B60A5CF66A /* ASLayoutSpec+Subclasses.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASLayoutSpec+Subclasses.mm"; path = "Source/Layout/ASLayoutSpec+Subclasses.mm"; sourceTree = ""; }; - EC547208CC428C4630ADEBFBA2A2BDAD /* CGAffineTransform+transformWithScaleTranslationCenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "CGAffineTransform+transformWithScaleTranslationCenter.swift"; sourceTree = ""; }; - ECE0D92D4EC523A9855D1F722186A1E5 /* ASWeakProxy.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASWeakProxy.mm; path = Source/Details/ASWeakProxy.mm; sourceTree = ""; }; - ED0C90099C4B69F62EA096A7F273C971 /* AnimationEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AnimationEvent.swift; sourceTree = ""; }; - ED741FEC7CF39C7B0B4271C1A6C33182 /* ASLayoutController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutController.h; path = Source/Details/ASLayoutController.h; sourceTree = ""; }; - ED7A7B2E8EC994618EEA9CF500126C01 /* ASImageNode+AnimatedImagePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASImageNode+AnimatedImagePrivate.h"; path = "Source/Private/ASImageNode+AnimatedImagePrivate.h"; sourceTree = ""; }; - ED8FA0390861FE0DF8871CD7F10DABFA /* _ASPendingState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASPendingState.h; path = Source/Private/_ASPendingState.h; sourceTree = ""; }; - EDBFF3393C31CD709ECF615266088C91 /* ASLog.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASLog.mm; path = Source/Base/ASLog.mm; sourceTree = ""; }; - EEAF04827173959AAD3EFF77C1B1F0FB /* InjectableLoggers-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "InjectableLoggers-Info.plist"; sourceTree = ""; }; - EF0AED795C713127D4F67E01AAC3B788 /* ASScrollNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASScrollNode.h; path = Source/ASScrollNode.h; sourceTree = ""; }; - EF4FFFABB7BE54C6BCBF9A61F17A6A98 /* ASPageTable.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASPageTable.mm; path = Source/Details/ASPageTable.mm; sourceTree = ""; }; - EFB4F1B82C208BE59AA0898C1479B48F /* ASLayerBackingTipProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayerBackingTipProvider.h; path = Source/Private/ASLayerBackingTipProvider.h; sourceTree = ""; }; - EFBD7E465FF5839A50DEEEE7A6A8AEE3 /* _ASDisplayView.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASDisplayView.mm; path = Source/Details/_ASDisplayView.mm; sourceTree = ""; }; - F10A7F445C73E4B81EB75D2B1FAC1888 /* NSIndexSet+ASHelpers.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "NSIndexSet+ASHelpers.mm"; path = "Source/Details/NSIndexSet+ASHelpers.mm"; sourceTree = ""; }; - F23780FCB6ACAED58B9318C15C8B0DE8 /* ASPageTable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPageTable.h; path = Source/Details/ASPageTable.h; sourceTree = ""; }; - F33ACD58C957BAAC992E6CFFB0F23696 /* ASTextKitTailTruncater.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitTailTruncater.mm; path = Source/TextKit/ASTextKitTailTruncater.mm; sourceTree = ""; }; - F378A66FF19F87E754731A02F1D8352E /* ASCollectionLayoutDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionLayoutDelegate.h; path = Source/Details/ASCollectionLayoutDelegate.h; sourceTree = ""; }; - F46831F4FCE3AB140F12577CE0C2AAB3 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = AsyncDisplayKit.framework; path = Texture.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F4BB088F3EDEBE342A3FC4D32B254AAD /* PINCache-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PINCache-Info.plist"; sourceTree = ""; }; - F74E2E2EDB48C048F9F569CFC937193E /* ASDimensionInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDimensionInternal.h; path = Source/Layout/ASDimensionInternal.h; sourceTree = ""; }; - F751A2E0A0D199939EFC0DF626CE0957 /* PINSpeedRecorder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINSpeedRecorder.h; path = Source/Classes/PINSpeedRecorder.h; sourceTree = ""; }; - F77132454B2BB691E5070FA6A0E46957 /* _ASAsyncTransaction.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = _ASAsyncTransaction.mm; path = Source/Details/Transactions/_ASAsyncTransaction.mm; sourceTree = ""; }; - F77355B911C772EB2AD735BF076E4CFD /* ASDelegateProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDelegateProxy.h; path = Source/Details/ASDelegateProxy.h; sourceTree = ""; }; - F7B197008C37795CA80DA38516F408A2 /* ASAssert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASAssert.h; path = Source/Base/ASAssert.h; sourceTree = ""; }; - F8876372AC72ABDE78438AC6901D6A2C /* PINMemMapAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINMemMapAnimatedImage.m; path = Source/Classes/AnimatedImages/PINMemMapAnimatedImage.m; sourceTree = ""; }; - F8E01445D32DABC80642FEC5993BD8A7 /* ASCollectionView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASCollectionView.h; path = Source/ASCollectionView.h; sourceTree = ""; }; - FA02D2C56C599E247CA011F6D621AA3A /* PINRemoteImageMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageMacros.h; path = Source/Classes/PINRemoteImageMacros.h; sourceTree = ""; }; - FA100E34969B2131C471F94030FF7F28 /* PINCacheObjectSubscripting.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCacheObjectSubscripting.h; path = Source/PINCacheObjectSubscripting.h; sourceTree = ""; }; - FA55D18353B91480033D3AC52439C4BF /* PINSpeedRecorder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINSpeedRecorder.m; path = Source/Classes/PINSpeedRecorder.m; sourceTree = ""; }; - FAF9BF2152AEE816BD4063566927C2C7 /* ASDisplayNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASDisplayNode.mm; path = Source/ASDisplayNode.mm; sourceTree = ""; }; - FBCF740EBE5DE3C173D4E8439D0DFF36 /* ASTipsWindow.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTipsWindow.mm; path = Source/Private/ASTipsWindow.mm; sourceTree = ""; }; - FC678FBD26515FC0EEA585EC6DE85663 /* ASDisplayNode+AsyncDisplay.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "ASDisplayNode+AsyncDisplay.mm"; path = "Source/Private/ASDisplayNode+AsyncDisplay.mm"; sourceTree = ""; }; - FC8926956354A9BB50C3BB8FFD5A07D9 /* PINRemoteImageCategoryManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageCategoryManager.h; path = Source/Classes/PINRemoteImageCategoryManager.h; sourceTree = ""; }; - FCBF961C99AB6BE3B67E1A5D49BD0FBA /* ASTableViewProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASTableViewProtocols.h; path = Source/ASTableViewProtocols.h; sourceTree = ""; }; - FD0555E6007F93E7AB71B7AC7A643894 /* AsyncDisplayKit+Debug.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "AsyncDisplayKit+Debug.mm"; path = "Source/Debug/AsyncDisplayKit+Debug.mm"; sourceTree = ""; }; - FD5548AE6697EB822F1F6AE7D549CDA3 /* PINCache.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PINCache.modulemap; sourceTree = ""; }; - FD73543F8F59FA39EB762F129AC023EF /* ASBatchContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASBatchContext.h; path = Source/Details/ASBatchContext.h; sourceTree = ""; }; - FDA847AF8B056A3AC9A65250377F027C /* ASTextKitCoreTextAdditions.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASTextKitCoreTextAdditions.mm; path = Source/TextKit/ASTextKitCoreTextAdditions.mm; sourceTree = ""; }; - FEDBB3F3DD47B161C406D03FF3A9BCC5 /* UICollectionViewLayout+ASConvenience.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = "UICollectionViewLayout+ASConvenience.mm"; path = "Source/Details/UICollectionViewLayout+ASConvenience.mm"; sourceTree = ""; }; - FEEE1F4CD0EBD604CAB288E054835B9B /* ASVisibilityProtocols.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASVisibilityProtocols.h; path = Source/ASVisibilityProtocols.h; sourceTree = ""; }; - FF34E71B804FA873D12D62187CBBB9BC /* ASObjectDescriptionHelpers.mm */ = {isa = PBXFileReference; includeInIndex = 1; name = ASObjectDescriptionHelpers.mm; path = Source/Details/ASObjectDescriptionHelpers.mm; sourceTree = ""; }; + EA7C2CD848FACF3605201842A31CAE94 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/ImageIO.framework; sourceTree = DEVELOPER_DIR; }; + EBBC13C1697AD5A79814942839EB3BE6 /* ASLayoutManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASLayoutManager.h; path = Source/TextKit/ASLayoutManager.h; sourceTree = ""; }; + EBDEAAC4C345279ED09C50CF3BF09B7B /* PINAlternateRepresentationProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINAlternateRepresentationProvider.m; path = Source/Classes/PINAlternateRepresentationProvider.m; sourceTree = ""; }; + ED6036BDF81C2EFDD33A26E96FF6AFF2 /* ASLayerBackingTipProvider.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayerBackingTipProvider.mm; path = Source/Private/ASLayerBackingTipProvider.mm; sourceTree = ""; }; + EDBF575B54A123E2694047C8C6894AB7 /* PINImageView+PINRemoteImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PINImageView+PINRemoteImage.h"; path = "Source/Classes/include/PINImageView+PINRemoteImage.h"; sourceTree = ""; }; + EDC1F1D124388ACE2413346CB3B8CEB2 /* PINRemoteImageMemoryContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteImageMemoryContainer.h; path = Source/Classes/PINRemoteImageMemoryContainer.h; sourceTree = ""; }; + EE6B4FA98E3B71705FE19CC355592CD3 /* ASTextKitFontSizeAdjuster.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTextKitFontSizeAdjuster.mm; path = Source/TextKit/ASTextKitFontSizeAdjuster.mm; sourceTree = ""; }; + EE7A1B087B94691BF730791439BE3281 /* ASImageNode+CGExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASImageNode+CGExtras.h"; path = "Source/Private/ASImageNode+CGExtras.h"; sourceTree = ""; }; + EED6E5D64A260BBC73D89EAC4EE5A380 /* ASPagerNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASPagerNode.h; path = Source/ASPagerNode.h; sourceTree = ""; }; + EFB8D888E1320584A10E63E2737403F0 /* PINOperation-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PINOperation-prefix.pch"; sourceTree = ""; }; + F06F5857985D77588F3293CCCB51FC40 /* NSIndexSet+ASHelpers.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "NSIndexSet+ASHelpers.mm"; path = "Source/Details/NSIndexSet+ASHelpers.mm"; sourceTree = ""; }; + F0C1A4032113C581DBC652A5D1C30293 /* PINRemoteLock.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINRemoteLock.h; path = Source/Classes/PINRemoteLock.h; sourceTree = ""; }; + F0FDFF2101834ADCDD23AA9D3985EC49 /* ASBasicImageDownloader.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASBasicImageDownloader.mm; path = Source/Details/ASBasicImageDownloader.mm; sourceTree = ""; }; + F14EC73928B311AAA3201B108B38181E /* Texture-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Texture-prefix.pch"; sourceTree = ""; }; + F2C1DB9479499FE9B70BDD375E242A22 /* ASDisplayNodeExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDisplayNodeExtras.h; path = Source/ASDisplayNodeExtras.h; sourceTree = ""; }; + F2C21DD7FDAD82793DA6912B527CCA8A /* ASSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASSectionController.h; path = Source/ASSectionController.h; sourceTree = ""; }; + F2DB9FFDC78A1FFD1EAFA4CB07F1F0C8 /* Texture.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Texture.debug.xcconfig; sourceTree = ""; }; + F2E4639A35242C5823DACB52A5054354 /* ASTwoDimensionalArrayUtils.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTwoDimensionalArrayUtils.mm; path = Source/Private/ASTwoDimensionalArrayUtils.mm; sourceTree = ""; }; + F3E440CADA5070BE3D563D05B491DE62 /* PINOperationQueue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINOperationQueue.m; path = Source/PINOperationQueue.m; sourceTree = ""; }; + F46831F4FCE3AB140F12577CE0C2AAB3 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F53D4B6F4C18BE99E9336EAE1707A8DE /* NSParagraphStyle+ASText.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = "NSParagraphStyle+ASText.mm"; path = "Source/Private/TextExperiment/Utility/NSParagraphStyle+ASText.mm"; sourceTree = ""; }; + F56C6B1FEAADDD67177C4FC528C76323 /* ASAbstractLayoutController+FrameworkPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASAbstractLayoutController+FrameworkPrivate.h"; path = "Source/Private/ASAbstractLayoutController+FrameworkPrivate.h"; sourceTree = ""; }; + F5AB42EA0047BCD585B5B0401C2E88B3 /* PINButton+PINRemoteImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "PINButton+PINRemoteImage.m"; path = "Source/Classes/ImageCategories/PINButton+PINRemoteImage.m"; sourceTree = ""; }; + F701E64DB403DD2CAF9D8004138DF2E6 /* ASPendingStateController.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASPendingStateController.mm; path = Source/Private/ASPendingStateController.mm; sourceTree = ""; }; + F772F99383F940F834E7E84E4E1CADA3 /* DefaultAnimators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DefaultAnimators.swift; sourceTree = ""; }; + F8B91C4F2D81045D14D0886080099732 /* ASTableView+Undeprecated.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ASTableView+Undeprecated.h"; path = "Source/Private/ASTableView+Undeprecated.h"; sourceTree = ""; }; + FA621A2A3717016D8818217BBCE87FF4 /* ASStackPositionedLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASStackPositionedLayout.h; path = Source/Private/Layout/ASStackPositionedLayout.h; sourceTree = ""; }; + FA82910B21B45CA35C2E513D8126CBA5 /* ASConfigurationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASConfigurationInternal.h; path = Source/ASConfigurationInternal.h; sourceTree = ""; }; + FAC0FF9654DDE91AD4E6B491A1132129 /* ASDimensionInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDimensionInternal.h; path = Source/Layout/ASDimensionInternal.h; sourceTree = ""; }; + FAC4D6232B240A0232B376FE8DF140DB /* PINCache-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PINCache-Info.plist"; sourceTree = ""; }; + FBA716F6CEBD4B6202124CCF837017B5 /* ASVideoNode.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASVideoNode.mm; path = Source/ASVideoNode.mm; sourceTree = ""; }; + FBFD8FA4FCE93DB01B5963643900A267 /* _ASDisplayLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASDisplayLayer.h; path = Source/Details/_ASDisplayLayer.h; sourceTree = ""; }; + FC078748D3AA3E0CB9EABB51A9790BA9 /* _ASCollectionGalleryLayoutInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _ASCollectionGalleryLayoutInfo.h; path = Source/Private/_ASCollectionGalleryLayoutInfo.h; sourceTree = ""; }; + FC6C539347674A43A36A914B13136CF0 /* ASDimension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASDimension.h; path = Source/Layout/ASDimension.h; sourceTree = ""; }; + FD5B4CECF91B0EEB87A10C231F414D2B /* ASMainSerialQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMainSerialQueue.h; path = Source/Details/ASMainSerialQueue.h; sourceTree = ""; }; + FD6F468C17D5D55709E1A98E64A9A77E /* PINCacheMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PINCacheMacros.h; path = Source/PINCacheMacros.h; sourceTree = ""; }; + FE5C5EA569981CB127DA87B026FAE639 /* ASTipsWindow.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = ASTipsWindow.mm; path = Source/Private/ASTipsWindow.mm; sourceTree = ""; }; + FEF2AB20596EBB5D41C0C30CDE3733FA /* ImageZoomControllerActions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ImageZoomControllerActions.swift; sourceTree = ""; }; + FF1C4282E2564807E444F007450542C7 /* PINAnimatedImage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = PINAnimatedImage.m; path = Source/Classes/AnimatedImages/PINAnimatedImage.m; sourceTree = ""; }; + FFBC5C72774055D3AC41F455A190BA47 /* ASMainThreadDeallocation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ASMainThreadDeallocation.h; path = Source/ASMainThreadDeallocation.h; sourceTree = ""; }; + FFE7B568EE5763387E9FD7DA97625EA1 /* CanProvideAnimatorForEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CanProvideAnimatorForEvent.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 05AE22FDDE21CE1249C98951A6CFB8D2 /* Frameworks */ = { + 059E3121D15442F422222D8AD47E0686 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 77B666155C44BA2A2F1C2A5850970505 /* Foundation.framework in Frameworks */, + 40AE1EFE7405EB78CE80A1AAF989AA95 /* Foundation.framework in Frameworks */, + 6E4E5512E8EC803F48F6D04561EA0A2B /* PINOperation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 1936C21DE636BD2B82081D2BDFFD902B /* Frameworks */ = { + 087AD93CFA987850BCC1EC91DD1AB6D1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2F3EA1FD73E0904E3966BF1FE94E5264 /* Foundation.framework in Frameworks */, + CC9C25D74EAD02331BA2CB002D9B20E3 /* Foundation.framework in Frameworks */, + EC86C6197A99F375E5FF8034604630EA /* InjectableLoggers.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 242A85C074D836A1CF05972D090A651B /* Frameworks */ = { + 1561721F7DAB089F0EC0B49011A14513 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BABCA75A40E66297E498280E1D393E26 /* AssetsLibrary.framework in Frameworks */, - 992ABABCE0CD2DA9F69174880AA167E2 /* AVFoundation.framework in Frameworks */, - D12FEAC2B168519EA04F32F80A1A6C26 /* CoreLocation.framework in Frameworks */, - B70DC15A7BF4D41B8A2DA1C20C646285 /* CoreMedia.framework in Frameworks */, - 9ACCEA9EC6A16D4B1FF719E2ED3895ED /* Foundation.framework in Frameworks */, - F26DBA07E4395641FAE0F387285C6DAD /* MapKit.framework in Frameworks */, - 154078E295CEF73049CC0E6EA4E894BF /* Photos.framework in Frameworks */, - B078D55EE106C5BFF41BFFDE043A00C0 /* PINRemoteImage.framework in Frameworks */, + 454EC213F2ABCFC7C51C7BC1B2976F9D /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5AFBCAE07840B05D6980655DD22E042C /* Frameworks */ = { + 47B7B7C3BC1A08173D52ED498F5155FF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 23D397D9E8853F04EDDA3D79FC58B312 /* Foundation.framework in Frameworks */, + 3D204BC922D2A57C4467B506DA458873 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - A6B54C63632E82DB9B90BA9E3681612B /* Frameworks */ = { + 4944372286DB7CF00171CB0CC5D55B61 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4C5031DC1938A816B9BC7DE205504AC6 /* Foundation.framework in Frameworks */, + C782835223517924A26F0EBFEA0C00DF /* AssetsLibrary.framework in Frameworks */, + FE31388AFA377EF837E0D80C74351FD7 /* AVFoundation.framework in Frameworks */, + EB472359A2A67364B3578253C8C4ABC3 /* CoreLocation.framework in Frameworks */, + 8AB6AEE4DF780E7CAA39A698FA4E7634 /* CoreMedia.framework in Frameworks */, + 2E4E16EEF78B38EA1F4977CF1EC63511 /* Foundation.framework in Frameworks */, + DDBE0B9C33CFF36A689113FB2148B8ED /* MapKit.framework in Frameworks */, + B1103DF2D4C2767291DD23DFCEA33024 /* Photos.framework in Frameworks */, + 713DAEE94040383AD0A64FE5E1C6E0D0 /* PINRemoteImage.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - A778F03BF6D5012EB67925281D5EFB16 /* Frameworks */ = { + 5622EFD94CDE5BAE4CEE2FFE1B600A96 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DA0B2AAB4F5383AB91442800F650D264 /* Foundation.framework in Frameworks */, - 49A75566AFB4BA6F389C3D26415B1C69 /* PINOperation.framework in Frameworks */, + 7E51B87E055DF9E8C348B479D57C9E5B /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - C9B63557A48A85F69CC4F8F9491D5720 /* Frameworks */ = { + 5AFBCAE07840B05D6980655DD22E042C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9132BC4491E756E7A4233BAB58C923B7 /* Accelerate.framework in Frameworks */, - 11499C360C83931E8E9F51425561E58B /* Foundation.framework in Frameworks */, - A4D739A03F6C168A7A30A212D7560C68 /* ImageIO.framework in Frameworks */, - 2A15AB6DF134AD6043C18E6CC95B3C94 /* PINCache.framework in Frameworks */, - 4251732D573F5FDD6CC34108977CEC1C /* PINOperation.framework in Frameworks */, - C00B0DE199AEFE459F4BA1046560AAC5 /* UIKit.framework in Frameworks */, + 397CBCED265CEF9B598462C78FB412DD /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - CC4043B6599186B8FECA284855B9B05B /* Frameworks */ = { + C6A2093EFA9C0E4742B6F8AF6DCB412D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BDCA468F44DD0877EBE9ED4A2FBDD578 /* Foundation.framework in Frameworks */, - 4779B0E0D89E2A8468BCDDB30AFA1373 /* InjectableLoggers.framework in Frameworks */, + F803EDD45DA76E8392546A43BD223D8F /* Accelerate.framework in Frameworks */, + 9A7F2B5821CB7EA9AD72F2FA5B67D152 /* Foundation.framework in Frameworks */, + 8BE298408DCAF8348629CC2FD95B8883 /* ImageIO.framework in Frameworks */, + 743030AC14DFBE803BDE5EC37D25C31C /* PINCache.framework in Frameworks */, + 94E0E3DE8E35A8EE40E20D8A0B253561 /* PINOperation.framework in Frameworks */, + A247EE1D278372734D41DA53BCC96820 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1395,7 +1410,7 @@ 008B733A3A0CE69B21F7D0D550C1D495 /* Development Pods */ = { isa = PBXGroup; children = ( - BA8FA0D88ED96BD5B1C0707270FDB372 /* Zoomy */, + 457D693EBA1C7235BB0857B8664E22AE /* Zoomy */, ); name = "Development Pods"; sourceTree = ""; @@ -1417,637 +1432,674 @@ path = "Target Support Files/Pods-Zoomy_Example"; sourceTree = ""; }; - 02C87EF1FDD1FD2D9945FA312B308B94 /* Support Files */ = { + 07B52338B264853E539C9E6A6CD8F107 /* Classes */ = { isa = PBXGroup; children = ( - 212B04CD850FD5C27BB5A749200F1C38 /* PINRemoteImage.modulemap */, - 638BCD02FE611C5776A63C02551D7ED6 /* PINRemoteImage.xcconfig */, - EBEA00E447337E1023D98C0AC23E2C42 /* PINRemoteImage-dummy.m */, - AD83B8B951B27AA22FAEEA2F1531D940 /* PINRemoteImage-Info.plist */, - 0169698F1001B64F149CDB5D6DD08CF9 /* PINRemoteImage-prefix.pch */, - 843527DDA67E9C01B757C84DADBE0839 /* PINRemoteImage-umbrella.h */, + 7553FE85837FFE5E024123DA400A5BB6 /* ImageZoomController.swift */, + 40161622AE9EB7912BC3BF1CBBC09039 /* ImageZoomController.Factory.swift */, + FEF2AB20596EBB5D41C0C30CDE3733FA /* ImageZoomControllerActions.swift */, + 03DB36FBE1545B64BB23CA4E02BDE1E5 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift */, + 51135E999C9B63A3A146C9EC1CD3D0CE /* ImageZoomControllerIsNotPresentingOverlayState.swift */, + C9D73CD563E03400418EBC0A4784D1C1 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift */, + B70C3A4BA56751CA33F52C2D0C4B7517 /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift */, + 2EACF1E5973F81B5B80D4AEC7EEA6F72 /* ZoomyLogger.swift */, ); - name = "Support Files"; - path = "../Target Support Files/PINRemoteImage"; + name = Classes; + path = Zoomy/Classes/Classes; sourceTree = ""; }; - 0C809562BCB7DCE75A67EC92B9F5863A /* TypeAliasses */ = { + 0843A613A1AAC1896E325FD72B7DC432 /* PINOperation */ = { isa = PBXGroup; children = ( - 0F0BD0EDE0ED2F616D20EF4F8324DBE4 /* TypeAliasses.swift */, + 298080512F81BC540FE52192C678D1FC /* PINOperation.h */, + 3DB890B5C2AB3082392D9AB6F63D1103 /* PINOperationGroup.h */, + 523240EAB47539D12567510B8F883DC8 /* PINOperationGroup.m */, + 4A3E448B9053C61DFE2DFCF6CBA4ACA7 /* PINOperationMacros.h */, + 9E5A50B85249AF7029C56D5811BF80F3 /* PINOperationQueue.h */, + F3E440CADA5070BE3D563D05B491DE62 /* PINOperationQueue.m */, + E4BE922521021592DF0960FC9290CA4D /* PINOperationTypes.h */, + 65EBDC89727160B14CBA9C21C4A800A0 /* Support Files */, ); - name = TypeAliasses; - path = Zoomy/Classes/TypeAliasses; + path = PINOperation; + sourceTree = ""; + }; + 0EB569258E26AF52E6AC102C75B9353F /* PINRemoteImage */ = { + isa = PBXGroup; + children = ( + 6EA8459D30C6CC0A4979A83CC8061FC6 /* Core */, + C8DA20F1B0BF541FBAB685848823E9C5 /* PINCache */, + 2D899C0FD28A947892E6EFDBFE23B24E /* Support Files */, + ); + path = PINRemoteImage; + sourceTree = ""; + }; + 2C37E21A44E2D6891973A4EC33C71CB1 /* InjectableLoggers */ = { + isa = PBXGroup; + children = ( + 9D1DFA6C99F765607130031AF14FE7C9 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift */, + 2DED5930F943F0D3748F0B68C9814C9A /* CanLog.swift */, + CAB7AEB454892E87F9B1C2F04DCFE0D0 /* CanLogAtLevel.swift */, + 8572FDFE5D32A555792D8D264EBEC9C4 /* CanLogMessage.swift */, + E805F69FFCA26465321093F9D504AC2C /* CanLogMessageAtLevel.swift */, + 927D9DECBCACA5CF8DBD67DACE505DC2 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift */, + 96B7C2C62F443A5228AC674A23FCCD87 /* CanLogMessageInFileInFunctionAtLine.swift */, + 6A5BE4F496799AB427B7E02D30B8550C /* ConsoleLogger.swift */, + 8E130B5861ABC920DB5C7C130B2CD5F8 /* HasDefaultLoglevel.swift */, + 72E63BB89BB4648998A676175AA7FCFE /* Logger.swift */, + 3EADEF54394FEF3203A0D14FB0FBB32E /* Logger.FormatSettings.swift */, + 049DEE219089C56A9FF4D8DB4DE90C83 /* Logger.Formatter.swift */, + 377942A736134FFDA949F494767752F1 /* Logger.Settings.swift */, + D8935CD3A0EBC471E7D637DB30BA926B /* LogLevel.swift */, + 787A46EF98C950C390FA42BB039DA0EC /* MockLogger.swift */, + 0091DD8DF08F9D4D4FED8A7FAECB171C /* SimpleLogger.swift */, + 1123D4B16476D633BF2D6511A5A81017 /* SimpleLogger.Settings.swift */, + DD5185F64A8E805ED7D94A1EE0EC8153 /* Support Files */, + ); + path = InjectableLoggers; sourceTree = ""; }; - 1029FFB6429F144BB0AE342861E093D9 /* Support Files */ = { + 2D899C0FD28A947892E6EFDBFE23B24E /* Support Files */ = { isa = PBXGroup; children = ( - 99944E9365C1EDE2071B715261BF6FD9 /* Texture.modulemap */, - 073F5156FDFEF3B8AA6981CD17F054AE /* Texture.xcconfig */, - C601CF5677E9413D7D662DCBFF8A420B /* Texture-dummy.m */, - 66EAE704190CA358DB4856F26E0607E6 /* Texture-Info.plist */, - 17D2ABE499E151BD596D45D813CB5E23 /* Texture-prefix.pch */, - DA6B00F5DCBD9D92902113D39B1EE973 /* Texture-umbrella.h */, + 7948440DC9755B2496424FB9E4AE8E15 /* PINRemoteImage.modulemap */, + 72993BC01B036B4DF85688844D2A00C3 /* PINRemoteImage-dummy.m */, + 8B652808CFCA8AB41B6DAE371EEDFFB4 /* PINRemoteImage-Info.plist */, + C9E659D0C8C2D9712FEC2736A469A090 /* PINRemoteImage-umbrella.h */, + 540D079F51C83D244C9ED5EB1C961001 /* PINRemoteImage.debug.xcconfig */, + D4CC5A8855E96D7657A8163FB9889C8E /* PINRemoteImage.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/Texture"; + path = "../Target Support Files/PINRemoteImage"; sourceTree = ""; }; - 1378D9D016621281A1EF9C2C2FBB8BE7 /* PINOperation */ = { + 33BAB025C28ACB0A07C2D0141F6F812E /* Enums */ = { isa = PBXGroup; children = ( - 64BFE2FB5FD0C114FE30D1443B38097B /* PINOperation.h */, - 00B19F9A89A433337404373E49907CF9 /* PINOperationGroup.h */, - EA5FD6837C3BC283BCEAE16603AE8BA9 /* PINOperationGroup.m */, - 8601A38169596B1A8B21A3BA548AA1E4 /* PINOperationMacros.h */, - C4000565ABB42B463A834CB1F2577D74 /* PINOperationQueue.h */, - 069772F35BA6AC6B783EA915D5DABFC2 /* PINOperationQueue.m */, - D66AD00BCB9A19991B9EE09548F16733 /* PINOperationTypes.h */, - E5200B3D67ECDB575C62E70D876F1D9A /* Support Files */, + 921BD97807EB0DDC435B8194E258EA9F /* AnimationEvent.swift */, + 3BA08AA67D939C3E23A4D3312A8ACA70 /* ImageZoomControllerContentState.swift */, + 240A9BD4EECE73A564FCDC42E7A35203 /* Side.swift */, ); - name = PINOperation; - path = PINOperation; + name = Enums; + path = Zoomy/Classes/Enums; sourceTree = ""; }; - 14427FF774844D2289117EC6C9AD0158 /* Arc-exception-safe */ = { + 3C9BF88808D009880EEFEEB1AC65068E /* Support Files */ = { isa = PBXGroup; children = ( - C4F0FE57A14FE3D7B4120DEFA866E5A6 /* PINDiskCache.m */, + DC8FE4D97CE0DAE7FA9E101ADC4714F8 /* Zoomy.modulemap */, + A8C5B4CDB31225A9BF38BCC18B506CBC /* Zoomy-dummy.m */, + 6824D67D89E086ACB941848B24C0DF26 /* Zoomy-Info.plist */, + A8B619F8704EE467BAD027D7B3D78A8B /* Zoomy-prefix.pch */, + B2004AC400F42335B666DAB0028739F9 /* Zoomy-umbrella.h */, + A0126269F7621AA924B3EA6B12F43F45 /* Zoomy.debug.xcconfig */, + 8FB1B03C5E645FDFD3FACFBDACA87DB9 /* Zoomy.release.xcconfig */, ); - name = "Arc-exception-safe"; + name = "Support Files"; + path = "Example/Pods/Target Support Files/Zoomy"; sourceTree = ""; }; - 1D23800CE9F9E437C92CE24658520490 /* Core */ = { + 3D2DCE4D62A5211128639CCDCBF7870F /* Core */ = { isa = PBXGroup; children = ( - C479D571D3825B10ECABE5FE1938450E /* NSData+ImageDetectors.h */, - 30A7CAD63165CA3F03F1EB41082C5271 /* NSData+ImageDetectors.m */, - 0FD6A1C78C243ABC82E24C0705F1F667 /* PINAlternateRepresentationProvider.h */, - E3B0B3833F78F5202AE6A4EDAACABE40 /* PINAlternateRepresentationProvider.m */, - DA268B7E44D38BCD77321FABC32B31D0 /* PINAnimatedImage.h */, - 7BF91A7594887570D0581A2292B69202 /* PINAnimatedImage.m */, - 8FC68EA45CF88CEF4344C5649820AC99 /* PINButton+PINRemoteImage.h */, - 0F618C832DC0906460A5823141B80889 /* PINButton+PINRemoteImage.m */, - 8B4568266DA1D977E83A8C75D4C2C35E /* PINCachedAnimatedImage.h */, - 29AEC841809838E1FBD4FB000000901E /* PINCachedAnimatedImage.m */, - 86F85E0F87EC16039F8621F5162F9270 /* PINGIFAnimatedImage.h */, - 88BB970C61F10199085A0DDA55F977CB /* PINGIFAnimatedImage.m */, - 688A39228B8F3C56FD32EA204F9A9FEC /* PINGIFAnimatedImageManager.h */, - 9C9B91A2092075DF22A0BDCB1A1EEBCA /* PINGIFAnimatedImageManager.m */, - 93858681644872716A52C7FA30FF1F36 /* PINImage+DecodedImage.h */, - B5DE6DADB18EAD43910351907C8EAB45 /* PINImage+DecodedImage.m */, - 385E6F060FBF7CFBD72B759FD50D0667 /* PINImage+ScaledImage.h */, - 5A26326A1EC4D60A6D350C454C89D29D /* PINImage+ScaledImage.m */, - 164865052A57263BCC5A5D2DD47E2FE9 /* PINImage+WebP.h */, - 59FBECE43ADC1822C1BFB2AF4CC30D0B /* PINImage+WebP.m */, - AB0C309D246B1C8BAD0377A6A1815153 /* PINImageView+PINRemoteImage.h */, - 91ECE220C50CE0A538355C0A14CA578F /* PINImageView+PINRemoteImage.m */, - 18516CDF6334CB04ECD67DD6C9994D10 /* PINMemMapAnimatedImage.h */, - F8876372AC72ABDE78438AC6901D6A2C /* PINMemMapAnimatedImage.m */, - A70EC583D74B1259AF4D563FB225D45C /* PINProgressiveImage.h */, - 90D1F9DA550B0E716C6CB4EF9EA9DAE5 /* PINProgressiveImage.m */, - A396339D2FC678CBF9BBF4141C6E3AED /* PINRemoteImage.h */, - 640CE1206037C85BD667C306F05F33BB /* PINRemoteImageBasicCache.h */, - 71B1E4BAAE8A86601C8C6B97DEFE47E4 /* PINRemoteImageBasicCache.m */, - BC8BCDD05FFF87F653DF293D126D9292 /* PINRemoteImageCaching.h */, - AD44715CD9D5542D3941D58B4A413098 /* PINRemoteImageCallbacks.h */, - 682AC42FFA98ABE6BB66417D133D425D /* PINRemoteImageCallbacks.m */, - FC8926956354A9BB50C3BB8FFD5A07D9 /* PINRemoteImageCategoryManager.h */, - 38C81F994E42B0DB94073425D99DAC06 /* PINRemoteImageCategoryManager.m */, - 0AEE3B05A5D034B14D96235552DAB8A1 /* PINRemoteImageDownloadQueue.h */, - 29423EDA573890D6CA0D528B6D1D3269 /* PINRemoteImageDownloadQueue.m */, - 444CA15EA0AAE68E84B2D0D2BF11BF8D /* PINRemoteImageDownloadTask.h */, - 3FE9A85EBB7C7832A0718380B6834F01 /* PINRemoteImageDownloadTask.m */, - FA02D2C56C599E247CA011F6D621AA3A /* PINRemoteImageMacros.h */, - 601C1AF391DB366A2C1A19B86C26DEFA /* PINRemoteImageManager.h */, - 28253AD44028A9D310E9A7C4E2F34231 /* PINRemoteImageManager.m */, - 056F5351D15FECFF550FF001A1172E9C /* PINRemoteImageManager+Private.h */, - 58DF4723F4C3C47CA4B7F675A4BA05FF /* PINRemoteImageManagerResult.h */, - 75B8ACE26E3AB8DC3A77EAF33F43FB07 /* PINRemoteImageManagerResult.m */, - 92540F298A1CABBD995289FDD9759F69 /* PINRemoteImageMemoryContainer.h */, - DCB779A3A6B164BAAA0959C229254646 /* PINRemoteImageMemoryContainer.m */, - 96BE75919B287F89A7548E608DFC243C /* PINRemoteImageProcessorTask.h */, - CB9B0F0A3D14749D0C88E4093EF353C9 /* PINRemoteImageProcessorTask.m */, - 538A265EC6AEC4BBC85EC2796FB9D3BE /* PINRemoteImageTask.h */, - BF28046FF0FAA13D619A64DAA2D048C1 /* PINRemoteImageTask.m */, - 821867185C05134187FCADAB598C7AFB /* PINRemoteImageTask+Subclassing.h */, - 01D61BF0A499F5857CF17E32798585EE /* PINRemoteLock.h */, - 1D861E5A7BB213F7BDA5A3E68863582E /* PINRemoteLock.m */, - 31E8320921F753F72E16B6995A77EBF3 /* PINRequestRetryStrategy.h */, - 5F3472C9C5C5A1BC89A55AC74BFCC7B1 /* PINRequestRetryStrategy.m */, - 098428E42955EF96D87FE1C354E8AD9D /* PINResume.h */, - EAC8AE04C6D624912867C7AF28B45A3F /* PINResume.m */, - F751A2E0A0D199939EFC0DF626CE0957 /* PINSpeedRecorder.h */, - FA55D18353B91480033D3AC52439C4BF /* PINSpeedRecorder.m */, - 8625D5C81FCFE2B385A4DD440C2B9EBA /* PINURLSessionManager.h */, - 15EF4E25B85DD21D7F9FDD4BF7B1AB46 /* PINURLSessionManager.m */, - 4BF08A0A062F57E0ABEE60019B8BFE6A /* PINWebPAnimatedImage.h */, - 4FF0F8D6BD0C7F366D8BCA8064C2636D /* PINWebPAnimatedImage.m */, + 43C20F8B4080DCC6F47FE97ECA3E5486 /* _ASAsyncTransaction.h */, + C8E316AF000D6A307AFFBFC59E27FCB2 /* _ASAsyncTransaction.mm */, + 9EC45975D0A70E685883A6EE402012D1 /* _ASAsyncTransactionContainer.h */, + D084ECEB354EC79F4F4DB811D3C5B611 /* _ASAsyncTransactionContainer.mm */, + 65133D87AEBB73F5FF7A1A7CC904EE8A /* _ASAsyncTransactionContainer+Private.h */, + 6B0113958F688610CF771535C447AA8F /* _ASAsyncTransactionGroup.h */, + 0B82A3E466AAE96E03B8609312FAF2F6 /* _ASAsyncTransactionGroup.mm */, + FC078748D3AA3E0CB9EABB51A9790BA9 /* _ASCollectionGalleryLayoutInfo.h */, + 5E86488B04A57D96057DE295100FCB4F /* _ASCollectionGalleryLayoutInfo.mm */, + CB3CC8A51469A1A050DF9202D4ABD37C /* _ASCollectionGalleryLayoutItem.h */, + 1563E54ED0D8EAADD8B23DD9E695A4C0 /* _ASCollectionGalleryLayoutItem.mm */, + 4EB5231AD49D7544AA0B2B2C57B47080 /* _ASCollectionReusableView.h */, + 2AE87F010BB241641A5655B985A653C6 /* _ASCollectionReusableView.mm */, + 08A05187C58CF3FEFE6C3FD04038BFD7 /* _ASCollectionViewCell.h */, + 4915512699D90A7C7C29F8F493235B79 /* _ASCollectionViewCell.mm */, + 007EA24CB3D0521364C550D47F1E4C56 /* _ASCoreAnimationExtras.h */, + CEB22121B395ED735216159F1CA578D8 /* _ASCoreAnimationExtras.mm */, + FBFD8FA4FCE93DB01B5963643900A267 /* _ASDisplayLayer.h */, + 6B5DFABF4BDE70BA28458B972B220A13 /* _ASDisplayLayer.mm */, + 310BD706DB638309D39CAFB2E12E51E8 /* _ASDisplayView.h */, + D1FB03D4F024FA0F361CB89A886A04E6 /* _ASDisplayView.mm */, + 3FBE47550DB37A88FC7CFE0100233D15 /* _ASDisplayViewAccessiblity.h */, + 4CD4A80CBB44F35AB6DC6F1CD500C93C /* _ASDisplayViewAccessiblity.mm */, + A7A7381EDB33C4C063714E18E447DF8D /* _ASHierarchyChangeSet.h */, + DB9FBBC1EF5AF543DA86EBF741B82694 /* _ASHierarchyChangeSet.mm */, + 90589B54C0040F9F2E141D6205FB3F95 /* _ASPendingState.h */, + 02B7FAE0B0A89921AA60FCD1B1A628AB /* _ASPendingState.mm */, + B92BC147B759930674C603C4E1C3555E /* _ASScopeTimer.h */, + 626C3FFAA488C3DD09D53C2E75C9CF17 /* _ASTransitionContext.h */, + BF015D61C4F514CD102521B65306C0DE /* _ASTransitionContext.mm */, + 9ABD6F3FC6B368A8ADD0AA7A57D95A2F /* ASAbsoluteLayoutElement.h */, + 4D501F0E961A620207729EC46BD2A385 /* ASAbsoluteLayoutSpec.h */, + 3CC29518FB41642415C151CB182BC02A /* ASAbsoluteLayoutSpec.mm */, + 2BFA9B4CE54E1E697CA67579BE312597 /* ASAbstractLayoutController.h */, + 365171A2F8B907C0ABA54E5D81DEC78F /* ASAbstractLayoutController.mm */, + F56C6B1FEAADDD67177C4FC528C76323 /* ASAbstractLayoutController+FrameworkPrivate.h */, + 2609443EEA2A32EE403E707D0572F9D7 /* ASAsciiArtBoxCreator.h */, + D017BE463D6FA4889B4C3BBCB7F0058C /* ASAsciiArtBoxCreator.mm */, + BDA4460D90E3CCCCDF6A594AC96AB183 /* ASAssert.h */, + 11FC95FCA7AA02C819434E619DB2974B /* ASAssert.mm */, + C9B95674F1A017DABD24226712B9D591 /* ASAvailability.h */, + C57821E88CDD7886ACE86068E06D5B34 /* ASBackgroundLayoutSpec.h */, + AF60023FF5645E71160109652BDEE4D3 /* ASBackgroundLayoutSpec.mm */, + 86B385DAAFF0820A00FF000415C6DF6A /* ASBaseDefines.h */, + E706D8361E42669B2765F7B815C532A3 /* ASBasicImageDownloader.h */, + F0FDFF2101834ADCDD23AA9D3985EC49 /* ASBasicImageDownloader.mm */, + 03ADCD0D9AD000A2C92CBC5FFF6E8F97 /* ASBasicImageDownloaderInternal.h */, + D28E1FDF6AF4C8EA76A2E6B04468EFF3 /* ASBatchContext.h */, + 24C95280DDBF1B216647DC50DD8E35F5 /* ASBatchContext.mm */, + 2AC31EF58C1CD0626B658B072A7EBAF8 /* ASBatchFetching.h */, + 357620DEBE7E9C5DCAAB4AFEDA157938 /* ASBatchFetching.mm */, + 2729346235A1EF46585A750ACC6F4126 /* ASBatchFetchingDelegate.h */, + D50F83AD1942253690114023E7CE92B4 /* ASBlockTypes.h */, + E8FFDB3A91E0FACEF3DDB279AD37CF30 /* ASButtonNode.h */, + 92C807BC6495BAE35DE79649C8299695 /* ASButtonNode.mm */, + C18764D310DCB6C30034EB3C014E0109 /* ASButtonNode+Private.h */, + 9088145837DA903D0C458572E6EF9C58 /* ASButtonNode+Yoga.h */, + DE98C566C001F35E47A53562D425064B /* ASButtonNode+Yoga.mm */, + 142E661BE19C27497AF8807710A34D02 /* ASCellNode.h */, + DBE5E5CF4C0125FBD1052D5DA0FA70CF /* ASCellNode.mm */, + 6D233C7E013C07D0389984F3466CB2AE /* ASCellNode+Internal.h */, + 7001D920A126D34017D9904AFB7E7953 /* ASCenterLayoutSpec.h */, + 47B21A7594492D19411EB2B50736A93B /* ASCenterLayoutSpec.mm */, + 4511DC1ED7A4174E351EB4F214894AC1 /* ASCollectionElement.h */, + B34FE789AA0085844B00920EA8ABD869 /* ASCollectionElement.mm */, + 9D4F5A26F434E2EAAE82328C892FBD1F /* ASCollectionFlowLayoutDelegate.h */, + 2BA01D0006D36A0A50DA88B677CAC904 /* ASCollectionFlowLayoutDelegate.mm */, + D3E3CB0CBCFA59CE439FF53F8006C3D4 /* ASCollectionGalleryLayoutDelegate.h */, + 37E5CD5480F273CCD7018C4EFA617514 /* ASCollectionGalleryLayoutDelegate.mm */, + 9C5DB655C78F3CA1A91002A40F883065 /* ASCollectionInternal.h */, + 1C2812E8C508184CDBAF31A4379A5723 /* ASCollectionLayout.h */, + 75555F5FF44B7570151D3E07C14B9091 /* ASCollectionLayout.mm */, + 1D30461653DA6AAEF282297EADDE6C6D /* ASCollectionLayoutCache.h */, + 3F1C5EEC6A9FC7250D38B875AF12D067 /* ASCollectionLayoutCache.mm */, + CC905E638224A0B0E664476444B10514 /* ASCollectionLayoutContext.h */, + 9C22693BC29DF70A295F36C2C6CE01D4 /* ASCollectionLayoutContext.mm */, + AEFEFAA3AC9FF06B1F868CF0C07B6C39 /* ASCollectionLayoutContext+Private.h */, + 408A5ACE5EC400AE7CEBD7C6338B76F5 /* ASCollectionLayoutDefines.h */, + 468BEF0C99D14026C3FCCE9045D3FE0B /* ASCollectionLayoutDefines.mm */, + 89EA7BCC1CA29B222E7DC77185E5C1CA /* ASCollectionLayoutDelegate.h */, + 17C0F831AF0AD17DC6B683449FD9CC26 /* ASCollectionLayoutState.h */, + 86164D80FD547DBCDC04ACDD06E541B5 /* ASCollectionLayoutState.mm */, + D5AB57FF552FD673BCFA9C23733069E1 /* ASCollectionLayoutState+Private.h */, + 22D109FC09C04222622A33E7750D7643 /* ASCollectionNode.h */, + 19F6B2C5C172044761158C11A9A96621 /* ASCollectionNode.mm */, + 5F45FF692CB5E624BFFD980CA029E126 /* ASCollectionNode+Beta.h */, + CDDA219ED517C33E1056E0948A145ECB /* ASCollections.h */, + 2C3E4D9221467A6AE8193D74B696E4BF /* ASCollections.mm */, + 409C4A8ACE8739BE0634656BDA26878E /* ASCollectionView.h */, + 1697C102E28F0ADF18FC253681444445 /* ASCollectionView.mm */, + BC90C657CBDF1FAC23AE4269E0F58A3F /* ASCollectionView+Undeprecated.h */, + 761330E4F43F9ADCCDA54B430683FEE6 /* ASCollectionViewFlowLayoutInspector.h */, + 34E1BFF37B6AB67835029387BC31D4C3 /* ASCollectionViewFlowLayoutInspector.mm */, + 18F1BEAE413D70F9613D56431D07F05C /* ASCollectionViewLayoutController.h */, + CEA532B0E1FFE30D664CFBE7878662F9 /* ASCollectionViewLayoutController.mm */, + 19C46A1F5BE9058D1B31FEFC6B3EEC63 /* ASCollectionViewLayoutFacilitatorProtocol.h */, + 12980397AA04450775600F72E475AD3C /* ASCollectionViewLayoutInspector.h */, + 953AD4EF877BF93E174279ECC0B1D89F /* ASCollectionViewLayoutInspector.mm */, + 1AB0436DEE011645CA194E623E6C08C5 /* ASCollectionViewProtocols.h */, + 2FBDA1D7FC21A68B8185A1567B2052E0 /* ASConfiguration.h */, + 2F5C8DE6CFB8EC60F48B06A6985E2BB5 /* ASConfiguration.mm */, + 7A48A5E4ED7ED7758E6885FF2C6A8189 /* ASConfigurationDelegate.h */, + FA82910B21B45CA35C2E513D8126CBA5 /* ASConfigurationInternal.h */, + 57A3175B4809F18AD11501B59B1C4D9B /* ASConfigurationInternal.mm */, + C6F40F1552ED00CC77D7799621E479C8 /* ASContextTransitioning.h */, + 803B09D806B71B6D194635CE75C342F9 /* ASControlNode.h */, + BE7824C8E50170F8A0526B9205882F3B /* ASControlNode.mm */, + 39AAA51020546A6E36D2E221A7CFEAA4 /* ASControlNode+Private.h */, + 3827902523392E04E0D92EE4073D9308 /* ASControlNode+Subclasses.h */, + 5CBF1A501D9D01565FC9A9FA7C2F0260 /* ASControlNode+tvOS.mm */, + E3F88046DBCA3A2EA1314244D40E4317 /* ASControlTargetAction.h */, + E998BC7957EE5F98E6C31919CCAE829B /* ASControlTargetAction.mm */, + 4DF39BEE8B1A3AA7DE7BF57F9E71C5EB /* ASCornerLayoutSpec.h */, + 12FC3E52F0ECF3D85BF407DE1BA0C960 /* ASCornerLayoutSpec.mm */, + 923B449EB1487E6024A361F239600946 /* ASDataController.h */, + 38DCEAAC959C2F8E5E2B80424211C42A /* ASDataController.mm */, + 306C52DBD27D295784295FD504964C94 /* ASDefaultPlaybackButton.h */, + 7CB9C9311AA6D37B9C029A0C12C4B4E7 /* ASDefaultPlaybackButton.mm */, + 595AC5EED6C4EC88217327C18B6CAC62 /* ASDefaultPlayButton.h */, + 6F57D723495FFB4BA8278626AE81835B /* ASDefaultPlayButton.mm */, + A52E2451F6B76F104A42C6B6EBABAC0E /* ASDelegateProxy.h */, + 220D778DF6D3BB45E14EF18549516AF7 /* ASDelegateProxy.mm */, + FC6C539347674A43A36A914B13136CF0 /* ASDimension.h */, + A2FC73F1B141C088A7A71E3189F506E9 /* ASDimension.mm */, + FAC0FF9654DDE91AD4E6B491A1132129 /* ASDimensionInternal.h */, + 1556D6D5C310D21F1F6570B9AAA70140 /* ASDimensionInternal.mm */, + 42BE1A9D7E289850DE3E3703B8B59B2E /* ASDispatch.h */, + 1B5474379A62711C3A3090973FF8C323 /* ASDispatch.mm */, + 3EEE47F5587BC9E53C27A71C7BE04F1F /* ASDisplayNode.h */, + B68757212BC40EE9FAA2CCF6917D014D /* ASDisplayNode.mm */, + A09FF82F01D38B1FBEA2718AEE09F391 /* ASDisplayNode+Ancestry.h */, + 9556208FA82CB1183791FB5EB2A58D5F /* ASDisplayNode+Ancestry.mm */, + 82F2FC1618232C6338E87A6A00200C50 /* ASDisplayNode+AsyncDisplay.mm */, + 31504EBDF705C4C91C4E481E42167F36 /* ASDisplayNode+Beta.h */, + DC0B6D34284EEEC294A8BB6750F6173E /* ASDisplayNode+Convenience.h */, + AF1305A2D3148FEB652C18D895431362 /* ASDisplayNode+Convenience.mm */, + 40D046AE2D842A61F6773318B2AED5EF /* ASDisplayNode+DebugTiming.h */, + 90EA83CDB56F528D679D861D7FADF2DC /* ASDisplayNode+DebugTiming.mm */, + 168588F383395609A225C17729EADFE8 /* ASDisplayNode+FrameworkPrivate.h */, + 21431E3065B17D68BBAC5602987EEF90 /* ASDisplayNode+InterfaceState.h */, + CA697F21425C3FDC3FD77AF6CA5A1E37 /* ASDisplayNode+Layout.mm */, + B3C8F3A4509640386CCC3F9E5A843E10 /* ASDisplayNode+LayoutSpec.h */, + 9DADFC8D98A3FEE0083A1D8E2A124F0B /* ASDisplayNode+LayoutSpec.mm */, + A49EDF562F5CD661061E25A7EC26B58C /* ASDisplayNode+Subclasses.h */, + 092BA4C0B35FCC3C7EDF8A310EADD496 /* ASDisplayNode+UIViewBridge.mm */, + 7406A55AE2F314560B18CF0D1F166146 /* ASDisplayNode+Yoga.h */, + 3A0D3879E96DD88097B82C514252031F /* ASDisplayNode+Yoga.mm */, + D4E478F22E41312C2EE4D3F570D425EF /* ASDisplayNodeCornerLayerDelegate.h */, + AD9ABC06E9F1438A47B1B873A9BF1FC9 /* ASDisplayNodeCornerLayerDelegate.mm */, + F2C1DB9479499FE9B70BDD375E242A22 /* ASDisplayNodeExtras.h */, + 67856706A15072A489163BBFBED7EF43 /* ASDisplayNodeExtras.mm */, + DF6BA3DB4965D0F13E4DF91222F3D9E4 /* ASDisplayNodeInternal.h */, + 371B020D432D68BA6D7638A16BE2D91A /* ASDisplayNodeLayout.h */, + A0F896E241CC0E46B053F5953BCCC504 /* ASDisplayNodeTipState.h */, + 796DC49204A7543AA048026D7A6B67AF /* ASDisplayNodeTipState.mm */, + DD1CF1EC74DC9F3B2DB54518639BCC57 /* ASDKViewController.h */, + ADDB82741AD2FBDEE3C9C44C84A11380 /* ASDKViewController.mm */, + 7BBE389DE054D871BA72D30EF0A95A02 /* ASEditableTextNode.h */, + C14B8C1CB8961F309BF9D6412F088BAD /* ASEditableTextNode.mm */, + 51712480D4DC2E936F5A74EB8E97FF76 /* ASElementMap.h */, + 52202AAAF785699FB3C841AAEB80C544 /* ASElementMap.mm */, + 9B2FC7355BCE92FE29D5BE9B82EA04A2 /* ASEqualityHelpers.h */, + A4E31B166F2E3EE17BA52F79751D6ED5 /* ASExperimentalFeatures.h */, + A85BDA95A647F56CD7259E121D6FA99A /* ASExperimentalFeatures.mm */, + DC3967FE11381864148284469B3951BC /* ASGraphicsContext.h */, + 19013B6B61D3353D8B1996BC41ED22EF /* ASGraphicsContext.mm */, + 5F11697E2E11491618C74B039E70FF8D /* ASHashing.h */, + A7E2AFAFBC59C4434EA0F452218F8C42 /* ASHashing.mm */, + 97E777762D92CC607C25F3EF65BEA975 /* ASHighlightOverlayLayer.h */, + 5DA54E673A5C3F5C8521C04A015E4A9C /* ASHighlightOverlayLayer.mm */, + BA36FE7BA8C83C8B594E50029C928965 /* ASIGListAdapterBasedDataSource.h */, + A3139E8FDADE2AA15C6B526F491D387D /* ASIGListAdapterBasedDataSource.mm */, + CBA1CDFAC330F024F79F55928AF761B0 /* ASImageContainerProtocolCategories.h */, + 340A9CEE164056E549AB70B491ABB841 /* ASImageContainerProtocolCategories.mm */, + 370CE66493F16C4B60162BC899D50685 /* ASImageNode.h */, + 6A7F6539EFE7A2DEBB6CFE6B7C4F7BE5 /* ASImageNode.mm */, + 760CAD4BE95145071691BD6C8BEAA67D /* ASImageNode+AnimatedImage.mm */, + 43DCE70B2460DEDE2FD73D6A661057E2 /* ASImageNode+AnimatedImagePrivate.h */, + EE7A1B087B94691BF730791439BE3281 /* ASImageNode+CGExtras.h */, + 3D3E8FFD05B04AEC48C46759AA2FC4E3 /* ASImageNode+CGExtras.mm */, + 0813AB2B539FBB3C7172EC17D1183DD9 /* ASImageNode+Private.h */, + E936B1B04FFAF35C7B129A8753B7710D /* ASImageNode+tvOS.mm */, + 9E362247576ABDCAC95FD27020FA954B /* ASImageProtocols.h */, + 2948BC247C32FEAEBBD7ABDF5868196D /* ASInsetLayoutSpec.h */, + 08C5161AA3E2ED418F8D43129A259B24 /* ASInsetLayoutSpec.mm */, + 0D754AB94C11E710749C06408EC6AD11 /* ASIntegerMap.h */, + 88F59C80E030B1D3C2C1D47FFBB972AA /* ASIntegerMap.mm */, + 2DADF593FC3453A7056F179131A40785 /* ASInternalHelpers.h */, + 372E2B51845B9764F1568E5E09EF43FC /* ASInternalHelpers.mm */, + A2CAEDFAB34F305AE5494D35EA368453 /* ASLayerBackingTipProvider.h */, + ED6036BDF81C2EFDD33A26E96FF6AFF2 /* ASLayerBackingTipProvider.mm */, + A289C7402C699BD2D20E8279A1D473D7 /* ASLayout.h */, + 9B0C5AF838B291A38952B93A37CA6D83 /* ASLayout.mm */, + 5018A23014FEB83B19C3753F33FFEFC0 /* ASLayout+IGListDiffKit.h */, + B21D04D0712E0F8DFD37114AD104DB83 /* ASLayout+IGListDiffKit.mm */, + 265855D3D2AF279E97701DA7779E70A3 /* ASLayoutController.h */, + 714C8766D214CF2BDDCA14DB63D82CC2 /* ASLayoutElement.h */, + CF97BCE466D911620708CE0E0D8EEA45 /* ASLayoutElement.mm */, + 42EC66579E3600DB1C45F90542FFCF49 /* ASLayoutElementExtensibility.h */, + E8A9CD8D77D91D235463968FC1DAEDE0 /* ASLayoutElementPrivate.h */, + 368616C4DF8B8A2508BCA3C152DE6171 /* ASLayoutElementStylePrivate.h */, + EBBC13C1697AD5A79814942839EB3BE6 /* ASLayoutManager.h */, + 898DCAC1CFAD91697899114511875124 /* ASLayoutManager.mm */, + CE226A57A895770566512D114E6BFEB6 /* ASLayoutRangeType.h */, + C032C2C59E35E90D29510094FA3BAF62 /* ASLayoutSpec.h */, + 13E6CB8779192BAEF893B4437244A36A /* ASLayoutSpec.mm */, + 9265300B5E28071C901DCD8848EDAF35 /* ASLayoutSpec+Subclasses.h */, + BEB872092B992DC253680FAA0499FE5C /* ASLayoutSpec+Subclasses.mm */, + C7EB412042D3B0B82DDB17C56280EA20 /* ASLayoutSpecPrivate.h */, + 85C3AB3ED77627F864E584556D9B3B4C /* ASLayoutSpecUtilities.h */, + E9206743DCC6A30DA6327E9E79F04B39 /* ASLayoutTransition.h */, + 6B22A6ED73746F28404AF31C57E32E29 /* ASLayoutTransition.mm */, + 738E3C383FCEEEA646A90093F39D90DD /* ASLocking.h */, + 13B363B9CC87A3361E75819CA2B9289F /* ASLog.h */, + 6FA0AF584416D60BE3C121B151A81600 /* ASLog.mm */, + FD5B4CECF91B0EEB87A10C231F414D2B /* ASMainSerialQueue.h */, + 326EBDBAEB04836A41AA1E86991F8885 /* ASMainSerialQueue.mm */, + FFBC5C72774055D3AC41F455A190BA47 /* ASMainThreadDeallocation.h */, + B0C21DADF77FC6BC3F01C866041F4B12 /* ASMainThreadDeallocation.mm */, + 9445659F6DDC49F7C027607DDB4B67FB /* ASMapNode.h */, + AC76142E2ECD50C70F0A3150606B27D0 /* ASMapNode.mm */, + 017310D7700BEE6573A7BA14FD8BDCD1 /* ASMultiplexImageNode.h */, + 41FA311245598CBA5457902CA98F6E61 /* ASMultiplexImageNode.mm */, + DDEF3F1193C7C7E6815D0965E430ACFD /* ASMutableAttributedStringBuilder.h */, + C250DF90BD78A3A463AF8A46C191D656 /* ASMutableAttributedStringBuilder.mm */, + 8A98596125EEEC4B752CF6D26D39B317 /* ASMutableElementMap.h */, + 9F1B1FC6DB693AE9866C6A07C199E430 /* ASMutableElementMap.mm */, + 52594DD4EB49DC177D64B179999D001B /* ASNavigationController.h */, + 3FB144D267D64DAD5769709D3C613A09 /* ASNavigationController.mm */, + BF5302E3309861B195B9B558D3E4869F /* ASNetworkImageLoadInfo.h */, + 848FD9809F9E6E909227DBA5454D0642 /* ASNetworkImageLoadInfo.mm */, + DDDD167A6A9C02AB6892A227DA6B537C /* ASNetworkImageLoadInfo+Private.h */, + 17739224B8FFBBFD4A919676A9DB5B99 /* ASNetworkImageNode.h */, + 8C41426A4CB5C87B270CAB6661B145AE /* ASNetworkImageNode.mm */, + 4503752DE626CEFFDC467B93D6760868 /* ASNodeController+Beta.h */, + 288309C0A0B85677861ECC27CE99504A /* ASNodeController+Beta.mm */, + A639AABF7D211E360C74CE4CC936E311 /* ASObjectDescriptionHelpers.h */, + 3B5DD44288F18DA76B04EEA1C33CB9D3 /* ASObjectDescriptionHelpers.mm */, + 56F9B8B1351E3504AA1167C5A3F2B8E5 /* ASOverlayLayoutSpec.h */, + 96D07D4CC3912A46A18D147E14F42FBF /* ASOverlayLayoutSpec.mm */, + 9C976C49525F404BB47056D7ABA4E4ED /* ASPagerFlowLayout.h */, + E3D2C16A2AE576BAE4EEE64B5C6ED5FD /* ASPagerFlowLayout.mm */, + EED6E5D64A260BBC73D89EAC4EE5A380 /* ASPagerNode.h */, + 40FF8F46258CC48006CE98E0E8C827FD /* ASPagerNode.mm */, + D0B846671C568323E113112E28C84E3A /* ASPagerNode+Beta.h */, + D0319B8963465C591687AFFE645BC7C4 /* ASPageTable.h */, + 48DDC75CC866EBE491AD3724F92861C6 /* ASPageTable.mm */, + D6EBCABE6BBB30D4231E0B246B73ECE8 /* ASPendingStateController.h */, + F701E64DB403DD2CAF9D8004138DF2E6 /* ASPendingStateController.mm */, + 9E360A0A97628D2F2F2CA7508A2A54DC /* ASPhotosFrameworkImageRequest.h */, + 3E886463829E8179D30A3CC87E9F971C /* ASPhotosFrameworkImageRequest.mm */, + 56A4DCB09556D8E69491C29B81F6717E /* ASPINRemoteImageDownloader.h */, + 97CD5B552AABAF73943AE088CCB7BAFA /* ASPINRemoteImageDownloader.mm */, + C74FC41E348067EE93ED92F12742298D /* ASRangeController.h */, + 1F3CBC9D77FD5B66D00BA89359E50FE7 /* ASRangeController.mm */, + 6ABCC1E22FDEC639E66D76B27F1C5922 /* ASRangeControllerUpdateRangeProtocol+Beta.h */, + C49FC0A2F8D7B1D6EA3AF666E636C296 /* ASRangeManagingNode.h */, + 91BFC03CE4B616D14105ACD4A4486EC1 /* ASRatioLayoutSpec.h */, + 773C92C3B53030CCB6156F70AC47231C /* ASRatioLayoutSpec.mm */, + 153CDAA7E2893700C4226503B3F7E0CF /* ASRecursiveUnfairLock.h */, + 6D7E831DD0A378B5BBA9E3EB6ACC1B49 /* ASRecursiveUnfairLock.mm */, + 47D53418A1AF4E0E9F8A9A6A6E85FE2F /* ASRelativeLayoutSpec.h */, + A6C94B27A14D01BA956D86F321DBFF8F /* ASRelativeLayoutSpec.mm */, + E7883E00BE5AA81AAE8BD1C5407224B2 /* ASResponderChainEnumerator.h */, + BEA709AB9B51E31AB78426C3BC827746 /* ASResponderChainEnumerator.mm */, + 7194F334C486D84103D8B7F489484B85 /* ASRunLoopQueue.h */, + 6AA80045BD16B35CDB5DE468DF1034F6 /* ASRunLoopQueue.mm */, + 90697248975C12C20D265C8FC2F89492 /* ASScrollDirection.h */, + 08256B415C39B30BF9ECE1264B713481 /* ASScrollDirection.mm */, + A546884224C6ED423FD4E6E7883B3077 /* ASScrollNode.h */, + 46CD0F5DE0D2F59A5681151F4D1EDBC1 /* ASScrollNode.mm */, + AAE59626849BEF2264FC9EB98B2EBDB3 /* ASSection.h */, + CC85FED712EC5B803BB64410FA1944AF /* ASSection.mm */, + A1D0D3B5F98B76FBBF66FBC689B55B7F /* ASSectionContext.h */, + F2C21DD7FDAD82793DA6912B527CCA8A /* ASSectionController.h */, + E70BC18B679C8A3330AAB74EC44E137B /* ASSignpost.h */, + AC262B220308DD0BE3539DADEF6A984D /* ASStackLayoutDefines.h */, + 8AE225CFAAB0B6186AECCF6530A1C315 /* ASStackLayoutElement.h */, + 0DC49CAEDA64A6918B1C646A7903EE50 /* ASStackLayoutSpec.h */, + 3A7A6660529033C8FB462698E66D5056 /* ASStackLayoutSpec.mm */, + 3EAF61F88391C9B13AB0AE7D2ABB1CDF /* ASStackLayoutSpecUtilities.h */, + FA621A2A3717016D8818217BBCE87FF4 /* ASStackPositionedLayout.h */, + E0B89AC0CDBA02149E8DFBB8ACEAF0CB /* ASStackPositionedLayout.mm */, + 4E68C30C5EACF8A5292490A67CA0F259 /* ASStackUnpositionedLayout.h */, + 631EFD7F1F37EB5DE9EBBFE915A49FEE /* ASStackUnpositionedLayout.mm */, + 6CFFF44F0A0757458B152AA0C8E5E1AA /* ASSupplementaryNodeSource.h */, + C6EEB10F62EB74DDAFD182C55A257738 /* ASTabBarController.h */, + 4CD3F57888B836CD8BBDEE5A0761834F /* ASTabBarController.mm */, + 53F754CCB8549BBB25671573986F6C65 /* ASTableLayoutController.h */, + E55325CF18F732FB37081F750E0577E4 /* ASTableLayoutController.mm */, + DAE31B940FABACE013CA45FF2FDC046B /* ASTableNode.h */, + 5D5C12E5C2E7EDA156BB9B2EE42C1683 /* ASTableNode.mm */, + 39628548B97DE9F4CF62A1084EFDC199 /* ASTableNode+Beta.h */, + BE54CB3D9126A0A4E84D9DA6BD4293D0 /* ASTableView.h */, + C2AFE0C39F1F92051B063681E2F546D3 /* ASTableView.mm */, + F8B91C4F2D81045D14D0886080099732 /* ASTableView+Undeprecated.h */, + 5E621B2AEB638A986D4D7B368348FB9F /* ASTableViewInternal.h */, + CAA9D4CFE9C5A4813A54148D6F1BEB6C /* ASTableViewProtocols.h */, + 1B000E5335F1D299484CA411EAD77450 /* ASTextAttribute.h */, + 1E3FE85A4B2BCDA182B605CDB5DBB8DB /* ASTextAttribute.mm */, + 012FFB5866BEDA74EBFDE3FF86B46104 /* ASTextDebugOption.h */, + 9CB12185681B73727DC1273F336BFD9D /* ASTextDebugOption.mm */, + 238638299CCBABB2A4FA0768A080732E /* ASTextInput.h */, + 152968521F92B8C3F6F5427C21D3C73C /* ASTextInput.mm */, + 8645412BECF2A0A622A033A39E216975 /* ASTextKitAttributes.h */, + DE1F7FC0245A875D45AC0863A15BD969 /* ASTextKitAttributes.mm */, + 9F713CCF7949E74D4E972F737A6788BE /* ASTextKitComponents.h */, + B86953550C8475069C247A7C7039CC61 /* ASTextKitComponents.mm */, + A9434A1F46A9E3864CE96A3F43924782 /* ASTextKitContext.h */, + 8C92A50FED85091B4E69170C3E055C0C /* ASTextKitContext.mm */, + 915AA3BE58BFD111EC7114C0CB67E360 /* ASTextKitCoreTextAdditions.h */, + E00E407AA304E669975F496CDE757534 /* ASTextKitCoreTextAdditions.mm */, + C158E5545E3BD2D22EB64B23FBED2C7E /* ASTextKitEntityAttribute.h */, + 8326C4C67628C534D2FB0AC51B6CA084 /* ASTextKitEntityAttribute.mm */, + 36E00A3E64E6BBD8E773493B48077674 /* ASTextKitFontSizeAdjuster.h */, + EE6B4FA98E3B71705FE19CC355592CD3 /* ASTextKitFontSizeAdjuster.mm */, + 8E8DE6B6E689A78CB6F2E92F79BEC7E0 /* ASTextKitRenderer.h */, + 8A3377EFCA934EA4647740466F62D987 /* ASTextKitRenderer.mm */, + 46C1ADF815AD1AC88EAD0E635BB938B9 /* ASTextKitRenderer+Positioning.h */, + D37EA35A7EC92AF0C4C89CB9055045D9 /* ASTextKitRenderer+Positioning.mm */, + D2D0DD2A8BC4A91FDFB94D2232DC0252 /* ASTextKitRenderer+TextChecking.h */, + 15E4F72EFEDBF482E6EA7FC3C9B045BC /* ASTextKitRenderer+TextChecking.mm */, + CC9F7354BB576AE97ADD36345C6980E2 /* ASTextKitShadower.h */, + 7C8F79D8FCF9015BF86D560DE3589B65 /* ASTextKitShadower.mm */, + 780C4053DCDEF3BE175B88490A56D53D /* ASTextKitTailTruncater.h */, + 59576C4206771C56B34C93A2DD701D91 /* ASTextKitTailTruncater.mm */, + 11243C7D597D928BACF6593432FFCF01 /* ASTextKitTruncating.h */, + 633114E3879F0F946FFC6622C69D9C57 /* ASTextLayout.h */, + C8AF5F4BB16D9D38E6011A150CF1DC25 /* ASTextLayout.mm */, + 1EFB738992A1ADC2BE3751D558350E17 /* ASTextLine.h */, + DDCD3C215394710BFCE24A682B80FD0F /* ASTextLine.mm */, + 3A1161DF44833F8207702FDDDADDC190 /* ASTextNode.h */, + EA0B213E1618F546074778126A6A7EBA /* ASTextNode.mm */, + 9DA27E6D1F06A57F16EC910BF9212642 /* ASTextNode+Beta.h */, + 614DA3C78C8C5DFC5E9D4AE0CE7BFF7C /* ASTextNode2.h */, + 84CB3A49900E50746B7BBE91B3975FA8 /* ASTextNode2.mm */, + 0D800D50130BA0F8D82C5558F54DDF7B /* ASTextNodeCommon.h */, + 7096E0A9B680A32ABA967518D12A789E /* ASTextNodeTypes.h */, + DA4E05471B629E5426D5E5F9A38C11FF /* ASTextNodeWordKerner.h */, + A3824C2887A3C7EC685E7EF3070F9A4E /* ASTextNodeWordKerner.mm */, + 6950A957CBC973B8CCDA5898C7B8DA83 /* ASTextRunDelegate.h */, + DCB893AAFE47BD80E8CC7CC44A00CD56 /* ASTextRunDelegate.mm */, + 806DDF999DDE3AAC2ABC6FF9CE3E5B8A /* ASTextUtilities.h */, + 738C0D498805A7D7930418DE87AC4F5E /* ASTextUtilities.mm */, + 23A34852D7571C40B1F57F6978C437C4 /* ASThread.h */, + 0A25DDB1BFA6A6D466803A5137028A77 /* ASTip.h */, + CEA675A20EAE7B49521E742D5681B170 /* ASTip.mm */, + 0B11BD730349E9A6BC10FD9485AABFE8 /* ASTipNode.h */, + 550B11CBF85493C4523215E0EA060AAD /* ASTipNode.mm */, + A32CFB4D17BCD23C29D1D5787CE32EF3 /* ASTipProvider.h */, + 7B1FFF4BE75E530F7F98CC130B827756 /* ASTipProvider.mm */, + 411BC26AEB991FC58D93C8947E77F4BE /* ASTipsController.h */, + 2C042B669A64064D7FC3E52DEBA0E071 /* ASTipsController.mm */, + 5A6FAD6EA5CF728CE7EC0668E10C7324 /* ASTipsWindow.h */, + FE5C5EA569981CB127DA87B026FAE639 /* ASTipsWindow.mm */, + 0F59C6A23784A24F14DF9A84E27DE123 /* ASTraitCollection.h */, + 8BD494C55125932909BE35FA36C3C97B /* ASTraitCollection.mm */, + CD82409E784C5B82AFCB8E3B4B899B32 /* ASTwoDimensionalArrayUtils.h */, + F2E4639A35242C5823DACB52A5054354 /* ASTwoDimensionalArrayUtils.mm */, + 73AC4D83CEDD69BA236A57352337FD54 /* ASVideoNode.h */, + FBA716F6CEBD4B6202124CCF837017B5 /* ASVideoNode.mm */, + E7F66832F49B3C0B4A07085F98189176 /* ASVideoPlayerNode.h */, + B5A3F7221807630DE3D0449E1D30FC1F /* ASVideoPlayerNode.mm */, + DC9C83426449CBC7979380EE2EC7A48D /* ASVisibilityProtocols.h */, + E47C6BB78AA408F7C35EF60421326F79 /* ASVisibilityProtocols.mm */, + 424205752E50C0BA7AD6C7C527C90AD1 /* ASWeakMap.h */, + 24D8C47FE0E7DA22CB28B45FF4DED726 /* ASWeakMap.mm */, + 93D192702C0F63552D3A3479AC17225A /* ASWeakProxy.h */, + 64331C191E00E170739F31033B58DE07 /* ASWeakProxy.mm */, + 43869A044BD5D3313051C1FB0FA1CC40 /* ASWeakSet.h */, + 9E2503BEFEB4448C0FA1DA31215EB7C1 /* ASWeakSet.mm */, + AF56F95269473FF68D4A9F83950E1E15 /* AsyncDisplayKit.h */, + 8E96667745230EA660158A21EACF1E3F /* AsyncDisplayKit+Debug.h */, + A2D83E80452A02F4E51C53E14432A3AF /* AsyncDisplayKit+Debug.mm */, + B9A1585DD0E56306F2329498432F63E9 /* AsyncDisplayKit+IGListKitMethods.h */, + 628632B58BF8798C5B49581ECE1D5BD1 /* AsyncDisplayKit+IGListKitMethods.mm */, + 924DB1E2EBFF6B95672DC515046ACE58 /* AsyncDisplayKit+Tips.h */, + 303F4D4B9D072C75B58EF0D2D7630454 /* AsyncDisplayKit+Tips.mm */, + C61A4B82B4BA5097E9F686A1948C1EFC /* ASYogaUtilities.h */, + C2E1EDF37D5C7392BCBCBC2626230325 /* ASYogaUtilities.mm */, + D0162762B4A4C18C34AF7BDF70585D4E /* CoreGraphics+ASConvenience.h */, + A2C7DF35D1B0CC4FC09821434405BCEF /* IGListAdapter+AsyncDisplayKit.h */, + C1269DFD61BDAA9D7616E24B0189FA96 /* IGListAdapter+AsyncDisplayKit.mm */, + 27CF84EEF4ECAF9F8FDB5259AB280B10 /* NSArray+Diffing.h */, + 56E6B6A59DD9BAA9AF2C4608AB94F0C1 /* NSArray+Diffing.mm */, + 53BF3551C5EE1DC95729A01E0E1632BF /* NSAttributedString+ASText.h */, + 6E1443385934C571269E9950D816D792 /* NSAttributedString+ASText.mm */, + 3518A0BB390B2AA90F7647C5B8E71E30 /* NSIndexSet+ASHelpers.h */, + F06F5857985D77588F3293CCCB51FC40 /* NSIndexSet+ASHelpers.mm */, + 30DD3DAFDA45E1C0E7B07DC0F2E7F0D3 /* NSMutableAttributedString+TextKitAdditions.h */, + 30A71EB2149D0A7CDCA3CA7E9039E3AA /* NSMutableAttributedString+TextKitAdditions.mm */, + 2800D748DA8B5242EEFED6AC2283901D /* NSParagraphStyle+ASText.h */, + F53D4B6F4C18BE99E9336EAE1707A8DE /* NSParagraphStyle+ASText.mm */, + 0F4227E8F62083D39A853A5913213842 /* UICollectionViewLayout+ASConvenience.h */, + 16A94C3E9D1D354B1FA7BFB225090329 /* UICollectionViewLayout+ASConvenience.mm */, + 444483F0B2D3A9B3C7257762F9297D60 /* UIImage+ASConvenience.h */, + C463CC735CC90CC6C36E6AF98D671B2A /* UIImage+ASConvenience.mm */, + D1D44D0CB5735DF9E0EF1C2ABCB9D3A4 /* UIResponder+AsyncDisplayKit.h */, + 721C9415CD678F2601E830BE4F543FBE /* UIResponder+AsyncDisplayKit.mm */, + 11F9C53368EC8719F7CD5EDC99DCD3B4 /* UIView+ASConvenience.h */, ); name = Core; sourceTree = ""; }; - 2CD8E879787766BA57718E7D32EE2F7E /* Classes */ = { + 457D693EBA1C7235BB0857B8664E22AE /* Zoomy */ = { isa = PBXGroup; children = ( - 1C957DCA2DFAE3DE735CBF4FF71F8C79 /* ImageZoomController.swift */, - 49405BF411A045F9971308FAA95292D5 /* ImageZoomController.Factory.swift */, - 114F5E4FAA06F5EB193F8331FF581260 /* ImageZoomControllerActions.swift */, - 751A5BF60BC5A9847C0C9673E8CF01D8 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift */, - 0CFAF1E8969912E3093CDAE51ABFB670 /* ImageZoomControllerIsNotPresentingOverlayState.swift */, - 4A2517A7943CC5A852D4396DD7B89109 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift */, - 84BCA78334AF16808277D2FAC66F02BD /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift */, - 29C587DED2BBD35B19E135E0E1AC63BC /* ZoomyLogger.swift */, + 07B52338B264853E539C9E6A6CD8F107 /* Classes */, + 33BAB025C28ACB0A07C2D0141F6F812E /* Enums */, + 4FB35CC0455D30CDB5AAE327FCE28819 /* ExtendedProtocols */, + 45E8C58CF81096FDDFD747382207FAC5 /* Extensions */, + BA25C412665B5A953935E26945E097F0 /* Pod */, + 775FF7B089A54C06A91CF75A2BE638AB /* Protocols */, + E52A0EE5D0BF8DDBE41E687CBC50CEC7 /* SharedInstances */, + F22E3557B1C250BA8BDCCC83C98CAA97 /* Structs */, + 3C9BF88808D009880EEFEEB1AC65068E /* Support Files */, + CB217531456694B41E9A8C0D5C6F1591 /* TypeAliasses */, ); - name = Classes; - path = Zoomy/Classes/Classes; + name = Zoomy; + path = ../..; sourceTree = ""; }; - 3104EAF2841F590DE0976E1959532011 /* Extensions */ = { + 45E8C58CF81096FDDFD747382207FAC5 /* Extensions */ = { isa = PBXGroup; children = ( - EC547208CC428C4630ADEBFBA2A2BDAD /* CGAffineTransform+transformWithScaleTranslationCenter.swift */, - EAF935CFCE349E367CFD3CFE312B4EFD /* CGPoint+dominantDirection.swift */, - EBE5E3D5558488FDEAE33619126F1513 /* CGPoint+maximumAbsoluteValue.swift */, - 7433465CCEDABF6373CF6FC715F02577 /* CGPoint+valueInDirection.swift */, - 437A7EB85DC2C2F59274B60DA2238D0B /* CGRect+Difference.swift */, - 0D9DB88CFA4413907F47AD1A71EAE35D /* CGRect+transformedByTransform.swift */, - 1D982B7DE0FA01AF1D3A98523B0AD71B /* ImageZoomControllerSettings+Equatable.swift */, - 4E52B15796BB4A915D828880D8E9AA75 /* NSObject+AsociatedKeyForImageZoomControllers.swift */, - 577ABC84D61A466B9DC126551BCA72E8 /* UIGestureRecognizerState+CustomStringConvertible.swift */, - 417957CD232E64384DA98C2BA8ED91D2 /* UIImage+Color.swift */, - 0347E82F5AE84656ECD2CB86F0972084 /* UIImageView+Zoomable.swift */, - 53EB558A5AE8A80267886C93479C1753 /* UIView+layoutHelpers.swift */, - DB7B857F48C145A0BB64AE203A20EAEA /* UIViewController+CanManageZoomBehavior.swift */, - CAA043EEB04C16347822B57BAA117E2E /* UIViewController+HasImageZoomControllers.swift */, + 0ABEAEBF38D032F544B343E700443A9D /* CGAffineTransform+transformWithScaleTranslationCenter.swift */, + CA3C2F847A27247611C3DBD2ADB2A71F /* CGPoint+dominantDirection.swift */, + A0D66F0C5F3D4DD3B7CA386D3563C254 /* CGPoint+maximumAbsoluteValue.swift */, + C2A96E21690DBA5F5E4DD8C744A598A8 /* CGPoint+valueInDirection.swift */, + 276AB991EAC927FD7C3D0F3175E37042 /* CGRect+Difference.swift */, + E3DC378C69742B7E1C2A8D1B02460DB0 /* CGRect+transformedByTransform.swift */, + 1618D9D9C78605F98FD056F93E140550 /* ImageZoomControllerSettings+Equatable.swift */, + 06DDD98B42182B137D220784A22E6697 /* NSObject+AsociatedKeyForImageZoomControllers.swift */, + 96BAB84DDE20C8E79F0FFC7E5B015EDC /* UIGestureRecognizerState+CustomStringConvertible.swift */, + 27B7C9717F02B14FD5F36AA14557AB11 /* UIImage+Color.swift */, + 7C638CF5711825D56D2E5DF07B0F1D6D /* UIImageView+Zoomable.swift */, + 0DA4D69598D7C62D33AEA4FBDE19BCC2 /* UIView+layoutHelpers.swift */, + 695B0EF784C58FAC0A0A0275CFA6385A /* UIViewController+CanManageZoomBehavior.swift */, + 05091C81B06DA14E3F1E22B5438F6079 /* UIViewController+HasImageZoomControllers.swift */, ); name = Extensions; path = Zoomy/Classes/Extensions; sourceTree = ""; }; - 3E7D133135A9285D5DB5CE46D4F3FDD6 /* Core */ = { + 4FB35CC0455D30CDB5AAE327FCE28819 /* ExtendedProtocols */ = { isa = PBXGroup; children = ( - 7B8B564BFF8B5501803B1A4631A19657 /* PINCache.h */, - 31182033736429F714F11A99D15B5A37 /* PINCache.m */, - 2DEA1E8382A2B2C35A6C1A9EAC3A087E /* PINCacheMacros.h */, - FA100E34969B2131C471F94030FF7F28 /* PINCacheObjectSubscripting.h */, - DB46CE9E8985343894F642F0878128C5 /* PINCaching.h */, - 860C40113A4C6ADD6363A09B97EB2272 /* PINDiskCache.h */, - B8FC2C1E24D7F7723065F7C02EDB1715 /* PINMemoryCache.h */, - 3208DEBA29C56FF8EBA5563EFAB53B48 /* PINMemoryCache.m */, + 734F9C74F82633188225C4CC9C72FDAD /* CanAnimate.swift */, + 2BDB8103640F2CC1D67C9C58171A5E8D /* CanManageZoomBehaviors.swift */, + 4281A047ADE807364869D0EC4C706EF6 /* ConfigurableUsingClosure.swift */, + C9F7A8AFC48B5338B1D11FBEEE473EC8 /* HasImageZoomControllers.swift */, + 4012AE46C9AA9C1919E2A94BD8460C38 /* ImageZoomControllerDelegate.swift */, + 8A40BCD8285FC1DEF12569A10100C4C1 /* ImageZoomControllerState.swift */, ); - name = Core; + name = ExtendedProtocols; + path = Zoomy/Classes/ExtendedProtocols; sourceTree = ""; }; - 4B271EDA85BFA5465BA902C1A95405EA /* InjectableLoggers */ = { + 65EBDC89727160B14CBA9C21C4A800A0 /* Support Files */ = { isa = PBXGroup; children = ( - BC4DA700D665D4C0D110ACE8AAED6FB4 /* CanFormatMessageInFileInFunctionAtLineWithSettings.swift */, - 854C0BA85C5EBE5FC30BE62E6B85A1A1 /* CanLog.swift */, - 18EF9DB92D4E1F229060F5B5B0DDF41E /* CanLogAtLevel.swift */, - 1337D073335F7331614C588A0EEAAB54 /* CanLogMessage.swift */, - 0CDAA8013007AE7BA76340E480145741 /* CanLogMessageAtLevel.swift */, - 1033543310C731B9BF398A69B3587CE4 /* CanLogMessageAtLevelInFileInFunctionAtLine.swift */, - 3521512E9AA05650F6F76700EC1D65D9 /* CanLogMessageInFileInFunctionAtLine.swift */, - 14D5664BB8FDFB48A12DED4645631583 /* ConsoleLogger.swift */, - B9FB154DB28A1272A40CA2071CA41E71 /* HasDefaultLoglevel.swift */, - 8155FA2A18B7EFC15B8F6773207514EE /* Logger.swift */, - 06A281B1005F95408C915408AFB29679 /* Logger.FormatSettings.swift */, - 911A2B69447A9FA80318E2B59EBEE264 /* Logger.Formatter.swift */, - C8550F0BE91A5EAD479CBC31C1CC9D2E /* Logger.Settings.swift */, - DF0FE47D3163C04184775EB308246232 /* LogLevel.swift */, - CB0BAAC0ACC1784F708C88E5C8EBCC43 /* MockLogger.swift */, - BEAC1BDFD6524223CCD83E5EDC23DEE1 /* SimpleLogger.swift */, - DCADF277F8E0FE040B220E44C2285265 /* SimpleLogger.Settings.swift */, - DC969E6D5EE19A3224AE1EEB82058CDA /* Support Files */, + 0D6CDE01C9407A307C0579A9C1D7B913 /* PINOperation.modulemap */, + 6BA7F456BF4EFB86CEC78435D24C3393 /* PINOperation-dummy.m */, + 0C38088EF6E60B8FD72EFC5E2DDE25C1 /* PINOperation-Info.plist */, + EFB8D888E1320584A10E63E2737403F0 /* PINOperation-prefix.pch */, + 3405A596EC79FF405C0EBA48F483F456 /* PINOperation-umbrella.h */, + 522F7194EE4805844AF8037C5D463760 /* PINOperation.debug.xcconfig */, + 10C285230E7CFFE2A19F1963D1321A46 /* PINOperation.release.xcconfig */, ); - name = InjectableLoggers; - path = InjectableLoggers; + name = "Support Files"; + path = "../Target Support Files/PINOperation"; sourceTree = ""; }; - 5D6F07251A5D11B048518942F41F1B59 /* Core */ = { + 6B3A07B13F80F51615340DB5497DC1F2 /* PINCache */ = { isa = PBXGroup; children = ( - D23FE5069CB05E377F270A620883B989 /* _ASAsyncTransaction.h */, - F77132454B2BB691E5070FA6A0E46957 /* _ASAsyncTransaction.mm */, - 45732382F06CCCBEF2548090FD84E0FE /* _ASAsyncTransactionContainer.h */, - BB14945CFEBAC7BB06C3931211F933FB /* _ASAsyncTransactionContainer.mm */, - EA4F56FDA7A6B32FF3A7DB0EA0E30D9C /* _ASAsyncTransactionContainer+Private.h */, - 8B02FDCFBF0D352D4CCC5ACF96478DF5 /* _ASAsyncTransactionGroup.h */, - 79619D75C2722640361977842EF8C593 /* _ASAsyncTransactionGroup.mm */, - 6808266211BF925459BF96812FD61642 /* _ASCollectionGalleryLayoutInfo.h */, - D48173B3E33DB97A878FAA3E003BCE42 /* _ASCollectionGalleryLayoutInfo.mm */, - 5A4BBF35A5BFF3C8055E41FF8D16E77F /* _ASCollectionGalleryLayoutItem.h */, - AA3875A1795ED07E509FDD997F948597 /* _ASCollectionGalleryLayoutItem.mm */, - D31A98FCF7B961D3A00D60EA1953837E /* _ASCollectionReusableView.h */, - 5249F6990C1876E77A173D504374E85A /* _ASCollectionReusableView.mm */, - B42F164AEA1DD630EF5DB88F3E6546A1 /* _ASCollectionViewCell.h */, - E8EE8E285A79E86E91454D38BAA31F49 /* _ASCollectionViewCell.mm */, - CA6C4621E433A72E826090B170427229 /* _ASCoreAnimationExtras.h */, - 3728B36A01891C41B0E5AAC664EC09FE /* _ASCoreAnimationExtras.mm */, - 093258A51C5A055B7D4487D97D048C02 /* _ASDisplayLayer.h */, - 74903A67A4FAF9B14E31F4D571B27DFB /* _ASDisplayLayer.mm */, - 70ECAAA631B9C5458137845A17153DE7 /* _ASDisplayView.h */, - EFBD7E465FF5839A50DEEEE7A6A8AEE3 /* _ASDisplayView.mm */, - C9579AF5CF380A430E2296E21C0498ED /* _ASDisplayViewAccessiblity.h */, - D10C816C7692C03BB6F3FC1DB50EA606 /* _ASDisplayViewAccessiblity.mm */, - 77352767819B3F1506BB79361E5199A9 /* _ASHierarchyChangeSet.h */, - A2DA07ACA67D6E241C85078FE67F857E /* _ASHierarchyChangeSet.mm */, - ED8FA0390861FE0DF8871CD7F10DABFA /* _ASPendingState.h */, - 74F6A7ADB0BD1789A4271467B0355510 /* _ASPendingState.mm */, - 34C2E7C5F0F15FD412B6E90CE66616C6 /* _ASScopeTimer.h */, - 8C0888B5BCFB99062C58EB43E8AD7554 /* _ASTransitionContext.h */, - 5834B039278C6686064003CC4DF97395 /* _ASTransitionContext.mm */, - 041B4A598ADB602F7DCCBC8D326BBE3B /* ASAbsoluteLayoutElement.h */, - 6471DAF51E7A7C9B6CA4B243EA9D399E /* ASAbsoluteLayoutSpec.h */, - 3159FFF68D91838D2CC5D7DAA07DD14A /* ASAbsoluteLayoutSpec.mm */, - A566D0D02EDF7ADE78AD3563AC231EF8 /* ASAbstractLayoutController.h */, - 162A36187E75CC621EFD3DAA504D4BA1 /* ASAbstractLayoutController.mm */, - 8FDE745A011DD537BF75CF20625D7C2E /* ASAbstractLayoutController+FrameworkPrivate.h */, - 5929816D10F8DFF27EA0E163D3AF6351 /* ASAsciiArtBoxCreator.h */, - 20F81D70DF5D1073C6720482B6C22D53 /* ASAsciiArtBoxCreator.mm */, - F7B197008C37795CA80DA38516F408A2 /* ASAssert.h */, - DD3CADDF86084740EAE1184277C790BA /* ASAssert.mm */, - 7D05F80B69A6CAAC89037EC81A01CAE8 /* ASAvailability.h */, - 4AA4FC6584F3CD6AEA868108B7CA6DAB /* ASBackgroundLayoutSpec.h */, - 03C015688FA02187BD871480FC999411 /* ASBackgroundLayoutSpec.mm */, - 846F36BAF3041EB8ED21F54F6B9DE07B /* ASBaseDefines.h */, - 47887C414E19B0A79D466E48240E56AF /* ASBasicImageDownloader.h */, - 83079A844C816FE05A93291E7FA5196B /* ASBasicImageDownloader.mm */, - 02074016ADB05CBAFE0127B2661EB0AC /* ASBasicImageDownloaderInternal.h */, - FD73543F8F59FA39EB762F129AC023EF /* ASBatchContext.h */, - ADEAF002D779FE80DA13FE31725E5FCA /* ASBatchContext.mm */, - E9297A4D9C730E526E63A5654A200E28 /* ASBatchFetching.h */, - 1FBE0A2E9ED2D152CC1D9833F6C7A9C6 /* ASBatchFetching.mm */, - 1993B19AB3BDE5C6993A436E9862ED6C /* ASBatchFetchingDelegate.h */, - 09A492A5EDB688BCE2C833245EA50EE8 /* ASBlockTypes.h */, - 0FD60A2E7EE5CFF2D707B5995C946BC1 /* ASButtonNode.h */, - 76D2AC89B328615BB7546EA1E9E047D5 /* ASButtonNode.mm */, - 2FF0E128FF2A7195FA58FADEB2B67B78 /* ASCellNode.h */, - 9534DB6C12F7A203D038C860278C69B2 /* ASCellNode.mm */, - 7B2C8E75862CFCA96FB97B2D340B2600 /* ASCellNode+Internal.h */, - 999ABCA7921CDF37F8B7B19411E1084D /* ASCenterLayoutSpec.h */, - 99E23194CF8E8F54AF09B96E09EFE9FD /* ASCenterLayoutSpec.mm */, - 97E41C83A55213B5CA3787B8C3A4CA01 /* ASCGImageBuffer.h */, - B34887E975D5A8E86DCAEB7D3EC54B38 /* ASCGImageBuffer.mm */, - 68B678E30769470CE9F5F7EB95D5A260 /* ASCollectionElement.h */, - C77B159A3B34D6119258725CE283719C /* ASCollectionElement.mm */, - 4738C3EE9ADB91DAF08960FDEDE3D702 /* ASCollectionFlowLayoutDelegate.h */, - 67D1F9A6121EE2D97F3C6002FB464798 /* ASCollectionFlowLayoutDelegate.mm */, - A32221AE94CD1425D9F2E1F183BBC001 /* ASCollectionGalleryLayoutDelegate.h */, - EB5705798083744EEEEB7CE058B58C09 /* ASCollectionGalleryLayoutDelegate.mm */, - E4787675C54E05A8E87785A4179A5048 /* ASCollectionInternal.h */, - 34B72E8FAB374BBB6BA3BC734730D1B8 /* ASCollectionLayout.h */, - D49499B1B65785F2A7C1C4CD99765E4D /* ASCollectionLayout.mm */, - 5725152FA9CBD3409857DF7D14892C1D /* ASCollectionLayoutCache.h */, - C47D135FDC8D2FF911DEA2FC755D8C75 /* ASCollectionLayoutCache.mm */, - 9C8C5E2FFC7D7BAB935A72ACA952F4B7 /* ASCollectionLayoutContext.h */, - 8BF6A75BC54E75526F8E7A07BDED4AD6 /* ASCollectionLayoutContext.mm */, - 34264FCFBCD166A0BE6E3B41DBF13876 /* ASCollectionLayoutContext+Private.h */, - 47BEA003F98AF411A6A7DF57679996D9 /* ASCollectionLayoutDefines.h */, - 06679FB2C6525803A57E1ABF62E2AE5B /* ASCollectionLayoutDefines.mm */, - F378A66FF19F87E754731A02F1D8352E /* ASCollectionLayoutDelegate.h */, - 9698D9EA7BD19EB23AB3EAB57A993843 /* ASCollectionLayoutState.h */, - 05641F15444EBE2BE289D9C02E82E530 /* ASCollectionLayoutState.mm */, - A98A5F46B2F5435F186701CCADD6D4CD /* ASCollectionLayoutState+Private.h */, - 3EE6623F7681F2A64EA741D31CCF2563 /* ASCollectionNode.h */, - 22D04588E915CA87458FE8343D2779A2 /* ASCollectionNode.mm */, - E13F304F25BDA4F5138C786C6D8541C3 /* ASCollectionNode+Beta.h */, - 8612405434DF8846A00ADCFE8E364394 /* ASCollections.h */, - A38C44A24E481D727A9C07A5CA684514 /* ASCollections.mm */, - F8E01445D32DABC80642FEC5993BD8A7 /* ASCollectionView.h */, - 937DE4AA07CF005B3D3E13301EDEDDAF /* ASCollectionView.mm */, - 7DA44FE89D4C0FCD5F37208DB3FA170E /* ASCollectionView+Undeprecated.h */, - DE70B4985D2139726F4E0BC1FE545A58 /* ASCollectionViewFlowLayoutInspector.h */, - E19DB721C1C7526CC7059B683149A992 /* ASCollectionViewFlowLayoutInspector.mm */, - 264EC3CABA35458466AEC4B4DACC46AA /* ASCollectionViewLayoutController.h */, - C745ABE5CF7074BDCB56E1DF0CE7481C /* ASCollectionViewLayoutController.mm */, - 68EBD106F17D31DCE3ACD608207D0124 /* ASCollectionViewLayoutFacilitatorProtocol.h */, - 5C216819A1D5BC5B2AFC924E6C9858A2 /* ASCollectionViewLayoutInspector.h */, - 879C8B32AAE6359D599F78BC16CBB13F /* ASCollectionViewLayoutInspector.mm */, - 3B8177727C674D026E37566A26B57945 /* ASCollectionViewProtocols.h */, - D8669BDD150909EC0BEE733EFBE3F7E6 /* ASConfiguration.h */, - E327F711FFD756BD667AD6AC61D3C660 /* ASConfiguration.mm */, - 745BC45253F7B8CB5026E5AE52813E82 /* ASConfigurationDelegate.h */, - 86BD044C71694B82FE5978E510C75CBA /* ASConfigurationInternal.h */, - 63C9ACDEAE8A9552A325796A234F79AC /* ASConfigurationInternal.mm */, - 956EDCF688E51E9B81CC568337DB6AF1 /* ASContextTransitioning.h */, - 01E4661F07305554D5DE06D73578BF89 /* ASControlNode.h */, - 998892452F748ECC73ACD89183345341 /* ASControlNode.mm */, - 73DC94ADF25673F66DD319923A0E77FD /* ASControlNode+Private.h */, - C187236A999EC1D588BFDC6A9269C806 /* ASControlNode+Subclasses.h */, - CA013F86E55F43BBBB8A8C7596DE700A /* ASControlNode+tvOS.mm */, - CAF24DC1C17849451322FD125AD2E70C /* ASControlTargetAction.h */, - 6A8C7D884197F26D73FBA82D4A4132C5 /* ASControlTargetAction.mm */, - B10A8EE0FA86A85383E48A756A391C24 /* ASCornerLayoutSpec.h */, - 162E6601E2398E3D0F75F647411164AA /* ASCornerLayoutSpec.mm */, - CF0DDADC13D1CF8AB42051D93B8555C1 /* ASDataController.h */, - BEC9D1A35829C776E86C1943567228B3 /* ASDataController.mm */, - 4DDC011BFAD764B9FB35A1A1F6280062 /* ASDefaultPlaybackButton.h */, - C54C9862069FBA457D7E8F2CAC1BEDEF /* ASDefaultPlaybackButton.mm */, - CC192131041D44BC2AB4EA73128B108E /* ASDefaultPlayButton.h */, - B093FB7C9D3A95FC8A8BA9F203EF0987 /* ASDefaultPlayButton.mm */, - F77355B911C772EB2AD735BF076E4CFD /* ASDelegateProxy.h */, - 3435983882FBE500A5D5F17D35799084 /* ASDelegateProxy.mm */, - 88E78B612E8360D5296AEE501054F09A /* ASDimension.h */, - 0B739A419D028F8BC409ADB9AD9CA527 /* ASDimension.mm */, - F74E2E2EDB48C048F9F569CFC937193E /* ASDimensionInternal.h */, - 124148AADE44AC741CFADC231F551605 /* ASDimensionInternal.mm */, - 23695E05ACF79219EBCDE5C2958F0D74 /* ASDispatch.h */, - 1DEFE7301FC80CCC24CC61198C436845 /* ASDispatch.mm */, - 4E6A03617F6864E29B9A5454452C1AE3 /* ASDisplayNode.h */, - FAF9BF2152AEE816BD4063566927C2C7 /* ASDisplayNode.mm */, - DD7FED1C7830F32AA3BC824803FC338C /* ASDisplayNode+Ancestry.h */, - C3A340B8DECFEA34B858E29D8A3B6860 /* ASDisplayNode+Ancestry.mm */, - FC678FBD26515FC0EEA585EC6DE85663 /* ASDisplayNode+AsyncDisplay.mm */, - 4376ADF353DC2577C335D8807B54245F /* ASDisplayNode+Beta.h */, - CEFCD08353CEB062A616617D7CB0E38D /* ASDisplayNode+Convenience.h */, - B5CA33263F85C6E21A268F342F079528 /* ASDisplayNode+Convenience.mm */, - A184C7A5B0B71E080B56514AB7E8A425 /* ASDisplayNode+DebugTiming.h */, - 4F0AFD63DC30E3247C4918C6BEA9A0AE /* ASDisplayNode+DebugTiming.mm */, - 6490DDA9673AE60693B85E2B708DC4D8 /* ASDisplayNode+FrameworkPrivate.h */, - 252EBBCA9827ECA85C255F6F5B58D251 /* ASDisplayNode+InterfaceState.h */, - 3BF2212F3A7D876C37A5DD2521386AF8 /* ASDisplayNode+Layout.mm */, - 9CFB3A1E5D6B29DCDD26302D3E775DC1 /* ASDisplayNode+LayoutSpec.h */, - E68F514908D5394AA86EBEA208E47A04 /* ASDisplayNode+LayoutSpec.mm */, - 007B9E9F13C247C344FE3DC65E2AB901 /* ASDisplayNode+Subclasses.h */, - A867957DE758B3752902421CE4EA0DF8 /* ASDisplayNode+UIViewBridge.mm */, - 3A590B674BD9CFE88538617C0FE64948 /* ASDisplayNode+Yoga.h */, - E01A5CAF748172FE038684764702EF61 /* ASDisplayNode+Yoga.mm */, - EB97330F8020838EA2C835F2D5E380A1 /* ASDisplayNodeCornerLayerDelegate.h */, - AF8951F6130635C32B10D41798AA0F40 /* ASDisplayNodeCornerLayerDelegate.mm */, - B73C16ED725233597781AD592DEAE342 /* ASDisplayNodeExtras.h */, - 9716B558FD71C638448F6241417C5707 /* ASDisplayNodeExtras.mm */, - 4EFD085094FB76099386A32CCCDDB062 /* ASDisplayNodeInternal.h */, - 734D5D9C89E717418FCAA7185ED7E02B /* ASDisplayNodeLayout.h */, - 2352CE5ABD68B97D2C20A75FE2B8F448 /* ASDisplayNodeTipState.h */, - 8C4C2353FF592E40999EFBD5AB3AE15C /* ASDisplayNodeTipState.mm */, - 443574802076FB68086CBFC32F215FC9 /* ASEditableTextNode.h */, - B283A07DE6907D817AC983307646ED4C /* ASEditableTextNode.mm */, - C2FEC161E352AF6BAEC084E513C5C48D /* ASElementMap.h */, - 0D5AA6B6BFFB0F4BA2616154920180D8 /* ASElementMap.mm */, - 42ADB8EFEEAEEBFE11A460E7A0B67630 /* ASEqualityHelpers.h */, - 9BB3F630C68C3A5DFB13F24E7FCAD25A /* ASEventLog.h */, - 6DBD0F18AD2C048A15C6E508350FE156 /* ASEventLog.mm */, - 0496BFF0C5BC4DE37E77097EBE8DAA21 /* ASExperimentalFeatures.h */, - 9D593D3251E3CB76916473892474B96F /* ASExperimentalFeatures.mm */, - DE74719B84443664ED5311A61911759A /* ASGraphicsContext.h */, - BCAAB9B73EF8F3432A4345B9A9A25A2D /* ASGraphicsContext.mm */, - 7D4271F88523068290159A5B308C26DE /* ASHashing.h */, - B2F4A9B3C994EF9CD4EE8D995926F08B /* ASHashing.mm */, - 771C739307382FB3BE6C97B81D92D604 /* ASHighlightOverlayLayer.h */, - 4EC82CF26F151D3049C9FF32F22AF94D /* ASHighlightOverlayLayer.mm */, - 5E4321DB363EC82D6737D7BD0179F660 /* ASIGListAdapterBasedDataSource.h */, - A5C0CFFB06A4F703B26E2CB912988F77 /* ASIGListAdapterBasedDataSource.mm */, - 8AFD059D7D4CBEA0213433EBCFF64EA2 /* ASImageContainerProtocolCategories.h */, - C635F17EAEE4E59A1CE2F6202E5247EE /* ASImageContainerProtocolCategories.mm */, - 7135BADF9C0B4425CC0C0126CB809820 /* ASImageNode.h */, - 58F66FB0AEB4E161B98EEC0563AAAA83 /* ASImageNode.mm */, - 609E9C43163ADCB8E907714C5FFF8826 /* ASImageNode+AnimatedImage.mm */, - ED7A7B2E8EC994618EEA9CF500126C01 /* ASImageNode+AnimatedImagePrivate.h */, - 75F5EC2D6BBD57314094328D47EFA189 /* ASImageNode+CGExtras.h */, - 00F0D9E4494E6E4440167C3B132C83CA /* ASImageNode+CGExtras.mm */, - CA1EEA85B1AB08A62240A714B72B51CD /* ASImageNode+Private.h */, - CF54AE29F0904364F8BAB4731C2B61F5 /* ASImageNode+tvOS.mm */, - 04B46B85C03FC5CC066ED7F633FEC888 /* ASImageProtocols.h */, - 617A1C88184B4FC6BD7DF6B8D9D96833 /* ASInsetLayoutSpec.h */, - 607041B6536208E2F64B565D46764939 /* ASInsetLayoutSpec.mm */, - 7A0720ADCEE5EA7E1BF10055515487F0 /* ASIntegerMap.h */, - DF9CAE59564D99FB78072D06EBB3E37B /* ASIntegerMap.mm */, - AEFE143F7C05931041DA6DF354DE63CC /* ASInternalHelpers.h */, - DF1D4FA61A9EBACC795AA678AB81D0CA /* ASInternalHelpers.mm */, - EFB4F1B82C208BE59AA0898C1479B48F /* ASLayerBackingTipProvider.h */, - E8DDE817DC02BCD96ACFB1094843BFC0 /* ASLayerBackingTipProvider.mm */, - 21328B9DF462AD6B1267E304A81AB8FD /* ASLayout.h */, - 004EEF67B238D8D591FAA3567F4B1D67 /* ASLayout.mm */, - D29A4225F3A3D743A92285D5F23D9CEA /* ASLayout+IGListKit.h */, - AE1FE096C913D8F624564FE170A0B4B1 /* ASLayout+IGListKit.mm */, - ED741FEC7CF39C7B0B4271C1A6C33182 /* ASLayoutController.h */, - 9CF3ECB29AFF0D004E804019BA456BAF /* ASLayoutElement.h */, - 15C1333DEA8E11B47C507085AA30FC6F /* ASLayoutElement.mm */, - 4C3E8E8DF87C3112F7930C4F95399416 /* ASLayoutElementExtensibility.h */, - B1257D21990FE33E970249DA587E24A9 /* ASLayoutElementPrivate.h */, - 675E0F7FDD409F8A77A5C35C201C300D /* ASLayoutElementStylePrivate.h */, - CD72B567F111E9E3EDFE39E0620500FA /* ASLayoutManager.h */, - 77DB577F26D2B45960B5B6BFA0762A2E /* ASLayoutManager.mm */, - DBBFE01B8675C3711CF07D2843B07D0F /* ASLayoutRangeType.h */, - 3B8A34FE38ED02DDC1550A4B16A33A3B /* ASLayoutSpec.h */, - 2BF44023A1917C6A267664CDCC906D27 /* ASLayoutSpec.mm */, - 0DA500C380D603BFBE1C536274B05AAC /* ASLayoutSpec+Subclasses.h */, - EC5266FA08A00D7A1C2EB5B60A5CF66A /* ASLayoutSpec+Subclasses.mm */, - 445246B3B756F5F96B99AEF7BBA3F014 /* ASLayoutSpecPrivate.h */, - BB82EEF6CD35EC54E853AD4070BB9F25 /* ASLayoutSpecUtilities.h */, - 0678905DA353A09C60572A337DEF943B /* ASLayoutTransition.h */, - B5D733DA59C42F85C9420CC9D53FD100 /* ASLayoutTransition.mm */, - 4D45CA8A0CD161A2FD16B69E7A3F23C4 /* ASLocking.h */, - E7B49D7AC5C2C0142D862EFD6D43B2B5 /* ASLog.h */, - EDBFF3393C31CD709ECF615266088C91 /* ASLog.mm */, - 4C4D6B95F7D6F2215E963E83CE181D37 /* ASMainSerialQueue.h */, - 70D4BAD9DE5E975D5E04B308B0B3BE07 /* ASMainSerialQueue.mm */, - 44265DBCB67F313E59BFA3FCE8D51190 /* ASMainThreadDeallocation.h */, - DDD6A5FCBA65371A45826CB1728A0F7A /* ASMainThreadDeallocation.mm */, - 23C2025A1786911B195905E0D5D2B2FC /* ASMapNode.h */, - 285A45E26308C77E98740CEB3DA1101E /* ASMapNode.mm */, - DF8DF606941FFEEC9EE31E1353EF53A6 /* ASMultiplexImageNode.h */, - 44B1FF984C74EB2DBF074043ABBA4F0F /* ASMultiplexImageNode.mm */, - 4B2586BBD79ACE8F25C2855963C00306 /* ASMutableAttributedStringBuilder.h */, - 29ADC9D575218E44CB3B4434E2C47BEA /* ASMutableAttributedStringBuilder.mm */, - E6581AA58586EF122B4A7935CF2A0838 /* ASMutableElementMap.h */, - 504B06FD3DACEEAFDEA8D5E809A7095B /* ASMutableElementMap.mm */, - 6E59B54071C5A06019DE422E434D54C4 /* ASNavigationController.h */, - C35693DA8C2E5A82EBA0F056580C2534 /* ASNavigationController.mm */, - 4A70B3A34B45D1967D684671ED89E5B6 /* ASNetworkImageLoadInfo.h */, - E0846880D85E50BD74D66583A3F4D4CC /* ASNetworkImageLoadInfo.mm */, - D038D5D65D25E6B9A55A199B3C5E4C72 /* ASNetworkImageLoadInfo+Private.h */, - A9E479AD6CC4807738F653AF75B351CB /* ASNetworkImageNode.h */, - 53BF6FEFB38F9EA8AE1B2C5E3FE6DD85 /* ASNetworkImageNode.mm */, - BAC3EE3B34E6F03D24161D8B69B10D48 /* ASNodeController+Beta.h */, - 26245E1F996E74C2E922A30F3ED2D3E9 /* ASNodeController+Beta.mm */, - 836EA6D72B4490C73AF0C525C6876D37 /* ASObjectDescriptionHelpers.h */, - FF34E71B804FA873D12D62187CBBB9BC /* ASObjectDescriptionHelpers.mm */, - 02E082F190CD64742376FA1DCF16D316 /* ASOverlayLayoutSpec.h */, - 784EF6F897319AE9C0047B80A777FE72 /* ASOverlayLayoutSpec.mm */, - E6ACA3ECDEAADA5D85338D020179D6EC /* ASPagerFlowLayout.h */, - 2CF418803B52917B4CDEEFEECE88DF2D /* ASPagerFlowLayout.mm */, - B6A6531A377911E1EFE834A1B541072D /* ASPagerNode.h */, - 4FF46F97C823C0B402802B311E54781C /* ASPagerNode.mm */, - 5960F0BD04B70C94B98548918A2C94EA /* ASPagerNode+Beta.h */, - F23780FCB6ACAED58B9318C15C8B0DE8 /* ASPageTable.h */, - EF4FFFABB7BE54C6BCBF9A61F17A6A98 /* ASPageTable.mm */, - 7541B18A6C986C3B141071F12EC8AA87 /* ASPendingStateController.h */, - 2640238F95E8A009DD6CFE7B65C34E9B /* ASPendingStateController.mm */, - D9ACB6B0A84C9EC8F26624BCE6B949FF /* ASPhotosFrameworkImageRequest.h */, - 19E53513494050AA573FBF57F1E0B64F /* ASPhotosFrameworkImageRequest.mm */, - E062EE8439098EF20D02C7338C975C52 /* ASPINRemoteImageDownloader.h */, - AECD5C2F25705D0D88F3CBD2374C4F9B /* ASPINRemoteImageDownloader.mm */, - C7CDB77E762DB5C99E6306652B4B6947 /* ASRangeController.h */, - D2C7409FD631FBD85594A03B3F0C598D /* ASRangeController.mm */, - 67F4D61E91F117DC2FA2C8092679E51A /* ASRangeControllerUpdateRangeProtocol+Beta.h */, - DA0C325BE2C19C06990097FF199548F0 /* ASRangeManagingNode.h */, - 8F6250F9BD3F49B51499B90504EE1D5C /* ASRatioLayoutSpec.h */, - E3B9A8B07F628C3AF0B0565D94907370 /* ASRatioLayoutSpec.mm */, - 22C7A16ABC9185C93FB35F8D1A38EE48 /* ASRecursiveUnfairLock.h */, - 860B39EE6BB8A3966AF1259098EEB687 /* ASRecursiveUnfairLock.mm */, - D5DDD9B2DE79EA31E77C347CB177062F /* ASRelativeLayoutSpec.h */, - 31C3C3A510E1FC44FB2F8FBE5BD8C95F /* ASRelativeLayoutSpec.mm */, - 74A617AD6A6D696D3F0296CD7F204CA1 /* ASResponderChainEnumerator.h */, - 35E06328EC3399B7E3571D2B013A22CD /* ASResponderChainEnumerator.mm */, - 780AEE0E9559677F32F78674DB2BBC5A /* ASRunLoopQueue.h */, - D34150625D2DF5F1674579F01ACAEA54 /* ASRunLoopQueue.mm */, - 37BFD09009E1CA2D06CA1E0299275DFD /* ASScrollDirection.h */, - 8EE240ED270F427A2A20035145E4E12D /* ASScrollDirection.mm */, - EF0AED795C713127D4F67E01AAC3B788 /* ASScrollNode.h */, - C065EA4E96480B78158007EA06DE3DA7 /* ASScrollNode.mm */, - E8154B80F3BF383F5EB574E1497B614C /* ASSection.h */, - 5CCAD733BD22B89DD6EDFD49B0683A7D /* ASSection.mm */, - C107CFBED03119CB9FB979B38275EFDE /* ASSectionContext.h */, - 3606305E249E94F9CB41FE90831B0107 /* ASSectionController.h */, - 9C6960CA476D12BC3E1596C094F2BFAD /* ASSignpost.h */, - A953839D36FAD7AB1C3B310EA76073D0 /* ASStackLayoutDefines.h */, - D98D4102DE5D0527079F24439B32B5AE /* ASStackLayoutElement.h */, - 54E63B392FE4A4F0BA38E50DB0D4ECD5 /* ASStackLayoutSpec.h */, - 3E08232F3108F02C86EA8BAD407FEBB6 /* ASStackLayoutSpec.mm */, - 4A522E2430B709898EF722555E8A4DDB /* ASStackLayoutSpecUtilities.h */, - 4B50F73FC9907B3B5250EDDF7ED1B18E /* ASStackPositionedLayout.h */, - 07729A9F499A036868ED6B53393E7A5C /* ASStackPositionedLayout.mm */, - 9A3CFDC315D163384B2F7024695124BD /* ASStackUnpositionedLayout.h */, - D7BCDD0C9A3A1E746B9F1E99D158C91E /* ASStackUnpositionedLayout.mm */, - 7E372AA815D2A151D2CBA8ACF92FC280 /* ASSupplementaryNodeSource.h */, - E729BFF861BF80E417AA7161ED356A47 /* ASTabBarController.h */, - 5062F79F55E2B3E2E71540B5210A7541 /* ASTabBarController.mm */, - C34BD2D317CCDC7344BEA22900C93E20 /* ASTableLayoutController.h */, - D43741DA796D220E39698D245C0C7FD0 /* ASTableLayoutController.mm */, - 3BF7B14A070E69EF1B3DCDCDC5341299 /* ASTableNode.h */, - 4AEA21345119E8A9D19E256F0B3EA1C0 /* ASTableNode.mm */, - 46F73ED5DBD4B0E2A039193D5663B7A5 /* ASTableNode+Beta.h */, - 8B303C567292DC11F1B0DAACE614A6AC /* ASTableView.h */, - CD9985360CAA99C3433E43A198C9C8C4 /* ASTableView.mm */, - 2E4AE2CCC6E863F878281B34B30F6FFC /* ASTableView+Undeprecated.h */, - 36B6B10464BF4A4C825532E2CC503B37 /* ASTableViewInternal.h */, - FCBF961C99AB6BE3B67E1A5D49BD0FBA /* ASTableViewProtocols.h */, - D13C42FAFFDAA633F5D53CA57A8C1683 /* ASTextAttribute.h */, - 0ADDD0546EE438CB2D70AE96914E0431 /* ASTextAttribute.mm */, - 501BF04BC8D41B8C49F2412A7F6EA9E5 /* ASTextDebugOption.h */, - 66025E37962CFCFF58E31BD4B8B8AE1F /* ASTextDebugOption.mm */, - DD90D4DE2B4C773B25DE461741FCE6BE /* ASTextInput.h */, - 1029CE67DEA0959BCCAA7D9F534FEC84 /* ASTextInput.mm */, - 18777AD77F0E97539ACAD1F9141F38DA /* ASTextKitAttributes.h */, - D18419ABCCABCA2F165BA42ED0301C18 /* ASTextKitAttributes.mm */, - BE5BE38429E1421B25B26E3F778B6388 /* ASTextKitComponents.h */, - BDF8134E8543067B3399A8AFC359C859 /* ASTextKitComponents.mm */, - C1B5279955DCE765725B542C20DC2C37 /* ASTextKitContext.h */, - 6972254463A4E42E119C4C796390CFF9 /* ASTextKitContext.mm */, - E5B9950A1BB7AB4BB4F981109C561078 /* ASTextKitCoreTextAdditions.h */, - FDA847AF8B056A3AC9A65250377F027C /* ASTextKitCoreTextAdditions.mm */, - 44F8BC427F71546D5619B405BCE1DD36 /* ASTextKitEntityAttribute.h */, - 3E8220DCF4A5EA772D044B1A50261387 /* ASTextKitEntityAttribute.mm */, - 4633B6D7E44B708326E2E31CBFD78C9D /* ASTextKitFontSizeAdjuster.h */, - E778EA8770ABFA8D712897C593624C1B /* ASTextKitFontSizeAdjuster.mm */, - 6641DA3D150545A95436CF794C0CBE48 /* ASTextKitRenderer.h */, - 1D13214627B0CA8A7BE823B9652281FB /* ASTextKitRenderer.mm */, - 67980F51D8D7857FD5DF2B3CFD94B2DC /* ASTextKitRenderer+Positioning.h */, - 6901B23BFB9DC7E4D4147AA505777EA5 /* ASTextKitRenderer+Positioning.mm */, - 3E4CBF6674EF31AA91520974C6E01BD9 /* ASTextKitRenderer+TextChecking.h */, - B88ACF20E41D2246608FEA823AC77B13 /* ASTextKitRenderer+TextChecking.mm */, - 899757F2A351E6C05F6A5A3EE1B687CC /* ASTextKitShadower.h */, - 0EAFE70C30090A5CF72DE2F7415578D1 /* ASTextKitShadower.mm */, - DF5B20F75E416F1C307A219C5A41109B /* ASTextKitTailTruncater.h */, - F33ACD58C957BAAC992E6CFFB0F23696 /* ASTextKitTailTruncater.mm */, - 8E7536DF5C436E513BCB94280E7CFD70 /* ASTextKitTruncating.h */, - 9981AC172C1B313D4AFDF736B83E76DD /* ASTextLayout.h */, - 583C97D8927B51E6485A4BAD1EE6C61D /* ASTextLayout.mm */, - 7C30E737EC48CE6BA7BA08E469B40F7E /* ASTextLine.h */, - C6168D2B373231D675211F9910C528C7 /* ASTextLine.mm */, - 11C0D27698278E492EDF141A99066C51 /* ASTextNode.h */, - B54D5C75E76CBA98DF5873350D8E1932 /* ASTextNode.mm */, - 8F207CE79ECE5ADC0BED3DD0D8B7B83B /* ASTextNode+Beta.h */, - 3D4DA64813A14F793D42CFE74070D648 /* ASTextNode2.h */, - 722AB0BD59691CFBC5D191DD68CDC635 /* ASTextNode2.mm */, - 2566ED78C35450BA5FD2005C76B64425 /* ASTextNodeCommon.h */, - 053572BA7FE13DAC5CA8C9ED6FF7310D /* ASTextNodeTypes.h */, - 833117E1C1902A1A1262B53ADA674BD0 /* ASTextNodeWordKerner.h */, - 19BD6E57E86CCDA20DCA33B5615D6479 /* ASTextNodeWordKerner.mm */, - CFEE3F2F5FCAF0F3908A81163FD68D8D /* ASTextRunDelegate.h */, - 717574B35CF1E6D3F744307CCE00121F /* ASTextRunDelegate.mm */, - 994BF7579A66B53B1E474D7F2E06A292 /* ASTextUtilities.h */, - 0DB18754F7DBD5680043B023D3924CDD /* ASTextUtilities.mm */, - B25D491B0A31A845AF0339A0BEA95052 /* ASThread.h */, - C513C2D2192061E27F0D119FF031C017 /* ASTip.h */, - 1EF3A863F3C8E076FC078D3A85201FE2 /* ASTip.mm */, - 50FE37FFD7EF2429C10029089C508EBC /* ASTipNode.h */, - 82B5FE5440AD8C2D32D0905139420FC0 /* ASTipNode.mm */, - 8300AF8B7A5E55E071CE2BBFFC6404B9 /* ASTipProvider.h */, - 947A438B776425860B7954368A814273 /* ASTipProvider.mm */, - 551ECA207D97BC65B3FF2EC1D0187E25 /* ASTipsController.h */, - 04FE1FDDBACAF8709FBAB591EA6C2155 /* ASTipsController.mm */, - E144F57F0B8D28515331682DD09E32BA /* ASTipsWindow.h */, - FBCF740EBE5DE3C173D4E8439D0DFF36 /* ASTipsWindow.mm */, - E3B02A8C5EF0BFB03017CAE2C8D4303F /* ASTraceEvent.h */, - 023744D1EB94358EFF5B46ED666E1A78 /* ASTraceEvent.mm */, - E1B40F69DFD16A71ACDCF95E5D218731 /* ASTraitCollection.h */, - 9B7C5313BA0D58DED056D33BC4538443 /* ASTraitCollection.mm */, - 5CE71255C1FCB63798369B1B61543897 /* ASTwoDimensionalArrayUtils.h */, - A0C4D1E5B3896EEE58F2719BD330AE3D /* ASTwoDimensionalArrayUtils.mm */, - 64BF78B27F9F9D6D702EEDC1DDB09901 /* ASVideoNode.h */, - A23F94511B338FE277EC2BCFEC053F24 /* ASVideoNode.mm */, - 64C1E527A330B58A62D7FBCC27451933 /* ASVideoPlayerNode.h */, - A78AFDF66148881309B4E97383CA01DC /* ASVideoPlayerNode.mm */, - C2F3FAB56ABA986E779429D2637559C7 /* ASViewController.h */, - 3622A7B1520B6EA76FA4B4AFEA470CE0 /* ASViewController.mm */, - FEEE1F4CD0EBD604CAB288E054835B9B /* ASVisibilityProtocols.h */, - 5B2B7A0F27A1B1C961C4EA3C16175B81 /* ASVisibilityProtocols.mm */, - A62DAA92B3EEF14B2EBFA714FFF6B6D7 /* ASWeakMap.h */, - 8B63699EFB4C341DDCA0160947E19395 /* ASWeakMap.mm */, - D62BAA7299811C6007375660954B85C9 /* ASWeakProxy.h */, - ECE0D92D4EC523A9855D1F722186A1E5 /* ASWeakProxy.mm */, - D804DC3A2743336B5C1C7F72579362A6 /* ASWeakSet.h */, - 739717630BB5AE208463BF141B4995DA /* ASWeakSet.mm */, - 843DB650E83C835994FAEF2C6A66B8CC /* AsyncDisplayKit.h */, - 9D768DA83B418CA0C1CC710850566A92 /* AsyncDisplayKit+Debug.h */, - FD0555E6007F93E7AB71B7AC7A643894 /* AsyncDisplayKit+Debug.mm */, - CB5EA34046D5FB220392F961B785A319 /* AsyncDisplayKit+IGListKitMethods.h */, - B8965C6AC7D32CBE8AB47BD3DD1AA7D1 /* AsyncDisplayKit+IGListKitMethods.mm */, - A7DB14A5844AB9D9843C0B181E42BE46 /* AsyncDisplayKit+Tips.h */, - 46AB7C0E0E8242F41B205E4DBD3C10E3 /* AsyncDisplayKit+Tips.mm */, - 4A8933680D912A0075750162CB15EF9F /* ASYogaUtilities.h */, - 2B07470A9306150D188132273127CF31 /* ASYogaUtilities.mm */, - 7EEF9D9818AB62929E90309B6F369ED2 /* CoreGraphics+ASConvenience.h */, - BD47532762609FE8FD8106735ABFB4FB /* IGListAdapter+AsyncDisplayKit.h */, - 157FB8FE619F3FCDFB26DECF132232C3 /* IGListAdapter+AsyncDisplayKit.mm */, - 32E1A5A62805A96755862D0EA25E6BA4 /* NSArray+Diffing.h */, - 86803184503140C2A4F07DFFED434615 /* NSArray+Diffing.mm */, - DB05D8F15693818ED24FF6BAF2F27166 /* NSAttributedString+ASText.h */, - 4DE06937FCEE16FB4B9F13D19D95CF74 /* NSAttributedString+ASText.mm */, - 5DB52888B23BC72D0EC9DE977B805591 /* NSIndexSet+ASHelpers.h */, - F10A7F445C73E4B81EB75D2B1FAC1888 /* NSIndexSet+ASHelpers.mm */, - 286CD9D4C899902427554B69AEB67772 /* NSMutableAttributedString+TextKitAdditions.h */, - 07A5F3EBB5DB5D888DFCF04CA861A73F /* NSMutableAttributedString+TextKitAdditions.mm */, - 2FE925E84A281D06546AD497ECF45514 /* NSParagraphStyle+ASText.h */, - DFD6F206B8FFE0C84A6A76F86D80AD38 /* NSParagraphStyle+ASText.mm */, - 1402CF84CB36E6A58305FC9A07AE9A7E /* UICollectionViewLayout+ASConvenience.h */, - FEDBB3F3DD47B161C406D03FF3A9BCC5 /* UICollectionViewLayout+ASConvenience.mm */, - 8C13FE60D14FB69B42CF62FDDB8882EF /* UIImage+ASConvenience.h */, - 067CAA9F4FC781E023BDE479666C0EBF /* UIImage+ASConvenience.mm */, - 5D2F12F4DBC147ABBFF5EBB4E003AD04 /* UIResponder+AsyncDisplayKit.h */, - 4AD6A102FE402E0C21F9D0C9B94E7115 /* UIResponder+AsyncDisplayKit.mm */, - 2ACA70DF8BDDEF5677F2ADD9A82261E8 /* UIView+ASConvenience.h */, + E8A8AF7EEF202B8EC2F8D48620BB43D0 /* Arc-exception-safe */, + 7A0D647FBFA4A8009356B0D05D195FA4 /* Core */, + F16F4FC9B01EBEDAD9B6C2E9C3CA7D21 /* Support Files */, ); - name = Core; + path = PINCache; sourceTree = ""; }; - 60211FC11C929BF770528AF531F8E0A1 /* Structs */ = { + 6EA8459D30C6CC0A4979A83CC8061FC6 /* Core */ = { isa = PBXGroup; children = ( - 81225F64FFCB713D06102F384EE235EC /* Animator.swift */, - 8D67F8257B9EA483BC03A079926677DF /* BounceOffsets.swift */, - 4AE0C290967EDFE3B12512326F5BFD16 /* DefaultAnimators.swift */, - E20F56D2D244CECF2FAD0815934D1751 /* ImageZoomControllerSettings.swift */, - 79CFD9BC7AF69EDB01B34D77788E7A4F /* SpringAnimator.swift */, + DCDFEDEA0B238450F5F65B65C2CD9079 /* NSData+ImageDetectors.h */, + E4D3DCB3C009FD5D8659089E34B277D3 /* NSData+ImageDetectors.m */, + 51DDB8C289581DFC7295DF13B2B679A4 /* NSHTTPURLResponse+MaxAge.h */, + 31A38BD86467F4397BAAE01B7769BEC5 /* NSHTTPURLResponse+MaxAge.m */, + 3696C349E675BB987AA159ECE86A472A /* PINAlternateRepresentationProvider.h */, + EBDEAAC4C345279ED09C50CF3BF09B7B /* PINAlternateRepresentationProvider.m */, + 3781AD18516F84156D9A016E7EF16502 /* PINAnimatedImage.h */, + FF1C4282E2564807E444F007450542C7 /* PINAnimatedImage.m */, + 4BF24D2130002A993A0633A50C598F0F /* PINAnimatedImageView.h */, + A6349CF71BFAF7D4A5704EB8D83E462E /* PINAnimatedImageView.m */, + 55B088323CEDD9CEA3BE4A747A5B7678 /* PINAnimatedImageView+PINRemoteImage.h */, + 4C602B3BA1E2B5E8FC405E54B8C10F5E /* PINAnimatedImageView+PINRemoteImage.m */, + 2321BFDF7A7BF190C1DCE0E4D175DF36 /* PINButton+PINRemoteImage.h */, + F5AB42EA0047BCD585B5B0401C2E88B3 /* PINButton+PINRemoteImage.m */, + 8585E737744727C5F5FFFE96D84A234F /* PINCachedAnimatedImage.h */, + A12D2284A307229BE1FCA6C56606D464 /* PINCachedAnimatedImage.m */, + 89CFBF3A3B10B6EDE93CCE993C1D33E3 /* PINDisplayLink.h */, + 4F70B8787ECCD2A332EB261E7189325E /* PINDisplayLink.m */, + 38CDE6D0609F3155BF724C4A383D3D69 /* PINGIFAnimatedImage.h */, + 19BEACB67CAFEBFC1ED66A82A7CEAC6C /* PINGIFAnimatedImage.m */, + 46BAB278C37D8CD0A78E57EBDAFFD703 /* PINImage+DecodedImage.h */, + 5A6A497EE4715107B9947A54E6593162 /* PINImage+DecodedImage.m */, + 3BAD4FB41EAFF0AE7B2153EF48C5BB88 /* PINImage+ScaledImage.h */, + BDD93100C2924931FBF3E404B81576D0 /* PINImage+ScaledImage.m */, + 022D02D7B64CA9E34BA2086AF7BDF23F /* PINImage+WebP.h */, + 2075A4B105A9E0F67B8A3420DFBA3ED7 /* PINImage+WebP.m */, + EDBF575B54A123E2694047C8C6894AB7 /* PINImageView+PINRemoteImage.h */, + 695CBAFD35269D7D30D7126BA1A9FE5C /* PINImageView+PINRemoteImage.m */, + B0ED94615CE6CEC319F06AACF1CEB800 /* PINProgressiveImage.h */, + 94FA6A0CED36425F79643AE9E44BDD3B /* PINProgressiveImage.m */, + 9E60EF003F598F328ED07D1336D1290D /* PINRemoteImage.h */, + CF3F18E47D07B321917AC4271C1ED51B /* PINRemoteImageBasicCache.h */, + 95FEC909C32BFD96EB1F86C86CAAD03D /* PINRemoteImageBasicCache.m */, + 0836BBF553616112912E10DCA57993A6 /* PINRemoteImageCaching.h */, + B4877B07FDD3DFF09B753FA5D3BB2FD9 /* PINRemoteImageCallbacks.h */, + 3961C9750DE5B388A186362677458C58 /* PINRemoteImageCallbacks.m */, + 7303F3582F8703C93C9B86724B41E492 /* PINRemoteImageCategoryManager.h */, + A6608A16D83A6A25E6DD589D4FF08DB9 /* PINRemoteImageCategoryManager.m */, + 60F2D5EB7FDFCC0BE3CB468C0D60DAB6 /* PINRemoteImageDownloadQueue.h */, + E758EA4E1865DE8FB11FE7DF08146477 /* PINRemoteImageDownloadQueue.m */, + 301AA79FF07CF4C0F6E48120A66F49CC /* PINRemoteImageDownloadTask.h */, + 764D542477B60E5C299092AEEED074EC /* PINRemoteImageDownloadTask.m */, + 1431CB6DD8433797E27E18B00DA74313 /* PINRemoteImageMacros.h */, + 6489C428B7BF38CBF9D3B664F3057F20 /* PINRemoteImageManager.h */, + 229924D8EAEEC020747355F7941265D7 /* PINRemoteImageManager.m */, + 21EE2773F3C79088F0071460CD0433C7 /* PINRemoteImageManager+Private.h */, + 67744A952643A0AB3D672202110107F4 /* PINRemoteImageManagerConfiguration.h */, + 107ECA26011E51E00F0FB2B12FFC1711 /* PINRemoteImageManagerConfiguration.m */, + 5275A3C1B1BB261CE7A641E5F1A4AE10 /* PINRemoteImageManagerResult.h */, + 9BB21D41481E7275F0290AEC1A3596C4 /* PINRemoteImageManagerResult.m */, + EDC1F1D124388ACE2413346CB3B8CEB2 /* PINRemoteImageMemoryContainer.h */, + 5A338D2C7BECE0973CC5A926E046FBF5 /* PINRemoteImageMemoryContainer.m */, + 30D28688CC6CE710EEF7F4DBA6B1C90C /* PINRemoteImageProcessorTask.h */, + BB3F1F87F50F1A78B7D2377AA4249147 /* PINRemoteImageProcessorTask.m */, + 612B944990F6D2B3032C498585070523 /* PINRemoteImageTask.h */, + 89AD76C27E390A5F98261196C2496BC8 /* PINRemoteImageTask.m */, + 0C4FA8380ADD141C97EB7236C2AF9B27 /* PINRemoteImageTask+Subclassing.h */, + F0C1A4032113C581DBC652A5D1C30293 /* PINRemoteLock.h */, + A7604C8C65BB4E702C08E6E64DCF64CF /* PINRemoteLock.m */, + D8AEF5A40C43AB90E6B7ED37BB01E1F8 /* PINRemoteWeakProxy.h */, + 22AB87EEF08419D87CD7B63869817E1D /* PINRemoteWeakProxy.m */, + B7DEDDDAA6240649B443BDBFF9429D77 /* PINRequestRetryStrategy.h */, + 50E2F80499CEA6B33FF927221C7377BC /* PINRequestRetryStrategy.m */, + 3B342DA9EE3B882BD437A5542477B69D /* PINResume.h */, + BE7C4386005ED1B9320FCC1D31C621CC /* PINResume.m */, + 4AF1C172FB6FEB6970604804FE237F4D /* PINSpeedRecorder.h */, + 327665699F63693627351B86322A4BBC /* PINSpeedRecorder.m */, + 529107AAD032EC80C54BE9CDC8EC94AB /* PINURLSessionManager.h */, + 0AC1D2A9DBE44C85842578B7376D7A5C /* PINURLSessionManager.m */, + B68441AB82FA9337F6184B4FC8706C89 /* PINWebPAnimatedImage.h */, + 677CD4785FE892E11D23DB575EF58964 /* PINWebPAnimatedImage.m */, ); - name = Structs; - path = Zoomy/Classes/Structs; + name = Core; sourceTree = ""; }; 74EB93897A62211E02383F834D1B051A /* Pods-Zoomy_Tests */ = { @@ -2067,49 +2119,31 @@ path = "Target Support Files/Pods-Zoomy_Tests"; sourceTree = ""; }; - 79341590646B0E12B058DFDA735D212A /* Enums */ = { - isa = PBXGroup; - children = ( - ED0C90099C4B69F62EA096A7F273C971 /* AnimationEvent.swift */, - 675C60B5C42D6C1F553B1698D747A649 /* ImageZoomControllerContentState.swift */, - DFD881480973960CF3694AFEA4B9513A /* Side.swift */, - ); - name = Enums; - path = Zoomy/Classes/Enums; - sourceTree = ""; - }; - 7B760CB5446D57B614B71D049B348F4B /* Texture */ = { - isa = PBXGroup; - children = ( - 5D6F07251A5D11B048518942F41F1B59 /* Core */, - 1029FFB6429F144BB0AE342861E093D9 /* Support Files */, - ); - name = Texture; - path = Texture; - sourceTree = ""; - }; - 833416CE96B575F64195C9F2ED27BB5F /* Pod */ = { + 775FF7B089A54C06A91CF75A2BE638AB /* Protocols */ = { isa = PBXGroup; children = ( - 1B878D70C0CE606BFEBFD094B59CFADD /* LICENSE */, - D53C635281133902C9689B13271D8B8F /* README.md */, - 46613995C9582C0CA35A0AA88C407A51 /* Zoomy.podspec */, + 0AE75587CBB8EE0DA0491F98A06B0181 /* CanBetriggered.swift */, + ABB94274587D4AB055B0098469B62741 /* CanPerformAction.swift */, + FFE7B568EE5763387E9FD7DA97625EA1 /* CanProvideAnimatorForEvent.swift */, + 594FEB1CE4589393B0B4FCA53EDA995C /* Zoomable.swift */, ); - name = Pod; + name = Protocols; + path = Zoomy/Classes/Protocols; sourceTree = ""; }; - 86EDDF74319DABCA7B38A299D56F2551 /* ExtendedProtocols */ = { + 7A0D647FBFA4A8009356B0D05D195FA4 /* Core */ = { isa = PBXGroup; children = ( - DBBFC51734B70A5463EA74EE6AA9EB96 /* CanAnimate.swift */, - 0C6AC42AE8AC5B546767B472AC3D4143 /* CanManageZoomBehaviors.swift */, - 0C2261536A1F390C347C83BE1AA59011 /* ConfigurableUsingClosure.swift */, - 95405DC3767380B72AF31549E659FCF7 /* HasImageZoomControllers.swift */, - CB1BF56DC2832DD482B008CA61701A5B /* ImageZoomControllerDelegate.swift */, - 27C5BA4CCAE91E983D7C8C9D067168C9 /* ImageZoomControllerState.swift */, + 19CFFC5B9E6CC2B79A757940780E4809 /* PINCache.h */, + 1AA1804B20C4BA59B74A32AC511B1713 /* PINCache.m */, + FD6F468C17D5D55709E1A98E64A9A77E /* PINCacheMacros.h */, + D49A19FBB24B7F8EE96F2736AD1B740B /* PINCacheObjectSubscripting.h */, + D2E37F15D53DA5704377A7D5836636C9 /* PINCaching.h */, + B067FDE9BD6960EBEA76FECAE06AA589 /* PINDiskCache.h */, + E8C9DEC2483B11E8B516171B7AE19CB7 /* PINMemoryCache.h */, + 3CA0EDA238063FF0C538D31F2961EAA5 /* PINMemoryCache.m */, ); - name = ExtendedProtocols; - path = Zoomy/Classes/ExtendedProtocols; + name = Core; sourceTree = ""; }; 89409EB517C1193F0871616032FD515D /* Frameworks */ = { @@ -2119,27 +2153,26 @@ 406975D5F17381231A901E0D62D7A138 /* PINCache.framework */, 3DF75328C738F4C8E40C3924A1C776D6 /* PINOperation.framework */, 5FB6F534B1401FE906AEF92CCF6A339D /* PINRemoteImage.framework */, - ADB9D43111B19603707ABD779F580BCD /* iOS */, + A7316655395657162CAE7A6F5C66BCC2 /* iOS */, ); name = Frameworks; sourceTree = ""; }; - 9F7F8D30DC588501190396ADE349685D /* SharedInstances */ = { - isa = PBXGroup; - children = ( - C1BC0617843927EBC5E65D973264D1FC /* logger.swift */, - ); - name = SharedInstances; - path = Zoomy/Classes/SharedInstances; - sourceTree = ""; - }; - A1F74C2C392E878E1AA2913FB4213063 /* PINCache */ = { + A7316655395657162CAE7A6F5C66BCC2 /* iOS */ = { isa = PBXGroup; children = ( - B763F6804A576872367A393D9228CA2E /* PINCache+PINRemoteImageCaching.h */, - A038B802D8F0C0EC85498DA10C1EC1F5 /* PINCache+PINRemoteImageCaching.m */, + 76F317BA0E076D34E8461D2E6827CD8E /* Accelerate.framework */, + DD6B76E7CC9E6D168E1CA155B92BD27F /* AssetsLibrary.framework */, + A12A3705DF38020F5B68418E190D0109 /* AVFoundation.framework */, + 832B4AE6E6704ADC13BF1022950A7A6F /* CoreLocation.framework */, + 27A91CE2CB94BB7B3F82B020DC588A81 /* CoreMedia.framework */, + 6C89951A2F1DEDB59773CA2C17ED4A78 /* Foundation.framework */, + EA7C2CD848FACF3605201842A31CAE94 /* ImageIO.framework */, + 4A5C0BBAAA11ABB306A67D1CE1F475FB /* MapKit.framework */, + 2D4435A927BF442E68357226A04D7421 /* Photos.framework */, + 0A8E2F46E8351A43B40AFBB4C8BEF3AE /* UIKit.framework */, ); - name = PINCache; + name = iOS; sourceTree = ""; }; AD898D9348493435A50A21E5A3B69FF7 /* Products */ = { @@ -2157,88 +2190,65 @@ name = Products; sourceTree = ""; }; - ADB9D43111B19603707ABD779F580BCD /* iOS */ = { + BA25C412665B5A953935E26945E097F0 /* Pod */ = { isa = PBXGroup; children = ( - 383761BD6584FEC55E5C246F77B1B93A /* Accelerate.framework */, - 10CD2F8A82E752D0F5290FF3DBFC0BE6 /* AssetsLibrary.framework */, - 95722285F0E34655A8452709EE3B6E55 /* AVFoundation.framework */, - 1303302AFAE1A1492C119553EB9326C0 /* CoreLocation.framework */, - 31959479D3789CFC54BD384F0D0E20A0 /* CoreMedia.framework */, - 216EA938ACBDE7DA3F84B2B903A98379 /* Foundation.framework */, - E1C23264DA61204A0B428A18A76C774A /* ImageIO.framework */, - 92F9025F046A5B8CD0B0A7FBF4C53383 /* MapKit.framework */, - 49091F146299E5C296CCD271B6BCF996 /* Photos.framework */, - A2D9B780803CCE87983E460EF683910E /* UIKit.framework */, + 27CFDDA4A05FD078952636CF1BA4BE40 /* LICENSE */, + 0558DFDA007EDF0D1EFF53A5B7F6F4D2 /* README.md */, + 8DDCCA94D499BCBA2318214BADCD72DF /* Zoomy.podspec */, ); - name = iOS; + name = Pod; sourceTree = ""; }; - B050ED44EBEA126D20728CB6EB3BA404 /* Support Files */ = { + C49DA58D333028707D138AEAED5241B3 /* Targets Support Files */ = { isa = PBXGroup; children = ( - FD5548AE6697EB822F1F6AE7D549CDA3 /* PINCache.modulemap */, - BA4B0255BD9DE24340698FC805C07449 /* PINCache.xcconfig */, - CFEB1F047D58C0F0393C41C23A4A4F88 /* PINCache-dummy.m */, - F4BB088F3EDEBE342A3FC4D32B254AAD /* PINCache-Info.plist */, - 75800818748B9EDEDA0DF1E0F708AB70 /* PINCache-prefix.pch */, - 78C0E5FE49415C26C04C9F48071F9E03 /* PINCache-umbrella.h */, + 01154D587A1540FDF117D717B7BEB0E4 /* Pods-Zoomy_Example */, + 74EB93897A62211E02383F834D1B051A /* Pods-Zoomy_Tests */, ); - name = "Support Files"; - path = "../Target Support Files/PINCache"; + name = "Targets Support Files"; sourceTree = ""; }; - B6530CACCDCD60ECA5C30A124B91F76B /* Support Files */ = { + C64418AC1B60C05B1377445C595D5AD4 /* Support Files */ = { isa = PBXGroup; children = ( - DC03C8D323C8A2C573128340067B2BEC /* Zoomy.modulemap */, - 724D27438A0502C29D8A0A72E0248013 /* Zoomy.xcconfig */, - 56E68C5787A7BC6FABD14F34D978338E /* Zoomy-dummy.m */, - 0805474ED89380D8B81280D3F8AB1044 /* Zoomy-Info.plist */, - 0D4C2A2B7E38D7C5569ED910C53B3B97 /* Zoomy-prefix.pch */, - 9A83CB18A0AFD9B76C70CFE0F7189A01 /* Zoomy-umbrella.h */, + 717054082F77141CEA737C820EDA3693 /* Texture.modulemap */, + 0E8547225274D91482FA087FFCE18E18 /* Texture-dummy.m */, + B1FBF5272BEF80A065086982B71E6AD2 /* Texture-Info.plist */, + F14EC73928B311AAA3201B108B38181E /* Texture-prefix.pch */, + A73CB612A2B88D87EABFAA2E231091B4 /* Texture-umbrella.h */, + F2DB9FFDC78A1FFD1EAFA4CB07F1F0C8 /* Texture.debug.xcconfig */, + 46310E5AB97B1359090388D99D9A9CD0 /* Texture.release.xcconfig */, ); name = "Support Files"; - path = "Example/Pods/Target Support Files/Zoomy"; + path = "../Target Support Files/Texture"; sourceTree = ""; }; - BA8FA0D88ED96BD5B1C0707270FDB372 /* Zoomy */ = { + C7C295982232AD4E03020C2BF739C535 /* Texture */ = { isa = PBXGroup; children = ( - 2CD8E879787766BA57718E7D32EE2F7E /* Classes */, - 79341590646B0E12B058DFDA735D212A /* Enums */, - 86EDDF74319DABCA7B38A299D56F2551 /* ExtendedProtocols */, - 3104EAF2841F590DE0976E1959532011 /* Extensions */, - 833416CE96B575F64195C9F2ED27BB5F /* Pod */, - CD6920807D03CD2F6FCEC918FD617A01 /* Protocols */, - 9F7F8D30DC588501190396ADE349685D /* SharedInstances */, - 60211FC11C929BF770528AF531F8E0A1 /* Structs */, - B6530CACCDCD60ECA5C30A124B91F76B /* Support Files */, - 0C809562BCB7DCE75A67EC92B9F5863A /* TypeAliasses */, + 3D2DCE4D62A5211128639CCDCBF7870F /* Core */, + C64418AC1B60C05B1377445C595D5AD4 /* Support Files */, ); - name = Zoomy; - path = ../..; + path = Texture; sourceTree = ""; }; - C49DA58D333028707D138AEAED5241B3 /* Targets Support Files */ = { + C8DA20F1B0BF541FBAB685848823E9C5 /* PINCache */ = { isa = PBXGroup; children = ( - 01154D587A1540FDF117D717B7BEB0E4 /* Pods-Zoomy_Example */, - 74EB93897A62211E02383F834D1B051A /* Pods-Zoomy_Tests */, + 5B81CEBEEA110B801B201B7E31584FD2 /* PINCache+PINRemoteImageCaching.h */, + 574D0A0487078EFBFCF4F03C47469787 /* PINCache+PINRemoteImageCaching.m */, ); - name = "Targets Support Files"; + name = PINCache; sourceTree = ""; }; - CD6920807D03CD2F6FCEC918FD617A01 /* Protocols */ = { + CB217531456694B41E9A8C0D5C6F1591 /* TypeAliasses */ = { isa = PBXGroup; children = ( - 6B2040AC217069203B2EA5F3FF24FE3C /* CanBetriggered.swift */, - 05EBA3BEF494A23D32FC5023A4303A8F /* CanPerformAction.swift */, - B1649C9B28814A0E5C609ACCC9D4BFEA /* CanProvideAnimatorForEvent.swift */, - 6C830822319FA08CBD72F6C6A234F64F /* Zoomable.swift */, + 15C80D074046D9ED56A3DFB11E613D9D /* TypeAliasses.swift */, ); - name = Protocols; - path = Zoomy/Classes/Protocols; + name = TypeAliasses; + path = Zoomy/Classes/TypeAliasses; sourceTree = ""; }; CF1408CF629C7361332E53B88F7BD30C = { @@ -2253,408 +2263,421 @@ ); sourceTree = ""; }; - D0FB96AF553E59DA762E027C3F734A0F /* PINCache */ = { + DD5185F64A8E805ED7D94A1EE0EC8153 /* Support Files */ = { isa = PBXGroup; children = ( - 14427FF774844D2289117EC6C9AD0158 /* Arc-exception-safe */, - 3E7D133135A9285D5DB5CE46D4F3FDD6 /* Core */, - B050ED44EBEA126D20728CB6EB3BA404 /* Support Files */, + 49A30867A82786A03C25B75416C6A599 /* InjectableLoggers.modulemap */, + D1B0B1E3406CFE376B8C7A053A6D027A /* InjectableLoggers-dummy.m */, + 1B461C264744B763F9716CED13E8304C /* InjectableLoggers-Info.plist */, + 18B0AE685477C6FF35E804AEB5CC74FB /* InjectableLoggers-prefix.pch */, + 4717228A634CE28E966300DE88992C3A /* InjectableLoggers-umbrella.h */, + A6260ECA1905AD096C8931DC364B024D /* InjectableLoggers.debug.xcconfig */, + 7AF0970735CEF05D54172A8598F05F00 /* InjectableLoggers.release.xcconfig */, ); - name = PINCache; - path = PINCache; + name = "Support Files"; + path = "../Target Support Files/InjectableLoggers"; sourceTree = ""; }; - DB789A35C77BE8319E0B71DFD15DD17F /* PINRemoteImage */ = { + E13E0D137CDF36FD3055C76FDA1D0D31 /* Pods */ = { isa = PBXGroup; children = ( - 1D23800CE9F9E437C92CE24658520490 /* Core */, - A1F74C2C392E878E1AA2913FB4213063 /* PINCache */, - 02C87EF1FDD1FD2D9945FA312B308B94 /* Support Files */, + 2C37E21A44E2D6891973A4EC33C71CB1 /* InjectableLoggers */, + 6B3A07B13F80F51615340DB5497DC1F2 /* PINCache */, + 0843A613A1AAC1896E325FD72B7DC432 /* PINOperation */, + 0EB569258E26AF52E6AC102C75B9353F /* PINRemoteImage */, + C7C295982232AD4E03020C2BF739C535 /* Texture */, ); - name = PINRemoteImage; - path = PINRemoteImage; + name = Pods; sourceTree = ""; }; - DC969E6D5EE19A3224AE1EEB82058CDA /* Support Files */ = { + E52A0EE5D0BF8DDBE41E687CBC50CEC7 /* SharedInstances */ = { isa = PBXGroup; children = ( - BF5E1C8959ABF12DB3C62716FE084307 /* InjectableLoggers.modulemap */, - 39AAC467404002DC03ECB50462243558 /* InjectableLoggers.xcconfig */, - C04BAB749055606D3946777030990DE3 /* InjectableLoggers-dummy.m */, - EEAF04827173959AAD3EFF77C1B1F0FB /* InjectableLoggers-Info.plist */, - 6700B1B2756EB1F11759EBDE0E513D51 /* InjectableLoggers-prefix.pch */, - 639031EEB8C0E0780319C2E1B91EC177 /* InjectableLoggers-umbrella.h */, + A96C263605C9675F6111B10DC6EBA561 /* logger.swift */, ); - name = "Support Files"; - path = "../Target Support Files/InjectableLoggers"; + name = SharedInstances; + path = Zoomy/Classes/SharedInstances; sourceTree = ""; }; - E13E0D137CDF36FD3055C76FDA1D0D31 /* Pods */ = { + E8A8AF7EEF202B8EC2F8D48620BB43D0 /* Arc-exception-safe */ = { isa = PBXGroup; children = ( - 4B271EDA85BFA5465BA902C1A95405EA /* InjectableLoggers */, - D0FB96AF553E59DA762E027C3F734A0F /* PINCache */, - 1378D9D016621281A1EF9C2C2FBB8BE7 /* PINOperation */, - DB789A35C77BE8319E0B71DFD15DD17F /* PINRemoteImage */, - 7B760CB5446D57B614B71D049B348F4B /* Texture */, + 677EEE3656D43FF4C34D547EC105A5AB /* PINDiskCache.m */, ); - name = Pods; + name = "Arc-exception-safe"; sourceTree = ""; }; - E5200B3D67ECDB575C62E70D876F1D9A /* Support Files */ = { + F16F4FC9B01EBEDAD9B6C2E9C3CA7D21 /* Support Files */ = { isa = PBXGroup; children = ( - 3CE549225FFDA099F6B291DEA1171623 /* PINOperation.modulemap */, - 49E96E5D11156E2C12B0FF6F8ACD6B3D /* PINOperation.xcconfig */, - 4ADFA05F60AA04316A5BB156A0555D0B /* PINOperation-dummy.m */, - CBF30FE548E806618E1A450023D31620 /* PINOperation-Info.plist */, - 514733900AE2783243A60B99D2A1009B /* PINOperation-prefix.pch */, - AB585F9D4AB7A266D774F3A142704648 /* PINOperation-umbrella.h */, + 8861C945B300C693E14494F50424D783 /* PINCache.modulemap */, + 9912693AC1AD6E93BC00EDC6E1E48E91 /* PINCache-dummy.m */, + FAC4D6232B240A0232B376FE8DF140DB /* PINCache-Info.plist */, + 5C0472B406D8D5A2FB7D3CC3DC5B85B8 /* PINCache-prefix.pch */, + B451A50AAD10F605219DFD5A70CE2156 /* PINCache-umbrella.h */, + 8D2B6528B911C7F2F567D3505C788ED9 /* PINCache.debug.xcconfig */, + BAF321EC18304D2D7018D41AE15755A2 /* PINCache.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/PINOperation"; + path = "../Target Support Files/PINCache"; + sourceTree = ""; + }; + F22E3557B1C250BA8BDCCC83C98CAA97 /* Structs */ = { + isa = PBXGroup; + children = ( + D8577C9C2A1140AD10A4FAB08CFA88B0 /* Animator.swift */, + 27990D3C91F8BA9D332FBE68E2775751 /* BounceOffsets.swift */, + F772F99383F940F834E7E84E4E1CADA3 /* DefaultAnimators.swift */, + A50A604616BEE784281355A14AB4924B /* ImageZoomControllerSettings.swift */, + 4A9EECB4E20FA3E0A3CC8F611CA69F56 /* SpringAnimator.swift */, + ); + name = Structs; + path = Zoomy/Classes/Structs; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 0FFDC764A31978B2A43158C74453953B /* Headers */ = { + 2A105393BCB5FE9278CB202153804F72 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - B86DF2CD8EDE86C19772343D0B2945FE /* _ASAsyncTransaction.h in Headers */, - CD7F69C88C619060BBC6A59FFF61C639 /* _ASAsyncTransactionContainer+Private.h in Headers */, - DCD1424C14D939C036F742ADAB03DEA2 /* _ASAsyncTransactionContainer.h in Headers */, - 5DBA02868B801D2A716CF9CA8E92AE81 /* _ASAsyncTransactionGroup.h in Headers */, - 11EC62A0043EF4EE18B0D99DA444B8E9 /* _ASCollectionGalleryLayoutInfo.h in Headers */, - 4D2DDBFD3EE5709B5674F7949EFB3FAF /* _ASCollectionGalleryLayoutItem.h in Headers */, - F285BAE9B392AE3FDEE0859C9C61B2B1 /* _ASCollectionReusableView.h in Headers */, - 90F4FA9213433356D089C0DF1F71F12E /* _ASCollectionViewCell.h in Headers */, - 7B57B12F9FEE2321D4984D5E697DB396 /* _ASCoreAnimationExtras.h in Headers */, - 09E1B26CCFAD9C7A295BB181DCCC0BB4 /* _ASDisplayLayer.h in Headers */, - C94CBEE8592258E9711DFAF7033F1EFD /* _ASDisplayView.h in Headers */, - E18E5E71D76E5D16380523D37653E3BE /* _ASDisplayViewAccessiblity.h in Headers */, - FF854CA6EAEA89511D244275C9E22617 /* _ASHierarchyChangeSet.h in Headers */, - 1A4F82222C3795E4CE2A87A593619A35 /* _ASPendingState.h in Headers */, - DE53B395CDF47347AD2A31FE6F1F1DF5 /* _ASScopeTimer.h in Headers */, - 970512FB1DD0042DDD5D9DFA7C75B74C /* _ASTransitionContext.h in Headers */, - 58753E1516397F4D04341782B8D6A9CB /* ASAbsoluteLayoutElement.h in Headers */, - 7B238AA4B05D561D86DE8F678AEE6FC6 /* ASAbsoluteLayoutSpec.h in Headers */, - 0BD4C7C6A2EB249987586F5444AAD546 /* ASAbstractLayoutController+FrameworkPrivate.h in Headers */, - DA53E5B9E93222ADBC1F715CCFAA7213 /* ASAbstractLayoutController.h in Headers */, - CCE160B0B53C129CB762ABEA9C679306 /* ASAsciiArtBoxCreator.h in Headers */, - 4A34BCF888B15A35B4C5723EE20BFE16 /* ASAssert.h in Headers */, - 3C5906F9B284E443F5CA74151CE89DF4 /* ASAvailability.h in Headers */, - CABFD58E0EC8F3FBC7C7BAFB0EE3D814 /* ASBackgroundLayoutSpec.h in Headers */, - DB0B0877719D949A31200A8EDE68CC81 /* ASBaseDefines.h in Headers */, - 0E2B3A5B6C9DA77C2A1843CEA33101D2 /* ASBasicImageDownloader.h in Headers */, - 95D84CF91CAA6D321C2648DD47068800 /* ASBasicImageDownloaderInternal.h in Headers */, - 289B94828460A43B11C67396FA7A9AF4 /* ASBatchContext.h in Headers */, - 6E5F58395286B921136BD6E9895978D3 /* ASBatchFetching.h in Headers */, - 4F00CB06B21669120C987F32487A9730 /* ASBatchFetchingDelegate.h in Headers */, - 7EAC704B0234A558A7C1651A2A48F970 /* ASBlockTypes.h in Headers */, - BDCEA7D86EF5EAA1D0132FA11A8C7679 /* ASButtonNode.h in Headers */, - 8CCD7C47780AEB7679C85CEE040DFD38 /* ASCellNode+Internal.h in Headers */, - A1387BF912438142526E1346D8ED55A8 /* ASCellNode.h in Headers */, - 5F5D9D949369EB06621D08D716C5BE04 /* ASCenterLayoutSpec.h in Headers */, - 68AF0FADD42ACAC71C4E009A0F8A8E45 /* ASCGImageBuffer.h in Headers */, - 5A8461D5F903DF711A276BE04577F79A /* ASCollectionElement.h in Headers */, - 66597F792DE7AB95DA3BE159B891FA16 /* ASCollectionFlowLayoutDelegate.h in Headers */, - B318E6FB4194F6FE456852556DF10B32 /* ASCollectionGalleryLayoutDelegate.h in Headers */, - AE1391BE88B7BC0556E20AFB8A2E151F /* ASCollectionInternal.h in Headers */, - 0DB7D0EE591B6FA31F1EA8AD52435873 /* ASCollectionLayout.h in Headers */, - EE9826EAD4013D63E0102D26BDD5E460 /* ASCollectionLayoutCache.h in Headers */, - 8CE679AB1CE25AD3CB3BE134A206DB26 /* ASCollectionLayoutContext+Private.h in Headers */, - 91EFE7EF1EC22F6738D99690A572D007 /* ASCollectionLayoutContext.h in Headers */, - 60E8314B695F682FCF6706C3255FF541 /* ASCollectionLayoutDefines.h in Headers */, - F40D3A0927A12DC0CA8E02FBD4A98AC7 /* ASCollectionLayoutDelegate.h in Headers */, - 6041607BC6CEC6D5727CD75BD44F0CE1 /* ASCollectionLayoutState+Private.h in Headers */, - AF58796BAFCDA0138554EF6F8C388EA7 /* ASCollectionLayoutState.h in Headers */, - 9DB1B4681E1BD5B5180D5F5A74EAC1A7 /* ASCollectionNode+Beta.h in Headers */, - 93A2714B5C617D45BA9E4D8460B29357 /* ASCollectionNode.h in Headers */, - A3DCB42D23A31F02C36CD9FB4AD19186 /* ASCollections.h in Headers */, - 7C27E5F68E9EB61979B1E88841500324 /* ASCollectionView+Undeprecated.h in Headers */, - C4BEE12FE70FC9F48E1178A70756AA0A /* ASCollectionView.h in Headers */, - E9FDE332EF4FB89FBF5865A984B4E650 /* ASCollectionViewFlowLayoutInspector.h in Headers */, - BE59001D9DB09B6CD705182FDAD54849 /* ASCollectionViewLayoutController.h in Headers */, - 178246C79CE61DF43CC5578F9CC506B3 /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */, - D51D44504EF0A8D760929A136FC580FA /* ASCollectionViewLayoutInspector.h in Headers */, - 7FCBE3CFACCF27A81091AC9F96E7A026 /* ASCollectionViewProtocols.h in Headers */, - E9445389569C3B57DC6184A48247CA17 /* ASConfiguration.h in Headers */, - 2790D1518B5518A127BF3AA6A3067804 /* ASConfigurationDelegate.h in Headers */, - 469C351BC6D64602B1742D5F0045BD29 /* ASConfigurationInternal.h in Headers */, - C6BB719F1B9AEEA25559EC0A0A8B1EF6 /* ASContextTransitioning.h in Headers */, - ABD2F42F5CA66A0DF0CB77FD77ECE5FF /* ASControlNode+Private.h in Headers */, - 3005777C0CE73129A6B810B3555D2F2D /* ASControlNode+Subclasses.h in Headers */, - 1C687D3F4D8F67B2032CF289BB9AB025 /* ASControlNode.h in Headers */, - 5D309A8ABE8407419521CEACEC94444E /* ASControlTargetAction.h in Headers */, - 3C28F730FA7B9B85C19031FAFC4500FE /* ASCornerLayoutSpec.h in Headers */, - AA5B44790F97B6CDA6F650E1028456EB /* ASDataController.h in Headers */, - 471BC5ABB7D0E3B32E5C3F43F461F256 /* ASDefaultPlaybackButton.h in Headers */, - A43975A29E7120EAD986F334818BB97F /* ASDefaultPlayButton.h in Headers */, - EF4C0AB9A764F1E676C064BB9BFF41BA /* ASDelegateProxy.h in Headers */, - 0640D451C48BDD8858DA1EFA09998318 /* ASDimension.h in Headers */, - 61C78F3D284DB41CBB280CBEC4AB47F4 /* ASDimensionInternal.h in Headers */, - 9EA768EAC7DD105D55C6E0ADE5C11A44 /* ASDispatch.h in Headers */, - 250D19DEB99FD549897E6B9C20A5CAAA /* ASDisplayNode+Ancestry.h in Headers */, - 96C54E25711BFD7A16443DE074CCF6A6 /* ASDisplayNode+Beta.h in Headers */, - 89FCE49736568D9D968ACBA85F4E8FE1 /* ASDisplayNode+Convenience.h in Headers */, - BABF973B5B192D51D6C4F7456103BE75 /* ASDisplayNode+DebugTiming.h in Headers */, - 02A6DB9492DDC5300BC18FB2FD203B06 /* ASDisplayNode+FrameworkPrivate.h in Headers */, - E144FAB97090ABE2509D521A107C550A /* ASDisplayNode+InterfaceState.h in Headers */, - A033E8E58BF2B79C8DEFE5D940E041F5 /* ASDisplayNode+LayoutSpec.h in Headers */, - B91877FE183B4921AC6F3DD06246EBA7 /* ASDisplayNode+Subclasses.h in Headers */, - 369C1DD571DE019562ADE66655FE36D3 /* ASDisplayNode+Yoga.h in Headers */, - FFEAD4B42A1A5B7C625A65F682BDC889 /* ASDisplayNode.h in Headers */, - DE5647C516D1BFDA0500E66F88A9114F /* ASDisplayNodeCornerLayerDelegate.h in Headers */, - 72F6F0CC202391378422014A75933647 /* ASDisplayNodeExtras.h in Headers */, - 413452835A420243CD07E4FAC1D0B3B1 /* ASDisplayNodeInternal.h in Headers */, - 2C489D68B1A024EFF3E7364EC82D8126 /* ASDisplayNodeLayout.h in Headers */, - D7B81994873CE58FC1520DA0AC804398 /* ASDisplayNodeTipState.h in Headers */, - B3EC6CC66DCD0E7C779CCE05A52FCA16 /* ASEditableTextNode.h in Headers */, - 9717C51CEB89E213E78999453DC842BD /* ASElementMap.h in Headers */, - 8C1C4738C8EDA4CC19C0E3DEB0AC6DB5 /* ASEqualityHelpers.h in Headers */, - 9D62D32EB5AE2F7884B5E616F40FA296 /* ASEventLog.h in Headers */, - 337CDAF5180D8D774C75895165C67D49 /* ASExperimentalFeatures.h in Headers */, - 7A8F02BCDCA7BED9E86546B9B8D10C9B /* ASGraphicsContext.h in Headers */, - 3239D33A632969DE1D916FF47EDC2323 /* ASHashing.h in Headers */, - 418AB08FFDAE36CF2098EC8C0000E462 /* ASHighlightOverlayLayer.h in Headers */, - E22741A4AFDACFD4EFA1796CD566D9A0 /* ASIGListAdapterBasedDataSource.h in Headers */, - C6DC15608E4521CB5D4580A4EB9E80A5 /* ASImageContainerProtocolCategories.h in Headers */, - 0D73C8C9DC543315F1B17E1815A3D2F1 /* ASImageNode+AnimatedImagePrivate.h in Headers */, - 83008984A17DE638809E3C6791924A01 /* ASImageNode+CGExtras.h in Headers */, - 0D6395EA2227BAA083EA3F045E165EC5 /* ASImageNode+Private.h in Headers */, - BFBF2B9AE08BE7EE2104716D4DAEBEAB /* ASImageNode.h in Headers */, - DBBE66619BE131AAB0ED29B21F4C0782 /* ASImageProtocols.h in Headers */, - 4A25794D6B189477201E5B59C041EC84 /* ASInsetLayoutSpec.h in Headers */, - C3D2774B53014573A099E87AA4C0CED8 /* ASIntegerMap.h in Headers */, - D80EA33818CC22A16D38B466350CED22 /* ASInternalHelpers.h in Headers */, - 9CC2B88E26F683FE73C473A17936AB65 /* ASLayerBackingTipProvider.h in Headers */, - 68F351CE7440322DC392C7236A6FE2E1 /* ASLayout+IGListKit.h in Headers */, - C3D0D54F1D4AC76E5159ADE76A4BF3E5 /* ASLayout.h in Headers */, - F7B128017791AC59B7F495BFBDEDF46C /* ASLayoutController.h in Headers */, - 341FC0D3130F9D9AF4B060B02921A8BB /* ASLayoutElement.h in Headers */, - AADB3FB272AF788B501CA83C13A04256 /* ASLayoutElementExtensibility.h in Headers */, - 0DD653DC248232E3421B2BDAA665EE07 /* ASLayoutElementPrivate.h in Headers */, - 802BB286EA6040319B686BCA471CBE2D /* ASLayoutElementStylePrivate.h in Headers */, - EEC8FA0CF9FC6D0865029B43A2DA1579 /* ASLayoutManager.h in Headers */, - 317E4E8B93A75823613C601DFFCF3B4E /* ASLayoutRangeType.h in Headers */, - 9D5AED0578E631788B8D9895C1B949E4 /* ASLayoutSpec+Subclasses.h in Headers */, - 5B6BD09559DC9FD1598F007FACFDDF4A /* ASLayoutSpec.h in Headers */, - F259DE3E21154420D8C2D9C786100761 /* ASLayoutSpecPrivate.h in Headers */, - 4E441B704883F919B3E9E7B053EB1582 /* ASLayoutSpecUtilities.h in Headers */, - B8C0C60FA8A8D1523B5E966079559F1F /* ASLayoutTransition.h in Headers */, - A5F9BA06922BEC0C77A87D10E3369359 /* ASLocking.h in Headers */, - E594B2023EDA296EB759343493CCC0B1 /* ASLog.h in Headers */, - C68FF971E5ADEAA4FC8C82CEFA83FCAE /* ASMainSerialQueue.h in Headers */, - 8D266BD043026CFD80471BC9149FF30E /* ASMainThreadDeallocation.h in Headers */, - 32755CD2F36CBBDD8493829C91DC192A /* ASMapNode.h in Headers */, - F7936E3687857A615BB7E330C12081B0 /* ASMultiplexImageNode.h in Headers */, - A6CE791214EA7B272BDBD2A8FB34CD56 /* ASMutableAttributedStringBuilder.h in Headers */, - DC709A9A173411EDA887B60009912C0B /* ASMutableElementMap.h in Headers */, - 071C5AE6A74A0CBFEE0A5E02D0ED5AEE /* ASNavigationController.h in Headers */, - B556BFF1FE33E6C7E520CD0441F86555 /* ASNetworkImageLoadInfo+Private.h in Headers */, - 10DBE461D8A06CE975D03AE020106808 /* ASNetworkImageLoadInfo.h in Headers */, - A12A3B1598439F5E521304D01DD71980 /* ASNetworkImageNode.h in Headers */, - BCB68BB3E16B87F0C927313DC119424E /* ASNodeController+Beta.h in Headers */, - 84F093402374686E873B5F8F4F1603E5 /* ASObjectDescriptionHelpers.h in Headers */, - 69E72A894605CAF7EF193A72D998F405 /* ASOverlayLayoutSpec.h in Headers */, - 10D685AF3B1C113F3E459C939ABDF7F1 /* ASPagerFlowLayout.h in Headers */, - AB8598927B43148CE5839F78DF6019B3 /* ASPagerNode+Beta.h in Headers */, - 3D030866F9597CB3CA56ACCFE037BA10 /* ASPagerNode.h in Headers */, - 16642C1D32032DBB54C485753C29E3A9 /* ASPageTable.h in Headers */, - 6DF19AC2B068CB4D76C669934D5DA485 /* ASPendingStateController.h in Headers */, - 0579970DD7F65FFC5ED5B3403CFE1D69 /* ASPhotosFrameworkImageRequest.h in Headers */, - 4645B27FF433ED2750B4309F2489FC50 /* ASPINRemoteImageDownloader.h in Headers */, - 2137C3377BF2B235A0BA017C04B5AB2E /* ASRangeController.h in Headers */, - 5D1565CA4B17BCB9FDDF642A8C002A4F /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */, - 1739373E24C91A75D0D20FEC8170563E /* ASRangeManagingNode.h in Headers */, - 5720B9A487E2CA3174F80DD0C547F608 /* ASRatioLayoutSpec.h in Headers */, - BCE1BD0B7DCCEC19DB489FD3BB67EE62 /* ASRecursiveUnfairLock.h in Headers */, - 083D3FC1CE6C10C882D9D0C710C3DC7A /* ASRelativeLayoutSpec.h in Headers */, - DF9D78163203047F4A090E5E5A83034D /* ASResponderChainEnumerator.h in Headers */, - 00391BEF007FBA57A883F62A58C0ABEC /* ASRunLoopQueue.h in Headers */, - DA24A30C9DEDAA65BF82D23DBF1E18CC /* ASScrollDirection.h in Headers */, - 2CAE4CE007DCB8DBE3151C63D0741D5C /* ASScrollNode.h in Headers */, - BF479ECC5281CC06975C21B7E4B2689B /* ASSection.h in Headers */, - 11E4083FE5D92B1DC32D1165F97915D6 /* ASSectionContext.h in Headers */, - B15A3220207A7B9906FAC195E58C28A5 /* ASSectionController.h in Headers */, - BD71AB07F2DAD99A050F4B20FCA710F4 /* ASSignpost.h in Headers */, - 342A6850D79799714A72A1CB4A398F4D /* ASStackLayoutDefines.h in Headers */, - B62ABD16DB7DF5FE2F5E1B40E523CFDA /* ASStackLayoutElement.h in Headers */, - 5C364041B76A92A144283D38876524E9 /* ASStackLayoutSpec.h in Headers */, - 7DFC26E0B67DF88BBBE9AC332F6B8DF5 /* ASStackLayoutSpecUtilities.h in Headers */, - F0B1C782468C4E0A2D8EEF0C75AF7503 /* ASStackPositionedLayout.h in Headers */, - BCAEECEBCD2631F3331DABAA79A5EF45 /* ASStackUnpositionedLayout.h in Headers */, - 95B3312084D6FC4F8156EA5103367891 /* ASSupplementaryNodeSource.h in Headers */, - D91C82DAF9D9C5D5338B154770E5CDBA /* ASTabBarController.h in Headers */, - 6EC39DA7EF570831DDD7333E862B683F /* ASTableLayoutController.h in Headers */, - 65E418C3F2B732069D641B3CAA82D3C5 /* ASTableNode+Beta.h in Headers */, - FFBF9735C8C5AA11E62017EB58440E8A /* ASTableNode.h in Headers */, - 2B65580877A4771FF00AB1120636E94F /* ASTableView+Undeprecated.h in Headers */, - 5CB479B0FEE291255662867DE7FD8399 /* ASTableView.h in Headers */, - 8D9FD022C6378039CE5ABDC733C96157 /* ASTableViewInternal.h in Headers */, - D45F1A1B99E2307710FB21A12E7CEA47 /* ASTableViewProtocols.h in Headers */, - 82FAA5D094671D3E80C780F797E706E9 /* ASTextAttribute.h in Headers */, - D8E28917CF1DBA136BE47898774C4AFC /* ASTextDebugOption.h in Headers */, - B657E5107351084226E67342A4616E78 /* ASTextInput.h in Headers */, - BF7A2BE0EDC947CA0B96A79A0E8A85B0 /* ASTextKitAttributes.h in Headers */, - 6F38B3364F5E8E7CFAE3F75665C6680A /* ASTextKitComponents.h in Headers */, - 800B28591DEE42878E61A0CE4479B452 /* ASTextKitContext.h in Headers */, - 0059D15A6BCB46E90F712F915EE11B82 /* ASTextKitCoreTextAdditions.h in Headers */, - 0F8E467E705C3E5BF72DD363595CA32D /* ASTextKitEntityAttribute.h in Headers */, - FF1496139C9609A42E5571CD9A20D40E /* ASTextKitFontSizeAdjuster.h in Headers */, - D98D4D50645DBEC555A76768B120960F /* ASTextKitRenderer+Positioning.h in Headers */, - F226556F01BEFDF2DE085670133A3149 /* ASTextKitRenderer+TextChecking.h in Headers */, - 55FC8B0BB41DD8D17143B6983BAAB8E3 /* ASTextKitRenderer.h in Headers */, - D4D187C5502D1B6BE469EB84707455CD /* ASTextKitShadower.h in Headers */, - B62DD4DFA44285E33BE86A99104E7CFA /* ASTextKitTailTruncater.h in Headers */, - 81D8CB5489749AD323DCC8FF7B5DA738 /* ASTextKitTruncating.h in Headers */, - 9F970FCFAD7D3A9D6E6C8DD64D8BE519 /* ASTextLayout.h in Headers */, - 2872FE27D5885A9FB8CB020F330AB19A /* ASTextLine.h in Headers */, - 01A3D7BB0E63D3A900D0A0865A2D547B /* ASTextNode+Beta.h in Headers */, - A2CE68BDBED902622AF5A34FDDF7FF78 /* ASTextNode.h in Headers */, - E23A7BFDFD83FB3EF705AE91EDE800C0 /* ASTextNode2.h in Headers */, - 6F98B53F8BD238D23C4FB3A1A984E831 /* ASTextNodeCommon.h in Headers */, - E931910D623E887EE1B3E9635BEA0906 /* ASTextNodeTypes.h in Headers */, - 912D70FE36FF86469754897249570AFF /* ASTextNodeWordKerner.h in Headers */, - 27F239354D9946FFCD3A1128E1A361DC /* ASTextRunDelegate.h in Headers */, - 38E99CD9A2904EBF5DBB0F33BBED2CC6 /* ASTextUtilities.h in Headers */, - 8F9E256B8EABE696443FC7ABFE7631D7 /* ASThread.h in Headers */, - 1687E1405D8B76F297F6D9853BAB346E /* ASTip.h in Headers */, - 6AA9E27C2D6FEF10A9C0C6F1EE05A171 /* ASTipNode.h in Headers */, - 045B3BAABA7A144648846AEB06F8D093 /* ASTipProvider.h in Headers */, - EBF6479922ED01E185419A2FDE61454C /* ASTipsController.h in Headers */, - C6739911713F8557CF19854FEEBF1F7B /* ASTipsWindow.h in Headers */, - A9F53C282E93B0FB9FBEEE518FD295EF /* ASTraceEvent.h in Headers */, - C0086BD4E33E2BA653D4017DE6496C75 /* ASTraitCollection.h in Headers */, - ACD14DC8F6B89D7AD9E4047D89D7D5DE /* ASTwoDimensionalArrayUtils.h in Headers */, - B5332B7972E79B05B5E0EE2DDD0935DE /* ASVideoNode.h in Headers */, - 7263DE605516B38C4FA0F16E3FD4D981 /* ASVideoPlayerNode.h in Headers */, - 3CA7DA2DB852372F0CDCE063EC8BE397 /* ASViewController.h in Headers */, - FDF5877D38A81924C6A93138F33E3550 /* ASVisibilityProtocols.h in Headers */, - 9D92116AFE6C294869B1C2FFB0F9961B /* ASWeakMap.h in Headers */, - ABC2CC3E9F276C53711D53CD969E5E1A /* ASWeakProxy.h in Headers */, - 4E5D73F550952F377F7DFEF867C27DF5 /* ASWeakSet.h in Headers */, - 81166544D68BCBBB67F86AAB363EA440 /* AsyncDisplayKit+Debug.h in Headers */, - A4B3C475BEB8068C0B51A528C7C4F949 /* AsyncDisplayKit+IGListKitMethods.h in Headers */, - 89D81BC4E48F24D79618C79FC465EB02 /* AsyncDisplayKit+Tips.h in Headers */, - 11D7CF9506912DAADBA5ABF214E50103 /* AsyncDisplayKit.h in Headers */, - 3BF659B8C25F5BF3A88F50E2405EDAC7 /* ASYogaUtilities.h in Headers */, - 47244AD1C3D2DD40C6276E0E2B10C2F8 /* CoreGraphics+ASConvenience.h in Headers */, - 7845B815BDBA490E7BE225C43E9AD527 /* IGListAdapter+AsyncDisplayKit.h in Headers */, - F69C784A2AA9D039BDF1CDBB521025BB /* NSArray+Diffing.h in Headers */, - BE0308C81B8EB5C5854C50AFE4EC5F05 /* NSAttributedString+ASText.h in Headers */, - 4C480FDD8ADE120B5B9CDE009485248C /* NSIndexSet+ASHelpers.h in Headers */, - 945CECD5F856F8152BC44D08FE852CCF /* NSMutableAttributedString+TextKitAdditions.h in Headers */, - 25CF24BA0C6AAF9ED814A06492F5D70D /* NSParagraphStyle+ASText.h in Headers */, - 82E1F9883A68CC966B271D7AA1914358 /* Texture-umbrella.h in Headers */, - C5CEB80D72E251F94F35D3B6FB3EBAA8 /* UICollectionViewLayout+ASConvenience.h in Headers */, - 41A0BD05412EE95BC6D3FCF8D948FFE9 /* UIImage+ASConvenience.h in Headers */, - DC8601FE08234A9822B7C2514E1D1BC0 /* UIResponder+AsyncDisplayKit.h in Headers */, - 14B16D82223A9415B11A0158A2D627B9 /* UIView+ASConvenience.h in Headers */, + DF3EC03998606F8C6B59E9B8FA250DE1 /* NSData+ImageDetectors.h in Headers */, + E66C56441574428F0E6319DD42712F00 /* NSHTTPURLResponse+MaxAge.h in Headers */, + FA09956C6A65F04B260B032B19C3C408 /* PINAlternateRepresentationProvider.h in Headers */, + DEB64B74E02E6B5A3942813C4B0AA43A /* PINAnimatedImage.h in Headers */, + 938190A76B28D4FBC6FBD6EE39D3D21B /* PINAnimatedImageView+PINRemoteImage.h in Headers */, + 3F032BD5B92DB1386DD5F553C335D2AF /* PINAnimatedImageView.h in Headers */, + A616785B7772BEEE063DDDCC1A5C06B6 /* PINButton+PINRemoteImage.h in Headers */, + D83ADCEE529736987678A5E5678C3EF4 /* PINCache+PINRemoteImageCaching.h in Headers */, + F8D6DE5B1A9935A9B5C53769624F1C53 /* PINCachedAnimatedImage.h in Headers */, + 5AA521195197A5269FE3C52EE1F612FC /* PINDisplayLink.h in Headers */, + D27BEF1A0F0747FE98EF2B4AC76297BA /* PINGIFAnimatedImage.h in Headers */, + D55227D66C8BD0B9EF66806624057C53 /* PINImage+DecodedImage.h in Headers */, + 7615B92004681A1F0CE6E7F61389AC91 /* PINImage+ScaledImage.h in Headers */, + 331FEDE9B0C941A741D0076745ECE9F4 /* PINImage+WebP.h in Headers */, + 0D1AFB17D23CD14FEF004D8F753E170F /* PINImageView+PINRemoteImage.h in Headers */, + D5C26BE5B56878BE80E4E358D01505BF /* PINProgressiveImage.h in Headers */, + 329730AC1D8EB74370375033D89CAA04 /* PINRemoteImage-umbrella.h in Headers */, + FFA03ECBF831BCB7A9BB9D3AB5168587 /* PINRemoteImage.h in Headers */, + 8C59DA4CCC93CE415C2A15348CBFC83D /* PINRemoteImageBasicCache.h in Headers */, + 32E39D4168AA61D28735332214FD7A68 /* PINRemoteImageCaching.h in Headers */, + 792C265DC6709DF747E801A984353998 /* PINRemoteImageCallbacks.h in Headers */, + 79DEAF233C0FDF9487841F3A5226FE89 /* PINRemoteImageCategoryManager.h in Headers */, + 63585E8148886E80CB182E3920C51A11 /* PINRemoteImageDownloadQueue.h in Headers */, + 2E8CD8DDE7442B3C033B24194762F66B /* PINRemoteImageDownloadTask.h in Headers */, + 918B6F04B2ED6C34247F3355BB118462 /* PINRemoteImageMacros.h in Headers */, + DADB3AD2B89E46C6A114C733FCCFFCCF /* PINRemoteImageManager+Private.h in Headers */, + 04543BFEF8F8F32EE2B4A3304471A5F4 /* PINRemoteImageManager.h in Headers */, + 44231872CA5D99230474B02A713D193C /* PINRemoteImageManagerConfiguration.h in Headers */, + D792C77237A52B9B995A8A2E9FD39B2C /* PINRemoteImageManagerResult.h in Headers */, + 23E59691FBD46D8ACF53E02745593028 /* PINRemoteImageMemoryContainer.h in Headers */, + 02131FDD47626B3DCE579DFFC4E44CC2 /* PINRemoteImageProcessorTask.h in Headers */, + 588F5E132A531BF1B16C0FE24359FDA2 /* PINRemoteImageTask+Subclassing.h in Headers */, + CBEBD4CC5E49C32325142632AF551934 /* PINRemoteImageTask.h in Headers */, + D22F83E790D592BF6759A38C4001B050 /* PINRemoteLock.h in Headers */, + B5563B5BB14EBE69B0684B4C5A96F51A /* PINRemoteWeakProxy.h in Headers */, + C2B195B9AEF986D33CFF546944B10CDA /* PINRequestRetryStrategy.h in Headers */, + 45F21A0B56EC7B9577BC185A9ED007C4 /* PINResume.h in Headers */, + 5BFC4E12BD19E6A80D098D6A1288A43D /* PINSpeedRecorder.h in Headers */, + 25D87433F8998220C56DEB0CDDA167CA /* PINURLSessionManager.h in Headers */, + EAAACE6B4C88D9F0E4E8EC5CD698212C /* PINWebPAnimatedImage.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 1A4F2F7054609F2B50DFFBFFE028DC8B /* Headers */ = { + 2B86A805238C4F578280ABEFEFCE6D84 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 315D377B615593093071B69214134A03 /* Pods-Zoomy_Example-umbrella.h in Headers */, + 34529C466F5F797A6DE9080771A0427B /* Zoomy-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 38292BF5BFA07E265E0B720FDE8244D1 /* Headers */ = { + 3E04099278515D8B78AC25F1332C43C0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - CCEB9E6D89EA304ABF7D2ECF466B81D1 /* Zoomy-umbrella.h in Headers */, + 97B21F896732B315973456E97591AA04 /* Pods-Zoomy_Tests-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 56926779FD48CE6BC5A1285CEA3CA0CC /* Headers */ = { + 8FF077A241B3FC1B8D522A55D177EA98 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 15160F9217A3745BD8A1EAEA1FC121E5 /* PINCache-umbrella.h in Headers */, - 5D0E890EC641AAFB45DFF527CF1C7137 /* PINCache.h in Headers */, - 2D782F36DA488D371DF71775675CAA6A /* PINCacheMacros.h in Headers */, - 189DFEFB1A0130E9E4C859D5908032CC /* PINCacheObjectSubscripting.h in Headers */, - 9C2BB387083631012EB5C1EC1F8EE729 /* PINCaching.h in Headers */, - 16B7CFBB89DD8CBF96D4210337038E52 /* PINDiskCache.h in Headers */, - BCB657CBC4EF85FDD1F4F441C82D2A1D /* PINMemoryCache.h in Headers */, + 45112E474BA6016E05CED490D795AEC5 /* InjectableLoggers-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 65BE7F177614FB472D255DDDF16F6B49 /* Headers */ = { + BA923AD163937D722E40905AF3F28F6F /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 1EE6187046660F0B4B75F24D41C394F1 /* Pods-Zoomy_Tests-umbrella.h in Headers */, + 7A541079985175ED988475511FE5F2DC /* PINCache-umbrella.h in Headers */, + A468E4B8A47DCEC32494D8A69DAD4F2D /* PINCache.h in Headers */, + DE1FBD64E727449DFEB41D8CC0B764E4 /* PINCacheMacros.h in Headers */, + 354D5F302A89E5FA56123389EE9EF229 /* PINCacheObjectSubscripting.h in Headers */, + 681352C165A0A0DE357DFC95EF35D7ED /* PINCaching.h in Headers */, + 901059B0F79E50EA1BDACFD9B1A9D5CF /* PINDiskCache.h in Headers */, + 31E23F58653E80531A771415273BECDC /* PINMemoryCache.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 85A0ABC20A5B8AD24473F6E5CA432E8D /* Headers */ = { + CC0BD8F7B8855A58F797A585AFECBFEA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 8C97E12E8495FCF40CFFAE2D8D49AA26 /* NSData+ImageDetectors.h in Headers */, - B9F5A92FBE728D489778375486C724F1 /* PINAlternateRepresentationProvider.h in Headers */, - BB5681D14586A11A9AD8EB98441AF89C /* PINAnimatedImage.h in Headers */, - 159B31B50A5D17400CDE79FE85A619B5 /* PINButton+PINRemoteImage.h in Headers */, - 8663349419F69078AD6A1478F4BCF3CE /* PINCache+PINRemoteImageCaching.h in Headers */, - 46AA07F4FBF287F956D146C0008A9A3F /* PINCachedAnimatedImage.h in Headers */, - D33347049E4B7BF7ABC7E8674A2B74FB /* PINGIFAnimatedImage.h in Headers */, - 1F08CA3527039D1F70D90D8F2953B616 /* PINGIFAnimatedImageManager.h in Headers */, - CE2A06018735F6148FC6DE9E101DD198 /* PINImage+DecodedImage.h in Headers */, - 0926F72040D685FA90F0E1D0E63E236E /* PINImage+ScaledImage.h in Headers */, - 9D0817112AF21F39E12B9728BD57C178 /* PINImage+WebP.h in Headers */, - 0849CFDCCA9EBB766739F0123AC2B0A6 /* PINImageView+PINRemoteImage.h in Headers */, - 8883D817E3D5C322CD723CADF2B0589D /* PINMemMapAnimatedImage.h in Headers */, - AC24A47998913E653B537670122C8776 /* PINProgressiveImage.h in Headers */, - CBA83C25D3648F8445A0FE102057E32C /* PINRemoteImage-umbrella.h in Headers */, - 8705C173FB3E22334E41089FCD1D6338 /* PINRemoteImage.h in Headers */, - 9C60DBF2ABB6A7BCB9E90131D77D1DD5 /* PINRemoteImageBasicCache.h in Headers */, - 1ECA3D2CAA1C10E287A264E15ADB5C55 /* PINRemoteImageCaching.h in Headers */, - B7192267427214D14ED60D794277A00F /* PINRemoteImageCallbacks.h in Headers */, - 1FDCAB680F4DB300A4CF17EBD4960E8E /* PINRemoteImageCategoryManager.h in Headers */, - E9C4997FA9B5ECCCD2CDF876A2370BAC /* PINRemoteImageDownloadQueue.h in Headers */, - EC2BCD8F8DA759BB81C550F90BA144E6 /* PINRemoteImageDownloadTask.h in Headers */, - BE343ADDB5FC9F09B811B65C34577B96 /* PINRemoteImageMacros.h in Headers */, - 027F6D0B71B1C122F3DB0C889E14362D /* PINRemoteImageManager+Private.h in Headers */, - 10098F7134E99EF773535B6E07CB11C0 /* PINRemoteImageManager.h in Headers */, - DFBC058FFFAFAB5171AAB6050B29E4C0 /* PINRemoteImageManagerResult.h in Headers */, - 37F0A65D271A4278C9D59169D03F8A8F /* PINRemoteImageMemoryContainer.h in Headers */, - 1D6AFE79A5A65E81A6FCCB54DCD48D67 /* PINRemoteImageProcessorTask.h in Headers */, - 4FB8C73D7379AE01AE0D167CB8CF75C6 /* PINRemoteImageTask+Subclassing.h in Headers */, - 98AA250E903BA51AD650001A279AE9DA /* PINRemoteImageTask.h in Headers */, - 1F7ED5B3492CAD695B3A869203CF7E5C /* PINRemoteLock.h in Headers */, - 5FA9B797FDB867D05726693E35AE0C35 /* PINRequestRetryStrategy.h in Headers */, - E9DAD8B9BFF1BC7B4AF531B0630DE2A4 /* PINResume.h in Headers */, - EB7F659A9B5091F89DEC4A342B81B4F6 /* PINSpeedRecorder.h in Headers */, - 280708CDEBF58DAADAE72928157A82CD /* PINURLSessionManager.h in Headers */, - 249C5B2AFC9EA963597A509989F8AA6C /* PINWebPAnimatedImage.h in Headers */, + 74A2F87A0316F3AACB1B416593D49D4B /* Pods-Zoomy_Example-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 8FF077A241B3FC1B8D522A55D177EA98 /* Headers */ = { + CFDD8E01973A320462A7591B41B1F068 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 45112E474BA6016E05CED490D795AEC5 /* InjectableLoggers-umbrella.h in Headers */, + B0917E444B1352AF7285C09EF420028D /* _ASAsyncTransaction.h in Headers */, + 8DE9CA21A7082FC2A937E3DBF78E3A0F /* _ASAsyncTransactionContainer+Private.h in Headers */, + CC2E10F3DE5A2E0DEF91BF948FE2E06C /* _ASAsyncTransactionContainer.h in Headers */, + 37BBB02A7D765725890D32944453EB98 /* _ASAsyncTransactionGroup.h in Headers */, + 28F61DD0EBC89532FF28A6F967B0DBC7 /* _ASCollectionGalleryLayoutInfo.h in Headers */, + 2730E2AB0DF38DB833EF6AD02E788C2D /* _ASCollectionGalleryLayoutItem.h in Headers */, + 6AFFA660CBFFBF81A6DC1F34AC2B9E39 /* _ASCollectionReusableView.h in Headers */, + 7BAB8B3B6369EDFA0C7D13F60FBC6794 /* _ASCollectionViewCell.h in Headers */, + 37163A6F77A6128EA54B197A1B6E2AF3 /* _ASCoreAnimationExtras.h in Headers */, + B878FFB40DC743FA707E282E2F66C060 /* _ASDisplayLayer.h in Headers */, + E061922DF3A631DE569DEC0B02A0E55C /* _ASDisplayView.h in Headers */, + DFEDDB04D68B8A713D24FAB88F55988B /* _ASDisplayViewAccessiblity.h in Headers */, + 0368A0C1EE4DCCF63368E227AABF90FA /* _ASHierarchyChangeSet.h in Headers */, + 1B7F2F9ABEC6E2EF28D4200AAA0EA967 /* _ASPendingState.h in Headers */, + AB100DDB742EE0376A45715B42344509 /* _ASScopeTimer.h in Headers */, + E3DBA9B2AD2B13F98ABC7894743C5FF1 /* _ASTransitionContext.h in Headers */, + AF55C78E39FBB0158FDD1F04874978C2 /* ASAbsoluteLayoutElement.h in Headers */, + 2E1B3B900BECDFD697A94397EB3208A8 /* ASAbsoluteLayoutSpec.h in Headers */, + 8CF2DBA98444B46D088E8FC193E26B9D /* ASAbstractLayoutController+FrameworkPrivate.h in Headers */, + FAACAA3FAADE3A8D89DCE1E374BECEA7 /* ASAbstractLayoutController.h in Headers */, + 39441BD56324DADDA1A7387A039B11B4 /* ASAsciiArtBoxCreator.h in Headers */, + 3BC85D01305C01A02D674354EA81231E /* ASAssert.h in Headers */, + A93E5D1247E109BF74D6E0E0C56A1CA2 /* ASAvailability.h in Headers */, + FDA5B5348C842BAC45AE14D72B2E2782 /* ASBackgroundLayoutSpec.h in Headers */, + BEB3FA36F7395B27F36C4784927C3CFE /* ASBaseDefines.h in Headers */, + 46A6E2A05E106239C6D1B2429E6363CE /* ASBasicImageDownloader.h in Headers */, + BE9C538F9315DBDF8511D7B1C143276F /* ASBasicImageDownloaderInternal.h in Headers */, + DE43FB61D54CA4D4683A2976E2C4B17A /* ASBatchContext.h in Headers */, + B4419404D375692A51B0D095CAB19B67 /* ASBatchFetching.h in Headers */, + EBB98BADBF34A5832DC9812C4D45C02F /* ASBatchFetchingDelegate.h in Headers */, + 33AE74DEA0304E22B4B020C037BB4E8D /* ASBlockTypes.h in Headers */, + 5F4B683A5C8770F9092E0F839DC279B8 /* ASButtonNode+Private.h in Headers */, + 89CCF29068794758917D5BC53196B619 /* ASButtonNode+Yoga.h in Headers */, + E85CBF5F58F5FF76148975C11E38F27E /* ASButtonNode.h in Headers */, + AA177091C108492974D400BDB1A1CD62 /* ASCellNode+Internal.h in Headers */, + 690EAE385194D53B290B805C46BA4EF6 /* ASCellNode.h in Headers */, + 9BB40B9E5A27F0D228FDA2654B90A0C6 /* ASCenterLayoutSpec.h in Headers */, + 6DA1B9D0492B013012EC140F453A9C89 /* ASCollectionElement.h in Headers */, + 68C7FCDF3699122D51BBB8D181CE2A4F /* ASCollectionFlowLayoutDelegate.h in Headers */, + D511B3184C8CA22900E8CF81946472FA /* ASCollectionGalleryLayoutDelegate.h in Headers */, + C819EBDDE5B4938A862427E81C9B66E9 /* ASCollectionInternal.h in Headers */, + 4B16631D2EC2D5D065CBB55DC8881D0D /* ASCollectionLayout.h in Headers */, + B53BAD4FEA26F027B02C817B0D56B03F /* ASCollectionLayoutCache.h in Headers */, + 128159D60F5F30A14FFA7E2216B689A8 /* ASCollectionLayoutContext+Private.h in Headers */, + 8C31797394C8EC3AA2597206372419D9 /* ASCollectionLayoutContext.h in Headers */, + FC11F6DB1023A426B9D6DEC5FEAFEA20 /* ASCollectionLayoutDefines.h in Headers */, + AE00B7F987BD71B5EFD51D405455D667 /* ASCollectionLayoutDelegate.h in Headers */, + E028DD17CB226563694AD3E644DA0E8A /* ASCollectionLayoutState+Private.h in Headers */, + 4107EE649411835E2A9403AA3E75395E /* ASCollectionLayoutState.h in Headers */, + B9D87848BB35AC1F9280D3035D0E2BA4 /* ASCollectionNode+Beta.h in Headers */, + F1852DD8600E8B26A90C21441ED9FAF8 /* ASCollectionNode.h in Headers */, + 869A0AFC6E446D9559F81B9DE55339BB /* ASCollections.h in Headers */, + 7682DDBF21A55C03731203EDCBDFF27B /* ASCollectionView+Undeprecated.h in Headers */, + D2663A7660C2B444D8DFD65C341C210D /* ASCollectionView.h in Headers */, + 8DF538949C4DC97E959103D2208F3C69 /* ASCollectionViewFlowLayoutInspector.h in Headers */, + A248291B4CDBC90A07C1BCD8726C6CBC /* ASCollectionViewLayoutController.h in Headers */, + 8D5273A0FC56233E209A44A5FB5FC15B /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */, + FC78F578F793BE2AACE996A785F1C6A5 /* ASCollectionViewLayoutInspector.h in Headers */, + CF887DB488D89F9D6C22E641C34E37E5 /* ASCollectionViewProtocols.h in Headers */, + D8B254AD7AE2D4AD795D0F0D24A9DC63 /* ASConfiguration.h in Headers */, + F37A13201EAD5DDD51A3D7F7BA82C840 /* ASConfigurationDelegate.h in Headers */, + 85CA625022EC17DE0631D5B55F084FB7 /* ASConfigurationInternal.h in Headers */, + B205161CC6B478855EF36E244F0B2DA8 /* ASContextTransitioning.h in Headers */, + 17514581F08C4029877D4B19982B1AB0 /* ASControlNode+Private.h in Headers */, + 7367521E016788B60D3B821852CC1D49 /* ASControlNode+Subclasses.h in Headers */, + 32F74F879E223DC924F2D377B0E0438A /* ASControlNode.h in Headers */, + E80626C7D668DB07B848BEC6AAE711A4 /* ASControlTargetAction.h in Headers */, + 62642C50110C9B6D29E7CEBAD2B33BBC /* ASCornerLayoutSpec.h in Headers */, + 1D31956E47A1667E4ED78EDBCF63657F /* ASDataController.h in Headers */, + 45051BE690707C36628E0A3162A6655C /* ASDefaultPlaybackButton.h in Headers */, + 9ABA4A11DE428613126DA887698C5770 /* ASDefaultPlayButton.h in Headers */, + 1F51595178FA581C9FA84C59AAC0ADF2 /* ASDelegateProxy.h in Headers */, + 8A2E0B626887AF013A7F84103DA0A836 /* ASDimension.h in Headers */, + AC2E392B90F75B9B0B877513955A123D /* ASDimensionInternal.h in Headers */, + F7DCF358D078332CEB3F7AD5AAAC4530 /* ASDispatch.h in Headers */, + 55489F9E2C84ABA1DF343520666B7980 /* ASDisplayNode+Ancestry.h in Headers */, + C0A4A044D33E54CF070FA523D6FFA5AC /* ASDisplayNode+Beta.h in Headers */, + 15AB102788E5371031F010FB3494FDC4 /* ASDisplayNode+Convenience.h in Headers */, + 6A4E81CDAE9421C4389B34E66572AEAA /* ASDisplayNode+DebugTiming.h in Headers */, + 59ACDCDC7DDCA5D20DB4A8F2BB1D132B /* ASDisplayNode+FrameworkPrivate.h in Headers */, + 89C8791BCA6D98034A61A54E5FD9D4AE /* ASDisplayNode+InterfaceState.h in Headers */, + E8261A6238D988688A11ECD8B35A479C /* ASDisplayNode+LayoutSpec.h in Headers */, + B77EF1662C95CF840BD1498F309E8FFC /* ASDisplayNode+Subclasses.h in Headers */, + DCBB463A435F0BA2AA998D91A821BD63 /* ASDisplayNode+Yoga.h in Headers */, + 9ED8020DA12D0C5DBB23C41412BC265B /* ASDisplayNode.h in Headers */, + 458959AD13E6AC3374E81F6487F13B21 /* ASDisplayNodeCornerLayerDelegate.h in Headers */, + 1563756D23089B763B4317FAC682C06A /* ASDisplayNodeExtras.h in Headers */, + 625D5BDB7DC6971A04C2F0CC04E78316 /* ASDisplayNodeInternal.h in Headers */, + CB6EF8043EBA5C2100A53E6547E7FBD5 /* ASDisplayNodeLayout.h in Headers */, + DC9252B91D454E933573D0F02CD34A48 /* ASDisplayNodeTipState.h in Headers */, + 3E0ADF4FFBF1AEE2AFF6ADACAEFE3FA2 /* ASDKViewController.h in Headers */, + 4A5D639EB330216C5E0486C9CA40550A /* ASEditableTextNode.h in Headers */, + 162A11E39B08B85FD0E61EAB7E1FF9E0 /* ASElementMap.h in Headers */, + 8EDB472A1578F25B749BE234A65CAB68 /* ASEqualityHelpers.h in Headers */, + 1BC79FE7F10E5A56EBBB646BCA6A2974 /* ASExperimentalFeatures.h in Headers */, + 68158F620B989CD7611B3AEA782A5EEC /* ASGraphicsContext.h in Headers */, + B137969B8A651DA1148DEF66C0E26F73 /* ASHashing.h in Headers */, + 350592582D2BEEAD29989D3C406D296E /* ASHighlightOverlayLayer.h in Headers */, + 1FF802E6BAC65A931C00BE18248620DC /* ASIGListAdapterBasedDataSource.h in Headers */, + 292C3F25A497C5764E033ABE3491999B /* ASImageContainerProtocolCategories.h in Headers */, + AA38AD6092975ECEEE385AE0E53A830C /* ASImageNode+AnimatedImagePrivate.h in Headers */, + 667DE3D4FCA166D984EB80E3BD949F8E /* ASImageNode+CGExtras.h in Headers */, + 48FB2FA1183990E558E429461CDF77F4 /* ASImageNode+Private.h in Headers */, + 2EF0DBBD698C43C660D5C52D387762C3 /* ASImageNode.h in Headers */, + 09650E825B735144A1D66BFD8E55DE4A /* ASImageProtocols.h in Headers */, + F3E0A225E531BB32262D7D9E6BCCCC43 /* ASInsetLayoutSpec.h in Headers */, + 5D1C395E767F467B00623F3B9EF05B22 /* ASIntegerMap.h in Headers */, + 070ABBECB4EDE07A98B7B8194C7653F1 /* ASInternalHelpers.h in Headers */, + 5415B24BFD37F00BB5D405BCD49555EA /* ASLayerBackingTipProvider.h in Headers */, + 42C788E3094CBAAA03EC39561D7181DF /* ASLayout+IGListDiffKit.h in Headers */, + A655F6C0A8C3CE5A1554C2CCDE7AC866 /* ASLayout.h in Headers */, + F3457FE949B058184A4FB77C6AE576AE /* ASLayoutController.h in Headers */, + 33EBCAF7E4942B6C1E978213D1046FAF /* ASLayoutElement.h in Headers */, + 1D503DFE241AA255DA1D05DB8E0DAEFD /* ASLayoutElementExtensibility.h in Headers */, + 6D6BB69C4FAC4FC632BA75AD97D7D2AD /* ASLayoutElementPrivate.h in Headers */, + 2BEBC2DFEDD5845C56E21A6463822B63 /* ASLayoutElementStylePrivate.h in Headers */, + 12037D088DDA51D83DAED06FB069D79D /* ASLayoutManager.h in Headers */, + 5614B5D3B2DD1F30555A9233B65A2393 /* ASLayoutRangeType.h in Headers */, + FB849B4B080AD99E6AA582A08D0B136D /* ASLayoutSpec+Subclasses.h in Headers */, + E4AFCBB6059FC3C56FCE281FE6B88A14 /* ASLayoutSpec.h in Headers */, + 26B3AD7B5C5ED0A014DEFA3AA5CBD94A /* ASLayoutSpecPrivate.h in Headers */, + 9DF12A4EA63E693047BC33E9E9FB3458 /* ASLayoutSpecUtilities.h in Headers */, + 9572408CB866579D8EEFA59F946EC4C5 /* ASLayoutTransition.h in Headers */, + 6D342FAAF97311745F7FF709965F8273 /* ASLocking.h in Headers */, + 912138EAA142AB646C0AB9E4CDDFC505 /* ASLog.h in Headers */, + 92DD534C4085F25142F0ACFD4B930719 /* ASMainSerialQueue.h in Headers */, + 9E6C79BB56B41FFA1665D1E22479ADA2 /* ASMainThreadDeallocation.h in Headers */, + 8E50095CB420ADE04A0C30481174C03B /* ASMapNode.h in Headers */, + E2580439ED32A4AC27DF6CD05B69B472 /* ASMultiplexImageNode.h in Headers */, + 33AFC02D1DDFBFD1EEC47AFD8134C5F2 /* ASMutableAttributedStringBuilder.h in Headers */, + 49175285DAE0F984B215CA4FE269EB09 /* ASMutableElementMap.h in Headers */, + 4916347FD174C3002BE32C86D01422E3 /* ASNavigationController.h in Headers */, + 65EFFF712403A158D18F39A945B66278 /* ASNetworkImageLoadInfo+Private.h in Headers */, + A050FC9032EB0721F865B1DC6AACECE7 /* ASNetworkImageLoadInfo.h in Headers */, + AB48ADC61226FB5C1BC8D659EAF750F6 /* ASNetworkImageNode.h in Headers */, + D7B3E1598EAA524245035481CFA22A9A /* ASNodeController+Beta.h in Headers */, + 905B6202C6ACB27DA5B734CD0EF6923B /* ASObjectDescriptionHelpers.h in Headers */, + CA5853666CACFF05F38A33B2E5DA1949 /* ASOverlayLayoutSpec.h in Headers */, + E9BF9E31DBD24F528DC4BE7EC406F7F1 /* ASPagerFlowLayout.h in Headers */, + 9BED2B15E515CF1FC8DA1779587024AC /* ASPagerNode+Beta.h in Headers */, + 17ADD23D4835CB144BC6CD354844FF50 /* ASPagerNode.h in Headers */, + 25B46F5BF00AFAE8A15CC01AE4E5A643 /* ASPageTable.h in Headers */, + 0AB37573CCCB26C65FBC953E9DE6E3CA /* ASPendingStateController.h in Headers */, + 9D2156F8882790A1A11AB12D4CE15B63 /* ASPhotosFrameworkImageRequest.h in Headers */, + 30B53366BF7622BC324BBC3286D51EDA /* ASPINRemoteImageDownloader.h in Headers */, + 925401BD47D7A9AB180C1B3630BC0980 /* ASRangeController.h in Headers */, + F0CE14EDC70238AE475B95C1E92AB258 /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */, + CC40F97A1370E500B10B5536F9149E88 /* ASRangeManagingNode.h in Headers */, + C54D1790AEDE01C590686294934A1E13 /* ASRatioLayoutSpec.h in Headers */, + 2D9E8318C4E63140067B52E62DFF4B5B /* ASRecursiveUnfairLock.h in Headers */, + 34854853C570C98D6E3ACCAA4C7DD1DE /* ASRelativeLayoutSpec.h in Headers */, + 6EE514FBAD36F14E9DB7670A1A371419 /* ASResponderChainEnumerator.h in Headers */, + D65BE49AD19B4ED6FCCA1987CDFEAA81 /* ASRunLoopQueue.h in Headers */, + 383FAE52A9550C9936D6237F7A959AEB /* ASScrollDirection.h in Headers */, + 25283CF364080FF8D8C86F0B9D4936DE /* ASScrollNode.h in Headers */, + DD25CE53DC082769F959AC1EA39B47E1 /* ASSection.h in Headers */, + F1E44CF8A9BDBF622C310A0A52FC9069 /* ASSectionContext.h in Headers */, + F806F7F37B84AEC1C0AEE5C7000E0466 /* ASSectionController.h in Headers */, + F7E577DBB5E622CF4B9BE7D057FB7860 /* ASSignpost.h in Headers */, + CD68FB8439266630F7BEB187F7449BA3 /* ASStackLayoutDefines.h in Headers */, + A6DFC86F9D280E7B7F2E025EFCE9EC91 /* ASStackLayoutElement.h in Headers */, + 9E03D7C1EB8441DA4301C7E83D9A81FC /* ASStackLayoutSpec.h in Headers */, + B6FCFB22B26A8AD8B89DFAEAC29E0712 /* ASStackLayoutSpecUtilities.h in Headers */, + 8BB520FB3735FF2ED6F041EB6BD6EE0D /* ASStackPositionedLayout.h in Headers */, + C25457E2BE17FD066A98C816D2752261 /* ASStackUnpositionedLayout.h in Headers */, + 24E9D62BB1AEE5FC221F92CA8AFCBEC4 /* ASSupplementaryNodeSource.h in Headers */, + 66F58E36376855ADDBF863373C4D15A9 /* ASTabBarController.h in Headers */, + B1EEE6908F5B5C8DF426C37C012EA033 /* ASTableLayoutController.h in Headers */, + B70B74682AA34996E8CB2D683505E107 /* ASTableNode+Beta.h in Headers */, + 95B92DA06C709481C8E996BE378BAF05 /* ASTableNode.h in Headers */, + EFA0B7147CDDF2C33019191E9E492CDB /* ASTableView+Undeprecated.h in Headers */, + 25153085368DA21ADFDAAD6DA0EFCCC9 /* ASTableView.h in Headers */, + 53C40C404A29C9D36C39EFC2A41CE743 /* ASTableViewInternal.h in Headers */, + DDABD6DDE99C201E518E277995C4C3F7 /* ASTableViewProtocols.h in Headers */, + 3E0B594F11B1375A55CC7FB1BE1E7DA7 /* ASTextAttribute.h in Headers */, + C1D9DF1192508FC8B1DB84C55D1E7E98 /* ASTextDebugOption.h in Headers */, + 4A7C54E9E3062AE28473631F67C4A6A3 /* ASTextInput.h in Headers */, + A731B930111DDE6D8923FBB8664602BE /* ASTextKitAttributes.h in Headers */, + 179E80830E414D876BAE96A5E9D033B1 /* ASTextKitComponents.h in Headers */, + 41572627C786146E95259AC42812892C /* ASTextKitContext.h in Headers */, + 8F3296AA6F7126C161055219C1D70548 /* ASTextKitCoreTextAdditions.h in Headers */, + 8D8DB918AAA7B2598B2A1633502471E2 /* ASTextKitEntityAttribute.h in Headers */, + CD731F1BB5013903E2DF3A6BFF044E3B /* ASTextKitFontSizeAdjuster.h in Headers */, + 55DA22DDE15CDE86C6A4157789744B72 /* ASTextKitRenderer+Positioning.h in Headers */, + 1B05E3D885BC93FAC2F5D2007A888386 /* ASTextKitRenderer+TextChecking.h in Headers */, + A418F40185DE480BA18D77831E3C9FCB /* ASTextKitRenderer.h in Headers */, + F28CAD5ABEDD987D9FDBD0C75C1E22D5 /* ASTextKitShadower.h in Headers */, + F71109526514F1B3E7A8F233DE070559 /* ASTextKitTailTruncater.h in Headers */, + 35F73FFF5EC9D38FFF161D8CC64E5218 /* ASTextKitTruncating.h in Headers */, + CB74C471FCDF99CE778F9F12A435D480 /* ASTextLayout.h in Headers */, + 914D6D51178B6E7DC511BBFBCE5B8C60 /* ASTextLine.h in Headers */, + 2BF1C444606DA73A783706F748051F54 /* ASTextNode+Beta.h in Headers */, + 2045F583C05F550162C635C56DB9F44E /* ASTextNode.h in Headers */, + 693AD7C903CD68AA67FAD2DF0D3F676A /* ASTextNode2.h in Headers */, + 6A837AB4E8BB2D3161A42C4BE819519E /* ASTextNodeCommon.h in Headers */, + 3843A5FD95EEDC8984B03B4AB0872139 /* ASTextNodeTypes.h in Headers */, + 0BE5326613B0772676696939B028455F /* ASTextNodeWordKerner.h in Headers */, + 9A7E5CC0B063C1F1B56B4864E262C508 /* ASTextRunDelegate.h in Headers */, + 101880381147AEAF37111DAC551649D3 /* ASTextUtilities.h in Headers */, + 70FFE5752D7735FF6DA612721FAF1AD4 /* ASThread.h in Headers */, + 3013DDB20CC86DBA1FBD4BF107C9EE76 /* ASTip.h in Headers */, + F39F51D473548ECD4D257BF5CDF965CD /* ASTipNode.h in Headers */, + 2FB492957D10701BDFECCA77C563479B /* ASTipProvider.h in Headers */, + D9E389EF92E5B549EA600E659E8CD045 /* ASTipsController.h in Headers */, + B0E599A3B72EBA636823B6322F4CBF36 /* ASTipsWindow.h in Headers */, + C48CA75F831753B49D4987E98DCAD48E /* ASTraitCollection.h in Headers */, + FE4EC78B53C49C251ADA8964979013D8 /* ASTwoDimensionalArrayUtils.h in Headers */, + 51B91F5F6C099C23A0C0BADC9B435BC7 /* ASVideoNode.h in Headers */, + 766AFE24E8D800787DBAAF4EFA1C86D8 /* ASVideoPlayerNode.h in Headers */, + 16ABB0CB811745D54DC052D21166EF81 /* ASVisibilityProtocols.h in Headers */, + 18395D9552702EEA995F3EBDE3DDF009 /* ASWeakMap.h in Headers */, + 5367E1DE5A0A1BAB05B32E3C6BD4B9F2 /* ASWeakProxy.h in Headers */, + C499B5868927409608468028A8408838 /* ASWeakSet.h in Headers */, + C959FB55033C5DE24B6B14315BCD441B /* AsyncDisplayKit+Debug.h in Headers */, + 665AFE433398FCE3DEF4DA527D3835EF /* AsyncDisplayKit+IGListKitMethods.h in Headers */, + D263AAA51D764356CED7F375B1536628 /* AsyncDisplayKit+Tips.h in Headers */, + 0A1A2CA05738BF97386132DC453056D3 /* AsyncDisplayKit.h in Headers */, + 6F310E7B5C2D8AF7297A422F050BFDB9 /* ASYogaUtilities.h in Headers */, + DFCF371994649A26AB2793A1539FDE27 /* CoreGraphics+ASConvenience.h in Headers */, + 9DDDBA392098C8E92D303321246E4A15 /* IGListAdapter+AsyncDisplayKit.h in Headers */, + C49B74B05E2ECF40545BE26D82908D69 /* NSArray+Diffing.h in Headers */, + 3C31CF98F49970F19686DB9430000254 /* NSAttributedString+ASText.h in Headers */, + AA08E3A01738ABED66294CFED9B6232E /* NSIndexSet+ASHelpers.h in Headers */, + F80827ADB4E39BC74D92F18ABD8F92A8 /* NSMutableAttributedString+TextKitAdditions.h in Headers */, + 0DCE1ED366ED82607C1A1BE2C822852A /* NSParagraphStyle+ASText.h in Headers */, + 4D6326702D2E5445867EDF0CB51981B7 /* Texture-umbrella.h in Headers */, + 1C085C8ED0685A8CE4B5B5735C7F7EF6 /* UICollectionViewLayout+ASConvenience.h in Headers */, + 311EEE0E05EAB3E5D744F65588D8FDDB /* UIImage+ASConvenience.h in Headers */, + 6E1760E30C9461F00BEA1F9E0C678A81 /* UIResponder+AsyncDisplayKit.h in Headers */, + 85F06D91CFD3730D46459D65E5BABCE8 /* UIView+ASConvenience.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - F7556F5D4547F81C91E32927E27F1C51 /* Headers */ = { + DF23360574F448E4E5C222A1EE5021C3 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 9A2F048A751AB4B164480B5DB8BFAE5A /* PINOperation-umbrella.h in Headers */, - 186BF255034FDE286A120E832E0A8988 /* PINOperation.h in Headers */, - 4A430940C462FDD1F79386EC5F75C1D1 /* PINOperationGroup.h in Headers */, - 22C6082EA35CCB6F3608CE0C9631A6EF /* PINOperationMacros.h in Headers */, - A5B267BEACDBCAEF2D1908F170D38A68 /* PINOperationQueue.h in Headers */, - 75EA6D8C949888CECFDE996ACBCC7E1C /* PINOperationTypes.h in Headers */, + F345BC25FC253D5C7A7F12837DA555FA /* PINOperation-umbrella.h in Headers */, + 850F458B09973351610ABDB656D8B509 /* PINOperation.h in Headers */, + 71C78052823AEF756093D47135DFD7E9 /* PINOperationGroup.h in Headers */, + AA32E52485890D5826877152E1486D18 /* PINOperationMacros.h in Headers */, + A72A2291E3F8C3EA7163E6C3AE2EA377 /* PINOperationQueue.h in Headers */, + 8E1A6C378C8BAAE59B60B4F9FB24AA7E /* PINOperationTypes.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2663,17 +2686,17 @@ /* Begin PBXNativeTarget section */ 159BCD99AC1F7CE7112319E6C584776F /* Zoomy */ = { isa = PBXNativeTarget; - buildConfigurationList = 64006B59F15E5C0ADB022E0DF7ABDFA7 /* Build configuration list for PBXNativeTarget "Zoomy" */; + buildConfigurationList = 23AE78DFA121AB90D635A8DD7955706E /* Build configuration list for PBXNativeTarget "Zoomy" */; buildPhases = ( - 38292BF5BFA07E265E0B720FDE8244D1 /* Headers */, - 7210D03F0EE0FF2E76AC6B6D2A24F716 /* Sources */, - CC4043B6599186B8FECA284855B9B05B /* Frameworks */, - 1EFB1E21586CC1855F511FF92F45EE97 /* Resources */, + 2B86A805238C4F578280ABEFEFCE6D84 /* Headers */, + CB530576E4CA6C8788F7A8ACC6408DB2 /* Sources */, + 087AD93CFA987850BCC1EC91DD1AB6D1 /* Frameworks */, + 6ACD26FD5C92D0E36222CBD761AD7105 /* Resources */, ); buildRules = ( ); dependencies = ( - A4352981CBE1B2F9DF668586053B2ECB /* PBXTargetDependency */, + 82980576C3AED334BE56E11578C8B91D /* PBXTargetDependency */, ); name = Zoomy; productName = Zoomy; @@ -2682,18 +2705,18 @@ }; 18EEA7ACDE3C246B954EB9F34B1E89A6 /* Pods-Zoomy_Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = 26527969D7620C46861F1AE4C5A176C0 /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Tests" */; + buildConfigurationList = 220373192DD9B5A8CE5F6300464F4ACD /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Tests" */; buildPhases = ( - 65BE7F177614FB472D255DDDF16F6B49 /* Headers */, - 34879DA1C69316FA24A8DF53DFA7FE39 /* Sources */, - A6B54C63632E82DB9B90BA9E3681612B /* Frameworks */, - F2D3BBBA5A99E0C6DB512AC9B6FF5937 /* Resources */, + 3E04099278515D8B78AC25F1332C43C0 /* Headers */, + 4F1A324B814E8A42309CC41ACA4BCD09 /* Sources */, + 47B7B7C3BC1A08173D52ED498F5155FF /* Frameworks */, + C2126B87405E743F9D9FE206F2AE15C9 /* Resources */, ); buildRules = ( ); dependencies = ( - A311BC91D46A6494B3238D18BDC1C948 /* PBXTargetDependency */, - E1B141FB624A642EF32744DC2572944B /* PBXTargetDependency */, + 412D8A7D3EF90A20050E44CA1273D272 /* PBXTargetDependency */, + 0BFD042443A5793299A80E674FEE5F70 /* PBXTargetDependency */, ); name = "Pods-Zoomy_Tests"; productName = "Pods-Zoomy_Tests"; @@ -2702,22 +2725,22 @@ }; 43C46F311E654020969485F1CE2D78DB /* Pods-Zoomy_Example */ = { isa = PBXNativeTarget; - buildConfigurationList = 50C1C31106C3D6E71D542BE402B4F57E /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Example" */; + buildConfigurationList = 781EA42DAB0BE3F655A4986FC97589BB /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Example" */; buildPhases = ( - 1A4F2F7054609F2B50DFFBFFE028DC8B /* Headers */, - 58675E0173030274B9A2A65EFE89B807 /* Sources */, - 05AE22FDDE21CE1249C98951A6CFB8D2 /* Frameworks */, - 6FA4417C7119E055DC8ED8E6D230991F /* Resources */, + CC0BD8F7B8855A58F797A585AFECBFEA /* Headers */, + EE6941D3A42C1ED276E9151729FCAD22 /* Sources */, + 1561721F7DAB089F0EC0B49011A14513 /* Frameworks */, + AF954972DE6B73E33F9B0E14FA9097DE /* Resources */, ); buildRules = ( ); dependencies = ( - 1A79743F84ED2F358625951865C27EC8 /* PBXTargetDependency */, - 1A9C231615A0B3DFBDCBE6C879A43F11 /* PBXTargetDependency */, - E2573EA6C5717696D6FE8241287E22BF /* PBXTargetDependency */, - AB66CAF24852F8DBCCC3D9C8E59C02D8 /* PBXTargetDependency */, - 956621FEDB7779168DE1A7FA5CF6E751 /* PBXTargetDependency */, - 376A8C24FB02DCF2F5D3522D8DA52FBE /* PBXTargetDependency */, + EBB57BE390B41A783ADA597BB44EB9F5 /* PBXTargetDependency */, + EC1F18F4329DFB524BE68E70F2AB5869 /* PBXTargetDependency */, + 131967F7F4F880DA80DD12D81FF8D93C /* PBXTargetDependency */, + 24DCB5EF3C5585D624336BA527102942 /* PBXTargetDependency */, + B0A07C61F8660E4693ABFC2FB052F142 /* PBXTargetDependency */, + D247019110BBD782DC6AF87B0E349833 /* PBXTargetDependency */, ); name = "Pods-Zoomy_Example"; productName = "Pods-Zoomy_Example"; @@ -2726,12 +2749,12 @@ }; 57310B016450E63387C9D64F4933E995 /* PINOperation */ = { isa = PBXNativeTarget; - buildConfigurationList = 5072AA0772B5784FDC4E8E7E8192A2AB /* Build configuration list for PBXNativeTarget "PINOperation" */; + buildConfigurationList = 4465A8BC1A4EAD0A929F46F30EBB7871 /* Build configuration list for PBXNativeTarget "PINOperation" */; buildPhases = ( - F7556F5D4547F81C91E32927E27F1C51 /* Headers */, - C967B2A425365D2ACC338CAA2CC33900 /* Sources */, - 1936C21DE636BD2B82081D2BDFFD902B /* Frameworks */, - F4026E69F805DA3A1557070E97082AFE /* Resources */, + DF23360574F448E4E5C222A1EE5021C3 /* Headers */, + 09CAAFEDD26B022DB7B5EB0C738E7EA4 /* Sources */, + 5622EFD94CDE5BAE4CEE2FFE1B600A96 /* Frameworks */, + 343DBA5B86A9719C1B9CBF4EDB5DAB18 /* Resources */, ); buildRules = ( ); @@ -2762,17 +2785,17 @@ }; A927C3CD51C30012080D6CA07959B246 /* PINCache */ = { isa = PBXNativeTarget; - buildConfigurationList = 80A4215346E29D0F80A19EFE25FA421A /* Build configuration list for PBXNativeTarget "PINCache" */; + buildConfigurationList = B794DF6469B3D94E9347E82D67AFAF6E /* Build configuration list for PBXNativeTarget "PINCache" */; buildPhases = ( - 56926779FD48CE6BC5A1285CEA3CA0CC /* Headers */, - 4CF091A6F21E933F0E417FCEC4B09D66 /* Sources */, - A778F03BF6D5012EB67925281D5EFB16 /* Frameworks */, - 07D05629E0227C7F280BF1758F5066B7 /* Resources */, + BA923AD163937D722E40905AF3F28F6F /* Headers */, + C1B61E7C7CFBEB67C3AF77D3B185E9FD /* Sources */, + 059E3121D15442F422222D8AD47E0686 /* Frameworks */, + 9C80EE02089BF890DF2D261AEAD04144 /* Resources */, ); buildRules = ( ); dependencies = ( - 2878FCD5AE1495E5A7586AD4804F9121 /* PBXTargetDependency */, + A09C766F92D67B48C9B693DAC6317D6D /* PBXTargetDependency */, ); name = PINCache; productName = PINCache; @@ -2781,17 +2804,17 @@ }; DB66E43BC980D741F3C7C5CF3ACEEFA4 /* Texture */ = { isa = PBXNativeTarget; - buildConfigurationList = 3CE812C41CAFAAF986137CD5A0B90AA1 /* Build configuration list for PBXNativeTarget "Texture" */; + buildConfigurationList = 78DCB2C5EC3B5BA90EEB95A1ACFFDF0E /* Build configuration list for PBXNativeTarget "Texture" */; buildPhases = ( - 0FFDC764A31978B2A43158C74453953B /* Headers */, - C9F4C3B3ABAD6CF00880FA054E7989F2 /* Sources */, - 242A85C074D836A1CF05972D090A651B /* Frameworks */, - F1A159E7F71BD5F176AEC22887F66E8B /* Resources */, + CFDD8E01973A320462A7591B41B1F068 /* Headers */, + 205A91CA63B15EDB711FBF192800F91A /* Sources */, + 4944372286DB7CF00171CB0CC5D55B61 /* Frameworks */, + 5932610002C5C8243CDFE673CFF79E62 /* Resources */, ); buildRules = ( ); dependencies = ( - A902B2D95EAA6F663620D6E8CDACCB1F /* PBXTargetDependency */, + 80B8A8586A473C942CFCE9FE98F8A4FD /* PBXTargetDependency */, ); name = Texture; productName = Texture; @@ -2800,18 +2823,18 @@ }; E2A8B2A28D2EAB2E4CCF3B69E6792851 /* PINRemoteImage */ = { isa = PBXNativeTarget; - buildConfigurationList = A1BBBFD4F6BA65DFB93D9A73935567BC /* Build configuration list for PBXNativeTarget "PINRemoteImage" */; + buildConfigurationList = 1000880B548699E9BBD74146AFFA3702 /* Build configuration list for PBXNativeTarget "PINRemoteImage" */; buildPhases = ( - 85A0ABC20A5B8AD24473F6E5CA432E8D /* Headers */, - 0A76ACF2FD420FD88731865A9F2E61F4 /* Sources */, - C9B63557A48A85F69CC4F8F9491D5720 /* Frameworks */, - 408FFA710B605512744622978D23CD74 /* Resources */, + 2A105393BCB5FE9278CB202153804F72 /* Headers */, + 6D126D8E6EF94CE128B535484322F538 /* Sources */, + C6A2093EFA9C0E4742B6F8AF6DCB412D /* Frameworks */, + A627139AA8F807B0BF8DC256470578D9 /* Resources */, ); buildRules = ( ); dependencies = ( - 406B3781A7C004245597BD6C366DD653 /* PBXTargetDependency */, - 3A8C577D3A0A9D1DDB802A5C39CEA459 /* PBXTargetDependency */, + 303A1DE6A2B09C67231DE68CEE80661E /* PBXTargetDependency */, + 223194865C40B02C96D834DE3D6FAA9A /* PBXTargetDependency */, ); name = PINRemoteImage; productName = PINRemoteImage; @@ -2825,7 +2848,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1100; - LastUpgradeCheck = 1100; + LastUpgradeCheck = 1250; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -2833,6 +2856,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; productRefGroup = AD898D9348493435A50A21E5A3B69FF7 /* Products */; @@ -2852,56 +2876,56 @@ /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 07D05629E0227C7F280BF1758F5066B7 /* Resources */ = { + 343DBA5B86A9719C1B9CBF4EDB5DAB18 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 1EFB1E21586CC1855F511FF92F45EE97 /* Resources */ = { + 5932610002C5C8243CDFE673CFF79E62 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 408FFA710B605512744622978D23CD74 /* Resources */ = { + 5CCF767E3C655F32FE1862E2B500C698 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 5CCF767E3C655F32FE1862E2B500C698 /* Resources */ = { + 6ACD26FD5C92D0E36222CBD761AD7105 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 6FA4417C7119E055DC8ED8E6D230991F /* Resources */ = { + 9C80EE02089BF890DF2D261AEAD04144 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - F1A159E7F71BD5F176AEC22887F66E8B /* Resources */ = { + A627139AA8F807B0BF8DC256470578D9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - F2D3BBBA5A99E0C6DB512AC9B6FF5937 /* Resources */ = { + AF954972DE6B73E33F9B0E14FA9097DE /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - F4026E69F805DA3A1557070E97082AFE /* Resources */ = { + C2126B87405E743F9D9FE206F2AE15C9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -2911,309 +2935,303 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 0A76ACF2FD420FD88731865A9F2E61F4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5D1948F6FC9E5CBD8CFB861BDF22FED3 /* NSData+ImageDetectors.m in Sources */, - 7B40EFBACF7283D118A018C64DB5D334 /* PINAlternateRepresentationProvider.m in Sources */, - 2C05B30FFB36608D359F1608EC16875A /* PINAnimatedImage.m in Sources */, - F6AAE4F5995235A0EE8ED3007BB228B2 /* PINButton+PINRemoteImage.m in Sources */, - 82FF8E0FA9C51316D0724EF1CC430FCF /* PINCache+PINRemoteImageCaching.m in Sources */, - DCDBE3F8533C0A3F52DD885C8F3961D8 /* PINCachedAnimatedImage.m in Sources */, - E084D2A81E75E3034A7C08B8B3E6006C /* PINGIFAnimatedImage.m in Sources */, - DA26D97E545E9A37D918D1B674D02F23 /* PINGIFAnimatedImageManager.m in Sources */, - 346F86D4ACD926D29B1D76D58B494FC9 /* PINImage+DecodedImage.m in Sources */, - 76769BF5A866CADF8435A5C3398B69BC /* PINImage+ScaledImage.m in Sources */, - C00C342DC14DCF42B6BA31F3A62611E6 /* PINImage+WebP.m in Sources */, - D76D435FF64CAC593C30BE295C7D45F1 /* PINImageView+PINRemoteImage.m in Sources */, - 351525A5E2172EF827DED5472494B3E4 /* PINMemMapAnimatedImage.m in Sources */, - 7AA2F6576E76A4BFA98EB7CAC8B544EA /* PINProgressiveImage.m in Sources */, - 6C45BAC40C71D9DAB390C432E290917B /* PINRemoteImage-dummy.m in Sources */, - 0A1D927875C8CDD62209FA3521CBEBF3 /* PINRemoteImageBasicCache.m in Sources */, - 58965593EE5EAB075D49BC808361B2C1 /* PINRemoteImageCallbacks.m in Sources */, - 2078DCF8E2791B2FD569971DD6641BD8 /* PINRemoteImageCategoryManager.m in Sources */, - 336CCF0C26845D984B5884EDFB29E3EA /* PINRemoteImageDownloadQueue.m in Sources */, - B11A06E34C796B6318E52F991C3A3FE8 /* PINRemoteImageDownloadTask.m in Sources */, - 983AED1C4422A62162CF7C8BD8C68EC4 /* PINRemoteImageManager.m in Sources */, - A7B0A20917692E0E5AF687E882D1D042 /* PINRemoteImageManagerResult.m in Sources */, - 9BF312C74933239A9980BCC85427F4D1 /* PINRemoteImageMemoryContainer.m in Sources */, - 1491813C6D4E5F79AE48C2007F6D31A2 /* PINRemoteImageProcessorTask.m in Sources */, - B4D223471AAEA86D04DB96D70D2F2466 /* PINRemoteImageTask.m in Sources */, - CE5C0993A786119367F5B72F4B039CF9 /* PINRemoteLock.m in Sources */, - DEC3A15E298F0EF0A5E9FDA37836D85E /* PINRequestRetryStrategy.m in Sources */, - 6E469EDA3A2AAB5BBE24305DA7F1248D /* PINResume.m in Sources */, - 6166FF001AC0578634672DB77A6C693C /* PINSpeedRecorder.m in Sources */, - 617A7C4C9D2B12CE7A2F34F71D69DA86 /* PINURLSessionManager.m in Sources */, - 595C704E7A256F3C67296B5DA2903F5F /* PINWebPAnimatedImage.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 34879DA1C69316FA24A8DF53DFA7FE39 /* Sources */ = { + 09CAAFEDD26B022DB7B5EB0C738E7EA4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 55BFE808912342EEC873F1E2393786E1 /* Pods-Zoomy_Tests-dummy.m in Sources */, + B62E2950A573C90432FB3A213E455B47 /* PINOperation-dummy.m in Sources */, + 30E5220AF082397668D8FBDB2BB4AD6F /* PINOperationGroup.m in Sources */, + F5108C9C22403076681B80297719B820 /* PINOperationQueue.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4CF091A6F21E933F0E417FCEC4B09D66 /* Sources */ = { + 205A91CA63B15EDB711FBF192800F91A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B3D52B59EC16AFE4E5C3EF3AD2F4606F /* PINCache-dummy.m in Sources */, - 0B269BCCD0EB4A0324303CF2EBF429BB /* PINCache.m in Sources */, - E5E0315BC7724AC94FFC07D5A26A491C /* PINDiskCache.m in Sources */, - D1C2B6C9B28D974F10C233EC059377C7 /* PINMemoryCache.m in Sources */, + 1B2A0A4681935DC95834481F21759220 /* _ASAsyncTransaction.mm in Sources */, + 3E66AC6AE52437F25DB9C77B405BF072 /* _ASAsyncTransactionContainer.mm in Sources */, + 835F0D17D2FD72B5C75AB3C73665B952 /* _ASAsyncTransactionGroup.mm in Sources */, + 9AD75CD02E114BE9834EF4E9DCF8FD35 /* _ASCollectionGalleryLayoutInfo.mm in Sources */, + 0FFDB747E5756746172DD89CAC9073A5 /* _ASCollectionGalleryLayoutItem.mm in Sources */, + D58F5F325475C2FA76B7A2C6D6DEBA08 /* _ASCollectionReusableView.mm in Sources */, + A1879D2E926B3B4D0434F59C3CFEA7E4 /* _ASCollectionViewCell.mm in Sources */, + 50EDFDEBF7240CDF4671942722897557 /* _ASCoreAnimationExtras.mm in Sources */, + 9481A617FEFD1628356CBB00160C2FC0 /* _ASDisplayLayer.mm in Sources */, + 3FA2661EC4B4764F8A0BAA3B6911CE07 /* _ASDisplayView.mm in Sources */, + EA86861420C58AAFFBDD4FE8B05A90F8 /* _ASDisplayViewAccessiblity.mm in Sources */, + EE30A346E8E2989D4D8A1E2A60608C5D /* _ASHierarchyChangeSet.mm in Sources */, + 44F5E8EAAFC519B827079C21092A3110 /* _ASPendingState.mm in Sources */, + A8DEB1E7C5738E83B9EB996DF3B6B780 /* _ASTransitionContext.mm in Sources */, + 065EC5AD7B86716183B6C6F10214ECE9 /* ASAbsoluteLayoutSpec.mm in Sources */, + 6C83627E6FAA6773A8F7CF351CAFB99F /* ASAbstractLayoutController.mm in Sources */, + 0284D979FE5030B1BBE20318DFF83407 /* ASAsciiArtBoxCreator.mm in Sources */, + 445A2C4091D5EB91003D00CA744F69C8 /* ASAssert.mm in Sources */, + 28A9C06F97CB780536F2C2405DF1E4CA /* ASBackgroundLayoutSpec.mm in Sources */, + 1E5042D00F802CC758E27A3DFFA27413 /* ASBasicImageDownloader.mm in Sources */, + 4863D9CFD8DF00F75537FC81AC2C1B9A /* ASBatchContext.mm in Sources */, + 0731FF1F4C72E85A9CF8BC8FA403E7CE /* ASBatchFetching.mm in Sources */, + 25950726ACAF3C2B3EF3B24499F05921 /* ASButtonNode+Yoga.mm in Sources */, + B74E2B68A0C6A8E73F27F0EB5B7695D1 /* ASButtonNode.mm in Sources */, + 66B9FA66EDE6CD8FD3B1C5823155167C /* ASCellNode.mm in Sources */, + F1CD75754D06FFE6667055828402AC19 /* ASCenterLayoutSpec.mm in Sources */, + E81BA6B935A20C3C5AF436FD1097A607 /* ASCollectionElement.mm in Sources */, + 4D1738F72E511D8788C448223DFF74C7 /* ASCollectionFlowLayoutDelegate.mm in Sources */, + 533DDBAE6B86634DC5AC964324AFBE5A /* ASCollectionGalleryLayoutDelegate.mm in Sources */, + E97E10031318F97C13605A4E7C6C241D /* ASCollectionLayout.mm in Sources */, + 5F4662B7E3B0E1B0B9F9C445EFE5FDEF /* ASCollectionLayoutCache.mm in Sources */, + 92B7317ED317260E96CC6D658EFAA5F0 /* ASCollectionLayoutContext.mm in Sources */, + 46602671A46883556573D357D8D58179 /* ASCollectionLayoutDefines.mm in Sources */, + 8B886D15BFD525FDF4FC0FD05C4E352F /* ASCollectionLayoutState.mm in Sources */, + 2718C849A663ADF0E69B40FFC1C5443E /* ASCollectionNode.mm in Sources */, + 4FEC6809913A309C1BB3AE70C9CD1856 /* ASCollections.mm in Sources */, + 5C4DD97A03493777545E355D09A8903E /* ASCollectionView.mm in Sources */, + 12BD7A4EE714789DE378364B25BC681F /* ASCollectionViewFlowLayoutInspector.mm in Sources */, + 26880973B4644E87C380BBB5E861951E /* ASCollectionViewLayoutController.mm in Sources */, + 1D0CD1F6962F538225CE1E3DD8275C0D /* ASCollectionViewLayoutInspector.mm in Sources */, + 03177DA0581846B708D9C1B4C69AF5B4 /* ASConfiguration.mm in Sources */, + 7FD4280D0F3552F62182C2797740B7FA /* ASConfigurationInternal.mm in Sources */, + 3FF4BD5B4A904AB6FDC3BFA4A77764EA /* ASControlNode+tvOS.mm in Sources */, + 7B226EB7B088CECD2ECA145103392D56 /* ASControlNode.mm in Sources */, + B487EEBAEBECA362C0EC6EE162A99EC3 /* ASControlTargetAction.mm in Sources */, + B12E5975BB9E7CB69C0C0E40564ABAFB /* ASCornerLayoutSpec.mm in Sources */, + E49A788AD2790861B385BA2E084BFEF2 /* ASDataController.mm in Sources */, + 3C5A9FE3D7C7FE22A922753CA96E5C12 /* ASDefaultPlaybackButton.mm in Sources */, + 725A23DC02BF12DAEFD17D9DD1C19537 /* ASDefaultPlayButton.mm in Sources */, + 326E08CB331794AD3AC0332E7B4F5DC0 /* ASDelegateProxy.mm in Sources */, + 095EAC3436164EBB3B0DA2704BEE8D7A /* ASDimension.mm in Sources */, + D20712489CC62AD1D69DE3D4F067CC6D /* ASDimensionInternal.mm in Sources */, + 26CC1A88B18BCEFF176989DDF566FEF2 /* ASDispatch.mm in Sources */, + C779ACC80C0E385B487DD2AF73C7B629 /* ASDisplayNode+Ancestry.mm in Sources */, + 6F0D7C379DAA9767920055697FA3B94C /* ASDisplayNode+AsyncDisplay.mm in Sources */, + 5F0259FB38017633D98701913A2EF502 /* ASDisplayNode+Convenience.mm in Sources */, + 48AB83373950DF31804839DF7317AEB2 /* ASDisplayNode+DebugTiming.mm in Sources */, + DCA67BCF11BB08C4CC754BAB7DE9700F /* ASDisplayNode+Layout.mm in Sources */, + 55F66909D00D87259EB4D88697ADF17F /* ASDisplayNode+LayoutSpec.mm in Sources */, + 0C8AFCED476D2CA82A33B9A602B7806E /* ASDisplayNode+UIViewBridge.mm in Sources */, + 5934C09B5C2A178ADD7D0D585AD36037 /* ASDisplayNode+Yoga.mm in Sources */, + B04D1648CEB49BF9A215EB68F782E66F /* ASDisplayNode.mm in Sources */, + D6FBD69E5AC966E364870F3BC89AE40B /* ASDisplayNodeCornerLayerDelegate.mm in Sources */, + 882C68A56DB9AAA11032882286153B46 /* ASDisplayNodeExtras.mm in Sources */, + 2E7753DD0798320C098D6F97215F4EDA /* ASDisplayNodeTipState.mm in Sources */, + 0A8BEE494BB1DFA8A3711444D6CF5728 /* ASDKViewController.mm in Sources */, + E74676FCA35F49AB90084F9D6A133BEC /* ASEditableTextNode.mm in Sources */, + 7485A8427B78F4D0D38AF63015919793 /* ASElementMap.mm in Sources */, + A23A686BD3E5A1A45732474F086E5108 /* ASExperimentalFeatures.mm in Sources */, + D5741B35FAD5625327DB7740816490EF /* ASGraphicsContext.mm in Sources */, + 30E321C7F2B2528CC0DEFA81FEE5020E /* ASHashing.mm in Sources */, + D8CDE83FC5F7BB9CBDDEF662EA434A76 /* ASHighlightOverlayLayer.mm in Sources */, + A43B3297E738E64DFE93D4CE2C81D24A /* ASIGListAdapterBasedDataSource.mm in Sources */, + 98DF10C729D708E8B23CC3DE227AC5BE /* ASImageContainerProtocolCategories.mm in Sources */, + 8C871044D0661199D892CAA1A56975A8 /* ASImageNode+AnimatedImage.mm in Sources */, + 95D49A06D8AAB718A13FFF1A29B6F6FE /* ASImageNode+CGExtras.mm in Sources */, + EFEBFE9D117F31C3EFBCFF03E4F374B8 /* ASImageNode+tvOS.mm in Sources */, + 9D3FF8DEE22B8C7BFB7A66C333F45B92 /* ASImageNode.mm in Sources */, + 1C8C87AA0418AAB89B67CEB269819488 /* ASInsetLayoutSpec.mm in Sources */, + ABEA1AED8D9E7FE95885384AAF7786A6 /* ASIntegerMap.mm in Sources */, + BF793A7E0F25CED19582524BD92EA327 /* ASInternalHelpers.mm in Sources */, + C8CF437ABF283BBC35D39F66A92F7895 /* ASLayerBackingTipProvider.mm in Sources */, + FEC35A85C255EC1E831E29A8A6A3280C /* ASLayout+IGListDiffKit.mm in Sources */, + 4B8E788E590ABA95BD8CC4573D0EBFC0 /* ASLayout.mm in Sources */, + D567696E69F612CCD04A8B52C6AE69FD /* ASLayoutElement.mm in Sources */, + E7F75D0551F60AC1E0FAAE389E0E48EE /* ASLayoutManager.mm in Sources */, + 2C3EE7C1BE5D6BDB615ABD6589CC1A1F /* ASLayoutSpec+Subclasses.mm in Sources */, + 3C3358F8891B4D0EEC5DBF01934EE2F4 /* ASLayoutSpec.mm in Sources */, + CD3FBB0BBE384A5810065C4D88D035A4 /* ASLayoutTransition.mm in Sources */, + 5F8115BA11746D390E7FE2DA8B4E195F /* ASLog.mm in Sources */, + 5E6DD54DC1FCC7FA938B7BDBFA6653AA /* ASMainSerialQueue.mm in Sources */, + 0671472257D854CBC8F14A6460CBD70A /* ASMainThreadDeallocation.mm in Sources */, + 1B3BD47E66BBC5F931984D74A3E0047A /* ASMapNode.mm in Sources */, + 8E2EEA6890AA83F0C1689F5273B37B8F /* ASMultiplexImageNode.mm in Sources */, + 2FD93AFDC2A9F0BE1EEF74E89B5AD84B /* ASMutableAttributedStringBuilder.mm in Sources */, + CE2FBCFCF10B33851635AE494E68C29D /* ASMutableElementMap.mm in Sources */, + FF15EAE598D7123397737DBC37BE77A0 /* ASNavigationController.mm in Sources */, + 7185AD0B6E50617EB5B063D049F7381E /* ASNetworkImageLoadInfo.mm in Sources */, + 29CAF11CD62CCBDC701E051CBF424C23 /* ASNetworkImageNode.mm in Sources */, + 0DB894195A40459248365D08C82C0BC5 /* ASNodeController+Beta.mm in Sources */, + 50EEFB8254EAF126BDAF9F4BB2F41EC1 /* ASObjectDescriptionHelpers.mm in Sources */, + CD2A3263FA9B3629F7D373E5D898B530 /* ASOverlayLayoutSpec.mm in Sources */, + 238353CE094AADDB351A5AE7D730F8F0 /* ASPagerFlowLayout.mm in Sources */, + 14B7A03552B6697528E765E9DD51F34F /* ASPagerNode.mm in Sources */, + 25BDEB129E29246C4BB4044B849B90D6 /* ASPageTable.mm in Sources */, + C7B9FC1B5CFDD47203D8019533E52F0B /* ASPendingStateController.mm in Sources */, + 93B61C99B25B247897629D42186F02AB /* ASPhotosFrameworkImageRequest.mm in Sources */, + 79D79C15A67C285A4FE840C164A61EAD /* ASPINRemoteImageDownloader.mm in Sources */, + 2490B901F64B7A71103C5BACBBC14195 /* ASRangeController.mm in Sources */, + D5F9094AB618823BE2D258D83450ACF8 /* ASRatioLayoutSpec.mm in Sources */, + 4404103D44CA3218F025DA315D800010 /* ASRecursiveUnfairLock.mm in Sources */, + A7D8E709A23130883C176E7E6572C392 /* ASRelativeLayoutSpec.mm in Sources */, + 34ADECC6CF4DB77F274F6ED5178FA3FF /* ASResponderChainEnumerator.mm in Sources */, + DFB3623B8303E1732A2DE7866457BFA5 /* ASRunLoopQueue.mm in Sources */, + 3DD4626268615851397E19A6D6F5E48A /* ASScrollDirection.mm in Sources */, + 90A83F1084AF8045B4B8EB567B188C4A /* ASScrollNode.mm in Sources */, + 379C8AD0CBCD05F0AC0AAD83E05058A5 /* ASSection.mm in Sources */, + 9F8BD0381058FDEDA5F0671FA6B3A02B /* ASStackLayoutSpec.mm in Sources */, + 9DB3E03C376FC722E70B094C2DF85DC2 /* ASStackPositionedLayout.mm in Sources */, + 4775D60B018E3B4BA0C456FCC93A3489 /* ASStackUnpositionedLayout.mm in Sources */, + F60818A3F394E384B349C7F3FD8896D1 /* ASTabBarController.mm in Sources */, + E13C6028A12C4D85EBAAAA04C96FF536 /* ASTableLayoutController.mm in Sources */, + 3EDE54BDA1749D9AA3F967EEE4C819A4 /* ASTableNode.mm in Sources */, + BF2296DF6290E9C557FF126C8EBBAA7F /* ASTableView.mm in Sources */, + 38B66488888B06F1D215DD4E907C8613 /* ASTextAttribute.mm in Sources */, + F40F8AD0FB1CAA4C367596C50912AF95 /* ASTextDebugOption.mm in Sources */, + 0ECB1E4D8FA0F073DC3CF9E5EBCA4370 /* ASTextInput.mm in Sources */, + C75C96A4CB5497109200277BC3B826AC /* ASTextKitAttributes.mm in Sources */, + FF4F84E904D5B54DD1E596BB8BB3C4B2 /* ASTextKitComponents.mm in Sources */, + 675811F894E8250FD70813BE06DF5E80 /* ASTextKitContext.mm in Sources */, + 17EE7FE8DDF79CAF395E4A3080D7B035 /* ASTextKitCoreTextAdditions.mm in Sources */, + 74E1593D7726C6250595B3640FC6908B /* ASTextKitEntityAttribute.mm in Sources */, + 82E0F28243DC81433820662B2BEA008C /* ASTextKitFontSizeAdjuster.mm in Sources */, + E3B60613FB36F520EAA02E7C405B4B10 /* ASTextKitRenderer+Positioning.mm in Sources */, + 5B2D3DF94C9F82AB1317E69DB48E8372 /* ASTextKitRenderer+TextChecking.mm in Sources */, + EF68CE5C31FA5D353DFA4536D85E7067 /* ASTextKitRenderer.mm in Sources */, + 40F7A9A1246007960D1C10A328562B85 /* ASTextKitShadower.mm in Sources */, + 80C24E482ED0EC7870E04616ECCD439A /* ASTextKitTailTruncater.mm in Sources */, + A42EC5DE809DA43B92C0A1FB1591A823 /* ASTextLayout.mm in Sources */, + 9E3882ED3E01A3E7A88E9667C0A0636E /* ASTextLine.mm in Sources */, + F1B69EBD630EA9C41E76FAF9B4878266 /* ASTextNode.mm in Sources */, + F01A56AD8FC4D13459E7A4088437DD60 /* ASTextNode2.mm in Sources */, + 9268301826042884BD37C81E02D6AA0C /* ASTextNodeWordKerner.mm in Sources */, + 781DA851FF46FF8A30B48C5E8115FE1B /* ASTextRunDelegate.mm in Sources */, + 1414F0DF56982DFC65C6E01ECE6A4374 /* ASTextUtilities.mm in Sources */, + C2C213FC002E05563E7A5E1688008092 /* ASTip.mm in Sources */, + A62703EF376B85BECA85A817C34DAEF3 /* ASTipNode.mm in Sources */, + 789C7B17F586529CFB16874F11D0612E /* ASTipProvider.mm in Sources */, + 78832930615717444B99AF06239A0497 /* ASTipsController.mm in Sources */, + 8FB8E71EDEEC0BAF253697B14D1A562D /* ASTipsWindow.mm in Sources */, + EB5CB15BE4021AEEE889E49C99751359 /* ASTraitCollection.mm in Sources */, + 09D5CC75390536E1FD6F02F5AE3862AE /* ASTwoDimensionalArrayUtils.mm in Sources */, + C6280E10614BA6CF600C8A80BC1C426E /* ASVideoNode.mm in Sources */, + E0B5B77C3B206FBB576000E18BF9C56A /* ASVideoPlayerNode.mm in Sources */, + BE96104ACD0169003A3A222039106C33 /* ASVisibilityProtocols.mm in Sources */, + 25F7C6715BCCB73CAA6C20FAE292CF9B /* ASWeakMap.mm in Sources */, + 982632D85E47F99F7181D8F921276FC8 /* ASWeakProxy.mm in Sources */, + 8D1C38CA2C15929280CC6482BFB46216 /* ASWeakSet.mm in Sources */, + CCF02EB012ED66CDE4DCEFE3C6731517 /* AsyncDisplayKit+Debug.mm in Sources */, + E99888C1284FD4BA652BFCCBA42A69D0 /* AsyncDisplayKit+IGListKitMethods.mm in Sources */, + 641B4519AF9A061FA679FD64B3CB984B /* AsyncDisplayKit+Tips.mm in Sources */, + 5A5D5F0390336EF5FB4E0C7E3A250AA0 /* ASYogaUtilities.mm in Sources */, + 6851E1AB040073EBF7F89AE04AF025F4 /* IGListAdapter+AsyncDisplayKit.mm in Sources */, + 715A56F9131273D746C866720B84F7FF /* NSArray+Diffing.mm in Sources */, + E192EDBF272B1EF298F8FE2FA6DDAF25 /* NSAttributedString+ASText.mm in Sources */, + 7DF36B3FA296898C2CE708F7A547929A /* NSIndexSet+ASHelpers.mm in Sources */, + A7319DA9AD51B4B7EA19086A54DD05DB /* NSMutableAttributedString+TextKitAdditions.mm in Sources */, + C5F8FA0CB5BB90D56C13A44180EE8329 /* NSParagraphStyle+ASText.mm in Sources */, + C1E1845DA59006D300466D68C4A6F56F /* Texture-dummy.m in Sources */, + E977832761EAFD3D2EF100FB74A57717 /* UICollectionViewLayout+ASConvenience.mm in Sources */, + 6549266D127F7CF008B8120024AD1826 /* UIImage+ASConvenience.mm in Sources */, + A27474180106AAAB41F2871304AC64CC /* UIResponder+AsyncDisplayKit.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 58675E0173030274B9A2A65EFE89B807 /* Sources */ = { + 4F1A324B814E8A42309CC41ACA4BCD09 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - CDE7A698F923984D4536BF034E55EBC0 /* Pods-Zoomy_Example-dummy.m in Sources */, + 0337373CAC9908A374853CDFC3B00A31 /* Pods-Zoomy_Tests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 7210D03F0EE0FF2E76AC6B6D2A24F716 /* Sources */ = { + 6D126D8E6EF94CE128B535484322F538 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B1EAE30D3FCDFED9AD5D90D251EA0A34 /* AnimationEvent.swift in Sources */, - 15CED60EDCFC60450E0BCB2A798D3D22 /* Animator.swift in Sources */, - F8A91671AB39F8109480C3A72D69D689 /* BounceOffsets.swift in Sources */, - F87387A8B2056D3EC40A154A8CB46F02 /* CanAnimate.swift in Sources */, - AB8430F07EEF189ACB7237DC3ADF73C8 /* CanBetriggered.swift in Sources */, - 83BD8B38847B9C96FBA4418A4C6F394F /* CanManageZoomBehaviors.swift in Sources */, - 8A286D7016BB48224320C686C39D2224 /* CanPerformAction.swift in Sources */, - 002F3F0490AA55AD66EDB40E8B51A4A6 /* CanProvideAnimatorForEvent.swift in Sources */, - 8C18DF4B9574971AA7D619FBB11B6C64 /* CGAffineTransform+transformWithScaleTranslationCenter.swift in Sources */, - 5F061989BF79A51FCBBA78724355A15E /* CGPoint+dominantDirection.swift in Sources */, - 01DB863C9D13E9599D5D77F7F2B36D1D /* CGPoint+maximumAbsoluteValue.swift in Sources */, - 6B593EFF0D07AB7A2869146C13130987 /* CGPoint+valueInDirection.swift in Sources */, - 1AC4A7DBD54618D6F1CBA4699C513313 /* CGRect+Difference.swift in Sources */, - E324F8907100F01247139C4AE582F80F /* CGRect+transformedByTransform.swift in Sources */, - D0B4B61F2B2E6DFAA1B9720D57FB36E0 /* ConfigurableUsingClosure.swift in Sources */, - 8A0627E70FCA5146143FC7BEC7C39309 /* DefaultAnimators.swift in Sources */, - 47F6AA826F870066399AADCB7180A7AE /* HasImageZoomControllers.swift in Sources */, - 0F4AED0CA7EECB3C56C6888C3F836480 /* ImageZoomController.Factory.swift in Sources */, - 430B85802BE09219C878C986B07EFE52 /* ImageZoomController.swift in Sources */, - 0A2B6E66AB8561876A5B7961CBAE6B2F /* ImageZoomControllerActions.swift in Sources */, - D2217169217657E37C514D6DB2D0CF05 /* ImageZoomControllerContentState.swift in Sources */, - 3297888C20BE64DE5ECC7C2ED5D2C39F /* ImageZoomControllerDelegate.swift in Sources */, - BDB2A5F0E63D0488D81945B048C8E6B8 /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift in Sources */, - A4DBE34A6E4132DCE5CAE57D60456641 /* ImageZoomControllerIsNotPresentingOverlayState.swift in Sources */, - 470A8F20E14325DF2B2928FD8FE214F5 /* ImageZoomControllerIsPresentingImageViewOverlayState.swift in Sources */, - F8ACA480E6D150199FE448D7993F5494 /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift in Sources */, - B31BEFBD1D6436910AE45F3F52856703 /* ImageZoomControllerSettings+Equatable.swift in Sources */, - 65F6D9099F2E3EDA63CC4FA2232374A5 /* ImageZoomControllerSettings.swift in Sources */, - B495074A8740E49AEA57A4C35888D585 /* ImageZoomControllerState.swift in Sources */, - BCAC5BA9D845AB51148932B5EB3A5C4E /* logger.swift in Sources */, - 553D516A845355E9AE7C6643C71D5C20 /* NSObject+AsociatedKeyForImageZoomControllers.swift in Sources */, - B0584D12CE37583826F48C67E9F319C4 /* Side.swift in Sources */, - 572D032B835BAB720EBFBA6A18908948 /* SpringAnimator.swift in Sources */, - A2A08FD631849349183CE1B5B2A0B1FF /* TypeAliasses.swift in Sources */, - 2BC37AF342E9A5BDCC9D7294EAFC1EB2 /* UIGestureRecognizerState+CustomStringConvertible.swift in Sources */, - 660F62E7D7AF5375CE4C1B230AE46A9A /* UIImage+Color.swift in Sources */, - 321436AC03A174B345BAB91AC4555A36 /* UIImageView+Zoomable.swift in Sources */, - F251373834CB3561F540AD2FFF148685 /* UIView+layoutHelpers.swift in Sources */, - 836F172786359578E36859CC821D68A1 /* UIViewController+CanManageZoomBehavior.swift in Sources */, - 04B5B722F581E8F3CBA1AA87C19D36AE /* UIViewController+HasImageZoomControllers.swift in Sources */, - B3D909D651548CA9F2796677F470DD13 /* Zoomable.swift in Sources */, - 7F87B587FCD817B1468A6D518458999E /* Zoomy-dummy.m in Sources */, - 62F3B4506E471EA184D4CB38CFA626B2 /* ZoomyLogger.swift in Sources */, + DCC0959800E3EC695210D0372765FBFA /* NSData+ImageDetectors.m in Sources */, + E83BD30C134DC77082910C65567F529D /* NSHTTPURLResponse+MaxAge.m in Sources */, + EC8A4029FDCEAEEB3810CF75685F7878 /* PINAlternateRepresentationProvider.m in Sources */, + 8DC6B9827D1C470510DC8F6E2F8B7086 /* PINAnimatedImage.m in Sources */, + 744967C02A56404990BC6E88C01BA548 /* PINAnimatedImageView+PINRemoteImage.m in Sources */, + 2984AD51F86779E093DBAF2C5DA6CB67 /* PINAnimatedImageView.m in Sources */, + 861967ACB77A0D10A198A15478A9FE5F /* PINButton+PINRemoteImage.m in Sources */, + 285F918F7A4896FA40D130FD5F6955EA /* PINCache+PINRemoteImageCaching.m in Sources */, + DD519256677113580497A433745E2AA5 /* PINCachedAnimatedImage.m in Sources */, + A86B4CF5B6E0E90E2002EFD6ECA2E74A /* PINDisplayLink.m in Sources */, + BF6DF4769ECC4026C46285CB77452357 /* PINGIFAnimatedImage.m in Sources */, + 8D5C3CB94A4EDD4BD08D8A18A9BD7356 /* PINImage+DecodedImage.m in Sources */, + 2799C7F1375B432E35F44F6B2011315E /* PINImage+ScaledImage.m in Sources */, + 2BC2B38EA553A533961723CECFC08DA2 /* PINImage+WebP.m in Sources */, + 74242DB7DEB36F897B59CC95AED2BDAE /* PINImageView+PINRemoteImage.m in Sources */, + 07DA5777E40B8C2671D3103F8E76F969 /* PINProgressiveImage.m in Sources */, + FA3B40D2C4CB095BE4314E8F1FF7000C /* PINRemoteImage-dummy.m in Sources */, + 386D4195994F9806D03777081DAEADC4 /* PINRemoteImageBasicCache.m in Sources */, + EBB22015243AF51E4A657BEB9377011D /* PINRemoteImageCallbacks.m in Sources */, + 0D6962F9248D95D9655C562687D377DD /* PINRemoteImageCategoryManager.m in Sources */, + 36C8E40A9B88DEE0CDE6738E6CE9B613 /* PINRemoteImageDownloadQueue.m in Sources */, + 3B4BDFF8FC2D4FC9050E5A18F96634F2 /* PINRemoteImageDownloadTask.m in Sources */, + ECB48648B7061F5DA13D61BF35E9E675 /* PINRemoteImageManager.m in Sources */, + 33A58AB76D5143C6639B180900E8A4AB /* PINRemoteImageManagerConfiguration.m in Sources */, + 9BB8B7D153A17A4341454EB34059F2D9 /* PINRemoteImageManagerResult.m in Sources */, + 78EA95A196E301CABCA9B8EF56972FE5 /* PINRemoteImageMemoryContainer.m in Sources */, + 047062E4C55AF0E9668F0D8A5210D4FA /* PINRemoteImageProcessorTask.m in Sources */, + 5D596E9F8BA6D87E1ADD712A13F131CF /* PINRemoteImageTask.m in Sources */, + D0D844293600CC08BA0440D086DF6F31 /* PINRemoteLock.m in Sources */, + DE51CF9E4A5474D3988D1BB66EF7618D /* PINRemoteWeakProxy.m in Sources */, + 7C9889D2309D0F679BEFAEF035704D5B /* PINRequestRetryStrategy.m in Sources */, + 1B264109896A02DB437B7C2FF68DF711 /* PINResume.m in Sources */, + FF156CB786C29B397B3A97686DDDA057 /* PINSpeedRecorder.m in Sources */, + ED7E794ADD340BEFFC80FC75837CFBBC /* PINURLSessionManager.m in Sources */, + 23E0F25169AB9190135651F5D06E8AFE /* PINWebPAnimatedImage.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C967B2A425365D2ACC338CAA2CC33900 /* Sources */ = { + C1B61E7C7CFBEB67C3AF77D3B185E9FD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E12D16B7BE97678712A0209876969023 /* PINOperation-dummy.m in Sources */, - 1064084DBDBC4D7B2C58F56C50F973A6 /* PINOperationGroup.m in Sources */, - 5DC3958D6527253CDDE5F8B2D00273B6 /* PINOperationQueue.m in Sources */, + EC5DD146A3413EF265E41C662ACFEA4B /* PINCache-dummy.m in Sources */, + 3364AEA7B40321356FE24B945F836C81 /* PINCache.m in Sources */, + 7662C10817C380C0792B383089502CAE /* PINDiskCache.m in Sources */, + C5F9B33244F7F718765BD17232268474 /* PINMemoryCache.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C9F4C3B3ABAD6CF00880FA054E7989F2 /* Sources */ = { + CB530576E4CA6C8788F7A8ACC6408DB2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 60B2952345981538EAF69C458EB663FE /* _ASAsyncTransaction.mm in Sources */, - 418C29E0B1D31105C9F3F09AD392AC67 /* _ASAsyncTransactionContainer.mm in Sources */, - A4C3B774A642CA7364A1DFB058721A68 /* _ASAsyncTransactionGroup.mm in Sources */, - 6D6B4B4263CD5E493A3CDC6871E5C71F /* _ASCollectionGalleryLayoutInfo.mm in Sources */, - EC1BB835D45773A0FFC8211C6BDC7DD3 /* _ASCollectionGalleryLayoutItem.mm in Sources */, - B2FF0B3F9E98DB9D32AC6F1FB4AF5973 /* _ASCollectionReusableView.mm in Sources */, - 7AD6ADCCC8C353495C934B8A5283D300 /* _ASCollectionViewCell.mm in Sources */, - 75B6AB3A7B5AF53467B25C45DF3B96C4 /* _ASCoreAnimationExtras.mm in Sources */, - 4C23EF2E6893AA838D689B28DC1F13E4 /* _ASDisplayLayer.mm in Sources */, - 9FFC4ED0B295E09FAF76E7892F457C62 /* _ASDisplayView.mm in Sources */, - DB83DB23211033F5D5A49DD39823CBEA /* _ASDisplayViewAccessiblity.mm in Sources */, - E05DDD2C31BAE9AFECC32980200EE627 /* _ASHierarchyChangeSet.mm in Sources */, - DEC3B69E096361E51BB678635ED78D1F /* _ASPendingState.mm in Sources */, - 52F16FA44A76E4C5D48734B43A537E5C /* _ASTransitionContext.mm in Sources */, - CA38ACE37FA6D3346953C102DC0CF417 /* ASAbsoluteLayoutSpec.mm in Sources */, - 8C3FFBD6AF1E1EE9E8B2638A90E65636 /* ASAbstractLayoutController.mm in Sources */, - 49D95BC71BDB81CF58A39ACF9704F2D2 /* ASAsciiArtBoxCreator.mm in Sources */, - F6F5A0CCAB6863529C1717F73562EECB /* ASAssert.mm in Sources */, - DA9D9E86E8AE00381E6236E38FE48D48 /* ASBackgroundLayoutSpec.mm in Sources */, - D8764C01C83F047859F91BD38CF46998 /* ASBasicImageDownloader.mm in Sources */, - 51CD3CA60054DAA0FFCD9DF88D973559 /* ASBatchContext.mm in Sources */, - 8A246297882AF4DC93926DC6E8C21371 /* ASBatchFetching.mm in Sources */, - 6D05E87535103228054BD3C4EF5B3A2C /* ASButtonNode.mm in Sources */, - 92710081F9E7141F2E165E6A5CD30818 /* ASCellNode.mm in Sources */, - 4D894BF22B604E122139AD67FBD8129B /* ASCenterLayoutSpec.mm in Sources */, - 799110AB6B3B61159954AD7212E849B6 /* ASCGImageBuffer.mm in Sources */, - 76D6E43BB3212A93FE99A96B8FC61A54 /* ASCollectionElement.mm in Sources */, - 5D982019D9EC96DFD1889874B1BA2500 /* ASCollectionFlowLayoutDelegate.mm in Sources */, - 8C320C32AB123F86A86770E7E82E4043 /* ASCollectionGalleryLayoutDelegate.mm in Sources */, - E5CCE08E7214C14DAF86AFE27769D7C7 /* ASCollectionLayout.mm in Sources */, - 3904433E32284DB84884CDD1B6E1ABED /* ASCollectionLayoutCache.mm in Sources */, - 5138A2E0796CC66D12A85C04920FA8C3 /* ASCollectionLayoutContext.mm in Sources */, - 31592827D033C5045F36B35D5235CD2C /* ASCollectionLayoutDefines.mm in Sources */, - 2DB1908538DE1243A6131530A62FDA54 /* ASCollectionLayoutState.mm in Sources */, - 3CA21E403D8E0004E59088033CBCDD2E /* ASCollectionNode.mm in Sources */, - B94E437AD7533B455340EE6D9A4B6463 /* ASCollections.mm in Sources */, - D1A7903C6CEDB9F9CA80C296D81651CF /* ASCollectionView.mm in Sources */, - 136841D83902F016BF8DAC289E1E3E71 /* ASCollectionViewFlowLayoutInspector.mm in Sources */, - 0D31219B5DC9333FDE2110ED1E4377B2 /* ASCollectionViewLayoutController.mm in Sources */, - CD29B7448A3BBED8D9D3DA42FE2C689A /* ASCollectionViewLayoutInspector.mm in Sources */, - 492AA2B3092756B8366B5069063130CE /* ASConfiguration.mm in Sources */, - E4DA68854AE8AEF318DD2002495169AF /* ASConfigurationInternal.mm in Sources */, - 1E65D5EB0BF41F25B9CEDFDB08A30624 /* ASControlNode+tvOS.mm in Sources */, - 3EDC0AACE3405379DDFBE2E35F8B0193 /* ASControlNode.mm in Sources */, - 46DB5F02CE4430EA881B21A9D3CEE370 /* ASControlTargetAction.mm in Sources */, - DFCB49429811C4C90DB5A12826D22904 /* ASCornerLayoutSpec.mm in Sources */, - 4F8327C406F433956A1A6A2AA46625B7 /* ASDataController.mm in Sources */, - 403C3B83126978396F209A3E5B7F6E7B /* ASDefaultPlaybackButton.mm in Sources */, - 508B94D0F4CDBB448A79FE70A11A36E2 /* ASDefaultPlayButton.mm in Sources */, - DF84A4991B37EECA24F294A6CB489AD5 /* ASDelegateProxy.mm in Sources */, - 7D209077CBCD22897C437A088B0F716A /* ASDimension.mm in Sources */, - 1A5F8D66D71A2AB8F4A5D7153246EFA4 /* ASDimensionInternal.mm in Sources */, - 1E1C0ACF37949DE482591B7149C6EBD9 /* ASDispatch.mm in Sources */, - C1C72D17FE7705F75F7D4A489C7FA901 /* ASDisplayNode+Ancestry.mm in Sources */, - C0A756D0CF5C0FA0BC67C0913192242D /* ASDisplayNode+AsyncDisplay.mm in Sources */, - C4A841122A1500C4F97A8D7C9E9D74BE /* ASDisplayNode+Convenience.mm in Sources */, - 8C846B6A703E78ED3479D656EE086558 /* ASDisplayNode+DebugTiming.mm in Sources */, - 6F6E88826C13843A8DC1B91ACAE2F01F /* ASDisplayNode+Layout.mm in Sources */, - D25038080560B83F9B92E9F473DB10D8 /* ASDisplayNode+LayoutSpec.mm in Sources */, - F8CD2CEBEBC1919F3E0F582F4CDF026D /* ASDisplayNode+UIViewBridge.mm in Sources */, - 3B5CF4A5E8DD242D99FAE2464626184F /* ASDisplayNode+Yoga.mm in Sources */, - 79CBD53F1BA8489870E7D07145984BEC /* ASDisplayNode.mm in Sources */, - AD4C26854C3F360B75A93F838BABA6AF /* ASDisplayNodeCornerLayerDelegate.mm in Sources */, - 1B97AAE188468779CE6CE48E9942428D /* ASDisplayNodeExtras.mm in Sources */, - 441D77CEBE2C3B8D28B5866F90374B50 /* ASDisplayNodeTipState.mm in Sources */, - 36575619B625EF1C5E621DDE0F9E99EB /* ASEditableTextNode.mm in Sources */, - 8E6B862A8628615589A2419BA04372A7 /* ASElementMap.mm in Sources */, - CDDB2859AD81C0BF3798E6E4B11D7EEB /* ASEventLog.mm in Sources */, - E1018F5B00E75731D029ADA8F9428D59 /* ASExperimentalFeatures.mm in Sources */, - 3A4C3C416115B6811876A290B0E3F9A9 /* ASGraphicsContext.mm in Sources */, - B3EF3DC901FEA39B0E0C790BC28A8A6D /* ASHashing.mm in Sources */, - DFB6860FBD6FBDCC6A3F1F6B4D96D78D /* ASHighlightOverlayLayer.mm in Sources */, - 10D745D19BDB05D784DA5ED816193FCA /* ASIGListAdapterBasedDataSource.mm in Sources */, - 5780A5A1818821D7645F46D8748C35AA /* ASImageContainerProtocolCategories.mm in Sources */, - 3E7A0FCCEA205520EDA2161B19BA9299 /* ASImageNode+AnimatedImage.mm in Sources */, - 2BA8083637ADC46C06E7E4AE82EA4C18 /* ASImageNode+CGExtras.mm in Sources */, - 902BAA1256D27B4392C7348AFB5E562E /* ASImageNode+tvOS.mm in Sources */, - A17158F8FEBD7F5199C031A6BE661B41 /* ASImageNode.mm in Sources */, - D2F6B3F151EE8B106C6E6105EC1739CE /* ASInsetLayoutSpec.mm in Sources */, - CCC6E16B2EBA80F74ADB96FB4A0321C1 /* ASIntegerMap.mm in Sources */, - CB8FAB30E0D91EDBB367D698A9BDFB36 /* ASInternalHelpers.mm in Sources */, - 66AA299AFB2C6722FBFA8D31B8E7D980 /* ASLayerBackingTipProvider.mm in Sources */, - 76486E3D71D10617BF6F2AE87460B3CA /* ASLayout+IGListKit.mm in Sources */, - 7CC5C2375A5EC03117CA2CA5B9C5F76D /* ASLayout.mm in Sources */, - 00AAF4C9D0B7869478DE156A538755F1 /* ASLayoutElement.mm in Sources */, - 66B67B26FAC73CCF9514B8C3468BF19D /* ASLayoutManager.mm in Sources */, - 2823B4A72F9BBA7D501A89E6EBDB81BE /* ASLayoutSpec+Subclasses.mm in Sources */, - E05B0B1D8724CCCB6E7F7B3843FB8884 /* ASLayoutSpec.mm in Sources */, - 7938644E140C00A37AEE202C0D91E0F2 /* ASLayoutTransition.mm in Sources */, - DA6B7135D9C9052FD7BC1B108F3B28DD /* ASLog.mm in Sources */, - B363D99E3B2358D13561DFAA81BD9573 /* ASMainSerialQueue.mm in Sources */, - FF965E8D91F7AE6511721F23130A8ACF /* ASMainThreadDeallocation.mm in Sources */, - D35D3F99EDC15ED140F016F880FF37ED /* ASMapNode.mm in Sources */, - DD8AE4A94D416EF6C0388BBC6C92493A /* ASMultiplexImageNode.mm in Sources */, - 4885AC283DC3BCEE21F90AE65106A0E3 /* ASMutableAttributedStringBuilder.mm in Sources */, - 01EB60D21A8130AF1CA4BEFEAB97AAE0 /* ASMutableElementMap.mm in Sources */, - F90417F58EC71BEE267F22B71CDD3A42 /* ASNavigationController.mm in Sources */, - CABC9E83A17F030D6B854E7BE681F79E /* ASNetworkImageLoadInfo.mm in Sources */, - 20DA623C76E1F8309F402CDECC5B9B42 /* ASNetworkImageNode.mm in Sources */, - 43CEE1A4B055933A0CB57409BDD51592 /* ASNodeController+Beta.mm in Sources */, - B4DA513CE3CDFB3203AE2B5598D59137 /* ASObjectDescriptionHelpers.mm in Sources */, - 980BF8E99DA73B6A3668CF91ECA47EDF /* ASOverlayLayoutSpec.mm in Sources */, - 3306C0DFD430ED8ACDA69D3A648D30B3 /* ASPagerFlowLayout.mm in Sources */, - EF79F88DE3DEBC770852C44680868FC6 /* ASPagerNode.mm in Sources */, - 520EA1553E617D6F84D57E6EAC9B5636 /* ASPageTable.mm in Sources */, - 5D52196BA79E4B7319FDE3B3C945A1E7 /* ASPendingStateController.mm in Sources */, - FE7DAF6410C68A5F2E2049B56FD4C2BD /* ASPhotosFrameworkImageRequest.mm in Sources */, - DAC47FBAC82155097731E61283236AC2 /* ASPINRemoteImageDownloader.mm in Sources */, - B314498ED96D2F0129A1A368118CD09C /* ASRangeController.mm in Sources */, - 94E4C0B68327D60B4DF469FEB4CA440A /* ASRatioLayoutSpec.mm in Sources */, - 4995DFDD8EC929DD86E170B882E3296B /* ASRecursiveUnfairLock.mm in Sources */, - A90DD763EC5DCE3CCC51D4B4D817FF0B /* ASRelativeLayoutSpec.mm in Sources */, - 0725BBB7407A94716CE1B783F29AB8E4 /* ASResponderChainEnumerator.mm in Sources */, - 27A3884796954EA8D1329687A8137FD9 /* ASRunLoopQueue.mm in Sources */, - 9EB5736C9607BD9049A4133F20594F65 /* ASScrollDirection.mm in Sources */, - 6E4633B4A34D4DC1FA0D5CBAEB4220A8 /* ASScrollNode.mm in Sources */, - 97685CD14F9FC6EC714BF57A8285B3DC /* ASSection.mm in Sources */, - 0243198C0934549E3873E32EF8E14B1D /* ASStackLayoutSpec.mm in Sources */, - 7DB2B68B4C0E8B6D2D778243D7942375 /* ASStackPositionedLayout.mm in Sources */, - 55DD95F28848F04D481771EC1EDC5BE3 /* ASStackUnpositionedLayout.mm in Sources */, - 08608B2879CDB2B1F99FA21A85C0C43E /* ASTabBarController.mm in Sources */, - 72A60D282E9C26F5EF2C0AB2908818C1 /* ASTableLayoutController.mm in Sources */, - 8DCCACCBADEC4FFCAE7F8CFA17843F6F /* ASTableNode.mm in Sources */, - 37CA83359712F5584386382793206669 /* ASTableView.mm in Sources */, - 04B103CAF019243ADC4DC9D3DD90A5CF /* ASTextAttribute.mm in Sources */, - BBB7FB02F6F6557968A0F8B614A3F917 /* ASTextDebugOption.mm in Sources */, - 77B4529FD12983A4B2E36A8B27A7FA69 /* ASTextInput.mm in Sources */, - E763AAE38EA62B4F77B25AD8CC2A8219 /* ASTextKitAttributes.mm in Sources */, - 1DC39F3F4F72437DE712C602F5AE4190 /* ASTextKitComponents.mm in Sources */, - ACF8783CAC2A000FD0C6466582F4181B /* ASTextKitContext.mm in Sources */, - 927F14D8D5513C8096D98B5A6ACFFA7B /* ASTextKitCoreTextAdditions.mm in Sources */, - 253FC2EE7D347619C895A80B6C0A1A3D /* ASTextKitEntityAttribute.mm in Sources */, - F636F0AC9D61B6CEE7356E35A1B21F98 /* ASTextKitFontSizeAdjuster.mm in Sources */, - EDD39001F5CEE1894315A687A3BBB54F /* ASTextKitRenderer+Positioning.mm in Sources */, - 66E9B6C804D7C61BA4314762F68ECB5B /* ASTextKitRenderer+TextChecking.mm in Sources */, - 6B7F558A8833FBC4915598ED230F8A48 /* ASTextKitRenderer.mm in Sources */, - D151AD5C0614B9CD096813DA5583792E /* ASTextKitShadower.mm in Sources */, - A16C3DA62CC6E9362A34AB89F8981591 /* ASTextKitTailTruncater.mm in Sources */, - C11E6D5E0CB6B45942374FC4161D0EFB /* ASTextLayout.mm in Sources */, - 798E0F169582BD5816A770931B6BFBC6 /* ASTextLine.mm in Sources */, - C5314BB868384564ECF4372C0175B34E /* ASTextNode.mm in Sources */, - 134CD958011333FAD509D1BD3F5D56F0 /* ASTextNode2.mm in Sources */, - E86A4F5E18F02F6D89A404F499A916E9 /* ASTextNodeWordKerner.mm in Sources */, - 1F70E930F9B87CC562271891712E24FF /* ASTextRunDelegate.mm in Sources */, - D61DF2CD8BEA2617F8A666D0F3828466 /* ASTextUtilities.mm in Sources */, - 1322EE221856557E83837888D63E3906 /* ASTip.mm in Sources */, - 0E1DD80748781A950EE5F94272757B5E /* ASTipNode.mm in Sources */, - 9B2EE65ED8B007D4C344FEC6F768C9B4 /* ASTipProvider.mm in Sources */, - 12225A320709A7FE471FBED2E9BC6F4F /* ASTipsController.mm in Sources */, - 8370E1B3198D380C3BFE9CA9F112F34C /* ASTipsWindow.mm in Sources */, - 88DEFDC0E299F801BC7656503D7264E2 /* ASTraceEvent.mm in Sources */, - 23BE55E8E6410B8D54D6F9C2D40BD16D /* ASTraitCollection.mm in Sources */, - CAD0F1279420E3AB6FE9053ACE0052AE /* ASTwoDimensionalArrayUtils.mm in Sources */, - FB5EEFB759CCDAC5A4D34FF8BC26A5C8 /* ASVideoNode.mm in Sources */, - 2BF72546F7877287B909A3110DD68986 /* ASVideoPlayerNode.mm in Sources */, - B0C54A106E41470E67AE2D2581DE4D27 /* ASViewController.mm in Sources */, - 8CD5FC51F562381181973EDBA13A4133 /* ASVisibilityProtocols.mm in Sources */, - E562E9196F87EB8868D5D150A50A4A0F /* ASWeakMap.mm in Sources */, - AAAE1A514D5EF921A3B3F2DF7FFEA117 /* ASWeakProxy.mm in Sources */, - 892242FD73E991B08D538460AEECC49B /* ASWeakSet.mm in Sources */, - B7E91ABE499B6733517D33FE1E4C1502 /* AsyncDisplayKit+Debug.mm in Sources */, - A48232B6EDFE017E0E343845B96EDDDB /* AsyncDisplayKit+IGListKitMethods.mm in Sources */, - 61818283679C6B38C94B9FB8B0AD55D6 /* AsyncDisplayKit+Tips.mm in Sources */, - 72D59D32A599A93C75D4FDAB7DC9737B /* ASYogaUtilities.mm in Sources */, - D31960D7801C8096710BC1E5BA45D3BC /* IGListAdapter+AsyncDisplayKit.mm in Sources */, - FCD292D043C501CF54E50BC83FB553E4 /* NSArray+Diffing.mm in Sources */, - 6377CEF639BB89C5C48555D177F4F34D /* NSAttributedString+ASText.mm in Sources */, - BA991D5B0D15C90393E182370ED3F7E3 /* NSIndexSet+ASHelpers.mm in Sources */, - 240BADF0416FB59ACD5D0102D73EC8E4 /* NSMutableAttributedString+TextKitAdditions.mm in Sources */, - C7EA3CF590053B0DF7B361B0BE896FE4 /* NSParagraphStyle+ASText.mm in Sources */, - D2D96C2A2312008724BC4C55BD130768 /* Texture-dummy.m in Sources */, - E7431794E12712C34829C882DA2C3E84 /* UICollectionViewLayout+ASConvenience.mm in Sources */, - 4762888C778D64B38AC1EE35F4D73F95 /* UIImage+ASConvenience.mm in Sources */, - 91FBB18FC6B78968CD3790576B1D791C /* UIResponder+AsyncDisplayKit.mm in Sources */, + 030C344EB05992E778CC730E39FB7709 /* AnimationEvent.swift in Sources */, + C4AD7C4F531DA9DD921A1218FEECE798 /* Animator.swift in Sources */, + 3D2C49C67BE979EADC17D22BF706D324 /* BounceOffsets.swift in Sources */, + 218E0CCCF87BB42550E157E145C6F584 /* CanAnimate.swift in Sources */, + C9C824BB23E3DE352523EC1811E6C2CF /* CanBetriggered.swift in Sources */, + 319FBFD5A5F8BB64B085C15007F1A250 /* CanManageZoomBehaviors.swift in Sources */, + E0A675EB8187301FBECDFEFDDF256FB5 /* CanPerformAction.swift in Sources */, + 25252F72502AA588EBB17EFDC7B915A1 /* CanProvideAnimatorForEvent.swift in Sources */, + B2E9AB96E82BA908122E38CABFFC981C /* CGAffineTransform+transformWithScaleTranslationCenter.swift in Sources */, + BF8095C5CC9C0A19DB54653A650E6DB3 /* CGPoint+dominantDirection.swift in Sources */, + 6966F6D5921F4FAF58B42833254B0CF3 /* CGPoint+maximumAbsoluteValue.swift in Sources */, + 742E9673AF159AE10F13506C910DA072 /* CGPoint+valueInDirection.swift in Sources */, + 96941E07E408BDF2122A01A926C0D52A /* CGRect+Difference.swift in Sources */, + 503122D8D65C663AE2CFCBFD675521F9 /* CGRect+transformedByTransform.swift in Sources */, + 0FEFBFB43ACCE25E8F4A6A699FA9D8B8 /* ConfigurableUsingClosure.swift in Sources */, + CEDB3EE3AAF87289B735602105E6FCEB /* DefaultAnimators.swift in Sources */, + 22AF64923BA5C136C59879B167617CA0 /* HasImageZoomControllers.swift in Sources */, + 5458596C6EE471CD495C661E92AA7788 /* ImageZoomController.Factory.swift in Sources */, + 942B48F3549901BB482B4861CE2FF178 /* ImageZoomController.swift in Sources */, + CFCAA590EA07C323370BBF4B05D775A5 /* ImageZoomControllerActions.swift in Sources */, + 26509BF34207E046B32367284B9E8DFA /* ImageZoomControllerContentState.swift in Sources */, + 0D1E926C7BD4DECD45A42036400EB261 /* ImageZoomControllerDelegate.swift in Sources */, + 60DE96D7E222EE4EE01E6DDF4710C78C /* ImageZoomControllerIsHandlingScrollViewBounceTriggeredDismissalState.swift in Sources */, + 11F5542BE8045A9068A57312EA5A028B /* ImageZoomControllerIsNotPresentingOverlayState.swift in Sources */, + 423FABDE3A20680EE138D3803DD6F2DC /* ImageZoomControllerIsPresentingImageViewOverlayState.swift in Sources */, + CDCC96FDBA67CD248AA13D4552D08B6F /* ImageZoomControllerIsPresentingScrollViewOverlayState.swift in Sources */, + 118F802C5199A586B39872DA5C5D70F9 /* ImageZoomControllerSettings+Equatable.swift in Sources */, + A3F4FE270937507D945DC440C5B3926E /* ImageZoomControllerSettings.swift in Sources */, + EFD256412FBB95F43A7114D1A0846301 /* ImageZoomControllerState.swift in Sources */, + 3213C2AD15E9B0CEA5DF4C1BAF3B2684 /* logger.swift in Sources */, + 41BE5BD614270839466666BEAC31B4F7 /* NSObject+AsociatedKeyForImageZoomControllers.swift in Sources */, + 15F5D45FBEC8A2C1AB621B8C2A4FED33 /* Side.swift in Sources */, + 6835DC954F0CF2CDF87AF3D95EF3604F /* SpringAnimator.swift in Sources */, + EE5B2A3F1514028E9756AAB7326B8ABC /* TypeAliasses.swift in Sources */, + D9554845DD1077123FC15B6F5FCD3050 /* UIGestureRecognizerState+CustomStringConvertible.swift in Sources */, + 5EAA850D67988DBDD6DCBE0F03D51DF5 /* UIImage+Color.swift in Sources */, + BCFF513947E0A3BA88E07AF5CE09F292 /* UIImageView+Zoomable.swift in Sources */, + EF3997132E45070F8934DFEF9D904A41 /* UIView+layoutHelpers.swift in Sources */, + 0BA46D04026103E69FEDDCECB4C092F8 /* UIViewController+CanManageZoomBehavior.swift in Sources */, + CEC0B7603A9B1CD378F02F1618FDB8D1 /* UIViewController+HasImageZoomControllers.swift in Sources */, + DE2B62E460FBD72E703EC2EB8F0EF54D /* Zoomable.swift in Sources */, + EDAA17A17F102B0684848D7F2243EEF0 /* Zoomy-dummy.m in Sources */, + 21B002B49EA6268FD714728C7E464A7F /* ZoomyLogger.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3242,96 +3260,102 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EE6941D3A42C1ED276E9151729FCAD22 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9798396EB28775D2D47B9AB4E5D761A6 /* Pods-Zoomy_Example-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 1A79743F84ED2F358625951865C27EC8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = InjectableLoggers; - target = 87C901210314C5B33D0D156EB4065E80 /* InjectableLoggers */; - targetProxy = 169FD5948F5CB9A3377EEF131586648E /* PBXContainerItemProxy */; - }; - 1A9C231615A0B3DFBDCBE6C879A43F11 /* PBXTargetDependency */ = { + 0BFD042443A5793299A80E674FEE5F70 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = PINCache; - target = A927C3CD51C30012080D6CA07959B246 /* PINCache */; - targetProxy = 20B5B114E7838256053942AF687637AB /* PBXContainerItemProxy */; + name = "Pods-Zoomy_Example"; + target = 43C46F311E654020969485F1CE2D78DB /* Pods-Zoomy_Example */; + targetProxy = 01DE0E6C033F494AC9CC06606A613C27 /* PBXContainerItemProxy */; }; - 2878FCD5AE1495E5A7586AD4804F9121 /* PBXTargetDependency */ = { + 131967F7F4F880DA80DD12D81FF8D93C /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = PINOperation; target = 57310B016450E63387C9D64F4933E995 /* PINOperation */; - targetProxy = FF30B81F9789B64937FC47064BE2F2FE /* PBXContainerItemProxy */; - }; - 376A8C24FB02DCF2F5D3522D8DA52FBE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Zoomy; - target = 159BCD99AC1F7CE7112319E6C584776F /* Zoomy */; - targetProxy = 1E70EA43018D6325FA41D3E82A15D5DF /* PBXContainerItemProxy */; + targetProxy = CCEB932B145C2CDB5CC5204860193914 /* PBXContainerItemProxy */; }; - 3A8C577D3A0A9D1DDB802A5C39CEA459 /* PBXTargetDependency */ = { + 223194865C40B02C96D834DE3D6FAA9A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = PINOperation; target = 57310B016450E63387C9D64F4933E995 /* PINOperation */; - targetProxy = 4BA479BF33A3CF04FB4ED9C34E802892 /* PBXContainerItemProxy */; + targetProxy = FEF46F416F93AF95E6C9635F25355BF9 /* PBXContainerItemProxy */; }; - 406B3781A7C004245597BD6C366DD653 /* PBXTargetDependency */ = { + 24DCB5EF3C5585D624336BA527102942 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = PINCache; - target = A927C3CD51C30012080D6CA07959B246 /* PINCache */; - targetProxy = 792DE55ABEE686D3376FF845FEB09BB3 /* PBXContainerItemProxy */; + name = PINRemoteImage; + target = E2A8B2A28D2EAB2E4CCF3B69E6792851 /* PINRemoteImage */; + targetProxy = 4A1FF4606E130E18880D0B3CB0B1EF70 /* PBXContainerItemProxy */; }; - 956621FEDB7779168DE1A7FA5CF6E751 /* PBXTargetDependency */ = { + 303A1DE6A2B09C67231DE68CEE80661E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Texture; - target = DB66E43BC980D741F3C7C5CF3ACEEFA4 /* Texture */; - targetProxy = 286B04891C620D5D4606E8D738CF47C7 /* PBXContainerItemProxy */; + name = PINCache; + target = A927C3CD51C30012080D6CA07959B246 /* PINCache */; + targetProxy = DF609D3EB5027804B8EF35F3F458C97C /* PBXContainerItemProxy */; }; - A311BC91D46A6494B3238D18BDC1C948 /* PBXTargetDependency */ = { + 412D8A7D3EF90A20050E44CA1273D272 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = InjectableLoggers; target = 87C901210314C5B33D0D156EB4065E80 /* InjectableLoggers */; - targetProxy = 26FB0FC8B00E1240DBA6330BF8A55D6A /* PBXContainerItemProxy */; + targetProxy = B305929B6D1BE593C753A90B2510AB4C /* PBXContainerItemProxy */; + }; + 80B8A8586A473C942CFCE9FE98F8A4FD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PINRemoteImage; + target = E2A8B2A28D2EAB2E4CCF3B69E6792851 /* PINRemoteImage */; + targetProxy = 6ACADBBD59E8392C283BEA6CF9C7D7DA /* PBXContainerItemProxy */; }; - A4352981CBE1B2F9DF668586053B2ECB /* PBXTargetDependency */ = { + 82980576C3AED334BE56E11578C8B91D /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = InjectableLoggers; target = 87C901210314C5B33D0D156EB4065E80 /* InjectableLoggers */; - targetProxy = CE9CC00963D6260A8B8E7E760172A397 /* PBXContainerItemProxy */; + targetProxy = 40E3E8573F082241997ECCFEF682F7E2 /* PBXContainerItemProxy */; }; - A902B2D95EAA6F663620D6E8CDACCB1F /* PBXTargetDependency */ = { + A09C766F92D67B48C9B693DAC6317D6D /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = PINRemoteImage; - target = E2A8B2A28D2EAB2E4CCF3B69E6792851 /* PINRemoteImage */; - targetProxy = 9E69C729BDC147DE35E03D350C945696 /* PBXContainerItemProxy */; + name = PINOperation; + target = 57310B016450E63387C9D64F4933E995 /* PINOperation */; + targetProxy = 968D982A4D792D95D7B48D57197BC2C2 /* PBXContainerItemProxy */; }; - AB66CAF24852F8DBCCC3D9C8E59C02D8 /* PBXTargetDependency */ = { + B0A07C61F8660E4693ABFC2FB052F142 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = PINRemoteImage; - target = E2A8B2A28D2EAB2E4CCF3B69E6792851 /* PINRemoteImage */; - targetProxy = AF99DF2C5B1DE9BD3877F13581C78F63 /* PBXContainerItemProxy */; + name = Texture; + target = DB66E43BC980D741F3C7C5CF3ACEEFA4 /* Texture */; + targetProxy = D418FB2567353AF5C24F0A6D9A5BC2F5 /* PBXContainerItemProxy */; }; - E1B141FB624A642EF32744DC2572944B /* PBXTargetDependency */ = { + D247019110BBD782DC6AF87B0E349833 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "Pods-Zoomy_Example"; - target = 43C46F311E654020969485F1CE2D78DB /* Pods-Zoomy_Example */; - targetProxy = 42F6296AE51CECA420F6AE0EB1ABCCE3 /* PBXContainerItemProxy */; + name = Zoomy; + target = 159BCD99AC1F7CE7112319E6C584776F /* Zoomy */; + targetProxy = 9799295E8AC30B9C0E603876C70AF87E /* PBXContainerItemProxy */; }; - E2573EA6C5717696D6FE8241287E22BF /* PBXTargetDependency */ = { + EBB57BE390B41A783ADA597BB44EB9F5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = PINOperation; - target = 57310B016450E63387C9D64F4933E995 /* PINOperation */; - targetProxy = 35AA28F7C7A889F1E5AA1095A517A762 /* PBXContainerItemProxy */; + name = InjectableLoggers; + target = 87C901210314C5B33D0D156EB4065E80 /* InjectableLoggers */; + targetProxy = 294AA6C335A6198807ABE2448FD36FF3 /* PBXContainerItemProxy */; + }; + EC1F18F4329DFB524BE68E70F2AB5869 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PINCache; + target = A927C3CD51C30012080D6CA07959B246 /* PINCache */; + targetProxy = DF7FE2683D059AC70D93B977B69C42BD /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 07BF91B0C54FE800B7CB61C7CDB0DCB3 /* Debug */ = { + 0505567233D733C12497302290D37B67 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 39AAC467404002DC03ECB50462243558 /* InjectableLoggers.xcconfig */; + baseConfigurationReference = F2DB9FFDC78A1FFD1EAFA4CB07F1F0C8 /* Texture.debug.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3340,14 +3364,14 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/InjectableLoggers/InjectableLoggers-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/InjectableLoggers/InjectableLoggers-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/Texture/Texture-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Texture/Texture-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/InjectableLoggers/InjectableLoggers.modulemap"; - PRODUCT_MODULE_NAME = InjectableLoggers; - PRODUCT_NAME = InjectableLoggers; + MODULEMAP_FILE = "Target Support Files/Texture/Texture.modulemap"; + PRODUCT_MODULE_NAME = AsyncDisplayKit; + PRODUCT_NAME = AsyncDisplayKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; @@ -3358,12 +3382,10 @@ }; name = Debug; }; - 1914CA58AACC7ABB5C506974505D3462 /* Debug */ = { + 0FCC6FA7F8AE5C68E7F6B25525A49B86 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 638BCD02FE611C5776A63C02551D7ED6 /* PINRemoteImage.xcconfig */; + baseConfigurationReference = 7AF0970735CEF05D54172A8598F05F00 /* InjectableLoggers.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3372,28 +3394,30 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/PINRemoteImage/PINRemoteImage-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/InjectableLoggers/InjectableLoggers-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/InjectableLoggers/InjectableLoggers-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage.modulemap"; - PRODUCT_MODULE_NAME = PINRemoteImage; - PRODUCT_NAME = PINRemoteImage; + MODULEMAP_FILE = "Target Support Files/InjectableLoggers/InjectableLoggers.modulemap"; + PRODUCT_MODULE_NAME = InjectableLoggers; + PRODUCT_NAME = InjectableLoggers; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - 257497152829C177993B5EC99C1D227A /* Release */ = { + 2B9E26EAE2CD392AD762421F663075A1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -3416,6 +3440,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -3423,13 +3448,16 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; + DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_RELEASE=1", + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -3438,24 +3466,23 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; - name = Release; + name = Debug; }; - 33603934652B731CD2AED69E205664D1 /* Release */ = { + 35C965BA81A9ABB07AD8B4134DC9A297 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 724D27438A0502C29D8A0A72E0248013 /* Zoomy.xcconfig */; + baseConfigurationReference = 8D2B6528B911C7F2F567D3505C788ED9 /* PINCache.debug.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3464,31 +3491,89 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/Zoomy/Zoomy-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Zoomy/Zoomy-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/PINCache/PINCache-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PINCache/PINCache-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/Zoomy/Zoomy.modulemap"; - PRODUCT_MODULE_NAME = Zoomy; - PRODUCT_NAME = Zoomy; + MODULEMAP_FILE = "Target Support Files/PINCache/PINCache.modulemap"; + PRODUCT_MODULE_NAME = PINCache; + PRODUCT_NAME = PINCache; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; + name = Debug; + }; + 63FAF33E1C55B71A5F5A8B3CC8749F99 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; name = Release; }; - 4C860EC22E3E90D1BD49D8F6B499D945 /* Release */ = { + 7886032428261A19CC71D50A73412346 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 49E96E5D11156E2C12B0FF6F8ACD6B3D /* PINOperation.xcconfig */; + baseConfigurationReference = BAF321EC18304D2D7018D41AE15755A2 /* PINCache.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3497,14 +3582,14 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/PINOperation/PINOperation-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/PINOperation/PINOperation-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/PINCache/PINCache-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PINCache/PINCache-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/PINOperation/PINOperation.modulemap"; - PRODUCT_MODULE_NAME = PINOperation; - PRODUCT_NAME = PINOperation; + MODULEMAP_FILE = "Target Support Files/PINCache/PINCache.modulemap"; + PRODUCT_MODULE_NAME = PINCache; + PRODUCT_NAME = PINCache; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; @@ -3516,12 +3601,10 @@ }; name = Release; }; - 50A878715B640D8DCC73F268EA7E1090 /* Release */ = { + 8BFE928F924913D9BE960B9173284ACB /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 638BCD02FE611C5776A63C02551D7ED6 /* PINRemoteImage.xcconfig */; + baseConfigurationReference = 522F7194EE4805844AF8037C5D463760 /* PINOperation.debug.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3530,31 +3613,28 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/PINRemoteImage/PINRemoteImage-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/PINOperation/PINOperation-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PINOperation/PINOperation-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage.modulemap"; - PRODUCT_MODULE_NAME = PINRemoteImage; - PRODUCT_NAME = PINRemoteImage; + MODULEMAP_FILE = "Target Support Files/PINOperation/PINOperation.modulemap"; + PRODUCT_MODULE_NAME = PINOperation; + PRODUCT_NAME = PINOperation; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - 702665F7E4F51F7122D92DC34288D2A5 /* Debug */ = { + 968242DC1FD972197D42C524394DB10A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BA4B0255BD9DE24340698FC805C07449 /* PINCache.xcconfig */; + baseConfigurationReference = D4CC5A8855E96D7657A8163FB9889C8E /* PINRemoteImage.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3563,30 +3643,28 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/PINCache/PINCache-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/PINCache/PINCache-Info.plist"; + INFOPLIST_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/PINCache/PINCache.modulemap"; - PRODUCT_MODULE_NAME = PINCache; - PRODUCT_NAME = PINCache; + MODULEMAP_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage.modulemap"; + PRODUCT_MODULE_NAME = PINRemoteImage; + PRODUCT_NAME = PINRemoteImage; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - 714F3E19A3D0BE1B693B6C04D32DAA6A /* Debug */ = { + A030C28A40E3EF2BAF84436068970B42 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 49E96E5D11156E2C12B0FF6F8ACD6B3D /* PINOperation.xcconfig */; + baseConfigurationReference = 8FB1B03C5E645FDFD3FACFBDACA87DB9 /* Zoomy.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3595,30 +3673,29 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/PINOperation/PINOperation-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/PINOperation/PINOperation-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/Zoomy/Zoomy-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Zoomy/Zoomy-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/PINOperation/PINOperation.modulemap"; - PRODUCT_MODULE_NAME = PINOperation; - PRODUCT_NAME = PINOperation; + MODULEMAP_FILE = "Target Support Files/Zoomy/Zoomy.modulemap"; + PRODUCT_MODULE_NAME = Zoomy; + PRODUCT_NAME = Zoomy; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - 8D04478F3E00A59AA36CEA6481E86C58 /* Release */ = { + A89B5D55AEAB47765DFDDE3ADE997875 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 39AAC467404002DC03ECB50462243558 /* InjectableLoggers.xcconfig */; + baseConfigurationReference = A6260ECA1905AD096C8931DC364B024D /* InjectableLoggers.debug.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3630,7 +3707,7 @@ GCC_PREFIX_HEADER = "Target Support Files/InjectableLoggers/InjectableLoggers-prefix.pch"; INFOPLIST_FILE = "Target Support Files/InjectableLoggers/InjectableLoggers-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/InjectableLoggers/InjectableLoggers.modulemap"; PRODUCT_MODULE_NAME = InjectableLoggers; @@ -3640,18 +3717,15 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - 952162EB478A085F5CA2038AA6945647 /* Release */ = { + B2503807C55928A0B5791D707F9FE9B5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 073F5156FDFEF3B8AA6981CD17F054AE /* Texture.xcconfig */; + baseConfigurationReference = 46310E5AB97B1359090388D99D9A9CD0 /* Texture.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3663,7 +3737,7 @@ GCC_PREFIX_HEADER = "Target Support Files/Texture/Texture-prefix.pch"; INFOPLIST_FILE = "Target Support Files/Texture/Texture-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/Texture/Texture.modulemap"; PRODUCT_MODULE_NAME = AsyncDisplayKit; @@ -3679,12 +3753,12 @@ }; name = Release; }; - 9DEB8B318286B13C49EC7B05D4D156E3 /* Debug */ = { + C12D2C4025C7B2E7BC2712EA9068F63A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 073F5156FDFEF3B8AA6981CD17F054AE /* Texture.xcconfig */; + baseConfigurationReference = CADDCC912439D00D2D010CFA70629127 /* Pods-Zoomy_Tests.debug.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3693,32 +3767,29 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/Texture/Texture-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Texture/Texture-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/Texture/Texture.modulemap"; - PRODUCT_MODULE_NAME = AsyncDisplayKit; - PRODUCT_NAME = AsyncDisplayKit; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - AF2709D513F7F1228222FC7A6AE5379E /* Release */ = { + C89C168FE41FA83B79121C31C534FBA4 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 08FAA55FB0053B36E2D4836258EBEEC4 /* Pods-Zoomy_Example.release.xcconfig */; + baseConfigurationReference = A0126269F7621AA924B3EA6B12F43F45 /* Zoomy.debug.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3727,34 +3798,30 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/Zoomy/Zoomy-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Zoomy/Zoomy-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + MODULEMAP_FILE = "Target Support Files/Zoomy/Zoomy.modulemap"; + PRODUCT_MODULE_NAME = Zoomy; + PRODUCT_NAME = Zoomy; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - C7D74F1435586754B8FF8DC620EF5FA8 /* Debug */ = { + D745690DA83EC92B79B247CA9828D34B /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CADDCC912439D00D2D010CFA70629127 /* Pods-Zoomy_Tests.debug.xcconfig */; + baseConfigurationReference = CD1FE7E96A5E345D913F7FF58A0CCFE0 /* Pods-Zoomy_Example.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3763,12 +3830,12 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.modulemap"; + MODULEMAP_FILE = "Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; @@ -3782,12 +3849,12 @@ }; name = Debug; }; - D2D4EF8EB09CEA6C337A9967DB53A7DA /* Debug */ = { + D8DC229F44BBD09EE35917CCFC51CF65 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 724D27438A0502C29D8A0A72E0248013 /* Zoomy.xcconfig */; + baseConfigurationReference = 214924C9F0E2FAC0CB4EAEEAC304F1BB /* Pods-Zoomy_Tests.release.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3796,94 +3863,30 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/Zoomy/Zoomy-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Zoomy/Zoomy-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/Zoomy/Zoomy.modulemap"; - PRODUCT_MODULE_NAME = Zoomy; - PRODUCT_NAME = Zoomy; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; - }; - DD8F832993327D1DD8046C3CBCBD97CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_DEBUG=1", - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - STRIP_INSTALLED_PRODUCT = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - SYMROOT = "${SRCROOT}/../build"; - }; - name = Debug; + name = Release; }; - F0340C119AA7E9D4E910EA3C4F4A8F5A /* Release */ = { + DB690DEAD73E16646E201820007C72B5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BA4B0255BD9DE24340698FC805C07449 /* PINCache.xcconfig */; + baseConfigurationReference = 540D079F51C83D244C9ED5EB1C961001 /* PINRemoteImage.debug.xcconfig */; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3892,33 +3895,29 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/PINCache/PINCache-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/PINCache/PINCache-Info.plist"; + INFOPLIST_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/PINCache/PINCache.modulemap"; - PRODUCT_MODULE_NAME = PINCache; - PRODUCT_NAME = PINCache; + MODULEMAP_FILE = "Target Support Files/PINRemoteImage/PINRemoteImage.modulemap"; + PRODUCT_MODULE_NAME = PINRemoteImage; + PRODUCT_NAME = PINRemoteImage; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - F06082FC310E02FE82E19C5E4E259A0D /* Debug */ = { + EDCF68F9D667AB944A92281B884FE29E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CD1FE7E96A5E345D913F7FF58A0CCFE0 /* Pods-Zoomy_Example.debug.xcconfig */; + baseConfigurationReference = 08FAA55FB0053B36E2D4836258EBEEC4 /* Pods-Zoomy_Example.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3929,7 +3928,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.modulemap"; @@ -3941,19 +3940,16 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - F561FB73B830A7A42A4B62F3D42295E1 /* Release */ = { + F1C6CE5C4EF9F2A54B7DE5AD8557FBDD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 214924C9F0E2FAC0CB4EAEEAC304F1BB /* Pods-Zoomy_Tests.release.xcconfig */; + baseConfigurationReference = 10C285230E7CFFE2A19F1963D1321A46 /* PINOperation.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; - CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -3962,19 +3958,18 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/PINOperation/PINOperation-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PINOperation/PINOperation-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + MODULEMAP_FILE = "Target Support Files/PINOperation/PINOperation.modulemap"; + PRODUCT_MODULE_NAME = PINOperation; + PRODUCT_NAME = PINOperation; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -3985,83 +3980,83 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 1FE65759E70A2FBB5A21F3DD0CD398F2 /* Build configuration list for PBXNativeTarget "InjectableLoggers" */ = { + 1000880B548699E9BBD74146AFFA3702 /* Build configuration list for PBXNativeTarget "PINRemoteImage" */ = { isa = XCConfigurationList; buildConfigurations = ( - 07BF91B0C54FE800B7CB61C7CDB0DCB3 /* Debug */, - 8D04478F3E00A59AA36CEA6481E86C58 /* Release */, + DB690DEAD73E16646E201820007C72B5 /* Debug */, + 968242DC1FD972197D42C524394DB10A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 26527969D7620C46861F1AE4C5A176C0 /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Tests" */ = { + 1FE65759E70A2FBB5A21F3DD0CD398F2 /* Build configuration list for PBXNativeTarget "InjectableLoggers" */ = { isa = XCConfigurationList; buildConfigurations = ( - C7D74F1435586754B8FF8DC620EF5FA8 /* Debug */, - F561FB73B830A7A42A4B62F3D42295E1 /* Release */, + A89B5D55AEAB47765DFDDE3ADE997875 /* Debug */, + 0FCC6FA7F8AE5C68E7F6B25525A49B86 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3CE812C41CAFAAF986137CD5A0B90AA1 /* Build configuration list for PBXNativeTarget "Texture" */ = { + 220373192DD9B5A8CE5F6300464F4ACD /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 9DEB8B318286B13C49EC7B05D4D156E3 /* Debug */, - 952162EB478A085F5CA2038AA6945647 /* Release */, + C12D2C4025C7B2E7BC2712EA9068F63A /* Debug */, + D8DC229F44BBD09EE35917CCFC51CF65 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + 23AE78DFA121AB90D635A8DD7955706E /* Build configuration list for PBXNativeTarget "Zoomy" */ = { isa = XCConfigurationList; buildConfigurations = ( - DD8F832993327D1DD8046C3CBCBD97CD /* Debug */, - 257497152829C177993B5EC99C1D227A /* Release */, + C89C168FE41FA83B79121C31C534FBA4 /* Debug */, + A030C28A40E3EF2BAF84436068970B42 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5072AA0772B5784FDC4E8E7E8192A2AB /* Build configuration list for PBXNativeTarget "PINOperation" */ = { + 4465A8BC1A4EAD0A929F46F30EBB7871 /* Build configuration list for PBXNativeTarget "PINOperation" */ = { isa = XCConfigurationList; buildConfigurations = ( - 714F3E19A3D0BE1B693B6C04D32DAA6A /* Debug */, - 4C860EC22E3E90D1BD49D8F6B499D945 /* Release */, + 8BFE928F924913D9BE960B9173284ACB /* Debug */, + F1C6CE5C4EF9F2A54B7DE5AD8557FBDD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 50C1C31106C3D6E71D542BE402B4F57E /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Example" */ = { + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - F06082FC310E02FE82E19C5E4E259A0D /* Debug */, - AF2709D513F7F1228222FC7A6AE5379E /* Release */, + 2B9E26EAE2CD392AD762421F663075A1 /* Debug */, + 63FAF33E1C55B71A5F5A8B3CC8749F99 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 64006B59F15E5C0ADB022E0DF7ABDFA7 /* Build configuration list for PBXNativeTarget "Zoomy" */ = { + 781EA42DAB0BE3F655A4986FC97589BB /* Build configuration list for PBXNativeTarget "Pods-Zoomy_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( - D2D4EF8EB09CEA6C337A9967DB53A7DA /* Debug */, - 33603934652B731CD2AED69E205664D1 /* Release */, + D745690DA83EC92B79B247CA9828D34B /* Debug */, + EDCF68F9D667AB944A92281B884FE29E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 80A4215346E29D0F80A19EFE25FA421A /* Build configuration list for PBXNativeTarget "PINCache" */ = { + 78DCB2C5EC3B5BA90EEB95A1ACFFDF0E /* Build configuration list for PBXNativeTarget "Texture" */ = { isa = XCConfigurationList; buildConfigurations = ( - 702665F7E4F51F7122D92DC34288D2A5 /* Debug */, - F0340C119AA7E9D4E910EA3C4F4A8F5A /* Release */, + 0505567233D733C12497302290D37B67 /* Debug */, + B2503807C55928A0B5791D707F9FE9B5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - A1BBBFD4F6BA65DFB93D9A73935567BC /* Build configuration list for PBXNativeTarget "PINRemoteImage" */ = { + B794DF6469B3D94E9347E82D67AFAF6E /* Build configuration list for PBXNativeTarget "PINCache" */ = { isa = XCConfigurationList; buildConfigurations = ( - 1914CA58AACC7ABB5C506974505D3462 /* Debug */, - 50A878715B640D8DCC73F268EA7E1090 /* Release */, + 35C965BA81A9ABB07AD8B4134DC9A297 /* Debug */, + 7886032428261A19CC71D50A73412346 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers-Info.plist b/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers-Info.plist index 0a12077..92aaf05 100644 --- a/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers-Info.plist +++ b/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.0 + 2.1.1 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers.debug.xcconfig b/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers.debug.xcconfig new file mode 100644 index 0000000..519f1ee --- /dev/null +++ b/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/InjectableLoggers +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers.release.xcconfig b/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers.release.xcconfig new file mode 100644 index 0000000..519f1ee --- /dev/null +++ b/Example/Pods/Target Support Files/InjectableLoggers/InjectableLoggers.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/InjectableLoggers +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/PINCache/PINCache-Info.plist b/Example/Pods/Target Support Files/PINCache/PINCache-Info.plist index b0b461e..b3ee339 100644 --- a/Example/Pods/Target Support Files/PINCache/PINCache-Info.plist +++ b/Example/Pods/Target Support Files/PINCache/PINCache-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.0.1 + 3.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/PINCache/PINCache.debug.xcconfig b/Example/Pods/Target Support Files/PINCache/PINCache.debug.xcconfig new file mode 100644 index 0000000..2aa8e20 --- /dev/null +++ b/Example/Pods/Target Support Files/PINCache/PINCache.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINCache +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -weak_framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PINCache +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/PINCache/PINCache.release.xcconfig b/Example/Pods/Target Support Files/PINCache/PINCache.release.xcconfig new file mode 100644 index 0000000..2aa8e20 --- /dev/null +++ b/Example/Pods/Target Support Files/PINCache/PINCache.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINCache +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -weak_framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PINCache +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/PINOperation/PINOperation-Info.plist b/Example/Pods/Target Support Files/PINOperation/PINOperation-Info.plist index 7ea8235..19f73ea 100644 --- a/Example/Pods/Target Support Files/PINOperation/PINOperation-Info.plist +++ b/Example/Pods/Target Support Files/PINOperation/PINOperation-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.1.2 + 1.2.1 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/PINOperation/PINOperation.debug.xcconfig b/Example/Pods/Target Support Files/PINOperation/PINOperation.debug.xcconfig new file mode 100644 index 0000000..53d7629 --- /dev/null +++ b/Example/Pods/Target Support Files/PINOperation/PINOperation.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINOperation +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PINOperation +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/PINOperation/PINOperation.release.xcconfig b/Example/Pods/Target Support Files/PINOperation/PINOperation.release.xcconfig new file mode 100644 index 0000000..53d7629 --- /dev/null +++ b/Example/Pods/Target Support Files/PINOperation/PINOperation.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINOperation +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PINOperation +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist index 4522675..b3ee339 100644 --- a/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist +++ b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.0.0 + 3.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-umbrella.h b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-umbrella.h index 728d85d..9fd0f73 100644 --- a/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-umbrella.h +++ b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage-umbrella.h @@ -10,40 +10,44 @@ #endif #endif -#import "PINAnimatedImage.h" -#import "PINCachedAnimatedImage.h" -#import "PINGIFAnimatedImage.h" -#import "PINMemMapAnimatedImage.h" -#import "PINWebPAnimatedImage.h" -#import "NSData+ImageDetectors.h" +#import "NSHTTPURLResponse+MaxAge.h" #import "PINImage+DecodedImage.h" #import "PINImage+ScaledImage.h" #import "PINImage+WebP.h" #import "PINRemoteImageTask+Subclassing.h" +#import "NSData+ImageDetectors.h" +#import "PINAlternateRepresentationProvider.h" +#import "PINAnimatedImage.h" +#import "PINAnimatedImageView+PINRemoteImage.h" +#import "PINAnimatedImageView.h" #import "PINButton+PINRemoteImage.h" +#import "PINCachedAnimatedImage.h" +#import "PINGIFAnimatedImage.h" #import "PINImageView+PINRemoteImage.h" -#import "PINAlternateRepresentationProvider.h" -#import "PINGIFAnimatedImageManager.h" #import "PINProgressiveImage.h" #import "PINRemoteImage.h" -#import "PINRemoteImageBasicCache.h" #import "PINRemoteImageCaching.h" -#import "PINRemoteImageCallbacks.h" #import "PINRemoteImageCategoryManager.h" -#import "PINRemoteImageDownloadQueue.h" -#import "PINRemoteImageDownloadTask.h" #import "PINRemoteImageMacros.h" -#import "PINRemoteImageManager+Private.h" #import "PINRemoteImageManager.h" #import "PINRemoteImageManagerResult.h" +#import "PINRequestRetryStrategy.h" +#import "PINURLSessionManager.h" +#import "PINWebPAnimatedImage.h" +#import "PINDisplayLink.h" +#import "PINRemoteImageBasicCache.h" +#import "PINRemoteImageCallbacks.h" +#import "PINRemoteImageDownloadQueue.h" +#import "PINRemoteImageDownloadTask.h" +#import "PINRemoteImageManager+Private.h" +#import "PINRemoteImageManagerConfiguration.h" #import "PINRemoteImageMemoryContainer.h" #import "PINRemoteImageProcessorTask.h" #import "PINRemoteImageTask.h" #import "PINRemoteLock.h" -#import "PINRequestRetryStrategy.h" +#import "PINRemoteWeakProxy.h" #import "PINResume.h" #import "PINSpeedRecorder.h" -#import "PINURLSessionManager.h" #import "PINCache+PINRemoteImageCaching.h" FOUNDATION_EXPORT double PINRemoteImageVersionNumber; diff --git a/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage.debug.xcconfig b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage.debug.xcconfig new file mode 100644 index 0000000..2014576 --- /dev/null +++ b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "ImageIO" -framework "UIKit" -weak_framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PINRemoteImage +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage.release.xcconfig b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage.release.xcconfig new file mode 100644 index 0000000..2014576 --- /dev/null +++ b/Example/Pods/Target Support Files/PINRemoteImage/PINRemoteImage.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "ImageIO" -framework "UIKit" -weak_framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PINRemoteImage +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example-frameworks.sh b/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example-frameworks.sh index 9a7aeb2..67dcdbf 100755 --- a/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example-frameworks.sh +++ b/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example-frameworks.sh @@ -19,9 +19,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" -# Used as a return value for each invocation of `strip_invalid_archs` function. -STRIP_BINARY_RETVAL=0 # This protects against multiple targets copying the same framework dependency at the same time. The solution # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html @@ -45,9 +44,19 @@ install_framework() source="$(readlink "${source}")" fi + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + # Use filter instead of exclude so missing patterns don't throw errors. - echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" - rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" @@ -80,69 +89,52 @@ install_framework() done fi } - # Copies and strips a vendored dSYM install_dsym() { local source="$1" + warn_missing_arch=${2:-true} if [ -r "$source" ]; then - # Copy the dSYM into a the targets temp dir. + # Copy the dSYM into the targets temp dir. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" local basename - basename="$(basename -s .framework.dSYM "$source")" - binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" - # Strip invalid architectures so "fat" simulator / device frameworks work on device + # Strip invalid architectures from the dSYM. if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then - strip_invalid_archs "$binary" + strip_invalid_archs "$binary" "$warn_missing_arch" fi - - if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then # Move the stripped file into its final destination. - echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" - rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" else # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. - touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" fi fi } -# Copies the bcsymbolmap files of a vendored framework -install_bcsymbolmap() { - local bcsymbolmap_path="$1" - local destination="${BUILT_PRODUCTS_DIR}" - echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" - rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" -} - -# Signs a framework with the provided identity -code_sign_if_enabled() { - if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then - # Use the current code_sign_identity - echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" - local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" - - if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then - code_sign_cmd="$code_sign_cmd &" - fi - echo "$code_sign_cmd" - eval "$code_sign_cmd" - fi -} +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 # Strip invalid architectures strip_invalid_archs() { binary="$1" + warn_missing_arch=${2:-true} # Get architectures for current target binary binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" # Intersect them with the architectures we are building for intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" # If there are no archs supported by this binary then warn the user if [[ -z "$intersected_archs" ]]; then - echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." - STRIP_BINARY_RETVAL=0 + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 return fi stripped="" @@ -156,9 +148,31 @@ strip_invalid_archs() { if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi - STRIP_BINARY_RETVAL=1 + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" } +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/InjectableLoggers/InjectableLoggers.framework" diff --git a/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.debug.xcconfig b/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.debug.xcconfig index 9b1638e..d4797c7 100644 --- a/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.debug.xcconfig +++ b/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.debug.xcconfig @@ -1,4 +1,5 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage" "${PODS_CONFIGURATION_BUILD_DIR}/Texture" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) AS_USE_ASSETS_LIBRARY=1 $(inherited) AS_USE_MAPKIT=1 $(inherited) AS_USE_PHOTOS=1 $(inherited) AS_USE_VIDEO=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers/InjectableLoggers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache/PINCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation/PINOperation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage/PINRemoteImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Texture/AsyncDisplayKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy/Zoomy.framework/Headers" @@ -9,3 +10,5 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.release.xcconfig b/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.release.xcconfig index 9b1638e..d4797c7 100644 --- a/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.release.xcconfig +++ b/Example/Pods/Target Support Files/Pods-Zoomy_Example/Pods-Zoomy_Example.release.xcconfig @@ -1,4 +1,5 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage" "${PODS_CONFIGURATION_BUILD_DIR}/Texture" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) AS_USE_ASSETS_LIBRARY=1 $(inherited) AS_USE_MAPKIT=1 $(inherited) AS_USE_PHOTOS=1 $(inherited) AS_USE_VIDEO=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers/InjectableLoggers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache/PINCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation/PINOperation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage/PINRemoteImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Texture/AsyncDisplayKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy/Zoomy.framework/Headers" @@ -9,3 +10,5 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-frameworks.sh b/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-frameworks.sh index 6855434..799fa29 100755 --- a/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-frameworks.sh +++ b/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests-frameworks.sh @@ -19,9 +19,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" -# Used as a return value for each invocation of `strip_invalid_archs` function. -STRIP_BINARY_RETVAL=0 # This protects against multiple targets copying the same framework dependency at the same time. The solution # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html @@ -45,9 +44,19 @@ install_framework() source="$(readlink "${source}")" fi + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + # Use filter instead of exclude so missing patterns don't throw errors. - echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" - rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" @@ -80,69 +89,52 @@ install_framework() done fi } - # Copies and strips a vendored dSYM install_dsym() { local source="$1" + warn_missing_arch=${2:-true} if [ -r "$source" ]; then - # Copy the dSYM into a the targets temp dir. + # Copy the dSYM into the targets temp dir. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" local basename - basename="$(basename -s .framework.dSYM "$source")" - binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" - # Strip invalid architectures so "fat" simulator / device frameworks work on device + # Strip invalid architectures from the dSYM. if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then - strip_invalid_archs "$binary" + strip_invalid_archs "$binary" "$warn_missing_arch" fi - - if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then # Move the stripped file into its final destination. - echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" - rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" else # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. - touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" fi fi } -# Copies the bcsymbolmap files of a vendored framework -install_bcsymbolmap() { - local bcsymbolmap_path="$1" - local destination="${BUILT_PRODUCTS_DIR}" - echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" - rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" -} - -# Signs a framework with the provided identity -code_sign_if_enabled() { - if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then - # Use the current code_sign_identity - echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" - local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" - - if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then - code_sign_cmd="$code_sign_cmd &" - fi - echo "$code_sign_cmd" - eval "$code_sign_cmd" - fi -} +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 # Strip invalid architectures strip_invalid_archs() { binary="$1" + warn_missing_arch=${2:-true} # Get architectures for current target binary binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" # Intersect them with the architectures we are building for intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" # If there are no archs supported by this binary then warn the user if [[ -z "$intersected_archs" ]]; then - echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." - STRIP_BINARY_RETVAL=0 + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 return fi stripped="" @@ -156,9 +148,31 @@ strip_invalid_archs() { if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi - STRIP_BINARY_RETVAL=1 + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" } +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/InjectableLoggers/InjectableLoggers.framework" diff --git a/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.debug.xcconfig b/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.debug.xcconfig index 9b1638e..d4797c7 100644 --- a/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.debug.xcconfig +++ b/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.debug.xcconfig @@ -1,4 +1,5 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage" "${PODS_CONFIGURATION_BUILD_DIR}/Texture" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) AS_USE_ASSETS_LIBRARY=1 $(inherited) AS_USE_MAPKIT=1 $(inherited) AS_USE_PHOTOS=1 $(inherited) AS_USE_VIDEO=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers/InjectableLoggers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache/PINCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation/PINOperation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage/PINRemoteImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Texture/AsyncDisplayKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy/Zoomy.framework/Headers" @@ -9,3 +10,5 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.release.xcconfig b/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.release.xcconfig index 9b1638e..d4797c7 100644 --- a/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.release.xcconfig +++ b/Example/Pods/Target Support Files/Pods-Zoomy_Tests/Pods-Zoomy_Tests.release.xcconfig @@ -1,4 +1,5 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage" "${PODS_CONFIGURATION_BUILD_DIR}/Texture" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) AS_USE_ASSETS_LIBRARY=1 $(inherited) AS_USE_MAPKIT=1 $(inherited) AS_USE_PHOTOS=1 $(inherited) AS_USE_VIDEO=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers/InjectableLoggers.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINCache/PINCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation/PINOperation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage/PINRemoteImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Texture/AsyncDisplayKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Zoomy/Zoomy.framework/Headers" @@ -9,3 +10,5 @@ PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Texture/Texture-Info.plist b/Example/Pods/Target Support Files/Texture/Texture-Info.plist index 9e07126..4522675 100644 --- a/Example/Pods/Target Support Files/Texture/Texture-Info.plist +++ b/Example/Pods/Target Support Files/Texture/Texture-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.8.1 + 3.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/Texture/Texture-umbrella.h b/Example/Pods/Target Support Files/Texture/Texture-umbrella.h index 98d3c03..1cbbed0 100644 --- a/Example/Pods/Target Support Files/Texture/Texture-umbrella.h +++ b/Example/Pods/Target Support Files/Texture/Texture-umbrella.h @@ -11,9 +11,10 @@ #endif #import "ASBlockTypes.h" +#import "ASButtonNode+Private.h" +#import "ASButtonNode+Yoga.h" #import "ASButtonNode.h" #import "ASCellNode.h" -#import "ASCGImageBuffer.h" #import "ASCollectionNode+Beta.h" #import "ASCollectionNode.h" #import "ASCollections.h" @@ -34,6 +35,7 @@ #import "ASDisplayNode+Yoga.h" #import "ASDisplayNode.h" #import "ASDisplayNodeExtras.h" +#import "ASDKViewController.h" #import "ASEditableTextNode.h" #import "ASExperimentalFeatures.h" #import "ASImageNode.h" @@ -65,7 +67,6 @@ #import "ASTextNodeCommon.h" #import "ASVideoNode.h" #import "ASVideoPlayerNode.h" -#import "ASViewController.h" #import "ASVisibilityProtocols.h" #import "AsyncDisplayKit+IGListKitMethods.h" #import "AsyncDisplayKit.h" @@ -89,7 +90,6 @@ #import "ASDataController.h" #import "ASDelegateProxy.h" #import "ASElementMap.h" -#import "ASEventLog.h" #import "ASGraphicsContext.h" #import "ASHashing.h" #import "ASHighlightOverlayLayer.h" @@ -111,7 +111,6 @@ #import "ASSectionContext.h" #import "ASTableLayoutController.h" #import "ASThread.h" -#import "ASTraceEvent.h" #import "ASTraitCollection.h" #import "ASWeakProxy.h" #import "ASWeakSet.h" @@ -139,7 +138,7 @@ #import "ASDimension.h" #import "ASDimensionInternal.h" #import "ASInsetLayoutSpec.h" -#import "ASLayout+IGListKit.h" +#import "ASLayout+IGListDiffKit.h" #import "ASLayout.h" #import "ASLayoutElement.h" #import "ASLayoutElementExtensibility.h" diff --git a/Example/Pods/Target Support Files/Texture/Texture.debug.xcconfig b/Example/Pods/Target Support Files/Texture/Texture.debug.xcconfig new file mode 100644 index 0000000..c68536c --- /dev/null +++ b/Example/Pods/Target Support Files/Texture/Texture.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_CXX_LANGUAGE_STANDARD = c++11 +CLANG_CXX_LIBRARY = libc++ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Texture +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) AS_USE_ASSETS_LIBRARY=1 $(inherited) AS_USE_MAPKIT=1 $(inherited) AS_USE_PHOTOS=1 $(inherited) AS_USE_VIDEO=1 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "AVFoundation" -framework "AssetsLibrary" -framework "CoreLocation" -framework "CoreMedia" -framework "MapKit" -framework "Photos" -weak_framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Texture +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Texture/Texture.release.xcconfig b/Example/Pods/Target Support Files/Texture/Texture.release.xcconfig new file mode 100644 index 0000000..c68536c --- /dev/null +++ b/Example/Pods/Target Support Files/Texture/Texture.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_CXX_LANGUAGE_STANDARD = c++11 +CLANG_CXX_LIBRARY = libc++ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Texture +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINCache" "${PODS_CONFIGURATION_BUILD_DIR}/PINOperation" "${PODS_CONFIGURATION_BUILD_DIR}/PINRemoteImage" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) AS_USE_ASSETS_LIBRARY=1 $(inherited) AS_USE_MAPKIT=1 $(inherited) AS_USE_PHOTOS=1 $(inherited) AS_USE_VIDEO=1 +OTHER_LDFLAGS = $(inherited) -l"c++" -framework "AVFoundation" -framework "AssetsLibrary" -framework "CoreLocation" -framework "CoreMedia" -framework "MapKit" -framework "Photos" -weak_framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Texture +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Zoomy/Zoomy.debug.xcconfig b/Example/Pods/Target Support Files/Zoomy/Zoomy.debug.xcconfig new file mode 100644 index 0000000..bf3fdf3 --- /dev/null +++ b/Example/Pods/Target Support Files/Zoomy/Zoomy.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Zoomy +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Target Support Files/Zoomy/Zoomy.release.xcconfig b/Example/Pods/Target Support Files/Zoomy/Zoomy.release.xcconfig new file mode 100644 index 0000000..bf3fdf3 --- /dev/null +++ b/Example/Pods/Target Support Files/Zoomy/Zoomy.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Zoomy +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/InjectableLoggers" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Example/Pods/Texture/README.md b/Example/Pods/Texture/README.md index 4b939fa..57e0c54 100644 --- a/Example/Pods/Texture/README.md +++ b/Example/Pods/Texture/README.md @@ -40,7 +40,7 @@ We use Slack for real-time debugging, community updates, and general talk about ## Release process -For the release process see the [RELEASE] (https://github.com/texturegroup/texture/blob/master/RELEASE.md) file. +For the release process see the [RELEASE](https://github.com/texturegroup/texture/blob/master/RELEASE.md) file. ## Contributing diff --git a/Example/Pods/Texture/Source/ASButtonNode+Private.h b/Example/Pods/Texture/Source/ASButtonNode+Private.h new file mode 100644 index 0000000..22ca4eb --- /dev/null +++ b/Example/Pods/Texture/Source/ASButtonNode+Private.h @@ -0,0 +1,45 @@ +// +// ASButtonNode+Private.h +// Texture +// +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 +// + +#import +#import +#import +#import + +@interface ASButtonNode () { + NSAttributedString *_normalAttributedTitle; + NSAttributedString *_highlightedAttributedTitle; + NSAttributedString *_selectedAttributedTitle; + NSAttributedString *_selectedHighlightedAttributedTitle; + NSAttributedString *_disabledAttributedTitle; + + UIImage *_normalImage; + UIImage *_highlightedImage; + UIImage *_selectedImage; + UIImage *_selectedHighlightedImage; + UIImage *_disabledImage; + + UIImage *_normalBackgroundImage; + UIImage *_highlightedBackgroundImage; + UIImage *_selectedBackgroundImage; + UIImage *_selectedHighlightedBackgroundImage; + UIImage *_disabledBackgroundImage; + + CGFloat _contentSpacing; + UIEdgeInsets _contentEdgeInsets; + ASTextNode *_titleNode; + ASImageNode *_imageNode; + ASImageNode *_backgroundImageNode; + + BOOL _laysOutHorizontally; + ASVerticalAlignment _contentVerticalAlignment; + ASHorizontalAlignment _contentHorizontalAlignment; + ASButtonNodeImageAlignment _imageAlignment; +} + +@end diff --git a/Example/Pods/Texture/Source/ASButtonNode+Yoga.h b/Example/Pods/Texture/Source/ASButtonNode+Yoga.h new file mode 100644 index 0000000..4fddc9d --- /dev/null +++ b/Example/Pods/Texture/Source/ASButtonNode+Yoga.h @@ -0,0 +1,20 @@ +// +// ASButtonNode+Yoga.h +// Texture +// +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ASButtonNode (Yoga) + +- (void)updateYogaLayoutIfNeeded; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASButtonNode+Yoga.mm b/Example/Pods/Texture/Source/ASButtonNode+Yoga.mm new file mode 100644 index 0000000..f4493bc --- /dev/null +++ b/Example/Pods/Texture/Source/ASButtonNode+Yoga.mm @@ -0,0 +1,105 @@ +// +// ASButtonNode+Yoga.mm +// Texture +// +// Copyright (c) Pinterest, Inc. All rights reserved. +// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 +// + +#import +#import "ASButtonNode+Yoga.h" +#import +#import +#import + +#if YOGA +static void ASButtonNodeResolveHorizontalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASHorizontalAlignment _horizontalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { + if (_direction == ASStackLayoutDirectionHorizontal) { + style.justifyContent = justifyContent(_horizontalAlignment, _justifyContent); + } else { + style.alignItems = alignment(_horizontalAlignment, _alignItems); + } +} + +static void ASButtonNodeResolveVerticalAlignmentForStyle(ASLayoutElementStyle *style, ASStackLayoutDirection _direction, ASVerticalAlignment _verticalAlignment, ASStackLayoutJustifyContent _justifyContent, ASStackLayoutAlignItems _alignItems) { + if (_direction == ASStackLayoutDirectionHorizontal) { + style.alignItems = alignment(_verticalAlignment, _alignItems); + } else { + style.justifyContent = justifyContent(_verticalAlignment, _justifyContent); + } +} + +@implementation ASButtonNode (Yoga) + +- (void)updateYogaLayoutIfNeeded +{ + NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; + { + ASLockScopeSelf(); + + // Build up yoga children for button node again + unowned ASLayoutElementStyle *style = [self _locked_style]; + [style yogaNodeCreateIfNeeded]; + + // Setup stack layout values + style.flexDirection = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; + + // Resolve horizontal and vertical alignment + ASButtonNodeResolveHorizontalAlignmentForStyle(style, style.flexDirection, _contentHorizontalAlignment, style.justifyContent, style.alignItems); + ASButtonNodeResolveVerticalAlignmentForStyle(style, style.flexDirection, _contentVerticalAlignment, style.justifyContent, style.alignItems); + + // Setup new yoga children + if (_imageNode.image != nil) { + [_imageNode.style yogaNodeCreateIfNeeded]; + [children addObject:_imageNode]; + } + + if (_titleNode.attributedText.length > 0) { + [_titleNode.style yogaNodeCreateIfNeeded]; + if (_imageAlignment == ASButtonNodeImageAlignmentBeginning) { + [children addObject:_titleNode]; + } else { + [children insertObject:_titleNode atIndex:0]; + } + } + + // Add spacing between title and button + if (children.count == 2) { + unowned ASLayoutElementStyle *firstChildStyle = children.firstObject.style; + if (_laysOutHorizontally) { + firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, 0, _contentSpacing)); + } else { + firstChildStyle.margin = ASEdgeInsetsMake(UIEdgeInsetsMake(0, 0, _contentSpacing, 0)); + } + } + + // Add padding to button + if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, _contentEdgeInsets) == NO) { + style.padding = ASEdgeInsetsMake(_contentEdgeInsets); + } + + // Add background node + if (_backgroundImageNode.image) { + [_backgroundImageNode.style yogaNodeCreateIfNeeded]; + [children insertObject:_backgroundImageNode atIndex:0]; + + _backgroundImageNode.style.positionType = YGPositionTypeAbsolute; + _backgroundImageNode.style.position = ASEdgeInsetsMake(UIEdgeInsetsZero); + } + } + + // Update new children + [self setYogaChildren:children]; +} + +@end + +#else + +@implementation ASButtonNode (Yoga) + +- (void)updateYogaLayoutIfNeeded {} + +@end + +#endif diff --git a/Example/Pods/Texture/Source/ASButtonNode.h b/Example/Pods/Texture/Source/ASButtonNode.h index f43a544..3963fb1 100644 --- a/Example/Pods/Texture/Source/ASButtonNode.h +++ b/Example/Pods/Texture/Source/ASButtonNode.h @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN /** Image alignment defines where the image will be placed relative to the text. */ -typedef NS_ENUM(NSInteger, ASButtonNodeImageAlignment) { +typedef NS_ENUM(unsigned char, ASButtonNodeImageAlignment) { /** Places the image before the text. */ ASButtonNodeImageAlignmentBeginning, /** Places the image after the text. */ diff --git a/Example/Pods/Texture/Source/ASButtonNode.mm b/Example/Pods/Texture/Source/ASButtonNode.mm index 5ec1f23..66b9cd3 100644 --- a/Example/Pods/Texture/Source/ASButtonNode.mm +++ b/Example/Pods/Texture/Source/ASButtonNode.mm @@ -7,39 +7,13 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import +#import #import #import #import #import #import -#import -#import -#import -#import - -@interface ASButtonNode () -{ - NSAttributedString *_normalAttributedTitle; - NSAttributedString *_highlightedAttributedTitle; - NSAttributedString *_selectedAttributedTitle; - NSAttributedString *_selectedHighlightedAttributedTitle; - NSAttributedString *_disabledAttributedTitle; - - UIImage *_normalImage; - UIImage *_highlightedImage; - UIImage *_selectedImage; - UIImage *_selectedHighlightedImage; - UIImage *_disabledImage; - - UIImage *_normalBackgroundImage; - UIImage *_highlightedBackgroundImage; - UIImage *_selectedBackgroundImage; - UIImage *_selectedHighlightedBackgroundImage; - UIImage *_disabledBackgroundImage; -} - -@end @implementation ASButtonNode @@ -53,6 +27,8 @@ @implementation ASButtonNode @synthesize imageNode = _imageNode; @synthesize backgroundImageNode = _backgroundImageNode; +#pragma mark - Lifecycle + - (instancetype)init { if (self = [super init]) { @@ -65,6 +41,8 @@ - (instancetype)init _contentEdgeInsets = UIEdgeInsetsZero; _imageAlignment = ASButtonNodeImageAlignmentBeginning; self.accessibilityTraits = self.defaultAccessibilityTraits; + + [self updateYogaLayoutIfNeeded]; } return self; } @@ -74,16 +52,21 @@ - (ASTextNode *)titleNode ASLockScopeSelf(); if (!_titleNode) { _titleNode = [[ASTextNode alloc] init]; -#if TARGET_OS_IOS + #if TARGET_OS_TV // tvOS needs access to the underlying view // of the button node to add a touch handler. - [_titleNode setLayerBacked:YES]; -#endif + [_titleNode setLayerBacked:NO]; + #else + [_titleNode setLayerBacked:YES]; + #endif _titleNode.style.flexShrink = 1.0; + _titleNode.textColorFollowsTintColor = YES; } return _titleNode; } +#pragma mark - Public Getter + - (ASImageNode *)imageNode { ASLockScopeSelf(); @@ -151,6 +134,20 @@ - (void)setDisplaysAsynchronously:(BOOL)displaysAsynchronously [self.titleNode setDisplaysAsynchronously:displaysAsynchronously]; } +-(void)tintColorDidChange +{ + [super tintColorDidChange]; + // UIButton documentation states that it tints the image and title of buttons when tintColor is set. + // | "The tint color to apply to the button title and image." + // | From: https://developer.apple.com/documentation/uikit/uibutton/1624025-tintcolor + [self lock]; + UIColor *tintColor = self.tintColor; + self.imageNode.tintColor = tintColor; + self.titleNode.tintColor = tintColor; + [self unlock]; + [self setNeedsDisplay]; +} + - (void)updateImage { [self lock]; @@ -172,6 +169,7 @@ - (void)updateImage _imageNode.image = newImage; [self unlock]; + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; return; } @@ -196,12 +194,14 @@ - (void)updateTitle newTitle = _normalAttributedTitle; } - // Calling self.titleNode is essential here because _titleNode is lazily created by the getter. - if ((_titleNode != nil || newTitle.length > 0) && [self.titleNode.attributedText isEqualToAttributedString:newTitle] == NO) { - _titleNode.attributedText = newTitle; + NSAttributedString *attributedString = _titleNode.attributedText; + if ((attributedString.length > 0 || newTitle.length > 0) && [attributedString isEqualToAttributedString:newTitle] == NO) { + // Calling self.titleNode is essential here because _titleNode is lazily created by the getter. + self.titleNode.attributedText = newTitle; [self unlock]; self.accessibilityLabel = self.defaultAccessibilityLabel; + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; return; } @@ -229,7 +229,8 @@ - (void)updateBackgroundImage if ((_backgroundImageNode != nil || newImage != nil) && newImage != self.backgroundImageNode.image) { _backgroundImageNode.image = newImage; [self unlock]; - + + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; return; } @@ -246,6 +247,7 @@ - (CGFloat)contentSpacing - (void)setContentSpacing:(CGFloat)contentSpacing { if (ASLockedSelfCompareAssign(_contentSpacing, contentSpacing)) { + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; } } @@ -259,6 +261,7 @@ - (BOOL)laysOutHorizontally - (void)setLaysOutHorizontally:(BOOL)laysOutHorizontally { if (ASLockedSelfCompareAssign(_laysOutHorizontally, laysOutHorizontally)) { + [self updateYogaLayoutIfNeeded]; [self setNeedsLayout]; } } @@ -315,12 +318,14 @@ - (void)setImageAlignment:(ASButtonNodeImageAlignment)imageAlignment #if TARGET_OS_IOS - (void)setTitle:(NSString *)title withFont:(UIFont *)font withColor:(UIColor *)color forState:(UIControlState)state { - NSDictionary *attributes = @{ - NSFontAttributeName: font ? : [UIFont systemFontOfSize:[UIFont buttonFontSize]], - NSForegroundColorAttributeName : color ? : [UIColor blackColor] - }; - - NSAttributedString *string = [[NSAttributedString alloc] initWithString:title attributes:attributes]; + NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; + attributes[NSFontAttributeName] = font ? : [UIFont systemFontOfSize:[UIFont buttonFontSize]]; + if (color != nil) { + // From apple's documentation: If color is not specified, NSForegroundColorAttributeName will fallback to black + // Only set if the color is nonnull + attributes[NSForegroundColorAttributeName] = color; + } + NSAttributedString *string = [[NSAttributedString alloc] initWithString:title attributes:[attributes copy]]; [self setAttributedTitle:string forState:state]; } #endif @@ -496,50 +501,6 @@ - (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state [self updateBackgroundImage]; } -- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize -{ - UIEdgeInsets contentEdgeInsets; - ASButtonNodeImageAlignment imageAlignment; - ASLayoutSpec *spec; - ASStackLayoutSpec *stack = [[ASStackLayoutSpec alloc] init]; - { - ASLockScopeSelf(); - stack.direction = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; - stack.spacing = _contentSpacing; - stack.horizontalAlignment = _contentHorizontalAlignment; - stack.verticalAlignment = _contentVerticalAlignment; - - contentEdgeInsets = _contentEdgeInsets; - imageAlignment = _imageAlignment; - } - - NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; - if (_imageNode.image) { - [children addObject:_imageNode]; - } - - if (_titleNode.attributedText.length > 0) { - if (imageAlignment == ASButtonNodeImageAlignmentBeginning) { - [children addObject:_titleNode]; - } else { - [children insertObject:_titleNode atIndex:0]; - } - } - - stack.children = children; - - spec = stack; - - if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, contentEdgeInsets) == NO) { - spec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:contentEdgeInsets child:spec]; - } - - if (_backgroundImageNode.image) { - spec = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:spec background:_backgroundImageNode]; - } - - return spec; -} - (NSString *)defaultAccessibilityLabel { @@ -553,6 +514,55 @@ - (UIAccessibilityTraits)defaultAccessibilityTraits : (UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled); } +#pragma mark - Layout + +#if !YOGA +- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize +{ + UIEdgeInsets contentEdgeInsets; + ASButtonNodeImageAlignment imageAlignment; + ASLayoutSpec *spec; + ASStackLayoutSpec *stack = [[ASStackLayoutSpec alloc] init]; + { + ASLockScopeSelf(); + stack.direction = _laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical; + stack.spacing = _contentSpacing; + stack.horizontalAlignment = _contentHorizontalAlignment; + stack.verticalAlignment = _contentVerticalAlignment; + + contentEdgeInsets = _contentEdgeInsets; + imageAlignment = _imageAlignment; + } + + NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2]; + if (_imageNode.image) { + [children addObject:_imageNode]; + } + + if (_titleNode.attributedText.length > 0) { + if (imageAlignment == ASButtonNodeImageAlignmentBeginning) { + [children addObject:_titleNode]; + } else { + [children insertObject:_titleNode atIndex:0]; + } + } + + stack.children = children; + + spec = stack; + + if (UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, contentEdgeInsets) == NO) { + spec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:contentEdgeInsets child:spec]; + } + + if (_backgroundImageNode.image) { + spec = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:spec background:_backgroundImageNode]; + } + + return spec; +} +#endif + - (void)layout { [super layout]; diff --git a/Example/Pods/Texture/Source/ASCGImageBuffer.h b/Example/Pods/Texture/Source/ASCGImageBuffer.h deleted file mode 100644 index a774526..0000000 --- a/Example/Pods/Texture/Source/ASCGImageBuffer.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// ASCGImageBuffer.h -// Texture -// -// Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -// - -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -AS_SUBCLASSING_RESTRICTED -@interface ASCGImageBuffer : NSObject - -/// Init a zero-filled buffer with the given length. -- (instancetype)initWithLength:(NSUInteger)length; - -@property (readonly) void *mutableBytes NS_RETURNS_INNER_POINTER; - -/// Don't do any drawing or call any methods after calling this. -- (CGDataProviderRef)createDataProviderAndInvalidate CF_RETURNS_RETAINED; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASCGImageBuffer.mm b/Example/Pods/Texture/Source/ASCGImageBuffer.mm deleted file mode 100644 index 6f05300..0000000 --- a/Example/Pods/Texture/Source/ASCGImageBuffer.mm +++ /dev/null @@ -1,88 +0,0 @@ -// -// ASCGImageBuffer.mm -// Texture -// -// Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -// - -#import "ASCGImageBuffer.h" - -#import -#import -#import -#import - -/** - * The behavior of this class is modeled on the private function - * _CGDataProviderCreateWithCopyOfData, which is the function used - * by CGBitmapContextCreateImage. - * - * If the buffer is larger than a page, we use mmap and mark it as - * read-only when they are finished drawing. Then we wrap the VM - * in an NSData - */ -@implementation ASCGImageBuffer { - BOOL _createdData; - BOOL _isVM; - NSUInteger _length; -} - -- (instancetype)initWithLength:(NSUInteger)length -{ - if (self = [super init]) { - _length = length; - _isVM = (length >= vm_page_size); - if (_isVM) { - _mutableBytes = mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, VM_MAKE_TAG(VM_MEMORY_COREGRAPHICS_DATA), 0); - if (_mutableBytes == MAP_FAILED) { - NSAssert(NO, @"Failed to map for CG image data."); - _isVM = NO; - } - } - - // Check the VM flag again because we may have failed above. - if (!_isVM) { - _mutableBytes = calloc(1, length); - } - } - return self; -} - -- (void)dealloc -{ - if (!_createdData) { - [ASCGImageBuffer deallocateBuffer:_mutableBytes length:_length isVM:_isVM]; - } -} - -- (CGDataProviderRef)createDataProviderAndInvalidate -{ - NSAssert(!_createdData, @"Should not create data provider from buffer multiple times."); - _createdData = YES; - - // Mark the pages as read-only. - if (_isVM) { - __unused kern_return_t result = vm_protect(mach_task_self(), (vm_address_t)_mutableBytes, _length, true, VM_PROT_READ); - NSAssert(result == noErr, @"Error marking buffer as read-only: %@", [NSError errorWithDomain:NSMachErrorDomain code:result userInfo:nil]); - } - - // Wrap in an NSData - BOOL isVM = _isVM; - NSData *d = [[NSData alloc] initWithBytesNoCopy:_mutableBytes length:_length deallocator:^(void * _Nonnull bytes, NSUInteger length) { - [ASCGImageBuffer deallocateBuffer:bytes length:length isVM:isVM]; - }]; - return CGDataProviderCreateWithCFData((__bridge CFDataRef)d); -} - -+ (void)deallocateBuffer:(void *)buf length:(NSUInteger)length isVM:(BOOL)isVM -{ - if (isVM) { - __unused kern_return_t result = vm_deallocate(mach_task_self(), (vm_address_t)buf, length); - NSAssert(result == noErr, @"Failed to unmap cg image buffer: %@", [NSError errorWithDomain:NSMachErrorDomain code:result userInfo:nil]); - } else { - free(buf); - } -} - -@end diff --git a/Example/Pods/Texture/Source/ASCellNode.h b/Example/Pods/Texture/Source/ASCellNode.h index 589d08e..c09becc 100644 --- a/Example/Pods/Texture/Source/ASCellNode.h +++ b/Example/Pods/Texture/Source/ASCellNode.h @@ -194,6 +194,12 @@ typedef NS_ENUM(NSUInteger, ASCellNodeVisibilityEvent) { */ @property (nullable) UIView *selectedBackgroundView; +/* @abstract The view used as the background of the cell. + * ASTableView uses these properties when configuring UITableViewCells that host ASCellNodes. + * ASCollectionView uses these properties when configuring UICollectionViewCells that host ASCellNodes. + */ +@property (nullable) UIView *backgroundView; + /* @abstract The accessory type view on the right side of the cell. Please take care of your ASLayoutSpec so that doesn't overlay the accessoryView * @default UITableViewCellAccessoryNone * ASTableView uses these properties when configuring UITableViewCells that host ASCellNodes. diff --git a/Example/Pods/Texture/Source/ASCellNode.mm b/Example/Pods/Texture/Source/ASCellNode.mm index 02ce2c8..208eb5f 100644 --- a/Example/Pods/Texture/Source/ASCellNode.mm +++ b/Example/Pods/Texture/Source/ASCellNode.mm @@ -19,9 +19,8 @@ #import #import #import -#import -#import +#import #import #import @@ -34,10 +33,11 @@ @interface ASCellNode () ASDisplayNodeDidLoadBlock _viewControllerDidLoadBlock; ASDisplayNode *_viewControllerNode; UIViewController *_viewController; + UICollectionViewLayoutAttributes *_layoutAttributes; BOOL _suspendInteractionDelegate; BOOL _selected; BOOL _highlighted; - UICollectionViewLayoutAttributes *_layoutAttributes; + BOOL _neverShowPlaceholders; } @end @@ -79,8 +79,8 @@ - (void)didLoad _viewController = _viewControllerBlock(); _viewControllerBlock = nil; - if ([_viewController isKindOfClass:[ASViewController class]]) { - ASViewController *asViewController = (ASViewController *)_viewController; + if ([_viewController isKindOfClass:[ASDKViewController class]]) { + ASDKViewController *asViewController = (ASDKViewController *)_viewController; _viewControllerNode = asViewController.node; [_viewController loadViewIfNeeded]; } else { @@ -137,7 +137,7 @@ - (void)setSelected:(BOOL)selected if (ASLockedSelfCompareAssign(_selected, selected)) { if (!_suspendInteractionDelegate) { ASPerformBlockOnMainThread(^{ - [_interactionDelegate nodeSelectedStateDidChange:self]; + [self->_interactionDelegate nodeSelectedStateDidChange:self]; }); } } @@ -153,7 +153,7 @@ - (void)setHighlighted:(BOOL)highlighted if (ASLockedSelfCompareAssign(_highlighted, highlighted)) { if (!_suspendInteractionDelegate) { ASPerformBlockOnMainThread(^{ - [_interactionDelegate nodeHighlightedStateDidChange:self]; + [self->_interactionDelegate nodeHighlightedStateDidChange:self]; }); } } @@ -200,6 +200,11 @@ - (UIViewController *)viewController return _viewController; } +- (id)owningNode +{ + return self.collectionElement.owningNode; +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-missing-super-calls" @@ -305,7 +310,7 @@ - (void)handleVisibilityChange:(BOOL)isVisible // in which case it is not valid to perform a convertRect (this actually crashes on iOS 8). UIScrollView *scrollView = (_scrollView != nil && view.superview != nil && [view isDescendantOfView:_scrollView]) ? _scrollView : nil; if (scrollView) { - cellFrame = [view convertRect:view.bounds toView:_scrollView]; + cellFrame = [view convertRect:view.bounds toView:scrollView]; } // If we did not convert, we'll pass along CGRectZero and a nil scrollView. The EventInvisible call is thus equivalent to @@ -322,7 +327,7 @@ - (void)handleVisibilityChange:(BOOL)isVisible UIScrollView *scrollView = self.scrollView; - ASDisplayNode *owningNode = scrollView.asyncdisplaykit_node; + id owningNode = self.owningNode; if ([owningNode isKindOfClass:[ASCollectionNode class]]) { NSIndexPath *ip = [(ASCollectionNode *)owningNode indexPathForNode:self]; if (ip != nil) { diff --git a/Example/Pods/Texture/Source/ASCollectionNode.h b/Example/Pods/Texture/Source/ASCollectionNode.h index 4615ecb..fde5a13 100644 --- a/Example/Pods/Texture/Source/ASCollectionNode.h +++ b/Example/Pods/Texture/Source/ASCollectionNode.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN * ASCollectionNode is a node based class that wraps an ASCollectionView. It can be used * as a subnode of another node, and provide room for many (great) features and improvements later on. */ -@interface ASCollectionNode : ASDisplayNode +@interface ASCollectionNode : ASDisplayNode - (instancetype)init NS_UNAVAILABLE; @@ -121,10 +121,16 @@ NS_ASSUME_NONNULL_BEGIN /** * A Boolean value that controls whether the horizontal scroll indicator is visible. - * The default value of this property is NO. + * The default value of this property is YES. */ @property (nonatomic) BOOL showsHorizontalScrollIndicator; +/** + * A Boolean value that determines whether paging is enabled for the scroll view. + * The default value of this property is NO. + */ +@property (nonatomic, getter=isPagingEnabled) BOOL pagingEnabled __TVOS_PROHIBITED; + /** * The layout used to organize the node's items. * @@ -672,6 +678,29 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)collectionNode:(ASCollectionNode *)collectionNode moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath; +/** + * Generate a unique identifier for an element in a collection. This helps state restoration persist the scroll position + * of a collection view even when the data in that table changes. See the documentation for UIDataSourceModelAssociation for more information. + * + * @param indexPath The index path of the requested node. + * + * @param collectionNode The sender. + * + * @return a unique identifier for the element at the given path. Return nil if the index path does not exist in the collection. + */ +- (nullable NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inNode:(ASCollectionNode *)collectionNode; + +/** + * Similar to -collectionView:cellForItemAtIndexPath:. See the documentation for UIDataSourceModelAssociation for more information. + * + * @param identifier The model identifier of the element, previously generated by a call to modelIdentifierForElementAtIndexPath + * + * @param collectionNode The sender. + * + * @return the index path to the current position of the matching element in the collection. Return nil if the element is not found. + */ +- (nullable NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inNode:(ASCollectionNode *)collectionNode; + /** * Similar to -collectionView:cellForItemAtIndexPath:. * diff --git a/Example/Pods/Texture/Source/ASCollectionNode.mm b/Example/Pods/Texture/Source/ASCollectionNode.mm index e79b08a..f1da3e5 100644 --- a/Example/Pods/Texture/Source/ASCollectionNode.mm +++ b/Example/Pods/Texture/Source/ASCollectionNode.mm @@ -18,12 +18,9 @@ #import #import #import -#import #import #import -#import #import -#import #import #import #import @@ -34,6 +31,21 @@ @interface _ASCollectionPendingState : NSObject { @public std::vector> _tuningParameters; + + // Keep these enums by the bitfield struct to save memory. + ASLayoutRangeMode _rangeMode; + ASCellLayoutMode _cellLayoutMode; + struct { + unsigned int allowsSelection:1; // default is YES + unsigned int allowsMultipleSelection:1; // default is NO + unsigned int inverted:1; //default is NO + unsigned int alwaysBounceVertical:1; + unsigned int alwaysBounceHorizontal:1; + unsigned int animatesContentOffset:1; + unsigned int showsVerticalScrollIndicator:1; + unsigned int showsHorizontalScrollIndicator:1; + unsigned int pagingEnabled:1; + } _flags; } @property (nonatomic, weak) id delegate; @property (nonatomic, weak) id dataSource; @@ -52,6 +64,7 @@ @interface _ASCollectionPendingState : NSObject { @property (nonatomic) BOOL animatesContentOffset; @property (nonatomic) BOOL showsVerticalScrollIndicator; @property (nonatomic) BOOL showsHorizontalScrollIndicator; +@property (nonatomic) BOOL pagingEnabled; @end @implementation _ASCollectionPendingState @@ -64,18 +77,131 @@ - (instancetype)init if (self) { _rangeMode = ASLayoutRangeModeUnspecified; _tuningParameters = [ASAbstractLayoutController defaultTuningParameters]; - _allowsSelection = YES; - _allowsMultipleSelection = NO; - _inverted = NO; + _flags.allowsSelection = YES; + _flags.allowsMultipleSelection = NO; + _flags.inverted = NO; _contentInset = UIEdgeInsetsZero; _contentOffset = CGPointZero; - _animatesContentOffset = NO; - _showsVerticalScrollIndicator = YES; - _showsHorizontalScrollIndicator = YES; + _flags.animatesContentOffset = NO; + _flags.showsVerticalScrollIndicator = YES; + _flags.showsHorizontalScrollIndicator = YES; + _flags.pagingEnabled = NO; } return self; } +#pragma mark Properties + +- (ASLayoutRangeMode)rangeMode +{ + return _rangeMode; +} + +- (void)setRangeMode:(ASLayoutRangeMode)rangeMode +{ + _rangeMode = rangeMode; +} + +- (ASCellLayoutMode)cellLayoutMode +{ + return _cellLayoutMode; +} + +- (void)setCellLayoutMode:(ASCellLayoutMode)cellLayoutMode +{ + _cellLayoutMode = cellLayoutMode; +} + +- (BOOL)allowsSelection +{ + return _flags.allowsSelection; +} + +- (void)setAllowsSelection:(BOOL)allowsSelection +{ + _flags.allowsSelection = allowsSelection; +} + +- (BOOL)allowsMultipleSelection +{ + return _flags.allowsMultipleSelection; +} + +- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection +{ + _flags.allowsMultipleSelection = allowsMultipleSelection; +} + +- (BOOL)inverted +{ + return _flags.inverted; +} + +-(void)setInverted:(BOOL)inverted +{ + _flags.inverted = inverted; +} + +-(BOOL)alwaysBounceVertical +{ + return _flags.alwaysBounceVertical; +} + +-(void)setAlwaysBounceVertical:(BOOL)alwaysBounceVertical +{ + _flags.alwaysBounceVertical = alwaysBounceVertical; +} + +-(BOOL)alwaysBounceHorizontal +{ + return _flags.alwaysBounceHorizontal; +} + +-(void)setAlwaysBounceHorizontal:(BOOL)alwaysBounceHorizontal +{ + _flags.alwaysBounceHorizontal = alwaysBounceHorizontal; +} + +- (BOOL)animatesContentOffset +{ + return _flags.animatesContentOffset; +} + +-(void)setAnimatesContentOffset:(BOOL)animatesContentOffset +{ + _flags.animatesContentOffset = animatesContentOffset; +} + +- (BOOL)showsVerticalScrollIndicator +{ + return _flags.showsVerticalScrollIndicator; +} + +- (void)setShowsVerticalScrollIndicator:(BOOL)showsVerticalScrollIndicator +{ + _flags.showsVerticalScrollIndicator = showsVerticalScrollIndicator; +} + +-(BOOL)showsHorizontalScrollIndicator +{ + return _flags.showsHorizontalScrollIndicator; +} + +- (void)setShowsHorizontalScrollIndicator:(BOOL)showsHorizontalScrollIndicator +{ + _flags.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator; +} + +-(BOOL)pagingEnabled +{ + return _flags.pagingEnabled; +} + +- (void)setPagingEnabled:(BOOL)pagingEnabled +{ + _flags.pagingEnabled = pagingEnabled; +} + #pragma mark Tuning Parameters - (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType @@ -106,7 +232,7 @@ - (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMo @interface ASCollectionNode () { - ASDN::RecursiveMutex _environmentStateLock; + AS::RecursiveMutex _environmentStateLock; Class _collectionViewClass; id _batchFetchingDelegate; } @@ -156,7 +282,7 @@ - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionVi __weak __typeof__(self) weakSelf = self; [self setViewBlock:^{ __typeof__(self) strongSelf = weakSelf; - return [[[strongSelf collectionViewClass] alloc] _initWithFrame:frame collectionViewLayout:strongSelf->_pendingState.collectionViewLayout layoutFacilitator:layoutFacilitator owningNode:strongSelf eventLog:ASDisplayNodeGetEventLog(strongSelf)]; + return [[[strongSelf collectionViewClass] alloc] _initWithFrame:frame collectionViewLayout:strongSelf->_pendingState.collectionViewLayout layoutFacilitator:layoutFacilitator owningNode:strongSelf]; }]; } return self; @@ -197,6 +323,9 @@ - (void)didLoad view.layoutInspector = pendingState.layoutInspector; view.showsVerticalScrollIndicator = pendingState.showsVerticalScrollIndicator; view.showsHorizontalScrollIndicator = pendingState.showsHorizontalScrollIndicator; +#if !TARGET_OS_TV + view.pagingEnabled = pendingState.pagingEnabled; +#endif // Only apply these flags if they're enabled; the view might come with them turned on. if (pendingState.alwaysBounceVertical) { @@ -528,6 +657,28 @@ - (BOOL)showsHorizontalScrollIndicator } } +#if !TARGET_OS_TV +- (void)setPagingEnabled:(BOOL)pagingEnabled +{ + if ([self pendingState]) { + _pendingState.pagingEnabled = pagingEnabled; + } else { + ASDisplayNodeAssert([self isNodeLoaded], + @"ASCollectionNode should be loaded if pendingState doesn't exist"); + self.view.pagingEnabled = pagingEnabled; + } +} + +- (BOOL)isPagingEnabled +{ + if ([self pendingState]) { + return _pendingState.pagingEnabled; + } else { + return self.view.isPagingEnabled; + } +} +#endif + - (void)setCollectionViewLayout:(UICollectionViewLayout *)layout { if ([self pendingState]) { @@ -1040,6 +1191,38 @@ - (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode; return result; } +#pragma mark - UIGestureRecognizerDelegate Methods +// The value returned below are default implementation of UIKit's UIGestureRecognizerDelegate +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer +{ + return YES; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch +{ + return YES; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press +{ + return YES; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return NO; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return NO; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return NO; +} + #pragma mark - Private methods - (void)_configureCollectionViewLayout:(UICollectionViewLayout *)layout diff --git a/Example/Pods/Texture/Source/ASCollectionView.h b/Example/Pods/Texture/Source/ASCollectionView.h index 6e9d343..1b250a2 100644 --- a/Example/Pods/Texture/Source/ASCollectionView.h +++ b/Example/Pods/Texture/Source/ASCollectionView.h @@ -30,7 +30,7 @@ NS_ASSUME_NONNULL_BEGIN * * @note ASCollectionNode is strongly recommended over ASCollectionView. This class exists for adoption convenience. */ -@interface ASCollectionView : UICollectionView +@interface ASCollectionView : UICollectionView /** * Returns the corresponding ASCollectionNode diff --git a/Example/Pods/Texture/Source/ASCollectionView.mm b/Example/Pods/Texture/Source/ASCollectionView.mm index dec648d..afe9716 100644 --- a/Example/Pods/Texture/Source/ASCollectionView.mm +++ b/Example/Pods/Texture/Source/ASCollectionView.mm @@ -19,7 +19,6 @@ #import #import #import -#import #import #import #import @@ -30,7 +29,6 @@ #import #import #import -#import #import #import #import @@ -65,7 +63,7 @@ // ASCellLayoutMode is an NSUInteger-based NS_OPTIONS field. Be careful with BOOL handling on the // 32-bit Objective-C runtime, and pattern after ASInterfaceStateIncludesVisible() & friends. -#define ASCellLayoutModeIncludes(layoutMode) ((_cellLayoutMode & layoutMode) == layoutMode) +#define ASCellLayoutModeIncludes(layoutMode) ((self->_cellLayoutMode & layoutMode) == layoutMode) /// What, if any, invalidation should we perform during the next -layoutSubviews. typedef NS_ENUM(NSUInteger, ASCollectionViewInvalidationStyle) { @@ -230,6 +228,7 @@ @interface ASCollectionView () )layoutFacilitator owningNode:(ASCollectionNode *)owningNode eventLog:(ASEventLog *)eventLog +- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id)layoutFacilitator owningNode:(ASCollectionNode *)owningNode { if (!(self = [super initWithFrame:frame collectionViewLayout:layout])) return nil; @@ -289,7 +288,7 @@ - (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionV _rangeController.delegate = self; _rangeController.layoutController = _layoutController; - _dataController = [[ASDataController alloc] initWithDataSource:self node:owningNode eventLog:eventLog]; + _dataController = [[ASDataController alloc] initWithDataSource:self node:owningNode]; _dataController.delegate = _rangeController; _batchContext = [[ASBatchContext alloc] init]; @@ -316,13 +315,8 @@ - (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionV [self registerClass:[_ASCollectionViewCell class] forCellWithReuseIdentifier:kReuseIdentifier]; [self _configureCollectionViewLayout:layout]; - - if (ASActivateExperimentalFeature(ASExperimentalNewDefaultCellLayoutMode)) { - _cellLayoutMode = ASCellLayoutModeSyncForSmallContent; - } else { - _cellLayoutMode = ASCellLayoutModeNone; - } - + + self.panGestureRecognizer.delegate = self; return self; } @@ -337,10 +331,6 @@ - (void)dealloc [self setAsyncDelegate:nil]; [self setAsyncDataSource:nil]; } - - // Data controller & range controller may own a ton of nodes, let's deallocate those off-main. - ASPerformBackgroundDeallocation(&_dataController); - ASPerformBackgroundDeallocation(&_rangeController); } #pragma mark - @@ -486,6 +476,9 @@ - (void)setAsyncDataSource:(id)asyncDataSource _asyncDataSourceFlags.interopViewForSupplementaryElement = [interopDataSource respondsToSelector:@selector(collectionView:viewForSupplementaryElementOfKind:atIndexPath:)]; } + _asyncDataSourceFlags.modelIdentifierMethods = [_asyncDataSource respondsToSelector:@selector(modelIdentifierForElementAtIndexPath:inNode:)] && [_asyncDataSource respondsToSelector:@selector(indexPathForElementWithModelIdentifier:inNode:)]; + + ASDisplayNodeAssert(_asyncDataSourceFlags.collectionNodeNumberOfItemsInSection || _asyncDataSourceFlags.collectionViewNumberOfItemsInSection, @"Data source must implement collectionNode:numberOfItemsInSection:"); ASDisplayNodeAssert(_asyncDataSourceFlags.collectionNodeNodeBlockForItem || _asyncDataSourceFlags.collectionNodeNodeForItem @@ -805,6 +798,29 @@ - (void)invalidateFlowLayoutDelegateMetrics // Subclass hook } +- (nullable NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inView:(UIView *)view { + if (_asyncDataSourceFlags.modelIdentifierMethods) { + GET_COLLECTIONNODE_OR_RETURN(collectionNode, nil); + NSIndexPath *convertedPath = [self convertIndexPathToCollectionNode:indexPath]; + if (convertedPath == nil) { + return nil; + } else { + return [_asyncDataSource modelIdentifierForElementAtIndexPath:convertedPath inNode:collectionNode]; + } + } else { + return nil; + } +} + +- (nullable NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view { + if (_asyncDataSourceFlags.modelIdentifierMethods) { + GET_COLLECTIONNODE_OR_RETURN(collectionNode, nil); + return [_asyncDataSource indexPathForElementWithModelIdentifier:identifier inNode:collectionNode]; + } else { + return nil; + } +} + #pragma mark Internal - (void)_configureCollectionViewLayout:(nonnull UICollectionViewLayout *)layout @@ -1229,6 +1245,7 @@ - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICol // Update the selected background view in collectionView:willDisplayCell:forItemAtIndexPath: otherwise it could be too // early e.g. if the selectedBackgroundView was set in didLoad() cell.selectedBackgroundView = cellNode.selectedBackgroundView; + cell.backgroundView = cellNode.backgroundView; // Under iOS 10+, cells may be removed/re-added to the collection view without // receiving prepareForReuse/applyLayoutAttributes, as an optimization for e.g. @@ -1561,7 +1578,7 @@ - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath if ([self.collectionViewLayout isKindOfClass:[ASCollectionLayout class]]) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - as_log_debug(ASCollectionLog(), "Collection node item interactive movement is not supported when using a layout delegate. This message will only be logged once. Node: %@", ASObjectDescriptionMakeTiny(self)); + os_log_debug(ASCollectionLog(), "Collection node item interactive movement is not supported when using a layout delegate. This message will only be logged once. Node: %@", ASObjectDescriptionMakeTiny(self)); }); return NO; } @@ -1684,7 +1701,8 @@ - (void)setLeadingScreensForBatching:(CGFloat)leadingScreensForBatching { if (_leadingScreensForBatching != leadingScreensForBatching) { _leadingScreensForBatching = leadingScreensForBatching; - ASPerformBlockOnMainThread(^{ + // Push this to the next runloop to be sure the scroll view has the right content size + dispatch_async(dispatch_get_main_queue(), ^{ [self _checkForBatchFetching]; }); } @@ -1851,14 +1869,14 @@ - (void)_beginBatchFetching if (_asyncDelegateFlags.collectionNodeWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ GET_COLLECTIONNODE_OR_RETURN(collectionNode, (void)0); - as_log_debug(ASCollectionLog(), "Beginning batch fetch for %@ with context %@", collectionNode, _batchContext); - [_asyncDelegate collectionNode:collectionNode willBeginBatchFetchWithContext:_batchContext]; + os_log_debug(ASCollectionLog(), "Beginning batch fetch for %@ with context %@", collectionNode, self->_batchContext); + [self->_asyncDelegate collectionNode:collectionNode willBeginBatchFetchWithContext:self->_batchContext]; }); } else if (_asyncDelegateFlags.collectionViewWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [_asyncDelegate collectionView:self willBeginBatchFetchWithContext:_batchContext]; + [self->_asyncDelegate collectionView:self willBeginBatchFetchWithContext:self->_batchContext]; #pragma clang diagnostic pop }); } @@ -1883,20 +1901,18 @@ - (BOOL)dataController:(ASDataController *)dataController shouldSynchronouslyPro if (ASCellLayoutModeIncludes(ASCellLayoutModeAlwaysAsync)) { return NO; } - if (ASCellLayoutModeIncludes(ASCellLayoutModeSyncForSmallContent)) { - // Reload data is expensive, don't block main while doing so. - if (changeSet.includesReloadData) { - return NO; - } - // If we have very few ASCellNodes (besides UIKit passthrough ones), match UIKit by blocking. - if (changeSet.countForAsyncLayout < 2) { - return YES; - } - CGSize contentSize = self.contentSize; - CGSize boundsSize = self.bounds.size; - if (contentSize.height <= boundsSize.height && contentSize.width <= boundsSize.width) { - return YES; - } + // Reload data is expensive, don't block main while doing so. + if (changeSet.includesReloadData) { + return NO; + } + // If we have very few ASCellNodes (besides UIKit passthrough ones), match UIKit by blocking. + if (changeSet.countForAsyncLayout < 2) { + return YES; + } + CGSize contentSize = self.contentSize; + CGSize boundsSize = self.bounds.size; + if (contentSize.height <= boundsSize.height && contentSize.width <= boundsSize.width) { + return YES; } return NO; // ASCellLayoutModeNone } @@ -2015,7 +2031,13 @@ - (BOOL)dataController:(ASDataController *)dataController presentedSizeForElemen ASDisplayNodeFailAssert(@"Data controller should not ask for presented size for element that is not presented."); return YES; } - UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath]; + + UICollectionViewLayoutAttributes *attributes; + if (element.supplementaryElementKind == nil) { + attributes = [self layoutAttributesForItemAtIndexPath:indexPath]; + } else { + attributes = [self layoutAttributesForSupplementaryElementOfKind:element.supplementaryElementKind atIndexPath:indexPath]; + } return CGSizeEqualToSizeWithIn(attributes.size, size, FLT_EPSILON); } @@ -2220,20 +2242,20 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet ASPerformBlockWithoutAnimation(!changeSet.animated, ^{ as_activity_scope(as_activity_create("Commit collection update", changeSet.rootActivity, OS_ACTIVITY_FLAG_DEFAULT)); if (changeSet.includesReloadData) { - _superIsPendingDataLoad = YES; + self->_superIsPendingDataLoad = YES; updates(); [self _superReloadData:nil completion:nil]; - as_log_debug(ASCollectionLog(), "Did reloadData %@", self.collectionNode); + os_log_debug(ASCollectionLog(), "Did reloadData %@", self.collectionNode); [changeSet executeCompletionHandlerWithFinished:YES]; } else { - [_layoutFacilitator collectionViewWillPerformBatchUpdates]; + [self->_layoutFacilitator collectionViewWillPerformBatchUpdates]; __block NSUInteger numberOfUpdates = 0; const auto completion = ^(BOOL finished) { as_activity_scope(as_activity_create("Handle collection update completion", changeSet.rootActivity, OS_ACTIVITY_FLAG_DEFAULT)); as_log_verbose(ASCollectionLog(), "Update animation finished %{public}@", self.collectionNode); // Flush any range changes that happened as part of the update animations ending. - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:numberOfUpdates]; [changeSet executeCompletionHandlerWithFinished:finished]; }; @@ -2285,11 +2307,11 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet } completion:completion]; } - as_log_debug(ASCollectionLog(), "Completed batch update %{public}@", self.collectionNode); + os_log_debug(ASCollectionLog(), "Completed batch update %{public}@", self.collectionNode); // Flush any range changes that happened as part of submitting the update. as_activity_scope(changeSet.rootActivity); - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; } }); } @@ -2485,10 +2507,39 @@ - (void)setPrefetchingEnabled:(BOOL)prefetchingEnabled - (NSArray *)accessibilityElements { - if (!ASActivateExperimentalFeature(ASExperimentalSkipAccessibilityWait)) { - [self waitUntilAllUpdatesAreCommitted]; - } + [self waitUntilAllUpdatesAreCommitted]; return [super accessibilityElements]; } +#pragma mark - UIGestureRecognizerDelegate Method +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer +{ + return [self.collectionNode gestureRecognizerShouldBegin:gestureRecognizer]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch +{ + return [self.collectionNode gestureRecognizer:gestureRecognizer shouldReceiveTouch:touch]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press +{ + return [self.collectionNode gestureRecognizer:gestureRecognizer shouldReceivePress:press]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return [self.collectionNode gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return [self.collectionNode gestureRecognizer:gestureRecognizer shouldRequireFailureOfGestureRecognizer:otherGestureRecognizer]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return [self.collectionNode gestureRecognizer:gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:otherGestureRecognizer]; +} + @end diff --git a/Example/Pods/Texture/Source/ASCollectionViewProtocols.h b/Example/Pods/Texture/Source/ASCollectionViewProtocols.h index 4913202..ec1b8d5 100644 --- a/Example/Pods/Texture/Source/ASCollectionViewProtocols.h +++ b/Example/Pods/Texture/Source/ASCollectionViewProtocols.h @@ -10,17 +10,12 @@ #import #import -typedef NS_OPTIONS(NSUInteger, ASCellLayoutMode) { +typedef NS_OPTIONS(unsigned short, ASCellLayoutMode) { /** * No options set. If cell layout mode is set to ASCellLayoutModeNone, the default values for * each flag listed below is used. */ ASCellLayoutModeNone = 0, - /** - * If ASCellLayoutModeSyncForSmallContent is enabled it will cause ASDataController to wait on the - * background queue if the amount of new content is small. - */ - ASCellLayoutModeSyncForSmallContent = 1 << 1, /** * If ASCellLayoutModeAlwaysSync is enabled it will cause the ASDataController to wait on the * background queue, and this ensures that any new / changed cells are in the hierarchy by the @@ -31,26 +26,26 @@ typedef NS_OPTIONS(NSUInteger, ASCellLayoutMode) { * default behavior is synchronous when there are 0 or 1 ASCellNodes in the data source, and * asynchronous when there are 2 or more. */ - ASCellLayoutModeAlwaysSync = 1 << 2, // Default OFF - ASCellLayoutModeAlwaysAsync = 1 << 3, // Default OFF - ASCellLayoutModeForceIfNeeded = 1 << 4, // Deprecated, default OFF. - ASCellLayoutModeAlwaysPassthroughDelegate = 1 << 5, // Deprecated, default ON. + ASCellLayoutModeAlwaysSync = 1 << 1, // Default OFF + ASCellLayoutModeAlwaysAsync = 1 << 2, // Default OFF + ASCellLayoutModeForceIfNeeded = 1 << 3, // Deprecated, default OFF. + ASCellLayoutModeAlwaysPassthroughDelegate = 1 << 4, // Deprecated, default ON. /** Instead of using performBatchUpdates: prefer using reloadData for changes for collection view */ - ASCellLayoutModeAlwaysReloadData = 1 << 6, // Default OFF + ASCellLayoutModeAlwaysReloadData = 1 << 5, // Default OFF /** If flag is enabled nodes are *not* gonna be range managed. */ - ASCellLayoutModeDisableRangeController = 1 << 7, // Default OFF - ASCellLayoutModeAlwaysLazy = 1 << 8, // Deprecated, default OFF. + ASCellLayoutModeDisableRangeController = 1 << 6, // Default OFF + ASCellLayoutModeAlwaysLazy = 1 << 7, // Deprecated, default OFF. /** * Defines if the node creation should happen serialized and not in parallel within the * data controller */ - ASCellLayoutModeSerializeNodeCreation = 1 << 9, // Default OFF + ASCellLayoutModeSerializeNodeCreation = 1 << 8, // Default OFF /** * When set, the performBatchUpdates: API (including animation) is used when handling Section * Reload operations. This is useful only when ASCellLayoutModeAlwaysReloadData is enabled and * cell height animations are desired. */ - ASCellLayoutModeAlwaysBatchUpdateSectionReload = 1 << 10 // Default OFF + ASCellLayoutModeAlwaysBatchUpdateSectionReload = 1 << 9, // Default OFF }; NS_ASSUME_NONNULL_BEGIN @@ -100,6 +95,13 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender ASDISPLAYNODE_DEPRECATED_MSG("Implement collectionNode:canPerformAction:forItemAtIndexPath:withSender: instead."); - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender ASDISPLAYNODE_DEPRECATED_MSG("Implement collectionNode:performAction:forItemAtIndexPath:withSender: instead."); +- (nullable UIContextMenuConfiguration *)collectionView:(UICollectionView *)collectionView contextMenuConfigurationForItemAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); + +- (nullable UITargetedPreview *)collectionView:(UICollectionView *)collectionView previewForHighlightingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); + +- (nullable UITargetedPreview *)collectionView:(UICollectionView *)collectionView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); + +- (void)collectionView:(UICollectionView *)collectionView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos); @end NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASConfiguration.mm b/Example/Pods/Texture/Source/ASConfiguration.mm index 34f11bd..a201dc2 100644 --- a/Example/Pods/Texture/Source/ASConfiguration.mm +++ b/Example/Pods/Texture/Source/ASConfiguration.mm @@ -7,7 +7,6 @@ // #import -#import /// Not too performance-sensitive here. diff --git a/Example/Pods/Texture/Source/ASConfigurationDelegate.h b/Example/Pods/Texture/Source/ASConfigurationDelegate.h index 127ec3e..fde3950 100644 --- a/Example/Pods/Texture/Source/ASConfigurationDelegate.h +++ b/Example/Pods/Texture/Source/ASConfigurationDelegate.h @@ -27,8 +27,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Texture framework initialized. This method is called synchronously * on the main thread from ASInitializeFrameworkMainThread if you defined - * AS_INITIALIZE_FRAMEWORK_MANUALLY or from the default initialization point - * (currently +load) otherwise. + * AS_INITIALIZE_FRAMEWORK_MANUALLY or otherwise from the default initialization point + * (currently a static constructor, called before main()). */ - (void)textureDidInitialize; diff --git a/Example/Pods/Texture/Source/ASConfigurationInternal.h b/Example/Pods/Texture/Source/ASConfigurationInternal.h index 3bad3fd..fa69496 100644 --- a/Example/Pods/Texture/Source/ASConfigurationInternal.h +++ b/Example/Pods/Texture/Source/ASConfigurationInternal.h @@ -20,12 +20,26 @@ NS_ASSUME_NONNULL_BEGIN * * The delegate will be notified asynchronously. */ -AS_EXTERN BOOL ASActivateExperimentalFeature(ASExperimentalFeatures option); +#if DEBUG +#define ASActivateExperimentalFeature(opt) _ASActivateExperimentalFeature(opt) +#else +#define ASActivateExperimentalFeature(opt) ({\ + static BOOL result;\ + static dispatch_once_t onceToken;\ + dispatch_once(&onceToken, ^{ result = _ASActivateExperimentalFeature(opt); });\ + result;\ +}) +#endif + +/** + * Internal function. Use the macro without the underbar. + */ +ASDK_EXTERN BOOL _ASActivateExperimentalFeature(ASExperimentalFeatures option); /** * Notify the configuration delegate that the framework initialized, if needed. */ -AS_EXTERN void ASNotifyInitialized(void); +ASDK_EXTERN void ASNotifyInitialized(void); AS_SUBCLASSING_RESTRICTED @interface ASConfigurationManager : NSObject diff --git a/Example/Pods/Texture/Source/ASConfigurationInternal.mm b/Example/Pods/Texture/Source/ASConfigurationInternal.mm index ec23823..4bcc1ff 100644 --- a/Example/Pods/Texture/Source/ASConfigurationInternal.mm +++ b/Example/Pods/Texture/Source/ASConfigurationInternal.mm @@ -8,11 +8,18 @@ #import "ASConfigurationInternal.h" #import -#import #import #import -#define ASGetSharedConfigMgr() (__bridge ASConfigurationManager *)ASConfigurationManager.sharedInstance +static ASConfigurationManager *ASSharedConfigurationManager; +static dispatch_once_t ASSharedConfigurationManagerOnceToken; + +NS_INLINE ASConfigurationManager *ASConfigurationManagerGet() { + dispatch_once(&ASSharedConfigurationManagerOnceToken, ^{ + ASSharedConfigurationManager = [[ASConfigurationManager alloc] init]; + }); + return ASSharedConfigurationManager; +} @implementation ASConfigurationManager { ASConfiguration *_config; @@ -21,17 +28,6 @@ @implementation ASConfigurationManager { _Atomic(ASExperimentalFeatures) _activatedExperiments; } -/// Return CFTypeRef to avoid retain/release on this singleton. -+ (CFTypeRef)sharedInstance -{ - static CFTypeRef inst; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - inst = (__bridge_retained CFTypeRef)[[ASConfigurationManager alloc] init]; - }); - return inst; -} - + (ASConfiguration *)defaultConfiguration NS_RETURNS_RETAINED { ASConfiguration *config = [[ASConfiguration alloc] init]; @@ -84,7 +80,7 @@ - (BOOL)activateExperimentalFeature:(ASExperimentalFeatures)requested // Notify delegate if needed. if (newlyTriggered != 0) { - __unsafe_unretained id del = _config.delegate; + unowned id del = _config.delegate; dispatch_async(_delegateQueue, ^{ [del textureDidActivateExperimentalFeatures:newlyTriggered]; }); @@ -96,19 +92,19 @@ - (BOOL)activateExperimentalFeature:(ASExperimentalFeatures)requested // Define this even when !DEBUG, since we may run our tests in release mode. + (void)test_resetWithConfiguration:(ASConfiguration *)configuration { - ASConfigurationManager *inst = ASGetSharedConfigMgr(); + ASConfigurationManager *inst = ASConfigurationManagerGet(); inst->_config = configuration ?: [self defaultConfiguration]; atomic_store(&inst->_activatedExperiments, 0); } @end -BOOL ASActivateExperimentalFeature(ASExperimentalFeatures feature) +BOOL _ASActivateExperimentalFeature(ASExperimentalFeatures feature) { - return [ASGetSharedConfigMgr() activateExperimentalFeature:feature]; + return [ASConfigurationManagerGet() activateExperimentalFeature:feature]; } void ASNotifyInitialized() { - [ASGetSharedConfigMgr() frameworkDidInitialize]; + [ASConfigurationManagerGet() frameworkDidInitialize]; } diff --git a/Example/Pods/Texture/Source/ASContextTransitioning.h b/Example/Pods/Texture/Source/ASContextTransitioning.h index 9802ece..aea3501 100644 --- a/Example/Pods/Texture/Source/ASContextTransitioning.h +++ b/Example/Pods/Texture/Source/ASContextTransitioning.h @@ -14,8 +14,8 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN NSString * const ASTransitionContextFromLayoutKey; -AS_EXTERN NSString * const ASTransitionContextToLayoutKey; +ASDK_EXTERN NSString * const ASTransitionContextFromLayoutKey; +ASDK_EXTERN NSString * const ASTransitionContextToLayoutKey; @protocol ASContextTransitioning diff --git a/Example/Pods/Texture/Source/ASControlNode.mm b/Example/Pods/Texture/Source/ASControlNode.mm index 1256d2d..4bc0ae6 100644 --- a/Example/Pods/Texture/Source/ASControlNode.mm +++ b/Example/Pods/Texture/Source/ASControlNode.mm @@ -8,15 +8,16 @@ // #import -#import #import #import #import #import -#import #import #import #import +#if TARGET_OS_TV +#import +#endif // UIControl allows dragging some distance outside of the control itself during // tracking. This value depends on the device idiom (25 or 70 points), so @@ -25,7 +26,6 @@ // Initial capacities for dispatch tables. #define kASControlNodeEventDispatchTableInitialCapacity 4 -#define kASControlNodeActionDispatchTableInitialCapacity 4 @interface ASControlNode () { @@ -300,10 +300,10 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeE dispatch_async(dispatch_get_main_queue(), ^{ // add a highlight overlay node with area of ASControlNode + UIEdgeInsets self.clipsToBounds = NO; - _debugHighlightOverlay = [[ASImageNode alloc] init]; - _debugHighlightOverlay.zPosition = 1000; // ensure we're over the top of any siblings - _debugHighlightOverlay.layerBacked = YES; - [self addSubnode:_debugHighlightOverlay]; + self->_debugHighlightOverlay = [[ASImageNode alloc] init]; + self->_debugHighlightOverlay.zPosition = 1000; // ensure we're over the top of any siblings + self->_debugHighlightOverlay.layerBacked = YES; + [self addSubnode:self->_debugHighlightOverlay]; }); } } @@ -319,7 +319,7 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeE { // Do we already have an event table for this control event? id eventKey = _ASControlNodeEventKeyForControlEvent(controlEvent); - NSMutableArray *eventTargetActionArray = _controlEventDispatchTable[eventKey]; + NSMutableArray *eventTargetActionArray = self->_controlEventDispatchTable[eventKey]; if (!eventTargetActionArray) { eventTargetActionArray = [[NSMutableArray alloc] init]; @@ -332,7 +332,7 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeE [eventTargetActionArray addObject:targetAction]; if (eventKey) { - [_controlEventDispatchTable setObject:eventTargetActionArray forKey:eventKey]; + [self->_controlEventDispatchTable setObject:eventTargetActionArray forKey:eventKey]; } }); @@ -393,7 +393,7 @@ - (void)removeTarget:(id)target action:(SEL)action forControlEvents:(ASControlNo { // Grab the dispatch table for this event (if we have it). id eventKey = _ASControlNodeEventKeyForControlEvent(controlEvent); - NSMutableArray *eventTargetActionArray = _controlEventDispatchTable[eventKey]; + NSMutableArray *eventTargetActionArray = self->_controlEventDispatchTable[eventKey]; if (!eventTargetActionArray) { return; } @@ -413,7 +413,7 @@ - (void)removeTarget:(id)target action:(SEL)action forControlEvents:(ASControlNo if (eventTargetActionArray.count == 0) { // If there are no targets for this event anymore, remove it. - [_controlEventDispatchTable removeObjectForKey:eventKey]; + [self->_controlEventDispatchTable removeObjectForKey:eventKey]; } }); } @@ -435,7 +435,7 @@ - (void)sendActionsForControlEvents:(ASControlNodeEvent)controlEvents withEvent: (ASControlNodeEvent controlEvent) { // Iterate on each target action pair - for (ASControlTargetAction *targetAction in _controlEventDispatchTable[_ASControlNodeEventKeyForControlEvent(controlEvent)]) { + for (ASControlTargetAction *targetAction in self->_controlEventDispatchTable[_ASControlNodeEventKeyForControlEvent(controlEvent)]) { ASControlTargetAction *resolvedTargetAction = [[ASControlTargetAction alloc] init]; resolvedTargetAction.action = targetAction.action; resolvedTargetAction.target = targetAction.target; diff --git a/Example/Pods/Texture/Source/ASViewController.h b/Example/Pods/Texture/Source/ASDKViewController.h similarity index 81% rename from Example/Pods/Texture/Source/ASViewController.h rename to Example/Pods/Texture/Source/ASDKViewController.h index 9486329..035b09e 100644 --- a/Example/Pods/Texture/Source/ASViewController.h +++ b/Example/Pods/Texture/Source/ASDKViewController.h @@ -1,5 +1,5 @@ // -// ASViewController.h +// ASDKViewController.h // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -19,25 +19,34 @@ typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitCollectionBlock)(U typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitWindowSizeBlock)(CGSize windowSize); /** - * ASViewController allows you to have a completely node backed hierarchy. It automatically + * ASDKViewController allows you to have a completely node backed hierarchy. It automatically * handles @c ASVisibilityDepth, automatic range mode and propogating @c ASDisplayTraits to contained nodes. * * You can opt-out of node backed hierarchy and use it like a normal UIViewController. * More importantly, you can use it as a base class for all of your view controllers among which some use a node hierarchy and some don't. * See examples/ASDKgram project for actual implementation. */ -@interface ASViewController<__covariant DisplayNodeType : ASDisplayNode *> : UIViewController +@interface ASDKViewController<__covariant DisplayNodeType : ASDisplayNode *> : UIViewController /** - * ASViewController initializer. + * ASDKViewController initializer. * * @param node An ASDisplayNode which will provide the root view (self.view) - * @return An ASViewController instance whose root view will be backed by the provided ASDisplayNode. + * @return An ASDKViewController instance whose root view will be backed by the provided ASDisplayNode. * * @see ASVisibilityDepth */ - (instancetype)initWithNode:(DisplayNodeType)node NS_DESIGNATED_INITIALIZER; +/** +* ASDKViewController initializer. Useful for interoperability with normal UIViewControllers. +* +* @return An ASDKViewController instance with a nil node whose root view will be backed by a standard UIView as with a normal UIViewController. +* +* @see ASVisibilityDepth +*/ +- (instancetype)init NS_DESIGNATED_INITIALIZER; + NS_ASSUME_NONNULL_END /** @@ -77,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface ASViewController (ASRangeControllerUpdateRangeProtocol) +@interface ASDKViewController (ASRangeControllerUpdateRangeProtocol) /** * Automatically adjust range mode based on view events. If you set this to YES, the view controller or its node diff --git a/Example/Pods/Texture/Source/ASViewController.mm b/Example/Pods/Texture/Source/ASDKViewController.mm similarity index 90% rename from Example/Pods/Texture/Source/ASViewController.mm rename to Example/Pods/Texture/Source/ASDKViewController.mm index d27f472..da4a19e 100644 --- a/Example/Pods/Texture/Source/ASViewController.mm +++ b/Example/Pods/Texture/Source/ASDKViewController.mm @@ -1,5 +1,5 @@ // -// ASViewController.mm +// ASDKViewController.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. @@ -7,16 +7,14 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import -#import +#import #import -#import #import -#import #import #import +#import -@implementation ASViewController +@implementation ASDKViewController { BOOL _ensureDisplayed; BOOL _automaticallyAdjustRangeModeBasedOnViewEvents; @@ -66,6 +64,17 @@ - (instancetype)initWithNode:(ASDisplayNode *)node return self; } +- (instancetype)init +{ + if (!(self = [super initWithNibName:nil bundle:nil])) { + return nil; + } + + [self _initializeInstance]; + + return self; +} + - (void)_initializeInstance { if (_node == nil) { @@ -96,11 +105,6 @@ - (void)_initializeInstance } } -- (void)dealloc -{ - ASPerformBackgroundDeallocation(&_node); -} - - (void)loadView { // Apple applies a frame and autoresizing masks we need. Allocating a view is not @@ -181,8 +185,8 @@ - (void)_updateNodeFallbackSafeArea - (void)viewWillAppear:(BOOL)animated { - as_activity_create_for_scope("ASViewController will appear"); - as_log_debug(ASNodeLog(), "View controller %@ will appear", self); + as_activity_create_for_scope("ASDKViewController will appear"); + os_log_debug(ASNodeLog(), "View controller %@ will appear", self); [super viewWillAppear:animated]; @@ -282,7 +286,7 @@ - (ASInterfaceState)interfaceState - (UIEdgeInsets)additionalSafeAreaInsets { - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { return super.additionalSafeAreaInsets; } @@ -291,7 +295,7 @@ - (UIEdgeInsets)additionalSafeAreaInsets - (void)setAdditionalSafeAreaInsets:(UIEdgeInsets)additionalSafeAreaInsets { - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { [super setAdditionalSafeAreaInsets:additionalSafeAreaInsets]; } else { _fallbackAdditionalSafeAreaInsets = additionalSafeAreaInsets; @@ -319,18 +323,13 @@ - (void)propagateNewTraitCollection:(ASPrimitiveTraitCollection)traitCollection ASPrimitiveTraitCollection oldTraitCollection = self.node.primitiveTraitCollection; if (ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(traitCollection, oldTraitCollection) == NO) { - as_activity_scope_verbose(as_activity_create("Propagate ASViewController trait collection", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); - as_log_debug(ASNodeLog(), "Propagating new traits for %@: %@", self, NSStringFromASPrimitiveTraitCollection(traitCollection)); - self.node.primitiveTraitCollection = traitCollection; - - NSArray> *children = [self.node sublayoutElements]; - for (id child in children) { - ASTraitCollectionPropagateDown(child, traitCollection); - } + as_activity_scope_verbose(as_activity_create("Propagate ASDKViewController trait collection", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); + os_log_debug(ASNodeLog(), "Propagating new traits for %@: %@", self, NSStringFromASPrimitiveTraitCollection(traitCollection)); + ASTraitCollectionPropagateDown(self.node, traitCollection); // Once we've propagated all the traits, layout this node. // Remeasure the node with the latest constrained size – old constrained size may be incorrect. - as_activity_scope_verbose(as_activity_create("Layout ASViewController node with new traits", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); + as_activity_scope_verbose(as_activity_create("Layout ASDKViewController node with new traits", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); [_node layoutThatFits:[self nodeConstrainedSize]]; } } diff --git a/Example/Pods/Texture/Source/ASDisplayNode+Beta.h b/Example/Pods/Texture/Source/ASDisplayNode+Beta.h index bbe66de..882042a 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+Beta.h +++ b/Example/Pods/Texture/Source/ASDisplayNode+Beta.h @@ -10,7 +10,6 @@ #import #import #import -#import #if YOGA #import YOGA_HEADER_PATH @@ -20,25 +19,13 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN void ASPerformBlockOnMainThread(void (^block)(void)); -AS_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT - -#if ASEVENTLOG_ENABLE - #define ASDisplayNodeLogEvent(node, ...) [node.eventLog logEventWithBacktrace:(AS_SAVE_EVENT_BACKTRACES ? [NSThread callStackSymbols] : nil) format:__VA_ARGS__] -#else - #define ASDisplayNodeLogEvent(node, ...) -#endif - -#if ASEVENTLOG_ENABLE - #define ASDisplayNodeGetEventLog(node) node.eventLog -#else - #define ASDisplayNodeGetEventLog(node) nil -#endif +ASDK_EXTERN void ASPerformBlockOnMainThread(void (^block)(void)); +ASDK_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT /** * Bitmask to indicate what performance measurements the cell should record. */ -typedef NS_OPTIONS(NSUInteger, ASDisplayNodePerformanceMeasurementOptions) { +typedef NS_OPTIONS(unsigned char, ASDisplayNodePerformanceMeasurementOptions) { ASDisplayNodePerformanceMeasurementOptionLayoutSpec = 1 << 0, ASDisplayNodePerformanceMeasurementOptionLayoutComputation = 1 << 1 }; @@ -96,13 +83,6 @@ typedef struct { */ @property (readonly) ASDisplayNodePerformanceMeasurements performanceMeasurements; -#if ASEVENTLOG_ENABLE -/* - * @abstract The primitive event tracing object. You shouldn't directly use it to log event. Use the ASDisplayNodeLogEvent macro instead. - */ -@property (nonatomic, readonly) ASEventLog *eventLog; -#endif - /** * @abstract Whether this node acts as an accessibility container. If set to YES, then this node's accessibility label will represent * an aggregation of all child nodes' accessibility labels. Nodes in this node's subtree that are also accessibility containers will @@ -143,7 +123,14 @@ typedef struct { * this hook could be called up to 1 + (pJPEGcount * pJPEGrenderCount) times. The render count depends on how many times the downloader calls the * progressImage block. */ -- (void)hierarchyDisplayDidFinish; +AS_CATEGORY_IMPLEMENTABLE +- (void)hierarchyDisplayDidFinish NS_REQUIRES_SUPER; + +/** + * Only called on the root during yoga layout. + */ +AS_CATEGORY_IMPLEMENTABLE +- (void)willCalculateLayout:(ASSizeRange)constrainedSize NS_REQUIRES_SUPER; /** * Only ASLayoutRangeModeVisibleOnly or ASLayoutRangeModeLowMemory are recommended. Default is ASLayoutRangeModeVisibleOnly, diff --git a/Example/Pods/Texture/Source/ASDisplayNode+Convenience.mm b/Example/Pods/Texture/Source/ASDisplayNode+Convenience.mm index 42ae4e4..c441290 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+Convenience.mm +++ b/Example/Pods/Texture/Source/ASDisplayNode+Convenience.mm @@ -9,8 +9,6 @@ #import "ASDisplayNode+Convenience.h" -#import - #import #import diff --git a/Example/Pods/Texture/Source/ASDisplayNode+InterfaceState.h b/Example/Pods/Texture/Source/ASDisplayNode+InterfaceState.h index 1de8370..96ff703 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+InterfaceState.h +++ b/Example/Pods/Texture/Source/ASDisplayNode+InterfaceState.h @@ -9,14 +9,14 @@ #import /** - * Interface state is available on ASDisplayNode and ASViewController, and + * Interface state is available on ASDisplayNode and ASDKViewController, and * allows checking whether a node is in an interface situation where it is prudent to trigger certain * actions: measurement, data loading, display, and visibility (the latter for animations or other onscreen-only effects). * * The defualt state, ASInterfaceStateNone, means that the element is not predicted to be onscreen soon and * preloading should not be performed. Swift: use [] for the default behavior. */ -typedef NS_OPTIONS(NSUInteger, ASInterfaceState) +typedef NS_OPTIONS(unsigned char, ASInterfaceState) { /** The element is not predicted to be onscreen soon and preloading should not be performed */ ASInterfaceStateNone = 0, @@ -127,4 +127,22 @@ typedef NS_OPTIONS(NSUInteger, ASInterfaceState) */ - (void)nodeWillCalculateLayout:(ASSizeRange)constrainedSize; +/** + * @abstract Called when the node's layer is about to enter the hierarchy. + * @discussion May be called more than once if the layer is participating in a higher-level + * animation, such as a UIViewController transition. These animations can cause the layer to get + * re-parented multiple times, and each time will trigger this call. + * @note This method is guaranteed to be called on main. + */ +- (void)didEnterHierarchy; + +/** + * @abstract Called when the node's layer has exited the hierarchy. + * @discussion May be called more than once if the layer is participating in a higher-level + * animation, such as a UIViewController transition. These animations can cause the layer to get + * re-parented multiple times, and each time will trigger this call. + * @note This method is guaranteed to be called on main. + */ +- (void)didExitHierarchy; + @end diff --git a/Example/Pods/Texture/Source/ASDisplayNode+Layout.mm b/Example/Pods/Texture/Source/ASDisplayNode+Layout.mm index bec21bf..ab99d3a 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+Layout.mm +++ b/Example/Pods/Texture/Source/ASDisplayNode+Layout.mm @@ -8,14 +8,30 @@ // #import +#import #import #import -#import #import #import #import #import -#import +#import +#import + +using AS::MutexLocker; + +@interface ASDisplayNode (ASLayoutElementStyleDelegate) +@end + +@implementation ASDisplayNode (ASLayoutElementStyleDelegate) + +#pragma mark + +- (void)style:(ASLayoutElementStyle *)style propertyDidChange:(NSString *)propertyName { + [self setNeedsLayout]; +} + +@end #pragma mark - ASDisplayNode (ASLayoutElement) @@ -25,7 +41,7 @@ @implementation ASDisplayNode (ASLayoutElement) - (BOOL)implementsLayoutMethod { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return (_methodOverrides & (ASDisplayNodeMethodOverrideLayoutSpecThatFits | ASDisplayNodeMethodOverrideCalcLayoutThatFits | ASDisplayNodeMethodOverrideCalcSizeThatFits)) != 0 || _layoutSpecBlock != nil; @@ -34,7 +50,7 @@ - (BOOL)implementsLayoutMethod - (ASLayoutElementStyle *)style { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_style]; } @@ -42,7 +58,12 @@ - (ASLayoutElementStyle *)_locked_style { DISABLED_ASAssertLocked(__instanceLock__); if (_style == nil) { +#if YOGA + // In Yoga mode we use the delegate to inform the tree if properties changes + _style = [[ASLayoutElementStyle alloc] initWithDelegate:self]; +#else _style = [[ASLayoutElementStyle alloc] init]; +#endif } return _style; } @@ -66,7 +87,7 @@ - (ASLayout *)layoutThatFits:(ASSizeRange)constrainedSize - (ASLayout *)layoutThatFits:(ASSizeRange)constrainedSize parentSize:(CGSize)parentSize { - ASDN::MutexLocker l(__instanceLock__); + ASScopedLockSelfOrToRoot(); // If one or multiple layout transitions are in flight it still can happen that layout information is requested // on other threads. As the pending and calculated layout to be updated in the layout transition in here just a @@ -104,16 +125,19 @@ - (ASLayout *)layoutThatFits:(ASSizeRange)constrainedSize parentSize:(CGSize)par - (ASPrimitiveTraitCollection)primitiveTraitCollection { - return _primitiveTraitCollection.load(); + AS::MutexLocker l(__instanceLock__); + return _primitiveTraitCollection; } - (void)setPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traitCollection { - if (ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(traitCollection, _primitiveTraitCollection.load()) == NO) { + AS::UniqueLock l(__instanceLock__); + if (ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(traitCollection, _primitiveTraitCollection) == NO) { + ASPrimitiveTraitCollection previousTraitCollection = _primitiveTraitCollection; _primitiveTraitCollection = traitCollection; - ASDisplayNodeLogEvent(self, @"asyncTraitCollectionDidChange: %@", NSStringFromASPrimitiveTraitCollection(traitCollection)); - [self asyncTraitCollectionDidChange]; + l.unlock(); + [self asyncTraitCollectionDidChangeWithPreviousTraitCollection:previousTraitCollection]; } } @@ -148,7 +172,7 @@ @implementation ASDisplayNode (ASLayout) - (ASLayoutEngineType)layoutEngineType { #if YOGA - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); YGNodeRef yogaNode = _style.yogaNode; BOOL hasYogaParent = (_yogaParent != nil); BOOL hasYogaChildren = (_yogaChildren.count > 0); @@ -162,13 +186,13 @@ - (ASLayoutEngineType)layoutEngineType - (ASLayout *)calculatedLayout { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _calculatedDisplayNodeLayout.layout; } - (CGSize)calculatedSize { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) { return _pendingDisplayNodeLayout.layout.size; } @@ -177,7 +201,7 @@ - (CGSize)calculatedSize - (ASSizeRange)constrainedSizeForCalculatedLayout { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_constrainedSizeForCalculatedLayout]; } @@ -241,11 +265,11 @@ - (void)_u_setNeedsLayoutFromAbove } } +// TODO It would be easier to work with if we could `ASAssertUnlocked` here, but we +// cannot due to locking to root in `_u_measureNodeWithBoundsIfNecessary`. - (void)_rootNodeDidInvalidateSize { ASDisplayNodeAssertThreadAffinity(self); - DISABLED_ASAssertUnlocked(__instanceLock__); - __instanceLock__.lock(); // We are the root node and need to re-flow the layout; at least one child needs a new size. @@ -271,11 +295,21 @@ - (void)_rootNodeDidInvalidateSize } } +// TODO +// We should remove this logic, which is relatively new, and instead +// rely on the parent / host of the root node to do this size change. That's always been the +// expectation with other node containers like ASTableView, ASCollectionView, ASDKViewController, etc. +// E.g. in ASCellNode the _interactionDelegate is a Table or Collection that will resize in this +// case. By resizing without participating with the parent, we could get cases where our parent size +// does not match, especially if there is a size constraint that is applied at that level. +// +// In general a node should never need to set its own size, instead allowing its parent to do so - +// even in the root case. Anyhow this is a separate / pre-existing issue, but I think it could be +// causing real issues in cases of resizing nodes. - (void)displayNodeDidInvalidateSizeNewSize:(CGSize)size { ASDisplayNodeAssertThreadAffinity(self); - DISABLED_ASAssertUnlocked(__instanceLock__); - + // The default implementation of display node changes the size of itself to the new size CGRect oldBounds = self.bounds; CGSize oldSize = oldBounds.size; @@ -297,8 +331,8 @@ - (void)displayNodeDidInvalidateSizeNewSize:(CGSize)size - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds { DISABLED_ASAssertUnlocked(__instanceLock__); + ASScopedLockSelfOrToRoot(); - ASDN::MutexLocker l(__instanceLock__); // Check if we are a subnode in a layout transition. // In this case no measurement is needed as it's part of the layout transition if ([self _locked_isLayoutTransitionInvalid]) { @@ -332,8 +366,8 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d", self, NSStringFromCGSize(boundsSizeForLayout), - NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size), - _calculatedDisplayNodeLayout->version < _layoutVersion); + NSStringFromCGSize(_calculatedDisplayNodeLayout.layout.size), + _calculatedDisplayNodeLayout.version < _layoutVersion); // _calculatedDisplayNodeLayout is not reusable we need to transition to a new one [self cancelLayoutTransition]; @@ -347,7 +381,7 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds // Figure out previous and pending layouts for layout transition ASDisplayNodeLayout nextLayout = _pendingDisplayNodeLayout; - #define layoutSizeDifferentFromBounds !CGSizeEqualToSize(nextLayout.layout.size, boundsSizeForLayout) + BOOL isLayoutSizeDifferentFromBounds = !CGSizeEqualToSize(nextLayout.layout.size, boundsSizeForLayout); // nextLayout was likely created by a call to layoutThatFits:, check if it is valid and can be applied. // If our bounds size is different than it, or invalid, recalculate. Use #define to avoid nullptr-> @@ -356,10 +390,10 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds as_log_verbose(ASLayoutLog(), "No pending layout."); } else if (!nextLayout.isValid(_layoutVersion)) { as_log_verbose(ASLayoutLog(), "Pending layout is stale."); - } else if (layoutSizeDifferentFromBounds) { - as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout->layout.size)); + } else if (isLayoutSizeDifferentFromBounds) { + as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout.layout.size)); } else { - as_log_verbose(ASLayoutLog(), "Using pending layout %@.", nextLayout->layout); + as_log_verbose(ASLayoutLog(), "Using pending layout %@.", nextLayout.layout); pendingLayoutApplicable = YES; } @@ -368,9 +402,19 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds // Use the last known constrainedSize passed from a parent during layout (if never, use bounds). NSUInteger version = _layoutVersion; ASSizeRange constrainedSize = [self _locked_constrainedSizeForLayoutPass]; +#if YOGA + // This flag indicates to the Texture+Yoga code that this next layout is intended to be + // displayed (vs. just for measurement). This will cause it to call setNeedsLayout on any nodes + // whose layout changes as a result of the Yoga recalculation. This is necessary because a + // change in one Yoga node can change the layout for any other node in the tree. + self.willApplyNextYogaCalculatedLayout = YES; +#endif ASLayout *layout = [self calculateLayoutThatFits:constrainedSize restrictedToSize:self.style.size relativeToParentSize:boundsSizeForLayout]; +#if YOGA + self.willApplyNextYogaCalculatedLayout = NO; +#endif nextLayout = ASDisplayNodeLayout(layout, constrainedSize, boundsSizeForLayout, version); // Now that the constrained size of pending layout might have been reused, the layout is useless // Release it and any orphaned subnodes it retains @@ -400,13 +444,23 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds __instanceLock__.lock(); } + // If we request that our root layout we may generate a new _pendingDisplayNodeLayout.layout which has + // requestedLayoutFromAbove set to NO. If the pending layout has a different constrained size than nextLayout's + // and the layout sizes don't change we could end up back here asking the root to layout again causing an + // infinite layout loop. Instead, we nil out the _pendingDisplayNodeLayout.layout here because it can be + // considered an undesired artifact of the layout request. nextLayout will become _calculatedDisplayNodeLayout + // when the pending layout transition which will be created later in this method is applied. + // We will use _calculatedLayout the next time around, so requestedLayoutFromAbove will be set to YES and we + // will break out of this layout loop. + _pendingDisplayNodeLayout.layout = nil; + // Update the layout's version here because _u_setNeedsLayoutFromAbove calls __setNeedsLayout which in turn increases _layoutVersion // Failing to do this will cause the layout to be invalid immediately nextLayout.version = _layoutVersion; } // Prepare to transition to nextLayout - ASDisplayNodeAssertNotNil(nextLayout.layout, @"nextLayout->layout should not be nil! %@", self); + ASDisplayNodeAssertNotNil(nextLayout.layout, @"nextLayout.layout should not be nil! %@", self); _pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self pendingLayout:nextLayout previousLayout:_calculatedDisplayNodeLayout]; @@ -420,7 +474,7 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds - (ASSizeRange)_constrainedSizeForLayoutPass { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_constrainedSizeForLayoutPass]; } @@ -457,10 +511,10 @@ - (void)_layoutSublayouts { ASDisplayNodeAssertThreadAffinity(self); DISABLED_ASAssertUnlocked(__instanceLock__); - + ASLayout *layout; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_calculatedDisplayNodeLayout.version < _layoutVersion) { return; } @@ -490,14 +544,14 @@ @implementation ASDisplayNode (ASAutomaticSubnodeManagement) - (BOOL)automaticallyManagesSubnodes { - ASDN::MutexLocker l(__instanceLock__); - return _automaticallyManagesSubnodes; + MutexLocker l(__instanceLock__); + return _flags.automaticallyManagesSubnodes; } - (void)setAutomaticallyManagesSubnodes:(BOOL)automaticallyManagesSubnodes { - ASDN::MutexLocker l(__instanceLock__); - _automaticallyManagesSubnodes = automaticallyManagesSubnodes; + MutexLocker l(__instanceLock__); + _flags.automaticallyManagesSubnodes = automaticallyManagesSubnodes; } @end @@ -509,7 +563,7 @@ @implementation ASDisplayNode (ASLayoutTransition) - (BOOL)_isLayoutTransitionInvalid { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_isLayoutTransitionInvalid]; } @@ -561,7 +615,7 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize { ASDisplayNodeAssertMainThread(); as_activity_create_for_scope("Transition node layout"); - as_log_debug(ASLayoutLog(), "Transition layout for %@ sizeRange %@ anim %d asyncMeasure %d", self, NSStringFromASSizeRange(constrainedSize), animated, shouldMeasureAsync); + os_log_debug(ASLayoutLog(), "Transition layout for %@ sizeRange %@ anim %d asyncMeasure %d", self, NSStringFromASSizeRange(constrainedSize), animated, shouldMeasureAsync); if (constrainedSize.max.width <= 0.0 || constrainedSize.max.height <= 0.0) { // Using CGSizeZero for the sizeRange can cause negative values in client layout code. @@ -571,7 +625,7 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize } { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); // Check if we are a subnode in a layout transition. // In this case no measurement is needed as we're part of the layout transition. @@ -597,7 +651,7 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize as_log_verbose(ASLayoutLog(), "Transition ID is %d", transitionID); // NOTE: This block captures self. It's cheaper than hitting the weak table. asdisplaynode_iscancelled_block_t isCancelled = ^{ - BOOL result = (_transitionID != transitionID); + BOOL result = (self->_transitionID != transitionID); if (result) { as_log_verbose(ASLayoutLog(), "Transition %d canceled, superseded by %d", transitionID, _transitionID.load()); } @@ -618,10 +672,10 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize } // Perform a full layout creation pass with passed in constrained size to create the new layout for the transition - NSUInteger newLayoutVersion = _layoutVersion; + NSUInteger newLayoutVersion = self->_layoutVersion; ASLayout *newLayout; { - ASDN::MutexLocker l(__instanceLock__); + ASScopedLockSelfOrToRoot(); ASLayoutElementContext *ctx = [[ASLayoutElementContext alloc] init]; ctx.transitionID = transitionID; @@ -653,10 +707,10 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize { // Grab __instanceLock__ here to make sure this transition isn't invalidated // right after it passed the validation test and before it proceeds - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(self->__instanceLock__); // Update calculated layout - const auto previousLayout = _calculatedDisplayNodeLayout; + const auto previousLayout = self->_calculatedDisplayNodeLayout; const auto pendingLayout = ASDisplayNodeLayout(newLayout, constrainedSize, constrainedSize.max, @@ -664,12 +718,12 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize [self _locked_setCalculatedDisplayNodeLayout:pendingLayout]; // Setup pending layout transition for animation - _pendingLayoutTransition = pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self + self->_pendingLayoutTransition = pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self pendingLayout:pendingLayout previousLayout:previousLayout]; // Setup context for pending layout transition. we need to hold a strong reference to the context - _pendingLayoutTransitionContext = pendingLayoutTransitionContext = [[_ASTransitionContext alloc] initWithAnimation:animated - layoutDelegate:_pendingLayoutTransition + self->_pendingLayoutTransitionContext = pendingLayoutTransitionContext = [[_ASTransitionContext alloc] initWithAnimation:animated + layoutDelegate:self->_pendingLayoutTransition completionDelegate:self]; } @@ -723,37 +777,37 @@ - (void)cancelLayoutTransition - (void)setDefaultLayoutTransitionDuration:(NSTimeInterval)defaultLayoutTransitionDuration { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _defaultLayoutTransitionDuration = defaultLayoutTransitionDuration; } - (NSTimeInterval)defaultLayoutTransitionDuration { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _defaultLayoutTransitionDuration; } - (void)setDefaultLayoutTransitionDelay:(NSTimeInterval)defaultLayoutTransitionDelay { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _defaultLayoutTransitionDelay = defaultLayoutTransitionDelay; } - (NSTimeInterval)defaultLayoutTransitionDelay { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _defaultLayoutTransitionDelay; } - (void)setDefaultLayoutTransitionOptions:(UIViewAnimationOptions)defaultLayoutTransitionOptions { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _defaultLayoutTransitionOptions = defaultLayoutTransitionOptions; } - (UIViewAnimationOptions)defaultLayoutTransitionOptions { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _defaultLayoutTransitionOptions; } @@ -915,35 +969,40 @@ - (void)_assertSubnodeState return; } - NSArray *subnodes = [self subnodes]; - NSArray *sublayouts = _calculatedDisplayNodeLayout.layout.sublayouts; - - const auto currentSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality - capacity:subnodes.count]; - const auto layoutSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality - capacity:sublayouts.count];; - for (ASDisplayNode *subnode in subnodes) { - [currentSubnodes addObject:subnode]; - } - - for (ASLayout *sublayout in sublayouts) { - id layoutElement = sublayout.layoutElement; - ASDisplayNodeAssert([layoutElement isKindOfClass:[ASDisplayNode class]], - @"All calculatedLayouts should be flattened and only contain nodes!"); - [layoutSubnodes addObject:(ASDisplayNode *)layoutElement]; + MutexLocker l(__instanceLock__); + NSArray *sublayouts = _calculatedDisplayNodeLayout.layout.sublayouts; + unowned ASLayout *cSublayouts[sublayouts.count]; + [sublayouts getObjects:cSublayouts range:NSMakeRange(0, AS_ARRAY_SIZE(cSublayouts))]; + + // Fast-path if we are in the correct state (likely). + if (_subnodes.count == AS_ARRAY_SIZE(cSublayouts)) { + NSUInteger i = 0; + BOOL matches = YES; + for (ASDisplayNode *subnode in _subnodes) { + if (subnode != cSublayouts[i].layoutElement) { + matches = NO; + } + i++; + } + if (matches) { + return; + } } - // Verify that all subnodes that occur in the current ASLayout tree are present in .subnodes array. - if ([layoutSubnodes isSubsetOfHashTable:currentSubnodes] == NO) { - // Note: This should be converted to an assertion after confirming it is rare. - NSLog(@"Warning: node's layout includes subnodes that have not been added: node = %@, subnodes = %@, subnodes in layout = %@", self, currentSubnodes, layoutSubnodes); + NSArray *layoutNodes = ASArrayByFlatMapping(sublayouts, ASLayout *layout, (ASDisplayNode *)layout.layoutElement); + NSIndexSet *insertions, *deletions; + [_subnodes asdk_diffWithArray:layoutNodes insertions:&insertions deletions:&deletions]; + if (insertions.count > 0) { + NSLog(@"Warning: node's layout includes subnode that has not been added: node = %@, subnodes = %@, subnodes in layout = %@", self, _subnodes, layoutNodes); } - // Verify that everything in the .subnodes array is present in the ASLayout tree (and correct it if not). - [currentSubnodes minusHashTable:layoutSubnodes]; - for (ASDisplayNode *orphanedSubnode in currentSubnodes) { - NSLog(@"Automatically removing orphaned subnode %@, from parent %@", orphanedSubnode, self); - [orphanedSubnode removeFromSupernode]; + // Remove any nodes that are in the tree but should not be. + // Go in reverse order so we don't shift our indexes. + if (deletions) { + for (NSUInteger i = deletions.lastIndex; i != NSNotFound; i = [deletions indexLessThanIndex:i]) { + NSLog(@"Automatically removing orphaned subnode %@, from parent %@", _subnodes[i], self); + [_subnodes[i] removeFromSupernode]; + } } } @@ -961,12 +1020,12 @@ - (void)_pendingLayoutTransitionDidComplete [self calculatedLayoutDidChange]; // Grab lock after calling out to subclass - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); // We generate placeholders at -layoutThatFits: time so that a node is guaranteed to have a placeholder ready to go. // This is also because measurement is usually asynchronous, but placeholders need to be set up synchronously. // First measurement is guaranteed to be before the node is onscreen, so we can create the image async. but still have it appear sync. - if (_placeholderEnabled && !_placeholderImage && [self _locked_displaysAsynchronously]) { + if (_flags.placeholderEnabled && !_placeholderImage && [self _locked_displaysAsynchronously]) { // Zero-sized nodes do not require a placeholder. CGSize layoutSize = _calculatedDisplayNodeLayout.layout.size; @@ -979,7 +1038,7 @@ - (void)_pendingLayoutTransitionDidComplete if (self.isNodeLoaded) { ASPerformBlockOnMainThread(^{ if (self.contents == nil) { - _placeholderImage = [self placeholderImage]; + self->_placeholderImage = [self placeholderImage]; } }); } else { @@ -995,7 +1054,7 @@ - (void)_pendingLayoutTransitionDidComplete - (void)_setCalculatedDisplayNodeLayout:(const ASDisplayNodeLayout &)displayNodeLayout { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); [self _locked_setCalculatedDisplayNodeLayout:displayNodeLayout]; } @@ -1010,3 +1069,30 @@ - (void)_locked_setCalculatedDisplayNodeLayout:(const ASDisplayNodeLayout &)disp } @end + +#pragma mark - +#pragma mark - ASDisplayNode (YogaLayout) + +@implementation ASDisplayNode (YogaLayout) + +- (BOOL)locked_shouldLayoutFromYogaRoot { +#if YOGA + YGNodeRef yogaNode = _style.yogaNode; + BOOL hasYogaParent = (_yogaParent != nil); + BOOL hasYogaChildren = (_yogaChildren.count > 0); + BOOL usesYoga = (yogaNode != NULL && (hasYogaParent || hasYogaChildren)); + if (usesYoga) { + if ([self shouldHaveYogaMeasureFunc] == NO) { + return YES; + } else { + return NO; + } + } else { + return NO; + } +#else + return NO; +#endif +} + +@end diff --git a/Example/Pods/Texture/Source/ASDisplayNode+LayoutSpec.mm b/Example/Pods/Texture/Source/ASDisplayNode+LayoutSpec.mm index 0fb3060..93ce0e6 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+LayoutSpec.mm +++ b/Example/Pods/Texture/Source/ASDisplayNode+LayoutSpec.mm @@ -7,7 +7,6 @@ // #import -#import #import #import @@ -15,8 +14,6 @@ #import #import #import -#import -#import @implementation ASDisplayNode (ASLayoutSpec) @@ -26,24 +23,23 @@ - (void)setLayoutSpecBlock:(ASLayoutSpecBlock)layoutSpecBlock // For now there should never be an override of layoutSpecThatFits: and a layoutSpecBlock together. ASDisplayNodeAssert(!(_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits), @"Nodes with a .layoutSpecBlock must not also implement -layoutSpecThatFits:"); - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); _layoutSpecBlock = layoutSpecBlock; } - (ASLayoutSpecBlock)layoutSpecBlock { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); return _layoutSpecBlock; } - (ASLayout *)calculateLayoutLayoutSpec:(ASSizeRange)constrainedSize { - ASDN::UniqueLock l(__instanceLock__); + AS::UniqueLock l(__instanceLock__); // Manual size calculation via calculateSizeThatFits: if (_layoutSpecBlock == NULL && (_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits) == 0) { CGSize size = [self calculateSizeThatFits:constrainedSize.max]; - ASDisplayNodeLogEvent(self, @"calculatedSize: %@", NSStringFromCGSize(size)); return [ASLayout layoutWithLayoutElement:self size:ASSizeRangeClamp(constrainedSize, size) sublayouts:nil]; } @@ -82,7 +78,7 @@ - (ASLayout *)calculateLayoutLayoutSpec:(ASSizeRange)constrainedSize // Manually propagate the trait collection here so that any layoutSpec children of layoutSpec will get a traitCollection { - ASDN::SumScopeTimer t(_layoutSpecTotalTime, measureLayoutSpec); + AS::SumScopeTimer t(_layoutSpecTotalTime, measureLayoutSpec); ASTraitCollectionPropagateDown(layoutElement, self.primitiveTraitCollection); } @@ -93,7 +89,7 @@ - (ASLayout *)calculateLayoutLayoutSpec:(ASSizeRange)constrainedSize // Layout element layout creation ASLayout *layout = ({ - ASDN::SumScopeTimer t(_layoutComputationTotalTime, measureLayoutComputation); + AS::SumScopeTimer t(_layoutComputationTotalTime, measureLayoutComputation); [layoutElement layoutThatFits:constrainedSize]; }); ASDisplayNodeAssertNotNil(layout, @"[ASLayoutElement layoutThatFits:] should never return nil! %@, %@", self, layout); @@ -104,7 +100,6 @@ - (ASLayout *)calculateLayoutLayoutSpec:(ASSizeRange)constrainedSize layout.position = CGPointZero; layout = [ASLayout layoutWithLayoutElement:self size:layout.size sublayouts:@[layout]]; } - ASDisplayNodeLogEvent(self, @"computedLayout: %@", layout); // PR #1157: Reduces accuracy of _unflattenedLayout for debugging/Weaver if ([ASDisplayNode shouldStoreUnflattenedLayouts]) { @@ -123,13 +118,13 @@ - (ASLayout *)calculateLayoutLayoutSpec:(ASSizeRange)constrainedSize if (_layoutSpecBlock != NULL) { return ({ - ASDN::MutexLocker l(__instanceLock__); - ASDN::SumScopeTimer t(_layoutSpecTotalTime, measureLayoutSpec); + AS::MutexLocker l(__instanceLock__); + AS::SumScopeTimer t(_layoutSpecTotalTime, measureLayoutSpec); _layoutSpecBlock(self, constrainedSize); }); } else { return ({ - ASDN::SumScopeTimer t(_layoutSpecTotalTime, measureLayoutSpec); + AS::SumScopeTimer t(_layoutSpecTotalTime, measureLayoutSpec); [self layoutSpecThatFits:constrainedSize]; }); } diff --git a/Example/Pods/Texture/Source/ASDisplayNode+Subclasses.h b/Example/Pods/Texture/Source/ASDisplayNode+Subclasses.h index 8a2d7b3..9adb933 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+Subclasses.h +++ b/Example/Pods/Texture/Source/ASDisplayNode+Subclasses.h @@ -10,6 +10,7 @@ #import #import #import +#import @class ASLayoutSpec, _ASDisplayLayer; @@ -69,8 +70,22 @@ NS_ASSUME_NONNULL_BEGIN * * @discussion This is the best time to add gesture recognizers to the view. */ +AS_CATEGORY_IMPLEMENTABLE - (void)didLoad ASDISPLAYNODE_REQUIRES_SUPER; +/** + * An empty method that you can implement in a category to add global + * node initialization behavior. This method will be called by [ASDisplayNode init]. + */ +AS_CATEGORY_IMPLEMENTABLE +- (void)baseDidInit; + +/** + * An empty method that you can implement in a category to add global + * node deallocation behavior. This method will be called by [ASDisplayNode dealloc]. + */ +AS_CATEGORY_IMPLEMENTABLE +- (void)baseWillDealloc; #pragma mark - Layout /** @name Layout */ @@ -88,6 +103,7 @@ NS_ASSUME_NONNULL_BEGIN * @discussion Gives a chance for subclasses to perform actions after the subclass and superclass have finished laying * out. */ +AS_CATEGORY_IMPLEMENTABLE - (void)layoutDidFinish ASDISPLAYNODE_REQUIRES_SUPER; /** @@ -96,6 +112,7 @@ NS_ASSUME_NONNULL_BEGIN * @discussion When the .calculatedLayout property is set to a new ASLayout (directly from -calculateLayoutThatFits: or * calculated via use of -layoutSpecThatFits:), subclasses may inspect it here. */ +AS_CATEGORY_IMPLEMENTABLE - (void)calculatedLayoutDidChange ASDISPLAYNODE_REQUIRES_SUPER; @@ -162,15 +179,25 @@ NS_ASSUME_NONNULL_BEGIN * For descriptions, see definition. */ +AS_CATEGORY_IMPLEMENTABLE - (void)didEnterVisibleState ASDISPLAYNODE_REQUIRES_SUPER; + +AS_CATEGORY_IMPLEMENTABLE - (void)didExitVisibleState ASDISPLAYNODE_REQUIRES_SUPER; +AS_CATEGORY_IMPLEMENTABLE - (void)didEnterDisplayState ASDISPLAYNODE_REQUIRES_SUPER; + +AS_CATEGORY_IMPLEMENTABLE - (void)didExitDisplayState ASDISPLAYNODE_REQUIRES_SUPER; +AS_CATEGORY_IMPLEMENTABLE - (void)didEnterPreloadState ASDISPLAYNODE_REQUIRES_SUPER; + +AS_CATEGORY_IMPLEMENTABLE - (void)didExitPreloadState ASDISPLAYNODE_REQUIRES_SUPER; +AS_CATEGORY_IMPLEMENTABLE - (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState ASDISPLAYNODE_REQUIRES_SUPER; @@ -178,8 +205,11 @@ NS_ASSUME_NONNULL_BEGIN * @abstract Called when the node's ASTraitCollection changes * * @discussion Subclasses can override this method to react to a trait collection change. + * + * @param previousTraitCollection The ASPrimitiveTraitCollection object before the interface environment changed. */ -- (void)asyncTraitCollectionDidChange; +AS_CATEGORY_IMPLEMENTABLE +- (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection ASDISPLAYNODE_REQUIRES_SUPER; #pragma mark - Drawing /** @name Drawing */ @@ -349,6 +379,13 @@ NS_ASSUME_NONNULL_BEGIN */ @property (readonly) CGFloat contentsScaleForDisplay; +/** + * Called as part of actionForLayer:forKey:. Gives the node a chance to provide a custom action for its layer. + * + * The default implementation returns NSNull, indicating that no action should be taken. + */ +AS_CATEGORY_IMPLEMENTABLE +- (nullable id)layerActionForKey:(NSString *)event; #pragma mark - Touch handling /** @name Touch handling */ diff --git a/Example/Pods/Texture/Source/ASDisplayNode+Yoga.h b/Example/Pods/Texture/Source/ASDisplayNode+Yoga.h index 14b7769..000bb90 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+Yoga.h +++ b/Example/Pods/Texture/Source/ASDisplayNode+Yoga.h @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @class ASLayout; -AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullable node, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullable node, void(^block)(ASDisplayNode *node)); @interface ASDisplayNode (Yoga) @@ -29,10 +29,21 @@ AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullab @property BOOL yogaLayoutInProgress; // TODO: Make this atomic (lock). @property (nullable, nonatomic) ASLayout *yogaCalculatedLayout; +@property (nonatomic) BOOL willApplyNextYogaCalculatedLayout; // Will walk up the Yoga tree and returns the root node - (ASDisplayNode *)yogaRoot; + +@end + +@interface ASDisplayNode (YogaLocking) +/** + * @discussion Attempts(spinning) to lock all node up to root node when yoga is enabled. + * This will lock self when yoga is not enabled; + */ +- (ASLockSet)lockToRootIfNeededForLayout; + @end @@ -44,9 +55,14 @@ AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullab /// For internal usage only - (ASLayout *)calculateLayoutYoga:(ASSizeRange)constrainedSize; /// For internal usage only -- (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize; +- (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize willApply:(BOOL)willApply; /// For internal usage only - (void)invalidateCalculatedYogaLayout; +/** + * @discussion return true only when yoga enabled and the node is in yoga tree and the node is + * not leaf that implemented measure function. + */ +- (BOOL)locked_shouldLayoutFromYogaRoot; @end @@ -79,4 +95,9 @@ AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullab NS_ASSUME_NONNULL_END +// When Yoga is enabled, there are several points where we want to lock the tree to the root but otherwise (without Yoga) +// will want to simply lock self. +#define ASScopedLockSelfOrToRoot() ASScopedLockSet lockSet = [self lockToRootIfNeededForLayout] +#else +#define ASScopedLockSelfOrToRoot() ASLockScopeSelf() #endif diff --git a/Example/Pods/Texture/Source/ASDisplayNode+Yoga.mm b/Example/Pods/Texture/Source/ASDisplayNode+Yoga.mm index dffe67b..619f5a7 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode+Yoga.mm +++ b/Example/Pods/Texture/Source/ASDisplayNode+Yoga.mm @@ -11,15 +11,17 @@ #if YOGA /* YOGA */ -#import +#import #import #import #import +#import #import #import #import #import #import +#import #import @@ -27,7 +29,7 @@ #pragma mark - ASDisplayNode+Yoga -@interface ASDisplayNode (YogaInternal) +@interface ASDisplayNode (YogaPrivate) @property (nonatomic, weak) ASDisplayNode *yogaParent; - (ASSizeRange)_locked_constrainedSizeForLayoutPass; @end @@ -46,7 +48,7 @@ - (ASDisplayNode *)yogaRoot - (void)setYogaChildren:(NSArray *)yogaChildren { - ASLockScope(self.yogaRoot); + ASScopedLockSelfOrToRoot(); for (ASDisplayNode *child in [_yogaChildren copy]) { // Make sure to un-associate the YGNodeRef tree before replacing _yogaChildren // If this becomes a performance bottleneck, it can be optimized by not doing the NSArray removals here. @@ -66,7 +68,7 @@ - (NSArray *)yogaChildren - (void)addYogaChild:(ASDisplayNode *)child { - ASLockScope(self.yogaRoot); + ASScopedLockSelfOrToRoot(); [self _locked_addYogaChild:child]; } @@ -77,7 +79,7 @@ - (void)_locked_addYogaChild:(ASDisplayNode *)child - (void)removeYogaChild:(ASDisplayNode *)child { - ASLockScope(self.yogaRoot); + ASScopedLockSelfOrToRoot(); [self _locked_removeYogaChild:child]; } @@ -91,11 +93,12 @@ - (void)_locked_removeYogaChild:(ASDisplayNode *)child // YGNodeRef removal is done in setParent: child.yogaParent = nil; + [self setNeedsLayout]; } - (void)insertYogaChild:(ASDisplayNode *)child atIndex:(NSUInteger)index { - ASLockScope(self.yogaRoot); + ASScopedLockSelfOrToRoot(); [self _locked_insertYogaChild:child atIndex:index]; } @@ -115,6 +118,7 @@ - (void)_locked_insertYogaChild:(ASDisplayNode *)child atIndex:(NSUInteger)index // YGNodeRef insertion is done in setParent: child.yogaParent = self; + [self setNeedsLayout]; } #pragma mark - Subclass Hooks @@ -129,6 +133,7 @@ - (void)semanticContentAttributeDidChange:(UISemanticContentAttribute)attribute - (void)setYogaParent:(ASDisplayNode *)yogaParent { + ASLockScopeSelf(); if (_yogaParent == yogaParent) { return; } @@ -161,6 +166,14 @@ - (ASLayout *)yogaCalculatedLayout return _yogaCalculatedLayout; } +- (BOOL)willApplyNextYogaCalculatedLayout { + return _flags.willApplyNextYogaCalculatedLayout; +} + +- (void)setWillApplyNextYogaCalculatedLayout:(BOOL)willApplyNextYogaCalculatedLayout { + _flags.willApplyNextYogaCalculatedLayout = willApplyNextYogaCalculatedLayout; +} + - (void)setYogaLayoutInProgress:(BOOL)yogaLayoutInProgress { setFlag(YogaLayoutInProgress, yogaLayoutInProgress); @@ -179,12 +192,19 @@ - (ASLayout *)layoutForYogaNode CGSize size = CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode)); CGPoint position = CGPointMake(YGNodeLayoutGetLeft(yogaNode), YGNodeLayoutGetTop(yogaNode)); + if (!ASIsCGSizeValidForSize(size)) { + size = CGSizeZero; + } + + if (!ASIsCGPositionValidForLayout(position)) { + position = CGPointZero; + } return [ASLayout layoutWithLayoutElement:self size:size position:position sublayouts:nil]; } -- (void)setupYogaCalculatedLayout +- (void)setupYogaCalculatedLayoutAndSetNeedsLayoutForChangedNodes:(BOOL)setNeedsLayoutForChangedNodes { - ASLockScopeSelf(); + ASScopedLockSelfOrToRoot(); YGNodeRef yogaNode = self.style.yogaNode; uint32_t childCount = YGNodeGetChildCount(yogaNode); @@ -194,13 +214,16 @@ - (void)setupYogaCalculatedLayout ASLayout *rawSublayouts[childCount]; int i = 0; - for (ASDisplayNode *subnode in self.yogaChildren) { + for (ASDisplayNode *subnode in _yogaChildren) { rawSublayouts[i++] = [subnode layoutForYogaNode]; } const auto sublayouts = [NSArray arrayByTransferring:rawSublayouts count:childCount]; // The layout for self should have position CGPointNull, but include the calculated size. CGSize size = CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode)); + if (!ASIsCGSizeValidForSize(size)) { + size = CGSizeZero; + } ASLayout *layout = [ASLayout layoutWithLayoutElement:self size:size sublayouts:sublayouts]; #if ASDISPLAYNODE_ASSERTIONS_ENABLED @@ -216,6 +239,13 @@ - (void)setupYogaCalculatedLayout layout = [layout filteredNodeLayoutTree]; if ([self.yogaCalculatedLayout isEqual:layout] == NO) { + if (setNeedsLayoutForChangedNodes && !self.willApplyNextYogaCalculatedLayout) { + // This flag will be set when this layout is intended for immediate display. In this case, we + // want to ensure that we call setNeedsLayout on any other nodes. Note that we skip any nodes + // whose willApplyNextYogaCalculatedLayout flags are set, as those are the nodes that are + // already being laid out. + [self setNeedsLayout]; + } self.yogaCalculatedLayout = layout; } else { layout = self.yogaCalculatedLayout; @@ -251,10 +281,11 @@ - (void)setupYogaCalculatedLayout - (BOOL)shouldHaveYogaMeasureFunc { + ASLockScopeSelf(); // Size calculation via calculateSizeThatFits: or layoutSpecThatFits: // For these nodes, we assume they may need custom Baseline calculation too. // This will be used for ASTextNode, as well as any other node that has no Yoga children - BOOL isLeafNode = (self.yogaChildren.count == 0); + BOOL isLeafNode = (_yogaChildren.count == 0); BOOL definesCustomLayout = [self implementsLayoutMethod]; return (isLeafNode && definesCustomLayout); } @@ -270,6 +301,7 @@ - (void)updateYogaMeasureFuncIfNeeded - (void)invalidateCalculatedYogaLayout { + ASLockScopeSelf(); YGNodeRef yogaNode = self.style.yogaNode; if (yogaNode && [self shouldHaveYogaMeasureFunc]) { // Yoga internally asserts that MarkDirty() may only be called on nodes with a measurement function. @@ -289,63 +321,60 @@ - (void)invalidateCalculatedYogaLayout - (ASLayout *)calculateLayoutYoga:(ASSizeRange)constrainedSize { - ASDN::UniqueLock l(__instanceLock__); + AS::UniqueLock l(__instanceLock__); // There are several cases where Yoga could arrive here: // - This node is not in a Yoga tree: it has neither a yogaParent nor yogaChildren. // - This node is a Yoga tree root: it has no yogaParent, but has yogaChildren. // - This node is a Yoga tree node: it has both a yogaParent and yogaChildren. // - This node is a Yoga tree leaf: it has a yogaParent, but no yogaChidlren. - YGNodeRef yogaNode = _style.yogaNode; - BOOL hasYogaParent = (_yogaParent != nil); - BOOL hasYogaChildren = (_yogaChildren.count > 0); - BOOL usesYoga = (yogaNode != NULL && (hasYogaParent || hasYogaChildren)); - if (usesYoga) { - // This node has some connection to a Yoga tree. - if ([self shouldHaveYogaMeasureFunc] == NO) { - // If we're a yoga root, tree node, or leaf with no measure func (e.g. spacer), then - // initiate a new Yoga calculation pass from root. - - as_activity_create_for_scope("Yoga layout calculation"); - if (self.yogaLayoutInProgress == NO) { - ASYogaLog("Calculating yoga layout from root %@, %@", self, NSStringFromASSizeRange(constrainedSize)); - l.unlock(); - [self calculateLayoutFromYogaRoot:constrainedSize]; - l.lock(); - } else { - ASYogaLog("Reusing existing yoga layout %@", _yogaCalculatedLayout); - } - ASDisplayNodeAssert(_yogaCalculatedLayout, @"Yoga node should have a non-nil layout at this stage: %@", self); - return _yogaCalculatedLayout; + if ([self locked_shouldLayoutFromYogaRoot]) { + // If we're a yoga root, tree node, or leaf with no measure func (e.g. spacer), then + // initiate a new Yoga calculation pass from root. + as_activity_create_for_scope("Yoga layout calculation"); + if (self.yogaLayoutInProgress == NO) { + ASYogaLog("Calculating yoga layout from root %@, %@", self, + NSStringFromASSizeRange(constrainedSize)); + [self calculateLayoutFromYogaRoot:constrainedSize willApply:self.willApplyNextYogaCalculatedLayout]; } else { - // If we're a yoga leaf node with custom measurement function, proceed with normal layout so layoutSpecs can run (e.g. ASButtonNode). - ASYogaLog("PROCEEDING past Yoga check to calculate ASLayout for: %@", self); + ASYogaLog("Reusing existing yoga layout %@", _yogaCalculatedLayout); } + ASDisplayNodeAssert(_yogaCalculatedLayout, + @"Yoga node should have a non-nil layout at this stage: %@", self); + return _yogaCalculatedLayout; + } else { + // If we're a yoga leaf node with custom measurement function, proceed with normal layout so + // layoutSpecs can run (e.g. ASButtonNode). + ASYogaLog("PROCEEDING past Yoga check to calculate ASLayout for: %@", self); } // Delegate to layout spec layout for nodes that do not support Yoga return [self calculateLayoutLayoutSpec:constrainedSize]; } -- (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize +- (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize willApply:(BOOL)willApply { + ASScopedLockSet lockSet = [self lockToRootIfNeededForLayout]; ASDisplayNode *yogaRoot = self.yogaRoot; if (self != yogaRoot) { ASYogaLog("ESCALATING to Yoga root: %@", self); // TODO(appleguy): Consider how to get the constrainedSize for the yogaRoot when escalating manually. - [yogaRoot calculateLayoutFromYogaRoot:ASSizeRangeUnconstrained]; + [yogaRoot calculateLayoutFromYogaRoot:ASSizeRangeUnconstrained willApply:willApply]; return; } + if (ASSizeRangeEqualToSizeRange(rootConstrainedSize, ASSizeRangeUnconstrained)) { + rootConstrainedSize = [self _locked_constrainedSizeForLayoutPass]; + } + + [self willCalculateLayout:rootConstrainedSize]; [self enumerateInterfaceStateDelegates:^(id _Nonnull delegate) { if ([delegate respondsToSelector:@selector(nodeWillCalculateLayout:)]) { [delegate nodeWillCalculateLayout:rootConstrainedSize]; } }]; - ASLockScopeSelf(); - // Prepare all children for the layout pass with the current Yoga tree configuration. ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode *_Nonnull node) { node.yogaLayoutInProgress = YES; @@ -357,10 +386,6 @@ - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize }; }); - if (ASSizeRangeEqualToSizeRange(rootConstrainedSize, ASSizeRangeUnconstrained)) { - rootConstrainedSize = [self _locked_constrainedSizeForLayoutPass]; - } - ASYogaLog("CALCULATING at Yoga root with constraint = {%@, %@}: %@", NSStringFromCGSize(rootConstrainedSize.min), NSStringFromCGSize(rootConstrainedSize.max), self); @@ -383,12 +408,12 @@ - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize // Reset accessible elements, since layout may have changed. ASPerformBlockOnMainThread(^{ if (self.nodeLoaded && !self.isSynchronous) { - [(_ASDisplayView *)self.view setAccessibilityElements:nil]; + self.view.accessibilityElements = nil; } }); ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode * _Nonnull node) { - [node setupYogaCalculatedLayout]; + [node setupYogaCalculatedLayoutAndSetNeedsLayoutForChangedNodes:willApply]; node.yogaLayoutInProgress = NO; }); @@ -400,11 +425,10 @@ - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize NSLog(@"******************** STARTING YOGA -> ASLAYOUT CREATION ********************"); NSLog(@"****************************************************************************"); ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode * _Nonnull node) { - NSLog(@" "); // Newline NSLog(@"node = %@", node); - NSLog(@"style = %@", node.style); - NSLog(@"layout = %@", node.yogaCalculatedLayout); - YGNodePrint(node.yogaNode, (YGPrintOptions)(YGPrintOptionsStyle | YGPrintOptionsLayout)); + YGNodePrint(node.style.yogaNode, (YGPrintOptions)(YGPrintOptionsStyle | YGPrintOptionsLayout)); + NSCAssert(ASIsCGSizeValidForSize(node.yogaCalculatedLayout.size), @"Yoga layout returned an invalid size"); + NSLog(@" "); // Newline }); } #endif /* YOGA_LAYOUT_LOGGING */ @@ -412,6 +436,40 @@ - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize @end +#pragma mark - ASDisplayNode (YogaLocking) + +@implementation ASDisplayNode (YogaLocking) + +- (ASLockSet)lockToRootIfNeededForLayout { + ASLockSet lockSet = ASLockSequence(^BOOL(ASAddLockBlock addLock) { + if (!addLock(self)) { + return NO; + } +#if YOGA + if (![self locked_shouldLayoutFromYogaRoot]) { + return YES; + } + if (self.nodeController && !addLock(self.nodeController)) { + return NO; + } + ASDisplayNode *parent = _supernode; + while (parent) { + if (!addLock(parent)) { + return NO; + } + if (parent.nodeController && !addLock(parent.nodeController)) { + return NO; + } + parent = parent->_supernode; + } +#endif + return true; + }); + return lockSet; +} + +@end + @implementation ASDisplayNode (YogaDebugging) - (NSString *)yogaTreeDescription { diff --git a/Example/Pods/Texture/Source/ASDisplayNode.h b/Example/Pods/Texture/Source/ASDisplayNode.h index 0649f2d..eff930c 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode.h +++ b/Example/Pods/Texture/Source/ASDisplayNode.h @@ -67,7 +67,7 @@ typedef ASLayoutSpec * _Nonnull(^ASLayoutSpecBlock)(__kindof ASDisplayNode *node */ typedef void (^ASDisplayNodeNonFatalErrorBlock)(NSError *error); -typedef NS_ENUM(NSInteger, ASCornerRoundingType) { +typedef NS_ENUM(unsigned char, ASCornerRoundingType) { ASCornerRoundingTypeDefaultSlowCALayer, ASCornerRoundingTypePrecomposited, ASCornerRoundingTypeClipping @@ -76,7 +76,7 @@ typedef NS_ENUM(NSInteger, ASCornerRoundingType) { /** * Default drawing priority for display node */ -AS_EXTERN NSInteger const ASDefaultDrawingPriority; +ASDK_EXTERN NSInteger const ASDefaultDrawingPriority; /** * An `ASDisplayNode` is an abstraction over `UIView` and `CALayer` that allows you to perform calculations about a view @@ -94,7 +94,15 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; * */ -@interface ASDisplayNode : NSObject +@interface ASDisplayNode : NSObject { +@public + /** + * The _displayNodeContext ivar is unused by Texture, but provided to enable advanced clients to make powerful extensions to base class functionality. + * For example, _displayNodeContext can be used to implement category methods on ASDisplayNode that add functionality to all node subclass types. + * Code demonstrating this technique can be found in the CatDealsCollectionView example. + */ + void *_displayNodeContext; +} /** @name Initializing a node object */ @@ -640,9 +648,9 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; * more efficient than CALayer. The only limitation of this approach is that it cannot clip children, and * thus works best for ASImageNodes or containers showing a background around their children. * - * - ASCornerRoundingTypeClipping: overlays 4 seperate opaque corners on top of the content that needs - * corner rounding. Requires .backgroundColor and .cornerRadius to be set. Use clip corners in situations - * in which is movement through the corner, with an opaque background (no movement underneath the corner). + * - ASCornerRoundingTypeClipping: overlays 4 separate opaque corners on top of the content that needs + * corner rounding. Requires .backgroundColor and .cornerRadius to be set. Use clip corners in situations + * where there is movement through the corner, with an opaque background (no movement underneath the corner). * Clipped corners are ideal for animating / resizing views, and still outperform CALayer. * * For more information and examples, see http://texturegroup.org/docs/corner-rounding.html @@ -658,6 +666,14 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; */ @property CGFloat cornerRadius; // default=0.0 +/** @abstract Which corners to mask when rounding corners. + * + * @note This option cannot be changed when using iOS < 11 + * and using ASCornerRoundingTypeDefaultSlowCALayer. Use a different corner rounding type to implement not-all-corners + * rounding in prior versions of iOS. + */ +@property CACornerMask maskedCorners; // default=all corners. + @property BOOL clipsToBounds; // default==NO @property (getter=isHidden) BOOL hidden; // default==NO @property (getter=isOpaque) BOOL opaque; // default==YES @@ -678,6 +694,8 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; @property (getter=isExclusiveTouch) BOOL exclusiveTouch; // default=NO #endif +@property (nullable, copy) NSDictionary> *actions; // default = nil + /** * @abstract The node view's background color. * @@ -687,7 +705,13 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; @property (nullable, copy) UIColor *backgroundColor; // default=nil @property (null_resettable, copy) UIColor *tintColor; // default=Blue -- (void)tintColorDidChange; // Notifies the node when the tintColor has changed. + +/** + * Notifies the node when the tintColor has changed. + * + * @note This method is guaranteed to be called if the tintColor is changed after the node loaded. + */ +- (void)tintColorDidChange; /** * @abstract A flag used to determine how a node lays out its content when its bounds change. @@ -710,7 +734,7 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; @property BOOL allowsGroupOpacity; @property BOOL allowsEdgeAntialiasing; -@property unsigned int edgeAntialiasingMask; // default==all values from CAEdgeAntialiasingMask +@property CAEdgeAntialiasingMask edgeAntialiasingMask; // default==all values from CAEdgeAntialiasingMask @property BOOL needsDisplayOnBoundsChange; // default==NO @property BOOL autoresizesSubviews; // default==YES (undefined for layer-backed nodes) @@ -783,6 +807,7 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority; @property BOOL accessibilityViewIsModal; @property BOOL shouldGroupAccessibilityChildren; @property UIAccessibilityNavigationStyle accessibilityNavigationStyle; +@property (nullable, copy) NSArray *accessibilityCustomActions API_AVAILABLE(ios(8.0),tvos(9.0)); #if TARGET_OS_TV @property (nullable, copy) NSArray *accessibilityHeaderElements; #endif diff --git a/Example/Pods/Texture/Source/ASDisplayNode.mm b/Example/Pods/Texture/Source/ASDisplayNode.mm index 6055884..abb339b 100644 --- a/Example/Pods/Texture/Source/ASDisplayNode.mm +++ b/Example/Pods/Texture/Source/ASDisplayNode.mm @@ -10,14 +10,10 @@ #import #import -#import #import -#import #import #import -#import - #import #import #import @@ -25,32 +21,23 @@ #import #import #import -#import #import -#import #import -#import -#import #import #import #import #import #import -#import -#import -#import #import #import #import #import -#import #import #import -#import // Conditionally time these scopes to our debug ivars (only exist in debug/profile builds) #if TIME_DISPLAYNODE_OPS - #define TIME_SCOPED(outVar) ASDN::ScopeTimer t(outVar) + #define TIME_SCOPED(outVar) AS::ScopeTimer t(outVar) #else #define TIME_SCOPED(outVar) #endif @@ -59,13 +46,11 @@ // TODO(wsdwsd0829): Rework enabling code to ensure that interface state behavior is not altered when ASCATransactionQueue is disabled. #define ENABLE_NEW_EXIT_HIERARCHY_BEHAVIOR 0 -static ASDisplayNodeNonFatalErrorBlock _nonFatalErrorBlock = nil; +using AS::MutexLocker; -// Forward declare CALayerDelegate protocol as the iOS 10 SDK moves CALayerDelegate from an informal delegate to a protocol. -// We have to forward declare the protocol as this place otherwise it will not compile compiling with an Base SDK < iOS 10 -@protocol CALayerDelegate; +static ASDisplayNodeNonFatalErrorBlock _nonFatalErrorBlock = nil; -@interface ASDisplayNode () +@interface ASDisplayNode () /** * See ASDisplayNodeInternal.h for ivars */ @@ -104,6 +89,14 @@ BOOL ASDisplayNodeNeedsSpecialPropertiesHandling(BOOL isSynchronous, BOOL isLaye return result; } +void StubImplementationWithNoArgs(id receiver, SEL _cmd) {} +void StubImplementationWithSizeRange(id receiver, SEL _cmd, ASSizeRange sr) {} +void StubImplementationWithTwoInterfaceStates(id receiver, SEL _cmd, ASInterfaceState s0, ASInterfaceState s1) {} + +/// Returning nil here won't trigger unwanted default actions, because we override +/// +defaultActionForKey: to return kCFNull. +id StubLayerActionImplementation(id receiver, SEL _cmd, NSString *key) { return nil; } + /** * Returns ASDisplayNodeFlags for the given class/instance. instance MAY BE NIL. * @@ -112,7 +105,7 @@ BOOL ASDisplayNodeNeedsSpecialPropertiesHandling(BOOL isSynchronous, BOOL isLaye * @remarks The instance value is used only if we suspect the class may be dynamic (because it overloads * +respondsToSelector: or -respondsToSelector.) In that case we use our "slow path", calling this * method on each -init and passing the instance value. While this may seem like an unlikely scenario, - * it turns our our own internal tests use a dynamic class, so it's worth capturing this edge case. + * it turns out our own internal tests use a dynamic class, so it's worth capturing this edge case. * * @return ASDisplayNode flags. */ @@ -163,24 +156,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c) if (ASDisplayNodeSubclassOverridesSelector(c, @selector(touchesEnded:withEvent:))) { overrides |= ASDisplayNodeMethodOverrideTouchesEnded; } - - // Responder chain - if (ASDisplayNodeSubclassOverridesSelector(c, @selector(canBecomeFirstResponder))) { - overrides |= ASDisplayNodeMethodOverrideCanBecomeFirstResponder; - } - if (ASDisplayNodeSubclassOverridesSelector(c, @selector(becomeFirstResponder))) { - overrides |= ASDisplayNodeMethodOverrideBecomeFirstResponder; - } - if (ASDisplayNodeSubclassOverridesSelector(c, @selector(canResignFirstResponder))) { - overrides |= ASDisplayNodeMethodOverrideCanResignFirstResponder; - } - if (ASDisplayNodeSubclassOverridesSelector(c, @selector(resignFirstResponder))) { - overrides |= ASDisplayNodeMethodOverrideResignFirstResponder; - } - if (ASDisplayNodeSubclassOverridesSelector(c, @selector(isFirstResponder))) { - overrides |= ASDisplayNodeMethodOverrideIsFirstResponder; - } - + // Layout related methods if (ASDisplayNodeSubclassOverridesSelector(c, @selector(layoutSpecThatFits:))) { overrides |= ASDisplayNodeMethodOverrideLayoutSpecThatFits; @@ -247,10 +223,39 @@ + (void)initialize }); class_replaceMethod(self, @selector(_staticInitialize), staticInitialize, "v:@"); + + // Add stub implementations for global methods that the client didn't + // implement in a category. We do this instead of hard-coding empty + // implementations to avoid a linker warning when it merges categories. + // Note: addMethod will not do anything if a method already exists. + if (self == ASDisplayNode.class) { + IMP noArgsImp = (IMP)StubImplementationWithNoArgs; + class_addMethod(self, @selector(baseDidInit), noArgsImp, "v@:"); + class_addMethod(self, @selector(baseWillDealloc), noArgsImp, "v@:"); + class_addMethod(self, @selector(didLoad), noArgsImp, "v@:"); + class_addMethod(self, @selector(layoutDidFinish), noArgsImp, "v@:"); + class_addMethod(self, @selector(didEnterPreloadState), noArgsImp, "v@:"); + class_addMethod(self, @selector(didExitPreloadState), noArgsImp, "v@:"); + class_addMethod(self, @selector(didEnterDisplayState), noArgsImp, "v@:"); + class_addMethod(self, @selector(didExitDisplayState), noArgsImp, "v@:"); + class_addMethod(self, @selector(didEnterVisibleState), noArgsImp, "v@:"); + class_addMethod(self, @selector(didExitVisibleState), noArgsImp, "v@:"); + class_addMethod(self, @selector(hierarchyDisplayDidFinish), noArgsImp, "v@:"); + class_addMethod(self, @selector(calculatedLayoutDidChange), noArgsImp, "v@:"); + + auto type0 = "v@:" + std::string(@encode(ASSizeRange)); + class_addMethod(self, @selector(willCalculateLayout:), (IMP)StubImplementationWithSizeRange, type0.c_str()); + + auto interfaceStateType = std::string(@encode(ASInterfaceState)); + auto type1 = "v@:" + interfaceStateType + interfaceStateType; + class_addMethod(self, @selector(interfaceStateDidChange:fromState:), (IMP)StubImplementationWithTwoInterfaceStates, type1.c_str()); + + class_addMethod(self, @selector(layerActionForKey:), (IMP)StubLayerActionImplementation, "@@:@"); + } } #if !AS_INITIALIZE_FRAMEWORK_MANUALLY -+ (void)load +__attribute__((constructor)) static void ASLoadFrameworkInitializer(void) { ASInitializeFrameworkMainThread(); } @@ -276,10 +281,7 @@ - (void)_staticInitialize - (void)_initializeInstance { [self _staticInitialize]; - -#if ASEVENTLOG_ENABLE - _eventLog = [[ASEventLog alloc] initWithObject:self]; -#endif + __instanceLock__.SetDebugNameWithObject(self); _viewClass = [self.class viewClass]; _layerClass = [self.class layerClass]; @@ -290,6 +292,7 @@ - (void)_initializeInstance _contentsScaleForDisplay = ASScreenScale(); _drawingPriority = ASDefaultTransactionPriority; + _maskedCorners = kASCACornerAllCorners; _primitiveTraitCollection = ASPrimitiveTraitCollectionMakeDefault(); @@ -303,13 +306,13 @@ - (void)_initializeInstance _flags.canCallSetNeedsDisplayOfLayer = YES; _fallbackSafeAreaInsets = UIEdgeInsetsZero; - _fallbackInsetsLayoutMarginsFromSafeArea = YES; - _isViewControllerRoot = NO; + _flags.fallbackInsetsLayoutMarginsFromSafeArea = YES; + _flags.isViewControllerRoot = NO; - _automaticallyRelayoutOnSafeAreaChanges = NO; - _automaticallyRelayoutOnLayoutMarginsChanges = NO; + _flags.automaticallyRelayoutOnSafeAreaChanges = NO; + _flags.automaticallyRelayoutOnLayoutMarginsChanges = NO; - ASDisplayNodeLogEvent(self, @"init"); + [self baseDidInit]; } - (instancetype)init @@ -416,7 +419,7 @@ - (ASDisplayNodeMethodOverrides)methodOverrides - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body { - ASDN::UniqueLock l(__instanceLock__); + AS::UniqueLock l(__instanceLock__); if ([self _locked_isNodeLoaded]) { ASDisplayNodeAssertThreadAffinity(self); @@ -430,9 +433,53 @@ - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body } } + +- (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection +{ + if (@available(iOS 13.0, tvOS 10.0, *)) { + // When changing between light and dark mode, often the entire node needs to re-render. + // This change doesn't happen frequently so it's fairly safe to render nodes again + __instanceLock__.lock(); + BOOL loaded = _loaded(self); + ASPrimitiveTraitCollection primitiveTraitCollection = _primitiveTraitCollection; + __instanceLock__.unlock(); + if (primitiveTraitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle) { + if (loaded) { + // we need to run that on main thread, cause accessing CALayer properties. + // It seems than in iOS 13 sometimes it causes deadlock. + ASPerformBlockOnMainThread(^{ + self->__instanceLock__.lock(); + CGFloat cornerRadius = self->_cornerRadius; + ASCornerRoundingType cornerRoundingType = self->_cornerRoundingType; + UIColor *backgroundColor = self->_backgroundColor; + self->__instanceLock__.unlock(); + // TODO: we should resolve color using node's trait collection + // but Texture changes it from many places, so we may receive the wrong one. + CGColorRef cgBackgroundColor = backgroundColor.CGColor; + if (!CGColorEqualToColor(self->_layer.backgroundColor, cgBackgroundColor)) { + // Background colors do not dynamically update for layer backed nodes since they utilize CGColorRef + // instead of UIColor. Non layer backed node also receive color to the layer (see [_ASPendingState -applyToView:withSpecialPropertiesHandling:]). + // We utilize the _backgroundColor instance variable to track the full dynamic color + // and apply any changes here when trait collection updates occur. + self->_layer.backgroundColor = cgBackgroundColor; + } + + // If we have clipping corners, re-render the clipping corner layer upon user interface style change + if (cornerRoundingType == ASCornerRoundingTypeClipping && cornerRadius > 0.0f) { + [self _updateClipCornerLayerContentsWithRadius:cornerRadius backgroundColor:backgroundColor]; + } + + [self setNeedsDisplay]; + }); + } + } + } +} + - (void)dealloc { _flags.isDeallocating = YES; + [self baseWillDealloc]; // Synchronous nodes may not be able to call the hierarchy notifications, so only enforce for regular nodes. ASDisplayNodeAssert(checkFlag(Synchronous) || !ASInterfaceStateIncludesVisible(_interfaceState), @"Node should always be marked invisible before deallocating. Node: %@", self); @@ -525,7 +572,6 @@ - (CALayer *)_locked_layerToLoad - (void)_locked_loadViewOrLayer { DISABLED_ASAssertLocked(__instanceLock__); - if (_flags.layerBacked) { TIME_SCOPED(_debugTimeToCreateView); _layer = [self _locked_layerToLoad]; @@ -555,7 +601,6 @@ - (void)_didLoad { ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); - ASDisplayNodeLogEvent(self, @"didLoad"); as_log_verbose(ASNodeLog(), "didLoad %@", self); TIME_SCOPED(_debugTimeForDidLoad); @@ -573,13 +618,6 @@ - (void)_didLoad }]; } -- (void)didLoad -{ - ASDisplayNodeAssertMainThread(); - - // Subclass hook -} - - (BOOL)isNodeLoaded { if (ASDisplayNodeThreadIsMain()) { @@ -587,7 +625,7 @@ - (BOOL)isNodeLoaded // where the state of this property can change. As an optimization, we can avoid locking. return _loaded(self); } else { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_isNodeLoaded]; } } @@ -602,7 +640,7 @@ - (BOOL)_locked_isNodeLoaded - (UIView *)view { - ASDN::UniqueLock l(__instanceLock__); + AS::UniqueLock l(__instanceLock__); ASDisplayNodeAssert(!_flags.layerBacked, @"Call to -view undefined on layer-backed nodes"); BOOL isLayerBacked = _flags.layerBacked; @@ -648,7 +686,7 @@ - (UIView *)view - (CALayer *)layer { - ASDN::UniqueLock l(__instanceLock__); + AS::UniqueLock l(__instanceLock__); if (_layer != nil) { return _layer; } @@ -689,7 +727,7 @@ - (CALayer *)layer // Returns nil if the layer is not an _ASDisplayLayer; will not create the layer if nil. - (_ASDisplayLayer *)asyncLayer { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_asyncLayer]; } @@ -709,7 +747,7 @@ - (void)setLayerBacked:(BOOL)isLayerBacked // Only call this if assertions are enabled – it could be expensive. ASDisplayNodeAssert(!isLayerBacked || self.supportsLayerBacking, @"Node %@ does not support layer backing.", self); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_flags.layerBacked == isLayerBacked) { return; } @@ -724,31 +762,31 @@ - (void)setLayerBacked:(BOOL)isLayerBacked - (BOOL)isLayerBacked { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.layerBacked; } - (BOOL)supportsLayerBacking { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return !checkFlag(Synchronous) && !_flags.viewEverHadAGestureRecognizerAttached && _viewClass == [_ASDisplayView class] && _layerClass == [_ASDisplayLayer class]; } - (BOOL)shouldAnimateSizeChanges { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.shouldAnimateSizeChanges; } - (void)setShouldAnimateSizeChanges:(BOOL)shouldAnimateSizeChanges { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _flags.shouldAnimateSizeChanges = shouldAnimateSizeChanges; } - (CGRect)threadSafeBounds { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_threadSafeBounds]; } @@ -760,19 +798,19 @@ - (CGRect)_locked_threadSafeBounds - (void)setThreadSafeBounds:(CGRect)newBounds { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _threadSafeBounds = newBounds; } - (void)nodeViewDidAddGestureRecognizer { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _flags.viewEverHadAGestureRecognizerAttached = YES; } - (UIEdgeInsets)fallbackSafeAreaInsets { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _fallbackSafeAreaInsets; } @@ -782,7 +820,7 @@ - (void)setFallbackSafeAreaInsets:(UIEdgeInsets)insets BOOL updatesLayoutMargins; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); ASDisplayNodeAssertThreadAffinity(self); if (UIEdgeInsetsEqualToEdgeInsets(insets, _fallbackSafeAreaInsets)) { @@ -833,38 +871,50 @@ - (void)_fallbackUpdateSafeAreaOnChildren - (BOOL)isViewControllerRoot { - ASDN::MutexLocker l(__instanceLock__); - return _isViewControllerRoot; + MutexLocker l(__instanceLock__); + return _flags.isViewControllerRoot; } - (void)setViewControllerRoot:(BOOL)flag { - ASDN::MutexLocker l(__instanceLock__); - _isViewControllerRoot = flag; + MutexLocker l(__instanceLock__); + _flags.isViewControllerRoot = flag; } - (BOOL)automaticallyRelayoutOnSafeAreaChanges { - ASDN::MutexLocker l(__instanceLock__); - return _automaticallyRelayoutOnSafeAreaChanges; + MutexLocker l(__instanceLock__); + return _flags.automaticallyRelayoutOnSafeAreaChanges; } - (void)setAutomaticallyRelayoutOnSafeAreaChanges:(BOOL)flag { - ASDN::MutexLocker l(__instanceLock__); - _automaticallyRelayoutOnSafeAreaChanges = flag; + MutexLocker l(__instanceLock__); + _flags.automaticallyRelayoutOnSafeAreaChanges = flag; } - (BOOL)automaticallyRelayoutOnLayoutMarginsChanges { - ASDN::MutexLocker l(__instanceLock__); - return _automaticallyRelayoutOnLayoutMarginsChanges; + MutexLocker l(__instanceLock__); + return _flags.automaticallyRelayoutOnLayoutMarginsChanges; } - (void)setAutomaticallyRelayoutOnLayoutMarginsChanges:(BOOL)flag { - ASDN::MutexLocker l(__instanceLock__); - _automaticallyRelayoutOnLayoutMarginsChanges = flag; + MutexLocker l(__instanceLock__); + _flags.automaticallyRelayoutOnLayoutMarginsChanges = flag; +} + +- (BOOL)placeholderEnabled +{ + MutexLocker l(__instanceLock__); + return _flags.placeholderEnabled; +} + +- (void)setPlaceholderEnabled:(BOOL)flag +{ + MutexLocker l(__instanceLock__); + _flags.placeholderEnabled = flag; } - (void)__setNodeController:(ASNodeController *)controller @@ -879,26 +929,6 @@ - (void)__setNodeController:(ASNodeController *)controller } } -#pragma mark - UIResponder - -#define HANDLE_NODE_RESPONDER_METHOD(__sel) \ - /* All responder methods should be called on the main thread */ \ - ASDisplayNodeAssertMainThread(); \ - if (checkFlag(Synchronous)) { \ - /* If the view is not a _ASDisplayView subclass (Synchronous) just call through to the view as we - expect it's a non _ASDisplayView subclass that will respond */ \ - return [_view __sel]; \ - } else { \ - if (ASSubclassOverridesSelector([_ASDisplayView class], _viewClass, @selector(__sel))) { \ - /* If the subclass overwrites canBecomeFirstResponder just call through - to it as we expect it will handle it */ \ - return [_view __sel]; \ - } else { \ - /* Call through to _ASDisplayView's superclass to get it handled */ \ - return [(_ASDisplayView *)_view __##__sel]; \ - } \ - } \ - - (void)checkResponderCompatibility { #if ASDISPLAYNODE_ASSERTIONS_ENABLED @@ -916,71 +946,17 @@ - (void)checkResponderCompatibility #endif } -- (BOOL)__canBecomeFirstResponder -{ - if (_view == nil) { - // By default we return NO if not view is created yet - return NO; - } - - HANDLE_NODE_RESPONDER_METHOD(canBecomeFirstResponder); -} - -- (BOOL)__becomeFirstResponder -{ - // Note: This implicitly loads the view if it hasn't been loaded yet. - [self view]; - - if (![self canBecomeFirstResponder]) { - return NO; - } - - HANDLE_NODE_RESPONDER_METHOD(becomeFirstResponder); -} - -- (BOOL)__canResignFirstResponder -{ - if (_view == nil) { - // By default we return YES if no view is created yet - return YES; - } - - HANDLE_NODE_RESPONDER_METHOD(canResignFirstResponder); -} - -- (BOOL)__resignFirstResponder -{ - // Note: This implicitly loads the view if it hasn't been loaded yet. - [self view]; - - if (![self canResignFirstResponder]) { - return NO; - } - - HANDLE_NODE_RESPONDER_METHOD(resignFirstResponder); -} - -- (BOOL)__isFirstResponder -{ - if (_view == nil) { - // If no view is created yet we can just return NO as it's unlikely it's the first responder - return NO; - } - - HANDLE_NODE_RESPONDER_METHOD(isFirstResponder); -} - #pragma mark - (NSString *)debugName { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _debugName; } - (void)setDebugName:(NSString *)debugName { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (!ASObjectIsEqual(_debugName, debugName)) { _debugName = [debugName copy]; } @@ -1004,7 +980,7 @@ - (void)__setNeedsLayout - (void)invalidateCalculatedLayout { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _layoutVersion++; @@ -1019,10 +995,10 @@ - (void)__layout { ASDisplayNodeAssertThreadAffinity(self); DISABLED_ASAssertUnlocked(__instanceLock__); - + BOOL loaded = NO; { - ASDN::UniqueLock l(__instanceLock__); + AS::UniqueLock l(__instanceLock__); loaded = [self _locked_isNodeLoaded]; CGRect bounds = _threadSafeBounds; @@ -1030,7 +1006,7 @@ - (void)__layout // Performing layout on a zero-bounds view often results in frame calculations // with negative sizes after applying margins, which will cause // layoutThatFits: on subnodes to assert. - as_log_debug(OS_LOG_DISABLED, "Warning: No size given for node before node was trying to layout itself: %@. Please provide a frame for the node.", self); + os_log_debug(OS_LOG_DISABLED, "Warning: No size given for node before node was trying to layout itself: %@. Please provide a frame for the node.", self); return; } @@ -1058,19 +1034,19 @@ - (void)__layout ASPerformBlockOnMainThread(^{ [self layout]; [self _layoutClipCornersIfNeeded]; - [self layoutDidFinish]; + [self _layoutDidFinish]; }); } [self _fallbackUpdateSafeAreaOnChildren]; } -- (void)layoutDidFinish +- (void)_layoutDidFinish { - // Hook for subclasses ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); ASDisplayNodeAssertTrue(self.isNodeLoaded); + [self layoutDidFinish]; } #pragma mark Calculation @@ -1082,12 +1058,12 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize as_activity_scope_verbose(as_activity_create("Calculate node layout", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); as_log_verbose(ASLayoutLog(), "Calculating layout for %@ sizeRange %@", self, NSStringFromASSizeRange(constrainedSize)); -#if AS_KDEBUG_ENABLE +#if AS_SIGNPOST_ENABLE // We only want one calculateLayout signpost interval per thread. // Currently there is no fallback for profiling i386, since it's not useful. static _Thread_local NSInteger tls_callDepth; if (tls_callDepth++ == 0) { - ASSignpostStart(ASSignpostCalculateLayout); + ASSignpostStart(CalculateLayout, self, "%@", ASObjectDescriptionMakeTiny(self)); } #endif @@ -1096,9 +1072,9 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize ASLayout *result = [self calculateLayoutThatFits:resolvedRange]; as_log_verbose(ASLayoutLog(), "Calculated layout %@", result); -#if AS_KDEBUG_ENABLE +#if AS_SIGNPOST_ENABLE if (--tls_callDepth == 0) { - ASSignpostEnd(ASSignpostCalculateLayout); + ASSignpostEnd(CalculateLayout, self, ""); } #endif @@ -1131,8 +1107,6 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { __ASDisplayNodeCheckForLayoutMethodOverrides; - - ASDisplayNodeLogEvent(self, @"calculateSizeThatFits: with constrainedSize: %@", NSStringFromCGSize(constrainedSize)); return ASIsCGSizeValidForSize(constrainedSize) ? constrainedSize : CGSizeZero; } @@ -1172,11 +1146,6 @@ - (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didC [self _pendingLayoutTransitionDidComplete]; } -- (void)calculatedLayoutDidChange -{ - // Subclass override -} - #pragma mark - Display NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification = @"ASRenderingEngineDidDisplayScheduledNodes"; @@ -1184,7 +1153,7 @@ - (void)calculatedLayoutDidChange - (BOOL)displaysAsynchronously { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [self _locked_displaysAsynchronously]; } @@ -1201,7 +1170,7 @@ - (void)setDisplaysAsynchronously:(BOOL)displaysAsynchronously { ASDisplayNodeAssertThreadAffinity(self); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); // Can't do this for synchronous nodes (using layers that are not _ASDisplayLayer and so we can't control display prevention/cancel) if (checkFlag(Synchronous)) { @@ -1219,13 +1188,13 @@ - (void)setDisplaysAsynchronously:(BOOL)displaysAsynchronously - (BOOL)rasterizesSubtree { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.rasterizesSubtree; } - (void)enableSubtreeRasterization { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); // Already rasterized from self. if (_flags.rasterizesSubtree) { return; @@ -1262,14 +1231,14 @@ - (void)enableSubtreeRasterization - (CGFloat)contentsScaleForDisplay { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _contentsScaleForDisplay; } - (void)setContentsScaleForDisplay:(CGFloat)contentsScaleForDisplay { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_contentsScaleForDisplay == contentsScaleForDisplay) { return; @@ -1298,7 +1267,7 @@ - (void)__setNeedsDisplay { BOOL shouldScheduleForDisplay = NO; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); BOOL nowDisplay = ASInterfaceStateIncludesDisplay(_interfaceState); // FIXME: This should not need to recursively display, so create a non-recursive variant. // The semantics of setNeedsDisplay (as defined by CALayer behavior) are not recursive. @@ -1337,7 +1306,7 @@ + (void)scheduleNodeForRecursiveDisplay:(ASDisplayNode *)node /// Helper method to summarize whether or not the node run through the display process - (BOOL)_implementsDisplay { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.implementsDrawRect || _flags.implementsImageDisplay || _flags.rasterizesSubtree; } @@ -1366,6 +1335,8 @@ - (void)_pendingNodeDidDisplay:(ASDisplayNode *)node [_pendingDisplayNodes removeObject:node]; if (_pendingDisplayNodes.isEmpty) { + // Reclaim object memory. + _pendingDisplayNodes = nil; [self hierarchyDisplayDidFinish]; [self enumerateInterfaceStateDelegates:^(id delegate) { @@ -1377,7 +1348,7 @@ - (void)_pendingNodeDidDisplay:(ASDisplayNode *)node __instanceLock__.lock(); if (_placeholderLayer.superlayer && !placeholderShouldPersist) { void (^cleanupBlock)() = ^{ - [_placeholderLayer removeFromSuperlayer]; + [self->_placeholderLayer removeFromSuperlayer]; }; if (_placeholderFadeDuration > 0.0 && ASInterfaceStateIncludesVisible(self.interfaceState)) { @@ -1394,16 +1365,11 @@ - (void)_pendingNodeDidDisplay:(ASDisplayNode *)node } } -- (void)hierarchyDisplayDidFinish -{ - // Subclass hook -} - // Helper method to determine if it's safe to call setNeedsDisplay on a layer without throwing away the content. // For details look at the comment on the canCallSetNeedsDisplayOfLayer flag - (BOOL)_canCallSetNeedsDisplayOfLayer { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.canCallSetNeedsDisplayOfLayer; } @@ -1411,7 +1377,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) { // This recursion must handle layers in various states: // 1. Just added to hierarchy, CA hasn't yet called -display - // 2. Previously in a hierarchy (such as a working window owned by an Intelligent Preloading class, like ASTableView / ASCollectionView / ASViewController) + // 2. Previously in a hierarchy (such as a working window owned by an Intelligent Preloading class, like ASTableView / ASCollectionView / ASDKViewController) // 3. Has no content to display at all // Specifically for case 1), we need to explicitly trigger a -display call now. // Otherwise, there is no opportunity to block the main thread after CoreAnimation's transaction commit @@ -1473,20 +1439,20 @@ - (void)recursivelyEnsureDisplaySynchronously:(BOOL)synchronously - (void)setShouldBypassEnsureDisplay:(BOOL)shouldBypassEnsureDisplay { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _flags.shouldBypassEnsureDisplay = shouldBypassEnsureDisplay; } - (BOOL)shouldBypassEnsureDisplay { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.shouldBypassEnsureDisplay; } - (void)setNeedsDisplayAtScale:(CGFloat)contentsScale { { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (contentsScale == _contentsScaleForDisplay) { return; } @@ -1507,17 +1473,17 @@ - (void)recursivelySetNeedsDisplayAtScale:(CGFloat)contentsScale - (void)_layoutClipCornersIfNeeded { ASDisplayNodeAssertMainThread(); - if (_clipCornerLayers[0] == nil) { + if (_clipCornerLayers[0] == nil && _clipCornerLayers[1] == nil && _clipCornerLayers[2] == nil && + _clipCornerLayers[3] == nil) { return; } - + CGSize boundsSize = self.bounds.size; for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) { BOOL isTop = (idx == 0 || idx == 1); - BOOL isRight = (idx == 1 || idx == 2); + BOOL isRight = (idx == 1 || idx == 3); if (_clipCornerLayers[idx]) { - // Note the Core Animation coordinates are reversed for y; 0 is at the bottom. - _clipCornerLayers[idx].position = CGPointMake(isRight ? boundsSize.width : 0.0, isTop ? boundsSize.height : 0.0); + _clipCornerLayers[idx].position = CGPointMake(isRight ? boundsSize.width : 0.0, isTop ? 0.0 : boundsSize.height); [_layer addSublayer:_clipCornerLayers[idx]]; } } @@ -1527,78 +1493,86 @@ - (void)_updateClipCornerLayerContentsWithRadius:(CGFloat)radius backgroundColor { ASPerformBlockOnMainThread(^{ for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) { - // Layers are, in order: Top Left, Top Right, Bottom Right, Bottom Left. + // Skip corners that aren't clipped (we have already set up & torn down layers based on maskedCorners.) + if (self->_clipCornerLayers[idx] == nil) { + continue; + } + + // Layers are, in order: Top Left, Top Right, Bottom Left, Bottom Right, which mirrors CACornerMask. // anchorPoint is Bottom Left at 0,0 and Top Right at 1,1. BOOL isTop = (idx == 0 || idx == 1); - BOOL isRight = (idx == 1 || idx == 2); - + BOOL isRight = (idx == 1 || idx == 3); + CGSize size = CGSizeMake(radius + 1, radius + 1); - ASGraphicsBeginImageContextWithOptions(size, NO, self.contentsScaleForDisplay); - - CGContextRef ctx = UIGraphicsGetCurrentContext(); - if (isRight == YES) { - CGContextTranslateCTM(ctx, -radius + 1, 0); - } - if (isTop == YES) { - CGContextTranslateCTM(ctx, 0, -radius + 1); - } - UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, radius * 2, radius * 2) cornerRadius:radius]; - [roundedRect setUsesEvenOddFillRule:YES]; - [roundedRect appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(-1, -1, radius * 2 + 1, radius * 2 + 1)]]; - [backgroundColor setFill]; - [roundedRect fill]; - + UIImage *newContents = ASGraphicsCreateImage(self.primitiveTraitCollection, size, NO, self.contentsScaleForDisplay, nil, nil, ^{ + CGContextRef ctx = UIGraphicsGetCurrentContext(); + if (isRight == YES) { + CGContextTranslateCTM(ctx, -radius + 1, 0); + } + if (isTop == NO) { + CGContextTranslateCTM(ctx, 0, -radius + 1); + } + UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, radius * 2, radius * 2) cornerRadius:radius]; + [roundedRect setUsesEvenOddFillRule:YES]; + [roundedRect appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(-1, -1, radius * 2 + 1, radius * 2 + 1)]]; + [backgroundColor setFill]; + [roundedRect fill]; + }); + // No lock needed, as _clipCornerLayers is only modified on the main thread. - CALayer *clipCornerLayer = _clipCornerLayers[idx]; - clipCornerLayer.contents = (id)(ASGraphicsGetImageAndEndCurrentContext().CGImage); + unowned CALayer *clipCornerLayer = self->_clipCornerLayers[idx]; + clipCornerLayer.contents = (id)(newContents.CGImage); clipCornerLayer.bounds = CGRectMake(0.0, 0.0, size.width, size.height); - clipCornerLayer.anchorPoint = CGPointMake(isRight ? 1.0 : 0.0, isTop ? 1.0 : 0.0); + clipCornerLayer.anchorPoint = CGPointMake(isRight ? 1.0 : 0.0, isTop ? 0.0 : 1.0); } [self _layoutClipCornersIfNeeded]; }); } -- (void)_setClipCornerLayersVisible:(BOOL)visible +- (void)_setClipCornerLayersVisible:(CACornerMask)visibleCornerLayers { ASPerformBlockOnMainThread(^{ ASDisplayNodeAssertMainThread(); - if (visible) { - for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) { - if (_clipCornerLayers[idx] == nil) { - static ASDisplayNodeCornerLayerDelegate *clipCornerLayers; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - clipCornerLayers = [[ASDisplayNodeCornerLayerDelegate alloc] init]; - }); - _clipCornerLayers[idx] = [[CALayer alloc] init]; - _clipCornerLayers[idx].zPosition = 99999; - _clipCornerLayers[idx].delegate = clipCornerLayers; - } - } - [self _updateClipCornerLayerContentsWithRadius:_cornerRadius backgroundColor:self.backgroundColor]; - } else { - for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) { - [_clipCornerLayers[idx] removeFromSuperlayer]; - _clipCornerLayers[idx] = nil; + for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) { + BOOL visible = (0 != (visibleCornerLayers & (1 << idx))); + if (visible == (self->_clipCornerLayers[idx] != nil)) { + continue; + } else if (visible) { + static ASDisplayNodeCornerLayerDelegate *clipCornerLayers; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + clipCornerLayers = [[ASDisplayNodeCornerLayerDelegate alloc] init]; + }); + self->_clipCornerLayers[idx] = [[CALayer alloc] init]; + self->_clipCornerLayers[idx].zPosition = 99999; + self->_clipCornerLayers[idx].delegate = clipCornerLayers; + } else { + [self->_clipCornerLayers[idx] removeFromSuperlayer]; + self->_clipCornerLayers[idx] = nil; } } + [self _updateClipCornerLayerContentsWithRadius:self->_cornerRadius backgroundColor:self.backgroundColor]; }); } -- (void)updateCornerRoundingWithType:(ASCornerRoundingType)newRoundingType cornerRadius:(CGFloat)newCornerRadius +- (void)updateCornerRoundingWithType:(ASCornerRoundingType)newRoundingType + cornerRadius:(CGFloat)newCornerRadius + maskedCorners:(CACornerMask)newMaskedCorners { __instanceLock__.lock(); CGFloat oldCornerRadius = _cornerRadius; ASCornerRoundingType oldRoundingType = _cornerRoundingType; + CACornerMask oldMaskedCorners = _maskedCorners; _cornerRadius = newCornerRadius; _cornerRoundingType = newRoundingType; + _maskedCorners = newMaskedCorners; __instanceLock__.unlock(); - + ASPerformBlockOnMainThread(^{ ASDisplayNodeAssertMainThread(); - if (oldRoundingType != newRoundingType || oldCornerRadius != newCornerRadius) { + if (oldRoundingType != newRoundingType || oldCornerRadius != newCornerRadius || oldMaskedCorners != newMaskedCorners) { if (oldRoundingType == ASCornerRoundingTypeDefaultSlowCALayer) { if (newRoundingType == ASCornerRoundingTypePrecomposited) { self.layerCornerRadius = 0.0; @@ -1610,14 +1584,16 @@ - (void)updateCornerRoundingWithType:(ASCornerRoundingType)newRoundingType corne } else if (newRoundingType == ASCornerRoundingTypeClipping) { self.layerCornerRadius = 0.0; - [self _setClipCornerLayersVisible:YES]; + [self _setClipCornerLayersVisible:newMaskedCorners]; } else if (newRoundingType == ASCornerRoundingTypeDefaultSlowCALayer) { self.layerCornerRadius = newCornerRadius; + self.layerMaskedCorners = newMaskedCorners; } } else if (oldRoundingType == ASCornerRoundingTypePrecomposited) { if (newRoundingType == ASCornerRoundingTypeDefaultSlowCALayer) { self.layerCornerRadius = newCornerRadius; + self.layerMaskedCorners = newMaskedCorners; [self setNeedsDisplay]; } else if (newRoundingType == ASCornerRoundingTypePrecomposited) { @@ -1626,22 +1602,23 @@ - (void)updateCornerRoundingWithType:(ASCornerRoundingType)newRoundingType corne [self setNeedsDisplay]; } else if (newRoundingType == ASCornerRoundingTypeClipping) { - [self _setClipCornerLayersVisible:YES]; + [self _setClipCornerLayersVisible:newMaskedCorners]; [self setNeedsDisplay]; } } else if (oldRoundingType == ASCornerRoundingTypeClipping) { if (newRoundingType == ASCornerRoundingTypeDefaultSlowCALayer) { self.layerCornerRadius = newCornerRadius; - [self _setClipCornerLayersVisible:NO]; + [self _setClipCornerLayersVisible:kNilOptions]; } else if (newRoundingType == ASCornerRoundingTypePrecomposited) { - [self _setClipCornerLayersVisible:NO]; + [self _setClipCornerLayersVisible:kNilOptions]; [self displayImmediately]; } else if (newRoundingType == ASCornerRoundingTypeClipping) { - // Clip corners already exist, but the radius has changed. - [self _updateClipCornerLayerContentsWithRadius:newCornerRadius backgroundColor:self.backgroundColor]; + // Clip corners already exist, but the radius and/or maskedCorners have changed. + // This method will add & remove them, and subsequently redraw them. + [self _setClipCornerLayersVisible:newMaskedCorners]; } } } @@ -1684,7 +1661,7 @@ static void _recursivelySetDisplaySuspended(ASDisplayNode *node, CALayer *layer, - (BOOL)displaySuspended { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.displaySuspended; } @@ -1745,7 +1722,6 @@ - (void)displayWillStartAsynchronously:(BOOL)asynchronously { ASDisplayNodeAssertMainThread(); - ASDisplayNodeLogEvent(self, @"displayWillStart"); // in case current node takes longer to display than it's subnodes, treat it as a dependent node [self _pendingNodeWillDisplay:self]; @@ -1760,7 +1736,6 @@ - (void)displayDidFinish { ASDisplayNodeAssertMainThread(); - ASDisplayNodeLogEvent(self, @"displayDidFinish"); [self _pendingNodeDidDisplay:self]; __instanceLock__.lock(); @@ -1784,17 +1759,19 @@ - (void)subnodeDisplayDidFinish:(ASDisplayNode *)subnode #pragma mark -// We are only the delegate for the layer when we are layer-backed, as UIView performs this function normally - (id)actionForLayer:(CALayer *)layer forKey:(NSString *)event { - if (event == kCAOnOrderIn) { - [self __enterHierarchy]; - } else if (event == kCAOnOrderOut) { - [self __exitHierarchy]; + // Only drive __enterHierarchy and __exitHierarchy if the node is layer-backed. + // View-backed nodes handle them in _ASDisplayView's -willMoveToWindow: and -didMoveToWindow. + if (self.isLayerBacked) { + if (event == kCAOnOrderIn) { + [self __enterHierarchy]; + } else if (event == kCAOnOrderOut) { + [self __exitHierarchy]; + } } - ASDisplayNodeAssert(_flags.layerBacked, @"We shouldn't get called back here unless we are layer-backed."); - return (id)kCFNull; + return [self layerActionForKey:event]; } #pragma mark - Error Handling @@ -1981,7 +1958,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) { // NOTE: This method must be dealloc-safe (should not retain self). - (ASDisplayNode *)supernode { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _supernode; } @@ -1990,7 +1967,7 @@ - (void)_setSupernode:(ASDisplayNode *)newSupernode BOOL supernodeDidChange = NO; ASDisplayNode *oldSupernode = nil; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_supernode != newSupernode) { oldSupernode = _supernode; // Access supernode properties outside of lock to avoid remote chance of deadlock, // in case supernode implementation must access one of our properties. @@ -2000,7 +1977,6 @@ - (void)_setSupernode:(ASDisplayNode *)newSupernode } if (supernodeDidChange) { - ASDisplayNodeLogEvent(self, @"supernodeDidChange: %@, oldValue = %@", ASObjectDescriptionMakeTiny(newSupernode), ASObjectDescriptionMakeTiny(oldSupernode)); // Hierarchy state ASHierarchyState stateToEnterOrExit = (newSupernode ? newSupernode.hierarchyState : oldSupernode.hierarchyState); @@ -2067,7 +2043,7 @@ - (void)_setSupernode:(ASDisplayNode *)newSupernode - (NSArray *)subnodes { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_cachedSubnodes == nil) { _cachedSubnodes = [_subnodes copy]; } else { @@ -2130,8 +2106,8 @@ - (void)_insertSubnode:(ASDisplayNode *)subnode atSubnodeIndex:(NSInteger)subnod [subnode __incrementVisibilityNotificationsDisabled]; } - [subnode _removeFromSupernode]; - [oldSubnode _removeFromSupernode]; + [subnode removeFromSupernode]; + [oldSubnode removeFromSupernode]; __instanceLock__.lock(); if (_subnodes == nil) { @@ -2192,13 +2168,6 @@ - (void)_insertSubnodeSubviewOrSublayer:(ASDisplayNode *)subnode atIndex:(NSInte } - (void)addSubnode:(ASDisplayNode *)subnode -{ - ASDisplayNodeLogEvent(self, @"addSubnode: %@ with automaticallyManagesSubnodes: %@", - subnode, self.automaticallyManagesSubnodes ? @"YES" : @"NO"); - [self _addSubnode:subnode]; -} - -- (void)_addSubnode:(ASDisplayNode *)subnode { ASDisplayNodeAssertThreadAffinity(self); @@ -2213,7 +2182,7 @@ - (void)_addSubnode:(ASDisplayNode *)subnode NSUInteger subnodesIndex; NSUInteger sublayersIndex; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); subnodesIndex = _subnodes.count; sublayersIndex = _layer.sublayers.count; } @@ -2243,13 +2212,6 @@ - (void)_addSubnodeSubviewOrSublayer:(ASDisplayNode *)subnode } - (void)replaceSubnode:(ASDisplayNode *)oldSubnode withSubnode:(ASDisplayNode *)replacementSubnode -{ - ASDisplayNodeLogEvent(self, @"replaceSubnode: %@ withSubnode: %@ with automaticallyManagesSubnodes: %@", - oldSubnode, replacementSubnode, self.automaticallyManagesSubnodes ? @"YES" : @"NO"); - [self _replaceSubnode:oldSubnode withSubnode:replacementSubnode]; -} - -- (void)_replaceSubnode:(ASDisplayNode *)oldSubnode withSubnode:(ASDisplayNode *)replacementSubnode { ASDisplayNodeAssertThreadAffinity(self); @@ -2268,7 +2230,7 @@ - (void)_replaceSubnode:(ASDisplayNode *)oldSubnode withSubnode:(ASDisplayNode * NSInteger subnodeIndex; NSInteger sublayerIndex = NSNotFound; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); ASDisplayNodeAssert(_subnodes, @"You should have subnodes if you have a subnode"); subnodeIndex = [_subnodes indexOfObjectIdenticalTo:oldSubnode]; @@ -2290,13 +2252,6 @@ - (void)_replaceSubnode:(ASDisplayNode *)oldSubnode withSubnode:(ASDisplayNode * } - (void)insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)below -{ - ASDisplayNodeLogEvent(self, @"insertSubnode: %@ belowSubnode: %@ with automaticallyManagesSubnodes: %@", - subnode, below, self.automaticallyManagesSubnodes ? @"YES" : @"NO"); - [self _insertSubnode:subnode belowSubnode:below]; -} - -- (void)_insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)below { ASDisplayNodeAssertThreadAffinity(self); // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 @@ -2315,7 +2270,7 @@ - (void)_insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)be NSInteger belowSubnodeIndex; NSInteger belowSublayerIndex = NSNotFound; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); ASDisplayNodeAssert(_subnodes, @"You should have subnodes if you have a subnode"); belowSubnodeIndex = [_subnodes indexOfObjectIdenticalTo:below]; @@ -2355,13 +2310,6 @@ - (void)_insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)be } - (void)insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)above -{ - ASDisplayNodeLogEvent(self, @"insertSubnode: %@ abodeSubnode: %@ with automaticallyManagesSubnodes: %@", - subnode, above, self.automaticallyManagesSubnodes ? @"YES" : @"NO"); - [self _insertSubnode:subnode aboveSubnode:above]; -} - -- (void)_insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)above { ASDisplayNodeAssertThreadAffinity(self); // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 @@ -2380,7 +2328,7 @@ - (void)_insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)ab NSInteger aboveSubnodeIndex; NSInteger aboveSublayerIndex = NSNotFound; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); ASDisplayNodeAssert(_subnodes, @"You should have subnodes if you have a subnode"); aboveSubnodeIndex = [_subnodes indexOfObjectIdenticalTo:above]; @@ -2418,13 +2366,6 @@ - (void)_insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)ab } - (void)insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx -{ - ASDisplayNodeLogEvent(self, @"insertSubnode: %@ atIndex: %td with automaticallyManagesSubnodes: %@", - subnode, idx, self.automaticallyManagesSubnodes ? @"YES" : @"NO"); - [self _insertSubnode:subnode atIndex:idx]; -} - -- (void)_insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx { ASDisplayNodeAssertThreadAffinity(self); // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 @@ -2437,7 +2378,7 @@ - (void)_insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx NSInteger sublayerIndex = NSNotFound; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (idx > _subnodes.count || idx < 0) { ASDisplayNodeFailAssert(@"Cannot insert a subnode at index %ld. Count is %ld", (long)idx, (long)_subnodes.count); @@ -2483,13 +2424,6 @@ - (void)_removeSubnode:(ASDisplayNode *)subnode } - (void)removeFromSupernode -{ - ASDisplayNodeLogEvent(self, @"removeFromSupernode with automaticallyManagesSubnodes: %@", - self.automaticallyManagesSubnodes ? @"YES" : @"NO"); - [self _removeFromSupernode]; -} - -- (void)_removeFromSupernode { ASDisplayNodeAssertThreadAffinity(self); // TODO: Disabled due to PR: https://github.com/TextureGroup/Texture/pull/1204 @@ -2550,13 +2484,13 @@ - (void)_removeFromSupernode:(ASDisplayNode *)supernode view:(UIView *)view laye - (BOOL)__visibilityNotificationsDisabled { // Currently, this method is only used by the testing infrastructure to verify this internal feature. - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.visibilityNotificationsDisabled > 0; } - (BOOL)__selfOrParentHasVisibilityNotificationsDisabled { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return (_hierarchyState & ASHierarchyStateTransitioningSupernodes); } @@ -2612,7 +2546,7 @@ - (void)_locked_layoutPlaceholderIfNecessary - (BOOL)_locked_shouldHavePlaceholderLayer { DISABLED_ASAssertLocked(__instanceLock__); - return (_placeholderEnabled && [self _implementsDisplay]); + return (_flags.placeholderEnabled && [self _implementsDisplay]); } - (void)_locked_setupPlaceholderLayerIfNeeded @@ -2658,7 +2592,7 @@ - (BOOL)placeholderShouldPersist - (BOOL)isInHierarchy { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _flags.isInHierarchy; } @@ -2666,8 +2600,6 @@ - (void)__enterHierarchy { ASDisplayNodeAssertMainThread(); ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"Should not cause recursive __enterHierarchy"); - DISABLED_ASAssertUnlocked(__instanceLock__); - ASDisplayNodeLogEvent(self, @"enterHierarchy"); // Profiling has shown that locking this method is beneficial, so each of the property accesses don't have to lock and unlock. __instanceLock__.lock(); @@ -2715,8 +2647,6 @@ - (void)__exitHierarchy { ASDisplayNodeAssertMainThread(); ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"Should not cause recursive __exitHierarchy"); - DISABLED_ASAssertUnlocked(__instanceLock__); - ASDisplayNodeLogEvent(self, @"exitHierarchy"); // Profiling has shown that locking this method is beneficial, so each of the property accesses don't have to lock and unlock. __instanceLock__.lock(); @@ -2766,7 +2696,7 @@ - (void)exitHierarchyState:(ASHierarchyState)hierarchyState - (ASHierarchyState)hierarchyState { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _hierarchyState; } @@ -2774,7 +2704,7 @@ - (void)setHierarchyState:(ASHierarchyState)newState { ASHierarchyState oldState = ASHierarchyStateNormal; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_hierarchyState == newState) { return; } @@ -2805,13 +2735,12 @@ - (void)setHierarchyState:(ASHierarchyState)newState // Entering layout pending state } else { // Leaving layout pending state, reset related properties - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _pendingTransitionID = ASLayoutElementContextInvalidTransitionID; _pendingLayoutTransition = nil; } } - ASDisplayNodeLogEvent(self, @"setHierarchyState: %@", NSStringFromASHierarchyStateChange(oldState, newState)); as_log_verbose(ASNodeLog(), "%s%@ %@", sel_getName(_cmd), NSStringFromASHierarchyStateChange(oldState, newState), self); } @@ -2824,7 +2753,7 @@ - (void)willEnterHierarchy if (![self supportsRangeManagedInterfaceState]) { self.interfaceState = ASInterfaceStateInHierarchy; - } else if (ASCATransactionQueue.sharedQueue.isEnabled) { + } else if (ASCATransactionQueueGet().enabled) { __instanceLock__.lock(); ASInterfaceState state = _preExitingInterfaceState; _preExitingInterfaceState = ASInterfaceStateNone; @@ -2842,6 +2771,12 @@ - (void)didEnterHierarchy { ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive"); ASDisplayNodeAssert(_flags.isInHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive"); DISABLED_ASAssertUnlocked(__instanceLock__); + + [self enumerateInterfaceStateDelegates:^(id del) { + if ([del respondsToSelector:@selector(didEnterHierarchy)]) { + [del didEnterHierarchy]; + } + }]; } - (void)didExitHierarchy @@ -2851,6 +2786,12 @@ - (void)didExitHierarchy ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive"); DISABLED_ASAssertUnlocked(__instanceLock__); + [self enumerateInterfaceStateDelegates:^(id del) { + if ([del respondsToSelector:@selector(didExitHierarchy)]) { + [del didExitHierarchy]; + } + }]; + // This case is important when tearing down hierarchies. We must deliver a visibileStateDidChange:NO callback, as part our API guarantee that this method can be used for // things like data analytics about user content viewing. We cannot call the method in the dealloc as any incidental retain operations in client code would fail. // Additionally, it may be that a Standard UIView which is containing us is moving between hierarchies, and we should not send the call if we will be re-added in the @@ -2867,13 +2808,13 @@ - (void)didExitHierarchy if (ASInterfaceStateIncludesVisible(self.pendingInterfaceState)) { void(^exitVisibleInterfaceState)(void) = ^{ // This block intentionally retains self. - __instanceLock__.lock(); - unsigned isStillInHierarchy = _flags.isInHierarchy; - BOOL isVisible = ASInterfaceStateIncludesVisible(_pendingInterfaceState); - ASInterfaceState newState = (_pendingInterfaceState & ~ASInterfaceStateVisible); + self->__instanceLock__.lock(); + unsigned isStillInHierarchy = self->_flags.isInHierarchy; + BOOL isVisible = ASInterfaceStateIncludesVisible(self->_pendingInterfaceState); + ASInterfaceState newState = (self->_pendingInterfaceState & ~ASInterfaceStateVisible); // layer may be thrashed, we need to remember the state so we can reset if it enters in same runloop later. - _preExitingInterfaceState = _pendingInterfaceState; - __instanceLock__.unlock(); + self->_preExitingInterfaceState = self->_pendingInterfaceState; + self->__instanceLock__.unlock(); if (!isStillInHierarchy && isVisible) { #if ENABLE_NEW_EXIT_HIERARCHY_BEHAVIOR if (![self supportsRangeManagedInterfaceState]) { @@ -2884,7 +2825,7 @@ - (void)didExitHierarchy } }; - if (!ASCATransactionQueue.sharedQueue.enabled) { + if (!ASCATransactionQueueGet().enabled) { dispatch_async(dispatch_get_main_queue(), exitVisibleInterfaceState); } else { exitVisibleInterfaceState(); @@ -2900,7 +2841,7 @@ - (void)didExitHierarchy */ - (BOOL)supportsRangeManagedInterfaceState { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return ASHierarchyStateIncludesRangeManaged(_hierarchyState); } @@ -2919,7 +2860,6 @@ - (void)exitInterfaceState:(ASInterfaceState)interfaceState if (interfaceState == ASInterfaceStateNone) { return; // This method is a no-op with a 0-bitfield argument, so don't bother recursing. } - ASDisplayNodeLogEvent(self, @"%s %@", sel_getName(_cmd), NSStringFromASInterfaceState(interfaceState)); ASDisplayNodePerformBlockOnEveryNode(nil, self, YES, ^(ASDisplayNode *node) { node.interfaceState &= (~interfaceState); }); @@ -2943,26 +2883,26 @@ - (void)recursivelySetInterfaceState:(ASInterfaceState)newInterfaceState - (ASInterfaceState)interfaceState { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _interfaceState; } - (void)setInterfaceState:(ASInterfaceState)newState { - if (!ASCATransactionQueue.sharedQueue.enabled) { + if (!ASCATransactionQueueGet().enabled) { [self applyPendingInterfaceState:newState]; } else { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_pendingInterfaceState != newState) { _pendingInterfaceState = newState; - [[ASCATransactionQueue sharedQueue] enqueue:self]; + [ASCATransactionQueueGet() enqueue:self]; } } } - (ASInterfaceState)pendingInterfaceState { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _pendingInterfaceState; } @@ -2978,10 +2918,10 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState ASInterfaceState oldState = ASInterfaceStateNone; ASInterfaceState newState = ASInterfaceStateNone; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); // newPendingState will not be used when ASCATransactionQueue is enabled // and use _pendingInterfaceState instead for interfaceState update. - if (!ASCATransactionQueue.sharedQueue.enabled) { + if (!ASCATransactionQueueGet().enabled) { _pendingInterfaceState = newPendingState; } oldState = _interfaceState; @@ -3010,12 +2950,12 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState if (nowPreload != wasPreload) { if (nowPreload) { - [self didEnterPreloadState]; + [self _didEnterPreloadState]; } else { // We don't want to call -didExitPreloadState on nodes that aren't being managed by a range controller. // Otherwise we get flashing behavior from normal UIKit manipulations like navigation controller push / pop. if ([self supportsRangeManagedInterfaceState]) { - [self didExitPreloadState]; + [self _didExitPreloadState]; } } } @@ -3033,9 +2973,9 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState [self setDisplaySuspended:YES]; //schedule clear contents on next runloop dispatch_async(dispatch_get_main_queue(), ^{ - __instanceLock__.lock(); - ASInterfaceState interfaceState = _interfaceState; - __instanceLock__.unlock(); + self->__instanceLock__.lock(); + ASInterfaceState interfaceState = self->_interfaceState; + self->__instanceLock__.unlock(); if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) { [self clearContents]; } @@ -3053,9 +2993,9 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState [[self asyncLayer] cancelAsyncDisplay]; //schedule clear contents on next runloop dispatch_async(dispatch_get_main_queue(), ^{ - __instanceLock__.lock(); - ASInterfaceState interfaceState = _interfaceState; - __instanceLock__.unlock(); + self->__instanceLock__.lock(); + ASInterfaceState interfaceState = self->_interfaceState; + self->__instanceLock__.unlock(); if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) { [self clearContents]; } @@ -3066,9 +3006,9 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState } if (nowDisplay) { - [self didEnterDisplayState]; + [self _didEnterDisplayState]; } else { - [self didExitDisplayState]; + [self _didExitDisplayState]; } } @@ -3079,9 +3019,9 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState if (nowVisible != wasVisible) { if (nowVisible) { - [self didEnterVisibleState]; + [self _didEnterVisibleState]; } else { - [self didExitVisibleState]; + [self _didExitVisibleState]; } } @@ -3092,8 +3032,7 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState as_log_verbose(ASNodeLog(), "%s %@ %@", sel_getName(_cmd), NSStringFromASInterfaceStateChange(oldState, newState), self); } - ASDisplayNodeLogEvent(self, @"interfaceStateDidChange: %@", NSStringFromASInterfaceStateChange(oldState, newState)); - [self interfaceStateDidChange:newState fromState:oldState]; + [self _interfaceStateDidChange:newState fromState:oldState]; } - (void)prepareForCATransactionCommit @@ -3102,10 +3041,11 @@ - (void)prepareForCATransactionCommit [self applyPendingInterfaceState:ASInterfaceStateNone]; } -- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState +- (void)_interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState { DISABLED_ASAssertUnlocked(__instanceLock__); ASDisplayNodeAssertMainThread(); + [self interfaceStateDidChange:newState fromState:oldState]; [self enumerateInterfaceStateDelegates:^(id del) { [del interfaceStateDidChange:newState fromState:oldState]; }]; @@ -3120,8 +3060,8 @@ - (BOOL)shouldScheduleDisplayWithNewInterfaceState:(ASInterfaceState)newInterfac - (void)addInterfaceStateDelegate:(id )interfaceStateDelegate { - ASDN::MutexLocker l(__instanceLock__); - _hasHadInterfaceStateDelegates = YES; + MutexLocker l(__instanceLock__); + _flags.hasHadInterfaceStateDelegates = YES; for (int i = 0; i < AS_MAX_INTERFACE_STATE_DELEGATES; i++) { if (_interfaceStateDelegates[i] == nil) { _interfaceStateDelegates[i] = interfaceStateDelegate; @@ -3133,7 +3073,7 @@ - (void)addInterfaceStateDelegate:(id )interfaceStateD - (void)removeInterfaceStateDelegate:(id )interfaceStateDelegate { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); for (int i = 0; i < AS_MAX_INTERFACE_STATE_DELEGATES; i++) { if (_interfaceStateDelegates[i] == interfaceStateDelegate) { _interfaceStateDelegates[i] = nil; @@ -3144,13 +3084,12 @@ - (void)removeInterfaceStateDelegate:(id )interfaceSta - (BOOL)isVisible { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return ASInterfaceStateIncludesVisible(_interfaceState); } -- (void)didEnterVisibleState +- (void)_didEnterVisibleState { - // subclass override ASDisplayNodeAssertMainThread(); #if ASDISPLAYNODE_ASSERTIONS_ENABLED @@ -3161,6 +3100,7 @@ - (void)didEnterVisibleState #endif DISABLED_ASAssertUnlocked(__instanceLock__); + [self didEnterVisibleState]; [self enumerateInterfaceStateDelegates:^(id del) { [del didEnterVisibleState]; }]; @@ -3170,11 +3110,11 @@ - (void)didEnterVisibleState #endif } -- (void)didExitVisibleState +- (void)_didExitVisibleState { - // subclass override ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); + [self didExitVisibleState]; [self enumerateInterfaceStateDelegates:^(id del) { [del didExitVisibleState]; }]; @@ -3182,25 +3122,25 @@ - (void)didExitVisibleState - (BOOL)isInDisplayState { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return ASInterfaceStateIncludesDisplay(_interfaceState); } -- (void)didEnterDisplayState +- (void)_didEnterDisplayState { - // subclass override ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); + [self didEnterDisplayState]; [self enumerateInterfaceStateDelegates:^(id del) { [del didEnterDisplayState]; }]; } -- (void)didExitDisplayState +- (void)_didExitDisplayState { - // subclass override ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); + [self didExitDisplayState]; [self enumerateInterfaceStateDelegates:^(id del) { [del didExitDisplayState]; }]; @@ -3208,7 +3148,7 @@ - (void)didExitDisplayState - (BOOL)isInPreloadState { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return ASInterfaceStateIncludesPreload(_interfaceState); } @@ -3237,11 +3177,12 @@ - (void)recursivelyClearPreloadedData }); } -- (void)didEnterPreloadState +- (void)_didEnterPreloadState { ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); - + [self didEnterPreloadState]; + // If this node has ASM enabled and is not yet visible, force a layout pass to apply its applicable pending layout, if any, // so that its subnodes are inserted/deleted and start preloading right away. // @@ -3259,10 +3200,11 @@ - (void)didEnterPreloadState }]; } -- (void)didExitPreloadState +- (void)_didExitPreloadState { ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); + [self didExitPreloadState]; [self enumerateInterfaceStateDelegates:^(id del) { [del didExitPreloadState]; }]; @@ -3273,7 +3215,7 @@ - (void)clearContents ASDisplayNodeAssertMainThread(); DISABLED_ASAssertUnlocked(__instanceLock__); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (_flags.canClearContentsOfLayer) { // No-op if these haven't been created yet, as that guarantees they don't have contents that needs to be released. _layer.contents = nil; @@ -3301,7 +3243,7 @@ - (void)enumerateInterfaceStateDelegates:(void (NS_NOESCAPE ^)(id *)propertiesForDescription { NSMutableArray *result = [NSMutableArray array]; @@ -3680,12 +3615,6 @@ - (CGRect)_frameInWindow } } -#pragma mark - Trait Collection Hooks - -- (void)asyncTraitCollectionDidChange -{ - // Subclass override -} @end #pragma mark - ASDisplayNode (Debugging) @@ -3704,7 +3633,7 @@ + (BOOL)shouldStoreUnflattenedLayouts - (ASLayout *)unflattenedCalculatedLayout { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _unflattenedLayout; } @@ -3738,7 +3667,7 @@ - (NSString *)_recursiveDescriptionHelperWithIndent:(NSString *)indent - (NSString *)detailedLayoutDescription { ASPushMainThreadAssertionsDisabled(); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); const auto props = [[NSMutableArray alloc] init]; [props addObject:@{ @"layoutVersion": @(_layoutVersion.load()) }]; diff --git a/Example/Pods/Texture/Source/ASDisplayNodeExtras.h b/Example/Pods/Texture/Source/ASDisplayNodeExtras.h index 09512ea..03f2940 100644 --- a/Example/Pods/Texture/Source/ASDisplayNodeExtras.h +++ b/Example/Pods/Texture/Source/ASDisplayNodeExtras.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN /// For deallocation of objects on the main thread across multiple run loops. -AS_EXTERN void ASPerformMainThreadDeallocation(id _Nullable __strong * _Nonnull objectPtr); +ASDK_EXTERN void ASPerformMainThreadDeallocation(id _Nullable __strong * _Nonnull objectPtr); // Because inline methods can't be extern'd and need to be part of the translation unit of code // that compiles with them to actually inline, we both declare and define these in the header. @@ -101,22 +101,22 @@ __unused static NSString *NSStringFromASInterfaceStateChange(ASInterfaceState ol /** Returns the appropriate interface state for a given ASDisplayNode and window */ -AS_EXTERN ASInterfaceState ASInterfaceStateForDisplayNode(ASDisplayNode *displayNode, UIWindow *window) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASInterfaceState ASInterfaceStateForDisplayNode(ASDisplayNode *displayNode, UIWindow *window) AS_WARN_UNUSED_RESULT; /** Given a layer, returns the associated display node, if any. */ -AS_EXTERN ASDisplayNode * _Nullable ASLayerToDisplayNode(CALayer * _Nullable layer) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode * _Nullable ASLayerToDisplayNode(CALayer * _Nullable layer) AS_WARN_UNUSED_RESULT; /** Given a view, returns the associated display node, if any. */ -AS_EXTERN ASDisplayNode * _Nullable ASViewToDisplayNode(UIView * _Nullable view) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode * _Nullable ASViewToDisplayNode(UIView * _Nullable view) AS_WARN_UNUSED_RESULT; /** Given a node, returns the root of the node hierarchy (where supernode == nil) */ -AS_EXTERN ASDisplayNode *ASDisplayNodeUltimateParentOfNode(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode *ASDisplayNodeUltimateParentOfNode(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; /** If traverseSublayers == YES, this function will walk the layer hierarchy, spanning discontinuous sections of the node hierarchy\ @@ -124,39 +124,39 @@ AS_EXTERN ASDisplayNode *ASDisplayNodeUltimateParentOfNode(ASDisplayNode *node) In the event that a node's backing layer is not created yet, the function will only walk the direct subnodes instead of forcing the layer hierarchy to be created. */ -AS_EXTERN void ASDisplayNodePerformBlockOnEveryNode(CALayer * _Nullable layer, ASDisplayNode * _Nullable node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryNode(CALayer * _Nullable layer, ASDisplayNode * _Nullable node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); /** This function will walk the node hierarchy in a breadth first fashion. It does run the block on the node provided directly to the function call. It does NOT traverse sublayers. */ -AS_EXTERN void ASDisplayNodePerformBlockOnEveryNodeBFS(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryNodeBFS(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); /** Identical to ASDisplayNodePerformBlockOnEveryNode, except it does not run the block on the node provided directly to the function call - only on all descendants. */ -AS_EXTERN void ASDisplayNodePerformBlockOnEverySubnode(ASDisplayNode *node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEverySubnode(ASDisplayNode *node, BOOL traverseSublayers, void(^block)(ASDisplayNode *node)); /** Given a display node, traverses up the layer tree hierarchy, returning the first display node that passes block. */ -AS_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernode(ASDisplayNode * _Nullable node, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodes` property instead."); +ASDK_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernode(ASDisplayNode * _Nullable node, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodes` property instead."); /** Given a display node, traverses up the layer tree hierarchy, returning the first display node of kind class. */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodeOfClass:includingSelf:` method instead."); +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSupernodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use the `supernodeOfClass:includingSelf:` method instead."); /** * Given a layer, find the window it lives in, if any. */ -AS_EXTERN UIWindow * _Nullable ASFindWindowOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIWindow * _Nullable ASFindWindowOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; /** * Given a layer, find the closest view it lives in, if any. */ -AS_EXTERN UIView * _Nullable ASFindClosestViewOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIView * _Nullable ASFindClosestViewOfLayer(CALayer *layer) AS_WARN_UNUSED_RESULT; /** * Given two nodes, finds their most immediate common parent. Used for geometry conversion methods. @@ -166,48 +166,48 @@ AS_EXTERN UIView * _Nullable ASFindClosestViewOfLayer(CALayer *layer) AS_WARN_UN * undefined and undocumented behavior of UIKit in ASDisplayNode, this operation is defined to be incorrect in all * circumstances and must be fixed wherever encountered. */ -AS_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindClosestCommonAncestor(ASDisplayNode *node1, ASDisplayNode *node2) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASDisplayNode * _Nullable ASDisplayNodeFindClosestCommonAncestor(ASDisplayNode *node1, ASDisplayNode *node2) AS_WARN_UNUSED_RESULT; /** Given a display node, collects all descendants. This is a specialization of ASCollectContainer() that walks the Core Animation layer tree as opposed to the display node tree, thus supporting non-continues display node hierarchies. */ -AS_EXTERN NSArray *ASCollectDisplayNodes(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASCollectDisplayNodes(ASDisplayNode *node) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning all the display nodes that pass the block. */ -AS_EXTERN NSArray *ASDisplayNodeFindAllSubnodes(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASDisplayNodeFindAllSubnodes(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning all the display nodes of kind class. */ -AS_EXTERN NSArray<__kindof ASDisplayNode *> *ASDisplayNodeFindAllSubnodesOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray<__kindof ASDisplayNode *> *ASDisplayNodeFindAllSubnodesOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning the depth-first display node, including the start node that pass the block. */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstNode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstNode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning the depth-first display node, excluding the start node, that pass the block */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnode(ASDisplayNode *start, BOOL (^block)(ASDisplayNode *node)) AS_WARN_UNUSED_RESULT; /** Given a display node, traverses down the node hierarchy, returning the depth-first display node of kind class. */ -AS_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN __kindof ASDisplayNode * _Nullable ASDisplayNodeFindFirstSubnodeOfClass(ASDisplayNode *start, Class c) AS_WARN_UNUSED_RESULT; -AS_EXTERN UIColor *ASDisplayNodeDefaultPlaceholderColor(void) AS_WARN_UNUSED_RESULT; -AS_EXTERN UIColor *ASDisplayNodeDefaultTintColor(void) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIColor *ASDisplayNodeDefaultPlaceholderColor(void) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN UIColor *ASDisplayNodeDefaultTintColor(void) AS_WARN_UNUSED_RESULT; /** Disable willAppear / didAppear / didDisappear notifications for a sub-hierarchy, then re-enable when done. Nested calls are supported. */ -AS_EXTERN void ASDisplayNodeDisableHierarchyNotifications(ASDisplayNode *node); -AS_EXTERN void ASDisplayNodeEnableHierarchyNotifications(ASDisplayNode *node); +ASDK_EXTERN void ASDisplayNodeDisableHierarchyNotifications(ASDisplayNode *node); +ASDK_EXTERN void ASDisplayNodeEnableHierarchyNotifications(ASDisplayNode *node); // Not to be called directly. -AS_EXTERN void _ASSetDebugNames(Class owningClass, NSString *names, ASDisplayNode * _Nullable object, ...); +ASDK_EXTERN void _ASSetDebugNames(Class owningClass, NSString *names, ASDisplayNode * _Nullable object, ...); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASDisplayNodeExtras.mm b/Example/Pods/Texture/Source/ASDisplayNodeExtras.mm index d1be157..2cebbb5 100644 --- a/Example/Pods/Texture/Source/ASDisplayNodeExtras.mm +++ b/Example/Pods/Texture/Source/ASDisplayNodeExtras.mm @@ -9,7 +9,6 @@ #import #import -#import #import #import diff --git a/Example/Pods/Texture/Source/ASEditableTextNode.mm b/Example/Pods/Texture/Source/ASEditableTextNode.mm index 0adc8b0..60be21f 100644 --- a/Example/Pods/Texture/Source/ASEditableTextNode.mm +++ b/Example/Pods/Texture/Source/ASEditableTextNode.mm @@ -9,7 +9,6 @@ #import -#import #import #import @@ -114,23 +113,25 @@ @interface ASEditableTextNode () // Core. id __weak _delegate; - BOOL _delegateDidUpdateEnqueued; // TextKit. - ASDN::RecursiveMutex _textKitLock; + AS::RecursiveMutex _textKitLock; ASTextKitComponents *_textKitComponents; ASTextKitComponents *_placeholderTextKitComponents; // Forwards NSLayoutManagerDelegate methods related to word kerning ASTextNodeWordKerner *_wordKerner; // UITextInputTraits - ASDN::RecursiveMutex _textInputTraitsLock; + AS::RecursiveMutex _textInputTraitsLock; _ASTextInputTraitsPendingState *_textInputTraits; // Misc. State. BOOL _displayingPlaceholder; // Defaults to YES. BOOL _isPreservingSelection; BOOL _selectionChangedForEditedText; + BOOL _delegateDidUpdateEnqueued; + BOOL _scrollEnabled; + NSRange _previousSelectedRange; } @@ -175,11 +176,11 @@ - (void)didLoad [super didLoad]; void (^configureTextView)(UITextView *) = ^(UITextView *textView) { - if (!_displayingPlaceholder || textView != _textKitComponents.textView) { + if (!self->_displayingPlaceholder || textView != self->_textKitComponents.textView) { // If showing the placeholder, don't propagate backgroundColor/opaque to the editable textView. It is positioned over the placeholder to accept taps to begin editing, and if it's opaque/colored then it'll obscure the placeholder. textView.backgroundColor = self.backgroundColor; textView.opaque = self.opaque; - } else if (_displayingPlaceholder && textView == _textKitComponents.textView) { + } else if (self->_displayingPlaceholder && textView == self->_textKitComponents.textView) { // The default backgroundColor for a textView is white. Due to the reason described above, make sure the editable textView starts out transparent. textView.backgroundColor = nil; textView.opaque = NO; @@ -188,23 +189,23 @@ - (void)didLoad // Configure textView with UITextInputTraits { - ASDN::MutexLocker l(_textInputTraitsLock); - if (_textInputTraits) { - textView.autocapitalizationType = _textInputTraits.autocapitalizationType; - textView.autocorrectionType = _textInputTraits.autocorrectionType; - textView.spellCheckingType = _textInputTraits.spellCheckingType; - textView.keyboardType = _textInputTraits.keyboardType; - textView.keyboardAppearance = _textInputTraits.keyboardAppearance; - textView.returnKeyType = _textInputTraits.returnKeyType; - textView.enablesReturnKeyAutomatically = _textInputTraits.enablesReturnKeyAutomatically; - textView.secureTextEntry = _textInputTraits.isSecureTextEntry; + AS::MutexLocker l(self->_textInputTraitsLock); + if (self->_textInputTraits) { + textView.autocapitalizationType = self->_textInputTraits.autocapitalizationType; + textView.autocorrectionType = self->_textInputTraits.autocorrectionType; + textView.spellCheckingType = self->_textInputTraits.spellCheckingType; + textView.keyboardType = self->_textInputTraits.keyboardType; + textView.keyboardAppearance = self->_textInputTraits.keyboardAppearance; + textView.returnKeyType = self->_textInputTraits.returnKeyType; + textView.enablesReturnKeyAutomatically = self->_textInputTraits.enablesReturnKeyAutomatically; + textView.secureTextEntry = self->_textInputTraits.isSecureTextEntry; } } [self.view addSubview:textView]; }; - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // Create and configure the placeholder text view. _placeholderTextKitComponents.textView = [[ASTextKitComponentsTextView alloc] initWithFrame:CGRectZero textContainer:_placeholderTextKitComponents.textContainer]; @@ -259,7 +260,7 @@ - (void)setBackgroundColor:(UIColor *)backgroundColor { [super setBackgroundColor:backgroundColor]; - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // If showing the placeholder, don't propagate backgroundColor/opaque to the editable textView. It is positioned over the placeholder to accept taps to begin editing, and if it's opaque/colored then it'll obscure the placeholder. // The backgroundColor/opaque will be propagated to the editable textView when editing begins. @@ -271,7 +272,7 @@ - (void)setBackgroundColor:(UIColor *)backgroundColor - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); _textContainerInset = textContainerInset; _textKitComponents.textView.textContainerInset = textContainerInset; @@ -282,7 +283,7 @@ - (void)setOpaque:(BOOL)opaque { [super setOpaque:opaque]; - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // If showing the placeholder, don't propagate backgroundColor/opaque to the editable textView. It is positioned over the placeholder to accept taps to begin editing, and if it's opaque/colored then it'll obscure the placeholder. // The backgroundColor/opaque will be propagated to the editable textView when editing begins. @@ -308,7 +309,7 @@ - (BOOL)supportsLayerBacking - (void)setScrollEnabled:(BOOL)scrollEnabled { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); _scrollEnabled = scrollEnabled; [_textKitComponents.textView setScrollEnabled:_scrollEnabled]; } @@ -342,7 +343,7 @@ - (void)setTypingAttributes:(NSDictionary *)typingAttributes _typingAttributes = [typingAttributes copy]; - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); _textKitComponents.textView.typingAttributes = _typingAttributes; } @@ -352,13 +353,13 @@ - (void)setTypingAttributes:(NSDictionary *)typingAttributes - (NSRange)selectedRange { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return _textKitComponents.textView.selectedRange; } - (void)setSelectedRange:(NSRange)selectedRange { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); _textKitComponents.textView.selectedRange = selectedRange; } @@ -372,14 +373,14 @@ - (BOOL)isDisplayingPlaceholder @dynamic attributedPlaceholderText; - (NSAttributedString *)attributedPlaceholderText { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_placeholderTextKitComponents.textStorage copy]; } - (void)setAttributedPlaceholderText:(NSAttributedString *)attributedPlaceholderText { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); if (ASObjectIsEqual(_placeholderTextKitComponents.textStorage, attributedPlaceholderText)) return; @@ -396,14 +397,14 @@ - (NSAttributedString *)attributedText if ([self isDisplayingPlaceholder]) return nil; - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_textKitComponents.textStorage copy]; } - (void)setAttributedText:(NSAttributedString *)attributedText { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // If we (_cmd) are called while the text view itself is updating (-textViewDidUpdate:), you cannot update the text storage and expect perfect propagation to the text view. // Thus, we always update the textview directly if it's been created already. @@ -445,7 +446,7 @@ - (void)setAttributedText:(NSAttributedString *)attributedText #pragma mark - Core - (void)_updateDisplayingPlaceholder { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // Show the placeholder if necessary. _displayingPlaceholder = (_textKitComponents.textStorage.length == 0); @@ -463,7 +464,7 @@ - (void)_updateDisplayingPlaceholder - (void)_layoutTextView { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // Layout filling our bounds. _textKitComponents.textView.frame = self.bounds; @@ -481,35 +482,35 @@ - (void)_layoutTextView @dynamic textInputMode; - (UITextInputMode *)textInputMode { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_textKitComponents.textView textInputMode]; } - (BOOL)isFirstResponder { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_textKitComponents.textView isFirstResponder]; } - (BOOL)canBecomeFirstResponder { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_textKitComponents.textView canBecomeFirstResponder]; } - (BOOL)becomeFirstResponder { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_textKitComponents.textView becomeFirstResponder]; } - (BOOL)canResignFirstResponder { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_textKitComponents.textView canResignFirstResponder]; } - (BOOL)resignFirstResponder { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); return [_textKitComponents.textView resignFirstResponder]; } @@ -525,7 +526,7 @@ - (_ASTextInputTraitsPendingState *)textInputTraits - (void)setAutocapitalizationType:(UITextAutocapitalizationType)autocapitalizationType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setAutocapitalizationType:autocapitalizationType]; } else { @@ -535,7 +536,7 @@ - (void)setAutocapitalizationType:(UITextAutocapitalizationType)autocapitalizati - (UITextAutocapitalizationType)autocapitalizationType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView autocapitalizationType]; } else { @@ -545,7 +546,7 @@ - (UITextAutocapitalizationType)autocapitalizationType - (void)setAutocorrectionType:(UITextAutocorrectionType)autocorrectionType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setAutocorrectionType:autocorrectionType]; } else { @@ -555,7 +556,7 @@ - (void)setAutocorrectionType:(UITextAutocorrectionType)autocorrectionType - (UITextAutocorrectionType)autocorrectionType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView autocorrectionType]; } else { @@ -565,7 +566,7 @@ - (UITextAutocorrectionType)autocorrectionType - (void)setSpellCheckingType:(UITextSpellCheckingType)spellCheckingType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setSpellCheckingType:spellCheckingType]; } else { @@ -575,7 +576,7 @@ - (void)setSpellCheckingType:(UITextSpellCheckingType)spellCheckingType - (UITextSpellCheckingType)spellCheckingType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView spellCheckingType]; } else { @@ -585,7 +586,7 @@ - (UITextSpellCheckingType)spellCheckingType - (void)setEnablesReturnKeyAutomatically:(BOOL)enablesReturnKeyAutomatically { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setEnablesReturnKeyAutomatically:enablesReturnKeyAutomatically]; } else { @@ -595,7 +596,7 @@ - (void)setEnablesReturnKeyAutomatically:(BOOL)enablesReturnKeyAutomatically - (BOOL)enablesReturnKeyAutomatically { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView enablesReturnKeyAutomatically]; } else { @@ -605,7 +606,7 @@ - (BOOL)enablesReturnKeyAutomatically - (void)setKeyboardAppearance:(UIKeyboardAppearance)setKeyboardAppearance { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setKeyboardAppearance:setKeyboardAppearance]; } else { @@ -615,7 +616,7 @@ - (void)setKeyboardAppearance:(UIKeyboardAppearance)setKeyboardAppearance - (UIKeyboardAppearance)keyboardAppearance { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView keyboardAppearance]; } else { @@ -625,7 +626,7 @@ - (UIKeyboardAppearance)keyboardAppearance - (void)setKeyboardType:(UIKeyboardType)keyboardType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setKeyboardType:keyboardType]; } else { @@ -635,7 +636,7 @@ - (void)setKeyboardType:(UIKeyboardType)keyboardType - (UIKeyboardType)keyboardType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView keyboardType]; } else { @@ -645,7 +646,7 @@ - (UIKeyboardType)keyboardType - (void)setReturnKeyType:(UIReturnKeyType)returnKeyType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setReturnKeyType:returnKeyType]; } else { @@ -655,7 +656,7 @@ - (void)setReturnKeyType:(UIReturnKeyType)returnKeyType - (UIReturnKeyType)returnKeyType { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView returnKeyType]; } else { @@ -665,7 +666,7 @@ - (UIReturnKeyType)returnKeyType - (void)setSecureTextEntry:(BOOL)secureTextEntry { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { [self.textView setSecureTextEntry:secureTextEntry]; } else { @@ -675,7 +676,7 @@ - (void)setSecureTextEntry:(BOOL)secureTextEntry - (BOOL)isSecureTextEntry { - ASDN::MutexLocker l(_textInputTraitsLock); + AS::MutexLocker l(_textInputTraitsLock); if (self.isNodeLoaded) { return [self.textView isSecureTextEntry]; } else { @@ -704,7 +705,7 @@ - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range r - (void)textViewDidChange:(UITextView *)textView { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // Note we received a text changed event. // This is used by _delegateDidChangeSelectionFromSelectedRange:toSelectedRange: to distinguish between selection changes that happen because of editing or pure selection changes. @@ -767,7 +768,7 @@ - (CGRect)layoutManager:(NSLayoutManager *)layoutManager boundingBoxForControlGl #pragma mark - Geometry - (CGRect)frameForTextRange:(NSRange)textRange { - ASDN::MutexLocker l(_textKitLock); + AS::MutexLocker l(_textKitLock); // Bail on invalid range. if (NSMaxRange(textRange) > [_textKitComponents.textStorage length]) { @@ -814,8 +815,8 @@ - (void)_delegateDidChangeSelectionFromSelectedRange:(NSRange)fromSelectedRange // 2. This delegate method (-textViewDidChangeSelection:) is called both before -textViewDidChange: and before the layout manager/etc. has necessarily generated+laid out its glyphs. Because of the former, we need to wait until -textViewDidChange: has had an opportunity to be called so can accurately determine whether this selection change is due to editing (_selectionChangedForEditedText). // Thus, to avoid calling out to client code in the middle of UITextView's processing, we call the delegate on the next run of the runloop, when all such internal processing is surely done. dispatch_async(dispatch_get_main_queue(), ^{ - if ([_delegate respondsToSelector:@selector(editableTextNodeDidChangeSelection:fromSelectedRange:toSelectedRange:dueToEditing:)]) - [_delegate editableTextNodeDidChangeSelection:self fromSelectedRange:fromSelectedRange toSelectedRange:toSelectedRange dueToEditing:_selectionChangedForEditedText]; + if ([self->_delegate respondsToSelector:@selector(editableTextNodeDidChangeSelection:fromSelectedRange:toSelectedRange:dueToEditing:)]) + [self->_delegate editableTextNodeDidChangeSelection:self fromSelectedRange:fromSelectedRange toSelectedRange:toSelectedRange dueToEditing:self->_selectionChangedForEditedText]; }); } @@ -830,9 +831,9 @@ - (void)_delegateDidUpdateText // UITextView invokes its delegate methods when it's in the middle of text-processing. For example, -textViewDidChange: is invoked before you can truly rely on the changes being propagated throughout the Text Kit hierarchy. // Thus, to avoid calling out to client code in the middle of UITextView's processing, we call the delegate on the next run of the runloop, when all such internal processing is surely done. dispatch_async(dispatch_get_main_queue(), ^{ - _delegateDidUpdateEnqueued = NO; - if ([_delegate respondsToSelector:@selector(editableTextNodeDidUpdateText:)]) - [_delegate editableTextNodeDidUpdateText:self]; + self->_delegateDidUpdateEnqueued = NO; + if ([self->_delegate respondsToSelector:@selector(editableTextNodeDidUpdateText:)]) + [self->_delegate editableTextNodeDidUpdateText:self]; }); } diff --git a/Example/Pods/Texture/Source/ASExperimentalFeatures.h b/Example/Pods/Texture/Source/ASExperimentalFeatures.h index 8061785..7729e2e 100644 --- a/Example/Pods/Texture/Source/ASExperimentalFeatures.h +++ b/Example/Pods/Texture/Source/ASExperimentalFeatures.h @@ -16,28 +16,26 @@ NS_ASSUME_NONNULL_BEGIN * A bit mask of features. Make sure to update configuration.json when you add entries. */ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) { - ASExperimentalGraphicsContexts = 1 << 0, // exp_graphics_contexts -#if AS_ENABLE_TEXTNODE - ASExperimentalTextNode = 1 << 1, // exp_text_node -#endif - ASExperimentalInterfaceStateCoalescing = 1 << 2, // exp_interface_state_coalesce - ASExperimentalUnfairLock = 1 << 3, // exp_unfair_lock - ASExperimentalLayerDefaults = 1 << 4, // exp_infer_layer_defaults - ASExperimentalNetworkImageQueue = 1 << 5, // exp_network_image_queue - ASExperimentalCollectionTeardown = 1 << 6, // exp_collection_teardown - ASExperimentalFramesetterCache = 1 << 7, // exp_framesetter_cache - ASExperimentalSkipClearData = 1 << 8, // exp_skip_clear_data - ASExperimentalDidEnterPreloadSkipASMLayout = 1 << 9, // exp_did_enter_preload_skip_asm_layout - ASExperimentalDisableAccessibilityCache = 1 << 10, // exp_disable_a11y_cache - ASExperimentalSkipAccessibilityWait = 1 << 11, // exp_skip_a11y_wait - ASExperimentalNewDefaultCellLayoutMode = 1 << 12, // exp_new_default_cell_layout_mode + // If AS_ENABLE_TEXTNODE=0 or TextNode2 subspec is used this setting is a no op and ASTextNode2 + // will be used in all cases + ASExperimentalTextNode = 1 << 0, // exp_text_node + ASExperimentalInterfaceStateCoalescing = 1 << 1, // exp_interface_state_coalesce + ASExperimentalLayerDefaults = 1 << 2, // exp_infer_layer_defaults + ASExperimentalCollectionTeardown = 1 << 3, // exp_collection_teardown + ASExperimentalFramesetterCache = 1 << 4, // exp_framesetter_cache + ASExperimentalSkipClearData = 1 << 5, // exp_skip_clear_data + ASExperimentalDidEnterPreloadSkipASMLayout = 1 << 6, // exp_did_enter_preload_skip_asm_layout + ASExperimentalDispatchApply = 1 << 7, // exp_dispatch_apply + ASExperimentalDrawingGlobal = 1 << 8, // exp_drawing_global + ASExperimentalOptimizeDataControllerPipeline = 1 << 9, // exp_optimize_data_controller_pipeline + ASExperimentalDoNotCacheAccessibilityElements = 1 << 10, // exp_do_not_cache_accessibility_elements ASExperimentalFeatureAll = 0xFFFFFFFF }; /// Convert flags -> name array. -AS_EXTERN NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags); +ASDK_EXTERN NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags); /// Convert name array -> flags. -AS_EXTERN ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray *array); +ASDK_EXTERN ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray *array); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASExperimentalFeatures.mm b/Example/Pods/Texture/Source/ASExperimentalFeatures.mm index 3f005be..fef124b 100644 --- a/Example/Pods/Texture/Source/ASExperimentalFeatures.mm +++ b/Example/Pods/Texture/Source/ASExperimentalFeatures.mm @@ -12,20 +12,17 @@ NSArray *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags) { - NSArray *allNames = ASCreateOnce((@[@"exp_graphics_contexts", - @"exp_text_node", + NSArray *allNames = ASCreateOnce((@[@"exp_text_node", @"exp_interface_state_coalesce", - @"exp_unfair_lock", @"exp_infer_layer_defaults", - @"exp_network_image_queue", @"exp_collection_teardown", @"exp_framesetter_cache", @"exp_skip_clear_data", @"exp_did_enter_preload_skip_asm_layout", - @"exp_disable_a11y_cache", - @"exp_skip_a11y_wait", - @"exp_new_default_cell_layout_mode"])); - + @"exp_dispatch_apply", + @"exp_drawing_global", + @"exp_optimize_data_controller_pipeline", + @"exp_do_not_cache_accessibility_elements"])); if (flags == ASExperimentalFeatureAll) { return allNames; } @@ -42,7 +39,7 @@ ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray *array) { NSArray *allNames = ASExperimentalFeaturesGetNames(ASExperimentalFeatureAll); - ASExperimentalFeatures result = 0; + ASExperimentalFeatures result = kNilOptions; for (NSString *str in array) { NSUInteger i = [allNames indexOfObject:str]; if (i != NSNotFound) { diff --git a/Example/Pods/Texture/Source/ASImageNode+AnimatedImage.mm b/Example/Pods/Texture/Source/ASImageNode+AnimatedImage.mm index df8be08..9716f85 100644 --- a/Example/Pods/Texture/Source/ASImageNode+AnimatedImage.mm +++ b/Example/Pods/Texture/Source/ASImageNode+AnimatedImage.mm @@ -9,8 +9,6 @@ #import -#import -#import #import #import #import @@ -20,7 +18,6 @@ #import #import #import -#import #import #define ASAnimatedImageDebug 0 @@ -82,11 +79,6 @@ - (void)_locked_setAnimatedImage:(id )animatedImage // not fire e.g. while scrolling down CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^(void) { [self animatedImageSet:animatedImage previousAnimatedImage:previousAnimatedImage]; - - // Animated image can take while to dealloc, do it off the main queue - if (previousAnimatedImage != nil) { - ASPerformBackgroundDeallocation(&previousAnimatedImage); - } }); // Don't need to wakeup the runloop as the current is already running // CFRunLoopWakeUp(runLoop); // Should not be necessary @@ -110,7 +102,7 @@ - (void)setAnimatedImagePaused:(BOOL)animatedImagePaused { ASLockScopeSelf(); - _animatedImagePaused = animatedImagePaused; + _imageNodeFlags.animatedImagePaused = animatedImagePaused; [self _locked_setShouldAnimate:!animatedImagePaused]; } @@ -118,7 +110,7 @@ - (void)setAnimatedImagePaused:(BOOL)animatedImagePaused - (BOOL)animatedImagePaused { ASLockScopeSelf(); - return _animatedImagePaused; + return _imageNodeFlags.animatedImagePaused; } - (void)setCoverImageCompleted:(UIImage *)coverImage @@ -166,13 +158,13 @@ - (void)_locked_setCoverImage:(UIImage *)coverImage - (NSString *)animatedImageRunLoopMode { - ASDN::MutexLocker l(_displayLinkLock); + AS::MutexLocker l(_displayLinkLock); return _animatedImageRunLoopMode; } - (void)setAnimatedImageRunLoopMode:(NSString *)runLoopMode { - ASDN::MutexLocker l(_displayLinkLock); + AS::MutexLocker l(_displayLinkLock); if (runLoopMode == nil) { runLoopMode = ASAnimatedImageDefaultRunLoopMode; @@ -235,7 +227,7 @@ - (void)_locked_startAnimating return; } - if (_animatedImagePaused) { + if (_imageNodeFlags.animatedImagePaused) { return; } @@ -247,13 +239,10 @@ - (void)_locked_startAnimating NSLog(@"starting animation: %p", self); #endif - // Get frame interval before holding display link lock to avoid deadlock - NSUInteger frameInterval = self.animatedImage.frameInterval; - ASDN::MutexLocker l(_displayLinkLock); + AS::MutexLocker l(_displayLinkLock); if (_displayLink == nil) { _playHead = 0; _displayLink = [CADisplayLink displayLinkWithTarget:[ASWeakProxy weakProxyWithTarget:self] selector:@selector(displayLinkFired:)]; - _displayLink.frameInterval = frameInterval; _lastSuccessfulFrameIndex = NSUIntegerMax; [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:_animatedImageRunLoopMode]; @@ -279,7 +268,7 @@ - (void)_locked_stopAnimating NSLog(@"stopping animation: %p", self); #endif ASDisplayNodeAssertMainThread(); - ASDN::MutexLocker l(_displayLinkLock); + AS::MutexLocker l(_displayLinkLock); _displayLink.paused = YES; self.lastDisplayLinkFire = 0; @@ -398,7 +387,7 @@ @implementation ASImageNode(AnimatedImageInvalidation) - (void)invalidateAnimatedImage { - ASDN::MutexLocker l(_displayLinkLock); + AS::MutexLocker l(_displayLinkLock); #if ASAnimatedImageDebug if (_displayLink) { NSLog(@"invalidating display link"); diff --git a/Example/Pods/Texture/Source/ASImageNode.h b/Example/Pods/Texture/Source/ASImageNode.h index d6271f5..dcdb110 100644 --- a/Example/Pods/Texture/Source/ASImageNode.h +++ b/Example/Pods/Texture/Source/ASImageNode.h @@ -21,8 +21,7 @@ NS_ASSUME_NONNULL_BEGIN * * @return A transformed image. */ -typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image); - +typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image, ASPrimitiveTraitCollection traitCollection); /** * @abstract Draws images. @@ -196,7 +195,7 @@ typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image); * * @return An ASImageNode image modification block. */ -AS_EXTERN asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor * _Nullable borderColor); +ASDK_EXTERN asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor * _Nullable borderColor); /** * @abstract Image modification block that applies a tint color à la UIImage configured with @@ -208,6 +207,6 @@ AS_EXTERN asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlo * * @return An ASImageNode image modification block. */ -AS_EXTERN asimagenode_modification_block_t ASImageNodeTintColorModificationBlock(UIColor *color); +ASDK_EXTERN asimagenode_modification_block_t ASImageNodeTintColorModificationBlock(UIColor *color); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASImageNode.mm b/Example/Pods/Texture/Source/ASImageNode.mm index 259d8b9..95ac201 100644 --- a/Example/Pods/Texture/Source/ASImageNode.mm +++ b/Example/Pods/Texture/Source/ASImageNode.mm @@ -12,8 +12,6 @@ #import #import -#import -#import #import #import #import @@ -32,8 +30,6 @@ // TODO: It would be nice to remove this dependency; it's the only subclass using more than +FrameworkSubclasses.h #import -static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - typedef void (^ASImageNodeDrawParametersBlock)(ASWeakMapEntry *entry); @interface ASImageNodeDrawParameters : NSObject { @@ -43,6 +39,7 @@ @interface ASImageNodeDrawParameters : NSObject { CGRect _bounds; CGFloat _contentsScale; UIColor *_backgroundColor; + UIColor *_tintColor; UIViewContentMode _contentMode; BOOL _cropEnabled; BOOL _forceUpscaling; @@ -53,6 +50,7 @@ @interface ASImageNodeDrawParameters : NSObject { ASDisplayNodeContextModifier _willDisplayNodeContentWithRenderingContext; ASDisplayNodeContextModifier _didDisplayNodeContentWithRenderingContext; ASImageNodeDrawParametersBlock _didDrawBlock; + ASPrimitiveTraitCollection _traitCollection; } @end @@ -71,10 +69,11 @@ @interface ASImageNodeContentsKey : NSObject @property CGRect imageDrawRect; @property BOOL isOpaque; @property (nonatomic, copy) UIColor *backgroundColor; +@property (nonatomic, copy) UIColor *tintColor; @property (nonatomic) ASDisplayNodeContextModifier willDisplayNodeContentWithRenderingContext; @property (nonatomic) ASDisplayNodeContextModifier didDisplayNodeContentWithRenderingContext; @property (nonatomic) asimagenode_modification_block_t imageModificationBlock; - +@property UIUserInterfaceStyle userInterfaceStyle API_AVAILABLE(tvos(10.0), ios(12.0)); @end @implementation ASImageNodeContentsKey @@ -91,14 +90,20 @@ - (BOOL)isEqual:(id)object // overheard of our caching, so it's likely not high-impact. if ([object isKindOfClass:[ASImageNodeContentsKey class]]) { ASImageNodeContentsKey *other = (ASImageNodeContentsKey *)object; - return [_image isEqual:other.image] + BOOL areKeysEqual = [_image isEqual:other.image] && CGSizeEqualToSize(_backingSize, other.backingSize) && CGRectEqualToRect(_imageDrawRect, other.imageDrawRect) && _isOpaque == other.isOpaque && [_backgroundColor isEqual:other.backgroundColor] + && [_tintColor isEqual:other.tintColor] && _willDisplayNodeContentWithRenderingContext == other.willDisplayNodeContentWithRenderingContext && _didDisplayNodeContentWithRenderingContext == other.didDisplayNodeContentWithRenderingContext && _imageModificationBlock == other.imageModificationBlock; + if (AS_AVAILABLE_IOS_TVOS(12, 10)) { + // iOS 12, tvOS 10 and later (userInterfaceStyle only available in iOS12+) + areKeysEqual = areKeysEqual && _userInterfaceStyle == other.userInterfaceStyle; + } + return areKeysEqual; } else { return NO; } @@ -114,6 +119,7 @@ - (NSUInteger)hash CGRect imageDrawRect; NSInteger isOpaque; NSUInteger backgroundColorHash; + NSUInteger tintColorHash; void *willDisplayNodeContentWithRenderingContext; void *didDisplayNodeContentWithRenderingContext; void *imageModificationBlock; @@ -124,6 +130,7 @@ - (NSUInteger)hash _imageDrawRect, _isOpaque, _backgroundColor.hash, + _tintColor.hash, (void *)_willDisplayNodeContentWithRenderingContext, (void *)_didDisplayNodeContentWithRenderingContext, (void *)_imageModificationBlock @@ -133,7 +140,6 @@ - (NSUInteger)hash @end - @implementation ASImageNode { @private @@ -142,13 +148,11 @@ @implementation ASImageNode UIColor *_placeholderColor; void (^_displayCompletionBlock)(BOOL canceled); - + // Drawing ASTextNode *_debugLabelNode; - + // Cropping. - BOOL _cropEnabled; // Defaults to YES. - BOOL _forceUpscaling; //Defaults to NO. CGSize _forcedSize; //Defaults to CGSizeZero, indicating no forced size. CGRect _cropRect; // Defaults to CGRectMake(0.5, 0.5, 0, 0) CGRect _cropDisplayBounds; // Defaults to CGRectNull @@ -175,13 +179,14 @@ - (instancetype)init // initial value. With setting a explicit backgroundColor we can prevent that change. self.backgroundColor = [UIColor clearColor]; - _cropEnabled = YES; - _forceUpscaling = NO; + _imageNodeFlags.cropEnabled = YES; + _imageNodeFlags.forceUpscaling = NO; + _imageNodeFlags.regenerateFromImageAsset = NO; _cropRect = CGRectMake(0.5, 0.5, 0, 0); _cropDisplayBounds = CGRectNull; _placeholderColor = ASDisplayNodeDefaultPlaceholderColor(); _animatedImageRunLoopMode = ASAnimatedImageDefaultRunLoopMode; - + return self; } @@ -201,15 +206,15 @@ - (UIImage *)placeholderImage if ((size.width * size.height) < CGFLOAT_EPSILON) { return nil; } - - ASDN::MutexLocker l(__instanceLock__); - - ASGraphicsBeginImageContextWithOptions(size, NO, 1); - [self.placeholderColor setFill]; - UIRectFill(CGRectMake(0, 0, size.width, size.height)); - UIImage *image = ASGraphicsGetImageAndEndCurrentContext(); - - return image; + + __instanceLock__.lock(); + ASPrimitiveTraitCollection tc = _primitiveTraitCollection; + __instanceLock__.unlock(); + return ASGraphicsCreateImage(tc, size, NO, 1, nil, nil, ^{ + AS::MutexLocker l(__instanceLock__); + [_placeholderColor setFill]; + UIRectFill(CGRectMake(0, 0, size.width, size.height)); + }); } #pragma mark - Layout and Sizing @@ -229,7 +234,7 @@ - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize - (void)setImage:(UIImage *)image { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); [self _locked_setImage:image]; } @@ -240,37 +245,26 @@ - (void)_locked_setImage:(UIImage *)image return; } - UIImage *oldImage = _image; _image = image; - + if (image != nil) { // We explicitly call setNeedsDisplay in this case, although we know setNeedsDisplay will be called with lock held. // Therefore we have to be careful in methods that are involved with setNeedsDisplay to not run into a deadlock [self setNeedsDisplay]; - + // For debugging purposes we don't care about locking for now if ([ASImageNode shouldShowImageScalingOverlay] && _debugLabelNode == nil) { // do not use ASPerformBlockOnMainThread here, if it performs the block synchronously it will continue // holding the lock while calling addSubnode. dispatch_async(dispatch_get_main_queue(), ^{ - _debugLabelNode = [[ASTextNode alloc] init]; - _debugLabelNode.layerBacked = YES; - [self addSubnode:_debugLabelNode]; + self->_debugLabelNode = [[ASTextNode alloc] init]; + self->_debugLabelNode.layerBacked = YES; + [self addSubnode:self->_debugLabelNode]; }); } } else { self.contents = nil; } - - // Destruction of bigger images on the main thread can be expensive - // and can take some time, so we dispatch onto a bg queue to - // actually dealloc. - CGSize oldImageSize = oldImage.size; - BOOL shouldReleaseImageOnBackgroundThread = oldImageSize.width > kMinReleaseImageOnBackgroundSize.width - || oldImageSize.height > kMinReleaseImageOnBackgroundSize.height; - if (shouldReleaseImageOnBackgroundThread) { - ASPerformBackgroundDeallocation(&oldImage); - } } - (UIImage *)image @@ -287,7 +281,7 @@ - (void)setPlaceholderColor:(UIColor *)placeholderColor { ASLockScopeSelf(); if (ASCompareAssignCopy(_placeholderColor, placeholderColor)) { - _placeholderEnabled = (placeholderColor != nil); + _flags.placeholderEnabled = (placeholderColor != nil); } } @@ -295,30 +289,49 @@ - (void)setPlaceholderColor:(UIColor *)placeholderColor - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer { - ASLockScopeSelf(); - ASImageNodeDrawParameters *drawParameters = [[ASImageNodeDrawParameters alloc] init]; - drawParameters->_image = _image; + + { + ASLockScopeSelf(); + UIImage *drawImage = _image; + if (AS_AVAILABLE_IOS_TVOS(13, 10)) { + if (_imageNodeFlags.regenerateFromImageAsset && drawImage != nil) { + _imageNodeFlags.regenerateFromImageAsset = NO; + UITraitCollection *tc = [UITraitCollection traitCollectionWithUserInterfaceStyle:_primitiveTraitCollection.userInterfaceStyle]; + UIImage *generatedImage = [drawImage.imageAsset imageWithTraitCollection:tc]; + if ( generatedImage != nil ) { + drawImage = generatedImage; + } + } + } + + drawParameters->_image = drawImage; + drawParameters->_contentsScale = _contentsScaleForDisplay; + drawParameters->_cropEnabled = _imageNodeFlags.cropEnabled; + drawParameters->_forceUpscaling = _imageNodeFlags.forceUpscaling; + drawParameters->_forcedSize = _forcedSize; + drawParameters->_cropRect = _cropRect; + drawParameters->_cropDisplayBounds = _cropDisplayBounds; + drawParameters->_imageModificationBlock = _imageModificationBlock; + drawParameters->_willDisplayNodeContentWithRenderingContext = _willDisplayNodeContentWithRenderingContext; + drawParameters->_didDisplayNodeContentWithRenderingContext = _didDisplayNodeContentWithRenderingContext; + drawParameters->_traitCollection = _primitiveTraitCollection; + + // Hack for now to retain the weak entry that was created while this drawing happened + drawParameters->_didDrawBlock = ^(ASWeakMapEntry *entry){ + ASLockScopeSelf(); + self->_weakCacheEntry = entry; + }; + } + + // We need to unlock before we access the other accessor. + // Especially tintColor because it needs to walk up the view hierarchy drawParameters->_bounds = [self threadSafeBounds]; drawParameters->_opaque = self.opaque; - drawParameters->_contentsScale = _contentsScaleForDisplay; drawParameters->_backgroundColor = self.backgroundColor; drawParameters->_contentMode = self.contentMode; - drawParameters->_cropEnabled = _cropEnabled; - drawParameters->_forceUpscaling = _forceUpscaling; - drawParameters->_forcedSize = _forcedSize; - drawParameters->_cropRect = _cropRect; - drawParameters->_cropDisplayBounds = _cropDisplayBounds; - drawParameters->_imageModificationBlock = _imageModificationBlock; - drawParameters->_willDisplayNodeContentWithRenderingContext = _willDisplayNodeContentWithRenderingContext; - drawParameters->_didDisplayNodeContentWithRenderingContext = _didDisplayNodeContentWithRenderingContext; - - // Hack for now to retain the weak entry that was created while this drawing happened - drawParameters->_didDrawBlock = ^(ASWeakMapEntry *entry){ - ASLockScopeSelf(); - _weakCacheEntry = entry; - }; - + drawParameters->_tintColor = self.tintColor; + return drawParameters; } @@ -330,13 +343,14 @@ + (UIImage *)displayWithParameters:(id)parameter isCancelled:(NS_NOESC if (image == nil) { return nil; } - + CGRect drawParameterBounds = drawParameter->_bounds; BOOL forceUpscaling = drawParameter->_forceUpscaling; CGSize forcedSize = drawParameter->_forcedSize; BOOL cropEnabled = drawParameter->_cropEnabled; BOOL isOpaque = drawParameter->_opaque; UIColor *backgroundColor = drawParameter->_backgroundColor; + UIColor *tintColor = drawParameter->_tintColor; UIViewContentMode contentMode = drawParameter->_contentMode; CGFloat contentsScale = drawParameter->_contentsScale; CGRect cropDisplayBounds = drawParameter->_cropDisplayBounds; @@ -344,41 +358,41 @@ + (UIImage *)displayWithParameters:(id)parameter isCancelled:(NS_NOESC asimagenode_modification_block_t imageModificationBlock = drawParameter->_imageModificationBlock; ASDisplayNodeContextModifier willDisplayNodeContentWithRenderingContext = drawParameter->_willDisplayNodeContentWithRenderingContext; ASDisplayNodeContextModifier didDisplayNodeContentWithRenderingContext = drawParameter->_didDisplayNodeContentWithRenderingContext; - + BOOL hasValidCropBounds = cropEnabled && !CGRectIsEmpty(cropDisplayBounds); CGRect bounds = (hasValidCropBounds ? cropDisplayBounds : drawParameterBounds); - - + + ASDisplayNodeAssert(contentsScale > 0, @"invalid contentsScale at display time"); - + // if the image is resizable, bail early since the image has likely already been configured BOOL stretchable = !UIEdgeInsetsEqualToEdgeInsets(image.capInsets, UIEdgeInsetsZero); if (stretchable) { if (imageModificationBlock != NULL) { - image = imageModificationBlock(image); + image = imageModificationBlock(image, drawParameter->_traitCollection); } return image; } - + CGSize imageSize = image.size; CGSize imageSizeInPixels = CGSizeMake(imageSize.width * image.scale, imageSize.height * image.scale); CGSize boundsSizeInPixels = CGSizeMake(std::floor(bounds.size.width * contentsScale), std::floor(bounds.size.height * contentsScale)); - + BOOL contentModeSupported = contentMode == UIViewContentModeScaleAspectFill || contentMode == UIViewContentModeScaleAspectFit || contentMode == UIViewContentModeCenter; - + CGSize backingSize = CGSizeZero; CGRect imageDrawRect = CGRectZero; - + if (boundsSizeInPixels.width * contentsScale < 1.0f || boundsSizeInPixels.height * contentsScale < 1.0f || imageSizeInPixels.width < 1.0f || imageSizeInPixels.height < 1.0f) { return nil; } - - + + // If we're not supposed to do any cropping, just decode image at original size - if (!cropEnabled || !contentModeSupported || stretchable) { + if (!cropEnabled || !contentModeSupported) { backingSize = imageSizeInPixels; imageDrawRect = (CGRect){.size = backingSize}; } else { @@ -396,7 +410,7 @@ + (UIImage *)displayWithParameters:(id)parameter isCancelled:(NS_NOESC &backingSize, &imageDrawRect); } - + if (backingSize.width <= 0.0f || backingSize.height <= 0.0f || imageDrawRect.size.width <= 0.0f || imageDrawRect.size.height <= 0.0f) { return nil; @@ -408,10 +422,15 @@ + (UIImage *)displayWithParameters:(id)parameter isCancelled:(NS_NOESC contentsKey.imageDrawRect = imageDrawRect; contentsKey.isOpaque = isOpaque; contentsKey.backgroundColor = backgroundColor; + contentsKey.tintColor = tintColor; contentsKey.willDisplayNodeContentWithRenderingContext = willDisplayNodeContentWithRenderingContext; contentsKey.didDisplayNodeContentWithRenderingContext = didDisplayNodeContentWithRenderingContext; contentsKey.imageModificationBlock = imageModificationBlock; + if (AS_AVAILABLE_IOS_TVOS(12, 10)) { + contentsKey.userInterfaceStyle = drawParameter->_traitCollection.userInterfaceStyle; + } + if (isCancelled()) { return nil; } @@ -423,7 +442,7 @@ + (UIImage *)displayWithParameters:(id)parameter isCancelled:(NS_NOESC if (entry == nil) { return nil; } - + if (drawParameter->_didDrawBlock) { drawParameter->_didDrawBlock(entry); } @@ -436,13 +455,13 @@ + (UIImage *)displayWithParameters:(id)parameter isCancelled:(NS_NOESC + (ASWeakMapEntry *)contentsForkey:(ASImageNodeContentsKey *)key drawParameters:(id)drawParameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled { static dispatch_once_t onceToken; - static ASDN::Mutex *cacheLock = nil; + static AS::Mutex *cacheLock = nil; dispatch_once(&onceToken, ^{ - cacheLock = new ASDN::Mutex(); + cacheLock = new AS::Mutex(); }); - + { - ASDN::MutexLocker l(*cacheLock); + AS::MutexLocker l(*cacheLock); if (!cache) { cache = [[ASWeakMap alloc] init]; } @@ -459,75 +478,79 @@ + (ASWeakMapEntry *)contentsForkey:(ASImageNodeContentsKey *)key drawParameters: } { - ASDN::MutexLocker l(*cacheLock); + AS::MutexLocker l(*cacheLock); return [cache setObject:contents forKey:key]; } } -+ (UIImage *)createContentsForkey:(ASImageNodeContentsKey *)key drawParameters:(id)drawParameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled ++ (UIImage *)createContentsForkey:(ASImageNodeContentsKey *)key drawParameters:(id)parameter isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled { - // The following `ASGraphicsBeginImageContextWithOptions` call will sometimes take take longer than 5ms on an + // The following `ASGraphicsCreateImage` call will sometimes take take longer than 5ms on an // A5 processor for a 400x800 backingSize. // Check for cancellation before we call it. if (isCancelled()) { return nil; } + + ASImageNodeDrawParameters *drawParameters = (ASImageNodeDrawParameters *)parameter; // Use contentsScale of 1.0 and do the contentsScale handling in boundsSizeInPixels so ASCroppedImageBackingSizeAndDrawRectInBounds // will do its rounding on pixel instead of point boundaries - ASGraphicsBeginImageContextWithOptions(key.backingSize, key.isOpaque, 1.0); - - BOOL contextIsClean = YES; - - CGContextRef context = UIGraphicsGetCurrentContext(); - if (context && key.willDisplayNodeContentWithRenderingContext) { - key.willDisplayNodeContentWithRenderingContext(context, drawParameters); - contextIsClean = NO; - } - - // if view is opaque, fill the context with background color - if (key.isOpaque && key.backgroundColor) { - [key.backgroundColor setFill]; - UIRectFill({ .size = key.backingSize }); - contextIsClean = NO; - } - - // iOS 9 appears to contain a thread safety regression when drawing the same CGImageRef on - // multiple threads concurrently. In fact, instead of crashing, it appears to deadlock. - // The issue is present in Mac OS X El Capitan and has been seen hanging Pro apps like Adobe Premiere, - // as well as iOS games, and a small number of ASDK apps that provide the same image reference - // to many separate ASImageNodes. A workaround is to set .displaysAsynchronously = NO for the nodes - // that may get the same pointer for a given UI asset image, etc. - // FIXME: We should replace @synchronized here, probably using a global, locked NSMutableSet, and - // only if the object already exists in the set we should create a semaphore to signal waiting threads - // upon removal of the object from the set when the operation completes. - // Another option is to have ASDisplayNode+AsyncDisplay coordinate these cases, and share the decoded buffer. - // Details tracked in https://github.com/facebook/AsyncDisplayKit/issues/1068 - - UIImage *image = key.image; - BOOL canUseCopy = (contextIsClean || ASImageAlphaInfoIsOpaque(CGImageGetAlphaInfo(image.CGImage))); - CGBlendMode blendMode = canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal; - - @synchronized(image) { - [image drawInRect:key.imageDrawRect blendMode:blendMode alpha:1]; - } - - if (context && key.didDisplayNodeContentWithRenderingContext) { - key.didDisplayNodeContentWithRenderingContext(context, drawParameters); - } + UIImage *result = ASGraphicsCreateImage(drawParameters->_traitCollection, key.backingSize, key.isOpaque, 1.0, key.image, isCancelled, ^{ + BOOL contextIsClean = YES; - // Check cancellation one last time before forming image. - if (isCancelled()) { - ASGraphicsEndImageContext(); - return nil; + CGContextRef context = UIGraphicsGetCurrentContext(); + if (context && key.willDisplayNodeContentWithRenderingContext) { + key.willDisplayNodeContentWithRenderingContext(context, drawParameters); + contextIsClean = NO; + } + + // if view is opaque, fill the context with background color + if (key.isOpaque && key.backgroundColor) { + [key.backgroundColor setFill]; + UIRectFill({ .size = key.backingSize }); + contextIsClean = NO; + } + + // iOS 9 appears to contain a thread safety regression when drawing the same CGImageRef on + // multiple threads concurrently. In fact, instead of crashing, it appears to deadlock. + // The issue is present in Mac OS X El Capitan and has been seen hanging Pro apps like Adobe Premiere, + // as well as iOS games, and a small number of ASDK apps that provide the same image reference + // to many separate ASImageNodes. A workaround is to set .displaysAsynchronously = NO for the nodes + // that may get the same pointer for a given UI asset image, etc. + // FIXME: We should replace @synchronized here, probably using a global, locked NSMutableSet, and + // only if the object already exists in the set we should create a semaphore to signal waiting threads + // upon removal of the object from the set when the operation completes. + // Another option is to have ASDisplayNode+AsyncDisplay coordinate these cases, and share the decoded buffer. + // Details tracked in https://github.com/facebook/AsyncDisplayKit/issues/1068 + + UIImage *image = key.image; + BOOL canUseCopy = (contextIsClean || ASImageAlphaInfoIsOpaque(CGImageGetAlphaInfo(image.CGImage))); + CGBlendMode blendMode = canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal; + UIImageRenderingMode renderingMode = [image renderingMode]; + if (renderingMode == UIImageRenderingModeAlwaysTemplate && key.tintColor) { + [key.tintColor setFill]; + } + + @synchronized(image) { + [image drawInRect:key.imageDrawRect blendMode:blendMode alpha:1]; + } + + if (context && key.didDisplayNodeContentWithRenderingContext) { + key.didDisplayNodeContentWithRenderingContext(context, drawParameters); + } + }); + + // if the original image was stretchy, keep it stretchy + UIImage *originalImage = key.image; + if (!UIEdgeInsetsEqualToEdgeInsets(originalImage.capInsets, UIEdgeInsetsZero)) { + result = [result resizableImageWithCapInsets:originalImage.capInsets resizingMode:originalImage.resizingMode]; } - UIImage *result = ASGraphicsGetImageAndEndCurrentContext(); - if (key.imageModificationBlock) { - result = key.imageModificationBlock(result); + result = key.imageModificationBlock(result, drawParameters->_traitCollection); } - + return result; } @@ -564,7 +587,7 @@ - (void)displayDidFinish _debugLabelNode.attributedText = nil; } } - + // If we've got a block to perform after displaying, do it. if (shouldPerformDisplayCompletionBlock) { displayCompletionBlock(NO); @@ -581,7 +604,7 @@ - (void)setNeedsDisplayWithCompletion:(void (^ _Nullable)(BOOL canceled))display // Stash the block and call-site queue. We'll invoke it in -displayDidFinish. { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); if (_displayCompletionBlock != displayCompletionBlock) { _displayCompletionBlock = displayCompletionBlock; } @@ -590,13 +613,40 @@ - (void)setNeedsDisplayWithCompletion:(void (^ _Nullable)(BOOL canceled))display [self setNeedsDisplay]; } +- (void)_setNeedsDisplayOnTemplatedImages +{ + BOOL isTemplateImage = NO; + { + AS::MutexLocker l(__instanceLock__); + isTemplateImage = (_image.renderingMode == UIImageRenderingModeAlwaysTemplate); + } + + if (isTemplateImage) { + [self setNeedsDisplay]; + } +} + +- (void)tintColorDidChange +{ + [super tintColorDidChange]; + + [self _setNeedsDisplayOnTemplatedImages]; +} + #pragma mark Interface State +- (void)didEnterHierarchy +{ + [super didEnterHierarchy]; + + [self _setNeedsDisplayOnTemplatedImages]; +} + - (void)clearContents { [super clearContents]; - - ASDN::MutexLocker l(__instanceLock__); + + AS::MutexLocker l(__instanceLock__); _weakCacheEntry = nil; // release contents from the cache. } @@ -604,8 +654,8 @@ - (void)clearContents - (BOOL)isCropEnabled { - ASDN::MutexLocker l(__instanceLock__); - return _cropEnabled; + AS::MutexLocker l(__instanceLock__); + return _imageNodeFlags.cropEnabled; } - (void)setCropEnabled:(BOOL)cropEnabled @@ -616,14 +666,14 @@ - (void)setCropEnabled:(BOOL)cropEnabled - (void)setCropEnabled:(BOOL)cropEnabled recropImmediately:(BOOL)recropImmediately inBounds:(CGRect)cropBounds { __instanceLock__.lock(); - if (_cropEnabled == cropEnabled) { + if (_imageNodeFlags.cropEnabled == cropEnabled) { __instanceLock__.unlock(); return; } - _cropEnabled = cropEnabled; + _imageNodeFlags.cropEnabled = cropEnabled; _cropDisplayBounds = cropBounds; - + UIImage *image = _image; __instanceLock__.unlock(); @@ -640,14 +690,14 @@ - (void)setCropEnabled:(BOOL)cropEnabled recropImmediately:(BOOL)recropImmediate - (CGRect)cropRect { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); return _cropRect; } - (void)setCropRect:(CGRect)cropRect { { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); if (CGRectEqualToRect(_cropRect, cropRect)) { return; } @@ -670,37 +720,37 @@ - (void)setCropRect:(CGRect)cropRect - (BOOL)forceUpscaling { - ASDN::MutexLocker l(__instanceLock__); - return _forceUpscaling; + AS::MutexLocker l(__instanceLock__); + return _imageNodeFlags.forceUpscaling; } - (void)setForceUpscaling:(BOOL)forceUpscaling { - ASDN::MutexLocker l(__instanceLock__); - _forceUpscaling = forceUpscaling; + AS::MutexLocker l(__instanceLock__); + _imageNodeFlags.forceUpscaling = forceUpscaling; } - (CGSize)forcedSize { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); return _forcedSize; } - (void)setForcedSize:(CGSize)forcedSize { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); _forcedSize = forcedSize; } - (asimagenode_modification_block_t)imageModificationBlock { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); return _imageModificationBlock; } - (void)setImageModificationBlock:(asimagenode_modification_block_t)imageModificationBlock { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); _imageModificationBlock = imageModificationBlock; } @@ -709,7 +759,7 @@ - (void)setImageModificationBlock:(asimagenode_modification_block_t)imageModific - (void)layout { [super layout]; - + if (_debugLabelNode) { CGSize boundsSize = self.bounds.size; CGSize debugLabelSize = [_debugLabelNode layoutThatFits:ASSizeRangeMake(CGSizeZero, boundsSize)].size; @@ -727,44 +777,55 @@ - (NSDictionary *)debugLabelAttributes }; } +- (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection { + [super asyncTraitCollectionDidChangeWithPreviousTraitCollection:previousTraitCollection]; + + if (AS_AVAILABLE_IOS_TVOS(13, 10)) { + AS::MutexLocker l(__instanceLock__); + // update image if userInterfaceStyle was changed (dark mode) + if (_image != nil + && _primitiveTraitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle) { + _imageNodeFlags.regenerateFromImageAsset = YES; + } + } +} + + @end #pragma mark - Extras asimagenode_modification_block_t ASImageNodeRoundBorderModificationBlock(CGFloat borderWidth, UIColor *borderColor) { - return ^(UIImage *originalImage) { - ASGraphicsBeginImageContextWithOptions(originalImage.size, NO, originalImage.scale); - UIBezierPath *roundOutline = [UIBezierPath bezierPathWithOvalInRect:(CGRect){CGPointZero, originalImage.size}]; + return ^(UIImage *originalImage, ASPrimitiveTraitCollection traitCollection) { + return ASGraphicsCreateImage(traitCollection, originalImage.size, NO, originalImage.scale, originalImage, nil, ^{ + UIBezierPath *roundOutline = [UIBezierPath bezierPathWithOvalInRect:(CGRect){CGPointZero, originalImage.size}]; - // Make the image round - [roundOutline addClip]; + // Make the image round + [roundOutline addClip]; - // Draw the original image - [originalImage drawAtPoint:CGPointZero blendMode:kCGBlendModeCopy alpha:1]; + // Draw the original image + [originalImage drawAtPoint:CGPointZero blendMode:kCGBlendModeCopy alpha:1]; - // Draw a border on top. - if (borderWidth > 0.0) { - [borderColor setStroke]; - [roundOutline setLineWidth:borderWidth]; - [roundOutline stroke]; - } - - return ASGraphicsGetImageAndEndCurrentContext(); + // Draw a border on top. + if (borderWidth > 0.0) { + [borderColor setStroke]; + [roundOutline setLineWidth:borderWidth]; + [roundOutline stroke]; + } + }); }; } asimagenode_modification_block_t ASImageNodeTintColorModificationBlock(UIColor *color) { - return ^(UIImage *originalImage) { - ASGraphicsBeginImageContextWithOptions(originalImage.size, NO, originalImage.scale); - - // Set color and render template - [color setFill]; - UIImage *templateImage = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - [templateImage drawAtPoint:CGPointZero blendMode:kCGBlendModeCopy alpha:1]; - - UIImage *modifiedImage = ASGraphicsGetImageAndEndCurrentContext(); + return ^(UIImage *originalImage, ASPrimitiveTraitCollection traitCollection) { + UIImage *modifiedImage = ASGraphicsCreateImage(traitCollection, originalImage.size, NO, originalImage.scale, originalImage, nil, ^{ + // Set color and render template + [color setFill]; + UIImage *templateImage = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + [templateImage drawAtPoint:CGPointZero blendMode:kCGBlendModeCopy alpha:1]; + }); // if the original image was stretchy, keep it stretchy if (!UIEdgeInsetsEqualToEdgeInsets(originalImage.capInsets, UIEdgeInsetsZero)) { diff --git a/Example/Pods/Texture/Source/ASMainThreadDeallocation.mm b/Example/Pods/Texture/Source/ASMainThreadDeallocation.mm index 1cf90ad..8b732a5 100644 --- a/Example/Pods/Texture/Source/ASMainThreadDeallocation.mm +++ b/Example/Pods/Texture/Source/ASMainThreadDeallocation.mm @@ -8,15 +8,11 @@ #import -#import #import #import #import #import -#import -#import - @implementation NSObject (ASMainThreadIvarTeardown) - (void)scheduleIvarsForMainThreadDeallocation @@ -42,7 +38,7 @@ - (void)scheduleIvarsForMainThreadDeallocation } if ([object_getClass(value) needsMainThreadDeallocation]) { - as_log_debug(ASMainThreadDeallocationLog(), "%@: Trampolining ivar '%s' value %@ for main deallocation.", self, ivar_getName(ivar), value); + os_log_debug(ASMainThreadDeallocationLog(), "%@: Trampolining ivar '%s' value %@ for main deallocation.", self, ivar_getName(ivar), value); // Release the ivar's reference before handing the object to the queue so we // don't risk holding onto it longer than the queue does. @@ -50,7 +46,7 @@ - (void)scheduleIvarsForMainThreadDeallocation ASPerformMainThreadDeallocation(&value); } else { - as_log_debug(ASMainThreadDeallocationLog(), "%@: Not trampolining ivar '%s' value %@.", self, ivar_getName(ivar), value); + os_log_debug(ASMainThreadDeallocationLog(), "%@: Not trampolining ivar '%s' value %@.", self, ivar_getName(ivar), value); } } } diff --git a/Example/Pods/Texture/Source/ASMapNode.mm b/Example/Pods/Texture/Source/ASMapNode.mm index 1c204ab..599851e 100644 --- a/Example/Pods/Texture/Source/ASMapNode.mm +++ b/Example/Pods/Texture/Source/ASMapNode.mm @@ -16,7 +16,6 @@ #import #import #import -#import #import #import #import @@ -222,39 +221,38 @@ - (void)takeSnapshot CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height); - ASGraphicsBeginImageContextWithOptions(image.size, YES, image.scale); - [image drawAtPoint:CGPointZero]; - - UIImage *pinImage; - CGPoint pinCenterOffset = CGPointZero; - - // Get a standard annotation view pin if there is no custom annotation block. - if (!strongSelf.imageForStaticMapAnnotationBlock) { - pinImage = [strongSelf.class defaultPinImageWithCenterOffset:&pinCenterOffset]; - } - - for (id annotation in annotations) { - if (strongSelf.imageForStaticMapAnnotationBlock) { - // Get custom annotation image from custom annotation block. - pinImage = strongSelf.imageForStaticMapAnnotationBlock(annotation, &pinCenterOffset); - if (!pinImage) { - // just for case block returned nil, which can happen - pinImage = [strongSelf.class defaultPinImageWithCenterOffset:&pinCenterOffset]; - } + image = ASGraphicsCreateImage(strongSelf.primitiveTraitCollection, image.size, YES, image.scale, image, nil, ^{ + [image drawAtPoint:CGPointZero]; + + UIImage *pinImage; + CGPoint pinCenterOffset = CGPointZero; + + // Get a standard annotation view pin if there is no custom annotation block. + if (!strongSelf.imageForStaticMapAnnotationBlock) { + pinImage = [strongSelf.class defaultPinImageWithCenterOffset:&pinCenterOffset]; } - - CGPoint point = [snapshot pointForCoordinate:annotation.coordinate]; - if (CGRectContainsPoint(finalImageRect, point)) { - CGSize pinSize = pinImage.size; - point.x -= pinSize.width / 2.0; - point.y -= pinSize.height / 2.0; - point.x += pinCenterOffset.x; - point.y += pinCenterOffset.y; - [pinImage drawAtPoint:point]; + + for (id annotation in annotations) { + if (strongSelf.imageForStaticMapAnnotationBlock) { + // Get custom annotation image from custom annotation block. + pinImage = strongSelf.imageForStaticMapAnnotationBlock(annotation, &pinCenterOffset); + if (!pinImage) { + // just for case block returned nil, which can happen + pinImage = [strongSelf.class defaultPinImageWithCenterOffset:&pinCenterOffset]; + } + } + + CGPoint point = [snapshot pointForCoordinate:annotation.coordinate]; + if (CGRectContainsPoint(finalImageRect, point)) { + CGSize pinSize = pinImage.size; + point.x -= pinSize.width / 2.0; + point.y -= pinSize.height / 2.0; + point.x += pinCenterOffset.x; + point.y += pinCenterOffset.y; + [pinImage drawAtPoint:point]; + } } - } - - image = ASGraphicsGetImageAndEndCurrentContext(); + }); } strongSelf.image = image; diff --git a/Example/Pods/Texture/Source/ASMultiplexImageNode.h b/Example/Pods/Texture/Source/ASMultiplexImageNode.h index 503b5cb..72a913a 100644 --- a/Example/Pods/Texture/Source/ASMultiplexImageNode.h +++ b/Example/Pods/Texture/Source/ASMultiplexImageNode.h @@ -9,7 +9,14 @@ #import #import + +#if AS_USE_PHOTOS #import +#else +@class PHAsset; +@class PHImageManager; +@class PHImageRequestOptions; +#endif NS_ASSUME_NONNULL_BEGIN @@ -18,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN typedef id ASImageIdentifier; -AS_EXTERN NSString *const ASMultiplexImageNodeErrorDomain; +ASDK_EXTERN NSString *const ASMultiplexImageNodeErrorDomain; /** * ASMultiplexImageNode error codes. @@ -125,10 +132,11 @@ typedef NS_ENUM(NSUInteger, ASMultiplexImageNodeErrorCode) { /** * @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) PHImageManager *imageManager API_AVAILABLE(ios(8.0), tvos(10.0)); + @end @@ -249,6 +257,9 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier @end #pragma mark - + +#if AS_USE_PHOTOS + @interface NSURL (ASPhotosFrameworkURLs) /** @@ -266,4 +277,6 @@ didFinishDownloadingImageWithIdentifier:(ASImageIdentifier)imageIdentifier @end +#endif + NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASMultiplexImageNode.mm b/Example/Pods/Texture/Source/ASMultiplexImageNode.mm index 3af8e5f..55de28d 100644 --- a/Example/Pods/Texture/Source/ASMultiplexImageNode.mm +++ b/Example/Pods/Texture/Source/ASMultiplexImageNode.mm @@ -13,7 +13,6 @@ #import #endif -#import #import #import #import @@ -32,14 +31,14 @@ #import #endif +using AS::MutexLocker; + NSString *const ASMultiplexImageNodeErrorDomain = @"ASMultiplexImageNodeErrorDomain"; #if AS_USE_ASSETS_LIBRARY static NSString *const kAssetsLibraryURLScheme = @"assets-library"; #endif -static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - /** @abstract Signature for the block to be performed after an image has loaded. @param image The image that was loaded, or nil if no image was loaded. @@ -53,7 +52,13 @@ @interface ASMultiplexImageNode () @private // Core. id _cache; + id _downloader; + struct { + unsigned int downloaderImplementsSetProgress:1; + unsigned int downloaderImplementsSetPriority:1; + unsigned int downloaderImplementsDownloadWithPriority:1; + } _downloaderFlags; __weak id _delegate; struct { @@ -74,7 +79,7 @@ @interface ASMultiplexImageNode () // Image flags. BOOL _downloadsIntermediateImages; // Defaults to NO. - ASDN::Mutex _imageIdentifiersLock; + AS::Mutex _imageIdentifiersLock; NSArray *_imageIdentifiers; id _loadedImageIdentifier; id _loadingImageIdentifier; @@ -82,15 +87,13 @@ @interface ASMultiplexImageNode () __weak NSOperation *_phImageRequestOperation; // Networking. - ASDN::RecursiveMutex _downloadIdentifierLock; + AS::RecursiveMutex _downloadIdentifierLock; id _downloadIdentifier; // Properties BOOL _shouldRenderProgressImages; //set on init only - BOOL _downloaderImplementsSetProgress; - BOOL _downloaderImplementsSetPriority; BOOL _cacheSupportsClearing; } @@ -171,13 +174,14 @@ - (instancetype)initWithCache:(id)cache downloader:(id)cache; _downloader = (id)downloader; - _downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)]; - _downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)]; + _downloaderFlags.downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)]; + _downloaderFlags.downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)]; + _downloaderFlags.downloaderImplementsDownloadWithPriority = [downloader respondsToSelector:@selector(downloadImageWithURL:priority:callbackQueue:downloadProgress:completion:)]; _cacheSupportsClearing = [cache respondsToSelector:@selector(clearFetchedImageFromCacheWithURL:)]; _shouldRenderProgressImages = YES; - + self.shouldBypassEnsureDisplay = YES; return self; @@ -271,17 +275,8 @@ - (BOOL)placeholderShouldPersist - (void)displayWillStartAsynchronously:(BOOL)asynchronously { [super displayWillStartAsynchronously:asynchronously]; - [self didEnterPreloadState]; - - if (_downloaderImplementsSetPriority) { - { - ASDN::MutexLocker l(_downloadIdentifierLock); - if (_downloadIdentifier != nil) { - [_downloader setPriority:ASImageDownloaderPriorityImminent withDownloadIdentifier:_downloadIdentifier]; - } - } - } + [self _updatePriorityOnDownloaderIfNeeded]; } /* didEnterVisibleState / didExitVisibleState in ASNetworkImageNode has a very similar implementation. Changes here are likely necessary @@ -289,31 +284,23 @@ - (void)displayWillStartAsynchronously:(BOOL)asynchronously - (void)didEnterVisibleState { [super didEnterVisibleState]; - - if (_downloaderImplementsSetPriority) { - ASDN::MutexLocker l(_downloadIdentifierLock); - if (_downloadIdentifier != nil) { - [_downloader setPriority:ASImageDownloaderPriorityVisible withDownloadIdentifier:_downloadIdentifier]; - } - } - + [self _updatePriorityOnDownloaderIfNeeded]; [self _updateProgressImageBlockOnDownloaderIfNeeded]; } - (void)didExitVisibleState { [super didExitVisibleState]; - - if (_downloaderImplementsSetPriority) { - ASDN::MutexLocker l(_downloadIdentifierLock); - if (_downloadIdentifier != nil) { - [_downloader setPriority:ASImageDownloaderPriorityPreload withDownloadIdentifier:_downloadIdentifier]; - } - } - + [self _updatePriorityOnDownloaderIfNeeded]; [self _updateProgressImageBlockOnDownloaderIfNeeded]; } +- (void)didExitDisplayState +{ + [super didExitDisplayState]; + [self _updatePriorityOnDownloaderIfNeeded]; +} + #pragma mark - Core - (void)setImage:(UIImage *)image @@ -381,14 +368,14 @@ - (BOOL)shouldRenderProgressImages - (NSArray *)imageIdentifiers { - ASDN::MutexLocker l(_imageIdentifiersLock); + MutexLocker l(_imageIdentifiersLock); return _imageIdentifiers; } - (void)setImageIdentifiers:(NSArray *)imageIdentifiers { { - ASDN::MutexLocker l(_imageIdentifiersLock); + MutexLocker l(_imageIdentifiersLock); if (ASObjectIsEqual(_imageIdentifiers, imageIdentifiers)) { return; } @@ -439,7 +426,7 @@ - (void)_setDisplayedImageIdentifier:(id)displayedImageIdentifier withImage:(UII - (void)_setDownloadIdentifier:(id)downloadIdentifier { - ASDN::MutexLocker l(_downloadIdentifierLock); + MutexLocker l(_downloadIdentifierLock); if (ASObjectIsEqual(downloadIdentifier, _downloadIdentifier)) return; @@ -449,7 +436,6 @@ - (void)_setDownloadIdentifier:(id)downloadIdentifier _downloadIdentifier = downloadIdentifier; } - #pragma mark - Image Loading Machinery - (void)_loadImageIdentifiers @@ -465,7 +451,7 @@ - (void)_loadImageIdentifiers - (UIImage *)_bestImmediatelyAvailableImageFromDataSource:(id *)imageIdentifierOut { - ASDN::MutexLocker l(_imageIdentifiersLock); + MutexLocker l(_imageIdentifiersLock); // If we don't have any identifiers to load or don't implement the image DS method, bail. if ([_imageIdentifiers count] == 0 || !_dataSourceFlags.image) { @@ -493,6 +479,22 @@ - (UIImage *)_bestImmediatelyAvailableImageFromDataSource:(id *)imageIdentifierO #pragma mark - +- (void)_updatePriorityOnDownloaderIfNeeded +{ + DISABLED_ASAssertUnlocked(_downloadIdentifierLock); + + if (_downloaderFlags.downloaderImplementsSetPriority) { + // Read our interface state before locking so that we don't lock super while holding our lock. + ASInterfaceState interfaceState = self.interfaceState; + MutexLocker l(_downloadIdentifierLock); + + if (_downloadIdentifier != nil) { + ASImageDownloaderPriority priority = ASImageDownloaderPriorityWithInterfaceState(interfaceState); + [_downloader setPriority:priority withDownloadIdentifier:_downloadIdentifier]; + } + } +} + - (void)_updateProgressImageBlockOnDownloaderIfNeeded { DISABLED_ASAssertUnlocked(_downloadIdentifierLock); @@ -501,9 +503,9 @@ - (void)_updateProgressImageBlockOnDownloaderIfNeeded // Read our interface state before locking so that we don't lock super while holding our lock. ASInterfaceState interfaceState = self.interfaceState; - ASDN::MutexLocker l(_downloadIdentifierLock); + MutexLocker l(_downloadIdentifierLock); - if (!_downloaderImplementsSetProgress || _downloadIdentifier == nil) { + if (!_downloaderFlags.downloaderImplementsSetProgress || _downloadIdentifier == nil) { return; } @@ -516,7 +518,7 @@ - (void)_updateProgressImageBlockOnDownloaderIfNeeded return; } - ASDN::MutexLocker l(strongSelf->_downloadIdentifierLock); + MutexLocker l(strongSelf->_downloadIdentifierLock); //Getting a result back for a different download identifier, download must not have been successfully canceled if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) { return; @@ -529,23 +531,13 @@ - (void)_updateProgressImageBlockOnDownloaderIfNeeded - (void)_clearImage { - // Destruction of bigger images on the main thread can be expensive - // and can take some time, so we dispatch onto a bg queue to - // actually dealloc. - UIImage *image = self.image; - CGSize imageSize = image.size; - BOOL shouldReleaseImageOnBackgroundThread = imageSize.width > kMinReleaseImageOnBackgroundSize.width || - imageSize.height > kMinReleaseImageOnBackgroundSize.height; [self _setImage:nil]; - if (shouldReleaseImageOnBackgroundThread) { - ASPerformBackgroundDeallocation(&image); - } } #pragma mark - - (id)_nextImageIdentifierToDownload { - ASDN::MutexLocker l(_imageIdentifiersLock); + MutexLocker l(_imageIdentifiersLock); // If we've already loaded the best identifier, we've got nothing else to do. id bestImageIdentifier = _imageIdentifiers.firstObject; @@ -615,7 +607,7 @@ - (void)_loadNextImage NSURL *nextImageURL = (_dataSourceFlags.URL) ? [_dataSource multiplexImageNode:self URLForImageIdentifier:nextImageIdentifier] : nil; // If we fail to get a URL for the image, we have no source and can't proceed. if (!nextImageURL) { - as_log_error(ASImageLoadingLog(), "Could not acquire URL %@ ident: (%@)", self, nextImageIdentifier); + os_log_error(ASImageLoadingLog(), "Could not acquire URL %@ ident: (%@)", self, nextImageIdentifier); finishedLoadingBlock(nil, nil, [NSError errorWithDomain:ASMultiplexImageNodeErrorDomain code:ASMultiplexImageNodeErrorCodeNoSourceForImage userInfo:nil]); return; } @@ -673,7 +665,7 @@ - (void)_loadNextImage 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); + os_log_error(ASImageLoadingLog(), "Error downloading image for %@ id: %@ err: %@", strongSelf, nextImageIdentifier, error); } finishedLoadingBlock(downloadedImage, nextImageIdentifier, error); }]; @@ -738,7 +730,7 @@ - (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identif PHAsset *imageAsset = nil; // Try to get the asset immediately from the data source. - if (_dataSourceFlags.asset) { + if (strongSelf->_dataSourceFlags.asset) { imageAsset = [strongSelf.dataSource multiplexImageNode:strongSelf assetForLocalIdentifier:request.assetIdentifier]; } @@ -802,7 +794,7 @@ - (void)_fetchImageWithIdentifierFromCache:(id)imageIdentifier URL:(NSURL *)imag ASDisplayNodeAssertNotNil(completionBlock, @"completionBlock is required"); if (_cache) { - [_cache cachedImageWithURL:imageURL callbackQueue:dispatch_get_main_queue() completion:^(id imageContainer) { + [_cache cachedImageWithURL:imageURL callbackQueue:dispatch_get_main_queue() completion:^(id imageContainer, __unused ASImageCacheType cacheType ) { completionBlock([imageContainer asdk_image]); }]; } @@ -823,7 +815,7 @@ - (void)_downloadImageWithIdentifier:(id)imageIdentifier URL:(NSURL *)imageURL c [_delegate multiplexImageNode:self didStartDownloadOfImageWithIdentifier:imageIdentifier]; __weak __typeof__(self) weakSelf = self; - void (^downloadProgressBlock)(CGFloat) = nil; + ASImageDownloaderProgress downloadProgressBlock = NULL; if (_delegateFlags.downloadProgress) { downloadProgressBlock = ^(CGFloat progress) { __typeof__(self) strongSelf = weakSelf; @@ -833,30 +825,65 @@ - (void)_downloadImageWithIdentifier:(id)imageIdentifier URL:(NSURL *)imageURL c }; } + ASImageDownloaderCompletion completion = ^(id imageContainer, NSError *error, id downloadIdentifier, id userInfo) { + // We dereference iVars directly, so we can't have weakSelf going nil on us. + __typeof__(self) strongSelf = weakSelf; + if (!strongSelf) + return; + + MutexLocker l(strongSelf->_downloadIdentifierLock); + //Getting a result back for a different download identifier, download must not have been successfully canceled + if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) { + return; + } + + completionBlock([imageContainer asdk_image], error); + + // Delegateify. + if (strongSelf->_delegateFlags.downloadFinish) + [strongSelf->_delegate multiplexImageNode:weakSelf didFinishDownloadingImageWithIdentifier:imageIdentifier error:error]; + }; + // Download! ASPerformBlockOnBackgroundThread(^{ - [self _setDownloadIdentifier:[_downloader downloadImageWithURL:imageURL - callbackQueue:dispatch_get_main_queue() - downloadProgress:downloadProgressBlock - completion:^(id imageContainer, NSError *error, id downloadIdentifier, id userInfo) { - // We dereference iVars directly, so we can't have weakSelf going nil on us. - __typeof__(self) strongSelf = weakSelf; - if (!strongSelf) - return; - - ASDN::MutexLocker l(_downloadIdentifierLock); - //Getting a result back for a different download identifier, download must not have been successfully canceled - if (ASObjectIsEqual(_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) { - return; - } - - completionBlock([imageContainer asdk_image], error); - - // Delegateify. - if (strongSelf->_delegateFlags.downloadFinish) - [strongSelf->_delegate multiplexImageNode:weakSelf didFinishDownloadingImageWithIdentifier:imageIdentifier error:error]; - }]]; - [self _updateProgressImageBlockOnDownloaderIfNeeded]; + __typeof__(self) strongSelf = weakSelf; + if (!strongSelf) + return; + + dispatch_queue_t callbackQueue = dispatch_get_main_queue(); + + id downloadIdentifier; + if (strongSelf->_downloaderFlags.downloaderImplementsDownloadWithPriority) { + /* + Decide a priority based on the current interface state of this node. + It can happen that this method was called when the node entered preload state + but the interface state, at this point, tells us that the node is (going to be) visible, + If that's the case, we jump to a higher priority directly. + */ + ASImageDownloaderPriority priority = ASImageDownloaderPriorityWithInterfaceState(strongSelf.interfaceState); + downloadIdentifier = [strongSelf->_downloader downloadImageWithURL:imageURL + priority:priority + callbackQueue:callbackQueue + downloadProgress:downloadProgressBlock + completion:completion]; + } else { + /* + Kick off a download with default priority. + The actual "default" value is decided by the downloader. + ASBasicImageDownloader and ASPINRemoteImageDownloader both use ASImageDownloaderPriorityImminent + which is mapped to NSURLSessionTaskPriorityDefault. + + This means that preload and display nodes use the same priority + and their requests are put into the same pool. + */ + downloadIdentifier = [strongSelf->_downloader downloadImageWithURL:imageURL + callbackQueue:callbackQueue + downloadProgress:downloadProgressBlock + completion:completion]; + } + + [strongSelf _setDownloadIdentifier:downloadIdentifier]; + [strongSelf _updateProgressImageBlockOnDownloaderIfNeeded]; }); } diff --git a/Example/Pods/Texture/Source/ASNavigationController.h b/Example/Pods/Texture/Source/ASNavigationController.h index cd6e417..0d259b2 100644 --- a/Example/Pods/Texture/Source/ASNavigationController.h +++ b/Example/Pods/Texture/Source/ASNavigationController.h @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN * * @discussion ASNavigationController is a drop in replacement for UINavigationController * which improves memory efficiency by implementing the @c ASManagesChildVisibilityDepth protocol. - * You can use ASNavigationController with regular UIViewControllers, as well as ASViewControllers. + * You can use ASNavigationController with regular UIViewControllers, as well as ASDKViewControllers. * It is safe to subclass or use even where AsyncDisplayKit is not adopted. * * @see ASManagesChildVisibilityDepth diff --git a/Example/Pods/Texture/Source/ASNavigationController.mm b/Example/Pods/Texture/Source/ASNavigationController.mm index 0e4abc3..2fbc488 100644 --- a/Example/Pods/Texture/Source/ASNavigationController.mm +++ b/Example/Pods/Texture/Source/ASNavigationController.mm @@ -61,7 +61,7 @@ - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BO { as_activity_create_for_scope("Pop multiple from ASNavigationController"); NSArray *viewControllers = [super popToViewController:viewController animated:animated]; - as_log_info(ASNodeLog(), "Popped %@ to %@, removing %@", self, viewController, ASGetDescriptionValueString(viewControllers)); + os_log_info(ASNodeLog(), "Popped %@ to %@, removing %@", self, viewController, ASGetDescriptionValueString(viewControllers)); [self visibilityDepthDidChange]; return viewControllers; @@ -71,7 +71,7 @@ - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated { as_activity_create_for_scope("Pop to root of ASNavigationController"); NSArray *viewControllers = [super popToRootViewControllerAnimated:animated]; - as_log_info(ASNodeLog(), "Popped view controllers %@ from %@", ASGetDescriptionValueString(viewControllers), self); + os_log_info(ASNodeLog(), "Popped view controllers %@ from %@", ASGetDescriptionValueString(viewControllers), self); [self visibilityDepthDidChange]; return viewControllers; @@ -88,7 +88,7 @@ - (void)setViewControllers:(NSArray *)viewControllers - (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated { as_activity_create_for_scope("Set view controllers of ASNavigationController"); - as_log_info(ASNodeLog(), "Set view controllers of %@ to %@ animated: %d", self, ASGetDescriptionValueString(viewControllers), animated); + os_log_info(ASNodeLog(), "Set view controllers of %@ to %@ animated: %d", self, ASGetDescriptionValueString(viewControllers), animated); [super setViewControllers:viewControllers animated:animated]; [self visibilityDepthDidChange]; } @@ -96,7 +96,7 @@ - (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { as_activity_create_for_scope("Push view controller on ASNavigationController"); - as_log_info(ASNodeLog(), "Pushing %@ onto %@", viewController, self); + os_log_info(ASNodeLog(), "Pushing %@ onto %@", viewController, self); [super pushViewController:viewController animated:animated]; [self visibilityDepthDidChange]; } @@ -105,7 +105,7 @@ - (UIViewController *)popViewControllerAnimated:(BOOL)animated { as_activity_create_for_scope("Pop view controller from ASNavigationController"); UIViewController *viewController = [super popViewControllerAnimated:animated]; - as_log_info(ASNodeLog(), "Popped %@ from %@", viewController, self); + os_log_info(ASNodeLog(), "Popped %@ from %@", viewController, self); [self visibilityDepthDidChange]; return viewController; } diff --git a/Example/Pods/Texture/Source/ASNetworkImageLoadInfo.mm b/Example/Pods/Texture/Source/ASNetworkImageLoadInfo.mm index 4c3d553..64ec547 100644 --- a/Example/Pods/Texture/Source/ASNetworkImageLoadInfo.mm +++ b/Example/Pods/Texture/Source/ASNetworkImageLoadInfo.mm @@ -7,7 +7,6 @@ // #import -#import @implementation ASNetworkImageLoadInfo diff --git a/Example/Pods/Texture/Source/ASNetworkImageNode.h b/Example/Pods/Texture/Source/ASNetworkImageNode.h index 33bddb1..fa07a3d 100644 --- a/Example/Pods/Texture/Source/ASNetworkImageNode.h +++ b/Example/Pods/Texture/Source/ASNetworkImageNode.h @@ -133,6 +133,13 @@ NS_ASSUME_NONNULL_BEGIN */ @property (readonly) CGFloat renderedImageQuality; +/** + * Download progress of the current image. + * When downloading a network image, this value would be updated to track download progress (value between 0 and 1) + * This is 1 if image load from cache or network successfully. + */ +@property (readonly) CGFloat downloadProgress; + @end @@ -172,6 +179,15 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)imageNodeDidLoadImageFromCache:(ASNetworkImageNode *)imageNode; +/** + * Notification that the image node failed to load image from cache + * + * @param imageNode The sender. + * + * @discussion Called on the main thread. + */ +- (void)imageNodeDidFailToLoadImageFromCache:(ASNetworkImageNode *)imageNode; + /** * Notification that the image node will load image from network * diff --git a/Example/Pods/Texture/Source/ASNetworkImageNode.mm b/Example/Pods/Texture/Source/ASNetworkImageNode.mm index e7a134b..085fc06 100644 --- a/Example/Pods/Texture/Source/ASNetworkImageNode.mm +++ b/Example/Pods/Texture/Source/ASNetworkImageNode.mm @@ -9,22 +9,17 @@ #import -#import #import #import #import -#import #import #import #import #import #import #import -#import #import -#import - #if AS_PIN_REMOTE_IMAGE #import #endif @@ -42,40 +37,43 @@ @interface ASNetworkImageNode () // The download identifier that we have set a progress block on, if any. id _downloadIdentifierForProgressBlock; - BOOL _imageLoaded; - BOOL _imageWasSetExternally; CGFloat _currentImageQuality; CGFloat _renderedImageQuality; - BOOL _shouldRenderProgressImages; - - struct { - unsigned int delegateWillStartDisplayAsynchronously:1; - unsigned int delegateWillLoadImageFromCache:1; - unsigned int delegateWillLoadImageFromNetwork:1; - unsigned int delegateDidStartFetchingData:1; - unsigned int delegateDidFailWithError:1; - unsigned int delegateDidFinishDecoding:1; - unsigned int delegateDidLoadImage:1; - unsigned int delegateDidLoadImageFromCache:1; - unsigned int delegateDidLoadImageWithInfo:1; - } _delegateFlags; + CGFloat _downloadProgress; - - // Immutable and set on init only. We don't need to lock in this case. + // Immutable and set on init only. We don't need to lock in this case. __weak id _downloader; - struct { - unsigned int downloaderImplementsSetProgress:1; - unsigned int downloaderImplementsSetPriority:1; - unsigned int downloaderImplementsAnimatedImage:1; - unsigned int downloaderImplementsCancelWithResume:1; - } _downloaderFlags; // Immutable and set on init only. We don't need to lock in this case. __weak id _cache; + + // Group all of these BOOLs into a shared bitfield struct in order to save on memory used. struct { - unsigned int cacheSupportsClearing:1; - unsigned int cacheSupportsSynchronousFetch:1; - } _cacheFlags; + unsigned int delegateWillStartDisplayAsynchronously:1; + unsigned int delegateWillLoadImageFromCache:1; + unsigned int delegateWillLoadImageFromNetwork:1; + unsigned int delegateDidStartFetchingData:1; + unsigned int delegateDidFailWithError:1; + unsigned int delegateDidFinishDecoding:1; + unsigned int delegateDidLoadImage:1; + unsigned int delegateDidLoadImageFromCache:1; + unsigned int delegateDidLoadImageWithInfo:1; + unsigned int delegateDidFailToLoadImageFromCache:1; + + unsigned int downloaderImplementsSetProgress:1; + unsigned int downloaderImplementsSetPriority:1; + unsigned int downloaderImplementsAnimatedImage:1; + unsigned int downloaderImplementsCancelWithResume:1; + unsigned int downloaderImplementsDownloadWithPriority:1; + + unsigned int cacheSupportsClearing:1; + unsigned int cacheSupportsSynchronousFetch:1; + + unsigned int imageLoaded:1; + unsigned int imageWasSetExternally:1; + unsigned int shouldRenderProgressImages:1; + unsigned int shouldCacheImage:1; + } _networkImageNodeFlags; } @end @@ -94,16 +92,17 @@ - (instancetype)initWithCache:(id)cache downloader:(id)cache; _downloader = (id)downloader; - _downloaderFlags.downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)]; - _downloaderFlags.downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)]; - _downloaderFlags.downloaderImplementsAnimatedImage = [downloader respondsToSelector:@selector(animatedImageWithData:)]; - _downloaderFlags.downloaderImplementsCancelWithResume = [downloader respondsToSelector:@selector(cancelImageDownloadWithResumePossibilityForIdentifier:)]; - - _cacheFlags.cacheSupportsClearing = [cache respondsToSelector:@selector(clearFetchedImageFromCacheWithURL:)]; - _cacheFlags.cacheSupportsSynchronousFetch = [cache respondsToSelector:@selector(synchronouslyFetchedCachedImageWithURL:)]; + _networkImageNodeFlags.downloaderImplementsSetProgress = [downloader respondsToSelector:@selector(setProgressImageBlock:callbackQueue:withDownloadIdentifier:)]; + _networkImageNodeFlags.downloaderImplementsSetPriority = [downloader respondsToSelector:@selector(setPriority:withDownloadIdentifier:)]; + _networkImageNodeFlags.downloaderImplementsAnimatedImage = [downloader respondsToSelector:@selector(animatedImageWithData:)]; + _networkImageNodeFlags.downloaderImplementsCancelWithResume = [downloader respondsToSelector:@selector(cancelImageDownloadWithResumePossibilityForIdentifier:)]; + _networkImageNodeFlags.downloaderImplementsDownloadWithPriority = [downloader respondsToSelector:@selector(downloadImageWithURL:priority:callbackQueue:downloadProgress:completion:)]; + + _networkImageNodeFlags.cacheSupportsClearing = [cache respondsToSelector:@selector(clearFetchedImageFromCacheWithURL:)]; + _networkImageNodeFlags.cacheSupportsSynchronousFetch = [cache respondsToSelector:@selector(synchronouslyFetchedCachedImageWithURL:)]; - _shouldCacheImage = YES; - _shouldRenderProgressImages = YES; + _networkImageNodeFlags.shouldCacheImage = YES; + _networkImageNodeFlags.shouldRenderProgressImages = YES; self.shouldBypassEnsureDisplay = YES; return self; @@ -125,21 +124,12 @@ - (void)dealloc - (dispatch_queue_t)callbackQueue { - static dispatch_once_t onceToken; - static dispatch_queue_t callbackQueue; - dispatch_once(&onceToken, ^{ - if (ASActivateExperimentalFeature(ASExperimentalNetworkImageQueue)) { - callbackQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - } else { - callbackQueue = dispatch_get_main_queue(); - } - }); - return callbackQueue; + return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); } #pragma mark - Public methods -- must lock -/// Setter for public image property. It has the side effect of setting an internal _imageWasSetExternally that prevents setting an image internally. Setting an image internally should happen with the _setImage: method +/// Setter for public image property. It has the side effect of setting an internal _networkImageNodeFlags.imageWasSetExternally that prevents setting an image internally. Setting an image internally should happen with the _setImage: method - (void)setImage:(UIImage *)image { ASLockScopeSelf(); @@ -151,8 +141,8 @@ - (void)_locked_setImage:(UIImage *)image DISABLED_ASAssertLocked(__instanceLock__); BOOL imageWasSetExternally = (image != nil); - BOOL shouldCancelAndClear = imageWasSetExternally && (imageWasSetExternally != _imageWasSetExternally); - _imageWasSetExternally = imageWasSetExternally; + BOOL shouldCancelAndClear = imageWasSetExternally && (imageWasSetExternally != _networkImageNodeFlags.imageWasSetExternally); + _networkImageNodeFlags.imageWasSetExternally = imageWasSetExternally; if (shouldCancelAndClear) { ASDisplayNodeAssertNil(_URL, @"Directly setting an image on an ASNetworkImageNode causes it to behave like an ASImageNode instead of an ASNetworkImageNode. If this is what you want, set the URL to nil first."); _URL = nil; @@ -162,6 +152,7 @@ - (void)_locked_setImage:(UIImage *)image // If our image is being set externally, the image quality is 100% if (imageWasSetExternally) { [self _setCurrentImageQuality:1.0]; + [self _setDownloadProgress:1.0]; } [self _locked__setImage:image]; @@ -208,13 +199,15 @@ - (void)setURL:(NSURL *)URL resetToDefault:(BOOL)reset URL = [URL copy]; - ASDisplayNodeAssert(_imageWasSetExternally == NO, @"Setting a URL to an ASNetworkImageNode after setting an image changes its behavior from an ASImageNode to an ASNetworkImageNode. If this is what you want, set the image to nil first."); + ASDisplayNodeAssert(_networkImageNodeFlags.imageWasSetExternally == NO, @"Setting a URL to an ASNetworkImageNode after setting an image changes its behavior from an ASImageNode to an ASNetworkImageNode. If this is what you want, set the image to nil first."); - _imageWasSetExternally = NO; + _networkImageNodeFlags.imageWasSetExternally = NO; [self _locked_cancelImageDownloadWithResumePossibility:NO]; - - _imageLoaded = NO; + + [self _setDownloadProgress:0.0]; + + _networkImageNodeFlags.imageLoaded = NO; _URL = URL; @@ -223,6 +216,7 @@ - (void)setURL:(NSURL *)URL resetToDefault:(BOOL)reset if (reset || hadURL) { [self _setCurrentImageQuality:(hadURL ? 0.0 : 1.0)]; [self _locked__setImage:_defaultImage]; + [self _locked_setAnimatedImage:nil]; } } @@ -249,7 +243,7 @@ - (void)_locked_setDefaultImage:(UIImage *)defaultImage _defaultImage = defaultImage; - if (!_imageLoaded) { + if (!_networkImageNodeFlags.imageLoaded) { [self _setCurrentImageQuality:((_URL == nil) ? 0.0 : 1.0)]; [self _locked__setImage:defaultImage]; } @@ -284,6 +278,30 @@ - (void)_setCurrentImageQuality:(CGFloat)imageQuality }); } +- (void)setDownloadProgress:(CGFloat)downloadProgress +{ + ASLockScopeSelf(); + _downloadProgress = downloadProgress; +} + +- (CGFloat)downloadProgress +{ + return ASLockedSelf(_downloadProgress); +} + +/** + * Always use these methods internally to update the current download progress + * We want to maintain the order that downloadProgress is set regardless of the calling thread, + * so we always have to dispatch to the main thread to ensure that we queue the operations in the correct order. + * (see comment in displayDidFinish) + */ +- (void)_setDownloadProgress:(CGFloat)downloadProgress +{ + dispatch_async(dispatch_get_main_queue(), ^{ + self.downloadProgress = downloadProgress; + }); +} + - (void)setRenderedImageQuality:(CGFloat)renderedImageQuality { ASLockScopeSelf(); @@ -301,15 +319,16 @@ - (void)setDelegate:(id)delegate ASLockScopeSelf(); _delegate = delegate; - _delegateFlags.delegateWillStartDisplayAsynchronously = [delegate respondsToSelector:@selector(imageNodeWillStartDisplayAsynchronously:)]; - _delegateFlags.delegateWillLoadImageFromCache = [delegate respondsToSelector:@selector(imageNodeWillLoadImageFromCache:)]; - _delegateFlags.delegateWillLoadImageFromNetwork = [delegate respondsToSelector:@selector(imageNodeWillLoadImageFromNetwork:)]; - _delegateFlags.delegateDidStartFetchingData = [delegate respondsToSelector:@selector(imageNodeDidStartFetchingData:)]; - _delegateFlags.delegateDidFailWithError = [delegate respondsToSelector:@selector(imageNode:didFailWithError:)]; - _delegateFlags.delegateDidFinishDecoding = [delegate respondsToSelector:@selector(imageNodeDidFinishDecoding:)]; - _delegateFlags.delegateDidLoadImage = [delegate respondsToSelector:@selector(imageNode:didLoadImage:)]; - _delegateFlags.delegateDidLoadImageFromCache = [delegate respondsToSelector:@selector(imageNodeDidLoadImageFromCache:)]; - _delegateFlags.delegateDidLoadImageWithInfo = [delegate respondsToSelector:@selector(imageNode:didLoadImage:info:)]; + _networkImageNodeFlags.delegateWillStartDisplayAsynchronously = [delegate respondsToSelector:@selector(imageNodeWillStartDisplayAsynchronously:)]; + _networkImageNodeFlags.delegateWillLoadImageFromCache = [delegate respondsToSelector:@selector(imageNodeWillLoadImageFromCache:)]; + _networkImageNodeFlags.delegateWillLoadImageFromNetwork = [delegate respondsToSelector:@selector(imageNodeWillLoadImageFromNetwork:)]; + _networkImageNodeFlags.delegateDidStartFetchingData = [delegate respondsToSelector:@selector(imageNodeDidStartFetchingData:)]; + _networkImageNodeFlags.delegateDidFailWithError = [delegate respondsToSelector:@selector(imageNode:didFailWithError:)]; + _networkImageNodeFlags.delegateDidFinishDecoding = [delegate respondsToSelector:@selector(imageNodeDidFinishDecoding:)]; + _networkImageNodeFlags.delegateDidLoadImage = [delegate respondsToSelector:@selector(imageNode:didLoadImage:)]; + _networkImageNodeFlags.delegateDidLoadImageFromCache = [delegate respondsToSelector:@selector(imageNodeDidLoadImageFromCache:)]; + _networkImageNodeFlags.delegateDidLoadImageWithInfo = [delegate respondsToSelector:@selector(imageNode:didLoadImage:info:)]; + _networkImageNodeFlags.delegateDidFailToLoadImageFromCache = [delegate respondsToSelector:@selector(imageNodeDidFailToLoadImageFromCache:)]; } - (id)delegate @@ -320,7 +339,7 @@ - (void)setDelegate:(id)delegate - (void)setShouldRenderProgressImages:(BOOL)shouldRenderProgressImages { - if (ASLockedSelfCompareAssign(_shouldRenderProgressImages, shouldRenderProgressImages)) { + if (ASLockedSelfCompareAssign(_networkImageNodeFlags.shouldRenderProgressImages, shouldRenderProgressImages)) { [self _updateProgressImageBlockOnDownloaderIfNeeded]; } } @@ -328,7 +347,18 @@ - (void)setShouldRenderProgressImages:(BOOL)shouldRenderProgressImages - (BOOL)shouldRenderProgressImages { ASLockScopeSelf(); - return _shouldRenderProgressImages; + return _networkImageNodeFlags.shouldRenderProgressImages; +} + +- (void)setShouldCacheImage:(BOOL)shouldCacheImage +{ + ASLockedSelfCompareAssign(_networkImageNodeFlags.shouldCacheImage, shouldCacheImage); +} + +- (BOOL)shouldCacheImage +{ + ASLockScopeSelf(); + return _networkImageNodeFlags.shouldCacheImage; } - (BOOL)placeholderShouldPersist @@ -347,30 +377,31 @@ - (void)displayWillStartAsynchronously:(BOOL)asynchronously BOOL notifyDelegate; { ASLockScopeSelf(); - notifyDelegate = _delegateFlags.delegateWillStartDisplayAsynchronously; + notifyDelegate = _networkImageNodeFlags.delegateWillStartDisplayAsynchronously; delegate = _delegate; } if (notifyDelegate) { [delegate imageNodeWillStartDisplayAsynchronously:self]; } - if (asynchronously == NO && _cacheFlags.cacheSupportsSynchronousFetch) { + if (asynchronously == NO && _networkImageNodeFlags.cacheSupportsSynchronousFetch) { ASLockScopeSelf(); NSURL *url = _URL; - if (_imageLoaded == NO && url && _downloadIdentifier == nil) { + if (_networkImageNodeFlags.imageLoaded == NO && url && _downloadIdentifier == nil) { UIImage *result = [[_cache synchronouslyFetchedCachedImageWithURL:url] asdk_image]; if (result) { [self _setCurrentImageQuality:1.0]; + [self _setDownloadProgress:1.0]; [self _locked__setImage:result]; - _imageLoaded = YES; + _networkImageNodeFlags.imageLoaded = YES; // Call out to the delegate. - if (_delegateFlags.delegateDidLoadImageWithInfo) { + if (_networkImageNodeFlags.delegateDidLoadImageWithInfo) { ASUnlockScope(self); const auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:url sourceType:ASNetworkImageSourceSynchronousCache downloadIdentifier:nil userInfo:nil]; [delegate imageNode:self didLoadImage:result info:info]; - } else if (_delegateFlags.delegateDidLoadImage) { + } else if (_networkImageNodeFlags.delegateDidLoadImage) { ASUnlockScope(self); [delegate imageNode:self didLoadImage:result]; } @@ -378,11 +409,8 @@ - (void)displayWillStartAsynchronously:(BOOL)asynchronously } } - if (self.image == nil && _downloaderFlags.downloaderImplementsSetPriority) { - id downloadIdentifier = ASLockedSelf(_downloadIdentifier); - if (downloadIdentifier != nil) { - [_downloader setPriority:ASImageDownloaderPriorityImminent withDownloadIdentifier:downloadIdentifier]; - } + if (self.image == nil) { + [self _updatePriorityOnDownloaderIfNeeded]; } } @@ -391,41 +419,29 @@ - (void)displayWillStartAsynchronously:(BOOL)asynchronously - (void)didEnterVisibleState { [super didEnterVisibleState]; - - id downloadIdentifier = ({ - ASLockScopeSelf(); - _downloaderFlags.downloaderImplementsSetPriority ? _downloadIdentifier : nil; - }); - - if (downloadIdentifier != nil) { - [_downloader setPriority:ASImageDownloaderPriorityVisible withDownloadIdentifier:downloadIdentifier]; - } - + [self _updatePriorityOnDownloaderIfNeeded]; [self _updateProgressImageBlockOnDownloaderIfNeeded]; } - (void)didExitVisibleState { [super didExitVisibleState]; - - id downloadIdentifier = ({ - ASLockScopeSelf(); - _downloaderFlags.downloaderImplementsSetPriority ? _downloadIdentifier : nil; - }); - - if (downloadIdentifier != nil) { - [_downloader setPriority:ASImageDownloaderPriorityPreload withDownloadIdentifier:downloadIdentifier]; - } - + [self _updatePriorityOnDownloaderIfNeeded]; [self _updateProgressImageBlockOnDownloaderIfNeeded]; } +- (void)didExitDisplayState +{ + [super didExitDisplayState]; + [self _updatePriorityOnDownloaderIfNeeded]; +} + - (void)didExitPreloadState { [super didExitPreloadState]; // If the image was set explicitly we don't want to remove it while exiting the preload state - if (ASLockedSelf(_imageWasSetExternally)) { + if (ASLockedSelf(_networkImageNodeFlags.imageWasSetExternally)) { return; } @@ -452,6 +468,17 @@ + (BOOL)useMainThreadDelegateCallbacks #pragma mark - Progress +- (void)_updateDownloadedProgress:(CGFloat)progress + downloadIdentifier:(nullable id)downloadIdentifier +{ + ASLockScopeSelf(); + // Getting a result back for a different download identifier, download must not have been successfully canceled + if (ASObjectIsEqual(_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) { + return; + } + [self _setDownloadProgress:progress]; +} + - (void)handleProgressImage:(UIImage *)progressImage progress:(CGFloat)progress downloadIdentifier:(nullable id)downloadIdentifier { ASLockScopeSelf(); @@ -466,16 +493,28 @@ - (void)handleProgressImage:(UIImage *)progressImage progress:(CGFloat)progress [self _locked__setImage:progressImage]; } +- (void)_updatePriorityOnDownloaderIfNeeded +{ + if (_networkImageNodeFlags.downloaderImplementsSetPriority) { + ASLockScopeSelf(); + + if (_downloadIdentifier != nil) { + ASImageDownloaderPriority priority = ASImageDownloaderPriorityWithInterfaceState(_interfaceState); + [_downloader setPriority:priority withDownloadIdentifier:_downloadIdentifier]; + } + } +} + - (void)_updateProgressImageBlockOnDownloaderIfNeeded { // If the downloader doesn't do progress, we are done. - if (_downloaderFlags.downloaderImplementsSetProgress == NO) { + if (_networkImageNodeFlags.downloaderImplementsSetProgress == NO) { return; } // Read state. [self lock]; - BOOL shouldRender = _shouldRenderProgressImages && ASInterfaceStateIncludesVisible(_interfaceState); + BOOL shouldRender = _networkImageNodeFlags.shouldRenderProgressImages && ASInterfaceStateIncludesVisible(_interfaceState); id oldDownloadIDForProgressBlock = _downloadIdentifierForProgressBlock; id newDownloadIDForProgressBlock = shouldRender ? _downloadIdentifier : nil; BOOL clearAndReattempt = NO; @@ -517,9 +556,7 @@ - (void)_updateProgressImageBlockOnDownloaderIfNeeded if (clearAndReattempt) { // In this case another thread changed the _downloadIdentifierForProgressBlock before we finished registering // the new progress block for newDownloadIDForProgressBlock ID. Let's clear it now and reattempt to register - if (newDownloadIDForProgressBlock) { - [_downloader setProgressImageBlock:nil callbackQueue:[self callbackQueue] withDownloadIdentifier:newDownloadIDForProgressBlock]; - } + [_downloader setProgressImageBlock:nil callbackQueue:[self callbackQueue] withDownloadIdentifier:newDownloadIDForProgressBlock]; [self _updateProgressImageBlockOnDownloaderIfNeeded]; } } @@ -538,11 +575,12 @@ - (void)_locked_cancelDownloadAndClearImageWithResumePossibility:(BOOL)storeResu [self _locked_setAnimatedImage:nil]; [self _setCurrentImageQuality:0.0]; + [self _setDownloadProgress:0.0]; [self _locked__setImage:_defaultImage]; - _imageLoaded = NO; + _networkImageNodeFlags.imageLoaded = NO; - if (_cacheFlags.cacheSupportsClearing) { + if (_networkImageNodeFlags.cacheSupportsClearing) { if (_URL != nil) { as_log_verbose(ASImageLoadingLog(), "Clearing cached image for %@ url: %@", self, _URL); [_cache clearFetchedImageFromCacheWithURL:_URL]; @@ -565,8 +603,8 @@ - (void)_locked_cancelImageDownloadWithResumePossibility:(BOOL)storeResume } if (_downloadIdentifier) { - if (storeResume && _downloaderFlags.downloaderImplementsCancelWithResume) { - as_log_verbose(ASImageLoadingLog(), "Canceling image download w resume for %@ id: %@", self, _downloadIdentifier); + if (storeResume && _networkImageNodeFlags.downloaderImplementsCancelWithResume) { + as_log_verbose(ASImageLoadingLog(), "Canceling image download with resume for %@ id: %@", self, _downloadIdentifier); [_downloader cancelImageDownloadWithResumePossibilityForIdentifier:_downloadIdentifier]; } else { as_log_verbose(ASImageLoadingLog(), "Canceling image download no resume for %@ id: %@", self, _downloadIdentifier); @@ -583,24 +621,61 @@ - (void)_downloadImageWithCompletion:(void (^)(id ima NSURL *url; id downloadIdentifier; BOOL cancelAndReattempt = NO; - + ASInterfaceState interfaceState; + // Below, to avoid performance issues, we're calling downloadImageWithURL without holding the lock. This is a bit ugly because // We need to reobtain the lock after and ensure that the task we've kicked off still matches our URL. If not, we need to cancel // it and try again. { ASLockScopeSelf(); url = self->_URL; + interfaceState = self->_interfaceState; } - - downloadIdentifier = [self->_downloader downloadImageWithURL:url - callbackQueue:[self callbackQueue] - downloadProgress:NULL - completion:^(id _Nullable imageContainer, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo) { - if (finished != NULL) { - finished(imageContainer, error, downloadIdentifier, userInfo); - } - }]; + dispatch_queue_t callbackQueue = [self callbackQueue]; + __weak __typeof__(self) weakSelf = self; + ASImageDownloaderProgress downloadProgress = ^(CGFloat progress){ + __typeof__(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf _updateDownloadedProgress:progress downloadIdentifier:downloadIdentifier]; + } + }; + ASImageDownloaderCompletion completion = ^(id _Nullable imageContainer, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo) { + if (finished != NULL) { + finished(imageContainer, error, downloadIdentifier, userInfo); + } + }; + + if (self->_networkImageNodeFlags.downloaderImplementsDownloadWithPriority) { + /* + Decide a priority based on the current interface state of this node. + It can happen that this method was called when the node entered preload state + but the interface state, at this point, tells us that the node is (going to be) visible. + If that's the case, we jump to a higher priority directly. + */ + ASImageDownloaderPriority priority = ASImageDownloaderPriorityWithInterfaceState(interfaceState); + + downloadIdentifier = [self->_downloader downloadImageWithURL:url + + priority:priority + callbackQueue:callbackQueue + downloadProgress:downloadProgress + completion:completion]; + } else { + /* + Kick off a download with default priority. + The actual "default" value is decided by the downloader. + ASBasicImageDownloader and ASPINRemoteImageDownloader both use ASImageDownloaderPriorityImminent + which is mapped to NSURLSessionTaskPriorityDefault. + + This means that preload and display nodes use the same priority + and their requests are put into the same pool. + */ + downloadIdentifier = [self->_downloader downloadImageWithURL:url + callbackQueue:callbackQueue + downloadProgress:downloadProgress + completion:completion]; + } as_log_verbose(ASImageLoadingLog(), "Downloading image for %@ url: %@", self, url); { @@ -634,12 +709,13 @@ - (void)_lazilyLoadImageIfNecessary [self lock]; __weak id delegate = _delegate; - BOOL delegateDidStartFetchingData = _delegateFlags.delegateDidStartFetchingData; - BOOL delegateWillLoadImageFromCache = _delegateFlags.delegateWillLoadImageFromCache; - BOOL delegateWillLoadImageFromNetwork = _delegateFlags.delegateWillLoadImageFromNetwork; - BOOL delegateDidLoadImageFromCache = _delegateFlags.delegateDidLoadImageFromCache; - BOOL isImageLoaded = _imageLoaded; - NSURL *URL = _URL; + BOOL delegateDidStartFetchingData = _networkImageNodeFlags.delegateDidStartFetchingData; + BOOL delegateWillLoadImageFromCache = _networkImageNodeFlags.delegateWillLoadImageFromCache; + BOOL delegateWillLoadImageFromNetwork = _networkImageNodeFlags.delegateWillLoadImageFromNetwork; + BOOL delegateDidLoadImageFromCache = _networkImageNodeFlags.delegateDidLoadImageFromCache; + BOOL delegateDidFailToLoadImageFromCache = _networkImageNodeFlags.delegateDidFailToLoadImageFromCache; + BOOL isImageLoaded = _networkImageNodeFlags.imageLoaded; + __block NSURL *URL = _URL; id currentDownloadIdentifier = _downloadIdentifier; [self unlock]; @@ -657,7 +733,7 @@ - (void)_lazilyLoadImageIfNecessary return; } - if (self->_shouldCacheImage) { + if (self->_networkImageNodeFlags.shouldCacheImage) { [self _locked__setImage:[UIImage imageNamed:URL.path.lastPathComponent]]; } else { // First try to load the path directly, for efficiency assuming a developer who @@ -669,12 +745,14 @@ - (void)_lazilyLoadImageIfNecessary NSString *filename = [[NSBundle mainBundle] pathForResource:URL.path.lastPathComponent ofType:nil]; if (filename != nil) { nonAnimatedImage = [[UIImage alloc] initWithContentsOfFile:filename]; + // Update URL to point to newly-resolved file URL for animated image load. + URL = nonAnimatedImage ? [NSURL URLWithString:filename] : URL; } } // If the file may be an animated gif and then created an animated image. id animatedImage = nil; - if (self->_downloaderFlags.downloaderImplementsAnimatedImage) { + if (self->_networkImageNodeFlags.downloaderImplementsAnimatedImage) { const auto data = [[NSData alloc] initWithContentsOfURL:URL]; if (data != nil) { animatedImage = [self->_downloader animatedImageWithData:data]; @@ -692,15 +770,16 @@ - (void)_lazilyLoadImageIfNecessary } } - self->_imageLoaded = YES; + self->_networkImageNodeFlags.imageLoaded = YES; [self _setCurrentImageQuality:1.0]; + [self _setDownloadProgress:1.0]; - if (self->_delegateFlags.delegateDidLoadImageWithInfo) { + if (self->_networkImageNodeFlags.delegateDidLoadImageWithInfo) { ASUnlockScope(self); const auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:ASNetworkImageSourceFileURL downloadIdentifier:nil userInfo:nil]; [delegate imageNode:self didLoadImage:self.image info:info]; - } else if (self->_delegateFlags.delegateDidLoadImage) { + } else if (self->_networkImageNodeFlags.delegateDidLoadImage) { ASUnlockScope(self); [delegate imageNode:self didLoadImage:self.image]; } @@ -734,15 +813,16 @@ - (void)_lazilyLoadImageIfNecessary UIImage *newImage; if (imageContainer != nil) { [strongSelf _setCurrentImageQuality:1.0]; + [strongSelf _setDownloadProgress:1.0]; NSData *animatedImageData = [imageContainer asdk_animatedImageData]; - if (animatedImageData && strongSelf->_downloaderFlags.downloaderImplementsAnimatedImage) { + if (animatedImageData && strongSelf->_networkImageNodeFlags.downloaderImplementsAnimatedImage) { id animatedImage = [strongSelf->_downloader animatedImageWithData:animatedImageData]; [strongSelf _locked_setAnimatedImage:animatedImage]; } else { newImage = [imageContainer asdk_image]; [strongSelf _locked__setImage:newImage]; } - strongSelf->_imageLoaded = YES; + strongSelf->_networkImageNodeFlags.imageLoaded = YES; } strongSelf->_downloadIdentifier = nil; @@ -751,17 +831,17 @@ - (void)_lazilyLoadImageIfNecessary void (^calloutBlock)(ASNetworkImageNode *inst); if (newImage) { - if (strongSelf->_delegateFlags.delegateDidLoadImageWithInfo) { + if (strongSelf->_networkImageNodeFlags.delegateDidLoadImageWithInfo) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { const auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:imageSource downloadIdentifier:downloadIdentifier userInfo:userInfo]; [delegate imageNode:strongSelf didLoadImage:newImage info:info]; }; - } else if (strongSelf->_delegateFlags.delegateDidLoadImage) { + } else if (strongSelf->_networkImageNodeFlags.delegateDidLoadImage) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { [delegate imageNode:strongSelf didLoadImage:newImage]; }; } - } else if (error && strongSelf->_delegateFlags.delegateDidFailWithError) { + } else if (error && strongSelf->_networkImageNodeFlags.delegateDidFailWithError) { calloutBlock = ^(ASNetworkImageNode *strongSelf) { [delegate imageNode:strongSelf didFailWithError:error]; }; @@ -788,13 +868,16 @@ - (void)_lazilyLoadImageIfNecessary as_log_verbose(ASImageLoadingLog(), "Decaching image for %@ url: %@", self, URL); - ASImageCacherCompletion completion = ^(id imageContainer) { + ASImageCacherCompletion completion = ^(id imageContainer, ASImageCacheType cacheType) { // If the cache sentinel changed, that means this request was cancelled. if (ASLockedSelf(self->_cacheSentinel != cacheSentinel)) { return; } - if ([imageContainer asdk_image] == nil && self->_downloader != nil) { + if ([imageContainer asdk_image] == nil && [imageContainer asdk_animatedImageData] == nil && self->_downloader != nil) { + if (delegateDidFailToLoadImageFromCache) { + [delegate imageNodeDidFailToLoadImageFromCache:self]; + } if (delegateWillLoadImageFromNetwork) { [delegate imageNodeWillLoadImageFromNetwork:self]; } @@ -805,8 +888,8 @@ - (void)_lazilyLoadImageIfNecessary if (delegateDidLoadImageFromCache) { [delegate imageNodeDidLoadImageFromCache:self]; } - as_log_verbose(ASImageLoadingLog(), "Decached image for %@ img: %@ url: %@", self, [imageContainer asdk_image], URL); - finished(imageContainer, nil, nil, ASNetworkImageSourceAsynchronousCache, nil); + as_log_verbose(ASImageLoadingLog(), "Decached image for %@ img: %@ url: %@ cacheType: %@", self, [imageContainer asdk_image], URL, cacheType); + finished(imageContainer, nil, nil, cacheType == ASImageCacheTypeSynchronous ? ASNetworkImageSourceSynchronousCache : ASNetworkImageSourceAsynchronousCache, nil); } }; @@ -838,7 +921,7 @@ - (void)displayDidFinish { ASLockScopeSelf(); - if (_delegateFlags.delegateDidFinishDecoding && self.layer.contents != nil) { + if (_networkImageNodeFlags.delegateDidFinishDecoding && self.layer.contents != nil) { /* We store the image quality in _currentImageQuality whenever _image is set. On the following displayDidFinish, we'll know that _currentImageQuality is the quality of the image that has just finished rendering. In order for this to be accurate, we need to be sure we are on main thread when we set _currentImageQuality. Otherwise, it is possible for _currentImageQuality diff --git a/Example/Pods/Texture/Source/ASNodeController+Beta.h b/Example/Pods/Texture/Source/ASNodeController+Beta.h index 56b7d93..6501a11 100644 --- a/Example/Pods/Texture/Source/ASNodeController+Beta.h +++ b/Example/Pods/Texture/Source/ASNodeController+Beta.h @@ -10,21 +10,18 @@ #import #import // for ASInterfaceState protocol -NS_ASSUME_NONNULL_BEGIN - /* ASNodeController is currently beta and open to change in the future */ @interface ASNodeController<__covariant DisplayNodeType : ASDisplayNode *> : NSObject -@property (strong, readonly /* may be weak! */) DisplayNodeType node; +@property (nonatomic, strong /* may be weak! */) DisplayNodeType node; // Until an ASNodeController can be provided in place of an ASCellNode, some apps may prefer to have // nodes keep their controllers alive (and a weak reference from controller to node) @property (nonatomic) BOOL shouldInvertStrongReference; -// called on an arbitrary thread by the framework. You do not call this. Return a new node instance. -- (DisplayNodeType)createNode; +- (void)loadNode; // for descriptions see definition - (void)nodeDidLoad ASDISPLAYNODE_REQUIRES_SUPER; @@ -47,12 +44,19 @@ NS_ASSUME_NONNULL_BEGIN - (void)hierarchyDisplayDidFinish ASDISPLAYNODE_REQUIRES_SUPER; +- (void)didEnterHierarchy ASDISPLAYNODE_REQUIRES_SUPER; +- (void)didExitHierarchy ASDISPLAYNODE_REQUIRES_SUPER; + +/** + * @discussion Attempts (via ASLockSequence, a backing-off spinlock similar to + * std::lock()) to lock both the node and its ASNodeController, if one exists. + */ +- (ASLockSet)lockPair; + @end @interface ASDisplayNode (ASNodeController) -@property(nullable, readonly) ASNodeController *nodeController; +@property(nonatomic, readonly) ASNodeController *nodeController; @end - -NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/ASNodeController+Beta.mm b/Example/Pods/Texture/Source/ASNodeController+Beta.mm index 56034c5..0245a7d 100644 --- a/Example/Pods/Texture/Source/ASNodeController+Beta.mm +++ b/Example/Pods/Texture/Source/ASNodeController+Beta.mm @@ -8,9 +8,7 @@ // #import -#import #import -#import #define _node (_shouldInvertStrongReference ? _weakNode : _strongNode) @@ -18,27 +16,22 @@ @implementation ASNodeController { ASDisplayNode *_strongNode; __weak ASDisplayNode *_weakNode; - ASDN::Mutex _nodeLock; + AS::RecursiveMutex __instanceLock__; } -- (ASDisplayNode *)createNode +- (void)loadNode { - return [[ASDisplayNode alloc] init]; + ASLockScopeSelf(); + self.node = [[ASDisplayNode alloc] init]; } - (ASDisplayNode *)node { - ASDN::MutexLocker l(_nodeLock); - ASDisplayNode *node = _node; - if (!node) { - node = [self createNode]; - if (!node) { - ASDisplayNodeCFailAssert(@"Returned nil from -createNode."); - node = [[ASDisplayNode alloc] init]; - } - [self setupReferencesWithNode:node]; + ASLockScopeSelf(); + if (_node == nil) { + [self loadNode]; } - return node; + return _node; } - (void)setupReferencesWithNode:(ASDisplayNode *)node @@ -55,6 +48,15 @@ - (void)setupReferencesWithNode:(ASDisplayNode *)node } [node __setNodeController:self]; +} + +- (void)setNode:(ASDisplayNode *)node +{ + ASLockScopeSelf(); + if (node == _node) { + return; + } + [self setupReferencesWithNode:node]; [node addInterfaceStateDelegate:self]; } @@ -88,23 +90,38 @@ - (void)interfaceStateDidChange:(ASInterfaceState)newState - (void)hierarchyDisplayDidFinish {} +- (void)didEnterHierarchy {} +- (void)didExitHierarchy {} + +- (ASLockSet)lockPair { + ASLockSet lockSet = ASLockSequence(^BOOL(ASAddLockBlock addLock) { + if (!addLock(_node)) { + return NO; + } + if (!addLock(self)) { + return NO; + } + return YES; + }); + + return lockSet; +} + #pragma mark NSLocking - (void)lock { - [self.node lock]; + __instanceLock__.lock(); } - (void)unlock { - // Since the node was already locked on this thread, we don't need to call our accessor or take our lock. - ASDisplayNodeAssertNotNil(_node, @"Node deallocated while locked."); - [_node unlock]; + __instanceLock__.unlock(); } - (BOOL)tryLock { - return [self.node tryLock]; + return __instanceLock__.try_lock(); } @end diff --git a/Example/Pods/Texture/Source/ASPagerNode.mm b/Example/Pods/Texture/Source/ASPagerNode.mm index 28de250..7ad8f1a 100644 --- a/Example/Pods/Texture/Source/ASPagerNode.mm +++ b/Example/Pods/Texture/Source/ASPagerNode.mm @@ -8,7 +8,6 @@ // #import -#import #import #import @@ -16,10 +15,9 @@ #import #import #import -#import #import -#import #import +#import @interface ASPagerNode () { @@ -29,6 +27,7 @@ @interface ASPagerNode () _pagerDelegate; ASPagerNodeProxy *_proxyDelegate; diff --git a/Example/Pods/Texture/Source/ASRunLoopQueue.h b/Example/Pods/Texture/Source/ASRunLoopQueue.h index 5cb6d2f..298fe76 100644 --- a/Example/Pods/Texture/Source/ASRunLoopQueue.h +++ b/Example/Pods/Texture/Source/ASRunLoopQueue.h @@ -48,12 +48,7 @@ AS_SUBCLASSING_RESTRICTED @end -AS_SUBCLASSING_RESTRICTED -@interface ASCATransactionQueue : ASAbstractRunLoopQueue -@property (readonly) BOOL isEmpty; - -@property (readonly, getter=isEnabled) BOOL enabled; /** * The queue to run on main run loop before CATransaction commit. @@ -62,16 +57,29 @@ AS_SUBCLASSING_RESTRICTED * to get last chance of updating/coalesce info like interface state. * Each node will only be called once per transaction commit to reflect interface change. */ -@property (class, readonly) ASCATransactionQueue *sharedQueue; -+ (ASCATransactionQueue *)sharedQueue NS_RETURNS_RETAINED; +AS_SUBCLASSING_RESTRICTED +@interface ASCATransactionQueue : ASAbstractRunLoopQueue + +@property (readonly) BOOL isEmpty; + +@property (readonly, getter=isEnabled) BOOL enabled; - (void)enqueue:(id)object; @end +extern ASCATransactionQueue *_ASSharedCATransactionQueue; +extern dispatch_once_t _ASSharedCATransactionQueueOnceToken; + +NS_INLINE ASCATransactionQueue *ASCATransactionQueueGet(void) { + dispatch_once(&_ASSharedCATransactionQueueOnceToken, ^{ + _ASSharedCATransactionQueue = [[ASCATransactionQueue alloc] init]; + }); + return _ASSharedCATransactionQueue; +} + @interface ASDeallocQueue : NSObject -@property (class, readonly) ASDeallocQueue *sharedDeallocationQueue; + (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED; - (void)drain; diff --git a/Example/Pods/Texture/Source/ASRunLoopQueue.mm b/Example/Pods/Texture/Source/ASRunLoopQueue.mm index 65ce8c4..fd896af 100644 --- a/Example/Pods/Texture/Source/ASRunLoopQueue.mm +++ b/Example/Pods/Texture/Source/ASRunLoopQueue.mm @@ -10,18 +10,16 @@ #import #import #import -#import #import #import #import -#import -#import -#import #import #define ASRunLoopQueueLoggingEnabled 0 #define ASRunLoopQueueVerboseLoggingEnabled 0 +using AS::MutexLocker; + static void runLoopSourceCallback(void *info) { // No-op #if ASRunLoopQueueVerboseLoggingEnabled @@ -33,7 +31,7 @@ static void runLoopSourceCallback(void *info) { @implementation ASDeallocQueue { std::vector _queue; - ASDN::Mutex _lock; + AS::Mutex _lock; } + (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED @@ -111,7 +109,7 @@ @interface ASRunLoopQueue () { CFRunLoopSourceRef _runLoopSource; CFRunLoopObserverRef _runLoopObserver; NSPointerArray *_internalQueue; // Use NSPointerArray so we can decide __strong or __weak per-instance. - ASDN::RecursiveMutex _internalQueueLock; + AS::RecursiveMutex _internalQueueLock; // In order to not pollute the top-level activities, each queue has 1 root activity. os_activity_t _rootActivity; @@ -147,8 +145,8 @@ - (instancetype)initWithRunLoop:(CFRunLoopRef)runloop retainObjects:(BOOL)retain } // Self is guaranteed to outlive the observer. Without the high cost of a weak pointer, - // __unsafe_unretained allows us to avoid flagging the memory cycle detector. - __unsafe_unretained __typeof__(self) weakSelf = self; + // unowned(__unsafe_unretained) allows us to avoid flagging the memory cycle detector. + unowned __typeof__(self) weakSelf = self; void (^handlerBlock) (CFRunLoopObserverRef observer, CFRunLoopActivity activity) = ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { [weakSelf processQueue]; }; @@ -205,7 +203,7 @@ - (void)processQueue BOOL isQueueDrained = NO; { - ASDN::MutexLocker l(_internalQueueLock); + MutexLocker l(_internalQueueLock); NSInteger internalQueueCount = _internalQueue.count; // Early-exit if the queue is empty. @@ -213,7 +211,7 @@ - (void)processQueue return; } - ASSignpostStart(ASSignpostRunLoopQueueBatch); + ASSignpostStart(RunLoopQueueBatch, self, "%s", object_getClassName(self)); // Snatch the next batch of items. NSInteger maxCountToProcess = MIN(internalQueueCount, self.batchSize); @@ -231,7 +229,7 @@ - (void)processQueue * object will be added to the autorelease pool. If the queue is strong, * it will retain the object until we transfer it (retain it) in itemsToProcess. */ - __unsafe_unretained id ptr = (__bridge id)[_internalQueue pointerAtIndex:i]; + unowned id ptr = (__bridge id)[_internalQueue pointerAtIndex:i]; if (ptr != nil) { foundItemCount++; if (hasExecutionBlock) { @@ -261,7 +259,7 @@ - (void)processQueue as_activity_scope_verbose(as_activity_create("Process run loop queue batch", _rootActivity, OS_ACTIVITY_FLAG_DEFAULT)); const auto itemsEnd = itemsToProcess.cend(); for (auto iterator = itemsToProcess.begin(); iterator < itemsEnd; iterator++) { - __unsafe_unretained id value = *iterator; + unowned id value = *iterator; _queueConsumer(value, isQueueDrained && iterator == itemsEnd - 1); as_log_verbose(ASDisplayLog(), "processed %@", value); } @@ -276,7 +274,7 @@ - (void)processQueue CFRunLoopWakeUp(_runLoop); } - ASSignpostEnd(ASSignpostRunLoopQueueBatch); + ASSignpostEnd(RunLoopQueueBatch, self, "count: %d", (int)count); } - (void)enqueue:(id)object @@ -285,7 +283,7 @@ - (void)enqueue:(id)object return; } - ASDN::MutexLocker l(_internalQueueLock); + MutexLocker l(_internalQueueLock); // Check if the object exists. BOOL foundObject = NO; @@ -301,15 +299,16 @@ - (void)enqueue:(id)object if (!foundObject) { [_internalQueue addPointer:(__bridge void *)object]; - - CFRunLoopSourceSignal(_runLoopSource); - CFRunLoopWakeUp(_runLoop); + if (_internalQueue.count == 1) { + CFRunLoopSourceSignal(_runLoopSource); + CFRunLoopWakeUp(_runLoop); + } } } - (BOOL)isEmpty { - ASDN::MutexLocker l(_internalQueueLock); + MutexLocker l(_internalQueueLock); return _internalQueue.count == 0; } @@ -320,11 +319,20 @@ - (BOOL)isEmpty #pragma mark - ASCATransactionQueue @interface ASCATransactionQueue () { - CFRunLoopRef _runLoop; CFRunLoopSourceRef _runLoopSource; CFRunLoopObserverRef _preTransactionObserver; - NSPointerArray *_internalQueue; - ASDN::RecursiveMutex _internalQueueLock; + + // Current buffer for new entries, only accessed from within its mutex. + std::vector> _internalQueue; + + // No retain, no release, pointer hash, pointer equality. + // Enforce uniqueness in our queue. std::unordered_set does a heap allocation for each entry – not good. + CFMutableSetRef _internalQueueHashSet; + + // Temporary buffer, only accessed from the main thread in -process. + std::vector> _batchBuffer; + + AS::Mutex _internalQueueLock; // In order to not pollute the top-level activities, each queue has 1 root activity. os_activity_t _rootActivity; @@ -342,22 +350,19 @@ @implementation ASCATransactionQueue // but after most other scheduled work on the runloop has processed. static int const kASASCATransactionQueueOrder = 1000000; -+ (ASCATransactionQueue *)sharedQueue NS_RETURNS_RETAINED -{ - static dispatch_once_t onceToken; - static ASCATransactionQueue *sharedQueue; - dispatch_once(&onceToken, ^{ - sharedQueue = [[ASCATransactionQueue alloc] init]; - }); - return sharedQueue; -} +ASCATransactionQueue *_ASSharedCATransactionQueue; +dispatch_once_t _ASSharedCATransactionQueueOnceToken; - (instancetype)init { if (self = [super init]) { - _runLoop = CFRunLoopGetMain(); - NSPointerFunctionsOptions options = NSPointerFunctionsStrongMemory; - _internalQueue = [[NSPointerArray alloc] initWithOptions:options]; + _internalQueueHashSet = CFSetCreateMutable(NULL, 0, NULL); + + // This is going to be a very busy queue – every node in the preload range will enter this queue. + // Save some time on first render by reserving space up front. + static constexpr int kInternalQueueInitialCapacity = 64; + _internalQueue.reserve(kInternalQueueInitialCapacity); + _batchBuffer.reserve(kInternalQueueInitialCapacity); // We don't want to pollute the top-level app activities with run loop batches, so we create one top-level // activity per queue, and each batch activity joins that one instead. @@ -369,16 +374,15 @@ - (instancetype)init } // Self is guaranteed to outlive the observer. Without the high cost of a weak pointer, - // __unsafe_unretained allows us to avoid flagging the memory cycle detector. - __unsafe_unretained __typeof__(self) weakSelf = self; - void (^handlerBlock) (CFRunLoopObserverRef observer, CFRunLoopActivity activity) = ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { - while (weakSelf->_internalQueue.count > 0) { - [weakSelf processQueue]; + // unowned(__unsafe_unretained) allows us to avoid flagging the memory cycle detector. + unowned __typeof__(self) weakSelf = self; + _preTransactionObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, kASASCATransactionQueueOrder, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { + while (!weakSelf->_internalQueue.empty()) { + [weakSelf processQueue]; } - }; - _preTransactionObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, kASASCATransactionQueueOrder, handlerBlock); + }); - CFRunLoopAddObserver(_runLoop, _preTransactionObserver, kCFRunLoopCommonModes); + CFRunLoopAddObserver(CFRunLoopGetMain(), _preTransactionObserver, kCFRunLoopCommonModes); // It is not guaranteed that the runloop will turn if it has no scheduled work, and this causes processing of // the queue to stop. Attaching a custom loop source to the run loop and signal it if new work needs to be done @@ -388,7 +392,7 @@ - (instancetype)init sourceContext.info = (__bridge void *)self; #endif _runLoopSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext); - CFRunLoopAddSource(_runLoop, _runLoopSource, kCFRunLoopCommonModes); + CFRunLoopAddSource(CFRunLoopGetMain(), _runLoopSource, kCFRunLoopCommonModes); #if ASRunLoopQueueLoggingEnabled _runloopQueueLoggingTimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(checkRunLoop) userInfo:nil repeats:YES]; @@ -400,7 +404,10 @@ - (instancetype)init - (void)dealloc { - CFRunLoopRemoveSource(_runLoop, _runLoopSource, kCFRunLoopCommonModes); + ASDisplayNodeAssertMainThread(); + + CFRelease(_internalQueueHashSet); + CFRunLoopRemoveSource(CFRunLoopGetMain(), _runLoopSource, kCFRunLoopCommonModes); CFRelease(_runLoopSource); _runLoopSource = nil; @@ -420,61 +427,31 @@ - (void)checkRunLoop - (void)processQueue { - // If we have an execution block, this vector will be populated, otherwise remains empty. - // This is to avoid needlessly retaining/releasing the objects if we don't have a block. - std::vector itemsToProcess; - - { - ASDN::MutexLocker l(_internalQueueLock); - - NSInteger internalQueueCount = _internalQueue.count; - // Early-exit if the queue is empty. - if (internalQueueCount == 0) { - return; - } - - ASSignpostStart(ASSignpostRunLoopQueueBatch); - - /** - * For each item in the next batch, if it's non-nil then NULL it out - * and if we have an execution block then add it in. - * This could be written a bunch of different ways but - * this particular one nicely balances readability, safety, and efficiency. - */ - NSInteger foundItemCount = 0; - for (NSInteger i = 0; i < internalQueueCount && foundItemCount < internalQueueCount; i++) { - /** - * It is safe to use unsafe_unretained here. If the queue is weak, the - * object will be added to the autorelease pool. If the queue is strong, - * it will retain the object until we transfer it (retain it) in itemsToProcess. - */ - __unsafe_unretained id ptr = (__bridge id)[_internalQueue pointerAtIndex:i]; - if (ptr != nil) { - foundItemCount++; - itemsToProcess.push_back(ptr); - [_internalQueue replacePointerAtIndex:i withPointer:NULL]; - } - } + ASDisplayNodeAssertMainThread(); - [_internalQueue compact]; + AS::UniqueLock l(_internalQueueLock); + NSInteger count = _internalQueue.size(); + // Early-exit if the queue is empty. + if (count == 0) { + return; } - - // itemsToProcess will be empty if _queueConsumer == nil so no need to check again. - const auto count = itemsToProcess.size(); - if (count > 0) { - as_activity_scope_verbose(as_activity_create("Process run loop queue batch", _rootActivity, OS_ACTIVITY_FLAG_DEFAULT)); - const auto itemsEnd = itemsToProcess.cend(); - for (auto iterator = itemsToProcess.begin(); iterator < itemsEnd; iterator++) { - __unsafe_unretained id value = *iterator; - [value prepareForCATransactionCommit]; - as_log_verbose(ASDisplayLog(), "processed %@", value); - } - if (count > 1) { - as_log_verbose(ASDisplayLog(), "processed %lu items", (unsigned long)count); - } + as_activity_scope_verbose(as_activity_create("Process run loop queue batch", _rootActivity, OS_ACTIVITY_FLAG_DEFAULT)); + ASSignpostStart(RunLoopQueueBatch, self, "CATransactionQueue"); + + // Swap buffers, clear our hash table. + _internalQueue.swap(_batchBuffer); + CFSetRemoveAllValues(_internalQueueHashSet); + + // Unlock early. We are done with internal queue, and batch buffer is main-thread-only so no lock. + l.unlock(); + + for (const id &value : _batchBuffer) { + [value prepareForCATransactionCommit]; + as_log_verbose(ASDisplayLog(), "processed %@", value); } - - ASSignpostEnd(ASSignpostRunLoopQueueBatch); + _batchBuffer.clear(); + as_log_verbose(ASDisplayLog(), "processed %lu items", (unsigned long)count); + ASSignpostEnd(RunLoopQueueBatch, self, "count: %d", (int)count); } - (void)enqueue:(id)object @@ -488,30 +465,22 @@ - (void)enqueue:(id)object return; } - ASDN::MutexLocker l(_internalQueueLock); - - // Check if the object exists. - BOOL foundObject = NO; - - for (id currentObject in _internalQueue) { - if (currentObject == object) { - foundObject = YES; - break; - } + MutexLocker l(_internalQueueLock); + if (CFSetContainsValue(_internalQueueHashSet, (__bridge void *)object)) { + return; } - - if (!foundObject) { - [_internalQueue addPointer:(__bridge void *)object]; - + CFSetAddValue(_internalQueueHashSet, (__bridge void *)object); + _internalQueue.emplace_back(object); + if (_internalQueue.size() == 1) { CFRunLoopSourceSignal(_runLoopSource); - CFRunLoopWakeUp(_runLoop); + CFRunLoopWakeUp(CFRunLoopGetMain()); } } - (BOOL)isEmpty { - ASDN::MutexLocker l(_internalQueueLock); - return _internalQueue.count == 0; + MutexLocker l(_internalQueueLock); + return _internalQueue.empty(); } - (BOOL)isEnabled diff --git a/Example/Pods/Texture/Source/ASScrollNode.mm b/Example/Pods/Texture/Source/ASScrollNode.mm index 497ef14..bb9c826 100644 --- a/Example/Pods/Texture/Source/ASScrollNode.mm +++ b/Example/Pods/Texture/Source/ASScrollNode.mm @@ -10,10 +10,12 @@ #import #import #import +#import #import #import #import #import +#import @interface ASScrollView : UIScrollView @end @@ -79,7 +81,7 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize restrictedToSize:(ASLayoutElementSize)size relativeToParentSize:(CGSize)parentSize { - ASLockScopeSelf(); // Lock for using our instance variables. + ASScopedLockSelfOrToRoot(); ASSizeRange contentConstrainedSize = constrainedSize; if (ASScrollDirectionContainsVerticalDirection(_scrollableDirections)) { @@ -109,6 +111,21 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize if (ASPointsValidForLayout(selfSize.height) == NO) { selfSize.height = _contentCalculatedSizeFromLayout.height; } + + // The side effect for layout with CGFLOAT_MAX is that the min-height/width on the child of + // ScrollNode may not be applied correctly. Resulting in the contentSize less than the + // scrollNode's bounds which may not be what the child want (e.g. The child want to fill + // ScrollNode's bounds). In that case we need to give it a chance to layout with ScrollNode's + // bound in case children want to fill the ScrollNode's bound. + if ((ASScrollDirectionContainsVerticalDirection(_scrollableDirections) && + layout.size.height < selfSize.height) || + (ASScrollDirectionContainsHorizontalDirection(_scrollableDirections) && + layout.size.width < selfSize.width)) { + layout = [super calculateLayoutThatFits:constrainedSize + restrictedToSize:size + relativeToParentSize:parentSize]; + } + // Don't provide a position, as that should be set by the parent. layout = [ASLayout layoutWithLayoutElement:self size:selfSize diff --git a/Example/Pods/Texture/Source/ASSectionController.h b/Example/Pods/Texture/Source/ASSectionController.h index 5d48bbe..6807596 100644 --- a/Example/Pods/Texture/Source/ASSectionController.h +++ b/Example/Pods/Texture/Source/ASSectionController.h @@ -16,13 +16,14 @@ NS_ASSUME_NONNULL_BEGIN @class ASBatchContext; /** - * A protocol that your section controllers should conform to, - * in order to be used with AsyncDisplayKit. + * A protocol that your section controllers should conform to, in order to be used with Texture. * * @note Your supplementary view source should conform to @c ASSupplementaryNodeSource. */ @protocol ASSectionController +@optional + /** * A method to provide the node block for the item at the given index. * The node block you return will be run asynchronously off the main thread, @@ -48,8 +49,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (ASCellNode *)nodeForItemAtIndex:(NSInteger)index; -@optional - /** * Asks the section controller whether it should batch fetch because the user is * near the end of the current data set. diff --git a/Example/Pods/Texture/Source/ASSupplementaryNodeSource.h b/Example/Pods/Texture/Source/ASSupplementaryNodeSource.h index 3d63a69..20beddd 100644 --- a/Example/Pods/Texture/Source/ASSupplementaryNodeSource.h +++ b/Example/Pods/Texture/Source/ASSupplementaryNodeSource.h @@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN @protocol ASSupplementaryNodeSource +@optional + /** * A method to provide the node-block for the supplementary element. * @@ -33,8 +35,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (ASCellNode *)nodeForSupplementaryElementOfKind:(NSString *)kind atIndex:(NSInteger)index; -@optional - /** * A method to provide the size range used for measuring the supplementary * element of the given kind at the given index. diff --git a/Example/Pods/Texture/Source/ASTabBarController.mm b/Example/Pods/Texture/Source/ASTabBarController.mm index 18ed4b4..63867f1 100644 --- a/Example/Pods/Texture/Source/ASTabBarController.mm +++ b/Example/Pods/Texture/Source/ASTabBarController.mm @@ -66,7 +66,7 @@ - (void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControlle - (void)setSelectedIndex:(NSUInteger)selectedIndex { as_activity_create_for_scope("Set selected index of ASTabBarController"); - as_log_info(ASNodeLog(), "Selected tab %tu of %@", selectedIndex, self); + os_log_info(ASNodeLog(), "Selected tab %tu of %@", selectedIndex, self); [super setSelectedIndex:selectedIndex]; [self visibilityDepthDidChange]; @@ -75,7 +75,7 @@ - (void)setSelectedIndex:(NSUInteger)selectedIndex - (void)setSelectedViewController:(__kindof UIViewController *)selectedViewController { as_activity_create_for_scope("Set selected view controller of ASTabBarController"); - as_log_info(ASNodeLog(), "Selected view controller %@ of %@", selectedViewController, self); + os_log_info(ASNodeLog(), "Selected view controller %@ of %@", selectedViewController, self); [super setSelectedViewController:selectedViewController]; [self visibilityDepthDidChange]; diff --git a/Example/Pods/Texture/Source/ASTableNode.h b/Example/Pods/Texture/Source/ASTableNode.h index 2cd2394..772f3a7 100644 --- a/Example/Pods/Texture/Source/ASTableNode.h +++ b/Example/Pods/Texture/Source/ASTableNode.h @@ -77,6 +77,12 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic) BOOL automaticallyAdjustsContentOffset; +/** + * A Boolean value that determines whether paging is enabled for the scroll view. + * The default value of this property is NO. + */ +@property (nonatomic, getter=isPagingEnabled) BOOL pagingEnabled __TVOS_PROHIBITED; + /* * A Boolean value that determines whether users can select a row. * If the value of this property is YES (the default), users can select rows. If you set it to NO, they cannot select rows. Setting this property affects cell selection only when the table view is not in editing mode. If you want to restrict selection of cells in editing mode, use `allowsSelectionDuringEditing`. @@ -569,6 +575,29 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)tableViewUnlockDataSource:(ASTableView *)tableView ASDISPLAYNODE_DEPRECATED_MSG("Data source accesses are on the main thread. Method will not be called."); +/** + * Generate a unique identifier for an element in a table. This helps state restoration persist the scroll position + * of a table view even when the data in that table changes. See the documentation for UIDataSourceModelAssociation for more information. + * + * @param indexPath The index path of the requested node. + * + * @param tableNode The sender. + * + * @return a unique identifier for the element at the given path. Return nil if the index path does not exist in the table. + */ +- (nullable NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inNode:(ASTableNode *)tableNode; + +/** + * Similar to -tableView:cellForRowAtIndexPath:. See the documentation for UIDataSourceModelAssociation for more information. + * + * @param identifier The model identifier of the element, previously generated by a call to modelIdentifierForElementAtIndexPath. + * + * @param tableNode The sender. + * + * @return the index path to the current position of the matching element in the table. Return nil if the element is not found. + */ +- (nullable NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inNode:(ASTableNode *)tableNode; + @end /** diff --git a/Example/Pods/Texture/Source/ASTableNode.mm b/Example/Pods/Texture/Source/ASTableNode.mm index 6524962..d8acc8a 100644 --- a/Example/Pods/Texture/Source/ASTableNode.mm +++ b/Example/Pods/Texture/Source/ASTableNode.mm @@ -15,14 +15,12 @@ #import #import #import -#import #import -#import -#import #import #import #import #import +#import #pragma mark - _ASTablePendingState @@ -43,7 +41,7 @@ @interface _ASTablePendingState : NSObject { @property (nonatomic) CGPoint contentOffset; @property (nonatomic) BOOL animatesContentOffset; @property (nonatomic) BOOL automaticallyAdjustsContentOffset; - +@property (nonatomic) BOOL pagingEnabled; @end @implementation _ASTablePendingState @@ -66,6 +64,7 @@ - (instancetype)init _contentOffset = CGPointZero; _animatesContentOffset = NO; _automaticallyAdjustsContentOffset = NO; + _pagingEnabled = NO; } return self; } @@ -100,7 +99,7 @@ - (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMo @interface ASTableNode () { - ASDN::RecursiveMutex _environmentStateLock; + AS::RecursiveMutex _environmentStateLock; id _batchFetchingDelegate; } @@ -119,7 +118,7 @@ - (instancetype)initWithStyle:(UITableViewStyle)style [self setViewBlock:^{ // Variable will be unused if event logging is off. __unused __typeof__(self) strongSelf = weakSelf; - return [[ASTableView alloc] _initWithFrame:CGRectZero style:style dataControllerClass:nil owningNode:strongSelf eventLog:ASDisplayNodeGetEventLog(strongSelf)]; + return [[ASTableView alloc] _initWithFrame:CGRectZero style:style dataControllerClass:nil owningNode:strongSelf]; }]; } return self; @@ -164,6 +163,9 @@ - (void)didLoad view.allowsMultipleSelection = pendingState.allowsMultipleSelection; view.allowsMultipleSelectionDuringEditing = pendingState.allowsMultipleSelectionDuringEditing; view.automaticallyAdjustsContentOffset = pendingState.automaticallyAdjustsContentOffset; +#if !TARGET_OS_TV + view.pagingEnabled = pendingState.pagingEnabled; +#endif UIEdgeInsets contentInset = pendingState.contentInset; if (!UIEdgeInsetsEqualToEdgeInsets(contentInset, UIEdgeInsetsZero)) { @@ -366,6 +368,30 @@ - (BOOL)automaticallyAdjustsContentOffset } } +#if !TARGET_OS_TV +- (void)setPagingEnabled:(BOOL)pagingEnabled +{ + _ASTablePendingState *pendingState = self.pendingState; + if (pendingState) { + pendingState.pagingEnabled = pagingEnabled; + } else { + ASDisplayNodeAssert([self isNodeLoaded], + @"ASCollectionNode should be loaded if pendingState doesn't exist"); + self.view.pagingEnabled = pagingEnabled; + } +} + +- (BOOL)isPagingEnabled +{ + _ASTablePendingState *pendingState = self.pendingState; + if (pendingState) { + return pendingState.pagingEnabled; + } else { + return self.view.isPagingEnabled; + } +} +#endif + - (void)setDelegate:(id )delegate { if ([self pendingState]) { diff --git a/Example/Pods/Texture/Source/ASTableView.mm b/Example/Pods/Texture/Source/ASTableView.mm index 8c3944f..97eb09f 100644 --- a/Example/Pods/Texture/Source/ASTableView.mm +++ b/Example/Pods/Texture/Source/ASTableView.mm @@ -12,7 +12,6 @@ #import #import #import -#import #import #import #import @@ -21,15 +20,16 @@ #import #import #import +#import #import #import #import #import #import -#import #import -#import #import +#import + static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; @@ -109,18 +109,21 @@ - (void)setElement:(ASCollectionElement *)element if (node) { self.backgroundColor = node.backgroundColor; self.selectedBackgroundView = node.selectedBackgroundView; + self.backgroundView = node.backgroundView; #if TARGET_OS_IOS self.separatorInset = node.separatorInset; #endif self.selectionStyle = node.selectionStyle; self.focusStyle = node.focusStyle; self.accessoryType = node.accessoryType; - self.tintColor = node.tintColor; // the following ensures that we clip the entire cell to it's bounds if node.clipsToBounds is set (the default) // This is actually a workaround for a bug we are seeing in some rare cases (selected background view // overlaps other cells if size of ASCellNode has changed.) self.clipsToBounds = node.clipsToBounds; + + // If the cell node has been explicitly configured with a tint color, we can apply that directly to the cell view to preserve the previous behavior + self.tintColor = node->_tintColor; } [node __setSelectedFromUIKit:self.selected]; @@ -270,6 +273,7 @@ @interface ASTableView () )asyncDataSource _asyncDataSourceFlags.tableViewCanMoveRow = [_asyncDataSource respondsToSelector:@selector(tableView:canMoveRowAtIndexPath:)]; _asyncDataSourceFlags.tableViewMoveRow = [_asyncDataSource respondsToSelector:@selector(tableView:moveRowAtIndexPath:toIndexPath:)]; _asyncDataSourceFlags.sectionIndexMethods = [_asyncDataSource respondsToSelector:@selector(sectionIndexTitlesForTableView:)] && [_asyncDataSource respondsToSelector:@selector(tableView:sectionForSectionIndexTitle:atIndex:)]; + _asyncDataSourceFlags.modelIdentifierMethods = [_asyncDataSource respondsToSelector:@selector(modelIdentifierForElementAtIndexPath:inNode:)] && [_asyncDataSource respondsToSelector:@selector(indexPathForElementWithModelIdentifier:inNode:)]; ASDisplayNodeAssert(_asyncDataSourceFlags.tableViewNodeBlockForRow || _asyncDataSourceFlags.tableViewNodeForRow @@ -960,6 +961,29 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger return [_dataController.visibleMap numberOfItemsInSection:section]; } +- (nullable NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inView:(UIView *)view { + if (_asyncDataSourceFlags.modelIdentifierMethods) { + GET_TABLENODE_OR_RETURN(tableNode, nil); + NSIndexPath *convertedPath = [self convertIndexPathToTableNode:indexPath]; + if (convertedPath == nil) { + return nil; + } else { + return [_asyncDataSource modelIdentifierForElementAtIndexPath:convertedPath inNode:tableNode]; + } + } else { + return nil; + } +} + +- (nullable NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view { + if (_asyncDataSourceFlags.modelIdentifierMethods) { + GET_TABLENODE_OR_RETURN(tableNode, nil); + return [_asyncDataSource indexPathForElementWithModelIdentifier:identifier inNode:tableNode]; + } else { + return nil; + } +} + - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { if (_asyncDataSourceFlags.tableViewCanMoveRow) { @@ -1472,13 +1496,13 @@ - (void)_beginBatchFetching if (_asyncDelegateFlags.tableNodeWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ GET_TABLENODE_OR_RETURN(tableNode, (void)0); - [_asyncDelegate tableNode:tableNode willBeginBatchFetchWithContext:_batchContext]; + [self->_asyncDelegate tableNode:tableNode willBeginBatchFetchWithContext:self->_batchContext]; }); } else if (_asyncDelegateFlags.tableViewWillBeginBatchFetch) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [_asyncDelegate tableView:self willBeginBatchFetchWithContext:_batchContext]; + [self->_asyncDelegate tableView:self willBeginBatchFetchWithContext:self->_batchContext]; #pragma clang diagnostic pop }); } @@ -1536,7 +1560,7 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet updates(); [super reloadData]; // Flush any range changes that happened as part of submitting the reload. - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:1]; [changeSet executeCompletionHandlerWithFinished:YES]; }); @@ -1654,7 +1678,7 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet LOG(@"--- UITableView endUpdates"); ASPerformBlockWithoutAnimation(!changeSet.animated, ^{ [super endUpdates]; - [_rangeController updateIfNeeded]; + [self->_rangeController updateIfNeeded]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:numberOfUpdates]; }); if (shouldAdjustContentOffset) { @@ -1677,20 +1701,18 @@ - (BOOL)dataControllerShouldSerializeNodeCreation:(ASDataController *)dataContro - (BOOL)dataController:(ASDataController *)dataController shouldSynchronouslyProcessChangeSet:(_ASHierarchyChangeSet *)changeSet { - if (ASActivateExperimentalFeature(ASExperimentalNewDefaultCellLayoutMode)) { - // Reload data is expensive, don't block main while doing so. - if (changeSet.includesReloadData) { - return NO; - } - // For more details on this method, see the comment in the ASCollectionView implementation. - if (changeSet.countForAsyncLayout < 2) { - return YES; - } - CGSize contentSize = self.contentSize; - CGSize boundsSize = self.bounds.size; - if (contentSize.height <= boundsSize.height && contentSize.width <= boundsSize.width) { - return YES; - } + // Reload data is expensive, don't block main while doing so. + if (changeSet.includesReloadData) { + return NO; + } + // For more details on this method, see the comment in the ASCollectionView implementation. + if (changeSet.countForAsyncLayout < 2) { + return YES; + } + CGSize contentSize = self.contentSize; + CGSize boundsSize = self.bounds.size; + if (contentSize.height <= boundsSize.height && contentSize.width <= boundsSize.width) { + return YES; } return NO; } @@ -1761,7 +1783,7 @@ - (ASCellNodeBlock)dataController:(ASDataController *)dataController nodeBlockAt if (node.interactionDelegate == nil) { node.interactionDelegate = strongSelf; } - if (_inverted) { + if (self->_inverted) { node.transform = CATransform3DMakeScale(1, -1, 1) ; } return node; @@ -2010,9 +2032,7 @@ - (void)didMoveToSuperview - (NSArray *)accessibilityElements { - if (!ASActivateExperimentalFeature(ASExperimentalSkipAccessibilityWait)) { - [self waitUntilAllUpdatesAreCommitted]; - } + [self waitUntilAllUpdatesAreCommitted]; return [super accessibilityElements]; } diff --git a/Example/Pods/Texture/Source/ASTableViewInternal.h b/Example/Pods/Texture/Source/ASTableViewInternal.h index d8bbf57..35a55d4 100644 --- a/Example/Pods/Texture/Source/ASTableViewInternal.h +++ b/Example/Pods/Texture/Source/ASTableViewInternal.h @@ -12,7 +12,6 @@ @class ASDataController; @class ASTableNode; @class ASRangeController; -@class ASEventLog; @interface ASTableView (Internal) @@ -29,10 +28,8 @@ * @param style A constant that specifies the style of the table view. See UITableViewStyle for descriptions of valid constants. * * @param dataControllerClass A controller class injected to and used to create a data controller for the table view. - * - * @param eventLog An event log passed through to the data controller. */ -- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass owningNode:(ASTableNode *)tableNode eventLog:(ASEventLog *)eventLog; +- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass owningNode:(ASTableNode *)tableNode; /// Set YES and we'll log every time we call [super insertRows…] etc @property (nonatomic) BOOL test_enableSuperUpdateCallLogging; diff --git a/Example/Pods/Texture/Source/ASTableViewProtocols.h b/Example/Pods/Texture/Source/ASTableViewProtocols.h index 969a5c6..ea392e2 100644 --- a/Example/Pods/Texture/Source/ASTableViewProtocols.h +++ b/Example/Pods/Texture/Source/ASTableViewProtocols.h @@ -75,7 +75,13 @@ NS_ASSUME_NONNULL_BEGIN - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath; - (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath; #if TARGET_OS_IOS -- (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath; +- (nullable NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath API_DEPRECATED_WITH_REPLACEMENT("tableView:trailingSwipeActionsConfigurationForRowAtIndexPath:", ios(8.0, 13.0)); +- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); +- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)); +- (nullable UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)); +- (nullable UITargetedPreview *)tableView:(UITableView *)tableView previewForHighlightingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); +- (nullable UITargetedPreview *)tableView:(UITableView *)tableView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)); +- (void)tableView:(UITableView *)tableView willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration animator:(id)animator API_AVAILABLE(ios(13.0)); #endif - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath; diff --git a/Example/Pods/Texture/Source/ASTextNode.h b/Example/Pods/Texture/Source/ASTextNode.h index 783eafc..b05a1d5 100644 --- a/Example/Pods/Texture/Source/ASTextNode.h +++ b/Example/Pods/Texture/Source/ASTextNode.h @@ -213,9 +213,23 @@ NS_ASSUME_NONNULL_BEGIN /** @abstract if YES will not intercept touches for non-link areas of the text. Default is NO. + @discussion If you still want to handle tap truncation action when passthroughNonlinkTouches is YES, + you should set the alwaysHandleTruncationTokenTap to YES. */ @property (nonatomic) BOOL passthroughNonlinkTouches; +/** + @abstract Always handle tap truncationAction, even the passthroughNonlinkTouches is YES. Default is NO. + @discussion if this is set to YES, the [ASTextNodeDelegate textNodeTappedTruncationToken:] callback will be called. + */ +@property (nonatomic) BOOL alwaysHandleTruncationTokenTap; + +/** + @abstract if YES will use the value of `self.tintColor` if the foreground color of text is not defined. + @discussion This is mainly used from ASButtonNode since by default text nodes do not respect tintColor settings unless contained within a interactive control + */ +@property (nonatomic) BOOL textColorFollowsTintColor; + @end @interface ASTextNode (Unavailable) diff --git a/Example/Pods/Texture/Source/ASTextNode.mm b/Example/Pods/Texture/Source/ASTextNode.mm index 4602cce..afffba5 100644 --- a/Example/Pods/Texture/Source/ASTextNode.mm +++ b/Example/Pods/Texture/Source/ASTextNode.mm @@ -23,21 +23,15 @@ #import #import #import -#import -#import #import +#import #import #import #import -#import -#import - #import #import -#import -#import /** * If set, we will record all values set to attributedText into an array @@ -57,17 +51,25 @@ #pragma mark - ASTextKitRenderer @interface ASTextNodeRendererKey : NSObject -@property (nonatomic) ASTextKitAttributes attributes; -@property (nonatomic) CGSize constrainedSize; +- (instancetype)initWithTextKitAttributes:(const ASTextKitAttributes &)attributes constrainedSize:(const CGSize)constrainedSize; @end @implementation ASTextNodeRendererKey { - std::mutex _m; + ASTextKitAttributes _attributes; + CGSize _constrainedSize; +} + +- (instancetype)initWithTextKitAttributes:(const ASTextKitAttributes &)attributes constrainedSize:(const CGSize)constrainedSize +{ + if (self = [super init]) { + _attributes = attributes; + _constrainedSize = constrainedSize; + } + return self; } - (NSUInteger)hash { - std::lock_guard _l(_m); #pragma clang diagnostic push #pragma clang diagnostic warning "-Wpadded" struct { @@ -86,13 +88,10 @@ - (BOOL)isEqual:(ASTextNodeRendererKey *)object if (self == object) { return YES; } - + if (!object) { + return NO; + } // NOTE: Skip the class check for this specialized, internal Key object. - - // Lock both objects, avoiding deadlock. - std::lock(_m, object->_m); - std::lock_guard lk1(_m, std::adopt_lock); - std::lock_guard lk2(object->_m, std::adopt_lock); return _attributes == object->_attributes && CGSizeEqualToSize(_constrainedSize, object->_constrainedSize); } @@ -120,9 +119,7 @@ - (BOOL)isEqual:(ASTextNodeRendererKey *)object { NSCache *cache = sharedRendererCache(); - ASTextNodeRendererKey *key = [[ASTextNodeRendererKey alloc] init]; - key.attributes = attributes; - key.constrainedSize = constrainedSize; + ASTextNodeRendererKey *key = [[ASTextNodeRendererKey alloc] initWithTextKitAttributes:attributes constrainedSize:constrainedSize]; ASTextKitRenderer *renderer = [cache objectForKey:key]; if (renderer == nil) { @@ -140,6 +137,10 @@ @interface ASTextNodeDrawParameter : NSObject { ASTextKitAttributes _rendererAttributes; UIColor *_backgroundColor; UIEdgeInsets _textContainerInsets; + CGFloat _contentScale; + BOOL _opaque; + CGRect _bounds; + ASPrimitiveTraitCollection _traitCollection; } @end @@ -148,12 +149,20 @@ @implementation ASTextNodeDrawParameter - (instancetype)initWithRendererAttributes:(ASTextKitAttributes)rendererAttributes backgroundColor:(/*nullable*/ UIColor *)backgroundColor textContainerInsets:(UIEdgeInsets)textContainerInsets + contentScale:(CGFloat)contentScale + opaque:(BOOL)opaque + bounds:(CGRect)bounds + traitCollection: (ASPrimitiveTraitCollection)traitCollection { self = [super init]; if (self != nil) { _rendererAttributes = rendererAttributes; _backgroundColor = backgroundColor; _textContainerInsets = textContainerInsets; + _contentScale = contentScale; + _opaque = opaque; + _bounds = bounds; + _traitCollection = traitCollection; } return self; } @@ -177,6 +186,7 @@ @implementation ASTextNode { CGSize _shadowOffset; CGColorRef _shadowColor; UIColor *_cachedShadowUIColor; + UIColor *_cachedTintColor; UIColor *_placeholderColor; CGFloat _shadowOpacity; CGFloat _shadowRadius; @@ -196,11 +206,14 @@ @implementation ASTextNode { NSString *_highlightedLinkAttributeName; id _highlightedLinkAttributeValue; - ASTextNodeHighlightStyle _highlightStyle; NSRange _highlightRange; ASHighlightOverlayLayer *_activeHighlightLayer; UILongPressGestureRecognizer *_longPressGestureRecognizer; + ASTextNodeHighlightStyle _highlightStyle; + BOOL _longPressCancelsTouches; + BOOL _passthroughNonlinkTouches; + BOOL _alwaysHandleTruncationTokenTap; } @dynamic placeholderEnabled; @@ -243,6 +256,10 @@ - (instancetype)init // on the special placeholder behavior of ASTextNode. _placeholderColor = ASDisplayNodeDefaultPlaceholderColor(); _placeholderInsets = UIEdgeInsetsMake(1.0, 0.0, 1.0, 0.0); + + // Tint color is applied when text nodes are within controls and indicate user action + // Most text nodes do not require interaction and this matches the default value of UILabel + _textColorFollowsTintColor = NO; } return self; @@ -251,14 +268,11 @@ - (instancetype)init - (void)dealloc { CGColorRelease(_shadowColor); +} - // TODO: This may not be necessary post-iOS-9 when most UIKit assign APIs - // were changed to weak. - if (_longPressGestureRecognizer) { - _longPressGestureRecognizer.delegate = nil; - [_longPressGestureRecognizer removeTarget:nil action:NULL]; - [self.view removeGestureRecognizer:_longPressGestureRecognizer]; - } +- (BOOL)usingExperiment +{ + return NO; } #pragma mark - Description @@ -371,7 +385,8 @@ - (ASTextKitAttributes)_locked_rendererAttributes .shadowOffset = _shadowOffset, .shadowColor = _cachedShadowUIColor, .shadowOpacity = _shadowOpacity, - .shadowRadius = _shadowRadius + .shadowRadius = _shadowRadius, + .tintColor = _cachedTintColor }; } @@ -462,12 +477,16 @@ - (void)setAttributedText:(NSAttributedString *)attributedText attributedText = [[NSAttributedString alloc] initWithString:@"" attributes:nil]; } + NSAttributedString *oldAttributedText = nil; + { ASLockScopeSelf(); if (ASObjectIsEqual(attributedText, _attributedText)) { return; } + oldAttributedText = _attributedText; + NSAttributedString *cleanedAttributedString = ASCleanseAttributedStringOfCoreTextAttributes(attributedText); // Invalidating the truncation text must be done while we still hold the lock. Because after we release it, @@ -496,7 +515,12 @@ - (void)setAttributedText:(NSAttributedString *)attributedText // Accessiblity const auto currentAttributedText = self.attributedText; // Grab attributed string again in case it changed in the meantime self.accessibilityLabel = self.defaultAccessibilityLabel; - self.isAccessibilityElement = (currentAttributedText.length != 0); // We're an accessibility element by default if there is a string. + + // We update the isAccessibilityElement setting if this node is not switching between strings. + if (oldAttributedText.length == 0 || currentAttributedText.length == 0) { + // We're an accessibility element by default if there is a string. + self.isAccessibilityElement = (currentAttributedText.length != 0); + } #if AS_TEXTNODE_RECORD_ATTRIBUTED_STRINGS [ASTextNode _registerAttributedText:_attributedText]; @@ -522,35 +546,55 @@ - (NSArray *)exclusionPaths - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer { + /// have to access tintColor outside of the lock to prevent dead lock when accessing up the view hierarchy + UIColor *tintColor = self.tintColor; ASLockScopeSelf(); - + if (_textColorFollowsTintColor) { + _cachedTintColor = tintColor; + } else { + _cachedTintColor = nil; + } return [[ASTextNodeDrawParameter alloc] initWithRendererAttributes:[self _locked_rendererAttributes] backgroundColor:self.backgroundColor - textContainerInsets:_textContainerInset]; + textContainerInsets:_textContainerInset + contentScale:_contentsScaleForDisplay + opaque:self.isOpaque + bounds:[self threadSafeBounds] + traitCollection:self.primitiveTraitCollection]; } -+ (void)drawRect:(CGRect)bounds withParameters:(id)parameters isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing ++ (UIImage *)displayWithParameters:(id)parameters isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelled { ASTextNodeDrawParameter *drawParameter = (ASTextNodeDrawParameter *)parameters; - UIColor *backgroundColor = (isRasterizing || drawParameter == nil) ? nil : drawParameter->_backgroundColor; - UIEdgeInsets textContainerInsets = drawParameter ? drawParameter->_textContainerInsets : UIEdgeInsetsZero; - ASTextKitRenderer *renderer = [drawParameter rendererForBounds:bounds]; - CGContextRef context = UIGraphicsGetCurrentContext(); - ASDisplayNodeAssert(context, @"This is no good without a context."); - - CGContextSaveGState(context); - CGContextTranslateCTM(context, textContainerInsets.left, textContainerInsets.top); - - // Fill background - if (backgroundColor != nil) { - [backgroundColor setFill]; - UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy); + if (drawParameter->_bounds.size.width <= 0 || drawParameter->_bounds.size.height <= 0) { + return nil; } - // Draw text - [renderer drawInContext:context bounds:bounds]; - CGContextRestoreGState(context); + UIColor *backgroundColor = drawParameter->_backgroundColor; + UIEdgeInsets textContainerInsets = drawParameter ? drawParameter->_textContainerInsets : UIEdgeInsetsZero; + ASTextKitRenderer *renderer = [drawParameter rendererForBounds:drawParameter->_bounds]; + + UIImage *result = ASGraphicsCreateImage(drawParameter->_traitCollection, CGSizeMake(drawParameter->_bounds.size.width, drawParameter->_bounds.size.height), drawParameter->_opaque, drawParameter->_contentScale, nil, nil, ^{ + CGContextRef context = UIGraphicsGetCurrentContext(); + ASDisplayNodeAssert(context, @"This is no good without a context."); + + CGContextSaveGState(context); + CGContextTranslateCTM(context, textContainerInsets.left, textContainerInsets.top); + + // Fill background + if (backgroundColor != nil) { + [backgroundColor setFill]; + UIRectFillUsingBlendMode(CGContextGetClipBoundingBox(context), kCGBlendModeCopy); + } + + + // Draw text + [renderer drawInContext:context bounds:drawParameter->_bounds]; + CGContextRestoreGState(context); + }); + + return result; } #pragma mark - Attributes @@ -733,6 +777,7 @@ - (void)setHighlightRange:(NSRange)highlightRange animated:(BOOL)animated - (void)_setHighlightRange:(NSRange)highlightRange forAttributeName:(NSString *)highlightedAttributeName value:(id)highlightedAttributeValue animated:(BOOL)animated { ASDisplayNodeAssertMainThread(); + ASLockScopeSelf(); _highlightedLinkAttributeName = highlightedAttributeName; _highlightedLinkAttributeValue = highlightedAttributeValue; @@ -792,7 +837,6 @@ - (void)_setHighlightRange:(NSRange)highlightRange forAttributeName:(NSString *) } if (highlightTargetLayer != nil) { - ASLockScopeSelf(); ASTextKitRenderer *renderer = [self _locked_renderer]; NSArray *highlightRects = [renderer rectsForTextRange:highlightRange measureOption:ASTextKitRendererMeasureOptionBlock]; @@ -912,6 +956,39 @@ - (CGRect)frameForTextRange:(NSRange)textRange return ASTextNodeAdjustRenderRectForShadowPadding(frame, self.shadowPadding); } +#pragma mark - Tint Colors + + +- (void)tintColorDidChange +{ + [super tintColorDidChange]; + + [self _setNeedsDisplayOnTintedTextColor]; +} + +- (void)_setNeedsDisplayOnTintedTextColor +{ + BOOL textColorFollowsTintColor = NO; + { + AS::MutexLocker l(__instanceLock__); + textColorFollowsTintColor = _textColorFollowsTintColor; + } + + if (textColorFollowsTintColor) { + [self setNeedsDisplay]; + } +} + + +#pragma mark Interface State + +- (void)didEnterHierarchy +{ + [super didEnterHierarchy]; + + [self _setNeedsDisplayOnTintedTextColor]; +} + #pragma mark - Placeholders - (UIColor *)placeholderColor @@ -937,7 +1014,7 @@ - (UIImage *)placeholderImage ASLockScopeSelf(); - ASGraphicsBeginImageContextWithOptions(size, NO, 1.0); + UIGraphicsBeginImageContextWithOptions(size, NO, 1.0); [self.placeholderColor setFill]; ASTextKitRenderer *renderer = [self _locked_renderer]; @@ -956,7 +1033,8 @@ - (UIImage *)placeholderImage } } - UIImage *image = ASGraphicsGetImageAndEndCurrentContext(); + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); return image; } @@ -965,11 +1043,16 @@ - (UIImage *)placeholderImage - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { ASDisplayNodeAssertMainThread(); - + ASLockScopeSelf(); // Protect usage of _passthroughNonlinkTouches and _alwaysHandleTruncationTokenTap ivars. + if (!_passthroughNonlinkTouches) { return [super pointInside:point withEvent:event]; } + if (_alwaysHandleTruncationTokenTap) { + return YES; + } + NSRange range = NSMakeRange(0, 0); NSString *linkAttributeName = nil; BOOL inAdditionalTruncationMessage = NO; @@ -1105,6 +1188,18 @@ - (BOOL)_pendingTruncationTap return [_highlightedLinkAttributeName isEqualToString:ASTextNodeTruncationTokenAttributeName]; } +- (BOOL)alwaysHandleTruncationTokenTap +{ + ASLockScopeSelf(); + return _alwaysHandleTruncationTokenTap; +} + +- (void)setAlwaysHandleTruncationTokenTap:(BOOL)alwaysHandleTruncationTokenTap +{ + ASLockScopeSelf(); + _alwaysHandleTruncationTokenTap = alwaysHandleTruncationTokenTap; +} + #pragma mark - Shadow Properties - (CGColorRef)shadowColor @@ -1260,6 +1355,11 @@ - (NSUInteger)lineCount return ASLockedSelf([[self _locked_renderer] lineCount]); } +- (BOOL)textColorFollowsTintColor +{ + return ASLockedSelf(_textColorFollowsTintColor); +} + #pragma mark - Truncation Message - (void)_invalidateTruncationText diff --git a/Example/Pods/Texture/Source/ASTextNode2.h b/Example/Pods/Texture/Source/ASTextNode2.h index 254ce40..5848adc 100644 --- a/Example/Pods/Texture/Source/ASTextNode2.h +++ b/Example/Pods/Texture/Source/ASTextNode2.h @@ -209,9 +209,23 @@ NS_ASSUME_NONNULL_BEGIN /** @abstract if YES will not intercept touches for non-link areas of the text. Default is NO. + @discussion If you still want to handle tap truncation action when passthroughNonlinkTouches is YES, + you should set the alwaysHandleTruncationTokenTap to YES. */ @property (nonatomic) BOOL passthroughNonlinkTouches; +/** + @abstract Always handle tap truncationAction, even the passthroughNonlinkTouches is YES. Default is NO. + @discussion if this is set to YES, the [ASTextNodeDelegate textNodeTappedTruncationToken:] callback will be called. + */ +@property (nonatomic) BOOL alwaysHandleTruncationTokenTap; + +/** + @abstract if YES will use the value of `self.tintColor` if the foreground color of text is not defined. + @discussion This is mainly used from ASButtonNode since by default text nodes do not respect tintColor settings unless contained within a interactive control + */ +@property (nonatomic) BOOL textColorFollowsTintColor; + + (void)enableDebugging; #pragma mark - Layout and Sizing diff --git a/Example/Pods/Texture/Source/ASTextNode2.mm b/Example/Pods/Texture/Source/ASTextNode2.mm index 46c49e6..e268eca 100644 --- a/Example/Pods/Texture/Source/ASTextNode2.mm +++ b/Example/Pods/Texture/Source/ASTextNode2.mm @@ -20,19 +20,13 @@ #import #import -#import #import -#import - -#import -#import #import -#import @interface ASTextCacheValue : NSObject { @package - ASDN::Mutex _m; + AS::Mutex _m; std::deque> _layouts; } @end @@ -55,10 +49,10 @@ @implementation ASTextCacheValue */ static NS_RETURNS_RETAINED ASTextLayout *ASTextNodeCompatibleLayoutWithContainerAndText(ASTextContainer *container, NSAttributedString *text) { static dispatch_once_t onceToken; - static ASDN::Mutex *layoutCacheLock; + static AS::Mutex *layoutCacheLock; static NSCache *textLayoutCache; dispatch_once(&onceToken, ^{ - layoutCacheLock = new ASDN::Mutex(); + layoutCacheLock = new AS::Mutex(); textLayoutCache = [[NSCache alloc] init]; }); @@ -71,7 +65,7 @@ @implementation ASTextCacheValue } // Lock the cache item for the rest of the method. Only after acquiring can we release the NSCache. - ASDN::MutexLocker lock(cacheValue->_m); + AS::MutexLocker lock(cacheValue->_m); layoutCacheLock->unlock(); CGRect containerBounds = (CGRect){ .size = container.size }; @@ -137,23 +131,23 @@ @implementation ASTextCacheValue return layout; } +static const NSTimeInterval ASTextNodeHighlightFadeOutDuration = 0.15; +static const NSTimeInterval ASTextNodeHighlightFadeInDuration = 0.1; static const CGFloat ASTextNodeHighlightLightOpacity = 0.11; static const CGFloat ASTextNodeHighlightDarkOpacity = 0.22; static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncationAttribute"; #if AS_ENABLE_TEXTNODE -@interface ASTextNode2 () +#define AS_TN2_CLASSNAME ASTextNode2 #else -@interface ASTextNode () +#define AS_TN2_CLASSNAME ASTextNode #endif +@interface AS_TN2_CLASSNAME () + @end -#if AS_ENABLE_TEXTNODE -@implementation ASTextNode2 { -#else -@implementation ASTextNode { -#endif +@implementation AS_TN2_CLASSNAME { ASTextContainer *_textContainer; CGSize _shadowOffset; @@ -164,18 +158,20 @@ @implementation ASTextNode { NSAttributedString *_attributedText; NSAttributedString *_truncationAttributedText; NSAttributedString *_additionalTruncationMessage; - NSAttributedString *_composedTruncationText; NSArray *_pointSizeScaleFactors; NSLineBreakMode _truncationMode; NSString *_highlightedLinkAttributeName; id _highlightedLinkAttributeValue; - ASTextNodeHighlightStyle _highlightStyle; NSRange _highlightRange; ASHighlightOverlayLayer *_activeHighlightLayer; UIColor *_placeholderColor; UILongPressGestureRecognizer *_longPressGestureRecognizer; + ASTextNodeHighlightStyle _highlightStyle; + BOOL _longPressCancelsTouches; + BOOL _passthroughNonlinkTouches; + BOOL _alwaysHandleTruncationTokenTap; } @dynamic placeholderEnabled; @@ -227,12 +223,6 @@ - (instancetype)init - (void)dealloc { CGColorRelease(_shadowColor); - - if (_longPressGestureRecognizer) { - _longPressGestureRecognizer.delegate = nil; - [_longPressGestureRecognizer removeTarget:nil action:NULL]; - [self.view removeGestureRecognizer:_longPressGestureRecognizer]; - } } #pragma mark - Description @@ -296,7 +286,10 @@ - (BOOL)supportsLayerBacking for (NSString *linkAttributeName in _linkAttributeNames) { __block BOOL hasLink = NO; [attributedText enumerateAttribute:linkAttributeName inRange:range options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) { - hasLink = (value != nil); + if (value == nil) { + return; + } + hasLink = YES; *stop = YES; }]; if (hasLink) { @@ -402,6 +395,7 @@ - (void)setAttributedText:(NSAttributedString *)attributedText // Holding it for the duration of the method is more efficient in this case. ASLockScopeSelf(); + NSAttributedString *oldAttributedText = _attributedText; if (!ASCompareAssignCopy(_attributedText, attributedText)) { return; } @@ -424,7 +418,12 @@ - (void)setAttributedText:(NSAttributedString *)attributedText // Accessiblity self.accessibilityLabel = self.defaultAccessibilityLabel; - self.isAccessibilityElement = (length != 0); // We're an accessibility element by default if there is a string. + + // We update the isAccessibilityElement setting if this node is not switching between strings. + if (oldAttributedText.length == 0 || length == 0) { + // We're an accessibility element by default if there is a string. + self.isAccessibilityElement = (length != 0); + } #if AS_TEXTNODE2_RECORD_ATTRIBUTED_STRINGS [ASTextNode _registerAttributedText:_attributedText]; @@ -518,21 +517,45 @@ - (void)prepareAttributedString:(NSMutableAttributedString *)attributedString is - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer { - ASLockScopeSelf(); - [self _ensureTruncationText]; - - // Unlike layout, here we must copy the container since drawing is asynchronous. - ASTextContainer *copiedContainer = [_textContainer copy]; - copiedContainer.size = self.bounds.size; - [copiedContainer makeImmutable]; - NSMutableAttributedString *mutableText = [_attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init]; - - [self prepareAttributedString:mutableText isForIntrinsicSize:NO]; + ASTextContainer *copiedContainer; + NSMutableAttributedString *mutableText; + BOOL needsTintColor; + id bgColor; + { + // Wrapping all the other access here, because we can't lock while accessing tintColor. + ASLockScopeSelf(); + [self _ensureTruncationText]; + + // Unlike layout, here we must copy the container since drawing is asynchronous. + copiedContainer = [_textContainer copy]; + copiedContainer.size = self.bounds.size; + [copiedContainer makeImmutable]; + mutableText = [_attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init]; + + [self prepareAttributedString:mutableText isForIntrinsicSize:NO]; + needsTintColor = self.textColorFollowsTintColor && mutableText.length > 0; + bgColor = self.backgroundColor ?: [NSNull null]; + } + // After all other attributes are set, apply tint color if needed and foreground color is not already specified + if (needsTintColor) { + // Apply tint color if specified and if foreground color is undefined for attributedString + NSRange limit = NSMakeRange(0, mutableText.length); + // Look for previous attributes that define foreground color + UIColor *attributeValue = (UIColor *)[mutableText attribute:NSForegroundColorAttributeName atIndex:limit.location effectiveRange:NULL]; + + // we need to unlock before accessing tintColor + UIColor *tintColor = self.tintColor; + if (attributeValue == nil && tintColor) { + // None are found, apply tint color if available. Fallback to "black" text color + [mutableText addAttributes:@{ NSForegroundColorAttributeName : tintColor } range:limit]; + } + } + return @{ @"container": copiedContainer, @"text": mutableText, - @"bgColor": self.backgroundColor ?: [NSNull null] + @"bgColor": bgColor }; } @@ -565,6 +588,38 @@ + (void)drawRect:(CGRect)bounds withParameters:(NSDictionary *)layoutDict isCanc [layout drawInContext:context size:bounds.size point:bounds.origin view:nil layer:nil debug:[ASTextDebugOption sharedDebugOption] cancel:isCancelledBlock]; } +#pragma mark - Tint Color + +- (void)tintColorDidChange +{ + [super tintColorDidChange]; + + [self _setNeedsDisplayOnTintedTextColor]; +} + +- (void)_setNeedsDisplayOnTintedTextColor +{ + BOOL textColorFollowsTintColor = NO; + { + AS::MutexLocker l(__instanceLock__); + textColorFollowsTintColor = _textColorFollowsTintColor; + } + + if (textColorFollowsTintColor) { + [self setNeedsDisplay]; + } +} + + +#pragma mark Interface State + +- (void)didEnterHierarchy +{ + [super didEnterHierarchy]; + + [self _setNeedsDisplayOnTintedTextColor]; +} + #pragma mark - Attributes - (id)linkAttributeValueAtPoint:(CGPoint)point @@ -601,25 +656,41 @@ - (id)_linkAttributeValueAtPoint:(CGPoint)point NSRange visibleRange = layout.visibleRange; NSRange clampedRange = NSIntersectionRange(visibleRange, NSMakeRange(0, _attributedText.length)); - ASTextRange *range = [layout closestTextRangeAtPoint:point]; - NSRange effectiveRange = NSMakeRange(0, 0); - for (__strong NSString *attributeName in self.linkAttributeNames) { - id value = [self.attributedText attribute:attributeName atIndex:range.start.offset longestEffectiveRange:&effectiveRange inRange:clampedRange]; - if (value == nil) { - // Didn't find any links specified with this attribute. + + // Search the 9 points of a 44x44 square around the touch until we find a link. + // Start from center, then do sides, then do top/bottom, then do corners. + static constexpr CGSize kRectOffsets[9] = { + { 0, 0 }, + { -22, 0 }, { 22, 0 }, + { 0, -22 }, { 0, 22 }, + { -22, -22 }, { -22, 22 }, + { 22, -22 }, { 22, 22 } + }; + + for (const CGSize &offset : kRectOffsets) { + const CGPoint testPoint = CGPointMake(point.x + offset.width, + point.y + offset.height); + ASTextPosition *pos = [layout closestPositionToPoint:testPoint]; + if (!pos || !NSLocationInRange(pos.offset, clampedRange)) { continue; } + for (NSString *attributeName in _linkAttributeNames) { + NSRange effectiveRange = NSMakeRange(0, 0); + id value = [_attributedText attribute:attributeName atIndex:pos.offset + longestEffectiveRange:&effectiveRange inRange:clampedRange]; + if (value == nil) { + // Didn't find any links specified with this attribute. + continue; + } - // If highlighting, check with delegate first. If not implemented, assume YES. - id delegate = self.delegate; - if (highlighting - && [delegate respondsToSelector:@selector(textNode:shouldHighlightLinkAttribute:value:atPoint:)] - && ![delegate textNode:(ASTextNode *)self shouldHighlightLinkAttribute:attributeName value:value atPoint:point]) { - value = nil; - attributeName = nil; - } + // If highlighting, check with delegate first. If not implemented, assume YES. + if (highlighting + && [_delegate respondsToSelector:@selector(textNode:shouldHighlightLinkAttribute:value:atPoint:)] + && ![_delegate textNode:(ASTextNode *)self shouldHighlightLinkAttribute:attributeName + value:value atPoint:point]) { + continue; + } - if (value != nil || attributeName != nil) { *rangeOut = NSIntersectionRange(visibleRange, effectiveRange); if (attributeNameOut != NULL) { @@ -647,9 +718,17 @@ - (BOOL)_locked_pointInsideAdditionalTruncationMessage:(CGPoint)point withLayout CTLineRef truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_truncationAttributedText); CFIndex truncationTokenLineGlyphCount = truncationTokenLine ? CTLineGetGlyphCount(truncationTokenLine) : 0; + if (truncationTokenLine) { + CFRelease(truncationTokenLine); + } + CTLineRef additionalTruncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)_additionalTruncationMessage); - CFIndex additionalTruncationTokenLineGlyphCount = additionalTruncationTokenLine ? CTLineGetGlyphCount(additionalTruncationTokenLine) : 0; + CFIndex additionalTruncationTokenLineGlyphCount = additionalTruncationTokenLine ? CTLineGetGlyphCount(additionalTruncationTokenLine) : 0; + if (additionalTruncationTokenLine) { + CFRelease(additionalTruncationTokenLine); + } + switch (_textContainer.truncationType) { case ASTextTruncationTypeStart: { CFIndex composedTruncationTextLineGlyphCount = truncationTokenLineGlyphCount + additionalTruncationTokenLineGlyphCount; @@ -758,17 +837,114 @@ - (void)setHighlightRange:(NSRange)highlightRange animated:(BOOL)animated - (void)_setHighlightRange:(NSRange)highlightRange forAttributeName:(NSString *)highlightedAttributeName value:(id)highlightedAttributeValue animated:(BOOL)animated { + ASDisplayNodeAssertMainThread(); ASLockScopeSelf(); // Protect usage of _highlight* ivars. // Set these so that link tapping works. _highlightedLinkAttributeName = highlightedAttributeName; _highlightedLinkAttributeValue = highlightedAttributeValue; - _highlightRange = highlightRange; - AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE(); - // Much of the code from original ASTextNode is probably usable here. + if (!NSEqualRanges(highlightRange, _highlightRange) && ((0 != highlightRange.length) || (0 != _highlightRange.length))) { - return; + _highlightRange = highlightRange; + + if (_activeHighlightLayer) { + if (animated) { + __weak CALayer *weakHighlightLayer = _activeHighlightLayer; + _activeHighlightLayer = nil; + + weakHighlightLayer.opacity = 0.0; + + CFTimeInterval beginTime = CACurrentMediaTime(); + CABasicAnimation *possibleFadeIn = (CABasicAnimation *)[weakHighlightLayer animationForKey:@"opacity"]; + if (possibleFadeIn) { + // Calculate when we should begin fading out based on the end of the fade in animation, + // Also check to make sure that the new begin time hasn't already passed + CGFloat newBeginTime = (possibleFadeIn.beginTime + possibleFadeIn.duration); + if (newBeginTime > beginTime) { + beginTime = newBeginTime; + } + } + + CABasicAnimation *fadeOut = [CABasicAnimation animationWithKeyPath:@"opacity"]; + fadeOut.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + fadeOut.fromValue = possibleFadeIn.toValue ? : @(((CALayer *)weakHighlightLayer.presentationLayer).opacity); + fadeOut.toValue = @0.0; + fadeOut.fillMode = kCAFillModeBoth; + fadeOut.duration = ASTextNodeHighlightFadeOutDuration; + fadeOut.beginTime = beginTime; + + dispatch_block_t prev = [CATransaction completionBlock]; + [CATransaction setCompletionBlock:^{ + [weakHighlightLayer removeFromSuperlayer]; + }]; + + [weakHighlightLayer addAnimation:fadeOut forKey:fadeOut.keyPath]; + + [CATransaction setCompletionBlock:prev]; + + } else { + [_activeHighlightLayer removeFromSuperlayer]; + _activeHighlightLayer = nil; + } + } + if (0 != highlightRange.length) { + // Find layer in hierarchy that allows us to draw highlighting on. + CALayer *highlightTargetLayer = self.layer; + while (highlightTargetLayer != nil) { + if (highlightTargetLayer.as_allowsHighlightDrawing) { + break; + } + highlightTargetLayer = highlightTargetLayer.superlayer; + } + + if (highlightTargetLayer != nil) { + // TODO: The copy and application of size shouldn't be required, but it is currently. + // See discussion in https://github.com/TextureGroup/Texture/pull/396 + ASTextContainer *textContainerCopy = [_textContainer copy]; + textContainerCopy.size = self.calculatedSize; + ASTextLayout *layout = ASTextNodeCompatibleLayoutWithContainerAndText(textContainerCopy, _attributedText); + + NSArray *highlightRects = [layout selectionRectsWithoutStartAndEndForRange:[ASTextRange rangeWithRange:highlightRange]]; + NSMutableArray *converted = [NSMutableArray arrayWithCapacity:highlightRects.count]; + + CALayer *layer = self.layer; + UIEdgeInsets shadowPadding = self.shadowPadding; + for (ASTextSelectionRect *rectValue in highlightRects) { + // Adjust shadow padding + CGRect rendererRect = ASTextNodeAdjustRenderRectForShadowPadding(rectValue.rect, shadowPadding); + CGRect highlightedRect = [layer convertRect:rendererRect toLayer:highlightTargetLayer]; + + // We set our overlay layer's frame to the bounds of the highlight target layer. + // Offset highlight rects to avoid double-counting target layer's bounds.origin. + highlightedRect.origin.x -= highlightTargetLayer.bounds.origin.x; + highlightedRect.origin.y -= highlightTargetLayer.bounds.origin.y; + [converted addObject:[NSValue valueWithCGRect:highlightedRect]]; + } + + ASHighlightOverlayLayer *overlayLayer = [[ASHighlightOverlayLayer alloc] initWithRects:converted]; + overlayLayer.highlightColor = [[self class] _highlightColorForStyle:self.highlightStyle]; + overlayLayer.frame = highlightTargetLayer.bounds; + overlayLayer.masksToBounds = NO; + overlayLayer.opacity = [[self class] _highlightOpacityForStyle:self.highlightStyle]; + [highlightTargetLayer addSublayer:overlayLayer]; + + if (animated) { + CABasicAnimation *fadeIn = [CABasicAnimation animationWithKeyPath:@"opacity"]; + fadeIn.fromValue = @0.0; + fadeIn.toValue = @(overlayLayer.opacity); + fadeIn.duration = ASTextNodeHighlightFadeInDuration; + fadeIn.beginTime = CACurrentMediaTime(); + + [overlayLayer addAnimation:fadeIn forKey:fadeIn.keyPath]; + } + + [overlayLayer setNeedsDisplay]; + + _activeHighlightLayer = overlayLayer; + } + } + } } - (void)_clearHighlightIfNecessary @@ -792,6 +968,12 @@ + (CGFloat)_highlightOpacityForStyle:(ASTextNodeHighlightStyle)style #pragma mark - Text rects +static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UIEdgeInsets shadowPadding) { + rendererRect.origin.x -= shadowPadding.left; + rendererRect.origin.y -= shadowPadding.top; + return rendererRect; +} + - (NSArray *)rectsForTextRange:(NSRange)textRange { AS_TEXT_ALERT_UNIMPLEMENTED_FEATURE(); @@ -842,10 +1024,15 @@ - (UIImage *)placeholderImage - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { ASDisplayNodeAssertMainThread(); - + ASLockScopeSelf(); // Protect usage of _passthroughNonlinkTouches and _alwaysHandleTruncationTokenTap ivars. + if (!_passthroughNonlinkTouches) { return [super pointInside:point withEvent:event]; } + + if (_alwaysHandleTruncationTokenTap) { + return YES; + } NSRange range = NSMakeRange(0, 0); NSString *linkAttributeName = nil; @@ -992,6 +1179,18 @@ - (BOOL)_pendingTruncationTap return [ASLockedSelf(_highlightedLinkAttributeName) isEqualToString:ASTextNodeTruncationTokenAttributeName]; } +- (BOOL)alwaysHandleTruncationTokenTap +{ + ASLockScopeSelf(); + return _alwaysHandleTruncationTokenTap; +} + +- (void)setAlwaysHandleTruncationTokenTap:(BOOL)alwaysHandleTruncationTokenTap +{ + ASLockScopeSelf(); + _alwaysHandleTruncationTokenTap = alwaysHandleTruncationTokenTap; +} + #pragma mark - Shadow Properties /** @@ -1232,22 +1431,20 @@ - (NSRange)_additionalTruncationMessageRangeWithVisibleRange:(NSRange)visibleRan - (NSAttributedString *)_locked_composedTruncationText { DISABLED_ASAssertLocked(__instanceLock__); - if (_composedTruncationText == nil) { - if (_truncationAttributedText != nil && _additionalTruncationMessage != nil) { - NSMutableAttributedString *newComposedTruncationString = [[NSMutableAttributedString alloc] initWithAttributedString:_truncationAttributedText]; - [newComposedTruncationString.mutableString appendString:@" "]; - [newComposedTruncationString appendAttributedString:_additionalTruncationMessage]; - _composedTruncationText = newComposedTruncationString; - } else if (_truncationAttributedText != nil) { - _composedTruncationText = _truncationAttributedText; - } else if (_additionalTruncationMessage != nil) { - _composedTruncationText = _additionalTruncationMessage; - } else { - _composedTruncationText = DefaultTruncationAttributedString(); - } - _composedTruncationText = [self _locked_prepareTruncationStringForDrawing:_composedTruncationText]; + NSAttributedString *composedTruncationText = nil; + if (_truncationAttributedText != nil && _additionalTruncationMessage != nil) { + NSMutableAttributedString *newComposedTruncationString = [[NSMutableAttributedString alloc] initWithAttributedString:_truncationAttributedText]; + [newComposedTruncationString.mutableString appendString:@" "]; + [newComposedTruncationString appendAttributedString:_additionalTruncationMessage]; + composedTruncationText = newComposedTruncationString; + } else if (_truncationAttributedText != nil) { + composedTruncationText = _truncationAttributedText; + } else if (_additionalTruncationMessage != nil) { + composedTruncationText = _additionalTruncationMessage; + } else { + composedTruncationText = DefaultTruncationAttributedString(); } - return _composedTruncationText; + return [self _locked_prepareTruncationStringForDrawing:composedTruncationText]; } /** diff --git a/Example/Pods/Texture/Source/ASTextNodeCommon.h b/Example/Pods/Texture/Source/ASTextNodeCommon.h index ab4e134..beee262 100644 --- a/Example/Pods/Texture/Source/ASTextNodeCommon.h +++ b/Example/Pods/Texture/Source/ASTextNodeCommon.h @@ -22,7 +22,7 @@ /** * Highlight styles. */ -typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) { +typedef NS_ENUM(unsigned char, ASTextNodeHighlightStyle) { /** * Highlight style for text on a light background. */ diff --git a/Example/Pods/Texture/Source/ASVideoNode.h b/Example/Pods/Texture/Source/ASVideoNode.h index 48726a6..440c71c 100644 --- a/Example/Pods/Texture/Source/ASVideoNode.h +++ b/Example/Pods/Texture/Source/ASVideoNode.h @@ -74,7 +74,7 @@ NS_ASSUME_NONNULL_BEGIN @property BOOL shouldAggressivelyRecoverFromStall; @property (readonly) ASVideoNodePlayerState playerState; -//! Defaults to 1000 +//! Defaults to 10000 @property int32_t periodicTimeObserverTimescale; //! Defaults to AVLayerVideoGravityResizeAspect @@ -106,7 +106,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)videoNode:(ASVideoNode *)videoNode willChangePlayerState:(ASVideoNodePlayerState)state toState:(ASVideoNodePlayerState)toState; /** - * @abstract Ssks delegate if state change is allowed + * @abstract Asks delegate if state change is allowed * ASVideoNodePlayerStatePlaying or ASVideoNodePlayerStatePaused. * asks delegate if state change is allowed. * @param videoNode The video node. diff --git a/Example/Pods/Texture/Source/ASVideoNode.mm b/Example/Pods/Texture/Source/ASVideoNode.mm index 654ce93..141ca2e 100644 --- a/Example/Pods/Texture/Source/ASVideoNode.mm +++ b/Example/Pods/Texture/Source/ASVideoNode.mm @@ -17,8 +17,6 @@ #import #import #import -#import -#import static BOOL ASAssetIsEqual(AVAsset *asset1, AVAsset *asset2) { return ASObjectIsEqual(asset1, asset2) @@ -291,7 +289,7 @@ - (void)generatePlaceholderImage - (void)imageAtTime:(CMTime)imageTime completionHandler:(void(^)(UIImage *image))completionHandler { ASPerformBlockOnBackgroundThread(^{ - AVAsset *asset = self.asset; + AVAsset *asset = self->_asset; // Skip the asset image generation if we don't have any tracks available that are capable of supporting it NSArray* visualAssetArray = [asset tracksWithMediaCharacteristic:AVMediaCharacteristicVisual]; @@ -302,7 +300,7 @@ - (void)imageAtTime:(CMTime)imageTime completionHandler:(void(^)(UIImage *image) AVAssetImageGenerator *previewImageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset]; previewImageGenerator.appliesPreferredTrackTransform = YES; - previewImageGenerator.videoComposition = _videoComposition; + previewImageGenerator.videoComposition = self->_videoComposition; [previewImageGenerator generateCGImagesAsynchronouslyForTimes:@[[NSValue valueWithCMTime:imageTime]] completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) { @@ -326,7 +324,7 @@ - (void)setVideoPlaceholderImage:(UIImage *)image - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - ASDN::UniqueLock l(__instanceLock__); + AS::UniqueLock l(__instanceLock__); if (object == _currentPlayerItem) { if ([keyPath isEqualToString:kStatus]) { @@ -417,7 +415,7 @@ - (void)didEnterPreloadState NSArray *requestedKeys = @[@"playable"]; [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:^{ ASPerformBlockOnMainThread(^{ - if (_delegateFlags.delegateVideoNodeDidFinishInitialLoading) { + if (self->_delegateFlags.delegateVideoNodeDidFinishInitialLoading) { [self.delegate videoNodeDidFinishInitialLoading:self]; } [self prepareToPlayAsset:asset withKeys:requestedKeys]; diff --git a/Example/Pods/Texture/Source/ASVideoPlayerNode.h b/Example/Pods/Texture/Source/ASVideoPlayerNode.h index 3fbef2f..4483f60 100644 --- a/Example/Pods/Texture/Source/ASVideoPlayerNode.h +++ b/Example/Pods/Texture/Source/ASVideoPlayerNode.h @@ -63,7 +63,7 @@ NS_ASSUME_NONNULL_BEGIN /// You should never set any value on the backing video node. Use exclusivively the video player node to set properties @property (nonatomic, readonly) ASVideoNode *videoNode; -//! Defaults to 100 +//! Defaults to 10000 @property (nonatomic) int32_t periodicTimeObserverTimescale; //! Defaults to AVLayerVideoGravityResizeAspect @property (nonatomic, copy) NSString *gravity; diff --git a/Example/Pods/Texture/Source/ASVideoPlayerNode.mm b/Example/Pods/Texture/Source/ASVideoPlayerNode.mm index f8fdc06..36b4a3f 100644 --- a/Example/Pods/Texture/Source/ASVideoPlayerNode.mm +++ b/Example/Pods/Texture/Source/ASVideoPlayerNode.mm @@ -16,9 +16,7 @@ #import #import -#import #import -#import static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext; @@ -437,19 +435,19 @@ - (void)_locked_createScrubber slider.minimumValue = 0.0; slider.maximumValue = 1.0; - if (_delegateFlags.delegateScrubberMinimumTrackTintColor) { + if (strongSelf->_delegateFlags.delegateScrubberMinimumTrackTintColor) { slider.minimumTrackTintColor = [strongSelf.delegate videoPlayerNodeScrubberMinimumTrackTint:strongSelf]; } - if (_delegateFlags.delegateScrubberMaximumTrackTintColor) { + if (strongSelf->_delegateFlags.delegateScrubberMaximumTrackTintColor) { slider.maximumTrackTintColor = [strongSelf.delegate videoPlayerNodeScrubberMaximumTrackTint:strongSelf]; } - if (_delegateFlags.delegateScrubberThumbTintColor) { + if (strongSelf->_delegateFlags.delegateScrubberThumbTintColor) { slider.thumbTintColor = [strongSelf.delegate videoPlayerNodeScrubberThumbTint:strongSelf]; } - if (_delegateFlags.delegateScrubberThumbImage) { + if (strongSelf->_delegateFlags.delegateScrubberThumbImage) { UIImage *thumbImage = [strongSelf.delegate videoPlayerNodeScrubberThumbImage:strongSelf]; [slider setThumbImage:thumbImage forState:UIControlStateNormal]; } @@ -647,14 +645,14 @@ - (void)showSpinner UIActivityIndicatorView *spinnnerView = [[UIActivityIndicatorView alloc] init]; spinnnerView.backgroundColor = [UIColor clearColor]; - if (_delegateFlags.delegateSpinnerTintColor) { - spinnnerView.color = [_delegate videoPlayerNodeSpinnerTint:strongSelf]; + if (strongSelf->_delegateFlags.delegateSpinnerTintColor) { + spinnnerView.color = [strongSelf->_delegate videoPlayerNodeSpinnerTint:strongSelf]; } else { - spinnnerView.color = _defaultControlsColor; + spinnnerView.color = strongSelf->_defaultControlsColor; } - if (_delegateFlags.delegateSpinnerStyle) { - spinnnerView.activityIndicatorViewStyle = [_delegate videoPlayerNodeSpinnerStyle:strongSelf]; + if (strongSelf->_delegateFlags.delegateSpinnerStyle) { + spinnnerView.activityIndicatorViewStyle = [strongSelf->_delegate videoPlayerNodeSpinnerStyle:strongSelf]; } return spinnnerView; diff --git a/Example/Pods/Texture/Source/ASVisibilityProtocols.h b/Example/Pods/Texture/Source/ASVisibilityProtocols.h index 837e848..b9f5c7b 100644 --- a/Example/Pods/Texture/Source/ASVisibilityProtocols.h +++ b/Example/Pods/Texture/Source/ASVisibilityProtocols.h @@ -14,13 +14,13 @@ NS_ASSUME_NONNULL_BEGIN @class UIViewController; -AS_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visibilityDepth); +ASDK_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visibilityDepth); /** * ASVisibilityDepth * * @discussion "Visibility Depth" represents the number of user actions required to make an ASDisplayNode or - * ASViewController visibile. AsyncDisplayKit uses this information to intelligently manage memory and focus + * ASDKViewController visibile. AsyncDisplayKit uses this information to intelligently manage memory and focus * resources where they are most visible to the user. * * The ASVisibilityDepth protocol describes how custom view controllers can integrate with this system. @@ -38,7 +38,7 @@ AS_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visib * @discussion Represents the number of user actions necessary to reach the view controller. An increased visibility * depth indicates a higher number of user interactions for the view controller to be visible again. For example, * an onscreen navigation controller's top view controller should have a visibility depth of 0. The view controller - * one from the top should have a visibility deptch of 1 as should the root view controller in the stack (because + * one from the top should have a visibility depth of 1 as should the root view controller in the stack (because * the user can hold the back button to pop to the root view controller). * * Visibility depth is used to automatically adjust ranges on range controllers (and thus free up memory) and can @@ -55,11 +55,11 @@ AS_EXTERN ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visib * If implemented by a view controller container, use this method to notify child view controllers that their view * depth has changed @see ASNavigationController.m * - * If implemented on an ASViewController, use this method to reduce or increase the resources that your + * If implemented on an ASDKViewController, use this method to reduce or increase the resources that your * view controller uses. A higher visibility depth view controller should decrease it's resource usage, a lower * visibility depth controller should pre-warm resources in preperation for a display at 0 depth. * - * ASViewController implements this method and reduces / increases range mode of supporting nodes (such as ASCollectionNode + * ASDKViewController implements this method and reduces / increases range mode of supporting nodes (such as ASCollectionNode * and ASTableNode). * * @see visibilityDepth diff --git a/Example/Pods/Texture/Source/AsyncDisplayKit.h b/Example/Pods/Texture/Source/AsyncDisplayKit.h index eafc03f..2ac6e9b 100644 --- a/Example/Pods/Texture/Source/AsyncDisplayKit.h +++ b/Example/Pods/Texture/Source/AsyncDisplayKit.h @@ -48,6 +48,7 @@ #import #import +#import #import #import #import @@ -63,7 +64,7 @@ #import #import -#import +#import #import #import #import @@ -100,7 +101,6 @@ #import #import #import -#import #import #import #import @@ -120,7 +120,6 @@ #import #import #import -#import #import #import #import @@ -130,4 +129,5 @@ #import #import -#import +#import +#import diff --git a/Example/Pods/Texture/Source/Base/ASAssert.h b/Example/Pods/Texture/Source/Base/ASAssert.h index f00ce96..4445b24 100644 --- a/Example/Pods/Texture/Source/Base/ASAssert.h +++ b/Example/Pods/Texture/Source/Base/ASAssert.h @@ -74,11 +74,11 @@ */ #pragma mark - Main Thread Assertions Disabling -AS_EXTERN BOOL ASMainThreadAssertionsAreDisabled(void); +ASDK_EXTERN BOOL ASMainThreadAssertionsAreDisabled(void); -AS_EXTERN void ASPushMainThreadAssertionsDisabled(void); +ASDK_EXTERN void ASPushMainThreadAssertionsDisabled(void); -AS_EXTERN void ASPopMainThreadAssertionsDisabled(void); +ASDK_EXTERN void ASPopMainThreadAssertionsDisabled(void); #pragma mark - Non-Fatal Assertions diff --git a/Example/Pods/Texture/Source/Base/ASAvailability.h b/Example/Pods/Texture/Source/Base/ASAvailability.h index 76f3b2b..b210397 100644 --- a/Example/Pods/Texture/Source/Base/ASAvailability.h +++ b/Example/Pods/Texture/Source/Base/ASAvailability.h @@ -50,8 +50,13 @@ #define __IPHONE_11_0 110000 #endif +#ifndef __IPHONE_13_0 + #define __IPHONE_13_0 130000 +#endif + #define AS_AT_LEAST_IOS10 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_10_0) #define AS_AT_LEAST_IOS11 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_11_0) +#define AS_AT_LEAST_IOS13 (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0) // Use __builtin_available if we're on Xcode >= 9, AS_AT_LEAST otherwise. #if __has_builtin(__builtin_available) @@ -81,6 +86,7 @@ #define AS_PIN_REMOTE_IMAGE __has_include() #define AS_IG_LIST_KIT __has_include() +#define AS_IG_LIST_DIFF_KIT __has_include() /** * For IGListKit versions < 3.0, you have to use IGListCollectionView. diff --git a/Example/Pods/Texture/Source/Base/ASBaseDefines.h b/Example/Pods/Texture/Source/Base/ASBaseDefines.h index 36e9e55..53ea66a 100644 --- a/Example/Pods/Texture/Source/Base/ASBaseDefines.h +++ b/Example/Pods/Texture/Source/Base/ASBaseDefines.h @@ -9,20 +9,14 @@ #import -#define AS_EXTERN FOUNDATION_EXTERN +#define ASDK_EXTERN FOUNDATION_EXTERN #define unowned __unsafe_unretained /** - * Hack to support building for iOS with Xcode 9. UIUserInterfaceStyle was previously tvOS-only, - * and it was added to iOS 12. Xcode 9 (iOS 11 SDK) will flat-out refuse to build anything that - * references this enum targeting iOS, even if it's guarded with the right availability macros, - * because it thinks the entire platform isn't compatible with the enum. + * Decorates methods that clients can implement in categories on our base class. These methods + * will be stubbed with an empty implementation if no implementation is provided. */ -#if TARGET_OS_TV || (defined(__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0) -#define AS_BUILD_UIUSERINTERFACESTYLE 1 -#else -#define AS_BUILD_UIUSERINTERFACESTYLE 0 -#endif +#define AS_CATEGORY_IMPLEMENTABLE #ifdef __GNUC__ # define ASDISPLAYNODE_GNUC(major, minor) \ @@ -67,17 +61,6 @@ #define AS_ENABLE_TIPS 0 #endif -/** - * The event backtraces take a static 2KB of memory - * and retain all objects present in all the registers - * of the stack frames. The memory consumption impact - * is too significant even to be enabled during general - * development. - */ -#ifndef AS_SAVE_EVENT_BACKTRACES -# define AS_SAVE_EVENT_BACKTRACES 0 -#endif - #ifndef __has_feature // Optional. #define __has_feature(x) 0 // Compatibility with non-clang compilers. #endif @@ -128,6 +111,8 @@ #define ASOVERLOADABLE __attribute__((overloadable)) +/// Xcode >= 10. +#define AS_HAS_OS_SIGNPOST __has_include() #if __has_attribute(noescape) #define AS_NOESCAPE __attribute__((noescape)) @@ -141,6 +126,8 @@ #define AS_SUBCLASSING_RESTRICTED #endif +#define AS_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + #define ASCreateOnce(expr) ({ \ static dispatch_once_t onceToken; \ static __typeof__(expr) staticVar; \ diff --git a/Example/Pods/Texture/Source/Base/ASLog.h b/Example/Pods/Texture/Source/Base/ASLog.h index ccab4b8..fb0eb57 100644 --- a/Example/Pods/Texture/Source/Base/ASLog.h +++ b/Example/Pods/Texture/Source/Base/ASLog.h @@ -30,7 +30,7 @@ * are at the `debug` log level, which the system * disables in production. */ -AS_EXTERN void ASDisableLogging(void); +ASDK_EXTERN void ASDisableLogging(void); /** * Restore logging that has been runtime-disabled via ASDisableLogging(). @@ -40,31 +40,39 @@ AS_EXTERN void ASDisableLogging(void); * configuration. This can be used in conjunction with ASDisableLogging() * to allow logging to be toggled off and back on at runtime. */ -AS_EXTERN void ASEnableLogging(void); +ASDK_EXTERN void ASEnableLogging(void); /// Log for general node events e.g. interfaceState, didLoad. #define ASNodeLogEnabled 1 -AS_EXTERN os_log_t ASNodeLog(void); +ASDK_EXTERN os_log_t ASNodeLog(void); /// Log for layout-specific events e.g. calculateLayout. #define ASLayoutLogEnabled 1 -AS_EXTERN os_log_t ASLayoutLog(void); +ASDK_EXTERN os_log_t ASLayoutLog(void); /// Log for display-specific events e.g. display queue batches. #define ASDisplayLogEnabled 1 -AS_EXTERN os_log_t ASDisplayLog(void); +ASDK_EXTERN os_log_t ASDisplayLog(void); /// Log for collection events e.g. reloadData, performBatchUpdates. #define ASCollectionLogEnabled 1 -AS_EXTERN os_log_t ASCollectionLog(void); +ASDK_EXTERN os_log_t ASCollectionLog(void); /// Log for ASNetworkImageNode and ASMultiplexImageNode events. #define ASImageLoadingLogEnabled 1 -AS_EXTERN os_log_t ASImageLoadingLog(void); +ASDK_EXTERN os_log_t ASImageLoadingLog(void); /// Specialized log for our main thread deallocation trampoline. #define ASMainThreadDeallocationLogEnabled 0 -AS_EXTERN os_log_t ASMainThreadDeallocationLog(void); +ASDK_EXTERN os_log_t ASMainThreadDeallocationLog(void); + +#define ASLockingLogEnabled 0 +ASDK_EXTERN os_log_t ASLockingLog(void); + +#if AS_HAS_OS_SIGNPOST +/// Uses the special POI category for Instruments. Used by ASSignpost.h. +ASDK_EXTERN os_log_t ASPointsOfInterestLog(void); +#endif /** * The activity tracing system changed a lot between iOS 9 and 10. @@ -76,8 +84,11 @@ AS_EXTERN os_log_t ASMainThreadDeallocationLog(void); * reflected in the log whereas activities described by the newer * os_activity_scope are. So unfortunately we must use these iOS 10 * APIs to get meaningful logging data. + * + * NOTE: Creating and tearing down activities require inter-process communication and can + * take dozens of microseconds on an A8. We do it quite often. Enable activities only during debugging. */ -#if OS_LOG_TARGET_HAS_10_12_FEATURES +#if DEBUG && OS_LOG_TARGET_HAS_10_12_FEATURES #define OS_ACTIVITY_NULLABLE nullable #define AS_ACTIVITY_CURRENT OS_ACTIVITY_CURRENT @@ -113,51 +124,8 @@ AS_EXTERN os_log_t ASMainThreadDeallocationLog(void); #define as_activity_create_for_scope(description) \ as_activity_scope(as_activity_create(description, AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)) -/** - * The logging macros are not guarded by deployment-target checks like the activity macros are, but they are - * only available on iOS >= 9 at runtime, so just make them conditional. - */ - -#define as_log_create(subsystem, category) ({ \ -os_log_t __val; \ -if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ - __val = os_log_create(subsystem, category); \ -} else { \ - __val = (os_log_t)0; \ -} \ -__val; \ -}) - -#define as_log_debug(log, format, ...) \ -if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ - os_log_debug(log, format, ##__VA_ARGS__); \ -} else { \ - (void)0; \ -} \ - -#define as_log_info(log, format, ...) \ -if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ - os_log_info(log, format, ##__VA_ARGS__); \ -} else { \ - (void)0; \ -} \ - -#define as_log_error(log, format, ...) \ -if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ - os_log_error(log, format, ##__VA_ARGS__); \ -} else { \ - (void)0; \ -} \ - -#define as_log_fault(log, format, ...) \ -if (AS_AVAILABLE_IOS_TVOS(9, 9)) { \ - os_log_fault(log, format, ##__VA_ARGS__); \ -} else { \ - (void)0; \ -} \ - #if ASEnableVerboseLogging - #define as_log_verbose(log, format, ...) as_log_debug(log, format, ##__VA_ARGS__) + #define as_log_verbose(log, format, ...) os_log_debug(log, format, ##__VA_ARGS__) #else #define as_log_verbose(log, format, ...) #endif diff --git a/Example/Pods/Texture/Source/Base/ASLog.mm b/Example/Pods/Texture/Source/Base/ASLog.mm index 2702464..e2014e2 100644 --- a/Example/Pods/Texture/Source/Base/ASLog.mm +++ b/Example/Pods/Texture/Source/Base/ASLog.mm @@ -8,6 +8,9 @@ #import #import +#if AS_HAS_OS_SIGNPOST +#import +#endif static atomic_bool __ASLogEnabled = ATOMIC_VAR_INIT(YES); @@ -24,25 +27,35 @@ ASDISPLAYNODE_INLINE BOOL ASLoggingIsEnabled() { } os_log_t ASNodeLog() { - return (ASNodeLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(as_log_create("org.TextureGroup.Texture", "Node")) : OS_LOG_DISABLED; + return (ASNodeLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(os_log_create("org.TextureGroup.Texture", "Node")) : OS_LOG_DISABLED; } os_log_t ASLayoutLog() { - return (ASLayoutLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(as_log_create("org.TextureGroup.Texture", "Layout")) : OS_LOG_DISABLED; + return (ASLayoutLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(os_log_create("org.TextureGroup.Texture", "Layout")) : OS_LOG_DISABLED; } os_log_t ASCollectionLog() { - return (ASCollectionLogEnabled && ASLoggingIsEnabled()) ?ASCreateOnce(as_log_create("org.TextureGroup.Texture", "Collection")) : OS_LOG_DISABLED; + return (ASCollectionLogEnabled && ASLoggingIsEnabled()) ?ASCreateOnce(os_log_create("org.TextureGroup.Texture", "Collection")) : OS_LOG_DISABLED; } os_log_t ASDisplayLog() { - return (ASDisplayLogEnabled && ASLoggingIsEnabled()) ?ASCreateOnce(as_log_create("org.TextureGroup.Texture", "Display")) : OS_LOG_DISABLED; + return (ASDisplayLogEnabled && ASLoggingIsEnabled()) ?ASCreateOnce(os_log_create("org.TextureGroup.Texture", "Display")) : OS_LOG_DISABLED; } os_log_t ASImageLoadingLog() { - return (ASImageLoadingLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(as_log_create("org.TextureGroup.Texture", "ImageLoading")) : OS_LOG_DISABLED; + return (ASImageLoadingLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(os_log_create("org.TextureGroup.Texture", "ImageLoading")) : OS_LOG_DISABLED; } os_log_t ASMainThreadDeallocationLog() { - return (ASMainThreadDeallocationLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(as_log_create("org.TextureGroup.Texture", "MainDealloc")) : OS_LOG_DISABLED; + return (ASMainThreadDeallocationLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(os_log_create("org.TextureGroup.Texture", "MainDealloc")) : OS_LOG_DISABLED; } + +os_log_t ASLockingLog() { + return (ASLockingLogEnabled && ASLoggingIsEnabled()) ? ASCreateOnce(os_log_create("org.TextureGroup.Texture", "Locking")) : OS_LOG_DISABLED; +} + +#if AS_HAS_OS_SIGNPOST +os_log_t ASPointsOfInterestLog() { + return ASCreateOnce(os_log_create("org.TextureGroup.Texture", OS_LOG_CATEGORY_POINTS_OF_INTEREST)); +} +#endif diff --git a/Example/Pods/Texture/Source/Base/ASSignpost.h b/Example/Pods/Texture/Source/Base/ASSignpost.h index a841794..27a44af 100644 --- a/Example/Pods/Texture/Source/Base/ASSignpost.h +++ b/Example/Pods/Texture/Source/Base/ASSignpost.h @@ -9,50 +9,34 @@ /// The signposts we use. Signposts are grouped by color. The SystemTrace.tracetemplate file /// should be kept up-to-date with these values. typedef NS_ENUM(uint32_t, ASSignpostName) { - // Collection/Table (Blue) + // Collection/Table ASSignpostDataControllerBatch = 300, // Alloc/layout nodes before collection update. ASSignpostRangeControllerUpdate, // Ranges update pass. - ASSignpostCollectionUpdate, // Entire update process, from -endUpdates to [super perform…] - // Rendering (Green) + // Rendering ASSignpostLayerDisplay = 325, // Client display callout. ASSignpostRunLoopQueueBatch, // One batch of ASRunLoopQueue. - // Layout (Purple) + // Layout ASSignpostCalculateLayout = 350, // Start of calculateLayoutThatFits to end. Max 1 per thread. - // Misc (Orange) + // Misc ASSignpostDeallocQueueDrain = 375, // One chunk of dealloc queue work. arg0 is count. - ASSignpostCATransactionLayout, // The CA transaction commit layout phase. - ASSignpostCATransactionCommit // The CA transaction commit post-layout phase. + ASSignpostOrientationChange, // From WillChangeStatusBarOrientation to animation end. }; -typedef NS_ENUM(uintptr_t, ASSignpostColor) { - ASSignpostColorBlue, - ASSignpostColorGreen, - ASSignpostColorPurple, - ASSignpostColorOrange, - ASSignpostColorRed, - ASSignpostColorDefault -}; - -static inline ASSignpostColor ASSignpostGetColor(ASSignpostName name, ASSignpostColor colorPref) { - if (colorPref == ASSignpostColorDefault) { - return (ASSignpostColor)((name / 25) % 4); - } else { - return colorPref; - } -} - -#if defined(PROFILE) && __has_include() - #define AS_KDEBUG_ENABLE 1 +#ifdef PROFILE + #define AS_SIGNPOST_ENABLE 1 #else - #define AS_KDEBUG_ENABLE 0 + #define AS_SIGNPOST_ENABLE 0 #endif -#if AS_KDEBUG_ENABLE +#if AS_SIGNPOST_ENABLE #import +#if AS_HAS_OS_SIGNPOST +#import +#endif // These definitions are required to build the backward-compatible kdebug trace // on the iOS 10 SDK. The kdebug_trace function crashes if run on iOS 9 and earlier. @@ -68,27 +52,55 @@ static inline ASSignpostColor ASSignpostGetColor(ASSignpostName name, ASSignpost #define APPSDBG_CODE(SubClass,code) KDBG_CODE(DBG_APPS, SubClass, code) #endif -// Currently we'll reserve arg3. -#define ASSignpost(name, identifier, arg2, color) \ -AS_AT_LEAST_IOS10 ? kdebug_signpost(name, (uintptr_t)identifier, (uintptr_t)arg2, 0, ASSignpostGetColor(name, color)) \ -: syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, name) | DBG_FUNC_NONE, (uintptr_t)identifier, (uintptr_t)arg2, 0, ASSignpostGetColor(name, color)); +#if AS_HAS_OS_SIGNPOST -#define ASSignpostStartCustom(name, identifier, arg2) \ -AS_AT_LEAST_IOS10 ? kdebug_signpost_start(name, (uintptr_t)identifier, (uintptr_t)arg2, 0, 0) \ -: syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, name) | DBG_FUNC_START, (uintptr_t)identifier, (uintptr_t)arg2, 0, 0); -#define ASSignpostStart(name) ASSignpostStartCustom(name, self, 0) +#define ASSignpostStart(name, identifier, format, ...) ({\ + if (AS_AVAILABLE_IOS_TVOS(12, 12)) { \ + unowned os_log_t log = ASPointsOfInterestLog(); \ + os_signpost_id_t spid = os_signpost_id_make_with_id(log, identifier); \ + os_signpost_interval_begin(log, spid, #name, format, ##__VA_ARGS__); \ + } else if (AS_AVAILABLE_IOS_TVOS(10, 10)) { \ + kdebug_signpost_start(ASSignpost##name, (uintptr_t)identifier, 0, 0, 0); \ + } else { \ + syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, ASSignpost##name) | DBG_FUNC_START, (uintptr_t)identifier, 0, 0, 0); \ + } \ +}) -#define ASSignpostEndCustom(name, identifier, arg2, color) \ -AS_AT_LEAST_IOS10 ? kdebug_signpost_end(name, (uintptr_t)identifier, (uintptr_t)arg2, 0, ASSignpostGetColor(name, color)) \ -: syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, name) | DBG_FUNC_END, (uintptr_t)identifier, (uintptr_t)arg2, 0, ASSignpostGetColor(name, color)); -#define ASSignpostEnd(name) ASSignpostEndCustom(name, self, 0, ASSignpostColorDefault) +#define ASSignpostEnd(name, identifier, format, ...) ({\ + if (AS_AVAILABLE_IOS_TVOS(12, 12)) { \ + unowned os_log_t log = ASPointsOfInterestLog(); \ + os_signpost_id_t spid = os_signpost_id_make_with_id(log, identifier); \ + os_signpost_interval_end(log, spid, #name, format, ##__VA_ARGS__); \ + } else if (AS_AVAILABLE_IOS_TVOS(10, 10)) { \ + kdebug_signpost_end(ASSignpost##name, (uintptr_t)identifier, 0, 0, 0); \ + } else { \ + syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, ASSignpost##name) | DBG_FUNC_END, (uintptr_t)identifier, 0, 0, 0); \ + } \ +}) -#else +#else // !AS_HAS_OS_SIGNPOST + +#define ASSignpostStart(name, identifier, format, ...) ({\ + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { \ + kdebug_signpost_start(ASSignpost##name, (uintptr_t)identifier, 0, 0, 0); \ + } else { \ + syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, ASSignpost##name) | DBG_FUNC_START, (uintptr_t)identifier, 0, 0, 0); \ + } \ +}) + +#define ASSignpostEnd(name, identifier, format, ...) ({\ + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { \ + kdebug_signpost_end(ASSignpost##name, (uintptr_t)identifier, 0, 0, 0); \ + } else { \ + syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, ASSignpost##name) | DBG_FUNC_END, (uintptr_t)identifier, 0, 0, 0); \ + } \ +}) + +#endif + +#else // !AS_SIGNPOST_ENABLE -#define ASSignpost(name, identifier, arg2, color) -#define ASSignpostStartCustom(name, identifier, arg2) -#define ASSignpostStart(name) -#define ASSignpostEndCustom(name, identifier, arg2, color) -#define ASSignpostEnd(name) +#define ASSignpostStart(name, identifier, format, ...) +#define ASSignpostEnd(name, identifier, format, ...) #endif diff --git a/Example/Pods/Texture/Source/Debug/AsyncDisplayKit+Debug.mm b/Example/Pods/Texture/Source/Debug/AsyncDisplayKit+Debug.mm index e5e4e7d..965b265 100644 --- a/Example/Pods/Texture/Source/Debug/AsyncDisplayKit+Debug.mm +++ b/Example/Pods/Texture/Source/Debug/AsyncDisplayKit+Debug.mm @@ -9,11 +9,10 @@ #import #import -#import #import -#import #import #import +#import #import #import #import @@ -140,16 +139,14 @@ - (void)layout UIColor *borderColor = [[UIColor orangeColor] colorWithAlphaComponent:0.8]; UIColor *clipsBorderColor = [UIColor colorWithRed:30/255.0 green:90/255.0 blue:50/255.0 alpha:0.7]; CGRect imgRect = CGRectMake(0, 0, 2.0 * borderWidth + 1.0, 2.0 * borderWidth + 1.0); - - ASGraphicsBeginImageContextWithOptions(imgRect.size, NO, 1); - - [fillColor setFill]; - UIRectFill(imgRect); - - [self drawEdgeIfClippedWithEdges:clippedEdges color:clipsBorderColor borderWidth:borderWidth imgRect:imgRect]; - [self drawEdgeIfClippedWithEdges:clipsToBoundsClippedEdges color:borderColor borderWidth:borderWidth imgRect:imgRect]; - - UIImage *debugHighlightImage = ASGraphicsGetImageAndEndCurrentContext(); + + UIImage *debugHighlightImage = ASGraphicsCreateImage(self.primitiveTraitCollection, imgRect.size, NO, 1, nil, nil, ^{ + [fillColor setFill]; + UIRectFill(imgRect); + + [self drawEdgeIfClippedWithEdges:clippedEdges color:clipsBorderColor borderWidth:borderWidth imgRect:imgRect]; + [self drawEdgeIfClippedWithEdges:clipsToBoundsClippedEdges color:borderColor borderWidth:borderWidth imgRect:imgRect]; + }); UIEdgeInsets edgeInsets = UIEdgeInsetsMake(borderWidth, borderWidth, borderWidth, borderWidth); debugOverlay.image = [debugHighlightImage resizableImageWithCapInsets:edgeInsets resizingMode:UIImageResizingModeStretch]; @@ -427,10 +424,10 @@ - (void)addRangeController:(ASRangeController *)rangeController } [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ - _animating = YES; + self->_animating = YES; [self layoutToFitAllBarsExcept:0]; } completion:^(BOOL finished) { - _animating = NO; + self->_animating = NO; }]; } @@ -457,10 +454,10 @@ - (void)updateRangeController:(ASRangeController *)controller CGFloat leadingDisplayTuningRatio = 0; CGFloat leadingPreloadTuningRatio = 0; - if (!((displayTuningParameters.leadingBufferScreenfuls + displayTuningParameters.trailingBufferScreenfuls) == 0)) { + if (displayTuningParameters.leadingBufferScreenfuls + displayTuningParameters.trailingBufferScreenfuls != 0) { leadingDisplayTuningRatio = displayTuningParameters.leadingBufferScreenfuls / (displayTuningParameters.leadingBufferScreenfuls + displayTuningParameters.trailingBufferScreenfuls); } - if (!((preloadTuningParameters.leadingBufferScreenfuls + preloadTuningParameters.trailingBufferScreenfuls) == 0)) { + if (preloadTuningParameters.leadingBufferScreenfuls + preloadTuningParameters.trailingBufferScreenfuls != 0) { leadingPreloadTuningRatio = preloadTuningParameters.leadingBufferScreenfuls / (preloadTuningParameters.leadingBufferScreenfuls + preloadTuningParameters.trailingBufferScreenfuls); } @@ -656,15 +653,15 @@ - (void)layoutSubviews BOOL animate = !_firstLayoutOfRects; [UIView animateWithDuration:animate ? 0.3 : 0.0 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{ - _visibleRect.frame = CGRectMake(HORIZONTAL_INSET + visiblePoint, rect.origin.y, visibleDimension, subCellHeight); - _displayRect.frame = CGRectMake(HORIZONTAL_INSET + displayPoint, rect.origin.y, displayDimension, subCellHeight); - _preloadRect.frame = CGRectMake(HORIZONTAL_INSET + preloadPoint, rect.origin.y, preloadDimension, subCellHeight); + self->_visibleRect.frame = CGRectMake(HORIZONTAL_INSET + visiblePoint, rect.origin.y, visibleDimension, subCellHeight); + self->_displayRect.frame = CGRectMake(HORIZONTAL_INSET + displayPoint, rect.origin.y, displayDimension, subCellHeight); + self->_preloadRect.frame = CGRectMake(HORIZONTAL_INSET + preloadPoint, rect.origin.y, preloadDimension, subCellHeight); } completion:^(BOOL finished) {}]; if (!animate) { _visibleRect.alpha = _displayRect.alpha = _preloadRect.alpha = 0; [UIView animateWithDuration:0.3 animations:^{ - _visibleRect.alpha = _displayRect.alpha = _preloadRect.alpha = 1; + self->_visibleRect.alpha = self->_displayRect.alpha = self->_preloadRect.alpha = 1; }]; } @@ -732,13 +729,15 @@ - (ASTextNode *)createDebugTextNode - (ASImageNode *)createRangeNodeWithColor:(UIColor *)color { ASImageNode *rangeBarImageNode = [[ASImageNode alloc] init]; + ASPrimitiveTraitCollection primitiveTraitCollection = ASPrimitiveTraitCollectionFromUITraitCollection(self.traitCollection); rangeBarImageNode.image = [UIImage as_resizableRoundedImageWithCornerRadius:RANGE_BAR_CORNER_RADIUS cornerColor:[UIColor clearColor] fillColor:[color colorWithAlphaComponent:0.5] borderColor:[[UIColor blackColor] colorWithAlphaComponent:0.9] borderWidth:RANGE_BAR_BORDER_WIDTH roundedCorners:UIRectCornerAllCorners - scale:[[UIScreen mainScreen] scale]]; + scale:[[UIScreen mainScreen] scale] + traitCollection:primitiveTraitCollection]; [self addSubnode:rangeBarImageNode]; return rangeBarImageNode; diff --git a/Example/Pods/Texture/Source/Details/ASAbstractLayoutController.h b/Example/Pods/Texture/Source/Details/ASAbstractLayoutController.h index 6de7801..4cc7b3a 100644 --- a/Example/Pods/Texture/Source/Details/ASAbstractLayoutController.h +++ b/Example/Pods/Texture/Source/Details/ASAbstractLayoutController.h @@ -12,11 +12,11 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); +ASDK_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); -AS_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); +ASDK_EXTERN ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters); -AS_EXTERN CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningParameters tuningParameters, ASScrollDirection scrollableDirections, ASScrollDirection scrollDirection); +ASDK_EXTERN CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningParameters tuningParameters, ASScrollDirection scrollableDirections, ASScrollDirection scrollDirection); @interface ASAbstractLayoutController : NSObject diff --git a/Example/Pods/Texture/Source/Details/ASBasicImageDownloader.mm b/Example/Pods/Texture/Source/Details/ASBasicImageDownloader.mm index ae92c53..f577eb1 100644 --- a/Example/Pods/Texture/Source/Details/ASBasicImageDownloader.mm +++ b/Example/Pods/Texture/Source/Details/ASBasicImageDownloader.mm @@ -15,6 +15,7 @@ #import #import +using AS::MutexLocker; #pragma mark - /** @@ -25,10 +26,23 @@ NSString * const kASBasicImageDownloaderContextProgressBlock = @"kASBasicImageDownloaderContextProgressBlock"; NSString * const kASBasicImageDownloaderContextCompletionBlock = @"kASBasicImageDownloaderContextCompletionBlock"; +static inline float NSURLSessionTaskPriorityWithImageDownloaderPriority(ASImageDownloaderPriority priority) { + switch (priority) { + case ASImageDownloaderPriorityPreload: + return NSURLSessionTaskPriorityLow; + + case ASImageDownloaderPriorityImminent: + return NSURLSessionTaskPriorityDefault; + + case ASImageDownloaderPriorityVisible: + return NSURLSessionTaskPriorityHigh; + } +} + @interface ASBasicImageDownloaderContext () { BOOL _invalid; - ASDN::RecursiveMutex __instanceLock__; + AS::RecursiveMutex __instanceLock__; } @property (nonatomic) NSMutableArray *callbackDatas; @@ -39,19 +53,19 @@ @implementation ASBasicImageDownloaderContext static NSMutableDictionary *currentRequests = nil; -+ (ASDN::Mutex *)currentRequestLock ++ (AS::Mutex *)currentRequestLock { static dispatch_once_t onceToken; - static ASDN::Mutex *currentRequestsLock; + static AS::Mutex *currentRequestsLock; dispatch_once(&onceToken, ^{ - currentRequestsLock = new ASDN::Mutex(); + currentRequestsLock = new AS::Mutex(); }); return currentRequestsLock; } + (ASBasicImageDownloaderContext *)contextForURL:(NSURL *)URL { - ASDN::MutexLocker l(*self.currentRequestLock); + MutexLocker l(*self.currentRequestLock); if (!currentRequests) { currentRequests = [[NSMutableDictionary alloc] init]; } @@ -65,7 +79,7 @@ + (ASBasicImageDownloaderContext *)contextForURL:(NSURL *)URL + (void)cancelContextWithURL:(NSURL *)URL { - ASDN::MutexLocker l(*self.currentRequestLock); + MutexLocker l(*self.currentRequestLock); if (currentRequests) { [currentRequests removeObjectForKey:URL]; } @@ -82,7 +96,7 @@ - (instancetype)initWithURL:(NSURL *)URL - (void)cancel { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); NSURLSessionTask *sessionTask = self.sessionTask; if (sessionTask) { @@ -96,19 +110,19 @@ - (void)cancel - (BOOL)isCancelled { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _invalid; } - (void)addCallbackData:(NSDictionary *)callbackData { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); [self.callbackDatas addObject:callbackData]; } - (void)performProgressBlocks:(CGFloat)progress { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); for (NSDictionary *callbackData in self.callbackDatas) { ASImageDownloaderProgress progressBlock = callbackData[kASBasicImageDownloaderContextProgressBlock]; dispatch_queue_t callbackQueue = callbackData[kASBasicImageDownloaderContextCallbackQueue]; @@ -123,7 +137,7 @@ - (void)performProgressBlocks:(CGFloat)progress - (void)completeWithImage:(UIImage *)image error:(NSError *)error { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); for (NSDictionary *callbackData in self.callbackDatas) { ASImageDownloaderCompletion completionBlock = callbackData[kASBasicImageDownloaderContextCompletionBlock]; dispatch_queue_t callbackQueue = callbackData[kASBasicImageDownloaderContextCallbackQueue]; @@ -141,7 +155,7 @@ - (void)completeWithImage:(UIImage *)image error:(NSError *)error - (NSURLSessionTask *)createSessionTaskIfNecessaryWithBlock:(NSURLSessionTask *(^)())creationBlock { { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (self.isCancelled) { return nil; @@ -155,7 +169,7 @@ - (NSURLSessionTask *)createSessionTaskIfNecessaryWithBlock:(NSURLSessionTask *( NSURLSessionTask *newTask = creationBlock(); { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); if (self.isCancelled) { return nil; @@ -238,10 +252,23 @@ - (instancetype)_init #pragma mark ASImageDownloaderProtocol. -- (id)downloadImageWithURL:(NSURL *)URL - callbackQueue:(dispatch_queue_t)callbackQueue - downloadProgress:(nullable ASImageDownloaderProgress)downloadProgress - completion:(ASImageDownloaderCompletion)completion +- (nullable id)downloadImageWithURL:(NSURL *)URL + callbackQueue:(dispatch_queue_t)callbackQueue + downloadProgress:(nullable ASImageDownloaderProgress)downloadProgress + completion:(ASImageDownloaderCompletion)completion +{ + return [self downloadImageWithURL:URL + priority:ASImageDownloaderPriorityImminent // maps to default priority + callbackQueue:callbackQueue + downloadProgress:downloadProgress + completion:completion]; +} + +- (nullable id)downloadImageWithURL:(NSURL *)URL + priority:(ASImageDownloaderPriority)priority + callbackQueue:(dispatch_queue_t)callbackQueue + downloadProgress:(ASImageDownloaderProgress)downloadProgress + completion:(ASImageDownloaderCompletion)completion { ASBasicImageDownloaderContext *context = [ASBasicImageDownloaderContext contextForURL:URL]; @@ -263,9 +290,10 @@ - (id)downloadImageWithURL:(NSURL *)URL [context addCallbackData:[[NSDictionary alloc] initWithDictionary:callbackData]]; // Create new task if necessary - NSURLSessionDownloadTask *task = (NSURLSessionDownloadTask *)[context createSessionTaskIfNecessaryWithBlock:^(){return [_session downloadTaskWithURL:URL];}]; + NSURLSessionDownloadTask *task = (NSURLSessionDownloadTask *)[context createSessionTaskIfNecessaryWithBlock:^(){return [self->_session downloadTaskWithURL:URL];}]; if (task) { + task.priority = NSURLSessionTaskPriorityWithImageDownloaderPriority(priority); task.originalRequest.asyncdisplaykit_context = context; // start downloading diff --git a/Example/Pods/Texture/Source/Details/ASBatchContext.mm b/Example/Pods/Texture/Source/Details/ASBatchContext.mm index 2eadb8f..a3395f6 100644 --- a/Example/Pods/Texture/Source/Details/ASBatchContext.mm +++ b/Example/Pods/Texture/Source/Details/ASBatchContext.mm @@ -48,7 +48,7 @@ - (void)beginBatchFetching - (void)completeBatchFetching:(BOOL)didComplete { if (didComplete) { - as_log_debug(ASCollectionLog(), "Completed batch fetch with context %@", self); + os_log_debug(ASCollectionLog(), "Completed batch fetch with context %@", self); atomic_store(&_state, ASBatchContextStateCompleted); } } diff --git a/Example/Pods/Texture/Source/Details/ASCollectionElement.mm b/Example/Pods/Texture/Source/Details/ASCollectionElement.mm index dcf2b92..9f9a05c 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionElement.mm +++ b/Example/Pods/Texture/Source/Details/ASCollectionElement.mm @@ -9,7 +9,7 @@ #import #import -#import +#import @interface ASCollectionElement () @@ -19,7 +19,7 @@ @interface ASCollectionElement () @end @implementation ASCollectionElement { - std::mutex _lock; + AS::Mutex _lock; ASCellNode *_node; } @@ -45,7 +45,7 @@ - (instancetype)initWithNodeModel:(id)nodeModel - (ASCellNode *)node { - std::lock_guard l(_lock); + AS::MutexLocker l(_lock); if (_nodeBlock != nil) { ASCellNode *node = _nodeBlock(); _nodeBlock = nil; @@ -53,7 +53,6 @@ - (ASCellNode *)node ASDisplayNodeFailAssert(@"Node block returned nil node!"); node = [[ASCellNode alloc] init]; } - node.owningNode = _owningNode; node.collectionElement = self; ASTraitCollectionPropagateDown(node, _traitCollection); node.nodeModel = _nodeModel; @@ -64,7 +63,7 @@ - (ASCellNode *)node - (ASCellNode *)nodeIfAllocated { - std::lock_guard l(_lock); + AS::MutexLocker l(_lock); return _node; } @@ -73,7 +72,7 @@ - (void)setTraitCollection:(ASPrimitiveTraitCollection)traitCollection ASCellNode *nodeIfNeedsPropagation; { - std::lock_guard l(_lock); + AS::MutexLocker l(_lock); if (! ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(_traitCollection, traitCollection)) { _traitCollection = traitCollection; nodeIfNeedsPropagation = _node; diff --git a/Example/Pods/Texture/Source/Details/ASCollectionGalleryLayoutDelegate.mm b/Example/Pods/Texture/Source/Details/ASCollectionGalleryLayoutDelegate.mm index a67abd5..5ba74d6 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionGalleryLayoutDelegate.mm +++ b/Example/Pods/Texture/Source/Details/ASCollectionGalleryLayoutDelegate.mm @@ -10,7 +10,6 @@ #import #import -#import #import #import #import @@ -19,7 +18,6 @@ #import #import #import -#import #import #import diff --git a/Example/Pods/Texture/Source/Details/ASCollectionInternal.h b/Example/Pods/Texture/Source/Details/ASCollectionInternal.h index 1023566..42f651a 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionInternal.h +++ b/Example/Pods/Texture/Source/Details/ASCollectionInternal.h @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN @class ASRangeController; @interface ASCollectionView () -- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id)layoutFacilitator owningNode:(nullable ASCollectionNode *)owningNode eventLog:(nullable ASEventLog *)eventLog; +- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id)layoutFacilitator owningNode:(nullable ASCollectionNode *)owningNode; @property (nonatomic, weak) ASCollectionNode *collectionNode; @property (nonatomic, readonly) ASDataController *dataController; diff --git a/Example/Pods/Texture/Source/Details/ASCollectionLayoutContext.mm b/Example/Pods/Texture/Source/Details/ASCollectionLayoutContext.mm index 350be99..6f2ba71 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionLayoutContext.mm +++ b/Example/Pods/Texture/Source/Details/ASCollectionLayoutContext.mm @@ -9,7 +9,6 @@ #import #import -#import #import #import #import diff --git a/Example/Pods/Texture/Source/Details/ASCollectionLayoutState.mm b/Example/Pods/Texture/Source/Details/ASCollectionLayoutState.mm index 47087a1..0f98b21 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionLayoutState.mm +++ b/Example/Pods/Texture/Source/Details/ASCollectionLayoutState.mm @@ -7,9 +7,7 @@ // #import -#import -#import #import #import #import @@ -32,7 +30,7 @@ @implementation NSMapTable (ASCollectionLayoutConvenience) @end @implementation ASCollectionLayoutState { - ASDN::Mutex __instanceLock__; + AS::Mutex __instanceLock__; CGSize _contentSize; ASCollectionLayoutContext *_context; NSMapTable *_elementToLayoutAttributesTable; @@ -182,7 +180,7 @@ - (ASPageToLayoutAttributesTable *)getAndRemoveUnmeasuredLayoutAttributesPageTab CGSize pageSize = _context.viewportSize; CGSize contentSize = _contentSize; - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); if (_unmeasuredPageToLayoutAttributesTable.count == 0 || CGRectIsNull(rect) || CGRectIsEmpty(rect) || CGSizeEqualToSize(CGSizeZero, contentSize) || CGSizeEqualToSize(CGSizeZero, pageSize)) { return nil; } diff --git a/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutController.mm b/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutController.mm index 497cae9..b31bb12 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutController.mm +++ b/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutController.mm @@ -12,8 +12,6 @@ #import #import #import -#import -#import struct ASRangeGeometry { CGRect rangeBounds; @@ -83,7 +81,7 @@ - (void)allElementsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(AS } // Avoid excessive retains and releases, as well as property calls. We know the element is kept alive by map. - __unsafe_unretained ASCollectionElement *e = [map elementForLayoutAttributes:la]; + unowned ASCollectionElement *e = [map elementForLayoutAttributes:la]; if (e != nil && intersectsDisplay) { [display addObject:e]; } diff --git a/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.h b/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.h index a1ddb34..4e58890 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.h +++ b/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.h @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView); +ASDK_EXTERN ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView); @protocol ASCollectionViewLayoutInspecting diff --git a/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.mm b/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.mm index 0488092..1747c46 100644 --- a/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.mm +++ b/Example/Pods/Texture/Source/Details/ASCollectionViewLayoutInspector.mm @@ -10,8 +10,8 @@ #import #import -#import #import +#import #pragma mark - Helper Functions diff --git a/Example/Pods/Texture/Source/Details/ASDataController.h b/Example/Pods/Texture/Source/Details/ASDataController.h index b64c052..88150cb 100644 --- a/Example/Pods/Texture/Source/Details/ASDataController.h +++ b/Example/Pods/Texture/Source/Details/ASDataController.h @@ -12,19 +12,12 @@ #import #import #import -#import #ifdef __cplusplus #import #endif NS_ASSUME_NONNULL_BEGIN -#if ASEVENTLOG_ENABLE -#define ASDataControllerLogEvent(dataController, ...) [dataController.eventLog logEventWithBacktrace:(AS_SAVE_EVENT_BACKTRACES ? [NSThread callStackSymbols] : nil) format:__VA_ARGS__] -#else -#define ASDataControllerLogEvent(dataController, ...) -#endif - @class ASCellNode; @class ASCollectionElement; @class ASCollectionLayoutContext; @@ -39,8 +32,8 @@ NS_ASSUME_NONNULL_BEGIN typedef NSUInteger ASDataControllerAnimationOptions; -AS_EXTERN NSString * const ASDataControllerRowNodeKind; -AS_EXTERN NSString * const ASCollectionInvalidUpdateException; +ASDK_EXTERN NSString * const ASDataControllerRowNodeKind; +ASDK_EXTERN NSString * const ASCollectionInvalidUpdateException; /** Data source for data controller @@ -163,7 +156,7 @@ AS_EXTERN NSString * const ASCollectionInvalidUpdateException; */ @interface ASDataController : NSObject -- (instancetype)initWithDataSource:(id)dataSource node:(nullable id)node eventLog:(nullable ASEventLog *)eventLog NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithDataSource:(id)dataSource node:(nullable id)node NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; @@ -227,13 +220,6 @@ AS_EXTERN NSString * const ASCollectionInvalidUpdateException; */ @property (nonatomic, readonly) BOOL initialReloadDataHasBeenCalled; -#if ASEVENTLOG_ENABLE -/* - * @abstract The primitive event tracing object. You shouldn't directly use it to log event. Use the ASDataControllerLogEvent macro instead. - */ -@property (nonatomic, readonly) ASEventLog *eventLog; -#endif - /** @name Data Updating */ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet; diff --git a/Example/Pods/Texture/Source/Details/ASDataController.mm b/Example/Pods/Texture/Source/Details/ASDataController.mm index b4e8e9a..76e58d8 100644 --- a/Example/Pods/Texture/Source/Details/ASDataController.mm +++ b/Example/Pods/Texture/Source/Details/ASDataController.mm @@ -9,26 +9,20 @@ #import -#include - #import #import -#import #import #import #import -#import #import #import #import #import -#import #import #import #import #import #import -#import #import #import @@ -88,7 +82,7 @@ @implementation ASDataController #pragma mark - Lifecycle -- (instancetype)initWithDataSource:(id)dataSource node:(nullable id)node eventLog:(ASEventLog *)eventLog +- (instancetype)initWithDataSource:(id)dataSource node:(nullable id)node { if (!(self = [super init])) { return nil; @@ -103,10 +97,6 @@ - (instancetype)initWithDataSource:(id)dataSource node:( _dataSourceFlags.constrainedSizeForNodeAtIndexPath = [_dataSource respondsToSelector:@selector(dataController:constrainedSizeForNodeAtIndexPath:)]; _dataSourceFlags.constrainedSizeForSupplementaryNodeOfKindAtIndexPath = [_dataSource respondsToSelector:@selector(dataController:constrainedSizeForSupplementaryNodeOfKind:atIndexPath:)]; _dataSourceFlags.contextForSection = [_dataSource respondsToSelector:@selector(dataController:contextForSection:)]; - -#if ASEVENTLOG_ENABLE - _eventLog = eventLog; -#endif self.visibleMap = self.pendingMap = [[ASElementMap alloc] init]; @@ -151,7 +141,7 @@ - (void)_allocateNodesFromElements:(NSArray *)elements return; } - ASSignpostStart(ASSignpostDataControllerBatch); + ASSignpostStart(DataControllerBatch, self, "%@", ASObjectDescriptionMakeTiny(weakDataSource)); { as_activity_create_for_scope("Data controller batch"); @@ -168,7 +158,13 @@ - (void)_allocateNodesFromElements:(NSArray *)elements } unowned ASCollectionElement *element = elements[i]; + + NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary]; + dict[ASThreadDictMaxConstraintSizeKey] = + [NSValue valueWithCGSize:element.constrainedSize.max]; unowned ASCellNode *node = element.node; + [dict removeObjectForKey:ASThreadDictMaxConstraintSizeKey]; + // Layout the node if the size range is valid. ASSizeRange sizeRange = element.constrainedSize; if (ASSizeRangeHasSignificantArea(sizeRange)) { @@ -177,7 +173,7 @@ - (void)_allocateNodesFromElements:(NSArray *)elements }); } - ASSignpostEndCustom(ASSignpostDataControllerBatch, self, 0, (weakDataSource != nil ? ASSignpostColorDefault : ASSignpostColorRed)); + ASSignpostEnd(DataControllerBatch, self, "count: %lu", (unsigned long)nodeCount); } /** @@ -537,57 +533,47 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet _synchronized = NO; [changeSet addCompletionHandler:^(BOOL finished) { - _synchronized = YES; + self->_synchronized = YES; [self onDidFinishProcessingUpdates:^{ - if (_synchronized) { - for (ASDataControllerSynchronizationBlock block in _onDidFinishSynchronizingBlocks) { + if (self->_synchronized) { + for (ASDataControllerSynchronizationBlock block in self->_onDidFinishSynchronizingBlocks) { block(); } - [_onDidFinishSynchronizingBlocks removeAllObjects]; + [self->_onDidFinishSynchronizingBlocks removeAllObjects]; } }]; }]; if (changeSet.includesReloadData) { if (_initialReloadDataHasBeenCalled) { - as_log_debug(ASCollectionLog(), "reloadData %@", ASViewToDisplayNode(ASDynamicCast(self.dataSource, UIView))); + os_log_debug(ASCollectionLog(), "reloadData %@", ASViewToDisplayNode(ASDynamicCast(self.dataSource, UIView))); } else { - as_log_debug(ASCollectionLog(), "Initial reloadData %@", ASViewToDisplayNode(ASDynamicCast(self.dataSource, UIView))); + os_log_debug(ASCollectionLog(), "Initial reloadData %@", ASViewToDisplayNode(ASDynamicCast(self.dataSource, UIView))); _initialReloadDataHasBeenCalled = YES; } } else { - as_log_debug(ASCollectionLog(), "performBatchUpdates %@ %@", ASViewToDisplayNode(ASDynamicCast(self.dataSource, UIView)), changeSet); + os_log_debug(ASCollectionLog(), "performBatchUpdates %@ %@", ASViewToDisplayNode(ASDynamicCast(self.dataSource, UIView)), changeSet); } - - NSTimeInterval transactionQueueFlushDuration = 0.0f; - { - ASDN::ScopeTimer t(transactionQueueFlushDuration); - dispatch_group_wait(_editingTransactionGroup, DISPATCH_TIME_FOREVER); + + if (!ASActivateExperimentalFeature(ASExperimentalOptimizeDataControllerPipeline)) { + NSTimeInterval transactionQueueFlushDuration = 0.0f; + { + AS::ScopeTimer t(transactionQueueFlushDuration); + dispatch_group_wait(_editingTransactionGroup, DISPATCH_TIME_FOREVER); + } } - + // If the initial reloadData has not been called, just bail because we don't have our old data source counts. // See ASUICollectionViewTests.testThatIssuingAnUpdateBeforeInitialReloadIsUnacceptable // for the issue that UICollectionView has that we're choosing to workaround. if (!_initialReloadDataHasBeenCalled) { - as_log_debug(ASCollectionLog(), "%@ Skipped update because load hasn't happened.", ASObjectDescriptionMakeTiny(_dataSource)); + os_log_debug(ASCollectionLog(), "%@ Skipped update because load hasn't happened.", ASObjectDescriptionMakeTiny(_dataSource)); [changeSet executeCompletionHandlerWithFinished:YES]; return; } [self invalidateDataSourceItemCounts]; - // Log events -#if ASEVENTLOG_ENABLE - ASDataControllerLogEvent(self, @"updateWithChangeSet waited on previous update for %fms. changeSet: %@", - transactionQueueFlushDuration * 1000.0f, changeSet); - NSTimeInterval changeSetStartTime = CACurrentMediaTime(); - NSString *changeSetDescription = ASObjectDescriptionMakeTiny(changeSet); - [changeSet addCompletionHandler:^(BOOL finished) { - ASDataControllerLogEvent(self, @"finishedUpdate in %fms: %@", - (CACurrentMediaTime() - changeSetStartTime) * 1000.0f, changeSetDescription); - }]; -#endif - // Attempt to mark the update completed. This is when update validation will occur inside the changeset. // If an invalid update exception is thrown, we catch it and inject our "validationErrorSource" object, // which is the table/collection node's data source, into the exception reason to help debugging. @@ -633,7 +619,7 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet } } - as_log_debug(ASCollectionLog(), "New content: %@", newMap.smallDescription); + os_log_debug(ASCollectionLog(), "New content: %@", newMap.smallDescription); Class layoutDelegateClass = [self.layoutDelegate class]; ++_editingTransactionGroupCount; @@ -660,9 +646,9 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet } // Step 4: Inform the delegate on main thread - [_mainSerialQueue performBlockOnMainThread:^{ + [self->_mainSerialQueue performBlockOnMainThread:^{ as_activity_scope_leave(&preparationScope); - [_delegate dataController:self updateWithChangeSet:changeSet updates:^{ + [self->_delegate dataController:self updateWithChangeSet:changeSet updates:^{ // Step 5: Deploy the new data as "completed" // // Note that since the backing collection view might be busy responding to user events (e.g scrolling), @@ -673,7 +659,7 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet self.visibleMap = newMap; }]; }]; - --_editingTransactionGroupCount; + --self->_editingTransactionGroupCount; }); // We've now dispatched node allocation and layout to a concurrent background queue. @@ -912,7 +898,7 @@ - (void)_relayoutAllNodes - (void)environmentDidChange { ASPerformBlockOnMainThread(^{ - if (!_initialReloadDataHasBeenCalled) { + if (!self->_initialReloadDataHasBeenCalled) { return; } @@ -920,7 +906,7 @@ - (void)environmentDidChange // i.e there might be some elements that were allocated using the old trait collection but haven't been added to _visibleMap [self _scheduleBlockOnMainSerialQueue:^{ ASPrimitiveTraitCollection newTraitCollection = [self.node primitiveTraitCollection]; - for (ASCollectionElement *element in _visibleMap) { + for (ASCollectionElement *element in self->_visibleMap) { element.traitCollection = newTraitCollection; } }]; diff --git a/Example/Pods/Texture/Source/Details/ASDelegateProxy.mm b/Example/Pods/Texture/Source/Details/ASDelegateProxy.mm index bc51bb3..844fe63 100644 --- a/Example/Pods/Texture/Source/Details/ASDelegateProxy.mm +++ b/Example/Pods/Texture/Source/Details/ASDelegateProxy.mm @@ -10,7 +10,20 @@ #import #import #import -#import + +// UIKit performs a class check for UIDataSourceModelAssociation protocol conformance rather than an instance check, so +// the implementation of conformsToProtocol: below never gets called. We need to declare the two as conforming to the protocol here, then +// we need to implement dummy methods to get rid of a compiler warning about not conforming to the protocol. +@interface ASTableViewProxy () +@end + +@interface ASCollectionViewProxy () +@end + +@interface ASDelegateProxy (UIDataSourceModelAssociationPrivate) +- (nullable NSString *)_modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inView:(UIView *)view; +- (nullable NSIndexPath *)_indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view; +@end @implementation ASTableViewProxy @@ -54,10 +67,22 @@ - (BOOL)interceptsSelector:(SEL)selector // used for batch fetching API selector == @selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:) || - selector == @selector(scrollViewDidEndDecelerating:) + selector == @selector(scrollViewDidEndDecelerating:) || + + // UIDataSourceModelAssociation + selector == @selector(modelIdentifierForElementAtIndexPath:inView:) || + selector == @selector(indexPathForElementWithModelIdentifier:inView:) ); } +- (nullable NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inView:(UIView *)view { + return [self _modelIdentifierForElementAtIndexPath:indexPath inView:view]; +} + +- (nullable NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view { + return [self _indexPathForElementWithModelIdentifier:identifier inView:view]; +} + @end @implementation ASCollectionViewProxy @@ -110,10 +135,22 @@ - (BOOL)interceptsSelector:(SEL)selector // intercepted due to not being supported by ASCollectionView (prevent bugs caused by usage) selector == @selector(collectionView:canMoveItemAtIndexPath:) || - selector == @selector(collectionView:moveItemAtIndexPath:toIndexPath:) + selector == @selector(collectionView:moveItemAtIndexPath:toIndexPath:) || + + // UIDataSourceModelAssociation + selector == @selector(modelIdentifierForElementAtIndexPath:inView:) || + selector == @selector(indexPathForElementWithModelIdentifier:inView:) ); } +- (nullable NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inView:(UIView *)view { + return [self _modelIdentifierForElementAtIndexPath:indexPath inView:view]; +} + +- (nullable NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view { + return [self _indexPathForElementWithModelIdentifier:identifier inView:view]; +} + @end @implementation ASPagerNodeProxy @@ -220,4 +257,12 @@ - (BOOL)interceptsSelector:(SEL)selector return NO; } +- (nullable NSString *)_modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inView:(UIView *)view { + return [(id)_interceptor modelIdentifierForElementAtIndexPath:indexPath inView:view]; +} + +- (nullable NSIndexPath *)_indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view { + return [(id)_interceptor indexPathForElementWithModelIdentifier:identifier inView:view]; +} + @end diff --git a/Example/Pods/Texture/Source/Details/ASElementMap.mm b/Example/Pods/Texture/Source/Details/ASElementMap.mm index 791344f..6dd0d64 100644 --- a/Example/Pods/Texture/Source/Details/ASElementMap.mm +++ b/Example/Pods/Texture/Source/Details/ASElementMap.mm @@ -13,7 +13,6 @@ #import #import #import -#import #import @interface ASElementMap () @@ -194,7 +193,7 @@ - (id)mutableCopyWithZone:(NSZone *)zone #pragma mark - NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id _Nullable __unsafe_unretained [])buffer count:(NSUInteger)len +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id _Nullable unowned [])buffer count:(NSUInteger)len { return [_elementToIndexPathMap countByEnumeratingWithState:state objects:buffer count:len]; } diff --git a/Example/Pods/Texture/Source/Details/ASEventLog.h b/Example/Pods/Texture/Source/Details/ASEventLog.h deleted file mode 100644 index 9a147f2..0000000 --- a/Example/Pods/Texture/Source/Details/ASEventLog.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// ASEventLog.h -// Texture -// -// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. -// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -// - -#import -#import - -#ifndef ASEVENTLOG_CAPACITY -#define ASEVENTLOG_CAPACITY 5 -#endif - -#ifndef ASEVENTLOG_ENABLE -#define ASEVENTLOG_ENABLE 0 -#endif - -NS_ASSUME_NONNULL_BEGIN - -AS_SUBCLASSING_RESTRICTED -@interface ASEventLog : NSObject - -/** - * Create a new event log. - * - * @param anObject The object whose events we are logging. This object is not retained. - */ -- (instancetype)initWithObject:(id)anObject; - -- (void)logEventWithBacktrace:(nullable NSArray *)backtrace format:(NSString *)format, ... NS_FORMAT_FUNCTION(2, 3); - -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Details/ASEventLog.mm b/Example/Pods/Texture/Source/Details/ASEventLog.mm deleted file mode 100644 index 00bdbb5..0000000 --- a/Example/Pods/Texture/Source/Details/ASEventLog.mm +++ /dev/null @@ -1,121 +0,0 @@ -// -// ASEventLog.mm -// Texture -// -// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. -// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -// - -#import -#import -#import -#import - -@implementation ASEventLog { - ASDN::RecursiveMutex __instanceLock__; - - // The index of the most recent log entry. -1 until first entry. - NSInteger _eventLogHead; - - // A description of the object we're logging for. This is immutable. - NSString *_objectDescription; -} - -/** - * Even just when debugging, all these events can take up considerable memory. - * Store them in a shared NSCache to limit the total consumption. - */ -+ (NSCache *> *)contentsCache -{ - static NSCache *cache; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - cache = [[NSCache alloc] init]; - }); - return cache; -} - -- (instancetype)initWithObject:(id)anObject -{ - if ((self = [super init])) { - _objectDescription = ASObjectDescriptionMakeTiny(anObject); - _eventLogHead = -1; - } - return self; -} - -- (instancetype)init -{ - // This method is marked unavailable so the compiler won't let them call it. - ASDisplayNodeFailAssert(@"Failed to call initWithObject:"); - return nil; -} - -- (void)logEventWithBacktrace:(NSArray *)backtrace format:(NSString *)format, ... -{ - va_list args; - va_start(args, format); - ASTraceEvent *event = [[ASTraceEvent alloc] initWithBacktrace:backtrace - format:format - arguments:args]; - va_end(args); - - ASDN::MutexLocker l(__instanceLock__); - NSCache *cache = [ASEventLog contentsCache]; - NSMutableArray *events = [cache objectForKey:self]; - if (events == nil) { - events = [NSMutableArray arrayWithObject:event]; - [cache setObject:events forKey:self]; - _eventLogHead = 0; - return; - } - - // Increment the head index. - _eventLogHead = (_eventLogHead + 1) % ASEVENTLOG_CAPACITY; - if (_eventLogHead < events.count) { - [events replaceObjectAtIndex:_eventLogHead withObject:event]; - } else { - [events insertObject:event atIndex:_eventLogHead]; - } -} - -- (NSArray *)events -{ - NSMutableArray *events = [[ASEventLog contentsCache] objectForKey:self]; - if (events == nil) { - return nil; - } - - ASDN::MutexLocker l(__instanceLock__); - NSUInteger tail = (_eventLogHead + 1); - NSUInteger count = events.count; - - NSMutableArray *result = [NSMutableArray array]; - - // Start from `tail` and go through array, wrapping around when we exceed end index. - for (NSUInteger actualIndex = 0; actualIndex < ASEVENTLOG_CAPACITY; actualIndex++) { - NSInteger ringIndex = (tail + actualIndex) % ASEVENTLOG_CAPACITY; - if (ringIndex < count) { - [result addObject:events[ringIndex]]; - } - } - return result; -} - -- (NSString *)description -{ - /** - * This description intentionally doesn't follow the standard description format. - * Since this is a log, it's important for the description to look a certain way, and - * the formal description style doesn't allow for newlines and has a ton of punctuation. - */ - NSArray *events = [self events]; - if (events == nil) { - return [NSString stringWithFormat:@"Event log for %@ was purged to conserve memory.", _objectDescription]; - } else { - return [NSString stringWithFormat:@"Event log for %@. Events: %@", _objectDescription, events]; - } -} - -@end diff --git a/Example/Pods/Texture/Source/Details/ASGraphicsContext.h b/Example/Pods/Texture/Source/Details/ASGraphicsContext.h index d22d380..5bd1537 100644 --- a/Example/Pods/Texture/Source/Details/ASGraphicsContext.h +++ b/Example/Pods/Texture/Source/Details/ASGraphicsContext.h @@ -6,45 +6,60 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import #import -#import - -@class UIImage; - -/** - * Functions for creating one-shot graphics contexts that do not have to copy - * their contents when an image is generated from them. This is efficient - * for our use, since we do not reuse graphics contexts. - * - * The API mirrors the UIGraphics API, with the exception that forming an image - * ends the context as well. - * - * Note: You must not mix-and-match between ASGraphics* and UIGraphics* functions - * within the same drawing operation. - */ +#import +#import NS_ASSUME_NONNULL_BEGIN /** - * Creates a one-shot context. + * A wrapper for the UIKit drawing APIs. If you are in ASExperimentalDrawingGlobal, and you have iOS >= 10, we will create + * a UIGraphicsRenderer with an appropriate format. Otherwise, we will use UIGraphicsBeginImageContext et al. * - * Behavior is the same as UIGraphicsBeginImageContextWithOptions. + * @param size The size of the context. + * @param opaque Whether the context should be opaque or not. + * @param scale The scale of the context. 0 uses main screen scale. + * @param sourceImage If you are planning to render a UIImage into this context, provide it here and we will use its + * preferred renderer format if we are using UIGraphicsImageRenderer. + * @param isCancelled An optional block for canceling the drawing before forming the image. Only takes effect under + * the legacy code path, as UIGraphicsRenderer does not support cancellation. + * @param work A block, wherein the current UIGraphics context is set based on the arguments. + * + * @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. */ -AS_EXTERN void ASGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale); +ASDK_EXTERN UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE _Nullable isCancelled, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImageWithTraitCollectionAndOptions instead"); /** - * Generates and image and ends the current one-shot context. - * - * Behavior is the same as UIGraphicsGetImageFromCurrentImageContext followed by UIGraphicsEndImageContext. - */ -AS_EXTERN UIImage * _Nullable ASGraphicsGetImageAndEndCurrentContext(void) NS_RETURNS_RETAINED; +* A wrapper for the UIKit drawing APIs. If you are in ASExperimentalDrawingGlobal, and you have iOS >= 10, we will create +* a UIGraphicsRenderer with an appropriate format. Otherwise, we will use UIGraphicsBeginImageContext et al. +* +* @param traitCollection Trait collection. The `work` block will be executed with this trait collection, so it will affect dynamic colors, etc. +* @param size The size of the context. +* @param opaque Whether the context should be opaque or not. +* @param scale The scale of the context. 0 uses main screen scale. +* @param sourceImage If you are planning to render a UIImage into this context, provide it here and we will use its +* preferred renderer format if we are using UIGraphicsImageRenderer. +* @param isCancelled An optional block for canceling the drawing before forming the image. +* @param work A block, wherein the current UIGraphics context is set based on the arguments. +* +* @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. +*/ +ASDK_EXTERN UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, asdisplaynode_iscancelled_block_t _Nullable NS_NOESCAPE isCancelled, void (NS_NOESCAPE ^work)(void)); /** - * Call this if you want to end the current context without making an image. - * - * Behavior is the same as UIGraphicsEndImageContext. - */ -AS_EXTERN void ASGraphicsEndImageContext(void); +* A wrapper for the UIKit drawing APIs. +* +* @param traitCollection Trait collection. The `work` block will be executed with this trait collection, so it will affect dynamic colors, etc. +* @param size The size of the context. +* @param opaque Whether the context should be opaque or not. +* @param scale The scale of the context. 0 uses main screen scale. +* @param sourceImage If you are planning to render a UIImage into this context, provide it here and we will use its +* preferred renderer format if we are using UIGraphicsImageRenderer. +* @param work A block, wherein the current UIGraphics context is set based on the arguments. +* +* @return The rendered image. You can also render intermediary images using UIGraphicsGetImageFromCurrentImageContext. +*/ +ASDK_EXTERN UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * _Nullable sourceImage, void (NS_NOESCAPE ^work)(void)) ASDISPLAYNODE_DEPRECATED_MSG("Use ASGraphicsCreateImage instead"); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Details/ASGraphicsContext.mm b/Example/Pods/Texture/Source/Details/ASGraphicsContext.mm index b950613..8f543e0 100644 --- a/Example/Pods/Texture/Source/Details/ASGraphicsContext.mm +++ b/Example/Pods/Texture/Source/Details/ASGraphicsContext.mm @@ -7,161 +7,130 @@ // #import -#import #import #import #import -#import -#import -#import +#import -/** - * Our version of the private CGBitmapGetAlignedBytesPerRow function. - * - * In both 32-bit and 64-bit, this function rounds up to nearest multiple of 32 - * in iOS 9, 10, and 11. We'll try to catch if this ever changes by asserting that - * the bytes-per-row for a 1x1 context from the system is 32. - */ -static size_t ASGraphicsGetAlignedBytesPerRow(size_t baseValue) { - // Add 31 then zero out low 5 bits. - return (baseValue + 31) & ~0x1F; -} -/** - * A key used to associate CGContextRef -> NSMutableData, nonatomic retain. - * - * That way the data will be released when the context dies. If they pull an image, - * we will retain the data object (in a CGDataProvider) before releasing the context. - */ -static UInt8 __contextDataAssociationKey; +#if AS_AT_LEAST_IOS13 +#define ASPerformBlockWithTraitCollection(work, traitCollection) \ + if (@available(iOS 13.0, tvOS 13.0, *)) { \ + UITraitCollection *uiTraitCollection = ASPrimitiveTraitCollectionToUITraitCollection(traitCollection); \ + [uiTraitCollection performAsCurrentTraitCollection:^{ \ + work(); \ + }];\ + } else { \ + work(); \ + } +#else +#define ASPerformBlockWithTraitCollection(work, traitCollection) work(); +#endif -#pragma mark - Graphics Contexts -void ASGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) +NS_AVAILABLE_IOS(10) +NS_INLINE void ASConfigureExtendedRange(UIGraphicsImageRendererFormat *format) { - if (!ASActivateExperimentalFeature(ASExperimentalGraphicsContexts)) { - UIGraphicsBeginImageContextWithOptions(size, opaque, scale); - return; - } - - // We use "reference contexts" to get device-specific options that UIKit - // uses. - static dispatch_once_t onceToken; - static CGContextRef refCtxOpaque; - static CGContextRef refCtxTransparent; - dispatch_once(&onceToken, ^{ - UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), YES, 1); - refCtxOpaque = CGContextRetain(UIGraphicsGetCurrentContext()); - ASDisplayNodeCAssert(CGBitmapContextGetBytesPerRow(refCtxOpaque) == 32, @"Expected bytes per row to be aligned to 32. Has CGBitmapGetAlignedBytesPerRow implementation changed?"); - UIGraphicsEndImageContext(); - - // Make transparent ref context. - UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), NO, 1); - refCtxTransparent = CGContextRetain(UIGraphicsGetCurrentContext()); - UIGraphicsEndImageContext(); - }); - - // These options are taken from UIGraphicsBeginImageContext. - CGContextRef refCtx = opaque ? refCtxOpaque : refCtxTransparent; - CGBitmapInfo bitmapInfo = CGBitmapContextGetBitmapInfo(refCtx); - - if (scale == 0) { - scale = ASScreenScale(); + if (AS_AVAILABLE_IOS_TVOS(12, 12)) { + // nop. We always use automatic range on iOS >= 12. + } else { + // Currently we never do wide color. One day we could pipe this information through from the ASImageNode if it was worth it. + format.prefersExtendedRange = NO; } - size_t intWidth = (size_t)ceil(size.width * scale); - size_t intHeight = (size_t)ceil(size.height * scale); - size_t bitsPerComponent = CGBitmapContextGetBitsPerComponent(refCtx); - size_t bytesPerRow = CGBitmapContextGetBitsPerPixel(refCtx) * intWidth / 8; - bytesPerRow = ASGraphicsGetAlignedBytesPerRow(bytesPerRow); - size_t bufferSize = bytesPerRow * intHeight; - CGColorSpaceRef colorspace = CGBitmapContextGetColorSpace(refCtx); - - // We create our own buffer, and wrap the context around that. This way we can prevent - // the copy that usually gets made when you form a CGImage from the context. - ASCGImageBuffer *buffer = [[ASCGImageBuffer alloc] initWithLength:bufferSize]; - - CGContextRef context = CGBitmapContextCreate(buffer.mutableBytes, intWidth, intHeight, bitsPerComponent, bytesPerRow, colorspace, bitmapInfo); - - // Transfer ownership of the data to the context. So that if the context - // is destroyed before we create an image from it, the data will be released. - objc_setAssociatedObject((__bridge id)context, &__contextDataAssociationKey, buffer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - - // Set the CTM to account for iOS orientation & specified scale. - // If only we could use CGContextSetBaseCTM. It doesn't - // seem like there are any consequences for our use case - // but we'll be on the look out. The internet hinted that it - // affects shadowing but I tested and shadowing works. - CGContextTranslateCTM(context, 0, intHeight); - CGContextScaleCTM(context, scale, -scale); - - // Save the state so we can restore it and recover our scale in GetImageAndEnd - CGContextSaveGState(context); - - // Transfer context ownership to the UIKit stack. - UIGraphicsPushContext(context); - CGContextRelease(context); } -UIImage * _Nullable ASGraphicsGetImageAndEndCurrentContext() NS_RETURNS_RETAINED +UIImage *ASGraphicsCreateImageWithOptions(CGSize size, BOOL opaque, CGFloat scale, UIImage *sourceImage, + asdisplaynode_iscancelled_block_t NS_NOESCAPE isCancelled, + void (^NS_NOESCAPE work)()) { - if (!ASActivateExperimentalFeature(ASExperimentalGraphicsContexts)) { - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return image; + return ASGraphicsCreateImage(ASPrimitiveTraitCollectionMakeDefault(), size, opaque, scale, sourceImage, isCancelled, work); +} + +UIImage *ASGraphicsCreateImage(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * sourceImage, asdisplaynode_iscancelled_block_t NS_NOESCAPE isCancelled, void (NS_NOESCAPE ^work)()) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { + if (ASActivateExperimentalFeature(ASExperimentalDrawingGlobal)) { + // If they used default scale, reuse one of two preferred formats. + static UIGraphicsImageRendererFormat *defaultFormat; + static UIGraphicsImageRendererFormat *opaqueFormat; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { + defaultFormat = [UIGraphicsImageRendererFormat preferredFormat]; + opaqueFormat = [UIGraphicsImageRendererFormat preferredFormat]; + } else { + defaultFormat = [UIGraphicsImageRendererFormat defaultFormat]; + opaqueFormat = [UIGraphicsImageRendererFormat defaultFormat]; + } + opaqueFormat.opaque = YES; + ASConfigureExtendedRange(defaultFormat); + ASConfigureExtendedRange(opaqueFormat); + }); + + UIGraphicsImageRendererFormat *format; + if (sourceImage) { + if (sourceImage.renderingMode == UIImageRenderingModeAlwaysTemplate) { + // Template images will be black and transparent, so if we use + // sourceImage.imageRenderFormat it will assume a grayscale color space. + // This is not good because a template image should be able to tint to any color, + // so we'll just use the default here. + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { + format = [UIGraphicsImageRendererFormat preferredFormat]; + } else { + format = [UIGraphicsImageRendererFormat defaultFormat]; + } + } else { + format = sourceImage.imageRendererFormat; + } + // We only want the private bits (color space and bits per component) from the image. + // We have our own ideas about opacity and scale. + format.opaque = opaque; + format.scale = scale; + } else if (scale == 0 || scale == ASScreenScale()) { + format = opaque ? opaqueFormat : defaultFormat; + } else { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { + format = [UIGraphicsImageRendererFormat preferredFormat]; + } else { + format = [UIGraphicsImageRendererFormat defaultFormat]; + } + if (opaque) format.opaque = YES; + format.scale = scale; + ASConfigureExtendedRange(format); + } + + // Avoid using the imageWithActions: method because it does not support cancellation at the + // last moment i.e. before actually creating the resulting image. + __block UIImage *image; + NSError *error; + [[[UIGraphicsImageRenderer alloc] initWithSize:size format:format] + runDrawingActions:^(UIGraphicsImageRendererContext *rendererContext) { + ASDisplayNodeCAssert(UIGraphicsGetCurrentContext(), @"Should have a context!"); + ASPerformBlockWithTraitCollection(work, traitCollection); + } + completionActions:^(UIGraphicsImageRendererContext *rendererContext) { + if (isCancelled == nil || !isCancelled()) { + image = rendererContext.currentImage; + } + } + error:&error]; + if (error) { + NSCAssert(NO, @"Error drawing: %@", error); + } + return image; + } } - - // Pop the context and make sure we have one. - CGContextRef context = UIGraphicsGetCurrentContext(); - if (context == NULL) { - ASDisplayNodeCFailAssert(@"Can't end image context without having begun one."); - return nil; + + // Bad OS or experiment flag. Use UIGraphics* API. + UIGraphicsBeginImageContextWithOptions(size, opaque, scale); + ASPerformBlockWithTraitCollection(work, traitCollection) + UIImage *image = nil; + if (isCancelled == nil || !isCancelled()) { + image = UIGraphicsGetImageFromCurrentImageContext(); } - - // Read the device-specific ICC-based color space to use for the image. - // For DeviceRGB contexts (e.g. UIGraphics), CGBitmapContextCreateImage - // generates an image in a device-specific color space (for wide color support). - // We replicate that behavior, even though at this time CA does not - // require the image to be in this space. Plain DeviceRGB images seem - // to be treated exactly the same, but better safe than sorry. - static CGColorSpaceRef imageColorSpace; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), YES, 0); - UIImage *refImage = UIGraphicsGetImageFromCurrentImageContext(); - imageColorSpace = CGColorSpaceRetain(CGImageGetColorSpace(refImage.CGImage)); - ASDisplayNodeCAssertNotNil(imageColorSpace, nil); - UIGraphicsEndImageContext(); - }); - - // Retrieve our buffer and create a CGDataProvider from it. - ASCGImageBuffer *buffer = objc_getAssociatedObject((__bridge id)context, &__contextDataAssociationKey); - ASDisplayNodeCAssertNotNil(buffer, nil); - CGDataProviderRef provider = [buffer createDataProviderAndInvalidate]; - - // Create the CGImage. Options taken from CGBitmapContextCreateImage. - CGImageRef cgImg = CGImageCreate(CGBitmapContextGetWidth(context), CGBitmapContextGetHeight(context), CGBitmapContextGetBitsPerComponent(context), CGBitmapContextGetBitsPerPixel(context), CGBitmapContextGetBytesPerRow(context), imageColorSpace, CGBitmapContextGetBitmapInfo(context), provider, NULL, true, kCGRenderingIntentDefault); - CGDataProviderRelease(provider); - - // We saved our GState right after setting the CTM so that we could restore it - // here and get the original scale back. - CGContextRestoreGState(context); - CGFloat scale = CGContextGetCTM(context).a; - - // Note: popping from the UIKit stack will probably destroy the context. - context = NULL; - UIGraphicsPopContext(); - - UIImage *result = [[UIImage alloc] initWithCGImage:cgImg scale:scale orientation:UIImageOrientationUp]; - CGImageRelease(cgImg); - return result; + UIGraphicsEndImageContext(); + return image; } -void ASGraphicsEndImageContext() -{ - if (!ASActivateExperimentalFeature(ASExperimentalGraphicsContexts)) { - UIGraphicsEndImageContext(); - return; - } - - UIGraphicsPopContext(); +UIImage *ASGraphicsCreateImageWithTraitCollectionAndOptions(ASPrimitiveTraitCollection traitCollection, CGSize size, BOOL opaque, CGFloat scale, UIImage * sourceImage, void (NS_NOESCAPE ^work)()) { + return ASGraphicsCreateImage(traitCollection, size, opaque, scale, sourceImage, nil, work); } diff --git a/Example/Pods/Texture/Source/Details/ASHashing.h b/Example/Pods/Texture/Source/Details/ASHashing.h index 084d740..42a4a98 100644 --- a/Example/Pods/Texture/Source/Details/ASHashing.h +++ b/Example/Pods/Texture/Source/Details/ASHashing.h @@ -35,6 +35,6 @@ NS_ASSUME_NONNULL_BEGIN * use `pragma clang diagnostic warning "-Wpadded"` around your struct definition * or manually initialize the fields of your struct (`myStruct.x = 7;` etc). */ -AS_EXTERN NSUInteger ASHashBytes(void *bytes, size_t length); +ASDK_EXTERN NSUInteger ASHashBytes(void *bytes, size_t length); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Details/ASImageProtocols.h b/Example/Pods/Texture/Source/Details/ASImageProtocols.h index 10ad85d..d91b8a7 100644 --- a/Example/Pods/Texture/Source/Details/ASImageProtocols.h +++ b/Example/Pods/Texture/Source/Details/ASImageProtocols.h @@ -20,7 +20,12 @@ NS_ASSUME_NONNULL_BEGIN @end -typedef void(^ASImageCacherCompletion)(id _Nullable imageFromCache); +typedef NS_ENUM(NSInteger, ASImageCacheType) { + ASImageCacheTypeAsynchronous = 0, + ASImageCacheTypeSynchronous, +}; + +typedef void(^ASImageCacherCompletion)(id _Nullable imageFromCache, ASImageCacheType cacheType); @protocol ASImageCacheProtocol @@ -102,17 +107,35 @@ typedef NS_ENUM(NSUInteger, ASImageDownloaderPriority) { /** @abstract Cancels an image download. @param downloadIdentifier The opaque download identifier object returned from - `downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:`. + `downloadImageWithURL:callbackQueue:downloadProgress:completion:`. @discussion This method has no effect if `downloadIdentifier` is nil. */ - (void)cancelImageDownloadForIdentifier:(id)downloadIdentifier; @optional +/** + @abstract Downloads an image with the given URL. + @param URL The URL of the image to download. + @param priority The priority at which the image should be downloaded. + @param callbackQueue The queue to call `downloadProgressBlock` and `completion` on. + @param downloadProgress The block to be invoked when the download of `URL` progresses. + @param completion The block to be invoked when the download has completed, or has failed. + @discussion This method is likely to be called on the main thread, so any custom implementations should make sure to background any expensive download operations. + @note If this method is implemented, it will be called instead of the required method (`downloadImageWithURL:callbackQueue:downloadProgress:completion:`). + @result An opaque identifier to be used in canceling the download, via `cancelImageDownloadForIdentifier:`. You must + retain the identifier if you wish to use it later. + */ +- (nullable id)downloadImageWithURL:(NSURL *)URL + priority:(ASImageDownloaderPriority)priority + callbackQueue:(dispatch_queue_t)callbackQueue + downloadProgress:(nullable ASImageDownloaderProgress)downloadProgress + completion:(ASImageDownloaderCompletion)completion; + /** @abstract Cancels an image download, however indicating resume data should be stored in case of redownload. @param downloadIdentifier The opaque download identifier object returned from - `downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:`. + `downloadImageWithURL:callbackQueue:downloadProgress:completion:`. @discussion This method has no effect if `downloadIdentifier` is nil. If implemented, this method may be called instead of `cancelImageDownloadForIdentifier:` in cases where ASDK believes there's a chance the image download will be resumed (currently when an image exits preload range). You can use this to store @@ -130,7 +153,7 @@ typedef NS_ENUM(NSUInteger, ASImageDownloaderPriority) { /** @abstract Sets block to be called when a progress image is available. @param progressBlock The block to be invoked when the download has a progressive render of an image available. - @param callbackQueue The queue to call `progressBlock` on. + @param callbackQueue The queue to call `progressImageBlock` on. @param downloadIdentifier The opaque download identifier object returned from `downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:`. */ diff --git a/Example/Pods/Texture/Source/Details/ASIntegerMap.mm b/Example/Pods/Texture/Source/Details/ASIntegerMap.mm index b07a7a1..fdf0d52 100644 --- a/Example/Pods/Texture/Source/Details/ASIntegerMap.mm +++ b/Example/Pods/Texture/Source/Details/ASIntegerMap.mm @@ -9,7 +9,6 @@ #import "ASIntegerMap.h" #import #import -#import #import /** diff --git a/Example/Pods/Texture/Source/Details/ASLayoutRangeType.h b/Example/Pods/Texture/Source/Details/ASLayoutRangeType.h index d4af470..1a60e29 100644 --- a/Example/Pods/Texture/Source/Details/ASLayoutRangeType.h +++ b/Example/Pods/Texture/Source/Details/ASLayoutRangeType.h @@ -15,16 +15,16 @@ typedef struct { CGFloat trailingBufferScreenfuls; } ASRangeTuningParameters; -AS_EXTERN ASRangeTuningParameters const ASRangeTuningParametersZero; +ASDK_EXTERN ASRangeTuningParameters const ASRangeTuningParametersZero; -AS_EXTERN BOOL ASRangeTuningParametersEqualToRangeTuningParameters(ASRangeTuningParameters lhs, ASRangeTuningParameters rhs); +ASDK_EXTERN BOOL ASRangeTuningParametersEqualToRangeTuningParameters(ASRangeTuningParameters lhs, ASRangeTuningParameters rhs); /** * Each mode has a complete set of tuning parameters for range types. * Depending on some conditions (including interface state and direction of the scroll view, state of rendering engine, etc), * a range controller can choose which mode it should use at a given time. */ -typedef NS_ENUM(NSInteger, ASLayoutRangeMode) { +typedef NS_ENUM(char, ASLayoutRangeMode) { ASLayoutRangeModeUnspecified = -1, /** diff --git a/Example/Pods/Texture/Source/Details/ASMainSerialQueue.mm b/Example/Pods/Texture/Source/Details/ASMainSerialQueue.mm index 3a5fa00..ba2c743 100644 --- a/Example/Pods/Texture/Source/Details/ASMainSerialQueue.mm +++ b/Example/Pods/Texture/Source/Details/ASMainSerialQueue.mm @@ -11,57 +11,44 @@ #import #import +#import @interface ASMainSerialQueue () { - ASDN::Mutex _serialQueueLock; - NSMutableArray *_blocks; + AS::Mutex _serialQueueLock; + std::queue _blocks; } @end @implementation ASMainSerialQueue -- (instancetype)init -{ - if (!(self = [super init])) { - return nil; - } - - _blocks = [[NSMutableArray alloc] init]; - return self; -} - - (NSUInteger)numberOfScheduledBlocks { - ASDN::MutexLocker l(_serialQueueLock); - return _blocks.count; + AS::MutexLocker l(_serialQueueLock); + return _blocks.size(); } - (void)performBlockOnMainThread:(dispatch_block_t)block { - - ASDN::UniqueLock l(_serialQueueLock); - [_blocks addObject:block]; { - l.unlock(); - [self runBlocks]; - l.lock(); + AS::MutexLocker l(_serialQueueLock); + _blocks.push(block); } + + [self runBlocks]; } - (void)runBlocks { dispatch_block_t mainThread = ^{ - ASDN::UniqueLock l(self->_serialQueueLock); + AS::UniqueLock l(self->_serialQueueLock); do { - dispatch_block_t block; - if (self->_blocks.count > 0) { - block = _blocks[0]; - [self->_blocks removeObjectAtIndex:0]; - } else { + if (self->_blocks.empty()) { break; } + dispatch_block_t block = self->_blocks.front(); + self->_blocks.pop(); { l.unlock(); block(); @@ -75,7 +62,15 @@ - (void)runBlocks - (NSString *)description { - return [[super description] stringByAppendingFormat:@" Blocks: %@", _blocks]; + NSString *desc = [super description]; + std::queue blocks = _blocks; + [desc stringByAppendingString:@" Blocks: "]; + while (!blocks.empty()) { + dispatch_block_t block = blocks.front(); + [desc stringByAppendingFormat:@"%@", block]; + blocks.pop(); + } + return desc; } @end diff --git a/Example/Pods/Texture/Source/Details/ASObjectDescriptionHelpers.h b/Example/Pods/Texture/Source/Details/ASObjectDescriptionHelpers.h index 5a2823b..beaf889 100644 --- a/Example/Pods/Texture/Source/Details/ASObjectDescriptionHelpers.h +++ b/Example/Pods/Texture/Source/Details/ASObjectDescriptionHelpers.h @@ -44,13 +44,13 @@ NS_ASSUME_NONNULL_BEGIN - (NSMutableArray *)propertiesForDescription; @end -AS_EXTERN NSString *ASGetDescriptionValueString(id object); +ASDK_EXTERN NSString *ASGetDescriptionValueString(id object); /// Useful for structs etc. Returns e.g. { position = (0 0); frame = (0 0; 50 50) } -AS_EXTERN NSString *ASObjectDescriptionMakeWithoutObject(NSArray * _Nullable propertyGroups); +ASDK_EXTERN NSString *ASObjectDescriptionMakeWithoutObject(NSArray * _Nullable propertyGroups); /// Returns e.g. -AS_EXTERN NSString *ASObjectDescriptionMake(__autoreleasing id object, NSArray * _Nullable propertyGroups); +ASDK_EXTERN NSString *ASObjectDescriptionMake(__autoreleasing id object, NSArray * _Nullable propertyGroups); /** * Returns e.g. @@ -58,8 +58,8 @@ AS_EXTERN NSString *ASObjectDescriptionMake(__autoreleasing id object, NSArray", object_getClassName(object), object); + return (__bridge_transfer NSString *)CFStringCreateWithBytes(NULL, (const UInt8 *)buf, len, kCFStringEncodingASCII, false); } NSString *ASStringWithQuotesIfMultiword(NSString *string) { diff --git a/Example/Pods/Texture/Source/Details/ASPINRemoteImageDownloader.mm b/Example/Pods/Texture/Source/Details/ASPINRemoteImageDownloader.mm index 35b1c91..df538f0 100644 --- a/Example/Pods/Texture/Source/Details/ASPINRemoteImageDownloader.mm +++ b/Example/Pods/Texture/Source/Details/ASPINRemoteImageDownloader.mm @@ -34,6 +34,19 @@ #import #import +static inline PINRemoteImageManagerPriority PINRemoteImageManagerPriorityWithASImageDownloaderPriority(ASImageDownloaderPriority priority) { + switch (priority) { + case ASImageDownloaderPriorityPreload: + return PINRemoteImageManagerPriorityLow; + + case ASImageDownloaderPriorityImminent: + return PINRemoteImageManagerPriorityDefault; + + case ASImageDownloaderPriorityVisible: + return PINRemoteImageManagerPriorityHigh; + } +} + #if PIN_ANIMATED_AVAILABLE @interface ASPINRemoteImageDownloader () @@ -218,14 +231,15 @@ - (void)cachedImageWithURL:(NSURL *)URL { [[self sharedPINRemoteImageManager] imageFromCacheWithURL:URL processorKey:nil options:PINRemoteImageManagerDownloadOptionsSkipDecode completion:^(PINRemoteImageManagerResult * _Nonnull result) { [ASPINRemoteImageDownloader _performWithCallbackQueue:callbackQueue work:^{ + ASImageCacheType cacheType = (result.resultType == PINRemoteImageResultTypeMemoryCache ? ASImageCacheTypeSynchronous : ASImageCacheTypeAsynchronous); #if PIN_ANIMATED_AVAILABLE if (result.alternativeRepresentation) { - completion(result.alternativeRepresentation); + completion(result.alternativeRepresentation, cacheType); } else { - completion(result.image); + completion(result.image, cacheType); } #else - completion(result.image); + completion(result.image, cacheType); #endif }]; }]; @@ -245,6 +259,21 @@ - (nullable id)downloadImageWithURL:(NSURL *)URL downloadProgress:(ASImageDownloaderProgress)downloadProgress completion:(ASImageDownloaderCompletion)completion; { + return [self downloadImageWithURL:URL + priority:ASImageDownloaderPriorityImminent // maps to default priority + callbackQueue:callbackQueue + downloadProgress:downloadProgress + completion:completion]; +} + +- (nullable id)downloadImageWithURL:(NSURL *)URL + priority:(ASImageDownloaderPriority)priority + callbackQueue:(dispatch_queue_t)callbackQueue + downloadProgress:(ASImageDownloaderProgress)downloadProgress + completion:(ASImageDownloaderCompletion)completion +{ + PINRemoteImageManagerPriority pi_priority = PINRemoteImageManagerPriorityWithASImageDownloaderPriority(priority); + PINRemoteImageManagerProgressDownload progressDownload = ^(int64_t completedBytes, int64_t totalBytes) { if (downloadProgress == nil) { return; } @@ -274,6 +303,7 @@ - (nullable id)downloadImageWithURL:(NSURL *)URL // check the cache as part of this download. return [[self sharedPINRemoteImageManager] downloadImageWithURL:URL options:PINRemoteImageManagerDownloadOptionsSkipDecode | PINRemoteImageManagerDownloadOptionsIgnoreCache + priority:pi_priority progressImage:nil progressDownload:progressDownload completion:imageCompletion]; @@ -310,20 +340,7 @@ - (void)setPriority:(ASImageDownloaderPriority)priority withDownloadIdentifier:( { ASDisplayNodeAssert([downloadIdentifier isKindOfClass:[NSUUID class]], @"downloadIdentifier must be NSUUID"); - PINRemoteImageManagerPriority pi_priority = PINRemoteImageManagerPriorityDefault; - switch (priority) { - case ASImageDownloaderPriorityPreload: - pi_priority = PINRemoteImageManagerPriorityLow; - break; - - case ASImageDownloaderPriorityImminent: - pi_priority = PINRemoteImageManagerPriorityDefault; - break; - - case ASImageDownloaderPriorityVisible: - pi_priority = PINRemoteImageManagerPriorityHigh; - break; - } + PINRemoteImageManagerPriority pi_priority = PINRemoteImageManagerPriorityWithASImageDownloaderPriority(priority); [[self sharedPINRemoteImageManager] setPriority:pi_priority ofTaskWithUUID:downloadIdentifier]; } @@ -332,7 +349,7 @@ - (void)setPriority:(ASImageDownloaderPriority)priority withDownloadIdentifier:( - (id)alternateRepresentationWithData:(NSData *)data options:(PINRemoteImageManagerDownloadOptions)options { #if PIN_ANIMATED_AVAILABLE - if ([data pin_isGIF]) { + if ([data pin_isAnimatedGIF]) { return data; } #if PIN_WEBP_AVAILABLE diff --git a/Example/Pods/Texture/Source/Details/ASPageTable.h b/Example/Pods/Texture/Source/Details/ASPageTable.h index 9b1921b..e9cd11a 100644 --- a/Example/Pods/Texture/Source/Details/ASPageTable.h +++ b/Example/Pods/Texture/Source/Details/ASPageTable.h @@ -23,7 +23,7 @@ typedef uintptr_t ASPageCoordinate; /** * Returns a page coordinate with the given x and y values. Both of them must be less than 65,535. */ -AS_EXTERN ASPageCoordinate ASPageCoordinateMake(uint16_t x, uint16_t y) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASPageCoordinate ASPageCoordinateMake(uint16_t x, uint16_t y) AS_WARN_UNUSED_RESULT; /** * Returns coordinate of the page that contains the specified point. @@ -33,13 +33,13 @@ AS_EXTERN ASPageCoordinate ASPageCoordinateMake(uint16_t x, uint16_t y) AS_WARN_ * * @param pageSize The size of each page. */ -AS_EXTERN ASPageCoordinate ASPageCoordinateForPageThatContainsPoint(CGPoint point, CGSize pageSize) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASPageCoordinate ASPageCoordinateForPageThatContainsPoint(CGPoint point, CGSize pageSize) AS_WARN_UNUSED_RESULT; -AS_EXTERN uint16_t ASPageCoordinateGetX(ASPageCoordinate pageCoordinate) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN uint16_t ASPageCoordinateGetX(ASPageCoordinate pageCoordinate) AS_WARN_UNUSED_RESULT; -AS_EXTERN uint16_t ASPageCoordinateGetY(ASPageCoordinate pageCoordinate) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN uint16_t ASPageCoordinateGetY(ASPageCoordinate pageCoordinate) AS_WARN_UNUSED_RESULT; -AS_EXTERN CGRect ASPageCoordinateGetPageRect(ASPageCoordinate pageCoordinate, CGSize pageSize) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN CGRect ASPageCoordinateGetPageRect(ASPageCoordinate pageCoordinate, CGSize pageSize) AS_WARN_UNUSED_RESULT; /** * Returns coordinate pointers for pages that intersect the specified rect. For each pointer, use ASPageCoordinateFromPointer() to get the original coordinate. @@ -51,7 +51,7 @@ AS_EXTERN CGRect ASPageCoordinateGetPageRect(ASPageCoordinate pageCoordinate, CG * * @param pageSize The size of each page. */ -AS_EXTERN NSPointerArray * _Nullable ASPageCoordinatesForPagesThatIntersectRect(CGRect rect, CGSize contentSize, CGSize pageSize) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSPointerArray * _Nullable ASPageCoordinatesForPagesThatIntersectRect(CGRect rect, CGSize contentSize, CGSize pageSize) AS_WARN_UNUSED_RESULT; /** * An alias for an NSMapTable created to store objects using ASPageCoordinates as keys. diff --git a/Example/Pods/Texture/Source/Details/ASPageTable.mm b/Example/Pods/Texture/Source/Details/ASPageTable.mm index 13baa95..fde8108 100644 --- a/Example/Pods/Texture/Source/Details/ASPageTable.mm +++ b/Example/Pods/Texture/Source/Details/ASPageTable.mm @@ -128,19 +128,19 @@ + (ASPageToLayoutAttributesTable *)pageTableWithLayoutAttributes:(id - NSString *const ASPhotosURLScheme = @"ph"; static NSString *const _ASPhotosURLQueryKeyWidth = @"width"; diff --git a/Example/Pods/Texture/Source/Details/ASRangeController.mm b/Example/Pods/Texture/Source/Details/ASRangeController.mm index d2ab45a..1dcd062 100644 --- a/Example/Pods/Texture/Source/Details/ASRangeController.mm +++ b/Example/Pods/Texture/Source/Details/ASRangeController.mm @@ -11,18 +11,16 @@ #import #import -#import #import +#import #import #import // Required for interfaceState and hierarchyState setter methods. #import -#import #import -#import -#import -#import +#import #import +#import #define AS_RANGECONTROLLER_LOG_UPDATE_FREQ 0 @@ -224,7 +222,7 @@ - (void)_updateVisibleNodeIndexPaths auto visibleElements = [_dataSource visibleElementsForRangeController:self]; NSHashTable *newVisibleNodes = [NSHashTable hashTableWithOptions:NSHashTableObjectPointerPersonality]; - ASSignpostStart(ASSignpostRangeControllerUpdate); + ASSignpostStart(RangeControllerUpdate, _dataSource, "%@", ASObjectDescriptionMakeTiny(_dataSource)); // Get the scroll direction. Default to using the previous one, if they're not scrolling. ASScrollDirection scrollDirection = [_dataSource scrollDirectionForRangeController:self]; @@ -242,6 +240,7 @@ - (void)_updateVisibleNodeIndexPaths [newVisibleNodes addObject:element.node]; } [self _setVisibleNodes:newVisibleNodes]; + ASSignpostEnd(RangeControllerUpdate, _dataSource, ""); return; // don't do anything for this update, but leave _rangeIsValid == NO to make sure we update it later } @@ -280,7 +279,7 @@ - (void)_updateVisibleNodeIndexPaths } else { if (emptyDisplayRange == YES) { displayElements = [NSHashTable hashTableWithOptions:NSHashTableObjectPointerPersonality]; - } if (equalDisplayVisible == YES) { + } else if (equalDisplayVisible == YES) { displayElements = visibleElements; } else { // Calculating only the Display range means the Preload range is either the same as Display or Visible. @@ -349,23 +348,20 @@ - (void)_updateVisibleNodeIndexPaths } } } else { - // If selfInterfaceState isn't visible, then visibleIndexPaths represents what /will/ be immediately visible at the - // instant we come onscreen. So, preload and display all of those things, but don't waste resources preloading yet. - // We handle this as a separate case to minimize set operations for offscreen preloading, including containsObject:. - - if ([allCurrentIndexPaths containsObject:indexPath]) { - // DO NOT set Visible: even though these elements are in the visible range / "viewport", - // our overall container object is itself not visible yet. The moment it becomes visible, we will run the condition above - - // Set Layout, Preload + // If selfInterfaceState isn't visible, then visibleIndexPaths represents either what /will/ be immediately visible at the + // instant we come onscreen, or what /will/ no longer be visible at the instant we come offscreen. + // So, preload and display all of those things, but don't waste resources displaying others. + // + // DO NOT set Visible: even though these elements are in the visible range / "viewport", + // our overall container object is itself not yet, or no longer, visible. + // The moment it becomes visible, we will run the condition above. + if ([visibleIndexPaths containsObject:indexPath]) { interfaceState |= ASInterfaceStatePreload; - if (rangeMode != ASLayoutRangeModeLowMemory) { - // Add Display. - // We might be looking at an indexPath that was previously in-range, but now we need to clear it. - // In that case we'll just set it back to MeasureLayout. Only set Display | Preload if in allCurrentIndexPaths. interfaceState |= ASInterfaceStateDisplay; } + } else if ([displayIndexPaths containsObject:indexPath]) { + interfaceState |= ASInterfaceStatePreload; } } @@ -400,10 +396,7 @@ - (void)_updateVisibleNodeIndexPaths if (ASDisplayNode.shouldShowRangeDebugOverlay) { ASScrollDirection scrollableDirections = ASScrollDirectionUp | ASScrollDirectionDown; if ([_dataSource isKindOfClass:NSClassFromString(@"ASCollectionView")]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundeclared-selector" - scrollableDirections = (ASScrollDirection)[_dataSource performSelector:@selector(scrollableDirections)]; -#pragma clang diagnostic pop + scrollableDirections = ((ASCollectionView *)_dataSource).scrollableDirections; } [self updateRangeController:self @@ -429,7 +422,7 @@ - (void)_updateVisibleNodeIndexPaths NSLog(@"Range update complete; modifiedIndexPaths: %@, rangeMode: %d", [self descriptionWithIndexPaths:modifiedIndexPaths], rangeMode); #endif - ASSignpostEnd(ASSignpostRangeControllerUpdate); + ASSignpostEnd(RangeControllerUpdate, _dataSource, ""); } #pragma mark - Notification observers diff --git a/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.h b/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.h index d705e4d..bf99f7e 100644 --- a/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.h +++ b/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.h @@ -20,20 +20,20 @@ NS_ASSUME_NONNULL_BEGIN OS_UNFAIR_LOCK_AVAILABILITY typedef struct { os_unfair_lock _lock OS_UNFAIR_LOCK_AVAILABILITY; - _Atomic(pthread_t) _thread; // Write-protected by lock + _Atomic(pthread_t) _thread; int _count; // Protected by lock } ASRecursiveUnfairLock; /** * Lock, blocking if needed. */ -AS_EXTERN OS_UNFAIR_LOCK_AVAILABILITY +ASDK_EXTERN OS_UNFAIR_LOCK_AVAILABILITY void ASRecursiveUnfairLockLock(ASRecursiveUnfairLock *l); /** * Try to lock without blocking. Returns whether we took the lock. */ -AS_EXTERN OS_UNFAIR_LOCK_AVAILABILITY +ASDK_EXTERN OS_UNFAIR_LOCK_AVAILABILITY BOOL ASRecursiveUnfairLockTryLock(ASRecursiveUnfairLock *l); /** @@ -41,7 +41,7 @@ BOOL ASRecursiveUnfairLockTryLock(ASRecursiveUnfairLock *l); * the lock will result in an assertion failure, and undefined * behavior if foundation assertions are disabled. */ -AS_EXTERN OS_UNFAIR_LOCK_AVAILABILITY +ASDK_EXTERN OS_UNFAIR_LOCK_AVAILABILITY void ASRecursiveUnfairLockUnlock(ASRecursiveUnfairLock *l); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.mm b/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.mm index 9e4a29d..d6eb188 100644 --- a/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.mm +++ b/Example/Pods/Texture/Source/Details/ASRecursiveUnfairLock.mm @@ -11,57 +11,61 @@ #import /** - * For our atomic _thread, we use acquire/release memory order so that we can have - * the minimum possible constraint on the hardware. The default, `memory_order_seq_cst` - * demands that there be a total order of all such modifications as seen by all threads. - * Acquire/release only requires that modifications to this specific atomic are - * synchronized across acquire/release pairs. - * http://en.cppreference.com/w/cpp/atomic/memory_order - * - * Note also that the unfair_lock involves a thread fence as well, so we don't need to - * take care of synchronizing other values. Just the thread value. + * Since the lock itself is a memory barrier, we only need memory_order_relaxed for our + * thread atomic. That guarantees we won't have torn writes, but otherwise no ordering + * is required. */ -#define rul_set_thread(l, t) atomic_store_explicit(&l->_thread, t, memory_order_release) -#define rul_get_thread(l) atomic_load_explicit(&l->_thread, memory_order_acquire) +#define rul_set_thread(l, t) atomic_store_explicit(&l->_thread, t, memory_order_relaxed) +#define rul_get_thread(l) atomic_load_explicit(&l->_thread, memory_order_relaxed) + +OS_UNFAIR_LOCK_AVAILABILITY +NS_INLINE void ASRecursiveUnfairLockDidAcquire(ASRecursiveUnfairLock *l, pthread_t tid) { + NSCAssert(pthread_equal(rul_get_thread(l), NULL) && l->_count == 0, @"Unfair lock error"); + rul_set_thread(l, tid); +} + +OS_UNFAIR_LOCK_AVAILABILITY +NS_INLINE void ASRecursiveUnfairLockWillRelease(ASRecursiveUnfairLock *l) { + NSCAssert(pthread_equal(rul_get_thread(l), pthread_self()) && l->_count == 0, @"Unfair lock error"); + rul_set_thread(l, NULL); +} + +OS_UNFAIR_LOCK_AVAILABILITY +NS_INLINE void ASRecursiveUnfairLockAssertHeld(ASRecursiveUnfairLock *l) { + NSCAssert(pthread_equal(rul_get_thread(l), pthread_self()) && l->_count > 0, @"Unfair lock error"); +} void ASRecursiveUnfairLockLock(ASRecursiveUnfairLock *l) { // Try to lock without blocking. If we fail, check what thread owns it. - // Note that the owning thread CAN CHANGE freely, but it can't become `self` - // because only we are `self`. And if it's already `self` then we already have - // the lock, because we reset it to NULL before we unlock. So (thread == self) is - // invariant. - + // Note that the owning thread CAN CHANGE freely, but if the thread is specifically `self` then we know + // it is a recursive call, because we clear it before unlocking, and only `self` can set it + // to `self`. + const pthread_t s = pthread_self(); - if (os_unfair_lock_trylock(&l->_lock)) { - // Owned by nobody. We now have the lock. Assign self. - rul_set_thread(l, s); - } else if (rul_get_thread(l) == s) { - // Owned by self (recursive lock). nop. + if (pthread_equal(rul_get_thread(l), s)) { + // Owned by self (recursive lock.) nop. + ASRecursiveUnfairLockAssertHeld(l); } else { - // Owned by other thread. Block and then set thread to self. os_unfair_lock_lock(&l->_lock); - rul_set_thread(l, s); + ASRecursiveUnfairLockDidAcquire(l, s); } - + l->_count++; } -BOOL ASRecursiveUnfairLockTryLock(ASRecursiveUnfairLock *l) -{ +BOOL ASRecursiveUnfairLockTryLock(ASRecursiveUnfairLock *l) { // Same as Lock above. See comments there. - const pthread_t s = pthread_self(); - if (os_unfair_lock_trylock(&l->_lock)) { - // Owned by nobody. We now have the lock. Assign self. - rul_set_thread(l, s); - } else if (rul_get_thread(l) == s) { - // Owned by self (recursive lock). nop. + if (pthread_equal(rul_get_thread(l), s)) { + ASRecursiveUnfairLockAssertHeld(l); + } else if (os_unfair_lock_trylock(&l->_lock)) { + ASRecursiveUnfairLockDidAcquire(l, s); } else { // Owned by other thread. Fail. return NO; } - + l->_count++; return YES; } @@ -70,14 +74,14 @@ void ASRecursiveUnfairLockUnlock(ASRecursiveUnfairLock *l) { // Ensure we have the lock. This check may miss some pathological cases, // but it'll catch 99.999999% of this serious programmer error. - NSCAssert(rul_get_thread(l) == pthread_self(), @"Unlocking from a different thread than locked."); + NSCAssert(pthread_equal(rul_get_thread(l), pthread_self()), @"Unlocking from a different thread than locked."); if (0 == --l->_count) { // Note that we have to clear this before unlocking because, if another thread // succeeds in locking above, but hasn't managed to update _thread, and we // try to re-lock, and fail the -tryLock, and read _thread, then we'll mistakenly // think that we still own the lock and proceed without blocking. - rul_set_thread(l, NULL); + ASRecursiveUnfairLockWillRelease(l); os_unfair_lock_unlock(&l->_lock); } } diff --git a/Example/Pods/Texture/Source/Details/ASScrollDirection.h b/Example/Pods/Texture/Source/Details/ASScrollDirection.h index 41538ed..14317ba 100644 --- a/Example/Pods/Texture/Source/Details/ASScrollDirection.h +++ b/Example/Pods/Texture/Source/Details/ASScrollDirection.h @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN -typedef NS_OPTIONS(NSInteger, ASScrollDirection) { +typedef NS_OPTIONS(unsigned char, ASScrollDirection) { ASScrollDirectionNone = 0, ASScrollDirectionRight = 1 << 0, ASScrollDirectionLeft = 1 << 1, @@ -22,16 +22,16 @@ typedef NS_OPTIONS(NSInteger, ASScrollDirection) { ASScrollDirectionDown = 1 << 3 }; -AS_EXTERN const ASScrollDirection ASScrollDirectionHorizontalDirections; -AS_EXTERN const ASScrollDirection ASScrollDirectionVerticalDirections; +ASDK_EXTERN const ASScrollDirection ASScrollDirectionHorizontalDirections; +ASDK_EXTERN const ASScrollDirection ASScrollDirectionVerticalDirections; -AS_EXTERN BOOL ASScrollDirectionContainsVerticalDirection(ASScrollDirection scrollDirection); -AS_EXTERN BOOL ASScrollDirectionContainsHorizontalDirection(ASScrollDirection scrollDirection); +ASDK_EXTERN BOOL ASScrollDirectionContainsVerticalDirection(ASScrollDirection scrollDirection); +ASDK_EXTERN BOOL ASScrollDirectionContainsHorizontalDirection(ASScrollDirection scrollDirection); -AS_EXTERN BOOL ASScrollDirectionContainsRight(ASScrollDirection scrollDirection); -AS_EXTERN BOOL ASScrollDirectionContainsLeft(ASScrollDirection scrollDirection); -AS_EXTERN BOOL ASScrollDirectionContainsUp(ASScrollDirection scrollDirection); -AS_EXTERN BOOL ASScrollDirectionContainsDown(ASScrollDirection scrollDirection); -AS_EXTERN ASScrollDirection ASScrollDirectionApplyTransform(ASScrollDirection scrollDirection, CGAffineTransform transform); +ASDK_EXTERN BOOL ASScrollDirectionContainsRight(ASScrollDirection scrollDirection); +ASDK_EXTERN BOOL ASScrollDirectionContainsLeft(ASScrollDirection scrollDirection); +ASDK_EXTERN BOOL ASScrollDirectionContainsUp(ASScrollDirection scrollDirection); +ASDK_EXTERN BOOL ASScrollDirectionContainsDown(ASScrollDirection scrollDirection); +ASDK_EXTERN ASScrollDirection ASScrollDirectionApplyTransform(ASScrollDirection scrollDirection, CGAffineTransform transform); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Details/ASThread.h b/Example/Pods/Texture/Source/Details/ASThread.h index 7b54b2a..0ef3d32 100644 --- a/Example/Pods/Texture/Source/Details/ASThread.h +++ b/Example/Pods/Texture/Source/Details/ASThread.h @@ -16,6 +16,8 @@ #import #import #import +#import +#import #import ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASDisplayNodeThreadIsMain() @@ -38,14 +40,14 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASDisplayNodeThreadIsMain() /// Same as ASLockScope(1) but lock isn't retained (be careful). #define ASLockScopeUnowned(nsLocking) \ - __unsafe_unretained id __lockToken __attribute__((cleanup(_ASLockScopeUnownedCleanup))) = nsLocking; \ + unowned id __lockToken __attribute__((cleanup(_ASLockScopeUnownedCleanup))) = nsLocking; \ [__lockToken lock]; ASDISPLAYNODE_INLINE void _ASLockScopeCleanup(id __strong * const lockPtr) { [*lockPtr unlock]; } -ASDISPLAYNODE_INLINE void _ASLockScopeUnownedCleanup(id __unsafe_unretained * const lockPtr) { +ASDISPLAYNODE_INLINE void _ASLockScopeUnownedCleanup(id unowned * const lockPtr) { [*lockPtr unlock]; } @@ -101,7 +103,7 @@ ASDISPLAYNODE_INLINE void _ASUnlockScopeCleanup(id __strong *lockPtr) #define DISABLED_ASAssertLocked(m) #define DISABLED_ASAssertUnlocked(m) -namespace ASDN { +namespace AS { // Set once in Mutex constructor. Linker fails if this is a member variable. ?? static bool gMutex_unfair; @@ -117,6 +119,12 @@ namespace ASDN { /// Constructs a plain mutex (the default). Mutex () : Mutex (false) {} + void SetDebugNameWithObject(id object) { +#if ASEnableVerboseLogging && ASDISPLAYNODE_ASSERTIONS_ENABLED + _debug_name = std::string(ASObjectDescriptionMakeTiny(object).UTF8String); +#endif + } + ~Mutex () { // Manually destroy since unions can't do it. switch (_type) { @@ -151,7 +159,11 @@ namespace ASDN { success = os_unfair_lock_trylock(&_unfair); break; case RecursiveUnfair: - success = ASRecursiveUnfairLockTryLock(&_runfair); + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + success = ASRecursiveUnfairLockTryLock(&_runfair); + } else { + success = _recursive.try_lock(); + } break; } if (success) { @@ -172,7 +184,11 @@ namespace ASDN { os_unfair_lock_lock(&_unfair); break; case RecursiveUnfair: - ASRecursiveUnfairLockLock(&_runfair); + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + ASRecursiveUnfairLockLock(&_runfair); + } else { + _recursive.lock(); + } break; } DidLock(); @@ -191,7 +207,11 @@ namespace ASDN { os_unfair_lock_unlock(&_unfair); break; case RecursiveUnfair: - ASRecursiveUnfairLockUnlock(&_runfair); + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + ASRecursiveUnfairLockUnlock(&_runfair); + } else { + _recursive.unlock(); + } break; } } @@ -210,14 +230,18 @@ namespace ASDN { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (AS_AVAILABLE_IOS_TVOS(10, 10)) { - gMutex_unfair = ASActivateExperimentalFeature(ASExperimentalUnfairLock); + gMutex_unfair = YES; } }); if (recursive) { if (gMutex_unfair) { _type = RecursiveUnfair; - _runfair = AS_RECURSIVE_UNFAIR_LOCK_INIT; + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + _runfair = AS_RECURSIVE_UNFAIR_LOCK_INIT; + } else { + new (&_recursive) std::recursive_mutex(); + } } else { _type = Recursive; new (&_recursive) std::recursive_mutex(); @@ -243,6 +267,11 @@ namespace ASDN { void WillUnlock() { #if ASDISPLAYNODE_ASSERTIONS_ENABLED +#if ASEnableVerboseLogging + if (!_debug_name.empty()) { + as_log_verbose(ASLockingLog(), "unlock %s, count is %d", _debug_name.c_str(), (int)(_count - 1)); + } +#endif if (--_count == 0) { _owner = std::thread::id(); } @@ -251,6 +280,11 @@ namespace ASDN { void DidLock() { #if ASDISPLAYNODE_ASSERTIONS_ENABLED +#if ASEnableVerboseLogging + if (!_debug_name.empty()) { + as_log_verbose(ASLockingLog(), "lock %s, count is %d", _debug_name.c_str(), (int)(_count + 1)); + } +#endif if (++_count == 1) { // New owner. _owner = std::this_thread::get_id(); @@ -265,6 +299,10 @@ namespace ASDN { std::mutex _plain; std::recursive_mutex _recursive; }; +#if ASEnableVerboseLogging + std::string _debug_name; +#endif + #if ASDISPLAYNODE_ASSERTIONS_ENABLED std::thread::id _owner = std::thread::id(); int _count = 0; @@ -290,6 +328,6 @@ namespace ASDN { typedef std::lock_guard MutexLocker; typedef std::unique_lock UniqueLock; -} // namespace ASDN +} // namespace AS #endif /* __cplusplus */ diff --git a/Example/Pods/Texture/Source/Details/ASTraceEvent.h b/Example/Pods/Texture/Source/Details/ASTraceEvent.h deleted file mode 100644 index 8ca7b32..0000000 --- a/Example/Pods/Texture/Source/Details/ASTraceEvent.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// ASTraceEvent.h -// Texture -// -// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. -// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -// - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -AS_SUBCLASSING_RESTRICTED -@interface ASTraceEvent : NSObject - -/** - * This method is dealloc safe. - */ -- (instancetype)initWithBacktrace:(nullable NSArray *)backtrace - format:(NSString *)format - arguments:(va_list)arguments NS_FORMAT_FUNCTION(2,0); - -// Will be nil unless AS_SAVE_EVENT_BACKTRACES=1 (default=0) -@property (nonatomic, nullable, readonly) NSArray *backtrace; -@property (nonatomic, readonly) NSString *message; -@property (nonatomic, readonly) NSTimeInterval timestamp; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Details/ASTraceEvent.mm b/Example/Pods/Texture/Source/Details/ASTraceEvent.mm deleted file mode 100644 index c809865..0000000 --- a/Example/Pods/Texture/Source/Details/ASTraceEvent.mm +++ /dev/null @@ -1,67 +0,0 @@ -// -// ASTraceEvent.mm -// Texture -// -// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. -// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved. -// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 -// - -#import -#import - -static NSString *const ASTraceEventThreadDescriptionKey = @"ASThreadTraceEventDescription"; - -@interface ASTraceEvent () -@property (nonatomic, readonly) NSString *objectDescription; -@property (nonatomic, readonly) NSString *threadDescription; -@end - -@implementation ASTraceEvent - -- (instancetype)initWithBacktrace:(NSArray *)backtrace format:(NSString *)format arguments:(va_list)args -{ - self = [super init]; - if (self != nil) { - static NSTimeInterval refTime; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - refTime = CACurrentMediaTime(); - }); - - // Create the format string passed to us. - _message = [[NSString alloc] initWithFormat:format arguments:args]; - - NSThread *thread = [NSThread currentThread]; - NSString *threadDescription = thread.name; - if (threadDescription.length == 0) { - if ([thread isMainThread]) { - threadDescription = @"Main"; - } else { - // If the bg thread has no name, we cache a 4-character ptr string to identify it by - // inside the thread dictionary. - NSMutableDictionary *threadDict = thread.threadDictionary; - threadDescription = threadDict[ASTraceEventThreadDescriptionKey]; - if (threadDescription == nil) { - // Want these to be 4-chars to line up with "Main". It's possible that a collision could happen - // here but it's so unbelievably likely to impact development, the risk is acceptable. - NSString *ptrString = [NSString stringWithFormat:@"%p", thread]; - threadDescription = [ptrString substringFromIndex:MAX(0, ptrString.length - 4)]; - threadDict[ASTraceEventThreadDescriptionKey] = threadDescription; - } - } - } - _threadDescription = threadDescription; - - _backtrace = backtrace; - _timestamp = CACurrentMediaTime() - refTime; - } - return self; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<(%@) t=%7.3f: %@>", _threadDescription, _timestamp, _message]; -} - -@end diff --git a/Example/Pods/Texture/Source/Details/ASTraitCollection.h b/Example/Pods/Texture/Source/Details/ASTraitCollection.h index 9ecf433..7adb197 100644 --- a/Example/Pods/Texture/Source/Details/ASTraitCollection.h +++ b/Example/Pods/Texture/Source/Details/ASTraitCollection.h @@ -40,43 +40,53 @@ typedef struct { UIUserInterfaceIdiom userInterfaceIdiom; UIForceTouchCapability forceTouchCapability; UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); -#if AS_BUILD_UIUSERINTERFACESTYLE UIUserInterfaceStyle userInterfaceStyle API_AVAILABLE(tvos(10.0), ios(12.0)); -#endif + // NOTE: This must be a constant. We will assert. unowned UIContentSizeCategory preferredContentSizeCategory API_AVAILABLE(ios(10.0)); CGSize containerSize; + +#if TARGET_OS_IOS + UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos); +#endif + UIAccessibilityContrast accessibilityContrast API_AVAILABLE(ios(13.0)); + UILegibilityWeight legibilityWeight API_AVAILABLE(ios(13.0)); } ASPrimitiveTraitCollection; #pragma clang diagnostic pop /** * Creates ASPrimitiveTraitCollection with default values. */ -AS_EXTERN ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault(void); +ASDK_EXTERN ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault(void); /** * Creates a ASPrimitiveTraitCollection from a given UITraitCollection. */ -AS_EXTERN ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection *traitCollection); +ASDK_EXTERN ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITraitCollection *traitCollection); + +/** + * Creates a UITraitCollection from a given ASPrimitiveTraitCollection. + */ +ASDK_EXTERN UITraitCollection * ASPrimitiveTraitCollectionToUITraitCollection(ASPrimitiveTraitCollection traitCollection); /** * Compares two ASPrimitiveTraitCollection to determine if they are the same. */ -AS_EXTERN BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTraitCollection lhs, ASPrimitiveTraitCollection rhs); +ASDK_EXTERN BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTraitCollection lhs, ASPrimitiveTraitCollection rhs); /** * Returns a string representation of a ASPrimitiveTraitCollection. */ -AS_EXTERN NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection traits); +ASDK_EXTERN NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection traits); /** * This function will walk the layout element hierarchy and updates the layout element trait collection for every * layout element within the hierarchy. */ -AS_EXTERN void ASTraitCollectionPropagateDown(id element, ASPrimitiveTraitCollection traitCollection); +ASDK_EXTERN void ASTraitCollectionPropagateDown(id element, ASPrimitiveTraitCollection traitCollection); /** * Abstraction on top of UITraitCollection for propagation within AsyncDisplayKit-Layout @@ -95,7 +105,7 @@ AS_EXTERN void ASTraitCollectionPropagateDown(id element, ASPri * @abstract Sets a trait collection on this environment state. * * @discussion This only exists as an internal convenience method. Users should not override trait collection using it. - * Use [ASViewController overrideDisplayTraitsWithTraitCollection] block instead. + * Use [ASDKViewController overrideDisplayTraitsWithTraitCollection] block instead. */ - (void)setPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traitCollection; @@ -106,20 +116,10 @@ AS_EXTERN void ASTraitCollectionPropagateDown(id element, ASPri @end -#define ASPrimitiveTraitCollectionDefaults \ -- (ASPrimitiveTraitCollection)primitiveTraitCollection\ -{\ - return _primitiveTraitCollection.load();\ -}\ -- (void)setPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traitCollection\ -{\ - _primitiveTraitCollection = traitCollection;\ -}\ - #define ASLayoutElementCollectionTableSetTraitCollection(lock) \ - (void)setPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traitCollection\ {\ - ASDN::MutexLocker l(lock);\ + AS::MutexLocker l(lock);\ \ ASPrimitiveTraitCollection oldTraits = self.primitiveTraitCollection;\ [super setPrimitiveTraitCollection:traitCollection];\ @@ -149,13 +149,18 @@ AS_SUBCLASSING_RESTRICTED @property (readonly) UIUserInterfaceIdiom userInterfaceIdiom; @property (readonly) UIForceTouchCapability forceTouchCapability; @property (readonly) UITraitEnvironmentLayoutDirection layoutDirection API_AVAILABLE(ios(10.0)); -#if AS_BUILD_UIUSERINTERFACESTYLE @property (readonly) UIUserInterfaceStyle userInterfaceStyle API_AVAILABLE(tvos(10.0), ios(12.0)); -#endif @property (readonly) UIContentSizeCategory preferredContentSizeCategory API_AVAILABLE(ios(10.0)); @property (readonly) CGSize containerSize; +#if TARGET_OS_IOS +@property (readonly) UIUserInterfaceLevel userInterfaceLevel API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos); +#endif + +@property (readonly) UIAccessibilityContrast accessibilityContrast API_AVAILABLE(ios(13.0)); +@property (readonly) UILegibilityWeight legibilityWeight API_AVAILABLE(ios(13.0)); + - (BOOL)isEqualToTraitCollection:(ASTraitCollection *)traitCollection; @end diff --git a/Example/Pods/Texture/Source/Details/ASTraitCollection.mm b/Example/Pods/Texture/Source/Details/ASTraitCollection.mm index e885239..f26a2be 100644 --- a/Example/Pods/Texture/Source/Details/ASTraitCollection.mm +++ b/Example/Pods/Texture/Source/Details/ASTraitCollection.mm @@ -33,16 +33,25 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { tc.horizontalSizeClass = UIUserInterfaceSizeClassUnspecified; tc.verticalSizeClass = UIUserInterfaceSizeClassUnspecified; tc.containerSize = CGSizeZero; - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { tc.displayGamut = UIDisplayGamutUnspecified; tc.preferredContentSizeCategory = UIContentSizeCategoryUnspecified; tc.layoutDirection = UITraitEnvironmentLayoutDirectionUnspecified; } -#if AS_BUILD_UIUSERINTERFACESTYLE if (AS_AVAILABLE_IOS_TVOS(12, 10)) { tc.userInterfaceStyle = UIUserInterfaceStyleUnspecified; } + +#if TARGET_OS_IOS + if(AS_AVAILABLE_IOS(13)){ + tc.userInterfaceLevel = UIUserInterfaceLevelUnspecified; + } #endif + + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { + tc.accessibilityContrast = UIAccessibilityContrastUnspecified; + tc.legibilityWeight = UILegibilityWeightUnspecified; + } return tc; } @@ -53,21 +62,52 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra environmentTraitCollection.displayScale = traitCollection.displayScale; environmentTraitCollection.userInterfaceIdiom = traitCollection.userInterfaceIdiom; environmentTraitCollection.forceTouchCapability = traitCollection.forceTouchCapability; - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { environmentTraitCollection.displayGamut = traitCollection.displayGamut; environmentTraitCollection.layoutDirection = traitCollection.layoutDirection; ASDisplayNodeCAssertPermanent(traitCollection.preferredContentSizeCategory); environmentTraitCollection.preferredContentSizeCategory = traitCollection.preferredContentSizeCategory; } -#if AS_BUILD_UIUSERINTERFACESTYLE if (AS_AVAILABLE_IOS_TVOS(12, 10)) { environmentTraitCollection.userInterfaceStyle = traitCollection.userInterfaceStyle; } + +#if TARGET_OS_IOS + if(AS_AVAILABLE_IOS(13)){ + environmentTraitCollection.userInterfaceLevel = traitCollection.userInterfaceLevel; + } #endif + + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { + environmentTraitCollection.accessibilityContrast = traitCollection.accessibilityContrast; + environmentTraitCollection.legibilityWeight = traitCollection.legibilityWeight; + } return environmentTraitCollection; } +ASDK_EXTERN UITraitCollection * ASPrimitiveTraitCollectionToUITraitCollection(ASPrimitiveTraitCollection traitCollection) { + NSMutableArray *collections = [[NSMutableArray alloc] initWithArray:@[ + [UITraitCollection traitCollectionWithHorizontalSizeClass:traitCollection.horizontalSizeClass], + [UITraitCollection traitCollectionWithVerticalSizeClass:traitCollection.verticalSizeClass], + [UITraitCollection traitCollectionWithDisplayScale:traitCollection.displayScale], + [UITraitCollection traitCollectionWithUserInterfaceIdiom:traitCollection.userInterfaceIdiom], + [UITraitCollection traitCollectionWithForceTouchCapability:traitCollection.forceTouchCapability], + ]]; + + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { + [collections addObject:[UITraitCollection traitCollectionWithDisplayGamut:traitCollection.displayGamut]]; + [collections addObject:[UITraitCollection traitCollectionWithLayoutDirection:traitCollection.layoutDirection]]; + [collections addObject:[UITraitCollection traitCollectionWithPreferredContentSizeCategory:traitCollection.preferredContentSizeCategory]]; + } + if (AS_AVAILABLE_IOS_TVOS(12, 10)) { + [collections addObject:[UITraitCollection traitCollectionWithUserInterfaceStyle:traitCollection.userInterfaceStyle]]; + } + + UITraitCollection *result = [UITraitCollection traitCollectionWithTraitsFromCollections:collections]; + return result; +} + BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTraitCollection lhs, ASPrimitiveTraitCollection rhs) { return !memcmp(&lhs, &rhs, sizeof(ASPrimitiveTraitCollection)); } @@ -139,7 +179,6 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr } // Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline -#if AS_BUILD_UIUSERINTERFACESTYLE API_AVAILABLE(tvos(10.0), ios(12.0)) ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIUserInterfaceStyle(UIUserInterfaceStyle userInterfaceStyle) { switch (userInterfaceStyle) { @@ -151,8 +190,50 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr return @"Unspecified"; } } + +#if TARGET_OS_IOS +// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(13)) +ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(UIUserInterfaceLevel userInterfaceLevel) { + switch (userInterfaceLevel) { + case UIUserInterfaceLevelBase: + return @"Base"; + case UIUserInterfaceLevelElevated: + return @"Elevated"; + default: + return @"Unspecified"; + } +} #endif +// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(13)) +ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentAccessibilityContrast(UIAccessibilityContrast accessibilityContrast) { + switch (accessibilityContrast) { + case UIAccessibilityContrastNormal: + return @"Normal"; + case UIAccessibilityContrastHigh: + return @"High"; + default: + return @"Unspecified"; + } +} + +// Named so as not to conflict with a hidden Apple function, in case compiler decides not to inline +API_AVAILABLE(ios(13)) +ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentLegibilityWeight(UILegibilityWeight legibilityWeight) { + switch (legibilityWeight) { + case UILegibilityWeightRegular: + return @"Regular"; + case UILegibilityWeightBold: + return @"Bold"; + default: + return @"Unspecified"; + } +} + + + NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection traits) { NSMutableArray *props = [NSMutableArray array]; [props addObject:@{ @"verticalSizeClass": AS_NSStringFromUIUserInterfaceSizeClass(traits.verticalSizeClass) }]; @@ -160,16 +241,27 @@ BOOL ASPrimitiveTraitCollectionIsEqualToASPrimitiveTraitCollection(ASPrimitiveTr [props addObject:@{ @"displayScale": [NSString stringWithFormat: @"%.0lf", (double)traits.displayScale] }]; [props addObject:@{ @"userInterfaceIdiom": AS_NSStringFromUIUserInterfaceIdiom(traits.userInterfaceIdiom) }]; [props addObject:@{ @"forceTouchCapability": AS_NSStringFromUIForceTouchCapability(traits.forceTouchCapability) }]; -#if AS_BUILD_UIUSERINTERFACESTYLE if (AS_AVAILABLE_IOS_TVOS(12, 10)) { [props addObject:@{ @"userInterfaceStyle": AS_NSStringFromUIUserInterfaceStyle(traits.userInterfaceStyle) }]; } -#endif - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { [props addObject:@{ @"layoutDirection": AS_NSStringFromUITraitEnvironmentLayoutDirection(traits.layoutDirection) }]; - [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; + if (traits.preferredContentSizeCategory != nil) { + [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; + } [props addObject:@{ @"displayGamut": AS_NSStringFromUIDisplayGamut(traits.displayGamut) }]; } + +#if TARGET_OS_IOS + if (AS_AVAILABLE_IOS(13)){ + [props addObject:@{ @"userInterfaceLevel": AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(traits.userInterfaceLevel) }]; + } +#endif + + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { + [props addObject:@{ @"accessibilityContrast": AS_NSStringFromUITraitEnvironmentAccessibilityContrast(traits.accessibilityContrast) }]; + [props addObject:@{ @"legibilityWeight": AS_NSStringFromUITraitEnvironmentLegibilityWeight(traits.legibilityWeight) }]; + } [props addObject:@{ @"containerSize": NSStringFromCGSize(traits.containerSize) }]; return ASObjectDescriptionMakeWithoutObject(props); } @@ -182,7 +274,7 @@ @implementation ASTraitCollection { + (ASTraitCollection *)traitCollectionWithASPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traits NS_RETURNS_RETAINED { ASTraitCollection *tc = [[ASTraitCollection alloc] init]; - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { ASDisplayNodeCAssertPermanent(traits.preferredContentSizeCategory); } tc->_prim = traits; @@ -220,16 +312,34 @@ - (CGSize)containerSize { return _prim.containerSize; } -#if AS_BUILD_UIUSERINTERFACESTYLE + - (UIUserInterfaceStyle)userInterfaceStyle { return _prim.userInterfaceStyle; } -#endif + - (UIContentSizeCategory)preferredContentSizeCategory { return _prim.preferredContentSizeCategory; } + +#if TARGET_OS_IOS +- (UIUserInterfaceLevel)userInterfaceLevel +{ + return _prim.userInterfaceLevel; +} +#endif + +- (UIAccessibilityContrast)accessibilityContrast +{ + return _prim.accessibilityContrast; +} + +- (UILegibilityWeight)legibilityWeight +{ + return _prim.legibilityWeight; +} + - (NSUInteger)hash { return ASHashBytes(&_prim, sizeof(ASPrimitiveTraitCollection)); } diff --git a/Example/Pods/Texture/Source/Details/ASWeakSet.mm b/Example/Pods/Texture/Source/Details/ASWeakSet.mm index 6530271..a65dbff 100644 --- a/Example/Pods/Texture/Source/Details/ASWeakSet.mm +++ b/Example/Pods/Texture/Source/Details/ASWeakSet.mm @@ -71,7 +71,7 @@ - (NSUInteger)count return count; } -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id _Nonnull *)buffer count:(NSUInteger)len +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(unowned id _Nonnull *)buffer count:(NSUInteger)len { return [_hashTable countByEnumeratingWithState:state objects:buffer count:len]; } diff --git a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.h b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.h index 245c62b..e3d0f21 100644 --- a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.h +++ b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.h @@ -32,7 +32,7 @@ typedef NS_ENUM(NSUInteger, ASAsyncTransactionState) { ASAsyncTransactionStateComplete }; -AS_EXTERN NSInteger const ASDefaultTransactionPriority; +ASDK_EXTERN NSInteger const ASDefaultTransactionPriority; /** @summary ASAsyncTransaction provides lightweight transaction semantics for asynchronous operations. diff --git a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.mm b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.mm index c147f5f..35d9a43 100644 --- a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.mm +++ b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransaction.mm @@ -14,13 +14,12 @@ #import #import #import -#import #ifndef __STRICT_ANSI__ #warning "Texture must be compiled with std=c++11 to prevent layout issues. gnu++ is not supported. This is hopefully temporary." #endif -AS_EXTERN NSRunLoopMode const UITrackingRunLoopMode; +ASDK_EXTERN NSRunLoopMode const UITrackingRunLoopMode; NSInteger const ASDefaultTransactionPriority = 0; @@ -269,10 +268,7 @@ - (NSString *)description if (_pendingOperations == 0) { dispatch_async(queue, block); } else { - GroupNotify notify; - notify._block = block; - notify._queue = queue; - _notifyList.push_back(notify); + _notifyList.push_back({block, queue}); } } @@ -334,7 +330,7 @@ @implementation _ASAsyncTransaction - (instancetype)initWithCompletionBlock:(void(^)(_ASAsyncTransaction *, BOOL))completionBlock { - if ((self = [self init])) { + if ((self = [super init])) { _completionBlock = completionBlock; self.state = ASAsyncTransactionStateOpen; } diff --git a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer+Private.h b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer+Private.h index 003184c..cd4b414 100644 --- a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer+Private.h +++ b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer+Private.h @@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN @class _ASAsyncTransaction; @interface CALayer (ASAsyncTransactionContainerTransactions) -@property (nonatomic, nullable, setter=asyncdisplaykit_setAsyncLayerTransactions:) NSHashTable<_ASAsyncTransaction *> *asyncdisplaykit_asyncLayerTransactions; +@property (nonatomic, nullable, setter=asyncdisplaykit_setAsyncLayerTransactions:) NSMutableSet<_ASAsyncTransaction *> *asyncdisplaykit_asyncLayerTransactions; - (void)asyncdisplaykit_asyncTransactionContainerWillBeginTransaction:(_ASAsyncTransaction *)transaction; - (void)asyncdisplaykit_asyncTransactionContainerDidCompleteTransaction:(_ASAsyncTransaction *)transaction; diff --git a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer.mm b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer.mm index ed44231..669a083 100644 --- a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer.mm +++ b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionContainer.mm @@ -10,6 +10,7 @@ #import #import +#import #import #import @@ -48,9 +49,9 @@ - (_ASAsyncTransaction *)asyncdisplaykit_asyncTransaction { _ASAsyncTransaction *transaction = self.asyncdisplaykit_currentAsyncTransaction; if (transaction == nil) { - NSHashTable *transactions = self.asyncdisplaykit_asyncLayerTransactions; + NSMutableSet<_ASAsyncTransaction *> *transactions = self.asyncdisplaykit_asyncLayerTransactions; if (transactions == nil) { - transactions = [NSHashTable hashTableWithOptions:NSHashTableObjectPointerPersonality]; + transactions = ASCreatePointerBasedMutableSet(); self.asyncdisplaykit_asyncLayerTransactions = transactions; } __weak CALayer *weakSelf = self; @@ -59,7 +60,11 @@ - (_ASAsyncTransaction *)asyncdisplaykit_asyncTransaction if (self == nil) { return; } - [transactions removeObject:completedTransaction]; + [self.asyncdisplaykit_asyncLayerTransactions removeObject:completedTransaction]; + if (self.asyncdisplaykit_asyncLayerTransactions.count == 0) { + // Reclaim object memory. + self.asyncdisplaykit_asyncLayerTransactions = nil; + } [self asyncdisplaykit_asyncTransactionContainerDidCompleteTransaction:completedTransaction]; }]; [transactions addObject:transaction]; diff --git a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionGroup.mm b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionGroup.mm index ae651d1..62cf4c7 100644 --- a/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionGroup.mm +++ b/Example/Pods/Texture/Source/Details/Transactions/_ASAsyncTransactionGroup.mm @@ -12,7 +12,6 @@ #import #import #import -#import @implementation _ASAsyncTransactionGroup { NSHashTable> *_containers; diff --git a/Example/Pods/Texture/Source/Details/UIView+ASConvenience.h b/Example/Pods/Texture/Source/Details/UIView+ASConvenience.h index 30d58a0..870793b 100644 --- a/Example/Pods/Texture/Source/Details/UIView+ASConvenience.h +++ b/Example/Pods/Texture/Source/Details/UIView+ASConvenience.h @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) CGFloat zPosition; @property (nonatomic) CGPoint anchorPoint; @property (nonatomic) CGFloat cornerRadius; +@property (nonatomic) CACornerMask maskedCorners API_AVAILABLE(ios(11), tvos(11)); @property (nullable, nonatomic) id contents; @property (nonatomic, copy) NSString *contentsGravity; @property (nonatomic) CGRect contentsRect; @@ -38,10 +39,11 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) CGFloat borderWidth; @property (nonatomic, getter = isOpaque) BOOL opaque; @property (nonatomic) __attribute__((NSObject)) CGColorRef borderColor; -@property (nonatomic) __attribute__((NSObject)) CGColorRef backgroundColor; +@property (nonatomic) UIColor *backgroundColor; @property (nonatomic) BOOL allowsGroupOpacity; @property (nonatomic) BOOL allowsEdgeAntialiasing; -@property (nonatomic) unsigned int edgeAntialiasingMask; +@property (nonatomic) CAEdgeAntialiasingMask edgeAntialiasingMask; +@property (nonatomic, nullable, copy) NSDictionary> *actions; - (void)setNeedsDisplay; - (void)setNeedsLayout; diff --git a/Example/Pods/Texture/Source/Details/_ASCollectionViewCell.mm b/Example/Pods/Texture/Source/Details/_ASCollectionViewCell.mm index 39afa16..28d8cec 100644 --- a/Example/Pods/Texture/Source/Details/_ASCollectionViewCell.mm +++ b/Example/Pods/Texture/Source/Details/_ASCollectionViewCell.mm @@ -110,12 +110,14 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event return nil; } - return [self.node hitTest:point withEvent:event]; + CGPoint pointOnNode = [self.node.view convertPoint:point fromView:self]; + return [self.node hitTest:pointOnNode withEvent:event]; } - (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event { - return [self.node pointInside:point withEvent:event]; + CGPoint pointOnNode = [self.node.view convertPoint:point fromView:self]; + return [self.node pointInside:pointOnNode withEvent:event]; } @end diff --git a/Example/Pods/Texture/Source/Details/_ASDisplayLayer.h b/Example/Pods/Texture/Source/Details/_ASDisplayLayer.h index e69ab71..1066a36 100644 --- a/Example/Pods/Texture/Source/Details/_ASDisplayLayer.h +++ b/Example/Pods/Texture/Source/Details/_ASDisplayLayer.h @@ -112,7 +112,7 @@ NS_ASSUME_NONNULL_BEGIN @summary Delegate override to provide new layer contents as a UIImage. @param parameters An object describing all of the properties you need to draw. Return this from -drawParametersForAsyncLayer: @param isCancelledBlock Execute this block to check whether the current drawing operation has been cancelled to avoid unnecessary work. A return value of YES means cancel drawing and return. - @return A UIImage with contents that are ready to display on the main thread. Make sure that the image is already decoded before returning it here. + @return A UIImage (backed by a CGImage) with contents that are ready to display on the main thread. Make sure that the image is already decoded before returning it here. */ + (UIImage *)displayWithParameters:(nullable id)parameters isCancelled:(AS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelledBlock; diff --git a/Example/Pods/Texture/Source/Details/_ASDisplayLayer.mm b/Example/Pods/Texture/Source/Details/_ASDisplayLayer.mm index 96eda9e..4e8569d 100644 --- a/Example/Pods/Texture/Source/Details/_ASDisplayLayer.mm +++ b/Example/Pods/Texture/Source/Details/_ASDisplayLayer.mm @@ -9,35 +9,20 @@ #import -#import - #import #import #import #import -#import -#import -#import @implementation _ASDisplayLayer { BOOL _attemptedDisplayWhileZeroSized; - - struct { - BOOL delegateDidChangeBounds:1; - } _delegateFlags; } @dynamic displaysAsynchronously; #pragma mark - Properties -- (void)setDelegate:(id)delegate -{ - [super setDelegate:delegate]; - _delegateFlags.delegateDidChangeBounds = [delegate respondsToSelector:@selector(layer:didChangeBoundsWithOldValue:newValue:)]; -} - - (void)setDisplaySuspended:(BOOL)displaySuspended { ASDisplayNodeAssertMainThread(); @@ -59,12 +44,11 @@ - (void)setBounds:(CGRect)bounds if (!valid) { return; } - if (_delegateFlags.delegateDidChangeBounds) { + if ([self.delegate respondsToSelector:@selector(layer:didChangeBoundsWithOldValue:newValue:)]) { CGRect oldBounds = self.bounds; [super setBounds:bounds]; self.asyncdisplaykit_node.threadSafeBounds = bounds; [(id)self.delegate layer:self didChangeBoundsWithOldValue:oldBounds newValue:bounds]; - } else { [super setBounds:bounds]; self.asyncdisplaykit_node.threadSafeBounds = bounds; @@ -115,6 +99,13 @@ - (void)setNeedsDisplay #pragma mark - ++ (id)defaultActionForKey:(NSString *)event +{ + // We never want to run one of CA's root default actions. So if we return nil from actionForLayer:forKey:, and let CA + // dig into the actions dictionary, and it doesn't find it there, it will check here and we need to stop the search. + return (id)kCFNull; +} + + (dispatch_queue_t)displayQueue { static dispatch_queue_t displayQueue = NULL; diff --git a/Example/Pods/Texture/Source/Details/_ASDisplayView.h b/Example/Pods/Texture/Source/Details/_ASDisplayView.h index 519fde8..7e3fe35 100644 --- a/Example/Pods/Texture/Source/Details/_ASDisplayView.h +++ b/Example/Pods/Texture/Source/Details/_ASDisplayView.h @@ -31,14 +31,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)__forwardTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)__forwardTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; -// These methods expose a way for ASDisplayNode responder methods to let the view call super responder methods -// They are called from ASDisplayNode to pass through UIResponder methods to the view -- (BOOL)__canBecomeFirstResponder; -- (BOOL)__becomeFirstResponder; -- (BOOL)__canResignFirstResponder; -- (BOOL)__resignFirstResponder; -- (BOOL)__isFirstResponder; - @end NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Details/_ASDisplayView.mm b/Example/Pods/Texture/Source/Details/_ASDisplayView.mm index 0bf1514..7741e44 100644 --- a/Example/Pods/Texture/Source/Details/_ASDisplayView.mm +++ b/Example/Pods/Texture/Source/Details/_ASDisplayView.mm @@ -8,60 +8,14 @@ // #import -#import #import #import #import #import -#import #import -#import #import -#import -#import - -#pragma mark - _ASDisplayViewMethodOverrides - -typedef NS_OPTIONS(NSUInteger, _ASDisplayViewMethodOverrides) -{ - _ASDisplayViewMethodOverrideNone = 0, - _ASDisplayViewMethodOverrideCanBecomeFirstResponder = 1 << 0, - _ASDisplayViewMethodOverrideBecomeFirstResponder = 1 << 1, - _ASDisplayViewMethodOverrideCanResignFirstResponder = 1 << 2, - _ASDisplayViewMethodOverrideResignFirstResponder = 1 << 3, - _ASDisplayViewMethodOverrideIsFirstResponder = 1 << 4, -}; - -/** - * Returns _ASDisplayViewMethodOverrides for the given class - * - * @param c the class, required. - * - * @return _ASDisplayViewMethodOverrides. - */ -static _ASDisplayViewMethodOverrides GetASDisplayViewMethodOverrides(Class c) -{ - ASDisplayNodeCAssertNotNil(c, @"class is required"); - - _ASDisplayViewMethodOverrides overrides = _ASDisplayViewMethodOverrideNone; - if (ASSubclassOverridesSelector([_ASDisplayView class], c, @selector(canBecomeFirstResponder))) { - overrides |= _ASDisplayViewMethodOverrideCanBecomeFirstResponder; - } - if (ASSubclassOverridesSelector([_ASDisplayView class], c, @selector(becomeFirstResponder))) { - overrides |= _ASDisplayViewMethodOverrideBecomeFirstResponder; - } - if (ASSubclassOverridesSelector([_ASDisplayView class], c, @selector(canResignFirstResponder))) { - overrides |= _ASDisplayViewMethodOverrideCanResignFirstResponder; - } - if (ASSubclassOverridesSelector([_ASDisplayView class], c, @selector(resignFirstResponder))) { - overrides |= _ASDisplayViewMethodOverrideResignFirstResponder; - } - if (ASSubclassOverridesSelector([_ASDisplayView class], c, @selector(isFirstResponder))) { - overrides |= _ASDisplayViewMethodOverrideIsFirstResponder; - } - return overrides; -} +#import #pragma mark - _ASDisplayView @@ -74,55 +28,28 @@ @interface _ASDisplayView () @implementation _ASDisplayView { - BOOL _inHitTest; - BOOL _inPointInside; + struct _ASDisplayViewInternalFlags { + unsigned inHitTest:1; + unsigned inPointInside:1; + + unsigned inCanBecomeFirstResponder:1; + unsigned inBecomeFirstResponder:1; + unsigned inCanResignFirstResponder:1; + unsigned inResignFirstResponder:1; + unsigned inIsFirstResponder:1; + } _internalFlags; NSArray *_accessibilityElements; CGRect _lastAccessibilityElementsFrame; - - _ASDisplayViewMethodOverrides _methodOverrides; } #pragma mark - Class -+ (void)initialize -{ - __unused Class initializeSelf = self; - IMP staticInitialize = imp_implementationWithBlock(^(_ASDisplayView *view) { - ASDisplayNodeAssert(view.class == initializeSelf, @"View class %@ does not have a matching _staticInitialize method; check to ensure [super initialize] is called within any custom +initialize implementations! Overridden methods will not be called unless they are also implemented by superclass %@", view.class, initializeSelf); - view->_methodOverrides = GetASDisplayViewMethodOverrides(view.class); - }); - - class_replaceMethod(self, @selector(_staticInitialize), staticInitialize, "v:@"); -} - + (Class)layerClass { return [_ASDisplayLayer class]; } -#pragma mark - NSObject Overrides - -- (instancetype)init -{ - if (!(self = [super init])) - return nil; - - [self _initializeInstance]; - - return self; -} - -- (void)_initializeInstance -{ - [self _staticInitialize]; -} - -- (void)_staticInitialize -{ - ASDisplayNodeAssert(NO, @"_staticInitialize must be overridden"); -} - // e.g. ; frame = ...> - (NSString *)description { @@ -153,6 +80,21 @@ - (NSString *)description #pragma mark - UIView Overrides +- (id)actionForLayer:(CALayer *)layer forKey:(NSString *)event +{ + id uikitAction = [super actionForLayer:layer forKey:event]; + + // Even though the UIKit action will take precedence, we still unconditionally forward to the node so that it can + // track events like kCAOnOrderIn. + id nodeAction = [_asyncdisplaykit_node actionForLayer:layer forKey:event]; + + // If UIKit specifies an action, that takes precedence. That's an animation block so it's explicit. + if (uikitAction && uikitAction != (id)kCFNull) { + return uikitAction; + } + return nodeAction; +} + - (void)willMoveToWindow:(UIWindow *)newWindow { ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. @@ -210,7 +152,7 @@ - (void)willMoveToSuperview:(UIView *)newSuperview if (needsSupernodeUpdate) { // -removeFromSupernode is called by -addSubnode:, if it is needed. // FIXME: Needs rethinking if automaticallyManagesSubnodes=YES - [newSuperview.asyncdisplaykit_node _addSubnode:node]; + [newSuperview.asyncdisplaykit_node addSubnode:node]; } } } @@ -234,7 +176,7 @@ - (void)didMoveToSuperview if (superview && node.viewControllerRoot) { UIViewController *vc = [node closestViewController]; - ASDisplayNodeAssert(vc != nil && [vc isKindOfClass:[ASViewController class]] && ((ASViewController*)vc).node == node, @"This node was once used as a view controller's node. You should not reuse it without its view controller."); + ASDisplayNodeAssert(vc != nil && [vc isKindOfClass:[ASDKViewController class]] && ((ASDKViewController*)vc).node == node, @"This node was once used as a view controller's node. You should not reuse it without its view controller."); } #endif @@ -271,7 +213,7 @@ - (void)didMoveToSuperview if (needsSupernodeRemoval) { // The node will only disconnect from its supernode, not removeFromSuperview, in this condition. // FIXME: Needs rethinking if automaticallyManagesSubnodes=YES - [node _removeFromSupernode]; + [node removeFromSupernode]; } } } @@ -412,10 +354,10 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event // hitTest:, it will call it on the view, which is _ASDisplayView. After calling into the node, any additional calls // should use the UIView implementation of hitTest: ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. - if (!_inHitTest) { - _inHitTest = YES; + if (!_internalFlags.inHitTest) { + _internalFlags.inHitTest = YES; UIView *hitView = [node hitTest:point withEvent:event]; - _inHitTest = NO; + _internalFlags.inHitTest = NO; return hitView; } else { return [super hitTest:point withEvent:event]; @@ -426,10 +368,10 @@ - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { // See comments in -hitTest:withEvent: for the strategy here. ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. - if (!_inPointInside) { - _inPointInside = YES; + if (!_internalFlags.inPointInside) { + _internalFlags.inPointInside = YES; BOOL result = [node pointInside:point withEvent:event]; - _inPointInside = NO; + _internalFlags.inPointInside = NO; return result; } else { return [super pointInside:point withEvent:event]; @@ -452,48 +394,70 @@ - (void)tintColorDidChange #pragma mark UIResponder Handling -#define IMPLEMENT_RESPONDER_METHOD(__sel, __nodeMethodOverride, __viewMethodOverride) \ -- (BOOL)__sel\ -{\ - ASDisplayNode *node = _asyncdisplaykit_node; /* Create strong reference to weak ivar. */ \ - /* Check if we can call through to ASDisplayNode subclass directly */ \ - if (node.methodOverrides & __nodeMethodOverride) { \ - return [node __sel]; \ - } else { \ - /* Prevent an infinite loop in here if [super __sel] was called on a \ - / _ASDisplayView subclass */ \ - if (self->_methodOverrides & __viewMethodOverride) { \ - /* Call through to views superclass as we expect super was called from the - _ASDisplayView subclass and a node subclass does not overwrite __sel */ \ - return [self __##__sel]; \ - } else { \ - /* Call through to internal node __sel method that will consider the view in responding */ \ - return [node __##__sel]; \ - } \ - } \ -}\ -/* All __ prefixed methods are called from ASDisplayNode to let the view decide in what UIResponder state they \ -are not overridden by a ASDisplayNode subclass */ \ -- (BOOL)__##__sel \ -{ \ - return [super __sel]; \ -} \ - -IMPLEMENT_RESPONDER_METHOD(canBecomeFirstResponder, - ASDisplayNodeMethodOverrideCanBecomeFirstResponder, - _ASDisplayViewMethodOverrideCanBecomeFirstResponder); -IMPLEMENT_RESPONDER_METHOD(becomeFirstResponder, - ASDisplayNodeMethodOverrideBecomeFirstResponder, - _ASDisplayViewMethodOverrideBecomeFirstResponder); -IMPLEMENT_RESPONDER_METHOD(canResignFirstResponder, - ASDisplayNodeMethodOverrideCanResignFirstResponder, - _ASDisplayViewMethodOverrideCanResignFirstResponder); -IMPLEMENT_RESPONDER_METHOD(resignFirstResponder, - ASDisplayNodeMethodOverrideResignFirstResponder, - _ASDisplayViewMethodOverrideResignFirstResponder); -IMPLEMENT_RESPONDER_METHOD(isFirstResponder, - ASDisplayNodeMethodOverrideIsFirstResponder, - _ASDisplayViewMethodOverrideIsFirstResponder); +- (BOOL)canBecomeFirstResponder +{ + ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. + if (!_internalFlags.inCanBecomeFirstResponder) { + _internalFlags.inCanBecomeFirstResponder = YES; + BOOL result = [node canBecomeFirstResponder]; + _internalFlags.inCanBecomeFirstResponder = NO; + return result; + } else { + return [super canBecomeFirstResponder]; + } +} + +- (BOOL)becomeFirstResponder +{ + ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. + if (!_internalFlags.inBecomeFirstResponder) { + _internalFlags.inBecomeFirstResponder = YES; + BOOL result = [node becomeFirstResponder]; + _internalFlags.inBecomeFirstResponder = NO; + return result; + } else { + return [super becomeFirstResponder]; + } +} + +- (BOOL)canResignFirstResponder +{ + ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. + if (!_internalFlags.inCanResignFirstResponder) { + _internalFlags.inCanResignFirstResponder = YES; + BOOL result = [node canResignFirstResponder]; + _internalFlags.inCanResignFirstResponder = NO; + return result; + } else { + return [super canResignFirstResponder]; + } +} + +- (BOOL)resignFirstResponder +{ + ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. + if (!_internalFlags.inResignFirstResponder) { + _internalFlags.inResignFirstResponder = YES; + BOOL result = [node resignFirstResponder]; + _internalFlags.inResignFirstResponder = NO; + return result; + } else { + return [super resignFirstResponder]; + } +} + +- (BOOL)isFirstResponder +{ + ASDisplayNode *node = _asyncdisplaykit_node; // Create strong reference to weak ivar. + if (!_internalFlags.inIsFirstResponder) { + _internalFlags.inIsFirstResponder = YES; + BOOL result = [node isFirstResponder]; + _internalFlags.inIsFirstResponder = NO; + return result; + } else { + return [super isFirstResponder]; + } +} - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { diff --git a/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.h b/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.h index 9d0bf07..7f159d1 100644 --- a/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.h +++ b/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.h @@ -8,10 +8,23 @@ // #import -#import // WARNING: When dealing with accessibility elements, please use the `accessibilityElements` // property instead of the older methods e.g. `accessibilityElementCount()`. While the older methods // should still work as long as accessibility is enabled, this framework provides no guarantees on // their correctness. For details, see // https://developer.apple.com/documentation/objectivec/nsobject/1615147-accessibilityelements + +// After recusively collecting all of the accessibility elements of a node, they get sorted. This sort determines +// the order that a screen reader will traverse the elements. By default, we sort these elements based on their +// origin: lower y origin comes first, then lower x origin. If 2 nodes have an equal origin, the node with the smaller +// height is placed before the node with the smaller width. If two nodes have the exact same rect, we throw up our hands +// and return NSOrderedSame. +// +// In general this seems to work fairly well. However, if you want to provide a custom sort you can do so via +// setUserDefinedAccessibilitySortComparator(). The two elements you are comparing are NSObjects, which conforms to the +// informal UIAccessibility protocol, so you can safely compare properties like accessibilityFrame. +typedef NSComparisonResult (^ASSortAccessibilityElementsComparator)(NSObject *, NSObject *); + +// Use this method to supply your own custom sort comparator used to determine the order of the accessibility elements +void setUserDefinedAccessibilitySortComparator(ASSortAccessibilityElementsComparator userDefinedComparator); diff --git a/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.mm b/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.mm index 74016e7..7fb79ea 100644 --- a/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.mm +++ b/Example/Pods/Texture/Source/Details/_ASDisplayViewAccessiblity.mm @@ -10,6 +10,7 @@ #ifndef ASDK_ACCESSIBILITY_DISABLE #import +#import #import #import #import @@ -19,90 +20,96 @@ #import -NS_INLINE UIAccessibilityTraits InteractiveAccessibilityTraitsMask() { - return UIAccessibilityTraitLink | UIAccessibilityTraitKeyboardKey | UIAccessibilityTraitButton; -} - #pragma mark - UIAccessibilityElement -@protocol ASAccessibilityElementPositioning - -@property (nonatomic, readonly) CGRect accessibilityFrame; - -@end +static ASSortAccessibilityElementsComparator currentAccessibilityComparator = nil; +static ASSortAccessibilityElementsComparator defaultAccessibilityComparator = nil; -typedef NSComparisonResult (^SortAccessibilityElementsComparator)(id, id); +void setUserDefinedAccessibilitySortComparator(ASSortAccessibilityElementsComparator userDefinedComparator) { + currentAccessibilityComparator = userDefinedComparator ?: defaultAccessibilityComparator; +} /// Sort accessiblity elements first by y and than by x origin. -static void SortAccessibilityElements(NSMutableArray *elements) +void SortAccessibilityElements(NSMutableArray *elements) { ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray"); - static SortAccessibilityElementsComparator comparator = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - comparator = ^NSComparisonResult(id a, id b) { - CGPoint originA = a.accessibilityFrame.origin; - CGPoint originB = b.accessibilityFrame.origin; - if (originA.y == originB.y) { - if (originA.x == originB.x) { - return NSOrderedSame; + defaultAccessibilityComparator = ^NSComparisonResult(NSObject *a, NSObject *b) { + CGPoint originA = a.accessibilityFrame.origin; + CGPoint originB = b.accessibilityFrame.origin; + if (originA.y == originB.y) { + if (originA.x == originB.x) { + // if we have the same origin, favor shorter items. If heights are the same, favor thinner items. If size is the same ¯\_(ツ)_/¯ + CGSize sizeA = a.accessibilityFrame.size; + CGSize sizeB = b.accessibilityFrame.size; + if (sizeA.height == sizeB.height) { + if (sizeA.width == sizeB.width) { + return NSOrderedSame; + } + return (sizeA.width < sizeB.width) ? NSOrderedAscending : NSOrderedDescending; } - return (originA.x < originB.x) ? NSOrderedAscending : NSOrderedDescending; + return (sizeA.height < sizeB.height) ? NSOrderedAscending : NSOrderedDescending; } - return (originA.y < originB.y) ? NSOrderedAscending : NSOrderedDescending; - }; + return (originA.x < originB.x) ? NSOrderedAscending : NSOrderedDescending; + } + return (originA.y < originB.y) ? NSOrderedAscending : NSOrderedDescending; + }; + + if (!currentAccessibilityComparator) { + currentAccessibilityComparator = defaultAccessibilityComparator; + } }); - [elements sortUsingComparator:comparator]; + + [elements sortUsingComparator:currentAccessibilityComparator]; +} + +static CGRect ASAccessibilityFrameForNode(ASDisplayNode *node) { + CALayer *layer = node.layer; + return [layer convertRect:node.bounds toLayer:ASFindWindowOfLayer(layer).layer]; } -@interface ASAccessibilityElement : UIAccessibilityElement +@interface ASAccessibilityElement : UIAccessibilityElement @property (nonatomic) ASDisplayNode *node; -@property (nonatomic) ASDisplayNode *containerNode; -+ (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)container node:(ASDisplayNode *)node containerNode:(ASDisplayNode *)containerNode; ++ (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)container node:(ASDisplayNode *)node; @end @implementation ASAccessibilityElement -+ (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)container node:(ASDisplayNode *)node containerNode:(ASDisplayNode *)containerNode ++ (ASAccessibilityElement *)accessibilityElementWithContainer:(UIView *)container node:(ASDisplayNode *)node { ASAccessibilityElement *accessibilityElement = [[ASAccessibilityElement alloc] initWithAccessibilityContainer:container]; accessibilityElement.node = node; - accessibilityElement.containerNode = containerNode; accessibilityElement.accessibilityIdentifier = node.accessibilityIdentifier; accessibilityElement.accessibilityLabel = node.accessibilityLabel; accessibilityElement.accessibilityHint = node.accessibilityHint; accessibilityElement.accessibilityValue = node.accessibilityValue; accessibilityElement.accessibilityTraits = node.accessibilityTraits; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + accessibilityElement.accessibilityElementsHidden = node.accessibilityElementsHidden; if (AS_AVAILABLE_IOS_TVOS(11, 11)) { accessibilityElement.accessibilityAttributedLabel = node.accessibilityAttributedLabel; accessibilityElement.accessibilityAttributedHint = node.accessibilityAttributedHint; accessibilityElement.accessibilityAttributedValue = node.accessibilityAttributedValue; } -#endif return accessibilityElement; } - (CGRect)accessibilityFrame { - CGRect accessibilityFrame = [self.containerNode convertRect:self.node.bounds fromNode:self.node]; - accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(accessibilityFrame, self.accessibilityContainer); - return accessibilityFrame; + return ASAccessibilityFrameForNode(self.node); } @end #pragma mark - _ASDisplayView / UIAccessibilityContainer -@interface ASAccessibilityCustomAction : UIAccessibilityCustomAction +@interface ASAccessibilityCustomAction : UIAccessibilityCustomAction -@property (nonatomic) UIView *container; @property (nonatomic) ASDisplayNode *node; -@property (nonatomic) ASDisplayNode *containerNode; @end @@ -110,9 +117,7 @@ @implementation ASAccessibilityCustomAction - (CGRect)accessibilityFrame { - CGRect accessibilityFrame = [self.containerNode convertRect:self.node.bounds fromNode:self.node]; - accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(accessibilityFrame, self.container); - return accessibilityFrame; + return ASAccessibilityFrameForNode(self.node); } @end @@ -121,19 +126,26 @@ - (CGRect)accessibilityFrame static void CollectUIAccessibilityElementsForNode(ASDisplayNode *node, ASDisplayNode *containerNode, id container, NSMutableArray *elements) { ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray"); - + ASDisplayNodePerformBlockOnEveryNodeBFS(node, ^(ASDisplayNode * _Nonnull currentNode) { // For every subnode that is layer backed or it's supernode has subtree rasterization enabled // we have to create a UIAccessibilityElement as no view for this node exists if (currentNode != containerNode && currentNode.isAccessibilityElement) { - UIAccessibilityElement *accessibilityElement = [ASAccessibilityElement accessibilityElementWithContainer:container node:currentNode containerNode:containerNode]; + UIAccessibilityElement *accessibilityElement = [ASAccessibilityElement accessibilityElementWithContainer:container node:currentNode]; [elements addObject:accessibilityElement]; } }); } -static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, UIView *view, NSMutableArray *elements) { - UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:container containerNode:container]; +static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, UIView *view, + NSMutableArray *elements) { + ASDisplayNodeCAssertNotNil(view, @"Passed in view should not be nil"); + if (view == nil) { + return; + } + UIAccessibilityElement *accessiblityElement = + [ASAccessibilityElement accessibilityElementWithContainer:view + node:container]; NSMutableArray *labeledNodes = [[NSMutableArray alloc] init]; NSMutableArray *actions = [[NSMutableArray alloc] init]; @@ -145,7 +157,7 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, U // value and do not perform the aggregation. BOOL shouldAggregateSubnodeLabels = (container.accessibilityLabel.length == 0) || - (container.accessibilityTraits & InteractiveAccessibilityTraitsMask()); + (container.accessibilityTraits & ASInteractiveAccessibilityTraitsMask()); ASDisplayNode *node = nil; while (!queue.empty()) { @@ -153,20 +165,20 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, U queue.pop(); if (node != container && node.isAccessibilityContainer) { - CollectAccessibilityElementsForContainer(node, view, elements); + UIView *containerView = node.isLayerBacked ? view : node.view; + CollectAccessibilityElementsForContainer(node, containerView, elements); continue; } if (node.accessibilityLabel.length > 0) { - if (node.accessibilityTraits & InteractiveAccessibilityTraitsMask()) { + if (node.accessibilityTraits & ASInteractiveAccessibilityTraitsMask()) { ASAccessibilityCustomAction *action = [[ASAccessibilityCustomAction alloc] initWithName:node.accessibilityLabel target:node selector:@selector(performAccessibilityCustomAction:)]; action.node = node; - action.containerNode = node.supernode; - action.container = node.supernode.view; [actions addObject:action]; + + node.accessibilityCustomAction = action; } else if (node == container || shouldAggregateSubnodeLabels) { - // Even though not surfaced to UIKit, create a non-interactive element for purposes of building sorted aggregated label. - ASAccessibilityElement *nonInteractiveElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:node containerNode:container]; + ASAccessibilityElement *nonInteractiveElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:node]; [labeledNodes addObject:nonInteractiveElement]; } } @@ -178,7 +190,6 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, U SortAccessibilityElements(labeledNodes); -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 if (AS_AVAILABLE_IOS_TVOS(11, 11)) { NSArray *attributedLabels = [labeledNodes valueForKey:@"accessibilityAttributedLabel"]; NSMutableAttributedString *attributedLabel = [NSMutableAttributedString new]; @@ -189,9 +200,7 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, U [attributedLabel appendAttributedString:(NSAttributedString *)obj]; }]; accessiblityElement.accessibilityAttributedLabel = attributedLabel; - } else -#endif - { + } else { NSArray *labels = [labeledNodes valueForKey:@"accessibilityLabel"]; accessiblityElement.accessibilityLabel = [labels componentsJoinedByString:@", "]; } @@ -202,12 +211,30 @@ static void CollectAccessibilityElementsForContainer(ASDisplayNode *container, U [elements addObject:accessiblityElement]; } +/// Check if a view is a subviews of an UIScrollView. This is used to determine whether to enforce that +/// accessibility elements must be on screen +static BOOL recusivelyCheckSuperviewsForScrollView(UIView *view) { + if (!view) { + return NO; + } else if ([view isKindOfClass:[UIScrollView class]]) { + return YES; + } + return recusivelyCheckSuperviewsForScrollView(view.superview); +} + +/// returns YES if this node should be considered "hidden" from the screen reader. +static BOOL nodeIsHiddenFromAcessibility(ASDisplayNode *node) { + return node.isHidden || node.alpha == 0.0 || node.accessibilityElementsHidden; +} + /// Collect all accessibliity elements for a given view and view node -static void CollectAccessibilityElementsForView(UIView *view, NSMutableArray *elements) +static void CollectAccessibilityElements(ASDisplayNode *node, NSMutableArray *elements) { ASDisplayNodeCAssertNotNil(elements, @"Should pass in a NSMutableArray"); - - ASDisplayNode *node = view.asyncdisplaykit_node; + ASDisplayNodeCAssertFalse(node.isLayerBacked); + if (node.isLayerBacked) { + return; + } BOOL anySubNodeIsCollection = (nil != ASDisplayNodeFindFirstNode(node, ^BOOL(ASDisplayNode *nodeToCheck) { @@ -215,24 +242,60 @@ static void CollectAccessibilityElementsForView(UIView *view, NSMutableArray *el ASDynamicCast(nodeToCheck, ASTableNode) != nil; })); + UIView *view = node.view; + + // If we don't have a window, let's just bail out + if (!view.window) { + return; + } + if (node.isAccessibilityContainer && !anySubNodeIsCollection) { CollectAccessibilityElementsForContainer(node, view, elements); return; } - + // Handle rasterize case if (node.rasterizesSubtree) { CollectUIAccessibilityElementsForNode(node, node, view, elements); return; } - for (ASDisplayNode *subnode in node.subnodes) { + if (nodeIsHiddenFromAcessibility(node)) { + return; + } + + // see if one of the subnodes is modal. If it is, then we only need to collect accessibilityElements from that + // node. If more than one subnode is modal, UIKit uses the last view in subviews as the modal view (it appears to + // be based on the index in the subviews array, not the location on screen). Let's do the same. + ASDisplayNode *modalSubnode = nil; + for (ASDisplayNode *subnode in node.subnodes.reverseObjectEnumerator) { + if (subnode.accessibilityViewIsModal) { + modalSubnode = subnode; + break; + } + } + + // If we have a modal subnode, just use that. Otherwise, use all subnodes + NSArray *subnodes = modalSubnode ? @[ modalSubnode ] : node.subnodes; + + for (ASDisplayNode *subnode in subnodes) { + // If a node is hidden or has an alpha of 0.0 we should not include it + if (nodeIsHiddenFromAcessibility(subnode)) { + continue; + } + + // If a subnode is outside of the view's window, exclude it UNLESS it is a subview of an UIScrollView. + // In this case UIKit will return the element even if it is outside of the window or the scrollView's visible rect (contentOffset + contentSize) + CGRect nodeInWindowCoords = [node convertRect:subnode.frame toNode:nil]; + if (!CGRectIntersectsRect(view.window.frame, nodeInWindowCoords) && !recusivelyCheckSuperviewsForScrollView(view)) { + continue; + } + if (subnode.isAccessibilityElement) { - // An accessiblityElement can either be a UIView or a UIAccessibilityElement if (subnode.isLayerBacked) { // No view for layer backed nodes exist. It's necessary to create a UIAccessibilityElement that represents this node - UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode containerNode:node]; + UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode]; [elements addObject:accessiblityElement]; } else { // Accessiblity element is not layer backed just add the view as accessibility element @@ -241,7 +304,7 @@ static void CollectAccessibilityElementsForView(UIView *view, NSMutableArray *el } else if (subnode.isLayerBacked) { // Go down the hierarchy of the layer backed subnode and collect all of the UIAccessibilityElement CollectUIAccessibilityElementsForNode(subnode, node, view, elements); - } else if ([subnode accessibilityElementCount] > 0) { + } else if (subnode.accessibilityElementCount > 0) { // UIView is itself a UIAccessibilityContainer just add it [elements addObject:subnode.view]; } @@ -261,19 +324,25 @@ @implementation _ASDisplayView (UIAccessibilityContainer) - (void)setAccessibilityElements:(NSArray *)accessibilityElements { ASDisplayNodeAssertMainThread(); + // While it looks very strange to ignore the accessibilyElements param and set _accessibilityElements to nil, it is actually on purpose. + // _ASDisplayView's accessibilityElements method will always defer to the node for accessibilityElements when _accessibilityElements is + // nil. Calling setAccessibilityElements on _ASDisplayView is basically clearing the cache and forcing _ASDisplayView to ask the node + // for its accessibilityElements the next time they are requested. _accessibilityElements = nil; } - (NSArray *)accessibilityElements { ASDisplayNodeAssertMainThread(); - + ASDisplayNode *viewNode = self.asyncdisplaykit_node; if (viewNode == nil) { return @[]; } - if (_accessibilityElements == nil || ASActivateExperimentalFeature(ASExperimentalDisableAccessibilityCache)) { + // when items become hidden/visible we have to manually clear the _accessibilityElements in order to get an updated version + // Instead, let's try computing the elements every time and see how badly it affects performance. + if (_accessibilityElements == nil || ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) { _accessibilityElements = [viewNode accessibilityElements]; } return _accessibilityElements; @@ -285,16 +354,52 @@ @implementation ASDisplayNode (AccessibilityInternal) - (NSArray *)accessibilityElements { + // NSObject implements the informal accessibility protocol. This means that all ASDisplayNodes already have an accessibilityElements + // property. If an ASDisplayNode subclass has explicitly set the property, let's use that instead of traversing the node tree to try + // to create the elements automatically + NSArray *elements = [super accessibilityElements]; + if (elements.count) { + return elements; + } + if (!self.isNodeLoaded) { ASDisplayNodeFailAssert(@"Cannot access accessibilityElements since node is not loaded"); return @[]; } NSMutableArray *accessibilityElements = [[NSMutableArray alloc] init]; - CollectAccessibilityElementsForView(self.view, accessibilityElements); + CollectAccessibilityElements(self, accessibilityElements); SortAccessibilityElements(accessibilityElements); return accessibilityElements; } @end +@implementation _ASDisplayView (UIAccessibilityAction) + +- (BOOL)accessibilityActivate { + return [self.asyncdisplaykit_node accessibilityActivate]; +} + +- (void)accessibilityIncrement { + [self.asyncdisplaykit_node accessibilityIncrement]; +} + +- (void)accessibilityDecrement { + [self.asyncdisplaykit_node accessibilityDecrement]; +} + +- (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { + return [self.asyncdisplaykit_node accessibilityScroll:direction]; +} + +- (BOOL)accessibilityPerformEscape { + return [self.asyncdisplaykit_node accessibilityPerformEscape]; +} + +- (BOOL)accessibilityPerformMagicTap { + return [self.asyncdisplaykit_node accessibilityPerformMagicTap]; +} + +@end + #endif diff --git a/Example/Pods/Texture/Source/IGListAdapter+AsyncDisplayKit.mm b/Example/Pods/Texture/Source/IGListAdapter+AsyncDisplayKit.mm index c3e81d3..bcfb246 100644 --- a/Example/Pods/Texture/Source/IGListAdapter+AsyncDisplayKit.mm +++ b/Example/Pods/Texture/Source/IGListAdapter+AsyncDisplayKit.mm @@ -13,8 +13,6 @@ #import #import -#import -#import @implementation IGListAdapter (AsyncDisplayKit) diff --git a/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.h b/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.h index 61bfbf8..23d27b6 100644 --- a/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.h +++ b/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.h @@ -13,7 +13,7 @@ typedef NS_ENUM(NSInteger, ASAbsoluteLayoutSpecSizing) { /** The spec will take up the maximum size possible. */ ASAbsoluteLayoutSpecSizingDefault, - /** Computes a size for the spec that is the union of all childrens' frames. */ + /** Computes a size for the spec that is the union of all children's frames. */ ASAbsoluteLayoutSpecSizingSizeToFit, }; diff --git a/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.mm index 18a3a3a..02b14df 100644 --- a/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASAbsoluteLayoutSpec.mm @@ -12,7 +12,6 @@ #import #import #import -#import #import #pragma mark - ASAbsoluteLayoutSpec diff --git a/Example/Pods/Texture/Source/Layout/ASAsciiArtBoxCreator.mm b/Example/Pods/Texture/Source/Layout/ASAsciiArtBoxCreator.mm index 78eb572..998267b 100644 --- a/Example/Pods/Texture/Source/Layout/ASAsciiArtBoxCreator.mm +++ b/Example/Pods/Texture/Source/Layout/ASAsciiArtBoxCreator.mm @@ -10,7 +10,6 @@ #import #import -#import static const NSUInteger kDebugBoxPadding = 2; diff --git a/Example/Pods/Texture/Source/Layout/ASBackgroundLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASBackgroundLayoutSpec.mm index 31dd754..2de9f49 100644 --- a/Example/Pods/Texture/Source/Layout/ASBackgroundLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASBackgroundLayoutSpec.mm @@ -11,7 +11,6 @@ #import -#import #import static NSUInteger const kForegroundChildIndex = 0; diff --git a/Example/Pods/Texture/Source/Layout/ASCenterLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASCenterLayoutSpec.mm index 107f317..9bf29ea 100644 --- a/Example/Pods/Texture/Source/Layout/ASCenterLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASCenterLayoutSpec.mm @@ -9,8 +9,6 @@ #import -#import - @implementation ASCenterLayoutSpec { ASCenterLayoutSpecCenteringOptions _centeringOptions; diff --git a/Example/Pods/Texture/Source/Layout/ASCornerLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASCornerLayoutSpec.mm index 6663b28..91a1ac8 100644 --- a/Example/Pods/Texture/Source/Layout/ASCornerLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASCornerLayoutSpec.mm @@ -9,7 +9,6 @@ #import #import #import -#import CGPoint as_calculatedCornerOriginIn(CGRect baseFrame, CGSize cornerSize, ASCornerLayoutLocation cornerLocation, CGPoint offset) { diff --git a/Example/Pods/Texture/Source/Layout/ASDimension.h b/Example/Pods/Texture/Source/Layout/ASDimension.h index 0cad40d..ab0717b 100644 --- a/Example/Pods/Texture/Source/Layout/ASDimension.h +++ b/Example/Pods/Texture/Source/Layout/ASDimension.h @@ -27,9 +27,10 @@ ASDISPLAYNODE_INLINE BOOL AS_WARN_UNUSED_RESULT ASIsCGSizeValidForLayout(CGSize return (ASPointsValidForLayout(size.width) && ASPointsValidForLayout(size.height)); } +// Note we want YGUndefined (10E20) to be considered invalid, so we have picked a smaller number than CGFLOAT_MAX/2.0 ASDISPLAYNODE_INLINE BOOL AS_WARN_UNUSED_RESULT ASPointsValidForSize(CGFloat points) { - return ((isnormal(points) || points == 0.0) && points >= 0.0 && points < (FLT_MAX / 2.0)); + return ((isnormal(points) || points == 0.0) && points >= 0.0 && points < 10000000.0); } ASDISPLAYNODE_INLINE BOOL AS_WARN_UNUSED_RESULT ASIsCGSizeValidForSize(CGSize size) @@ -37,9 +38,10 @@ ASDISPLAYNODE_INLINE BOOL AS_WARN_UNUSED_RESULT ASIsCGSizeValidForSize(CGSize si return (ASPointsValidForSize(size.width) && ASPointsValidForSize(size.height)); } +// Note we want YGUndefined (10E20) to be considered invalid, so we have picked a smaller number than CGFLOAT_MAX/2.0 ASDISPLAYNODE_INLINE BOOL ASIsCGPositionPointsValidForLayout(CGFloat points) { - return ((isnormal(points) || points == 0.0) && points < (CGFLOAT_MAX / 2.0)); + return ((isnormal(points) || points == 0.0) && points < 10000000.0); } ASDISPLAYNODE_INLINE BOOL ASIsCGPositionValidForLayout(CGPoint point) @@ -81,7 +83,7 @@ typedef struct { /** * Represents auto as ASDimension */ -AS_EXTERN ASDimension const ASDimensionAuto; +ASDK_EXTERN ASDimension const ASDimensionAuto; /** * Returns a dimension with the specified type and value. @@ -114,7 +116,7 @@ ASOVERLOADABLE ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASDimension ASDimensio * Examples: ASDimensionMake(@"50%") = ASDimensionMake(ASDimensionUnitFraction, 0.5) * ASDimensionMake(@"0.5pt") = ASDimensionMake(ASDimensionUnitPoints, 0.5) */ -ASOVERLOADABLE AS_WARN_UNUSED_RESULT AS_EXTERN ASDimension ASDimensionMake(NSString *dimension); +ASOVERLOADABLE AS_WARN_UNUSED_RESULT ASDK_EXTERN ASDimension ASDimensionMake(NSString *dimension); /** * Returns a dimension with the specified points value. @@ -145,7 +147,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASDimensionEqualToDimension(ASDi /** * Returns a NSString representation of a dimension. */ -AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASDimension(ASDimension dimension); +ASDK_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASDimension(ASDimension dimension); /** * Resolve this dimension to a parent size. @@ -172,7 +174,7 @@ typedef struct { ASDimension height; } ASLayoutSize; -AS_EXTERN ASLayoutSize const ASLayoutSizeAuto; +ASDK_EXTERN ASLayoutSize const ASLayoutSizeAuto; /* * Creates an ASLayoutSize with provided min and max dimensions. @@ -217,12 +219,12 @@ typedef struct { /** * A size range with all dimensions zero. */ -AS_EXTERN ASSizeRange const ASSizeRangeZero; +ASDK_EXTERN ASSizeRange const ASSizeRangeZero; /** * A size range from zero to infinity in both directions. */ -AS_EXTERN ASSizeRange const ASSizeRangeUnconstrained; +ASDK_EXTERN ASSizeRange const ASSizeRangeUnconstrained; /** * Returns whether a size range has > 0.1 max width and max height. @@ -273,7 +275,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT CGSize ASSizeRangeClamp(ASSizeRange s * Intersects another size range. If the other size range does not overlap in either dimension, this size range * "wins" by returning a single point within its own range that is closest to the non-overlapping range. */ -AS_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeIntersect(ASSizeRange sizeRange, ASSizeRange otherSizeRange); +ASDK_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASSizeRangeIntersect(ASSizeRange sizeRange, ASSizeRange otherSizeRange); /** * Returns whether two size ranges are equal in min and max size. @@ -286,7 +288,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASSizeRangeEqualToSizeRange(ASSi /** * Returns a string representation of a size range */ -AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASSizeRange(ASSizeRange sizeRange); +ASDK_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASSizeRange(ASSizeRange sizeRange); #if YOGA @@ -304,9 +306,9 @@ typedef struct { ASDimension all; } ASEdgeInsets; -AS_EXTERN ASEdgeInsets const ASEdgeInsetsZero; +ASDK_EXTERN ASEdgeInsets const ASEdgeInsetsZero; -AS_EXTERN ASEdgeInsets ASEdgeInsetsMake(UIEdgeInsets edgeInsets); +ASDK_EXTERN ASEdgeInsets ASEdgeInsetsMake(UIEdgeInsets edgeInsets); #endif diff --git a/Example/Pods/Texture/Source/Layout/ASDimension.mm b/Example/Pods/Texture/Source/Layout/ASDimension.mm index d1a4246..10af17c 100644 --- a/Example/Pods/Texture/Source/Layout/ASDimension.mm +++ b/Example/Pods/Texture/Source/Layout/ASDimension.mm @@ -11,8 +11,6 @@ #import -#import - #pragma mark - ASDimension ASDimension const ASDimensionAuto = {ASDimensionUnitAuto, 0}; diff --git a/Example/Pods/Texture/Source/Layout/ASDimensionInternal.h b/Example/Pods/Texture/Source/Layout/ASDimensionInternal.h index df8f056..dced2ff 100644 --- a/Example/Pods/Texture/Source/Layout/ASDimensionInternal.h +++ b/Example/Pods/Texture/Source/Layout/ASDimensionInternal.h @@ -77,7 +77,7 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASLayoutElementSizeEqualToLayout /** * Returns a string formatted to contain the data from an ASLayoutElementSize. */ -AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASLayoutElementSize(ASLayoutElementSize size); +ASDK_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASLayoutElementSize(ASLayoutElementSize size); /** * Resolve the given size relative to a parent size and an auto size. @@ -86,7 +86,7 @@ AS_EXTERN AS_WARN_UNUSED_RESULT NSString *NSStringFromASLayoutElementSize(ASLayo * dimension with unit ASDimensionUnitAuto the given autoASSizeRange value will be used. * Based on the calculated exact, min and max size constraints the final size range will be calculated. */ -AS_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASLayoutElementSizeResolveAutoSize(ASLayoutElementSize size, const CGSize parentSize, ASSizeRange autoASSizeRange); +ASDK_EXTERN AS_WARN_UNUSED_RESULT ASSizeRange ASLayoutElementSizeResolveAutoSize(ASLayoutElementSize size, const CGSize parentSize, ASSizeRange autoASSizeRange); /** * Resolve the given size to a parent size. Uses internally ASLayoutElementSizeResolveAutoSize with {INFINITY, INFINITY} as diff --git a/Example/Pods/Texture/Source/Layout/ASInsetLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASInsetLayoutSpec.mm index 450480f..93fd6ee 100644 --- a/Example/Pods/Texture/Source/Layout/ASInsetLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASInsetLayoutSpec.mm @@ -11,7 +11,6 @@ #import -#import #import @interface ASInsetLayoutSpec () diff --git a/Example/Pods/Texture/Source/Layout/ASLayout+IGListKit.h b/Example/Pods/Texture/Source/Layout/ASLayout+IGListDiffKit.h similarity index 52% rename from Example/Pods/Texture/Source/Layout/ASLayout+IGListKit.h rename to Example/Pods/Texture/Source/Layout/ASLayout+IGListDiffKit.h index 6f6753d..34636ef 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayout+IGListKit.h +++ b/Example/Pods/Texture/Source/Layout/ASLayout+IGListDiffKit.h @@ -1,15 +1,15 @@ // -// ASLayout+IGListKit.h +// ASLayout+IGListDiffKit.h // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#if AS_IG_LIST_KIT +#if AS_IG_LIST_DIFF_KIT #import -#import -@interface ASLayout(IGListKit) -@end +#import -#endif // AS_IG_LIST_KIT +@interface ASLayout(IGListDiffKit) +@end +#endif // AS_IG_LIST_DIFF_KIT diff --git a/Example/Pods/Texture/Source/Layout/ASLayout+IGListKit.mm b/Example/Pods/Texture/Source/Layout/ASLayout+IGListDiffKit.mm similarity index 73% rename from Example/Pods/Texture/Source/Layout/ASLayout+IGListKit.mm rename to Example/Pods/Texture/Source/Layout/ASLayout+IGListDiffKit.mm index f9cc139..d6e57b2 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayout+IGListKit.mm +++ b/Example/Pods/Texture/Source/Layout/ASLayout+IGListDiffKit.mm @@ -1,13 +1,13 @@ // -// ASLayout+IGListKit.mm +// ASLayout+IGListDiffKit.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // #import -#if AS_IG_LIST_KIT -#import "ASLayout+IGListKit.h" +#if AS_IG_LIST_DIFF_KIT +#import "ASLayout+IGListDiffKit.h" @interface ASLayout() { @public @@ -15,7 +15,7 @@ @interface ASLayout() { } @end -@implementation ASLayout(IGListKit) +@implementation ASLayout(IGListDiffKit) - (id )diffIdentifier { @@ -27,4 +27,4 @@ - (BOOL)isEqualToDiffableObject:(id )other return [self isEqual:other]; } @end -#endif // AS_IG_LIST_KIT +#endif // AS_IG_LIST_DIFF_KIT diff --git a/Example/Pods/Texture/Source/Layout/ASLayout.h b/Example/Pods/Texture/Source/Layout/ASLayout.h index af4ecd9..44b7de0 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayout.h +++ b/Example/Pods/Texture/Source/Layout/ASLayout.h @@ -14,16 +14,18 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN CGPoint const ASPointNull; // {NAN, NAN} +ASDK_EXTERN CGPoint const ASPointNull; // {NAN, NAN} -AS_EXTERN BOOL ASPointIsNull(CGPoint point); +ASDK_EXTERN BOOL ASPointIsNull(CGPoint point); + +ASDK_EXTERN NSString *const ASThreadDictMaxConstraintSizeKey; /** * Safely calculates the layout of the given root layoutElement by guarding against nil nodes. * @param rootLayoutElement The root node to calculate the layout for. * @param sizeRange The size range to calculate the root layout within. */ -AS_EXTERN ASLayout *ASCalculateRootLayout(id rootLayoutElement, const ASSizeRange sizeRange); +ASDK_EXTERN ASLayout *ASCalculateRootLayout(id rootLayoutElement, const ASSizeRange sizeRange); /** * Safely computes the layout of the given node by guarding against nil nodes. @@ -31,7 +33,7 @@ AS_EXTERN ASLayout *ASCalculateRootLayout(id rootLayoutElement, * @param sizeRange The size range to calculate the node layout within. * @param parentSize The parent size of the node to calculate the layout for. */ -AS_EXTERN ASLayout *ASCalculateLayout(idlayoutElement, const ASSizeRange sizeRange, const CGSize parentSize); +ASDK_EXTERN ASLayout *ASCalculateLayout(idlayoutElement, const ASSizeRange sizeRange, const CGSize parentSize); /** * A node in the layout tree that represents the size and position of the object that created it (ASLayoutElement). diff --git a/Example/Pods/Texture/Source/Layout/ASLayout.mm b/Example/Pods/Texture/Source/Layout/ASLayout.mm index 6da24e5..3979c84 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayout.mm +++ b/Example/Pods/Texture/Source/Layout/ASLayout.mm @@ -13,13 +13,13 @@ #import #import -#import #import #import #import #import -#import + +NSString *const ASThreadDictMaxConstraintSizeKey = @"kASThreadDictMaxConstraintSizeKey"; CGPoint const ASPointNull = {NAN, NAN}; diff --git a/Example/Pods/Texture/Source/Layout/ASLayoutElement.h b/Example/Pods/Texture/Source/Layout/ASLayoutElement.h index c4ba689..000f965 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayoutElement.h +++ b/Example/Pods/Texture/Source/Layout/ASLayoutElement.h @@ -25,13 +25,13 @@ NS_ASSUME_NONNULL_BEGIN /** A constant that indicates that the parent's size is not yet determined in a given dimension. */ -AS_EXTERN CGFloat const ASLayoutElementParentDimensionUndefined; +ASDK_EXTERN CGFloat const ASLayoutElementParentDimensionUndefined; /** A constant that indicates that the parent's size is not yet determined in either dimension. */ -AS_EXTERN CGSize const ASLayoutElementParentSizeUndefined; +ASDK_EXTERN CGSize const ASLayoutElementParentSizeUndefined; /** Type of ASLayoutElement */ -typedef NS_ENUM(NSUInteger, ASLayoutElementType) { +typedef NS_ENUM(unsigned char, ASLayoutElementType) { ASLayoutElementTypeLayoutSpec, ASLayoutElementTypeDisplayNode }; @@ -117,7 +117,7 @@ typedef NS_ENUM(NSUInteger, ASLayoutElementType) { * The base implementation of -layoutThatFits:parentSize: does the following for you: * 1. First, it uses the parentSize parameter to resolve the nodes's size (the one assigned to the size property). * 2. Then, it intersects the resolved size with the constrainedSize parameter. If the two don't intersect, - * constrainedSize wins. This allows a component to always override its childrens' sizes when computing its layout. + * constrainedSize wins. This allows a component to always override its children's sizes when computing its layout. * (The analogy for UIView: you might return a certain size from -sizeThatFits:, but a parent view can always override * that size and set your frame to any size.) * 3. It caches it result for reuse @@ -144,24 +144,24 @@ typedef NS_ENUM(NSUInteger, ASLayoutElementType) { #pragma mark - ASLayoutElementStyle -AS_EXTERN NSString * const ASLayoutElementStyleWidthProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMinWidthProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMaxWidthProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleWidthProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMinWidthProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMaxWidthProperty; -AS_EXTERN NSString * const ASLayoutElementStyleHeightProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMinHeightProperty; -AS_EXTERN NSString * const ASLayoutElementStyleMaxHeightProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleHeightProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMinHeightProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleMaxHeightProperty; -AS_EXTERN NSString * const ASLayoutElementStyleSpacingBeforeProperty; -AS_EXTERN NSString * const ASLayoutElementStyleSpacingAfterProperty; -AS_EXTERN NSString * const ASLayoutElementStyleFlexGrowProperty; -AS_EXTERN NSString * const ASLayoutElementStyleFlexShrinkProperty; -AS_EXTERN NSString * const ASLayoutElementStyleFlexBasisProperty; -AS_EXTERN NSString * const ASLayoutElementStyleAlignSelfProperty; -AS_EXTERN NSString * const ASLayoutElementStyleAscenderProperty; -AS_EXTERN NSString * const ASLayoutElementStyleDescenderProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleSpacingBeforeProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleSpacingAfterProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleFlexGrowProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleFlexShrinkProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleFlexBasisProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleAlignSelfProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleAscenderProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleDescenderProperty; -AS_EXTERN NSString * const ASLayoutElementStyleLayoutPositionProperty; +ASDK_EXTERN NSString * const ASLayoutElementStyleLayoutPositionProperty; @protocol ASLayoutElementStyleDelegate - (void)style:(__kindof ASLayoutElementStyle *)style propertyDidChange:(NSString *)propertyName; diff --git a/Example/Pods/Texture/Source/Layout/ASLayoutElement.mm b/Example/Pods/Texture/Source/Layout/ASLayoutElement.mm index 5a33a11..38d50d6 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayoutElement.mm +++ b/Example/Pods/Texture/Source/Layout/ASLayoutElement.mm @@ -8,14 +8,10 @@ // #import -#import -#import -#import #import -#import #import -#import +using AS::MutexLocker; #if YOGA #import YOGA_HEADER_PATH @@ -44,7 +40,7 @@ - (instancetype)init #if AS_TLS_AVAILABLE -static _Thread_local __unsafe_unretained ASLayoutElementContext *tls_context; +static _Thread_local unowned ASLayoutElementContext *tls_context; void ASLayoutElementPushContext(ASLayoutElementContext *context) { @@ -139,12 +135,19 @@ void ASLayoutElementPopContext() NSString * const ASYogaAspectRatioProperty = @"ASYogaAspectRatioProperty"; #endif -#define ASLayoutElementStyleSetSizeWithScope(x) \ - __instanceLock__.lock(); \ - ASLayoutElementSize newSize = _size.load(); \ - { x } \ - _size.store(newSize); \ - __instanceLock__.unlock(); +#define ASLayoutElementStyleSetSizeWithScope(x) \ + ({ \ + __instanceLock__.lock(); \ + const ASLayoutElementSize oldSize = _size.load(); \ + ASLayoutElementSize newSize = oldSize; \ + {x}; \ + BOOL changed = !ASLayoutElementSizeEqualToLayoutElementSize(oldSize, newSize); \ + if (changed) { \ + _size.store(newSize); \ + } \ + __instanceLock__.unlock(); \ + changed; \ + }) #define ASLayoutElementStyleCallDelegate(propertyName)\ do {\ @@ -153,7 +156,7 @@ void ASLayoutElementPopContext() } while(0) @implementation ASLayoutElementStyle { - ASDN::RecursiveMutex __instanceLock__; + AS::RecursiveMutex __instanceLock__; ASLayoutElementStyleExtensions _extensions; std::atomic _size; @@ -202,9 +205,13 @@ - (instancetype)init { self = [super init]; if (self) { - _size = ASLayoutElementSizeMake(); + std::atomic_init(&_size, ASLayoutElementSizeMake()); + std::atomic_init(&_flexBasis, ASDimensionAuto); #if YOGA _parentAlignStyle = ASStackLayoutAlignItemsNotSet; + std::atomic_init(&_flexDirection, ASStackLayoutDirectionVertical); + std::atomic_init(&_alignItems, ASStackLayoutAlignItemsStretch); + std::atomic_init(&_aspectRatio, static_cast(YGUndefined)); #endif } return self; @@ -236,10 +243,10 @@ - (ASDimension)width - (void)setWidth:(ASDimension)width { - ASLayoutElementStyleSetSizeWithScope({ - newSize.width = width; - }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleWidthProperty); + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.width = width; }); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleWidthProperty); + } } - (ASDimension)height @@ -249,10 +256,10 @@ - (ASDimension)height - (void)setHeight:(ASDimension)height { - ASLayoutElementStyleSetSizeWithScope({ - newSize.height = height; - }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleHeightProperty); + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.height = height; }); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleHeightProperty); + } } - (ASDimension)minWidth @@ -262,10 +269,10 @@ - (ASDimension)minWidth - (void)setMinWidth:(ASDimension)minWidth { - ASLayoutElementStyleSetSizeWithScope({ - newSize.minWidth = minWidth; - }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinWidthProperty); + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.minWidth = minWidth; }); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinWidthProperty); + } } - (ASDimension)maxWidth @@ -275,10 +282,10 @@ - (ASDimension)maxWidth - (void)setMaxWidth:(ASDimension)maxWidth { - ASLayoutElementStyleSetSizeWithScope({ - newSize.maxWidth = maxWidth; - }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxWidthProperty); + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.maxWidth = maxWidth; }); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxWidthProperty); + } } - (ASDimension)minHeight @@ -288,10 +295,10 @@ - (ASDimension)minHeight - (void)setMinHeight:(ASDimension)minHeight { - ASLayoutElementStyleSetSizeWithScope({ - newSize.minHeight = minHeight; - }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinHeightProperty); + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.minHeight = minHeight; }); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinHeightProperty); + } } - (ASDimension)maxHeight @@ -301,10 +308,10 @@ - (ASDimension)maxHeight - (void)setMaxHeight:(ASDimension)maxHeight { - ASLayoutElementStyleSetSizeWithScope({ - newSize.maxHeight = maxHeight; - }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxHeightProperty); + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.maxHeight = maxHeight; }); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxHeightProperty); + } } @@ -312,12 +319,14 @@ - (void)setMaxHeight:(ASDimension)maxHeight - (void)setPreferredSize:(CGSize)preferredSize { - ASLayoutElementStyleSetSizeWithScope({ + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.width = ASDimensionMakeWithPoints(preferredSize.width); newSize.height = ASDimensionMakeWithPoints(preferredSize.height); }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleWidthProperty); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleHeightProperty); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleWidthProperty); + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleHeightProperty); + } } - (CGSize)preferredSize @@ -338,22 +347,26 @@ - (CGSize)preferredSize - (void)setMinSize:(CGSize)minSize { - ASLayoutElementStyleSetSizeWithScope({ + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.minWidth = ASDimensionMakeWithPoints(minSize.width); newSize.minHeight = ASDimensionMakeWithPoints(minSize.height); }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinWidthProperty); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinHeightProperty); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinWidthProperty); + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinHeightProperty); + } } - (void)setMaxSize:(CGSize)maxSize { - ASLayoutElementStyleSetSizeWithScope({ + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.maxWidth = ASDimensionMakeWithPoints(maxSize.width); newSize.maxHeight = ASDimensionMakeWithPoints(maxSize.height); }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxWidthProperty); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxHeightProperty); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxWidthProperty); + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxHeightProperty); + } } - (ASLayoutSize)preferredLayoutSize @@ -364,12 +377,14 @@ - (ASLayoutSize)preferredLayoutSize - (void)setPreferredLayoutSize:(ASLayoutSize)preferredLayoutSize { - ASLayoutElementStyleSetSizeWithScope({ + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.width = preferredLayoutSize.width; newSize.height = preferredLayoutSize.height; }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleWidthProperty); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleHeightProperty); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleWidthProperty); + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleHeightProperty); + } } - (ASLayoutSize)minLayoutSize @@ -380,12 +395,14 @@ - (ASLayoutSize)minLayoutSize - (void)setMinLayoutSize:(ASLayoutSize)minLayoutSize { - ASLayoutElementStyleSetSizeWithScope({ + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.minWidth = minLayoutSize.width; newSize.minHeight = minLayoutSize.height; }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinWidthProperty); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinHeightProperty); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinWidthProperty); + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMinHeightProperty); + } } - (ASLayoutSize)maxLayoutSize @@ -396,20 +413,23 @@ - (ASLayoutSize)maxLayoutSize - (void)setMaxLayoutSize:(ASLayoutSize)maxLayoutSize { - ASLayoutElementStyleSetSizeWithScope({ + BOOL changed = ASLayoutElementStyleSetSizeWithScope({ newSize.maxWidth = maxLayoutSize.width; newSize.maxHeight = maxLayoutSize.height; }); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxWidthProperty); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxHeightProperty); + if (changed) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxWidthProperty); + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleMaxHeightProperty); + } } #pragma mark - ASStackLayoutElement - (void)setSpacingBefore:(CGFloat)spacingBefore { - _spacingBefore.store(spacingBefore); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleSpacingBeforeProperty); + if (_spacingBefore.exchange(spacingBefore) != spacingBefore) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleSpacingBeforeProperty); + } } - (CGFloat)spacingBefore @@ -419,8 +439,9 @@ - (CGFloat)spacingBefore - (void)setSpacingAfter:(CGFloat)spacingAfter { - _spacingAfter.store(spacingAfter); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleSpacingAfterProperty); + if (_spacingAfter.exchange(spacingAfter) != spacingAfter) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleSpacingAfterProperty); + } } - (CGFloat)spacingAfter @@ -430,8 +451,9 @@ - (CGFloat)spacingAfter - (void)setFlexGrow:(CGFloat)flexGrow { - _flexGrow.store(flexGrow); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleFlexGrowProperty); + if (_flexGrow.exchange(flexGrow) != flexGrow) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleFlexGrowProperty); + } } - (CGFloat)flexGrow @@ -441,8 +463,9 @@ - (CGFloat)flexGrow - (void)setFlexShrink:(CGFloat)flexShrink { - _flexShrink.store(flexShrink); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleFlexShrinkProperty); + if (_flexShrink.exchange(flexShrink) != flexShrink) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleFlexShrinkProperty); + } } - (CGFloat)flexShrink @@ -452,8 +475,9 @@ - (CGFloat)flexShrink - (void)setFlexBasis:(ASDimension)flexBasis { - _flexBasis.store(flexBasis); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleFlexBasisProperty); + if (!ASDimensionEqualToDimension(_flexBasis.exchange(flexBasis), flexBasis)) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleFlexBasisProperty); + } } - (ASDimension)flexBasis @@ -463,8 +487,9 @@ - (ASDimension)flexBasis - (void)setAlignSelf:(ASStackLayoutAlignSelf)alignSelf { - _alignSelf.store(alignSelf); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleAlignSelfProperty); + if (_alignSelf.exchange(alignSelf) != alignSelf) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleAlignSelfProperty); + } } - (ASStackLayoutAlignSelf)alignSelf @@ -474,8 +499,9 @@ - (ASStackLayoutAlignSelf)alignSelf - (void)setAscender:(CGFloat)ascender { - _ascender.store(ascender); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleAscenderProperty); + if (_ascender.exchange(ascender) != ascender) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleAscenderProperty); + } } - (CGFloat)ascender @@ -485,8 +511,9 @@ - (CGFloat)ascender - (void)setDescender:(CGFloat)descender { - _descender.store(descender); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleDescenderProperty); + if (_descender.exchange(descender) != descender) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleDescenderProperty); + } } - (CGFloat)descender @@ -498,8 +525,9 @@ - (CGFloat)descender - (void)setLayoutPosition:(CGPoint)layoutPosition { - _layoutPosition.store(layoutPosition); - ASLayoutElementStyleCallDelegate(ASLayoutElementStyleLayoutPositionProperty); + if (!CGPointEqualToPoint(_layoutPosition.exchange(layoutPosition), layoutPosition)) { + ASLayoutElementStyleCallDelegate(ASLayoutElementStyleLayoutPositionProperty); + } } - (CGPoint)layoutPosition @@ -513,7 +541,7 @@ - (void)setLayoutOptionExtensionBool:(BOOL)value atIndex:(int)idx { NSCAssert(idx < kMaxLayoutElementBoolExtensions, @"Setting index outside of max bool extensions space"); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _extensions.boolExtensions[idx] = value; } @@ -521,7 +549,7 @@ - (BOOL)layoutOptionExtensionBoolAtIndex:(int)idx\ { NSCAssert(idx < kMaxLayoutElementBoolExtensions, @"Accessing index outside of max bool extensions space"); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _extensions.boolExtensions[idx]; } @@ -529,7 +557,7 @@ - (void)setLayoutOptionExtensionInteger:(NSInteger)value atIndex:(int)idx { NSCAssert(idx < kMaxLayoutElementStateIntegerExtensions, @"Setting index outside of max integer extensions space"); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _extensions.integerExtensions[idx] = value; } @@ -537,7 +565,7 @@ - (NSInteger)layoutOptionExtensionIntegerAtIndex:(int)idx { NSCAssert(idx < kMaxLayoutElementStateIntegerExtensions, @"Accessing index outside of max integer extensions space"); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _extensions.integerExtensions[idx]; } @@ -545,7 +573,7 @@ - (void)setLayoutOptionExtensionEdgeInsets:(UIEdgeInsets)value atIndex:(int)idx { NSCAssert(idx < kMaxLayoutElementStateEdgeInsetExtensions, @"Setting index outside of max edge insets extensions space"); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _extensions.edgeInsetsExtensions[idx] = value; } @@ -553,7 +581,7 @@ - (UIEdgeInsets)layoutOptionExtensionEdgeInsetsAtIndex:(int)idx { NSCAssert(idx < kMaxLayoutElementStateEdgeInsetExtensions, @"Accessing index outside of max edge insets extensions space"); - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _extensions.edgeInsetsExtensions[idx]; } @@ -787,48 +815,64 @@ - (ASStackLayoutAlignItems)parentAlignStyle { } - (void)setFlexWrap:(YGWrap)flexWrap { - _flexWrap.store(flexWrap); - ASLayoutElementStyleCallDelegate(ASYogaFlexWrapProperty); + if (_flexWrap.exchange(flexWrap) != flexWrap) { + ASLayoutElementStyleCallDelegate(ASYogaFlexWrapProperty); + } } - (void)setFlexDirection:(ASStackLayoutDirection)flexDirection { - _flexDirection.store(flexDirection); - ASLayoutElementStyleCallDelegate(ASYogaFlexDirectionProperty); + if (_flexDirection.exchange(flexDirection) != flexDirection) { + ASLayoutElementStyleCallDelegate(ASYogaFlexDirectionProperty); + } } - (void)setDirection:(YGDirection)direction { - _direction.store(direction); - ASLayoutElementStyleCallDelegate(ASYogaDirectionProperty); + if (_direction.exchange(direction) != direction) { + ASLayoutElementStyleCallDelegate(ASYogaDirectionProperty); + } } - (void)setJustifyContent:(ASStackLayoutJustifyContent)justify { - _justifyContent.store(justify); - ASLayoutElementStyleCallDelegate(ASYogaJustifyContentProperty); + if (_justifyContent.exchange(justify) != justify) { + ASLayoutElementStyleCallDelegate(ASYogaJustifyContentProperty); + } } - (void)setAlignItems:(ASStackLayoutAlignItems)alignItems { - _alignItems.store(alignItems); - ASLayoutElementStyleCallDelegate(ASYogaAlignItemsProperty); + if (_alignItems.exchange(alignItems) != alignItems) { + ASLayoutElementStyleCallDelegate(ASYogaAlignItemsProperty); + } } - (void)setPositionType:(YGPositionType)positionType { - _positionType.store(positionType); - ASLayoutElementStyleCallDelegate(ASYogaPositionTypeProperty); + if (_positionType.exchange(positionType) != positionType) { + ASLayoutElementStyleCallDelegate(ASYogaPositionTypeProperty); + } } +/// TODO: smart compare ASEdgeInsets instead of memory compare. - (void)setPosition:(ASEdgeInsets)position { - _position.store(position); - ASLayoutElementStyleCallDelegate(ASYogaPositionProperty); + ASEdgeInsets oldValue = _position.exchange(position); + if (0 != memcmp(&position, &oldValue, sizeof(ASEdgeInsets))) { + ASLayoutElementStyleCallDelegate(ASYogaPositionProperty); + } } - (void)setMargin:(ASEdgeInsets)margin { - _margin.store(margin); - ASLayoutElementStyleCallDelegate(ASYogaMarginProperty); + ASEdgeInsets oldValue = _margin.exchange(margin); + if (0 != memcmp(&margin, &oldValue, sizeof(ASEdgeInsets))) { + ASLayoutElementStyleCallDelegate(ASYogaMarginProperty); + } } - (void)setPadding:(ASEdgeInsets)padding { - _padding.store(padding); - ASLayoutElementStyleCallDelegate(ASYogaPaddingProperty); + ASEdgeInsets oldValue = _padding.exchange(padding); + if (0 != memcmp(&padding, &oldValue, sizeof(ASEdgeInsets))) { + ASLayoutElementStyleCallDelegate(ASYogaPaddingProperty); + } } - (void)setBorder:(ASEdgeInsets)border { - _border.store(border); - ASLayoutElementStyleCallDelegate(ASYogaBorderProperty); + ASEdgeInsets oldValue = _border.exchange(border); + if (0 != memcmp(&border, &oldValue, sizeof(ASEdgeInsets))) { + ASLayoutElementStyleCallDelegate(ASYogaBorderProperty); + } } - (void)setAspectRatio:(CGFloat)aspectRatio { - _aspectRatio.store(aspectRatio); - ASLayoutElementStyleCallDelegate(ASYogaAspectRatioProperty); + if (_aspectRatio.exchange(aspectRatio) != aspectRatio) { + ASLayoutElementStyleCallDelegate(ASYogaAspectRatioProperty); + } } // private (ASLayoutElementStylePrivate.h) - (void)setParentAlignStyle:(ASStackLayoutAlignItems)style { diff --git a/Example/Pods/Texture/Source/Layout/ASLayoutElementPrivate.h b/Example/Pods/Texture/Source/Layout/ASLayoutElementPrivate.h index cf699f4..bf8c05b 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayoutElementPrivate.h +++ b/Example/Pods/Texture/Source/Layout/ASLayoutElementPrivate.h @@ -22,16 +22,16 @@ AS_SUBCLASSING_RESTRICTED @property (nonatomic) int32_t transitionID; @end -AS_EXTERN int32_t const ASLayoutElementContextInvalidTransitionID; +ASDK_EXTERN int32_t const ASLayoutElementContextInvalidTransitionID; -AS_EXTERN int32_t const ASLayoutElementContextDefaultTransitionID; +ASDK_EXTERN int32_t const ASLayoutElementContextDefaultTransitionID; // Does not currently support nesting – there must be no current context. -AS_EXTERN void ASLayoutElementPushContext(ASLayoutElementContext * context); +ASDK_EXTERN void ASLayoutElementPushContext(ASLayoutElementContext * context); -AS_EXTERN ASLayoutElementContext * _Nullable ASLayoutElementGetCurrentContext(void); +ASDK_EXTERN ASLayoutElementContext * _Nullable ASLayoutElementGetCurrentContext(void); -AS_EXTERN void ASLayoutElementPopContext(void); +ASDK_EXTERN void ASLayoutElementPopContext(void); NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Layout/ASLayoutSpec+Subclasses.mm b/Example/Pods/Texture/Source/Layout/ASLayoutSpec+Subclasses.mm index 17ff53e..fb9daf3 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayoutSpec+Subclasses.mm +++ b/Example/Pods/Texture/Source/Layout/ASLayoutSpec+Subclasses.mm @@ -9,7 +9,6 @@ #import -#import #import #pragma mark - ASNullLayoutSpec diff --git a/Example/Pods/Texture/Source/Layout/ASLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASLayoutSpec.mm index bcec515..6d0ba62 100644 --- a/Example/Pods/Texture/Source/Layout/ASLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASLayoutSpec.mm @@ -14,13 +14,7 @@ #import #import -#import #import -#import - -#import -#import -#import @implementation ASLayoutSpec @@ -62,7 +56,7 @@ - (BOOL)implementsLayoutMethod - (ASLayoutElementStyle *)style { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); if (_style == nil) { _style = [[ASLayoutElementStyle alloc] init]; } @@ -133,7 +127,7 @@ - (void)setChildren:(NSArray> *)children #pragma mark - NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained _Nullable [_Nonnull])buffer count:(NSUInteger)len +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id unowned _Nullable [_Nonnull])buffer count:(NSUInteger)len { return [_childrenArray countByEnumeratingWithState:state objects:buffer count:len]; } @@ -142,11 +136,21 @@ - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state object - (ASTraitCollection *)asyncTraitCollection { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); return [ASTraitCollection traitCollectionWithASPrimitiveTraitCollection:self.primitiveTraitCollection]; } -ASPrimitiveTraitCollectionDefaults +- (ASPrimitiveTraitCollection)primitiveTraitCollection +{ + AS::MutexLocker l(__instanceLock__); + return _primitiveTraitCollection; +} + +- (void)setPrimitiveTraitCollection:(ASPrimitiveTraitCollection)traitCollection +{ + AS::MutexLocker l(__instanceLock__); + _primitiveTraitCollection = traitCollection; +} #pragma mark - ASLayoutElementStyleExtensibility @@ -221,13 +225,13 @@ - (void)_findDuplicatedElementsInSubtreeWithWorkingSet:(NSHashTable #import -#import #import static NSUInteger const kUnderlayChildIndex = 0; diff --git a/Example/Pods/Texture/Source/Layout/ASRatioLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASRatioLayoutSpec.mm index 1580b2a..ceda856 100644 --- a/Example/Pods/Texture/Source/Layout/ASRatioLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASRatioLayoutSpec.mm @@ -15,7 +15,6 @@ #import -#import #import #pragma mark - ASRatioLayoutSpec diff --git a/Example/Pods/Texture/Source/Layout/ASStackLayoutDefines.h b/Example/Pods/Texture/Source/Layout/ASStackLayoutDefines.h index 8a86be1..de05439 100644 --- a/Example/Pods/Texture/Source/Layout/ASStackLayoutDefines.h +++ b/Example/Pods/Texture/Source/Layout/ASStackLayoutDefines.h @@ -10,15 +10,21 @@ #import /** The direction children are stacked in */ -typedef NS_ENUM(NSUInteger, ASStackLayoutDirection) { +typedef NS_ENUM(unsigned char, ASStackLayoutDirection) { /** Children are stacked vertically */ ASStackLayoutDirectionVertical, /** Children are stacked horizontally */ ASStackLayoutDirectionHorizontal, +#if YOGA + /** Children are stacked vertically, but in reverse. Only used by Yoga spec. */ + ASStackLayoutDirectionVerticalReverse, + /** Children are stacked horizontally, but in reverse. Only used by Yoga spec. */ + ASStackLayoutDirectionHorizontalReverse, +#endif }; /** If no children are flexible, how should this spec justify its children in the available space? */ -typedef NS_ENUM(NSUInteger, ASStackLayoutJustifyContent) { +typedef NS_ENUM(unsigned char, ASStackLayoutJustifyContent) { /** On overflow, children overflow out of this spec's bounds on the right/bottom side. On underflow, children are left/top-aligned within this spec's bounds. @@ -52,7 +58,7 @@ typedef NS_ENUM(NSUInteger, ASStackLayoutJustifyContent) { }; /** Orientation of children along cross axis */ -typedef NS_ENUM(NSUInteger, ASStackLayoutAlignItems) { +typedef NS_ENUM(unsigned char, ASStackLayoutAlignItems) { /** Align children to start of cross axis */ ASStackLayoutAlignItemsStart, /** Align children with end of cross axis */ @@ -72,7 +78,7 @@ typedef NS_ENUM(NSUInteger, ASStackLayoutAlignItems) { Each child may override their parent stack's cross axis alignment. @see ASStackLayoutAlignItems */ -typedef NS_ENUM(NSUInteger, ASStackLayoutAlignSelf) { +typedef NS_ENUM(unsigned char, ASStackLayoutAlignSelf) { /** Inherit alignment value from containing stack. */ ASStackLayoutAlignSelfAuto, /** Align to start of cross axis */ @@ -86,13 +92,13 @@ typedef NS_ENUM(NSUInteger, ASStackLayoutAlignSelf) { }; /** Whether children are stacked into a single or multiple lines. */ -typedef NS_ENUM(NSUInteger, ASStackLayoutFlexWrap) { +typedef NS_ENUM(unsigned char, ASStackLayoutFlexWrap) { ASStackLayoutFlexWrapNoWrap, ASStackLayoutFlexWrapWrap, }; /** Orientation of lines along cross axis if there are multiple lines. */ -typedef NS_ENUM(NSUInteger, ASStackLayoutAlignContent) { +typedef NS_ENUM(unsigned char, ASStackLayoutAlignContent) { ASStackLayoutAlignContentStart, ASStackLayoutAlignContentCenter, ASStackLayoutAlignContentEnd, @@ -102,7 +108,7 @@ typedef NS_ENUM(NSUInteger, ASStackLayoutAlignContent) { }; /** Orientation of children along horizontal axis */ -typedef NS_ENUM(NSUInteger, ASHorizontalAlignment) { +typedef NS_ENUM(unsigned char, ASHorizontalAlignment) { /** No alignment specified. Default value */ ASHorizontalAlignmentNone, /** Left aligned */ @@ -122,7 +128,7 @@ typedef NS_ENUM(NSUInteger, ASHorizontalAlignment) { }; /** Orientation of children along vertical axis */ -typedef NS_ENUM(NSUInteger, ASVerticalAlignment) { +typedef NS_ENUM(unsigned char, ASVerticalAlignment) { /** No alignment specified. Default value */ ASVerticalAlignmentNone, /** Top aligned */ diff --git a/Example/Pods/Texture/Source/Layout/ASStackLayoutElement.h b/Example/Pods/Texture/Source/Layout/ASStackLayoutElement.h index 46b263b..10e2d50 100644 --- a/Example/Pods/Texture/Source/Layout/ASStackLayoutElement.h +++ b/Example/Pods/Texture/Source/Layout/ASStackLayoutElement.h @@ -31,14 +31,14 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) CGFloat spacingAfter; /** - * @abstract If the sum of childrens' stack dimensions is less than the minimum size, how much should this component grow? + * @abstract If the sum of children's stack dimensions is less than the minimum size, how much should this component grow? * This value represents the "flex grow factor" and determines how much this component should grow in relation to any * other flexible children. */ @property (nonatomic) CGFloat flexGrow; /** - * @abstract If the sum of childrens' stack dimensions is greater than the maximum size, how much should this component shrink? + * @abstract If the sum of children's stack dimensions is greater than the maximum size, how much should this component shrink? * This value represents the "flex shrink factor" and determines how much this component should shink in relation to * other flexible children. */ diff --git a/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.h b/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.h index 535758a..ccc2084 100644 --- a/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.h +++ b/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.h @@ -27,10 +27,10 @@ NS_ASSUME_NONNULL_BEGIN - Suppose stacking direction is Vertical, min-width=100, max-width=300, min-height=200, max-height=500. - All children are laid out with min-width=100, max-width=300, min-height=0, max-height=INFINITY. - - If the sum of the childrens' heights is less than 200, children with flexGrow are flexed larger. - - If the sum of the childrens' heights is greater than 500, children with flexShrink are flexed smaller. + - If the sum of the children's heights is less than 200, children with flexGrow are flexed larger. + - If the sum of the children's heights is greater than 500, children with flexShrink are flexed smaller. Each child is shrunk by `((sum of heights) - 500)/(number of flexShrink-able children)`. - - If the sum of the childrens' heights is greater than 500 even after flexShrink-able children are flexed, + - If the sum of the children's heights is greater than 500 even after flexShrink-able children are flexed, justifyContent determines how children are laid out. */ @interface ASStackLayoutSpec : ASLayoutSpec diff --git a/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.mm b/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.mm index c7c9f8d..976cc02 100644 --- a/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.mm +++ b/Example/Pods/Texture/Source/Layout/ASStackLayoutSpec.mm @@ -13,14 +13,11 @@ #import #import -#import #import -#import #import #import #import #import -#import @implementation ASStackLayoutSpec @@ -193,6 +190,13 @@ - (void)resolveVerticalAlignment case ASStackLayoutDirectionHorizontal: [result insertObject:@{ (id)kCFNull: @"horizontal" } atIndex:0]; break; +#if YOGA + case ASStackLayoutDirectionVerticalReverse: + case ASStackLayoutDirectionHorizontalReverse: + // Currently not handled. + ASDisplayNodeFailAssert(@"Reverse directions not implemented."); + break; +#endif } return result; diff --git a/Example/Pods/Texture/Source/Layout/ASYogaUtilities.h b/Example/Pods/Texture/Source/Layout/ASYogaUtilities.h index c3d1d82..d5529fc 100644 --- a/Example/Pods/Texture/Source/Layout/ASYogaUtilities.h +++ b/Example/Pods/Texture/Source/Layout/ASYogaUtilities.h @@ -27,22 +27,22 @@ @end // pre-order, depth-first -AS_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); +ASDK_EXTERN void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode *node, void(^block)(ASDisplayNode *node)); #pragma mark - Yoga Type Conversion Helpers -AS_EXTERN YGAlign yogaAlignItems(ASStackLayoutAlignItems alignItems); -AS_EXTERN YGJustify yogaJustifyContent(ASStackLayoutJustifyContent justifyContent); -AS_EXTERN YGAlign yogaAlignSelf(ASStackLayoutAlignSelf alignSelf); -AS_EXTERN YGFlexDirection yogaFlexDirection(ASStackLayoutDirection direction); -AS_EXTERN float yogaFloatForCGFloat(CGFloat value); -AS_EXTERN float yogaDimensionToPoints(ASDimension dimension); -AS_EXTERN float yogaDimensionToPercent(ASDimension dimension); -AS_EXTERN ASDimension dimensionForEdgeWithEdgeInsets(YGEdge edge, ASEdgeInsets insets); - -AS_EXTERN void ASLayoutElementYogaUpdateMeasureFunc(YGNodeRef yogaNode, id layoutElement); -AS_EXTERN float ASLayoutElementYogaBaselineFunc(YGNodeRef yogaNode, const float width, const float height); -AS_EXTERN YGSize ASLayoutElementYogaMeasureFunc(YGNodeRef yogaNode, +ASDK_EXTERN YGAlign yogaAlignItems(ASStackLayoutAlignItems alignItems); +ASDK_EXTERN YGJustify yogaJustifyContent(ASStackLayoutJustifyContent justifyContent); +ASDK_EXTERN YGAlign yogaAlignSelf(ASStackLayoutAlignSelf alignSelf); +ASDK_EXTERN YGFlexDirection yogaFlexDirection(ASStackLayoutDirection direction); +ASDK_EXTERN float yogaFloatForCGFloat(CGFloat value); +ASDK_EXTERN float yogaDimensionToPoints(ASDimension dimension); +ASDK_EXTERN float yogaDimensionToPercent(ASDimension dimension); +ASDK_EXTERN ASDimension dimensionForEdgeWithEdgeInsets(YGEdge edge, ASEdgeInsets insets); + +ASDK_EXTERN void ASLayoutElementYogaUpdateMeasureFunc(YGNodeRef yogaNode, id layoutElement); +ASDK_EXTERN float ASLayoutElementYogaBaselineFunc(YGNodeRef yogaNode, const float width, const float height); +ASDK_EXTERN YGSize ASLayoutElementYogaMeasureFunc(YGNodeRef yogaNode, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode); diff --git a/Example/Pods/Texture/Source/Layout/ASYogaUtilities.mm b/Example/Pods/Texture/Source/Layout/ASYogaUtilities.mm index f0602ed..68beede 100644 --- a/Example/Pods/Texture/Source/Layout/ASYogaUtilities.mm +++ b/Example/Pods/Texture/Source/Layout/ASYogaUtilities.mm @@ -96,7 +96,16 @@ YGAlign yogaAlignSelf(ASStackLayoutAlignSelf alignSelf) YGFlexDirection yogaFlexDirection(ASStackLayoutDirection direction) { - return direction == ASStackLayoutDirectionVertical ? YGFlexDirectionColumn : YGFlexDirectionRow; + switch (direction) { + case ASStackLayoutDirectionVertical: + return YGFlexDirectionColumn; + case ASStackLayoutDirectionVerticalReverse: + return YGFlexDirectionColumnReverse; + case ASStackLayoutDirectionHorizontal: + return YGFlexDirectionRow; + case ASStackLayoutDirectionHorizontalReverse: + return YGFlexDirectionRowReverse; + } } float yogaFloatForCGFloat(CGFloat value) @@ -108,9 +117,9 @@ float yogaFloatForCGFloat(CGFloat value) } } -float cgFloatForYogaFloat(float yogaFloat) +CGFloat cgFloatForYogaFloat(float yogaFloat, CGFloat undefinedDefault) { - return (yogaFloat == YGUndefined) ? CGFLOAT_MAX : yogaFloat; + return YGFloatIsUndefined(yogaFloat) ? undefinedDefault : yogaFloat; } float yogaDimensionToPoints(ASDimension dimension) @@ -204,8 +213,8 @@ YGSize ASLayoutElementYogaMeasureFunc(YGNodeRef yogaNode, float width, YGMeasure id layoutElement = (__bridge id )YGNodeGetContext(yogaNode); ASDisplayNodeCAssert([layoutElement conformsToProtocol:@protocol(ASLayoutElement)], @"Yoga context must be "); - width = cgFloatForYogaFloat(width); - height = cgFloatForYogaFloat(height); + width = cgFloatForYogaFloat(width, CGFLOAT_MAX); + height = cgFloatForYogaFloat(height, CGFLOAT_MAX); ASSizeRange sizeRange; sizeRange.min = CGSizeZero; diff --git a/Example/Pods/Texture/Source/Private/ASBatchFetching.h b/Example/Pods/Texture/Source/Private/ASBatchFetching.h index 15d5a98..fec0c67 100644 --- a/Example/Pods/Texture/Source/Private/ASBatchFetching.h +++ b/Example/Pods/Texture/Source/Private/ASBatchFetching.h @@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN @param velocity The velocity of the scroll view (in points) at the moment the touch was released. @return Whether or not the current state should proceed with batch fetching. */ -AS_EXTERN BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, +ASDK_EXTERN BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, ASScrollDirection scrollDirection, ASScrollDirection scrollableDirections, CGPoint contentOffset, @@ -59,7 +59,7 @@ AS_EXTERN BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView owningNode; - @property (nonatomic, readonly) BOOL shouldUseUIKitCell; @end diff --git a/Example/Pods/Texture/Source/Private/ASCollectionLayout.mm b/Example/Pods/Texture/Source/Private/ASCollectionLayout.mm index d6b27b1..e69baa4 100644 --- a/Example/Pods/Texture/Source/Private/ASCollectionLayout.mm +++ b/Example/Pods/Texture/Source/Private/ASCollectionLayout.mm @@ -338,7 +338,12 @@ + (void)_measureElementsInRect:(CGRect)rect blockingRect:(CGRect)blockingRect la if (NSUInteger count = blockingAttrs.count) { ASDispatchApply(count, queue, 0, ^(size_t i) { UICollectionViewLayoutAttributes *attrs = blockingAttrs[i]; - ASCellNode *node = [elements elementForItemAtIndexPath:attrs.indexPath].node; + ASCellNode *node; + if (attrs.representedElementKind == nil) { + node = [elements elementForItemAtIndexPath:attrs.indexPath].node; + } else { + node = [elements supplementaryElementOfKind:attrs.representedElementKind atIndexPath:attrs.indexPath].node; + } CGSize expectedSize = attrs.frame.size; if (! CGSizeEqualToSize(expectedSize, node.calculatedSize)) { [node layoutThatFits:ASCollectionLayoutElementSizeRangeFromSize(expectedSize)]; @@ -353,7 +358,12 @@ + (void)_measureElementsInRect:(CGRect)rect blockingRect:(CGRect)blockingRect la __strong ASElementMap *strongElements = weakElements; if (strongElements) { UICollectionViewLayoutAttributes *attrs = nonBlockingAttrs[i]; - ASCellNode *node = [elements elementForItemAtIndexPath:attrs.indexPath].node; + ASCellNode *node; + if (attrs.representedElementKind == nil) { + node = [elements elementForItemAtIndexPath:attrs.indexPath].node; + } else { + node = [elements supplementaryElementOfKind:attrs.representedElementKind atIndexPath:attrs.indexPath].node; + } CGSize expectedSize = attrs.frame.size; if (! CGSizeEqualToSize(expectedSize, node.calculatedSize)) { [node layoutThatFits:ASCollectionLayoutElementSizeRangeFromSize(expectedSize)]; diff --git a/Example/Pods/Texture/Source/Private/ASCollectionLayoutCache.mm b/Example/Pods/Texture/Source/Private/ASCollectionLayoutCache.mm index cf09fef..a5d6d11 100644 --- a/Example/Pods/Texture/Source/Private/ASCollectionLayoutCache.mm +++ b/Example/Pods/Texture/Source/Private/ASCollectionLayoutCache.mm @@ -13,8 +13,10 @@ #import #import +using AS::MutexLocker; + @implementation ASCollectionLayoutCache { - ASDN::Mutex __instanceLock__; + AS::Mutex __instanceLock__; /** * The underlying data structure of this cache. @@ -46,7 +48,7 @@ - (ASCollectionLayoutState *)layoutForContext:(ASCollectionLayoutContext *)conte return nil; } - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return [[_map objectForKey:elements] objectForKey:context]; } @@ -57,7 +59,7 @@ - (void)setLayout:(ASCollectionLayoutState *)layout forContext:(ASCollectionLayo return; } - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); auto innerMap = [_map objectForKey:elements]; if (innerMap == nil) { innerMap = [NSMapTable strongToStrongObjectsMapTable]; @@ -73,13 +75,13 @@ - (void)removeLayoutForContext:(ASCollectionLayoutContext *)context return; } - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); [[_map objectForKey:elements] removeObjectForKey:context]; } - (void)removeAllLayouts { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); [_map removeAllObjects]; } diff --git a/Example/Pods/Texture/Source/Private/ASCollectionLayoutDefines.h b/Example/Pods/Texture/Source/Private/ASCollectionLayoutDefines.h index 61a8ac4..6c7ff9d 100644 --- a/Example/Pods/Texture/Source/Private/ASCollectionLayoutDefines.h +++ b/Example/Pods/Texture/Source/Private/ASCollectionLayoutDefines.h @@ -14,6 +14,6 @@ NS_ASSUME_NONNULL_BEGIN -AS_EXTERN ASSizeRange ASSizeRangeForCollectionLayoutThatFitsViewportSize(CGSize viewportSize, ASScrollDirection scrollableDirections) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN ASSizeRange ASSizeRangeForCollectionLayoutThatFitsViewportSize(CGSize viewportSize, ASScrollDirection scrollableDirections) AS_WARN_UNUSED_RESULT; NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Private/ASCollectionViewFlowLayoutInspector.mm b/Example/Pods/Texture/Source/Private/ASCollectionViewFlowLayoutInspector.mm index 8ba41ae..52d341c 100644 --- a/Example/Pods/Texture/Source/Private/ASCollectionViewFlowLayoutInspector.mm +++ b/Example/Pods/Texture/Source/Private/ASCollectionViewFlowLayoutInspector.mm @@ -9,10 +9,9 @@ #import #import -#import #import -#import #import +#import #define kDefaultItemSize CGSizeMake(50, 50) diff --git a/Example/Pods/Texture/Source/Private/ASDispatch.h b/Example/Pods/Texture/Source/Private/ASDispatch.h index e209418..caccf74 100644 --- a/Example/Pods/Texture/Source/Private/ASDispatch.h +++ b/Example/Pods/Texture/Source/Private/ASDispatch.h @@ -16,7 +16,7 @@ * Note: The actual number of threads may be lower than threadCount, if libdispatch * decides the system can't handle it. In reality this rarely happens. */ -AS_EXTERN void ASDispatchApply(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, NS_NOESCAPE void(^work)(size_t i)); +ASDK_EXTERN void ASDispatchApply(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, NS_NOESCAPE void(^work)(size_t i)); /** * Like dispatch_async, but you can set the thread count. 0 means 2*active CPUs. @@ -24,4 +24,4 @@ AS_EXTERN void ASDispatchApply(size_t iterationCount, dispatch_queue_t queue, NS * Note: The actual number of threads may be lower than threadCount, if libdispatch * decides the system can't handle it. In reality this rarely happens. */ -AS_EXTERN void ASDispatchAsync(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, NS_NOESCAPE void(^work)(size_t i)); +ASDK_EXTERN void ASDispatchAsync(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, NS_NOESCAPE void(^work)(size_t i)); diff --git a/Example/Pods/Texture/Source/Private/ASDispatch.mm b/Example/Pods/Texture/Source/Private/ASDispatch.mm index 5c713db..769a918 100644 --- a/Example/Pods/Texture/Source/Private/ASDispatch.mm +++ b/Example/Pods/Texture/Source/Private/ASDispatch.mm @@ -7,6 +7,8 @@ // #import +#import + // Prefer C atomics in this file because ObjC blocks can't capture C++ atomics well. #import @@ -19,6 +21,10 @@ */ void ASDispatchApply(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, NS_NOESCAPE void(^work)(size_t i)) { if (threadCount == 0) { + if (ASActivateExperimentalFeature(ASExperimentalDispatchApply)) { + dispatch_apply(iterationCount, queue, work); + return; + } threadCount = NSProcessInfo.processInfo.activeProcessorCount * 2; } dispatch_group_t group = dispatch_group_create(); diff --git a/Example/Pods/Texture/Source/Private/ASDisplayNode+AsyncDisplay.mm b/Example/Pods/Texture/Source/Private/ASDisplayNode+AsyncDisplay.mm index d473780..fd77a06 100644 --- a/Example/Pods/Texture/Source/Private/ASDisplayNode+AsyncDisplay.mm +++ b/Example/Pods/Texture/Source/Private/ASDisplayNode+AsyncDisplay.mm @@ -10,14 +10,12 @@ #import #import #import -#import #import -#import #import #import #import -#import +using AS::MutexLocker; @interface ASDisplayNode () <_ASDisplayLayerDelegate> @end @@ -210,15 +208,13 @@ - (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchro displayBlock = ^id{ CHECK_CANCELLED_AND_RETURN_NIL(); - - ASGraphicsBeginImageContextWithOptions(bounds.size, opaque, contentsScaleForDisplay); - for (dispatch_block_t block in displayBlocks) { - CHECK_CANCELLED_AND_RETURN_NIL(ASGraphicsEndImageContext()); - block(); - } - - UIImage *image = ASGraphicsGetImageAndEndCurrentContext(); + UIImage *image = ASGraphicsCreateImage(self.primitiveTraitCollection, bounds.size, opaque, contentsScaleForDisplay, nil, isCancelledBlock, ^{ + for (dispatch_block_t block in displayBlocks) { + if (isCancelledBlock()) return; + block(); + } + }); ASDN_DELAY_FOR_DISPLAY(); return image; @@ -227,33 +223,35 @@ - (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchro displayBlock = ^id{ CHECK_CANCELLED_AND_RETURN_NIL(); - if (shouldCreateGraphicsContext) { - ASGraphicsBeginImageContextWithOptions(bounds.size, opaque, contentsScaleForDisplay); - CHECK_CANCELLED_AND_RETURN_NIL( ASGraphicsEndImageContext(); ); - } + __block UIImage *image = nil; + void (^workWithContext)() = ^{ + CGContextRef currentContext = UIGraphicsGetCurrentContext(); + + if (shouldCreateGraphicsContext && !currentContext) { + ASDisplayNodeAssert(NO, @"Failed to create a CGContext (size: %@)", NSStringFromCGSize(bounds.size)); + return; + } + + // For -display methods, we don't have a context, and thus will not call the _willDisplayNodeContentWithRenderingContext or + // _didDisplayNodeContentWithRenderingContext blocks. It's up to the implementation of -display... to do what it needs. + [self __willDisplayNodeContentWithRenderingContext:currentContext drawParameters:drawParameters]; + + if (usesImageDisplay) { // If we are using a display method, we'll get an image back directly. + image = [self.class displayWithParameters:drawParameters isCancelled:isCancelledBlock]; + } else if (usesDrawRect) { // If we're using a draw method, this will operate on the currentContext. + [self.class drawRect:bounds withParameters:drawParameters isCancelled:isCancelledBlock isRasterizing:rasterizing]; + } + + [self __didDisplayNodeContentWithRenderingContext:currentContext image:&image drawParameters:drawParameters backgroundColor:backgroundColor borderWidth:borderWidth borderColor:borderColor]; + ASDN_DELAY_FOR_DISPLAY(); + }; - CGContextRef currentContext = UIGraphicsGetCurrentContext(); - UIImage *image = nil; - - // For -display methods, we don't have a context, and thus will not call the _willDisplayNodeContentWithRenderingContext or - // _didDisplayNodeContentWithRenderingContext blocks. It's up to the implementation of -display... to do what it needs. - [self __willDisplayNodeContentWithRenderingContext:currentContext drawParameters:drawParameters]; - - if (usesImageDisplay) { // If we are using a display method, we'll get an image back directly. - image = [self.class displayWithParameters:drawParameters isCancelled:isCancelledBlock]; - } else if (usesDrawRect) { // If we're using a draw method, this will operate on the currentContext. - [self.class drawRect:bounds withParameters:drawParameters isCancelled:isCancelledBlock isRasterizing:rasterizing]; - } - - [self __didDisplayNodeContentWithRenderingContext:currentContext image:&image drawParameters:drawParameters backgroundColor:backgroundColor borderWidth:borderWidth borderColor:borderColor]; - if (shouldCreateGraphicsContext) { - CHECK_CANCELLED_AND_RETURN_NIL( ASGraphicsEndImageContext(); ); - image = ASGraphicsGetImageAndEndCurrentContext(); + return ASGraphicsCreateImage(self.primitiveTraitCollection, bounds.size, opaque, contentsScaleForDisplay, nil, isCancelledBlock, workWithContext); + } else { + workWithContext(); + return image; } - - ASDN_DELAY_FOR_DISPLAY(); - return image; }; } @@ -261,12 +259,12 @@ - (asyncdisplaykit_async_transaction_operation_block_t)_displayBlockWithAsynchro If we're profiling, wrap the display block with signpost start and end. Color the interval red if cancelled, green otherwise. */ -#if AS_KDEBUG_ENABLE - __unsafe_unretained id ptrSelf = self; +#if AS_SIGNPOST_ENABLE + unowned id ptrSelf = (id)self; displayBlock = ^{ - ASSignpostStartCustom(ASSignpostLayerDisplay, ptrSelf, 0); + ASSignpostStart(LayerDisplay, ptrSelf, "%@", ASObjectDescriptionMakeTiny(ptrSelf)); id result = displayBlock(); - ASSignpostEndCustom(ASSignpostLayerDisplay, ptrSelf, 0, isCancelledBlock() ? ASSignpostColorRed : ASSignpostColorGreen); + ASSignpostEnd(LayerDisplay, ptrSelf, "(%d %d), canceled: %d", (int)bounds.size.width, (int)bounds.size.height, (int)isCancelledBlock()); return result; }; #endif @@ -281,13 +279,15 @@ - (void)__willDisplayNodeContentWithRenderingContext:(CGContextRef)context drawP ASCornerRoundingType cornerRoundingType = _cornerRoundingType; CGFloat cornerRadius = _cornerRadius; ASDisplayNodeContextModifier willDisplayNodeContentWithRenderingContext = _willDisplayNodeContentWithRenderingContext; + CACornerMask maskedCorners = _maskedCorners; __instanceLock__.unlock(); if (cornerRoundingType == ASCornerRoundingTypePrecomposited && cornerRadius > 0.0) { ASDisplayNodeAssert(context == UIGraphicsGetCurrentContext(), @"context is expected to be pushed on UIGraphics stack %@", self); // TODO: This clip path should be removed if we are rasterizing. CGRect boundingBox = CGContextGetClipBoundingBox(context); - [[UIBezierPath bezierPathWithRoundedRect:boundingBox cornerRadius:cornerRadius] addClip]; + CGSize radii = CGSizeMake(cornerRadius, cornerRadius); + [[UIBezierPath bezierPathWithRoundedRect:boundingBox byRoundingCorners:maskedCorners cornerRadii:radii] addClip]; } if (willDisplayNodeContentWithRenderingContext) { @@ -307,6 +307,7 @@ - (void)__didDisplayNodeContentWithRenderingContext:(CGContextRef)context image: CGFloat cornerRadius = _cornerRadius; CGFloat contentsScale = _contentsScaleForDisplay; ASDisplayNodeContextModifier didDisplayNodeContentWithRenderingContext = _didDisplayNodeContentWithRenderingContext; + CACornerMask maskedCorners = _maskedCorners; __instanceLock__.unlock(); if (context != NULL) { @@ -323,7 +324,7 @@ - (void)__didDisplayNodeContentWithRenderingContext:(CGContextRef)context image: bounds.size.height *= contentsScale; CGFloat white = 0.0f, alpha = 0.0f; [backgroundColor getWhite:&white alpha:&alpha]; - ASGraphicsBeginImageContextWithOptions(bounds.size, (alpha == 1.0f), contentsScale); + UIGraphicsBeginImageContextWithOptions(bounds.size, (alpha == 1.0f), contentsScale); [*image drawInRect:bounds]; } else { bounds = CGContextGetClipBoundingBox(context); @@ -332,7 +333,10 @@ - (void)__didDisplayNodeContentWithRenderingContext:(CGContextRef)context image: ASDisplayNodeAssert(UIGraphicsGetCurrentContext(), @"context is expected to be pushed on UIGraphics stack %@", self); UIBezierPath *roundedHole = [UIBezierPath bezierPathWithRect:bounds]; - [roundedHole appendPath:[UIBezierPath bezierPathWithRoundedRect:bounds cornerRadius:cornerRadius * contentsScale]]; + CGSize radii = CGSizeMake(cornerRadius * contentsScale, cornerRadius * contentsScale); + [roundedHole appendPath:[UIBezierPath bezierPathWithRoundedRect:bounds + byRoundingCorners:maskedCorners + cornerRadii:radii]]; roundedHole.usesEvenOddFillRule = YES; UIBezierPath *roundedPath = nil; @@ -353,7 +357,10 @@ - (void)__didDisplayNodeContentWithRenderingContext:(CGContextRef)context image: [roundedPath stroke]; // Won't do anything if borderWidth is 0 and roundedPath is nil. if (*image) { - *image = ASGraphicsGetImageAndEndCurrentContext(); + *image = UIGraphicsGetImageFromCurrentImageContext(); + } + if (context == NULL) { + UIGraphicsEndImageContext(); } } } @@ -462,25 +469,25 @@ - (void)cancelDisplayAsyncLayer:(_ASDisplayLayer *)asyncLayer - (ASDisplayNodeContextModifier)willDisplayNodeContentWithRenderingContext { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _willDisplayNodeContentWithRenderingContext; } - (ASDisplayNodeContextModifier)didDisplayNodeContentWithRenderingContext { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); return _didDisplayNodeContentWithRenderingContext; } - (void)setWillDisplayNodeContentWithRenderingContext:(ASDisplayNodeContextModifier)contextModifier { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _willDisplayNodeContentWithRenderingContext = contextModifier; } - (void)setDidDisplayNodeContentWithRenderingContext:(ASDisplayNodeContextModifier)contextModifier; { - ASDN::MutexLocker l(__instanceLock__); + MutexLocker l(__instanceLock__); _didDisplayNodeContentWithRenderingContext = contextModifier; } diff --git a/Example/Pods/Texture/Source/Private/ASDisplayNode+FrameworkPrivate.h b/Example/Pods/Texture/Source/Private/ASDisplayNode+FrameworkPrivate.h index c8d5476..ce53e79 100644 --- a/Example/Pods/Texture/Source/Private/ASDisplayNode+FrameworkPrivate.h +++ b/Example/Pods/Texture/Source/Private/ASDisplayNode+FrameworkPrivate.h @@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN cancelled below the point they are enabled. They continue to the leaves of the hierarchy. */ -typedef NS_OPTIONS(NSUInteger, ASHierarchyState) +typedef NS_OPTIONS(unsigned char, ASHierarchyState) { /** The node may or may not have a supernode, but no supernode has a special hierarchy-influencing option enabled. */ ASHierarchyStateNormal = 0, @@ -115,11 +115,6 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc #undef HIERARCHY_STATE_DELTA @interface ASDisplayNode () -{ -@protected - ASInterfaceState _interfaceState; - ASHierarchyState _hierarchyState; -} // The view class to use when creating a new display node instance. Defaults to _ASDisplayView. + (Class)viewClass; @@ -159,6 +154,11 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc */ @property (nonatomic) ASHierarchyState hierarchyState; +/** + * Represent the current custom action in representation for the node + */ +@property (nonatomic, weak) UIAccessibilityCustomAction *accessibilityCustomAction; + /** * @abstract Return if the node is range managed or not * @@ -174,7 +174,7 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc * @abstract Ensure that all rendering is complete for this node and its descendants. * * @discussion Calling this method on the main thread after a node is added to the view hierarchy will ensure that - * placeholder states are never visible to the user. It is used by ASTableView, ASCollectionView, and ASViewController + * placeholder states are never visible to the user. It is used by ASTableView, ASCollectionView, and ASDKViewController * to implement their respective ".neverShowPlaceholders" option. * * If all nodes have layer.contents set and/or their layer does not have -needsDisplay set, the method will return immediately. @@ -242,10 +242,10 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc /** * @abstract Indicates if this node is a view controller's root node. Defaults to NO. * - * @discussion Set to YES in -[ASViewController initWithNode:]. + * @discussion Set to YES in -[ASDKViewController initWithNode:]. * - * YES here only means that this node is used as an ASViewController node. It doesn't mean that this node is a root of - * ASDisplayNode hierarchy, e.g. when its view controller is parented by another ASViewController. + * YES here only means that this node is used as an ASDKViewController node. It doesn't mean that this node is a root of + * ASDisplayNode hierarchy, e.g. when its view controller is parented by another ASDKViewController. */ @property (nonatomic, getter=isViewControllerRoot) BOOL viewControllerRoot; @@ -312,6 +312,14 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc @end +/** + * Defines interactive accessibility traits which will be exposed as UIAccessibilityCustomActions + * for nodes within nodes that have isAccessibilityContainer is YES + */ +NS_INLINE UIAccessibilityTraits ASInteractiveAccessibilityTraitsMask() { + return UIAccessibilityTraitLink | UIAccessibilityTraitKeyboardKey | UIAccessibilityTraitButton; +} + @interface ASDisplayNode (AccessibilityInternal) - (NSArray *)accessibilityElements; @end; diff --git a/Example/Pods/Texture/Source/Private/ASDisplayNode+UIViewBridge.mm b/Example/Pods/Texture/Source/Private/ASDisplayNode+UIViewBridge.mm index 5107410..42dbbfc 100644 --- a/Example/Pods/Texture/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Example/Pods/Texture/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -7,12 +7,12 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // +#import #import #import #import #import #import -#import #import /** @@ -34,8 +34,8 @@ #define DISPLAYNODE_USE_LOCKS 1 #if DISPLAYNODE_USE_LOCKS -#define _bridge_prologue_read ASDN::MutexLocker l(__instanceLock__); ASDisplayNodeAssertThreadAffinity(self) -#define _bridge_prologue_write ASDN::MutexLocker l(__instanceLock__) +#define _bridge_prologue_read AS::MutexLocker l(__instanceLock__); ASDisplayNodeAssertThreadAffinity(self) +#define _bridge_prologue_write AS::MutexLocker l(__instanceLock__) #else #define _bridge_prologue_read ASDisplayNodeAssertThreadAffinity(self) #define _bridge_prologue_write @@ -127,32 +127,58 @@ - (UIView *)preferredFocusedView - (BOOL)canBecomeFirstResponder { - ASDisplayNodeAssertMainThread(); - return [self __canBecomeFirstResponder]; + if (_view == nil) { + // By default we return NO if not view is created yet + return NO; + } + return [_view canBecomeFirstResponder]; } -- (BOOL)canResignFirstResponder +- (BOOL)becomeFirstResponder { ASDisplayNodeAssertMainThread(); - return [self __canResignFirstResponder]; + + // Note: This implicitly loads the view if it hasn't been loaded yet. + [self view]; + + if (![self canBecomeFirstResponder]) { + return NO; + } + return [_view becomeFirstResponder]; } -- (BOOL)isFirstResponder +- (BOOL)canResignFirstResponder { ASDisplayNodeAssertMainThread(); - return [self __isFirstResponder]; + + if (_view == nil) { + // By default we return YES if no view is created yet + return YES; + } + return [_view canResignFirstResponder]; } -- (BOOL)becomeFirstResponder +- (BOOL)resignFirstResponder { ASDisplayNodeAssertMainThread(); - return [self __becomeFirstResponder]; + + // Note: This implicitly loads the view if it hasn't been loaded yet. + [self view]; + + if (![self canResignFirstResponder]) { + return NO; + } + return [_view resignFirstResponder]; } -- (BOOL)resignFirstResponder +- (BOOL)isFirstResponder { ASDisplayNodeAssertMainThread(); - return [self __resignFirstResponder]; + if (_view == nil) { + // If no view is created yet we can just return NO as it's unlikely it's the first responder + return NO; + } + return [_view isFirstResponder]; } - (BOOL)canPerformAction:(SEL)action withSender:(id)sender @@ -175,24 +201,39 @@ - (void)setAlpha:(CGFloat)newAlpha - (CGFloat)cornerRadius { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); return _cornerRadius; } - (void)setCornerRadius:(CGFloat)newCornerRadius { - [self updateCornerRoundingWithType:self.cornerRoundingType cornerRadius:newCornerRadius]; + [self updateCornerRoundingWithType:self.cornerRoundingType + cornerRadius:newCornerRadius + maskedCorners:self.maskedCorners]; } - (ASCornerRoundingType)cornerRoundingType { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); return _cornerRoundingType; } - (void)setCornerRoundingType:(ASCornerRoundingType)newRoundingType { - [self updateCornerRoundingWithType:newRoundingType cornerRadius:self.cornerRadius]; + [self updateCornerRoundingWithType:newRoundingType cornerRadius:self.cornerRadius maskedCorners:self.maskedCorners]; +} + +- (CACornerMask)maskedCorners +{ + AS::MutexLocker l(__instanceLock__); + return _maskedCorners; +} + +- (void)setMaskedCorners:(CACornerMask)newMaskedCorners +{ + [self updateCornerRoundingWithType:self.cornerRoundingType + cornerRadius:self.cornerRadius + maskedCorners:newMaskedCorners]; } - (NSString *)contentsGravity @@ -469,17 +510,32 @@ - (void)layoutIfNeeded - (BOOL)isOpaque { _bridge_prologue_read; - return _getFromLayer(opaque); + return _getFromViewOrLayer(opaque, opaque); } + - (void)setOpaque:(BOOL)newOpaque { _bridge_prologue_write; - BOOL shouldApply = ASDisplayNodeShouldApplyBridgedWriteToView(self); if (shouldApply) { + /* + NOTE: The values of `opaque` can be different between a view and layer. + + In debugging on Xcode 11 I saw the following in lldb: + - Initially for a new ASDisplayNode layer.isOpaque and _view.isOpaque are true + - Set the backgroundColor of the node to a valid UIColor + Expected: layer.isOpaque and view.isOpaque would be equal and true + Actual: view.isOpaque is true and layer.isOpaque is now false + + This broke some unit tests for view-backed nodes so I think we need to read directly from the view and can't rely on the layers value at this point. + */ BOOL oldOpaque = _layer.opaque; + if (!_flags.layerBacked) { + oldOpaque = _view.opaque; + _view.opaque = newOpaque; + } _layer.opaque = newOpaque; if (oldOpaque != newOpaque) { [self setNeedsDisplay]; @@ -685,49 +741,92 @@ - (void)setContentMode:(UIViewContentMode)contentMode - (UIColor *)backgroundColor { _bridge_prologue_read; - return [UIColor colorWithCGColor:_getFromLayer(backgroundColor)]; + if (_loaded(self)) { + /* + Note: We can no longer rely simply on the layers backgroundColor value if the color is set directly on `_view` + There is no longer a 1:1 mapping between _view.backgroundColor and _layer.backgroundColor after testing in iOS 13 / Xcode 11 so we should prefer one or the other depending on the backing type for the node (view or layer) + */ + if (_flags.layerBacked) { + return _backgroundColor; + } else { + return _view.backgroundColor; + } + } + return ASDisplayNodeGetPendingState(self).backgroundColor; } - (void)setBackgroundColor:(UIColor *)newBackgroundColor { _bridge_prologue_write; - - CGColorRef newBackgroundCGColor = [newBackgroundColor CGColor]; BOOL shouldApply = ASDisplayNodeShouldApplyBridgedWriteToView(self); - if (shouldApply) { - CGColorRef oldBackgroundCGColor = _layer.backgroundColor; - - BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesHandling(checkFlag(Synchronous), _flags.layerBacked); - if (specialPropertiesHandling) { - _view.backgroundColor = newBackgroundColor; + UIColor *oldBackgroundColor = _backgroundColor; + _backgroundColor = newBackgroundColor; + if (_flags.layerBacked) { + _layer.backgroundColor = _backgroundColor.CGColor; } else { - _layer.backgroundColor = newBackgroundCGColor; + /* + NOTE: Setting to the view and layer individually is necessary. + + As observed in lldb, the view does not appear to immediately propagate background color to the layer and actually clears it's value (`nil`) initially. This was caught by our snapshot tests. + + Given that UIColor / UIView has dynamic capabilties now, we should set directly to the view and make sure that the layers value is consistent here. + + */ + _view.backgroundColor = _backgroundColor; + // Gather the CGColorRef from the view incase there are any changes it might apply to which CGColorRef is returned for dynamic colors + _layer.backgroundColor = _view.backgroundColor.CGColor; } - - if (!CGColorEqualToColor(oldBackgroundCGColor, newBackgroundCGColor)) { + + if (![oldBackgroundColor isEqual:newBackgroundColor]) { [self setNeedsDisplay]; } } else { // NOTE: If we're in the background, we cannot read the current value of bgcolor (if loaded). // When the pending state is applied to the view on main, we will call `setNeedsDisplay` if // the new background color doesn't match the one on the layer. - ASDisplayNodeGetPendingState(self).backgroundColor = newBackgroundCGColor; + _backgroundColor = newBackgroundColor; + ASDisplayNodeGetPendingState(self).backgroundColor = newBackgroundColor; } } - (UIColor *)tintColor { - _bridge_prologue_read; - ASDisplayNodeAssert(!_flags.layerBacked, @"Danger: this property is undefined on layer-backed nodes."); - return _getFromViewOnly(tintColor); + __instanceLock__.lock(); + UIColor *retVal = nil; + BOOL shouldAscend = NO; + if (_flags.layerBacked) { + retVal = _tintColor; + // The first nondefault tint color value in the node’s hierarchy, ascending from and starting with the node itself. + shouldAscend = (retVal == nil); + } else { + ASDisplayNodeAssertThreadAffinity(self); + retVal = _getFromViewOnly(tintColor); + } + __instanceLock__.unlock(); + return shouldAscend ? self.supernode.tintColor : retVal; } - (void)setTintColor:(UIColor *)color { - _bridge_prologue_write; - ASDisplayNodeAssert(!_flags.layerBacked, @"Danger: this property is undefined on layer-backed nodes."); - _setToViewOnly(tintColor, color); + // Handle locking manually since we unlock to notify subclasses when tint color changes + __instanceLock__.lock(); + if (_flags.layerBacked) { + if (![_tintColor isEqual:color]) { + _tintColor = color; + + if (_loaded(self)) { + // Tint color has changed. Unlock here before calling subclasses and exit-early + __instanceLock__.unlock(); + [self tintColorDidChange]; + return; + } + } + } else { + _tintColor = color; + _setToViewOnly(tintColor, color); + } + __instanceLock__.unlock(); } - (void)tintColorDidChange @@ -831,13 +930,13 @@ - (void)setAllowsEdgeAntialiasing:(BOOL)allowsEdgeAntialiasing _setToLayer(allowsEdgeAntialiasing, allowsEdgeAntialiasing); } -- (unsigned int)edgeAntialiasingMask +- (CAEdgeAntialiasingMask)edgeAntialiasingMask { _bridge_prologue_read; return _getFromLayer(edgeAntialiasingMask); } -- (void)setEdgeAntialiasingMask:(unsigned int)edgeAntialiasingMask +- (void)setEdgeAntialiasingMask:(CAEdgeAntialiasingMask)edgeAntialiasingMask { _bridge_prologue_write; _setToLayer(edgeAntialiasingMask, edgeAntialiasingMask); @@ -906,7 +1005,7 @@ - (UIEdgeInsets)safeAreaInsets { _bridge_prologue_read; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (!_flags.layerBacked && _loaded(self)) { return self.view.safeAreaInsets; } @@ -928,9 +1027,9 @@ - (void)setInsetsLayoutMarginsFromSafeArea:(BOOL)insetsLayoutMarginsFromSafeArea { _bridge_prologue_write; - _fallbackInsetsLayoutMarginsFromSafeArea = insetsLayoutMarginsFromSafeArea; + _flags.fallbackInsetsLayoutMarginsFromSafeArea = insetsLayoutMarginsFromSafeArea; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (!_flags.layerBacked) { _setToViewOnly(insetsLayoutMarginsFromSafeArea, insetsLayoutMarginsFromSafeArea); } @@ -944,6 +1043,18 @@ - (void)setInsetsLayoutMarginsFromSafeArea:(BOOL)insetsLayoutMarginsFromSafeArea } } +- (NSDictionary> *)actions +{ + _bridge_prologue_read; + return _getFromLayer(actions); +} + +- (void)setActions:(NSDictionary> *)actions +{ + _bridge_prologue_write; + _setToLayer(actions, actions); +} + - (void)safeAreaInsetsDidChange { ASDisplayNodeAssertMainThread(); @@ -971,15 +1082,36 @@ - (void)setLayerCornerRadius:(CGFloat)newLayerCornerRadius _setToLayer(cornerRadius, newLayerCornerRadius); } +- (CACornerMask)layerMaskedCorners +{ + _bridge_prologue_read; + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { + return _getFromLayer(maskedCorners); + } else { + return kASCACornerAllCorners; + } +} + +- (void)setLayerMaskedCorners:(CACornerMask)newLayerMaskedCorners +{ + _bridge_prologue_write; + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { + _setToLayer(maskedCorners, newLayerMaskedCorners); + } else { + ASDisplayNodeAssert(newLayerMaskedCorners == kASCACornerAllCorners, + @"Cannot change maskedCorners property in iOS < 11 while using DefaultSlowCALayer rounding."); + } +} + - (BOOL)_locked_insetsLayoutMarginsFromSafeArea { DISABLED_ASAssertLocked(__instanceLock__); - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (!_flags.layerBacked) { return _getFromViewOnly(insetsLayoutMarginsFromSafeArea); } } - return _fallbackInsetsLayoutMarginsFromSafeArea; + return _flags.fallbackInsetsLayoutMarginsFromSafeArea; } @end @@ -1005,23 +1137,32 @@ - (BOOL)_locked_insetsLayoutMarginsFromSafeArea @implementation ASDisplayNode (UIViewBridgeAccessibility) -// iOS 11 only properties. Add this to silence "unimplemented selector" warnings -// in old SDKs. If the caller doesn't respect our API_AVAILABLE attributes, then they -// get an appropriate "unrecognized selector" runtime error. -#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0 -@dynamic accessibilityAttributedLabel, accessibilityAttributedHint, accessibilityAttributedValue; -#endif +// Walks up the view tree to nil out all the cached accsesibilityElements. This is required when changing +// accessibility properties like accessibilityViewIsModal. +- (void)invalidateAccessibilityElements +{ + // If we are not caching accessibilityElements we don't need to do anything here. + if (ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements)) { + return; + } + + // we want to check if we are on the main thread first, since _loaded checks the layer and can only be done on main + if (ASDisplayNodeThreadIsMain() && _loaded(self)) { + self.view.accessibilityElements = nil; + [self.supernode invalidateAccessibilityElements]; + } +} - (BOOL)isAccessibilityElement { _bridge_prologue_read; - return _getAccessibilityFromViewOrProperty(_isAccessibilityElement, isAccessibilityElement); + return _getAccessibilityFromViewOrProperty(_flags.isAccessibilityElement, isAccessibilityElement); } - (void)setIsAccessibilityElement:(BOOL)isAccessibilityElement { _bridge_prologue_write; - _setAccessibilityToViewAndProperty(_isAccessibilityElement, isAccessibilityElement, isAccessibilityElement, isAccessibilityElement); + _setAccessibilityToViewAndProperty(_flags.isAccessibilityElement, isAccessibilityElement, isAccessibilityElement, isAccessibilityElement); } - (NSString *)accessibilityLabel @@ -1033,16 +1174,25 @@ - (NSString *)accessibilityLabel - (void)setAccessibilityLabel:(NSString *)accessibilityLabel { _bridge_prologue_write; + NSString *oldAccessibilityLabel = _getFromViewOnly(accessibilityLabel); _setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityLabel, accessibilityLabel, accessibilityLabel); -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 if (AS_AVAILABLE_IOS_TVOS(11, 11)) { NSAttributedString *accessibilityAttributedLabel = accessibilityLabel ? [[NSAttributedString alloc] initWithString:accessibilityLabel] : nil; _setAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel); } -#endif + + // We need to update action name when it's changed to reflect the latest state. + // Note: Update the custom action itself won't work when a11y is inside a list of custom actions + // in which one action results in a name change in the next action. In that case the UIAccessibility + // will hold the old action strongly until a11y jumps out of the list of custom actions. + // Thus we can only update name in place to have the change take effect. + BOOL needsUpdateActionName = self.isNodeLoaded && ![oldAccessibilityLabel isEqualToString:accessibilityLabel] && (0 != (_accessibilityTraits & ASInteractiveAccessibilityTraitsMask())); + if (needsUpdateActionName) { + self.accessibilityCustomAction.name = accessibilityLabel; + } } -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + - (NSAttributedString *)accessibilityAttributedLabel { _bridge_prologue_read; @@ -1055,7 +1205,6 @@ - (void)setAccessibilityAttributedLabel:(NSAttributedString *)accessibilityAttri { _setAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel); } { _setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityAttributedLabel.string, accessibilityLabel, accessibilityAttributedLabel.string); } } -#endif - (NSString *)accessibilityHint { @@ -1067,15 +1216,12 @@ - (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_TVOS(11, 11)) { NSAttributedString *accessibilityAttributedHint = accessibilityHint ? [[NSAttributedString alloc] initWithString:accessibilityHint] : nil; _setAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint, accessibilityAttributedHint); } -#endif } -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - (NSAttributedString *)accessibilityAttributedHint { _bridge_prologue_read; @@ -1089,7 +1235,6 @@ - (void)setAccessibilityAttributedHint:(NSAttributedString *)accessibilityAttrib { _setAccessibilityToViewAndProperty(_accessibilityHint, accessibilityAttributedHint.string, accessibilityHint, accessibilityAttributedHint.string); } } -#endif - (NSString *)accessibilityValue { @@ -1101,15 +1246,12 @@ - (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_TVOS(11, 11)) { NSAttributedString *accessibilityAttributedValue = accessibilityValue ? [[NSAttributedString alloc] initWithString:accessibilityValue] : nil; _setAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue); } -#endif } -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 - (NSAttributedString *)accessibilityAttributedValue { _bridge_prologue_read; @@ -1122,7 +1264,6 @@ - (void)setAccessibilityAttributedValue:(NSAttributedString *)accessibilityAttri { _setAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue, accessibilityAttributedValue); } { _setAccessibilityToViewAndProperty(_accessibilityValue, accessibilityAttributedValue.string, accessibilityValue, accessibilityAttributedValue.string); } } -#endif - (UIAccessibilityTraits)accessibilityTraits { @@ -1163,37 +1304,50 @@ - (void)setAccessibilityLanguage:(NSString *)accessibilityLanguage - (BOOL)accessibilityElementsHidden { _bridge_prologue_read; - return _getAccessibilityFromViewOrProperty(_accessibilityElementsHidden, accessibilityElementsHidden); + return _getAccessibilityFromViewOrProperty(_flags.accessibilityElementsHidden, accessibilityElementsHidden); } - (void)setAccessibilityElementsHidden:(BOOL)accessibilityElementsHidden { _bridge_prologue_write; - _setAccessibilityToViewAndProperty(_accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden); + BOOL oldHiddenValue = _getFromViewOnly(accessibilityElementsHidden); + _setAccessibilityToViewAndProperty(_flags.accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden, accessibilityElementsHidden); + + // if we made a change, we need to clear the view's accessibilityElements cache. + if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldHiddenValue != accessibilityElementsHidden) { + [self invalidateAccessibilityElements]; + } } - (BOOL)accessibilityViewIsModal { _bridge_prologue_read; - return _getAccessibilityFromViewOrProperty(_accessibilityViewIsModal, accessibilityViewIsModal); + return _getAccessibilityFromViewOrProperty(_flags.accessibilityViewIsModal, accessibilityViewIsModal); } - (void)setAccessibilityViewIsModal:(BOOL)accessibilityViewIsModal { _bridge_prologue_write; - _setAccessibilityToViewAndProperty(_accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal); + BOOL oldAccessibilityViewIsModal = _getFromViewOnly(accessibilityViewIsModal); + _setAccessibilityToViewAndProperty(_flags.accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal, accessibilityViewIsModal); + + // if we made a change, we need to clear the view's accessibilityElements cache. + if (!ASActivateExperimentalFeature(ASExperimentalDoNotCacheAccessibilityElements) && self.isNodeLoaded && oldAccessibilityViewIsModal != accessibilityViewIsModal) { + [self invalidateAccessibilityElements]; + } } + - (BOOL)shouldGroupAccessibilityChildren { _bridge_prologue_read; - return _getAccessibilityFromViewOrProperty(_shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren); + return _getAccessibilityFromViewOrProperty(_flags.shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren); } - (void)setShouldGroupAccessibilityChildren:(BOOL)shouldGroupAccessibilityChildren { _bridge_prologue_write; - _setAccessibilityToViewAndProperty(_shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren); + _setAccessibilityToViewAndProperty(_flags.shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren, shouldGroupAccessibilityChildren); } - (NSString *)accessibilityIdentifier @@ -1220,6 +1374,18 @@ - (UIAccessibilityNavigationStyle)accessibilityNavigationStyle return _getAccessibilityFromViewOrProperty(_accessibilityNavigationStyle, accessibilityNavigationStyle); } +- (void)setAccessibilityCustomActions:(NSArray *)accessibilityCustomActions +{ + _bridge_prologue_write; + _setAccessibilityToViewAndProperty(_accessibilityCustomActions, accessibilityCustomActions, accessibilityCustomActions, accessibilityCustomActions); +} + +- (NSArray *)accessibilityCustomActions +{ + _bridge_prologue_read; + return _getAccessibilityFromViewOrProperty(_accessibilityCustomActions, accessibilityCustomActions); +} + #if TARGET_OS_TV - (void)setAccessibilityHeaderElements:(NSArray *)accessibilityHeaderElements { diff --git a/Example/Pods/Texture/Source/Private/ASDisplayNodeInternal.h b/Example/Pods/Texture/Source/Private/ASDisplayNodeInternal.h index f030db6..22f3648 100644 --- a/Example/Pods/Texture/Source/Private/ASDisplayNodeInternal.h +++ b/Example/Pods/Texture/Source/Private/ASDisplayNodeInternal.h @@ -15,6 +15,7 @@ #import #import #import +#import #import #import #import @@ -35,7 +36,7 @@ BOOL ASDisplayNodeNeedsSpecialPropertiesHandling(BOOL isSynchronous, BOOL isLaye /// Get the pending view state for the node, creating one if needed. _ASPendingState * ASDisplayNodeGetPendingState(ASDisplayNode * node); -typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) +typedef NS_OPTIONS(unsigned short, ASDisplayNodeMethodOverrides) { ASDisplayNodeMethodOverrideNone = 0, ASDisplayNodeMethodOverrideTouchesBegan = 1 << 0, @@ -45,11 +46,6 @@ typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) ASDisplayNodeMethodOverrideLayoutSpecThatFits = 1 << 4, ASDisplayNodeMethodOverrideCalcLayoutThatFits = 1 << 5, ASDisplayNodeMethodOverrideCalcSizeThatFits = 1 << 6, - ASDisplayNodeMethodOverrideCanBecomeFirstResponder= 1 << 7, - ASDisplayNodeMethodOverrideBecomeFirstResponder = 1 << 8, - ASDisplayNodeMethodOverrideCanResignFirstResponder= 1 << 9, - ASDisplayNodeMethodOverrideResignFirstResponder = 1 << 10, - ASDisplayNodeMethodOverrideIsFirstResponder = 1 << 11, }; typedef NS_OPTIONS(uint_least32_t, ASDisplayNodeAtomicFlags) @@ -66,25 +62,25 @@ typedef NS_OPTIONS(uint_least32_t, ASDisplayNodeAtomicFlags) #define setFlag(flag, x) (((x ? _atomicFlags.fetch_or(flag) \ : _atomicFlags.fetch_and(~flag)) & flag) != 0) -AS_EXTERN NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification; -AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp; +ASDK_EXTERN NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification; +ASDK_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp; // Allow 2^n increments of begin disabling hierarchy notifications #define VISIBILITY_NOTIFICATIONS_DISABLED_BITS 4 #define TIME_DISPLAYNODE_OPS 0 // If you're using this information frequently, try: (DEBUG || PROFILE) +static constexpr CACornerMask kASCACornerAllCorners = + kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner; #define NUM_CLIP_CORNER_LAYERS 4 -@interface ASDisplayNode () <_ASTransitionContextCompletionDelegate> +@interface ASDisplayNode () <_ASTransitionContextCompletionDelegate, CALayerDelegate> { @package - ASDN::RecursiveMutex __instanceLock__; + AS::RecursiveMutex __instanceLock__; _ASPendingState *_pendingViewState; - ASInterfaceState _pendingInterfaceState; - ASInterfaceState _preExitingInterfaceState; - + UIView *_view; CALayer *_layer; @@ -124,8 +120,39 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest unsigned isInHierarchy:1; unsigned visibilityNotificationsDisabled:VISIBILITY_NOTIFICATIONS_DISABLED_BITS; unsigned isDeallocating:1; + +#if YOGA + unsigned willApplyNextYogaCalculatedLayout:1; +#endif + // Automatically manages subnodes + unsigned automaticallyManagesSubnodes:1; // Main thread only + unsigned placeholderEnabled:1; + // Accessibility support + unsigned isAccessibilityElement:1; + unsigned accessibilityElementsHidden:1; + unsigned accessibilityViewIsModal:1; + unsigned shouldGroupAccessibilityChildren:1; + unsigned isAccessibilityContainer:1; + unsigned fallbackInsetsLayoutMarginsFromSafeArea:1; + unsigned automaticallyRelayoutOnSafeAreaChanges:1; + unsigned automaticallyRelayoutOnLayoutMarginsChanges:1; + unsigned isViewControllerRoot:1; + unsigned hasHadInterfaceStateDelegates:1; } _flags; - + + ASInterfaceState _interfaceState; + ASHierarchyState _hierarchyState; + ASInterfaceState _pendingInterfaceState; + ASInterfaceState _preExitingInterfaceState; + ASCornerRoundingType _cornerRoundingType; + ASDisplayNodePerformanceMeasurementOptions _measurementOptions; + ASDisplayNodeMethodOverrides _methodOverrides; + // Tinting support + UIColor *_tintColor; + + // Dynamic colors support + UIColor *_backgroundColor; + @protected ASDisplayNode * __weak _supernode; NSMutableArray *_subnodes; @@ -140,18 +167,12 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest // This is the desired contentsScale, not the scale at which the layer's contents should be displayed CGFloat _contentsScaleForDisplay; - ASDisplayNodeMethodOverrides _methodOverrides; UIEdgeInsets _hitTestSlop; - -#if ASEVENTLOG_ENABLE - ASEventLog *_eventLog; -#endif - // Layout support ASLayoutElementStyle *_style; - std::atomic _primitiveTraitCollection; + ASPrimitiveTraitCollection _primitiveTraitCollection; // Layout Spec ASLayoutSpecBlock _layoutSpecBlock; @@ -166,9 +187,6 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest ASLayout *_yogaCalculatedLayout; #endif - // Automatically manages subnodes - BOOL _automaticallyManagesSubnodes; // Main thread only - // Layout Transition _ASTransitionContext *_pendingLayoutTransitionContext; NSTimeInterval _defaultLayoutTransitionDuration; @@ -187,7 +205,6 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest // Layout Spec performance measurement - ASDisplayNodePerformanceMeasurementOptions _measurementOptions; NSTimeInterval _layoutSpecTotalTime; NSInteger _layoutSpecNumberOfPasses; NSTimeInterval _layoutComputationTotalTime; @@ -204,7 +221,6 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest // Placeholder support UIImage *_placeholderImage; - BOOL _placeholderEnabled; CALayer *_placeholderLayer; // keeps track of nodes/subnodes that have not finished display, used with placeholders @@ -213,15 +229,14 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest // Corner Radius support CGFloat _cornerRadius; - ASCornerRoundingType _cornerRoundingType; CALayer *_clipCornerLayers[NUM_CLIP_CORNER_LAYERS]; + CACornerMask _maskedCorners; ASDisplayNodeContextModifier _willDisplayNodeContentWithRenderingContext; ASDisplayNodeContextModifier _didDisplayNodeContentWithRenderingContext; // Accessibility support - BOOL _isAccessibilityElement; NSString *_accessibilityLabel; NSAttributedString *_accessibilityAttributedLabel; NSString *_accessibilityHint; @@ -231,26 +246,18 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest UIAccessibilityTraits _accessibilityTraits; CGRect _accessibilityFrame; NSString *_accessibilityLanguage; - BOOL _accessibilityElementsHidden; - BOOL _accessibilityViewIsModal; - BOOL _shouldGroupAccessibilityChildren; NSString *_accessibilityIdentifier; UIAccessibilityNavigationStyle _accessibilityNavigationStyle; + NSArray *_accessibilityCustomActions; NSArray *_accessibilityHeaderElements; CGPoint _accessibilityActivationPoint; UIBezierPath *_accessibilityPath; - BOOL _isAccessibilityContainer; // Safe Area support // These properties are used on iOS 10 and lower, where safe area is not supported by UIKit. UIEdgeInsets _fallbackSafeAreaInsets; - BOOL _fallbackInsetsLayoutMarginsFromSafeArea; - - BOOL _automaticallyRelayoutOnSafeAreaChanges; - BOOL _automaticallyRelayoutOnLayoutMarginsChanges; - BOOL _isViewControllerRoot; #pragma mark - ASDisplayNode (Debugging) @@ -265,7 +272,6 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest #endif /// Fast path: tells whether we've ever had an interface state delegate before. - BOOL _hasHadInterfaceStateDelegates; __weak id _interfaceStateDelegates[AS_MAX_INTERFACE_STATE_DELEGATES]; } @@ -305,16 +311,9 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest - (void)__layout; /** - * Internal method to add / replace / insert subnode and remove from supernode without checking if - * node has automaticallyManagesSubnodes set to YES. + * Internal tree modification methods. */ -- (void)_addSubnode:(ASDisplayNode *)subnode; -- (void)_replaceSubnode:(ASDisplayNode *)oldSubnode withSubnode:(ASDisplayNode *)replacementSubnode; -- (void)_insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)below; -- (void)_insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)above; -- (void)_insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx; - (void)_removeFromSupernodeIfEqualTo:(ASDisplayNode *)supernode; -- (void)_removeFromSupernode; // Private API for helper functions / unit tests. Use ASDisplayNodeDisableHierarchyNotifications() to control this. - (BOOL)__visibilityNotificationsDisabled; @@ -322,21 +321,16 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest - (void)__incrementVisibilityNotificationsDisabled; - (void)__decrementVisibilityNotificationsDisabled; -// Helper methods for UIResponder forwarding -- (BOOL)__canBecomeFirstResponder; -- (BOOL)__becomeFirstResponder; -- (BOOL)__canResignFirstResponder; -- (BOOL)__resignFirstResponder; -- (BOOL)__isFirstResponder; - /// Helper method to summarize whether or not the node run through the display process - (BOOL)_implementsDisplay; /// Display the node's view/layer immediately on the current thread, bypassing the background thread rendering. Will be deprecated. - (void)displayImmediately; -/// Refreshes any precomposited or drawn clip corners, setting up state as required to transition radius or rounding type. -- (void)updateCornerRoundingWithType:(ASCornerRoundingType)newRoundingType cornerRadius:(CGFloat)newCornerRadius; +/// Refreshes any precomposited or drawn clip corners, setting up state as required to transition corner config. +- (void)updateCornerRoundingWithType:(ASCornerRoundingType)newRoundingType + cornerRadius:(CGFloat)newCornerRadius + maskedCorners:(CACornerMask)newMaskedCorners; /// Alternative initialiser for backing with a custom view class. Supports asynchronous display with _ASDisplayView subclasses. - (instancetype)initWithViewClass:(Class)viewClass; @@ -355,20 +349,6 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest */ - (void)enumerateInterfaceStateDelegates:(void(NS_NOESCAPE ^)(id delegate))block; -/** - * // TODO: NOT YET IMPLEMENTED - * - * @abstract Prevents interface state changes from affecting the node, until disabled. - * - * @discussion Useful to avoid flashing after removing a node from the hierarchy and re-adding it. - * Removing a node from the hierarchy will cause it to exit the Display state, clearing its contents. - * For some animations, it's desirable to be able to remove a node without causing it to re-display. - * Once re-enabled, the interface state will be updated to the same value it would have been. - * - * @see ASInterfaceState - */ -@property (nonatomic) BOOL interfaceStateSuspended; - /** * This method has proven helpful in a few rare scenarios, similar to a category extension on UIView, * but it's considered private API for now and its use should not be encouraged. @@ -396,6 +376,9 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest @property (nonatomic) CGFloat layerCornerRadius; +/// NOTE: Changing this to non-default under iOS < 11 will make an assertion (for the end user to see.) +@property (nonatomic) CACornerMask layerMaskedCorners; + - (BOOL)_locked_insetsLayoutMarginsFromSafeArea; @end diff --git a/Example/Pods/Texture/Source/Private/ASIGListAdapterBasedDataSource.mm b/Example/Pods/Texture/Source/Private/ASIGListAdapterBasedDataSource.mm index ade87eb..10f51f3 100644 --- a/Example/Pods/Texture/Source/Private/ASIGListAdapterBasedDataSource.mm +++ b/Example/Pods/Texture/Source/Private/ASIGListAdapterBasedDataSource.mm @@ -86,6 +86,21 @@ - (void)collectionNode:(ASCollectionNode *)collectionNode didSelectItemAtIndexPa [self.delegate collectionView:collectionNode.view didSelectItemAtIndexPath:indexPath]; } +- (void)collectionNode:(ASCollectionNode *)collectionNode didDeselectItemAtIndexPath:(NSIndexPath *)indexPath +{ + [self.delegate collectionView:collectionNode.view didDeselectItemAtIndexPath:indexPath]; +} + +- (void)collectionNode:(ASCollectionNode *)collectionNode didHighlightItemAtIndexPath:(NSIndexPath *)indexPath +{ + [self.delegate collectionView:collectionNode.view didHighlightItemAtIndexPath:indexPath]; +} + +- (void)collectionNode:(ASCollectionNode *)collectionNode didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath +{ + [self.delegate collectionView:collectionNode.view didUnhighlightItemAtIndexPath:indexPath]; +} + - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self.delegate scrollViewDidScroll:scrollView]; @@ -147,6 +162,32 @@ - (void)collectionNode:(ASCollectionNode *)collectionNode willBeginBatchFetchWit [ctrl beginBatchFetchWithContext:context]; } +- (void)collectionNode:(ASCollectionNode *)collectionNode willDisplayItemWithNode:(ASCellNode *)node +{ + NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; + UIView *contentView = node.view.superview; + UICollectionViewCell *cell = (UICollectionViewCell *)contentView.superview; + + if (cell == nil || indexPath == nil) { + return; + } + + [self.delegate collectionView:collectionNode.view willDisplayCell:cell forItemAtIndexPath:indexPath]; +} + +- (void)collectionNode:(ASCollectionNode *)collectionNode didEndDisplayingItemWithNode:(ASCellNode *)node +{ + NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; + UIView *contentView = node.view.superview; + UICollectionViewCell *cell = (UICollectionViewCell *)contentView.superview; + + if (cell == nil || indexPath == nil) { + return; + } + + [self.delegate collectionView:collectionNode.view didEndDisplayingCell:cell forItemAtIndexPath:indexPath]; +} + /** * Note: It is not documented that ASCollectionNode will forward these UIKit delegate calls if they are implemented. * It is not considered harmful to do so, and adding them to documentation will confuse most users, who should @@ -215,12 +256,16 @@ - (NSInteger)numberOfSectionsInCollectionNode:(ASCollectionNode *)collectionNode - (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath { - return [[self sectionControllerForSection:indexPath.section] nodeBlockForItemAtIndex:indexPath.item]; + ASIGSectionController *ctrl = [self sectionControllerForSection:indexPath.section]; + ASDisplayNodeAssert([ctrl respondsToSelector:@selector(nodeBlockForItemAtIndex:)], @"Expected section controller to respond to to %@. Controller: %@", NSStringFromSelector(@selector(nodeBlockForItemAtIndex:)), ctrl); + return [ctrl nodeBlockForItemAtIndex:indexPath.item]; } - (ASCellNode *)collectionNode:(ASCollectionNode *)collectionNode nodeForItemAtIndexPath:(NSIndexPath *)indexPath { - return [[self sectionControllerForSection:indexPath.section] nodeForItemAtIndex:indexPath.item]; + ASIGSectionController *ctrl = [self sectionControllerForSection:indexPath.section]; + ASDisplayNodeAssert([ctrl respondsToSelector:@selector(nodeForItemAtIndex:)], @"Expected section controller to respond to to %@. Controller: %@", NSStringFromSelector(@selector(nodeForItemAtIndex:)), ctrl); + return [ctrl nodeForItemAtIndex:indexPath.item]; } - (ASSizeRange)collectionNode:(ASCollectionNode *)collectionNode constrainedSizeForItemAtIndexPath:(NSIndexPath *)indexPath @@ -235,12 +280,16 @@ - (ASSizeRange)collectionNode:(ASCollectionNode *)collectionNode constrainedSize - (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { - return [[self supplementaryElementSourceForSection:indexPath.section] nodeBlockForSupplementaryElementOfKind:kind atIndex:indexPath.item]; + id ctrl = [self supplementaryElementSourceForSection:indexPath.section]; + ASDisplayNodeAssert([ctrl respondsToSelector:@selector(nodeBlockForSupplementaryElementOfKind:atIndex:)], @"Expected section controller to respond to to %@. Controller: %@", NSStringFromSelector(@selector(nodeBlockForSupplementaryElementOfKind:atIndex:)), ctrl); + return [ctrl nodeBlockForSupplementaryElementOfKind:kind atIndex:indexPath.item]; } - (ASCellNode *)collectionNode:(ASCollectionNode *)collectionNode nodeForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { - return [[self supplementaryElementSourceForSection:indexPath.section] nodeForSupplementaryElementOfKind:kind atIndex:indexPath.item]; + id ctrl = [self supplementaryElementSourceForSection:indexPath.section]; + ASDisplayNodeAssert([ctrl respondsToSelector:@selector(nodeForSupplementaryElementOfKind:atIndex:)], @"Expected section controller to respond to to %@. Controller: %@", NSStringFromSelector(@selector(nodeForSupplementaryElementOfKind:atIndex:)), ctrl); + return [ctrl nodeForSupplementaryElementOfKind:kind atIndex:indexPath.item]; } - (NSArray *)collectionNode:(ASCollectionNode *)collectionNode supplementaryElementKindsInSection:(NSInteger)section diff --git a/Example/Pods/Texture/Source/Private/ASImageNode+AnimatedImagePrivate.h b/Example/Pods/Texture/Source/Private/ASImageNode+AnimatedImagePrivate.h index 39368c7..917eb6f 100644 --- a/Example/Pods/Texture/Source/Private/ASImageNode+AnimatedImagePrivate.h +++ b/Example/Pods/Texture/Source/Private/ASImageNode+AnimatedImagePrivate.h @@ -13,9 +13,8 @@ @interface ASImageNode () { - ASDN::Mutex _displayLinkLock; + AS::Mutex _displayLinkLock; id _animatedImage; - BOOL _animatedImagePaused; NSString *_animatedImageRunLoopMode; CADisplayLink *_displayLink; NSUInteger _lastSuccessfulFrameIndex; @@ -23,6 +22,14 @@ //accessed on main thread only CFTimeInterval _playHead; NSUInteger _playedLoops; + + // Group the BOOLs into a bitfield struct to save memory. + struct { + unsigned int animatedImagePaused:1; + unsigned int cropEnabled:1; // Defaults to YES. + unsigned int forceUpscaling:1; //Defaults to NO. + unsigned int regenerateFromImageAsset:1; //Defaults to NO. + } _imageNodeFlags; } @property (nonatomic) CFTimeInterval lastDisplayLinkFire; diff --git a/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.h b/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.h index 01b5464..dd529a3 100644 --- a/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.h +++ b/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.h @@ -20,7 +20,7 @@ @param forcedSize A CGSize, that if non-CGSizeZero, indicates that the backing size should be forcedSize and not calculated based on boundsSize. @discussion If the image is smaller than the size and UIViewContentModeScaleToAspectFill is specified, we suggest the input size so it will be efficiently upscaled on the GPU by the displaying layer at composite time. */ -AS_EXTERN void ASCroppedImageBackingSizeAndDrawRectInBounds(CGSize sourceImageSize, +ASDK_EXTERN void ASCroppedImageBackingSizeAndDrawRectInBounds(CGSize sourceImageSize, CGSize boundsSize, UIViewContentMode contentMode, CGRect cropRect, diff --git a/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.mm b/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.mm index c4f9fdc..b7550c5 100644 --- a/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.mm +++ b/Example/Pods/Texture/Source/Private/ASImageNode+CGExtras.mm @@ -9,8 +9,6 @@ #import -#import - // TODO rewrite these to be closer to the intended use -- take UIViewContentMode as param, CGRect destinationBounds, CGSize sourceSize. static CGSize _ASSizeFillWithAspectRatio(CGFloat aspectRatio, CGSize constraints); static CGSize _ASSizeFitWithAspectRatio(CGFloat aspectRatio, CGSize constraints); @@ -53,16 +51,17 @@ void ASCroppedImageBackingSizeAndDrawRectInBounds(CGSize sourceImageSize, // Per the API contract as commented in the header, we will adjust input parameters (destinationWidth, destinationHeight) to ensure that the image is not upscaled on the CPU. CGFloat boundsAspectRatio = (CGFloat)destinationWidth / (CGFloat)destinationHeight; - CGSize scaledSizeForImage = sourceImageSize; + CGSize minimumDestinationSize = sourceImageSize; BOOL cropToRectDimensions = !CGRectIsEmpty(cropRect); + // Given image size and container ratio, calculate minimum container size for the image under different contentMode if (cropToRectDimensions) { - scaledSizeForImage = CGSizeMake(boundsSize.width / cropRect.size.width, boundsSize.height / cropRect.size.height); + minimumDestinationSize = CGSizeMake(boundsSize.width / cropRect.size.width, boundsSize.height / cropRect.size.height); } else { if (contentMode == UIViewContentModeScaleAspectFill) - scaledSizeForImage = _ASSizeFillWithAspectRatio(boundsAspectRatio, sourceImageSize); + minimumDestinationSize = _ASSizeFitWithAspectRatio(boundsAspectRatio, sourceImageSize); else if (contentMode == UIViewContentModeScaleAspectFit) - scaledSizeForImage = _ASSizeFitWithAspectRatio(boundsAspectRatio, sourceImageSize); + minimumDestinationSize = _ASSizeFillWithAspectRatio(boundsAspectRatio, sourceImageSize); } // If fitting the desired aspect ratio to the image size actually results in a larger buffer, use the input values. @@ -70,9 +69,9 @@ void ASCroppedImageBackingSizeAndDrawRectInBounds(CGSize sourceImageSize, if (CGSizeEqualToSize(CGSizeZero, forcedSize) == NO) { destinationWidth = (size_t)round(forcedSize.width); destinationHeight = (size_t)round(forcedSize.height); - } else if (forceUpscaling == NO && (scaledSizeForImage.width * scaledSizeForImage.height) < (destinationWidth * destinationHeight)) { - destinationWidth = (size_t)round(scaledSizeForImage.width); - destinationHeight = (size_t)round(scaledSizeForImage.height); + } else if (forceUpscaling == NO && (minimumDestinationSize.width * minimumDestinationSize.height) < (destinationWidth * destinationHeight)) { + destinationWidth = (size_t)round(minimumDestinationSize.width); + destinationHeight = (size_t)round(minimumDestinationSize.height); if (destinationWidth == 0 || destinationHeight == 0) { *outBackingSize = CGSizeZero; *outDrawRect = CGRectZero; @@ -82,39 +81,39 @@ void ASCroppedImageBackingSizeAndDrawRectInBounds(CGSize sourceImageSize, // Figure out the scaled size within the destination bounds. CGFloat sourceImageAspectRatio = sourceImageSize.width / sourceImageSize.height; - CGSize scaledSizeForDestination = CGSizeMake(destinationWidth, destinationHeight); + CGSize scaledSizeForImage = CGSizeMake(destinationWidth, destinationHeight); if (cropToRectDimensions) { - scaledSizeForDestination = CGSizeMake(boundsSize.width / cropRect.size.width, boundsSize.height / cropRect.size.height); + scaledSizeForImage = CGSizeMake(boundsSize.width / cropRect.size.width, boundsSize.height / cropRect.size.height); } else { if (contentMode == UIViewContentModeScaleAspectFill) - scaledSizeForDestination = _ASSizeFillWithAspectRatio(sourceImageAspectRatio, scaledSizeForDestination); + scaledSizeForImage = _ASSizeFillWithAspectRatio(sourceImageAspectRatio, scaledSizeForImage); else if (contentMode == UIViewContentModeScaleAspectFit) - scaledSizeForDestination = _ASSizeFitWithAspectRatio(sourceImageAspectRatio, scaledSizeForDestination); + scaledSizeForImage = _ASSizeFitWithAspectRatio(sourceImageAspectRatio, scaledSizeForImage); } // Figure out the rectangle into which to draw the image. CGRect drawRect = CGRectZero; if (cropToRectDimensions) { - drawRect = CGRectMake(-cropRect.origin.x * scaledSizeForDestination.width, - -cropRect.origin.y * scaledSizeForDestination.height, - scaledSizeForDestination.width, - scaledSizeForDestination.height); + drawRect = CGRectMake(-cropRect.origin.x * scaledSizeForImage.width, + -cropRect.origin.y * scaledSizeForImage.height, + scaledSizeForImage.width, + scaledSizeForImage.height); } else { // We want to obey the origin of cropRect in aspect-fill mode. if (contentMode == UIViewContentModeScaleAspectFill) { - drawRect = CGRectMake(((destinationWidth - scaledSizeForDestination.width) * cropRect.origin.x), - ((destinationHeight - scaledSizeForDestination.height) * cropRect.origin.y), - scaledSizeForDestination.width, - scaledSizeForDestination.height); + drawRect = CGRectMake(((destinationWidth - scaledSizeForImage.width) * cropRect.origin.x), + ((destinationHeight - scaledSizeForImage.height) * cropRect.origin.y), + scaledSizeForImage.width, + scaledSizeForImage.height); } // And otherwise just center it. else { - drawRect = CGRectMake(((destinationWidth - scaledSizeForDestination.width) / 2.0), - ((destinationHeight - scaledSizeForDestination.height) / 2.0), - scaledSizeForDestination.width, - scaledSizeForDestination.height); + drawRect = CGRectMake(((destinationWidth - scaledSizeForImage.width) / 2.0), + ((destinationHeight - scaledSizeForImage.height) / 2.0), + scaledSizeForImage.width, + scaledSizeForImage.height); } } diff --git a/Example/Pods/Texture/Source/Private/ASInternalHelpers.h b/Example/Pods/Texture/Source/Private/ASInternalHelpers.h index e6d3811..69a8eab 100644 --- a/Example/Pods/Texture/Source/Private/ASInternalHelpers.h +++ b/Example/Pods/Texture/Source/Private/ASInternalHelpers.h @@ -12,44 +12,46 @@ #import #import +#import +#import NS_ASSUME_NONNULL_BEGIN -AS_EXTERN void ASInitializeFrameworkMainThread(void); +ASDK_EXTERN void ASInitializeFrameworkMainThread(void); -AS_EXTERN BOOL ASDefaultAllowsGroupOpacity(void); -AS_EXTERN BOOL ASDefaultAllowsEdgeAntialiasing(void); +ASDK_EXTERN BOOL ASDefaultAllowsGroupOpacity(void); +ASDK_EXTERN BOOL ASDefaultAllowsEdgeAntialiasing(void); -AS_EXTERN BOOL ASSubclassOverridesSelector(Class superclass, Class subclass, SEL selector); -AS_EXTERN BOOL ASSubclassOverridesClassSelector(Class superclass, Class subclass, SEL selector); +ASDK_EXTERN BOOL ASSubclassOverridesSelector(Class superclass, Class subclass, SEL selector); +ASDK_EXTERN BOOL ASSubclassOverridesClassSelector(Class superclass, Class subclass, SEL selector); /// Replace a method from the given class with a block and returns the original method IMP -AS_EXTERN IMP ASReplaceMethodWithBlock(Class c, SEL origSEL, id block); +ASDK_EXTERN IMP ASReplaceMethodWithBlock(Class c, SEL origSEL, id block); /// Dispatches the given block to the main queue if not already running on the main thread -AS_EXTERN void ASPerformBlockOnMainThread(void (^block)(void)); +ASDK_EXTERN void ASPerformBlockOnMainThread(void (^block)(void)); /// Dispatches the given block to a background queue with priority of DISPATCH_QUEUE_PRIORITY_DEFAULT if not already run on a background queue -AS_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT +ASDK_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT /// For deallocation of objects on a background thread without GCD overhead / thread explosion -AS_EXTERN void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object); +ASDK_EXTERN void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object); -AS_EXTERN CGFloat ASScreenScale(void); +ASDK_EXTERN CGFloat ASScreenScale(void); -AS_EXTERN CGSize ASFloorSizeValues(CGSize s); +ASDK_EXTERN CGSize ASFloorSizeValues(CGSize s); -AS_EXTERN CGFloat ASFloorPixelValue(CGFloat f); +ASDK_EXTERN CGFloat ASFloorPixelValue(CGFloat f); -AS_EXTERN CGPoint ASCeilPointValues(CGPoint p); +ASDK_EXTERN CGPoint ASCeilPointValues(CGPoint p); -AS_EXTERN CGSize ASCeilSizeValues(CGSize s); +ASDK_EXTERN CGSize ASCeilSizeValues(CGSize s); -AS_EXTERN CGFloat ASCeilPixelValue(CGFloat f); +ASDK_EXTERN CGFloat ASCeilPixelValue(CGFloat f); -AS_EXTERN CGFloat ASRoundPixelValue(CGFloat f); +ASDK_EXTERN CGFloat ASRoundPixelValue(CGFloat f); -AS_EXTERN Class _Nullable ASGetClassFromType(const char * _Nullable type); +ASDK_EXTERN Class _Nullable ASGetClassFromType(const char * _Nullable type); ASDISPLAYNODE_INLINE BOOL ASImageAlphaInfoIsOpaque(CGImageAlphaInfo info) { switch (info) { @@ -95,10 +97,31 @@ ASDISPLAYNODE_INLINE UIEdgeInsets ASConcatInsets(UIEdgeInsets insetsA, UIEdgeIns return insetsA; } +ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT ASImageDownloaderPriority ASImageDownloaderPriorityWithInterfaceState(ASInterfaceState interfaceState) { + if (ASInterfaceStateIncludesVisible(interfaceState)) { + return ASImageDownloaderPriorityVisible; + } + + if (ASInterfaceStateIncludesDisplay(interfaceState)) { + return ASImageDownloaderPriorityImminent; + } + + if (ASInterfaceStateIncludesPreload(interfaceState)) { + return ASImageDownloaderPriorityPreload; + } + + return ASImageDownloaderPriorityPreload; +} + @interface NSIndexPath (ASInverseComparison) - (NSComparisonResult)asdk_inverseCompare:(NSIndexPath *)otherIndexPath; @end +/** + * Create an NSMutableSet that uses pointers for hash & equality. + */ +ASDK_EXTERN NSMutableSet *ASCreatePointerBasedMutableSet(void); + NS_ASSUME_NONNULL_END #ifndef AS_INITIALIZE_FRAMEWORK_MANUALLY diff --git a/Example/Pods/Texture/Source/Private/ASInternalHelpers.mm b/Example/Pods/Texture/Source/Private/ASInternalHelpers.mm index a9926cc..7811c3b 100644 --- a/Example/Pods/Texture/Source/Private/ASInternalHelpers.mm +++ b/Example/Pods/Texture/Source/Private/ASInternalHelpers.mm @@ -9,13 +9,9 @@ #import -#import - -#import -#import - #import #import +#import #import static NSNumber *allowsGroupOpacityFromUIKitOrNil; @@ -43,6 +39,28 @@ BOOL ASDefaultAllowsEdgeAntialiasing() return edgeAntialiasing; } +#if AS_SIGNPOST_ENABLE +void _ASInitializeSignpostObservers(void) +{ + // Orientation changes. Unavailable on tvOS. +#if !TARGET_OS_TV + [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationWillChangeStatusBarOrientationNotification object:nil queue:nil usingBlock:^(NSNotification *note) { + UIInterfaceOrientation orientation = (UIInterfaceOrientation)[note.userInfo[UIApplicationStatusBarOrientationUserInfoKey] integerValue]; + ASSignpostStart(OrientationChange, (id)nil, "from %s", UIInterfaceOrientationIsPortrait(orientation) ? "portrait" : "landscape"); + [CATransaction begin]; + }]; + [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidChangeStatusBarOrientationNotification object:nil queue:nil usingBlock:^(NSNotification *note) { + // When profiling, go ahead and commit the transaction early so that it happens as part of our interval. + UIInterfaceOrientation orientation = (UIInterfaceOrientation)[note.userInfo[UIApplicationStatusBarOrientationUserInfoKey] integerValue]; + [CATransaction setCompletionBlock:^{ + ASSignpostEnd(OrientationChange, (id)nil, "to %s", UIInterfaceOrientationIsPortrait(orientation) ? "portrait" : "landscape"); + }]; + [CATransaction commit]; + }]; +#endif // TARGET_OS_TV +} +#endif // AS_SIGNPOST_ENABLE + void ASInitializeFrameworkMainThread(void) { static dispatch_once_t onceToken; @@ -57,6 +75,9 @@ void ASInitializeFrameworkMainThread(void) allowsEdgeAntialiasingFromUIKitOrNil = @(layer.allowsEdgeAntialiasing); } ASNotifyInitialized(); +#if AS_SIGNPOST_ENABLE + _ASInitializeSignpostObservers(); +#endif }); } @@ -231,3 +252,15 @@ - (NSComparisonResult)asdk_inverseCompare:(NSIndexPath *)otherIndexPath } @end + +NSMutableSet *ASCreatePointerBasedMutableSet() +{ + static CFSetCallBacks callbacks; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + callbacks = kCFTypeSetCallBacks; + callbacks.equal = nullptr; + callbacks.hash = nullptr; + }); + return (__bridge_transfer NSMutableSet *)CFSetCreateMutable(NULL, 0, &callbacks); +} diff --git a/Example/Pods/Texture/Source/Private/ASLayoutTransition.mm b/Example/Pods/Texture/Source/Private/ASLayoutTransition.mm index db9e285..588b275 100644 --- a/Example/Pods/Texture/Source/Private/ASLayoutTransition.mm +++ b/Example/Pods/Texture/Source/Private/ASLayoutTransition.mm @@ -12,16 +12,16 @@ #import #import -#import // Required for _insertSubnode... / _removeFromSupernode. -#import +#import // Required for _removeFromSupernodeIfEqualTo: #import -#if AS_IG_LIST_KIT -#import -#import +#if AS_IG_LIST_DIFF_KIT +#import #endif +using AS::MutexLocker; + /** * Search the whole layout stack if at least one layout has a layoutElement object that can not be layed out asynchronous. * This can be the case for example if a node was already loaded @@ -52,7 +52,7 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) { } @implementation ASLayoutTransition { - std::shared_ptr __instanceLock__; + std::shared_ptr __instanceLock__; BOOL _calculatedSubnodeOperations; NSArray *_insertedSubnodes; @@ -69,7 +69,7 @@ - (instancetype)initWithNode:(ASDisplayNode *)node { self = [super init]; if (self) { - __instanceLock__ = std::make_shared(); + __instanceLock__ = std::make_shared(); _node = node; _pendingLayout = pendingLayout; @@ -80,7 +80,7 @@ - (instancetype)initWithNode:(ASDisplayNode *)node - (BOOL)isSynchronous { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); return !ASLayoutCanTransitionAsynchronous(_pendingLayout.layout); } @@ -92,7 +92,7 @@ - (void)commitTransition - (void)applySubnodeInsertionsAndMoves { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; // Create an activity even if no subnodes affected. @@ -101,7 +101,6 @@ - (void)applySubnodeInsertionsAndMoves return; } - ASDisplayNodeLogEvent(_node, @"insertSubnodes: %@", _insertedSubnodes); NSUInteger i = 0; NSUInteger j = 0; for (auto const &move : _subnodeMoves) { @@ -112,32 +111,31 @@ - (void)applySubnodeInsertionsAndMoves NSUInteger p = _insertedSubnodePositions[i]; NSUInteger q = _subnodeMoves[j].second; if (p < q) { - [_node _insertSubnode:_insertedSubnodes[i] atIndex:p]; + [_node insertSubnode:_insertedSubnodes[i] atIndex:p]; i++; } else { - [_node _insertSubnode:_subnodeMoves[j].first atIndex:q]; + [_node insertSubnode:_subnodeMoves[j].first atIndex:q]; j++; } } for (; i < _insertedSubnodePositions.size(); ++i) { - [_node _insertSubnode:_insertedSubnodes[i] atIndex:_insertedSubnodePositions[i]]; + [_node insertSubnode:_insertedSubnodes[i] atIndex:_insertedSubnodePositions[i]]; } for (; j < _subnodeMoves.size(); ++j) { - [_node _insertSubnode:_subnodeMoves[j].first atIndex:_subnodeMoves[j].second]; + [_node insertSubnode:_subnodeMoves[j].first atIndex:_subnodeMoves[j].second]; } } - (void)applySubnodeRemovals { as_activity_scope(as_activity_create("Apply subnode removals", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT)); - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; if (_removedSubnodes.count == 0) { return; } - ASDisplayNodeLogEvent(_node, @"removeSubnodes: %@", _removedSubnodes); for (ASDisplayNode *subnode in _removedSubnodes) { // In this case we should only remove the subnode if it's still a subnode of the _node that executes a layout transition. // It can happen that a node already did a layout transition and added this subnode, in this case the subnode @@ -150,7 +148,7 @@ - (void)applySubnodeRemovals - (void)calculateSubnodeOperationsIfNeeded { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); if (_calculatedSubnodeOperations) { return; } @@ -161,13 +159,13 @@ - (void)calculateSubnodeOperationsIfNeeded ASLayout *pendingLayout = _pendingLayout.layout; if (previousLayout) { -#if AS_IG_LIST_KIT +#if AS_IG_LIST_DIFF_KIT // IGListDiff completes in linear time O(m+n), so use it if we have it: IGListIndexSetResult *result = IGListDiff(previousLayout.sublayouts, pendingLayout.sublayouts, IGListDiffEquality); _insertedSubnodePositions = findNodesInLayoutAtIndexes(pendingLayout, result.inserts, &_insertedSubnodes); findNodesInLayoutAtIndexes(previousLayout, result.deletes, &_removedSubnodes); for (IGListMoveIndex *move in result.moves) { - _subnodeMoves.push_back(std::make_pair(previousLayout.sublayouts[move.from].layoutElement, move.to)); + _subnodeMoves.emplace_back(previousLayout.sublayouts[move.from].layoutElement, move.to); } // Sort by ascending order of move destinations, this will allow easy loop of `insertSubnode:AtIndex` later. @@ -189,8 +187,8 @@ - (void)calculateSubnodeOperationsIfNeeded _removedSubnodes = [previousNodes objectsAtIndexes:deletions]; // These should arrive sorted in ascending order of move destinations. for (NSIndexPath *move in moves) { - _subnodeMoves.push_back(std::make_pair(previousLayout.sublayouts[([move indexAtPosition:0])].layoutElement, - [move indexAtPosition:1])); + _subnodeMoves.emplace_back(previousLayout.sublayouts[([move indexAtPosition:0])].layoutElement, + [move indexAtPosition:1]); } #endif } else { @@ -205,27 +203,27 @@ - (void)calculateSubnodeOperationsIfNeeded - (NSArray *)currentSubnodesWithTransitionContext:(_ASTransitionContext *)context { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); return _node.subnodes; } - (NSArray *)insertedSubnodesWithTransitionContext:(_ASTransitionContext *)context { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; return _insertedSubnodes; } - (NSArray *)removedSubnodesWithTransitionContext:(_ASTransitionContext *)context { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); [self calculateSubnodeOperationsIfNeeded]; return _removedSubnodes; } - (ASLayout *)transitionContext:(_ASTransitionContext *)context layoutForKey:(NSString *)key { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); if ([key isEqualToString:ASTransitionContextFromLayoutKey]) { return _previousLayout.layout; } else if ([key isEqualToString:ASTransitionContextToLayoutKey]) { @@ -237,7 +235,7 @@ - (ASLayout *)transitionContext:(_ASTransitionContext *)context layoutForKey:(NS - (ASSizeRange)transitionContext:(_ASTransitionContext *)context constrainedSizeForKey:(NSString *)key { - ASDN::MutexLocker l(*__instanceLock__); + MutexLocker l(*__instanceLock__); if ([key isEqualToString:ASTransitionContextFromLayoutKey]) { return _previousLayout.constrainedSize; } else if ([key isEqualToString:ASTransitionContextToLayoutKey]) { diff --git a/Example/Pods/Texture/Source/Private/ASMutableElementMap.mm b/Example/Pods/Texture/Source/Private/ASMutableElementMap.mm index 0ef1f01..f7bf210 100644 --- a/Example/Pods/Texture/Source/Private/ASMutableElementMap.mm +++ b/Example/Pods/Texture/Source/Private/ASMutableElementMap.mm @@ -10,10 +10,8 @@ #import #import -#import #import #import -#import typedef NSMutableArray *> ASMutableCollectionElementTwoDimensionalArray; @@ -29,7 +27,7 @@ - (instancetype)initWithSections:(NSArray *)sections items:(ASColle { if (self = [super init]) { _sections = [sections mutableCopy]; - _sectionsOfItems = (id)ASTwoDimensionalArrayDeepMutableCopy(items); + _sectionsOfItems = (ASMutableCollectionElementTwoDimensionalArray *)ASTwoDimensionalArrayDeepMutableCopy(items); _supplementaryElements = [ASMutableElementMap deepMutableCopyOfElementsDictionary:supplementaryElements]; } return self; diff --git a/Example/Pods/Texture/Source/Private/ASPendingStateController.mm b/Example/Pods/Texture/Source/Private/ASPendingStateController.mm index 89dedfa..269b37e 100644 --- a/Example/Pods/Texture/Source/Private/ASPendingStateController.mm +++ b/Example/Pods/Texture/Source/Private/ASPendingStateController.mm @@ -14,7 +14,7 @@ @interface ASPendingStateController() { - ASDN::Mutex _lock; + AS::Mutex _lock; struct ASPendingStateControllerFlags { unsigned pendingFlush:1; @@ -52,7 +52,7 @@ + (ASPendingStateController *)sharedInstance - (void)registerNode:(ASDisplayNode *)node { ASDisplayNodeAssert(node.nodeLoaded, @"Expected display node to be loaded before it was registered with ASPendingStateController. Node: %@", node); - ASDN::MutexLocker l(_lock); + AS::MutexLocker l(_lock); [_dirtyNodes addObject:node]; [self scheduleFlushIfNeeded]; diff --git a/Example/Pods/Texture/Source/Private/ASTipsController.mm b/Example/Pods/Texture/Source/Private/ASTipsController.mm index acc5921..e30a064 100644 --- a/Example/Pods/Texture/Source/Private/ASTipsController.mm +++ b/Example/Pods/Texture/Source/Private/ASTipsController.mm @@ -37,9 +37,9 @@ @implementation ASTipsController #pragma mark - Singleton -+ (void)load +__attribute__((constructor)) static void ASLoadTipsControllerNotification(void) { - [NSNotificationCenter.defaultCenter addObserver:self.shared + [NSNotificationCenter.defaultCenter addObserver:ASTipsController.shared selector:@selector(windowDidBecomeVisibleWithNotification:) name:UIWindowDidBecomeVisibleNotification object:nil]; diff --git a/Example/Pods/Texture/Source/Private/ASTipsWindow.h b/Example/Pods/Texture/Source/Private/ASTipsWindow.h index fab5251..5354cc9 100644 --- a/Example/Pods/Texture/Source/Private/ASTipsWindow.h +++ b/Example/Pods/Texture/Source/Private/ASTipsWindow.h @@ -7,7 +7,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import +#import #import #if AS_ENABLE_TIPS diff --git a/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.h b/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.h index 6a3c9bb..8bddf29 100644 --- a/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.h +++ b/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.h @@ -21,26 +21,26 @@ NS_ASSUME_NONNULL_BEGIN * Deep mutable copy of an array that contains arrays, which contain objects. It will go one level deep into the array to copy. * This method is substantially faster than the generalized version, e.g. about 10x faster, so use it whenever it fits the need. */ -AS_EXTERN NSMutableArray *ASTwoDimensionalArrayDeepMutableCopy(NSArray *array) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSMutableArray *ASTwoDimensionalArrayDeepMutableCopy(NSArray *array) AS_WARN_UNUSED_RESULT; /** * Delete the elements of the mutable two-dimensional array at given index paths – sorted in descending order! */ -AS_EXTERN void ASDeleteElementsInTwoDimensionalArrayAtIndexPaths(NSMutableArray *mutableArray, NSArray *indexPaths); +ASDK_EXTERN void ASDeleteElementsInTwoDimensionalArrayAtIndexPaths(NSMutableArray *mutableArray, NSArray *indexPaths); /** * Return all the index paths of a two-dimensional array, in ascending order. */ -AS_EXTERN NSArray *ASIndexPathsForTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASIndexPathsForTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; /** * Return all the elements of a two-dimensional array, in ascending order. */ -AS_EXTERN NSArray *ASElementsInTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN NSArray *ASElementsInTwoDimensionalArray(NSArray* twoDimensionalArray) AS_WARN_UNUSED_RESULT; /** * Attempt to get the object at the given index path. Returns @c nil if the index path is out of bounds. */ -AS_EXTERN id _Nullable ASGetElementInTwoDimensionalArray(NSArray *array, NSIndexPath *indexPath) AS_WARN_UNUSED_RESULT; +ASDK_EXTERN id _Nullable ASGetElementInTwoDimensionalArray(NSArray *array, NSIndexPath *indexPath) AS_WARN_UNUSED_RESULT; NS_ASSUME_NONNULL_END diff --git a/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.mm b/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.mm index 8b4836f..2a33334 100644 --- a/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.mm +++ b/Example/Pods/Texture/Source/Private/ASTwoDimensionalArrayUtils.mm @@ -8,12 +8,14 @@ // #import +#import #import #import +#import + // Import UIKit to get [NSIndexPath indexPathForItem:inSection:] which uses // tagged pointers. -#import #pragma mark - Public Methods @@ -63,31 +65,42 @@ void ASDeleteElementsInTwoDimensionalArrayAtIndexPaths(NSMutableArray *mutableAr NSArray *ASIndexPathsForTwoDimensionalArray(NSArray * twoDimensionalArray) { - NSMutableArray *result = [[NSMutableArray alloc] init]; - NSInteger section = 0; + NSInteger sectionCount = twoDimensionalArray.count; + NSInteger counts[sectionCount]; + NSInteger totalCount = 0; NSInteger i = 0; for (NSArray *subarray in twoDimensionalArray) { - ASDisplayNodeCAssert([subarray isKindOfClass:[NSArray class]], @"This function expects NSArray *"); - NSInteger itemCount = subarray.count; - for (NSInteger item = 0; item < itemCount; item++) { - result[i++] = [NSIndexPath indexPathForItem:item inSection:section]; + NSInteger count = subarray.count; + counts[i++] = count; + totalCount += count; + } + + // Count could be huge. Use a reserved vector rather than VLA (stack.) + std::vector indexPaths; + indexPaths.reserve(totalCount); + for (NSInteger i = 0; i < sectionCount; i++) { + for (NSInteger j = 0; j < counts[i]; j++) { + indexPaths.push_back([NSIndexPath indexPathForItem:j inSection:i]); } - section++; } - return result; + return [NSArray arrayByTransferring:indexPaths.data() count:totalCount]; } NSArray *ASElementsInTwoDimensionalArray(NSArray * twoDimensionalArray) { - NSMutableArray *result = [[NSMutableArray alloc] init]; - NSInteger i = 0; + NSInteger totalCount = 0; for (NSArray *subarray in twoDimensionalArray) { - ASDisplayNodeCAssert([subarray isKindOfClass:[NSArray class]], @"This function expects NSArray *"); - for (id element in subarray) { - result[i++] = element; + totalCount += subarray.count; + } + + std::vector elements; + elements.reserve(totalCount); + for (NSArray *subarray in twoDimensionalArray) { + for (id object in subarray) { + elements.push_back(object); } } - return result; + return [NSArray arrayByTransferring:elements.data() count:totalCount]; } id ASGetElementInTwoDimensionalArray(NSArray *array, NSIndexPath *indexPath) diff --git a/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecPrivate.h b/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecPrivate.h index 0a4a39b..9302320 100644 --- a/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecPrivate.h +++ b/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecPrivate.h @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN @interface ASLayoutSpec() { - ASDN::RecursiveMutex __instanceLock__; + AS::RecursiveMutex __instanceLock__; std::atomic _primitiveTraitCollection; ASLayoutElementStyle *_style; NSMutableArray *_childrenArray; diff --git a/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecUtilities.h b/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecUtilities.h index 62a3d91..82e07df 100644 --- a/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecUtilities.h +++ b/Example/Pods/Texture/Source/Private/Layout/ASLayoutSpecUtilities.h @@ -24,17 +24,15 @@ namespace AS { { // Some convenience type definitions typedef decltype(func(std::declval())) value_type; - typedef std::vector result_type; // Prepares an output vector of the appropriate size - result_type res(iterable.size()); + std::vector res; + res.reserve(iterable.size()); // Let std::transform apply `func` to all elements // (use perfect forwarding for the function object) - std::transform( - begin(iterable), end(iterable), res.begin(), - std::forward(func) - ); + std::transform(std::begin(iterable), std::end(iterable), std::back_inserter(res), + std::forward(func)); return res; } diff --git a/Example/Pods/Texture/Source/Private/Layout/ASStackPositionedLayout.mm b/Example/Pods/Texture/Source/Private/Layout/ASStackPositionedLayout.mm index 727db5d..0e9d896 100644 --- a/Example/Pods/Texture/Source/Private/Layout/ASStackPositionedLayout.mm +++ b/Example/Pods/Texture/Source/Private/Layout/ASStackPositionedLayout.mm @@ -12,7 +12,6 @@ #import #import -#import #import #import #import diff --git a/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.h b/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.h index 989b4c2..68f9421 100644 --- a/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.h +++ b/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.h @@ -14,7 +14,7 @@ #import /** The threshold that determines if a violation has actually occurred. */ -AS_EXTERN CGFloat const kViolationEpsilon; +ASDK_EXTERN CGFloat const kViolationEpsilon; struct ASStackLayoutSpecChild { /** The original source child. */ diff --git a/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.mm b/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.mm index 47141a7..773f8bb 100644 --- a/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.mm +++ b/Example/Pods/Texture/Source/Private/Layout/ASStackUnpositionedLayout.mm @@ -468,7 +468,7 @@ static void layoutFlexibleChildrenAtZeroSize(std::vector static CGFloat computeItemsStackDimensionSum(const std::vector &items, const ASStackLayoutSpecStyle &style) { - // Sum up the childrens' spacing + // Sum up the children's spacing const CGFloat childSpacingSum = std::accumulate(items.begin(), items.end(), // Start from default spacing between each child: items.empty() ? 0 : style.spacing * (items.size() - 1), @@ -476,7 +476,7 @@ static CGFloat computeItemsStackDimensionSum(const std::vector #import -#import - const CGSize ASTextContainerMaxSize = (CGSize){0x100000, 0x100000}; typedef struct { @@ -383,7 +381,7 @@ - (instancetype)_init { - (NSString *)description { return [NSString stringWithFormat:@"lines: %ld, visibleRange:%@, textBoundingRect:%@", - [self.lines count], + (long)[self.lines count], NSStringFromRange(self.visibleRange), NSStringFromCGRect(self.textBoundingRect)]; } @@ -834,7 +832,8 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri } } int i = 0; - if (type != kCTLineTruncationStart) { // Middle or End/Tail wants text preceding truncated content. + if (type != kCTLineTruncationStart) { // Middle or End/Tail wants to collect some text (at least one line's + // worth) preceding the truncated content, with which to construct a "truncated line". i = (int)removedLines.count - 1; while (atLeastOneLine < truncatedWidth && i >= 0) { if (lastLineText.length > 0 && [lastLineText.string characterAtIndex:lastLineText.string.length - 1] == '\n') { // Explicit newlines are always "long enough". @@ -846,7 +845,8 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri } [lastLineText appendAttributedString:truncationToken]; } - if (type != kCTLineTruncationEnd && removedLines.count > 0) { // Middle or Start/Head wants text following truncated content. + if (type != kCTLineTruncationEnd && removedLines.count > 0) { // Middle or Start/Head wants to collect some + // text following the truncated content. i = 0; atLeastOneLine = removedLines[i].width; while (atLeastOneLine < truncatedWidth && i < removedLines.count) { @@ -860,7 +860,9 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri [lastLineText appendAttributedString:nextLine]; } } - [lastLineText insertAttributedString:truncationToken atIndex:0]; + if (type == kCTLineTruncationStart) { + [lastLineText insertAttributedString:truncationToken atIndex:0]; + } } CTLineRef ctLastLineExtend = CTLineCreateWithAttributedString((CFAttributedStringRef) lastLineText); @@ -967,15 +969,16 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri [truncationToken enumerateAttributesInRange:NSMakeRange(0, truncationToken.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:block]; } } - - attachments = [NSMutableArray new]; - attachmentRanges = [NSMutableArray new]; - attachmentRects = [NSMutableArray new]; - attachmentContentsSet = [NSMutableSet new]; for (NSUInteger i = 0, max = lines.count; i < max; i++) { ASTextLine *line = lines[i]; if (truncatedLine && line.index == truncatedLine.index) line = truncatedLine; if (line.attachments.count > 0) { + if (!attachments) { + attachments = [[NSMutableArray alloc] init]; + attachmentRanges = [[NSMutableArray alloc] init]; + attachmentRects = [[NSMutableArray alloc] init]; + attachmentContentsSet = [[NSMutableSet alloc] init]; + } [attachments addObjectsFromArray:line.attachments]; [attachmentRanges addObjectsFromArray:line.attachmentRanges]; [attachmentRects addObjectsFromArray:line.attachmentRects]; @@ -986,9 +989,6 @@ + (ASTextLayout *)layoutWithContainer:(ASTextContainer *)container text:(NSAttri } } } - if (attachments.count == 0) { - attachments = attachmentRanges = attachmentRects = nil; - } layout.frame = ctFrame; layout.lines = lines; @@ -2142,7 +2142,9 @@ - (NSArray *)selectionRectsForRange:(ASTextRange *)range { if (isVertical) { topRect.rect = CGRectMake(startLine.left, topOffset, startLine.width, (_container.path ? startLine.bottom : _container.size.height - _container.insets.bottom) - topOffset); } else { - topRect.rect = CGRectMake(topOffset, startLine.top, (_container.path ? startLine.right : _container.size.width - _container.insets.right) - topOffset, startLine.height); + // TODO: Fixes highlighting first row only to the end of the text and not highlight + // the while line to the end. Needs to brought over to multiline support + topRect.rect = CGRectMake(topOffset, startLine.top, (_container.path ? startLine.right : _container.size.width - _container.insets.right) - topOffset - (_container.size.width - _container.insets.right - startLine.right), startLine.height); } } [rects addObject:topRect]; diff --git a/Example/Pods/Texture/Source/Private/TextExperiment/Component/ASTextLine.mm b/Example/Pods/Texture/Source/Private/TextExperiment/Component/ASTextLine.mm index a01311d..37c68e0 100644 --- a/Example/Pods/Texture/Source/Private/TextExperiment/Component/ASTextLine.mm +++ b/Example/Pods/Texture/Source/Private/TextExperiment/Component/ASTextLine.mm @@ -76,9 +76,9 @@ - (void)reloadBounds { NSUInteger runCount = CFArrayGetCount(runs); if (runCount == 0) return; - NSMutableArray *attachments = [NSMutableArray new]; - NSMutableArray *attachmentRanges = [NSMutableArray new]; - NSMutableArray *attachmentRects = [NSMutableArray new]; + NSMutableArray *attachments = nil; + NSMutableArray *attachmentRanges = nil; + NSMutableArray *attachmentRects = nil; for (NSUInteger r = 0; r < runCount; r++) { CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, r); CFIndex glyphCount = CTRunGetGlyphCount(run); @@ -104,14 +104,19 @@ - (void)reloadBounds { } NSRange runRange = ASTextNSRangeFromCFRange(CTRunGetStringRange(run)); + if (!attachments) { + attachments = [[NSMutableArray alloc] init]; + attachmentRanges = [[NSMutableArray alloc] init]; + attachmentRects = [[NSMutableArray alloc] init]; + } [attachments addObject:attachment]; [attachmentRanges addObject:[NSValue valueWithRange:runRange]]; [attachmentRects addObject:[NSValue valueWithCGRect:runTypoBounds]]; } } - _attachments = attachments.count ? attachments : nil; - _attachmentRanges = attachmentRanges.count ? attachmentRanges : nil; - _attachmentRects = attachmentRects.count ? attachmentRects : nil; + _attachments = attachments; + _attachmentRanges = attachmentRanges; + _attachmentRects = attachmentRects; } - (CGSize)size { diff --git a/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.h b/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.h index 2d9e377..571334e 100644 --- a/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.h +++ b/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.h @@ -23,7 +23,7 @@ typedef NS_OPTIONS(NSInteger, ASTextAttributeType) { }; /// Get the attribute type from an attribute name. -AS_EXTERN ASTextAttributeType ASTextAttributeGetType(NSString *attributeName); +ASDK_EXTERN ASTextAttributeType ASTextAttributeGetType(NSString *attributeName); /** Line style in ASText (similar to NSUnderlineStyle). diff --git a/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.mm b/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.mm index d1abadb..8af4322 100644 --- a/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.mm +++ b/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextAttribute.mm @@ -8,7 +8,6 @@ // #import "ASTextAttribute.h" -#import #import #import diff --git a/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextRunDelegate.h b/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextRunDelegate.h index 3d3bf11..973dc5f 100644 --- a/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextRunDelegate.h +++ b/Example/Pods/Texture/Source/Private/TextExperiment/String/ASTextRunDelegate.h @@ -43,7 +43,7 @@ NS_ASSUME_NONNULL_BEGIN /** Additional information about the the run delegate. */ -@property (nullable, nonatomic) NSDictionary *userInfo; +@property (nullable, nonatomic, copy) NSDictionary *userInfo; /** The typographic ascent of glyphs in the run. diff --git a/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.h b/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.h index f21a931..2ba0f09 100644 --- a/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.h +++ b/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.h @@ -132,7 +132,6 @@ static inline CGFloat ASTextEmojiGetDescentWithFontSize(CGFloat fontSize) { } else { return 0.3125 * fontSize; } - return 0; } /** diff --git a/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.mm b/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.mm index 8d01377..7194dad 100644 --- a/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.mm +++ b/Example/Pods/Texture/Source/Private/TextExperiment/Utility/ASTextUtilities.mm @@ -7,7 +7,6 @@ // #import "ASTextUtilities.h" -#import NSCharacterSet *ASTextVerticalFormRotateCharacterSet() { static NSMutableCharacterSet *set; diff --git a/Example/Pods/Texture/Source/Private/_ASCollectionGalleryLayoutItem.mm b/Example/Pods/Texture/Source/Private/_ASCollectionGalleryLayoutItem.mm index 5733702..3e4320e 100644 --- a/Example/Pods/Texture/Source/Private/_ASCollectionGalleryLayoutItem.mm +++ b/Example/Pods/Texture/Source/Private/_ASCollectionGalleryLayoutItem.mm @@ -10,13 +10,15 @@ #import #import -#import #import #import -@implementation _ASGalleryLayoutItem { - std::atomic _primitiveTraitCollection; -} +@interface _ASGalleryLayoutItem () +@property ASPrimitiveTraitCollection primitiveTraitCollection; + +@end + +@implementation _ASGalleryLayoutItem @synthesize style; @@ -33,7 +35,6 @@ - (instancetype)initWithItemSize:(CGSize)itemSize collectionElement:(ASCollectio } ASLayoutElementStyleExtensibilityForwarding -ASPrimitiveTraitCollectionDefaults - (ASTraitCollection *)asyncTraitCollection { diff --git a/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.h b/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.h index 5937f30..182bc35 100644 --- a/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.h +++ b/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.h @@ -34,21 +34,21 @@ @param obj ASDisplayNode, CALayer or object that conforms to `ASResizableContents` protocol @param image Image you would like to resize */ -AS_EXTERN void ASDisplayNodeSetResizableContents(id obj, UIImage *image); +ASDK_EXTERN void ASDisplayNodeSetResizableContents(id obj, UIImage *image); /** Turns a value of UIViewContentMode to a string for debugging or serialization @param contentMode Any of the UIViewContentMode constants @return A human-readable representation of the constant, or the integer value of the constant if not recognized. */ -AS_EXTERN NSString *ASDisplayNodeNSStringFromUIContentMode(UIViewContentMode contentMode); +ASDK_EXTERN NSString *ASDisplayNodeNSStringFromUIContentMode(UIViewContentMode contentMode); /** Turns a string representing a contentMode into a contentMode @param string Any of the strings in UIContentModeDescriptionLUT @return Any of the UIViewContentMode constants, or an int if the string is a number. If the string is not recognized, UIViewContentModeScaleToFill is returned. */ -AS_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string); +ASDK_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *string); /** Maps a value of UIViewContentMode to a corresponding contentsGravity @@ -56,7 +56,7 @@ AS_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromNSString(NSString *str @param contentMode A content mode except for UIViewContentModeRedraw, which has no corresponding contentsGravity (it corresponds to needsDisplayOnBoundsChange = YES) @return An NSString constant from the documentation, eg kCAGravityCenter... or nil if there is no corresponding contentsGravity. Will assert if contentMode is unknown. */ -AS_EXTERN NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIViewContentMode contentMode); +ASDK_EXTERN NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIViewContentMode contentMode); /** Maps a value of contentsGravity to a corresponding UIViewContentMode @@ -64,21 +64,21 @@ AS_EXTERN NSString *const ASDisplayNodeCAContentsGravityFromUIContentMode(UIView @param contentsGravity A contents gravity @return A UIViewContentMode constant from UIView.h, eg UIViewContentModeCenter..., or UIViewContentModeScaleToFill if contentsGravity is not one of the CA constants. Will assert if the contentsGravity is unknown. */ -AS_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromCAContentsGravity(NSString *const contentsGravity); +ASDK_EXTERN UIViewContentMode ASDisplayNodeUIContentModeFromCAContentsGravity(NSString *const contentsGravity); /** Use this to create a stretchable appropriate to approximate a filled rectangle, but with antialiasing on the edges when not pixel-aligned. It's best to keep the layer this image is added to with contentsScale equal to the scale of the final transform to screen space so it is able to antialias appropriately even when you shrink or grow the layer. @param color the fill color to use in the center of the image @param innerSize Unfortunately, 4 seems to be the smallest inner size that works if you're applying this stretchable to a larger box, whereas it does not display correctly for larger boxes. Thus some adjustment is necessary for the size of box you're displaying. If you're showing a 1px horizontal line, pass 1 height and at least 4 width. 2px vertical line: 2px wide, 4px high. Passing an innerSize greater that you desire is wasteful */ -AS_EXTERN UIImage *ASDisplayNodeStretchableBoxContentsWithColor(UIColor *color, CGSize innerSize); +ASDK_EXTERN UIImage *ASDisplayNodeStretchableBoxContentsWithColor(UIColor *color, CGSize innerSize); /** Checks whether a layer has ongoing animations @param layer A layer to check if animations are ongoing @return YES if the layer has ongoing animations, otherwise NO */ -AS_EXTERN BOOL ASDisplayNodeLayerHasAnimations(CALayer *layer); +ASDK_EXTERN BOOL ASDisplayNodeLayerHasAnimations(CALayer *layer); // This function is a less generalized version of ASDisplayNodeSetResizableContents. -AS_EXTERN void ASDisplayNodeSetupLayerContentsWithResizableImage(CALayer *layer, UIImage *image) ASDISPLAYNODE_DEPRECATED; +ASDK_EXTERN void ASDisplayNodeSetupLayerContentsWithResizableImage(CALayer *layer, UIImage *image) ASDISPLAYNODE_DEPRECATED; diff --git a/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.mm b/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.mm index b55bd64..e73c3ad 100644 --- a/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.mm +++ b/Example/Pods/Texture/Source/Private/_ASCoreAnimationExtras.mm @@ -9,7 +9,6 @@ #import #import -#import void ASDisplayNodeSetupLayerContentsWithResizableImage(CALayer *layer, UIImage *image) { @@ -80,7 +79,7 @@ void ASDisplayNodeSetResizableContents(id obj, UIImage *ima {UIViewContentModeBottomLeft, kCAGravityTopLeft}, {UIViewContentModeBottomRight, kCAGravityTopRight}, }; - *count = sizeof(sUIContentModeCAGravityLUT) / sizeof(sUIContentModeCAGravityLUT[0]); + *count = AS_ARRAY_SIZE(sUIContentModeCAGravityLUT); return sUIContentModeCAGravityLUT; } @@ -103,7 +102,7 @@ void ASDisplayNodeSetResizableContents(id obj, UIImage *ima {UIViewContentModeBottomLeft, @"bottomLeft"}, {UIViewContentModeBottomRight, @"bottomRight"}, }; - *count = sizeof(sUIContentModeDescriptionLUT) / sizeof(sUIContentModeDescriptionLUT[0]); + *count = AS_ARRAY_SIZE(sUIContentModeDescriptionLUT); return sUIContentModeDescriptionLUT; } diff --git a/Example/Pods/Texture/Source/Private/_ASHierarchyChangeSet.mm b/Example/Pods/Texture/Source/Private/_ASHierarchyChangeSet.mm index 2b264dd..825c6b8 100644 --- a/Example/Pods/Texture/Source/Private/_ASHierarchyChangeSet.mm +++ b/Example/Pods/Texture/Source/Private/_ASHierarchyChangeSet.mm @@ -11,12 +11,9 @@ #import #import #import -#import #import -#import #import #import -#import // If assertions are enabled and they haven't forced us to suppress the exception, // then throw, otherwise log. diff --git a/Example/Pods/Texture/Source/Private/_ASPendingState.mm b/Example/Pods/Texture/Source/Private/_ASPendingState.mm index 784d435..a9d760e 100644 --- a/Example/Pods/Texture/Source/Private/_ASPendingState.mm +++ b/Example/Pods/Texture/Source/Private/_ASPendingState.mm @@ -10,15 +10,17 @@ #import #import -#import -#import #import -#import #import -#define __shouldSetNeedsDisplay(layer) (flags.needsDisplay \ - || (flags.setOpaque && opaque != (layer).opaque)\ - || (flags.setBackgroundColor && !CGColorEqualToColor(backgroundColor, (layer).backgroundColor))) +#define __shouldSetNeedsDisplayForView(view) (flags.needsDisplay \ + || (flags.setOpaque && _flags.opaque != (view).opaque)\ + || (flags.setBackgroundColor && ![backgroundColor isEqual:(view).backgroundColor])\ + || (flags.setTintColor && ![tintColor isEqual:(view).tintColor])) + +#define __shouldSetNeedsDisplayForLayer(layer) (flags.needsDisplay \ + || (flags.setOpaque && _flags.opaque != (layer).opaque)\ + || (flags.setBackgroundColor && ![backgroundColor isEqual:[UIColor colorWithCGColor:(layer).backgroundColor]])) typedef struct { // Properties @@ -79,6 +81,7 @@ int setShouldGroupAccessibilityChildren:1; int setAccessibilityIdentifier:1; int setAccessibilityNavigationStyle:1; + int setAccessibilityCustomActions:1; int setAccessibilityHeaderElements:1; int setAccessibilityActivationPoint:1; int setAccessibilityPath:1; @@ -86,17 +89,23 @@ int setLayoutMargins:1; int setPreservesSuperviewLayoutMargins:1; int setInsetsLayoutMarginsFromSafeArea:1; + int setActions:1; + int setMaskedCorners : 1; } ASPendingStateFlags; + +static constexpr ASPendingStateFlags kZeroFlags = {0}; + @implementation _ASPendingState { @package //Expose all ivars for ASDisplayNode to bypass getters for efficiency UIViewAutoresizing autoresizingMask; - unsigned int edgeAntialiasingMask; + CAEdgeAntialiasingMask edgeAntialiasingMask; CGRect frame; // Frame is only to be used for synchronous views wrapped by nodes (see setFrame:) CGRect bounds; - CGColorRef backgroundColor; + UIColor *backgroundColor; + UIColor *tintColor; CGFloat alpha; CGFloat cornerRadius; UIViewContentMode contentMode; @@ -117,11 +126,7 @@ @implementation _ASPendingState CGFloat shadowRadius; CGFloat borderWidth; CGColorRef borderColor; - BOOL asyncTransactionContainer; UIEdgeInsets layoutMargins; - BOOL preservesSuperviewLayoutMargins; - BOOL insetsLayoutMarginsFromSafeArea; - BOOL isAccessibilityElement; NSString *accessibilityLabel; NSAttributedString *accessibilityAttributedLabel; NSString *accessibilityHint; @@ -131,17 +136,34 @@ @implementation _ASPendingState UIAccessibilityTraits accessibilityTraits; CGRect accessibilityFrame; NSString *accessibilityLanguage; - BOOL accessibilityElementsHidden; - BOOL accessibilityViewIsModal; - BOOL shouldGroupAccessibilityChildren; NSString *accessibilityIdentifier; UIAccessibilityNavigationStyle accessibilityNavigationStyle; + NSArray *accessibilityCustomActions; NSArray *accessibilityHeaderElements; CGPoint accessibilityActivationPoint; UIBezierPath *accessibilityPath; UISemanticContentAttribute semanticContentAttribute API_AVAILABLE(ios(9.0), tvos(9.0)); - - ASPendingStateFlags _flags; + NSDictionary> *actions; + + ASPendingStateFlags _stateToApplyFlags; + struct { + unsigned int asyncTransactionContainer:1; + unsigned int preservesSuperviewLayoutMargins:1; + unsigned int insetsLayoutMarginsFromSafeArea:1; + unsigned int isAccessibilityElement:1; + unsigned int accessibilityElementsHidden:1; + unsigned int accessibilityViewIsModal:1; + unsigned int shouldGroupAccessibilityChildren:1; + unsigned int clipsToBounds:1; + unsigned int opaque:1; + unsigned int hidden:1; + unsigned int needsDisplayOnBoundsChange:1; + unsigned int allowsGroupOpacity:1; + unsigned int allowsEdgeAntialiasing:1; + unsigned int autoresizesSubviews:1; + unsigned int userInteractionEnabled:1; + unsigned int exclusiveTouch:1; + } _flags; } /** @@ -154,7 +176,7 @@ @implementation _ASPendingState * value intact until application time (now). */ ASDISPLAYNODE_INLINE void ASPendingStateApplyMetricsToLayer(_ASPendingState *state, CALayer *layer) { - ASPendingStateFlags flags = state->_flags; + ASPendingStateFlags flags = state->_stateToApplyFlags; if (flags.setFrame) { CGRect _bounds = CGRectZero; CGPoint _position = CGPointZero; @@ -169,17 +191,10 @@ ASDISPLAYNODE_INLINE void ASPendingStateApplyMetricsToLayer(_ASPendingState *sta } } -@synthesize clipsToBounds=clipsToBounds; -@synthesize opaque=opaque; @synthesize frame=frame; @synthesize bounds=bounds; @synthesize backgroundColor=backgroundColor; -@synthesize hidden=isHidden; -@synthesize needsDisplayOnBoundsChange=needsDisplayOnBoundsChange; -@synthesize allowsGroupOpacity=allowsGroupOpacity; -@synthesize allowsEdgeAntialiasing=allowsEdgeAntialiasing; @synthesize edgeAntialiasingMask=edgeAntialiasingMask; -@synthesize autoresizesSubviews=autoresizesSubviews; @synthesize autoresizingMask=autoresizingMask; @synthesize tintColor=tintColor; @synthesize alpha=alpha; @@ -209,9 +224,10 @@ ASDISPLAYNODE_INLINE void ASPendingStateApplyMetricsToLayer(_ASPendingState *sta @synthesize layoutMargins=layoutMargins; @synthesize preservesSuperviewLayoutMargins=preservesSuperviewLayoutMargins; @synthesize insetsLayoutMarginsFromSafeArea=insetsLayoutMarginsFromSafeArea; +@synthesize actions=actions; +@synthesize maskedCorners = maskedCorners; static CGColorRef blackColorRef = NULL; -static UIColor *defaultTintColor = nil; - (instancetype)init { @@ -226,25 +242,24 @@ - (instancetype)init blackColorRef = CGColorCreate(colorSpace, (CGFloat[]){0,0,0,1} ); CFRetain(blackColorRef); CGColorSpaceRelease(colorSpace); - defaultTintColor = [UIColor colorWithRed:0.0 green:0.478 blue:1.0 alpha:1.0]; }); // Set defaults, these come from the defaults specified in CALayer and UIView - clipsToBounds = NO; - opaque = YES; + _flags.clipsToBounds = NO; + _flags.opaque = YES; frame = CGRectZero; bounds = CGRectZero; backgroundColor = nil; - tintColor = defaultTintColor; - isHidden = NO; - needsDisplayOnBoundsChange = NO; - allowsGroupOpacity = ASDefaultAllowsGroupOpacity(); - allowsEdgeAntialiasing = ASDefaultAllowsEdgeAntialiasing(); - autoresizesSubviews = YES; + tintColor = nil; + _flags.hidden = NO; + _flags.needsDisplayOnBoundsChange = NO; + _flags.allowsGroupOpacity = ASDefaultAllowsGroupOpacity(); + _flags.allowsEdgeAntialiasing = ASDefaultAllowsEdgeAntialiasing(); + _flags.autoresizesSubviews = YES; alpha = 1.0f; cornerRadius = 0.0f; contentMode = UIViewContentModeScaleToFill; - _flags.needsDisplay = NO; + _stateToApplyFlags.needsDisplay = NO; anchorPoint = CGPointMake(0.5, 0.5); position = CGPointZero; zPosition = 0.0; @@ -256,7 +271,7 @@ - (instancetype)init contentsCenter = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f); contentsScale = 1.0f; rasterizationScale = 1.0f; - userInteractionEnabled = YES; + _flags.userInteractionEnabled = YES; shadowColor = blackColorRef; shadowOpacity = 0.0; shadowOffset = CGSizeMake(0, -3); @@ -264,9 +279,9 @@ - (instancetype)init borderWidth = 0; borderColor = blackColorRef; layoutMargins = UIEdgeInsetsMake(8, 8, 8, 8); - preservesSuperviewLayoutMargins = NO; - insetsLayoutMarginsFromSafeArea = YES; - isAccessibilityElement = NO; + _flags.preservesSuperviewLayoutMargins = NO; + _flags.insetsLayoutMarginsFromSafeArea = YES; + _flags.isAccessibilityElement = NO; accessibilityLabel = nil; accessibilityAttributedLabel = nil; accessibilityHint = nil; @@ -276,11 +291,12 @@ - (instancetype)init accessibilityTraits = UIAccessibilityTraitNone; accessibilityFrame = CGRectZero; accessibilityLanguage = nil; - accessibilityElementsHidden = NO; - accessibilityViewIsModal = NO; - shouldGroupAccessibilityChildren = NO; + _flags.accessibilityElementsHidden = NO; + _flags.accessibilityViewIsModal = NO; + _flags.shouldGroupAccessibilityChildren = NO; accessibilityIdentifier = nil; accessibilityNavigationStyle = UIAccessibilityNavigationStyleAutomatic; + accessibilityCustomActions = nil; accessibilityHeaderElements = nil; accessibilityActivationPoint = CGPointZero; accessibilityPath = nil; @@ -292,71 +308,101 @@ - (instancetype)init - (void)setNeedsDisplay { - _flags.needsDisplay = YES; + _stateToApplyFlags.needsDisplay = YES; } - (void)setNeedsLayout { - _flags.needsLayout = YES; + _stateToApplyFlags.needsLayout = YES; } - (void)layoutIfNeeded { - _flags.layoutIfNeeded = YES; + _stateToApplyFlags.layoutIfNeeded = YES; } - (void)setClipsToBounds:(BOOL)flag { - clipsToBounds = flag; - _flags.setClipsToBounds = YES; + _flags.clipsToBounds = flag; + _stateToApplyFlags.setClipsToBounds = YES; +} + +- (BOOL)clipsToBounds +{ + return _flags.clipsToBounds; } - (void)setOpaque:(BOOL)flag { - opaque = flag; - _flags.setOpaque = YES; + _flags.opaque = flag; + _stateToApplyFlags.setOpaque = YES; +} + +- (BOOL)isOpaque +{ + return _flags.opaque; } - (void)setNeedsDisplayOnBoundsChange:(BOOL)flag { - needsDisplayOnBoundsChange = flag; - _flags.setNeedsDisplayOnBoundsChange = YES; + _flags.needsDisplayOnBoundsChange = flag; + _stateToApplyFlags.setNeedsDisplayOnBoundsChange = YES; +} + +- (BOOL)needsDisplayOnBoundsChange +{ + return _flags.needsDisplayOnBoundsChange; } - (void)setAllowsGroupOpacity:(BOOL)flag { - allowsGroupOpacity = flag; - _flags.setAllowsGroupOpacity = YES; + _flags.allowsGroupOpacity = flag; + _stateToApplyFlags.setAllowsGroupOpacity = YES; +} + +- (BOOL)allowsGroupOpacity +{ + return _flags.allowsGroupOpacity; } - (void)setAllowsEdgeAntialiasing:(BOOL)flag { - allowsEdgeAntialiasing = flag; - _flags.setAllowsEdgeAntialiasing = YES; + _flags.allowsEdgeAntialiasing = flag; + _stateToApplyFlags.setAllowsEdgeAntialiasing = YES; +} + +- (BOOL)allowsEdgeAntialiasing +{ + return _flags.allowsEdgeAntialiasing; } -- (void)setEdgeAntialiasingMask:(unsigned int)mask +- (void)setEdgeAntialiasingMask:(CAEdgeAntialiasingMask)mask { edgeAntialiasingMask = mask; - _flags.setEdgeAntialiasingMask = YES; + _stateToApplyFlags.setEdgeAntialiasingMask = YES; } - (void)setAutoresizesSubviews:(BOOL)flag { - autoresizesSubviews = flag; - _flags.setAutoresizesSubviews = YES; + _flags.autoresizesSubviews = flag; + _stateToApplyFlags.setAutoresizesSubviews = YES; +} + +- (BOOL)autoresizesSubviews +{ + return _flags.autoresizesSubviews; } - (void)setAutoresizingMask:(UIViewAutoresizing)mask { autoresizingMask = mask; - _flags.setAutoresizingMask = YES; + _stateToApplyFlags.setAutoresizingMask = YES; } - (void)setFrame:(CGRect)newFrame { frame = newFrame; - _flags.setFrame = YES; + _stateToApplyFlags.setFrame = YES; } - (void)setBounds:(CGRect)newBounds @@ -367,59 +413,76 @@ - (void)setBounds:(CGRect)newBounds if (isnan(newBounds.size.height)) newBounds.size.height = 0.0; bounds = newBounds; - _flags.setBounds = YES; + _stateToApplyFlags.setBounds = YES; } -- (CGColorRef)backgroundColor +- (UIColor *)backgroundColor { return backgroundColor; } -- (void)setBackgroundColor:(CGColorRef)color +- (void)setBackgroundColor:(UIColor *)color { - if (color == backgroundColor) { + if ([color isEqual:backgroundColor]) { return; } + backgroundColor = color; + _stateToApplyFlags.setBackgroundColor = YES; +} - CGColorRelease(backgroundColor); - backgroundColor = CGColorRetain(color); - _flags.setBackgroundColor = YES; +- (UIColor *)tintColor +{ + return tintColor; } - (void)setTintColor:(UIColor *)newTintColor { + if ([newTintColor isEqual:tintColor]) { + return; + } tintColor = newTintColor; - _flags.setTintColor = YES; + _stateToApplyFlags.setTintColor = YES; } - (void)setHidden:(BOOL)flag { - isHidden = flag; - _flags.setHidden = YES; + _flags.hidden = flag; + _stateToApplyFlags.setHidden = YES; +} + +- (BOOL)isHidden +{ + return _flags.hidden; } - (void)setAlpha:(CGFloat)newAlpha { alpha = newAlpha; - _flags.setAlpha = YES; + _stateToApplyFlags.setAlpha = YES; } - (void)setCornerRadius:(CGFloat)newCornerRadius { cornerRadius = newCornerRadius; - _flags.setCornerRadius = YES; + _stateToApplyFlags.setCornerRadius = YES; +} + +- (void)setMaskedCorners:(CACornerMask)newMaskedCorners +{ + maskedCorners = newMaskedCorners; + _stateToApplyFlags.setMaskedCorners = YES; } - (void)setContentMode:(UIViewContentMode)newContentMode { contentMode = newContentMode; - _flags.setContentMode = YES; + _stateToApplyFlags.setContentMode = YES; } - (void)setAnchorPoint:(CGPoint)newAnchorPoint { anchorPoint = newAnchorPoint; - _flags.setAnchorPoint = YES; + _stateToApplyFlags.setAnchorPoint = YES; } - (void)setPosition:(CGPoint)newPosition @@ -430,25 +493,25 @@ - (void)setPosition:(CGPoint)newPosition if (isnan(newPosition.y)) newPosition.y = 0.0; position = newPosition; - _flags.setPosition = YES; + _stateToApplyFlags.setPosition = YES; } - (void)setZPosition:(CGFloat)newPosition { zPosition = newPosition; - _flags.setZPosition = YES; + _stateToApplyFlags.setZPosition = YES; } - (void)setTransform:(CATransform3D)newTransform { transform = newTransform; - _flags.setTransform = YES; + _stateToApplyFlags.setTransform = YES; } - (void)setSublayerTransform:(CATransform3D)newSublayerTransform { sublayerTransform = newSublayerTransform; - _flags.setSublayerTransform = YES; + _stateToApplyFlags.setSublayerTransform = YES; } - (void)setContents:(id)newContents @@ -458,49 +521,59 @@ - (void)setContents:(id)newContents } contents = newContents; - _flags.setContents = YES; + _stateToApplyFlags.setContents = YES; } - (void)setContentsGravity:(NSString *)newContentsGravity { contentsGravity = newContentsGravity; - _flags.setContentsGravity = YES; + _stateToApplyFlags.setContentsGravity = YES; } - (void)setContentsRect:(CGRect)newContentsRect { contentsRect = newContentsRect; - _flags.setContentsRect = YES; + _stateToApplyFlags.setContentsRect = YES; } - (void)setContentsCenter:(CGRect)newContentsCenter { contentsCenter = newContentsCenter; - _flags.setContentsCenter = YES; + _stateToApplyFlags.setContentsCenter = YES; } - (void)setContentsScale:(CGFloat)newContentsScale { contentsScale = newContentsScale; - _flags.setContentsScale = YES; + _stateToApplyFlags.setContentsScale = YES; } - (void)setRasterizationScale:(CGFloat)newRasterizationScale { rasterizationScale = newRasterizationScale; - _flags.setRasterizationScale = YES; + _stateToApplyFlags.setRasterizationScale = YES; } - (void)setUserInteractionEnabled:(BOOL)flag { - userInteractionEnabled = flag; - _flags.setUserInteractionEnabled = YES; + _flags.userInteractionEnabled = flag; + _stateToApplyFlags.setUserInteractionEnabled = YES; +} + +- (BOOL)isUserInteractionEnabled +{ + return _flags.userInteractionEnabled; } - (void)setExclusiveTouch:(BOOL)flag { - exclusiveTouch = flag; - _flags.setExclusiveTouch = YES; + _flags.exclusiveTouch = flag; + _stateToApplyFlags.setExclusiveTouch = YES; +} + +- (BOOL)isExclusiveTouch +{ + return _flags.exclusiveTouch; } - (void)setShadowColor:(CGColorRef)color @@ -515,31 +588,31 @@ - (void)setShadowColor:(CGColorRef)color shadowColor = color; CGColorRetain(shadowColor); - _flags.setShadowColor = YES; + _stateToApplyFlags.setShadowColor = YES; } - (void)setShadowOpacity:(CGFloat)newOpacity { shadowOpacity = newOpacity; - _flags.setShadowOpacity = YES; + _stateToApplyFlags.setShadowOpacity = YES; } - (void)setShadowOffset:(CGSize)newOffset { shadowOffset = newOffset; - _flags.setShadowOffset = YES; + _stateToApplyFlags.setShadowOffset = YES; } - (void)setShadowRadius:(CGFloat)newRadius { shadowRadius = newRadius; - _flags.setShadowRadius = YES; + _stateToApplyFlags.setShadowRadius = YES; } - (void)setBorderWidth:(CGFloat)newWidth { borderWidth = newWidth; - _flags.setBorderWidth = YES; + _stateToApplyFlags.setBorderWidth = YES; } - (void)setBorderColor:(CGColorRef)color @@ -554,52 +627,73 @@ - (void)setBorderColor:(CGColorRef)color borderColor = color; CGColorRetain(borderColor); - _flags.setBorderColor = YES; + _stateToApplyFlags.setBorderColor = YES; } - (void)asyncdisplaykit_setAsyncTransactionContainer:(BOOL)flag { - asyncTransactionContainer = flag; - _flags.setAsyncTransactionContainer = YES; + _flags.asyncTransactionContainer = flag; + _stateToApplyFlags.setAsyncTransactionContainer = YES; +} + +- (BOOL)asyncdisplaykit_isAsyncTransactionContainer +{ + return _flags.asyncTransactionContainer; } - (void)setLayoutMargins:(UIEdgeInsets)margins { layoutMargins = margins; - _flags.setLayoutMargins = YES; + _stateToApplyFlags.setLayoutMargins = YES; } - (void)setPreservesSuperviewLayoutMargins:(BOOL)flag { - preservesSuperviewLayoutMargins = flag; - _flags.setPreservesSuperviewLayoutMargins = YES; + _flags.preservesSuperviewLayoutMargins = flag; + _stateToApplyFlags.setPreservesSuperviewLayoutMargins = YES; +} + +- (BOOL)preservesSuperviewLayoutMargins +{ + return _flags.preservesSuperviewLayoutMargins; } - (void)setInsetsLayoutMarginsFromSafeArea:(BOOL)flag { - insetsLayoutMarginsFromSafeArea = flag; - _flags.setInsetsLayoutMarginsFromSafeArea = YES; + _flags.insetsLayoutMarginsFromSafeArea = flag; + _stateToApplyFlags.setInsetsLayoutMarginsFromSafeArea = YES; +} + +- (BOOL)insetsLayoutMarginsFromSafeArea +{ + return _flags.insetsLayoutMarginsFromSafeArea; } - (void)setSemanticContentAttribute:(UISemanticContentAttribute)attribute API_AVAILABLE(ios(9.0), tvos(9.0)) { semanticContentAttribute = attribute; - _flags.setSemanticContentAttribute = YES; + _stateToApplyFlags.setSemanticContentAttribute = YES; +} + +- (void)setActions:(NSDictionary> *)actionsArg +{ + actions = [actionsArg copy]; + _stateToApplyFlags.setActions = YES; } - (BOOL)isAccessibilityElement { - return isAccessibilityElement; + return _flags.isAccessibilityElement; } - (void)setIsAccessibilityElement:(BOOL)newIsAccessibilityElement { - isAccessibilityElement = newIsAccessibilityElement; - _flags.setIsAccessibilityElement = YES; + _flags.isAccessibilityElement = newIsAccessibilityElement; + _stateToApplyFlags.setIsAccessibilityElement = YES; } - (NSString *)accessibilityLabel { - if (_flags.setAccessibilityAttributedLabel) { + if (_stateToApplyFlags.setAccessibilityAttributedLabel) { return accessibilityAttributedLabel.string; } return accessibilityLabel; @@ -608,13 +702,13 @@ - (NSString *)accessibilityLabel - (void)setAccessibilityLabel:(NSString *)newAccessibilityLabel { ASCompareAssignCopy(accessibilityLabel, newAccessibilityLabel); - _flags.setAccessibilityLabel = YES; - _flags.setAccessibilityAttributedLabel = NO; + _stateToApplyFlags.setAccessibilityLabel = YES; + _stateToApplyFlags.setAccessibilityAttributedLabel = NO; } - (NSAttributedString *)accessibilityAttributedLabel { - if (_flags.setAccessibilityLabel) { + if (_stateToApplyFlags.setAccessibilityLabel) { return [[NSAttributedString alloc] initWithString:accessibilityLabel]; } return accessibilityAttributedLabel; @@ -623,13 +717,13 @@ - (NSAttributedString *)accessibilityAttributedLabel - (void)setAccessibilityAttributedLabel:(NSAttributedString *)newAccessibilityAttributedLabel { ASCompareAssignCopy(accessibilityAttributedLabel, newAccessibilityAttributedLabel); - _flags.setAccessibilityAttributedLabel = YES; - _flags.setAccessibilityLabel = NO; + _stateToApplyFlags.setAccessibilityAttributedLabel = YES; + _stateToApplyFlags.setAccessibilityLabel = NO; } - (NSString *)accessibilityHint { - if (_flags.setAccessibilityAttributedHint) { + if (_stateToApplyFlags.setAccessibilityAttributedHint) { return accessibilityAttributedHint.string; } return accessibilityHint; @@ -638,13 +732,13 @@ - (NSString *)accessibilityHint - (void)setAccessibilityHint:(NSString *)newAccessibilityHint { ASCompareAssignCopy(accessibilityHint, newAccessibilityHint); - _flags.setAccessibilityHint = YES; - _flags.setAccessibilityAttributedHint = NO; + _stateToApplyFlags.setAccessibilityHint = YES; + _stateToApplyFlags.setAccessibilityAttributedHint = NO; } - (NSAttributedString *)accessibilityAttributedHint { - if (_flags.setAccessibilityHint) { + if (_stateToApplyFlags.setAccessibilityHint) { return [[NSAttributedString alloc] initWithString:accessibilityHint]; } return accessibilityAttributedHint; @@ -653,13 +747,13 @@ - (NSAttributedString *)accessibilityAttributedHint - (void)setAccessibilityAttributedHint:(NSAttributedString *)newAccessibilityAttributedHint { ASCompareAssignCopy(accessibilityAttributedHint, newAccessibilityAttributedHint); - _flags.setAccessibilityAttributedHint = YES; - _flags.setAccessibilityHint = NO; + _stateToApplyFlags.setAccessibilityAttributedHint = YES; + _stateToApplyFlags.setAccessibilityHint = NO; } - (NSString *)accessibilityValue { - if (_flags.setAccessibilityAttributedValue) { + if (_stateToApplyFlags.setAccessibilityAttributedValue) { return accessibilityAttributedValue.string; } return accessibilityValue; @@ -668,13 +762,13 @@ - (NSString *)accessibilityValue - (void)setAccessibilityValue:(NSString *)newAccessibilityValue { ASCompareAssignCopy(accessibilityValue, newAccessibilityValue); - _flags.setAccessibilityValue = YES; - _flags.setAccessibilityAttributedValue = NO; + _stateToApplyFlags.setAccessibilityValue = YES; + _stateToApplyFlags.setAccessibilityAttributedValue = NO; } - (NSAttributedString *)accessibilityAttributedValue { - if (_flags.setAccessibilityValue) { + if (_stateToApplyFlags.setAccessibilityValue) { return [[NSAttributedString alloc] initWithString:accessibilityValue]; } return accessibilityAttributedValue; @@ -683,8 +777,8 @@ - (NSAttributedString *)accessibilityAttributedValue - (void)setAccessibilityAttributedValue:(NSAttributedString *)newAccessibilityAttributedValue { ASCompareAssignCopy(accessibilityAttributedValue, newAccessibilityAttributedValue); - _flags.setAccessibilityAttributedValue = YES; - _flags.setAccessibilityValue = NO; + _stateToApplyFlags.setAccessibilityAttributedValue = YES; + _stateToApplyFlags.setAccessibilityValue = NO; } - (UIAccessibilityTraits)accessibilityTraits @@ -695,7 +789,7 @@ - (UIAccessibilityTraits)accessibilityTraits - (void)setAccessibilityTraits:(UIAccessibilityTraits)newAccessibilityTraits { accessibilityTraits = newAccessibilityTraits; - _flags.setAccessibilityTraits = YES; + _stateToApplyFlags.setAccessibilityTraits = YES; } - (CGRect)accessibilityFrame @@ -706,7 +800,7 @@ - (CGRect)accessibilityFrame - (void)setAccessibilityFrame:(CGRect)newAccessibilityFrame { accessibilityFrame = newAccessibilityFrame; - _flags.setAccessibilityFrame = YES; + _stateToApplyFlags.setAccessibilityFrame = YES; } - (NSString *)accessibilityLanguage @@ -716,41 +810,41 @@ - (NSString *)accessibilityLanguage - (void)setAccessibilityLanguage:(NSString *)newAccessibilityLanguage { - _flags.setAccessibilityLanguage = YES; + _stateToApplyFlags.setAccessibilityLanguage = YES; accessibilityLanguage = newAccessibilityLanguage; } - (BOOL)accessibilityElementsHidden { - return accessibilityElementsHidden; + return _flags.accessibilityElementsHidden; } - (void)setAccessibilityElementsHidden:(BOOL)newAccessibilityElementsHidden { - accessibilityElementsHidden = newAccessibilityElementsHidden; - _flags.setAccessibilityElementsHidden = YES; + _flags.accessibilityElementsHidden = newAccessibilityElementsHidden; + _stateToApplyFlags.setAccessibilityElementsHidden = YES; } - (BOOL)accessibilityViewIsModal { - return accessibilityViewIsModal; + return _flags.accessibilityViewIsModal; } - (void)setAccessibilityViewIsModal:(BOOL)newAccessibilityViewIsModal { - accessibilityViewIsModal = newAccessibilityViewIsModal; - _flags.setAccessibilityViewIsModal = YES; + _flags.accessibilityViewIsModal = newAccessibilityViewIsModal; + _stateToApplyFlags.setAccessibilityViewIsModal = YES; } - (BOOL)shouldGroupAccessibilityChildren { - return shouldGroupAccessibilityChildren; + return _flags.shouldGroupAccessibilityChildren; } - (void)setShouldGroupAccessibilityChildren:(BOOL)newShouldGroupAccessibilityChildren { - shouldGroupAccessibilityChildren = newShouldGroupAccessibilityChildren; - _flags.setShouldGroupAccessibilityChildren = YES; + _flags.shouldGroupAccessibilityChildren = newShouldGroupAccessibilityChildren; + _stateToApplyFlags.setShouldGroupAccessibilityChildren = YES; } - (NSString *)accessibilityIdentifier @@ -760,7 +854,7 @@ - (NSString *)accessibilityIdentifier - (void)setAccessibilityIdentifier:(NSString *)newAccessibilityIdentifier { - _flags.setAccessibilityIdentifier = YES; + _stateToApplyFlags.setAccessibilityIdentifier = YES; if (accessibilityIdentifier != newAccessibilityIdentifier) { accessibilityIdentifier = [newAccessibilityIdentifier copy]; } @@ -773,10 +867,23 @@ - (UIAccessibilityNavigationStyle)accessibilityNavigationStyle - (void)setAccessibilityNavigationStyle:(UIAccessibilityNavigationStyle)newAccessibilityNavigationStyle { - _flags.setAccessibilityNavigationStyle = YES; + _stateToApplyFlags.setAccessibilityNavigationStyle = YES; accessibilityNavigationStyle = newAccessibilityNavigationStyle; } +- (NSArray *)accessibilityCustomActions +{ + return accessibilityCustomActions; +} + +- (void)setAccessibilityCustomActions:(NSArray *)newAccessibilityCustomActions +{ + _stateToApplyFlags.setAccessibilityCustomActions = YES; + if (accessibilityCustomActions != newAccessibilityCustomActions) { + accessibilityCustomActions = [newAccessibilityCustomActions copy]; + } +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" - (NSArray *)accessibilityHeaderElements @@ -786,7 +893,7 @@ - (NSArray *)accessibilityHeaderElements - (void)setAccessibilityHeaderElements:(NSArray *)newAccessibilityHeaderElements { - _flags.setAccessibilityHeaderElements = YES; + _stateToApplyFlags.setAccessibilityHeaderElements = YES; if (accessibilityHeaderElements != newAccessibilityHeaderElements) { accessibilityHeaderElements = [newAccessibilityHeaderElements copy]; } @@ -795,7 +902,7 @@ - (void)setAccessibilityHeaderElements:(NSArray *)newAccessibilityHeaderElements - (CGPoint)accessibilityActivationPoint { - if (_flags.setAccessibilityActivationPoint) { + if (_stateToApplyFlags.setAccessibilityActivationPoint) { return accessibilityActivationPoint; } @@ -805,7 +912,7 @@ - (CGPoint)accessibilityActivationPoint - (void)setAccessibilityActivationPoint:(CGPoint)newAccessibilityActivationPoint { - _flags.setAccessibilityActivationPoint = YES; + _stateToApplyFlags.setAccessibilityActivationPoint = YES; accessibilityActivationPoint = newAccessibilityActivationPoint; } @@ -816,7 +923,7 @@ - (UIBezierPath *)accessibilityPath - (void)setAccessibilityPath:(UIBezierPath *)newAccessibilityPath { - _flags.setAccessibilityPath = YES; + _stateToApplyFlags.setAccessibilityPath = YES; if (accessibilityPath != newAccessibilityPath) { accessibilityPath = newAccessibilityPath; } @@ -824,9 +931,9 @@ - (void)setAccessibilityPath:(UIBezierPath *)newAccessibilityPath - (void)applyToLayer:(CALayer *)layer { - ASPendingStateFlags flags = _flags; + ASPendingStateFlags flags = _stateToApplyFlags; - if (__shouldSetNeedsDisplay(layer)) { + if (__shouldSetNeedsDisplayForLayer(layer)) { [layer setNeedsDisplay]; } @@ -861,16 +968,16 @@ - (void)applyToLayer:(CALayer *)layer layer.rasterizationScale = rasterizationScale; if (flags.setClipsToBounds) - layer.masksToBounds = clipsToBounds; + layer.masksToBounds = _flags.clipsToBounds; if (flags.setBackgroundColor) - layer.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; if (flags.setOpaque) - layer.opaque = opaque; + layer.opaque = _flags.opaque; if (flags.setHidden) - layer.hidden = isHidden; + layer.hidden = _flags.hidden; if (flags.setAlpha) layer.opacity = alpha; @@ -878,6 +985,12 @@ - (void)applyToLayer:(CALayer *)layer if (flags.setCornerRadius) layer.cornerRadius = cornerRadius; + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { + if (flags.setMaskedCorners) { + layer.maskedCorners = maskedCorners; + } + } + if (flags.setContentMode) layer.contentsGravity = ASDisplayNodeCAContentsGravityFromUIContentMode(contentMode); @@ -900,22 +1013,25 @@ - (void)applyToLayer:(CALayer *)layer layer.borderColor = borderColor; if (flags.setNeedsDisplayOnBoundsChange) - layer.needsDisplayOnBoundsChange = needsDisplayOnBoundsChange; + layer.needsDisplayOnBoundsChange = _flags.needsDisplayOnBoundsChange; if (flags.setAllowsGroupOpacity) - layer.allowsGroupOpacity = allowsGroupOpacity; + layer.allowsGroupOpacity = _flags.allowsGroupOpacity; if (flags.setAllowsEdgeAntialiasing) - layer.allowsEdgeAntialiasing = allowsEdgeAntialiasing; + layer.allowsEdgeAntialiasing = _flags.allowsEdgeAntialiasing; if (flags.setEdgeAntialiasingMask) layer.edgeAntialiasingMask = edgeAntialiasingMask; if (flags.setAsyncTransactionContainer) - layer.asyncdisplaykit_asyncTransactionContainer = asyncTransactionContainer; + layer.asyncdisplaykit_asyncTransactionContainer = _flags.asyncTransactionContainer; if (flags.setOpaque) - ASDisplayNodeAssert(layer.opaque == opaque, @"Didn't set opaque as desired"); + ASDisplayNodeAssert(layer.opaque == _flags.opaque, @"Didn't set opaque as desired"); + + if (flags.setActions) + layer.actions = actions; ASPendingStateApplyMetricsToLayer(self, layer); @@ -936,10 +1052,10 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr because a different setter would be called. */ - CALayer *layer = view.layer; + unowned CALayer *layer = view.layer; - ASPendingStateFlags flags = _flags; - if (__shouldSetNeedsDisplay(layer)) { + ASPendingStateFlags flags = _stateToApplyFlags; + if (__shouldSetNeedsDisplayForView(view)) { [view setNeedsDisplay]; } @@ -979,27 +1095,27 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr if (flags.setRasterizationScale) layer.rasterizationScale = rasterizationScale; + if (flags.setActions) + layer.actions = actions; + if (flags.setClipsToBounds) - view.clipsToBounds = clipsToBounds; + view.clipsToBounds = _flags.clipsToBounds; if (flags.setBackgroundColor) { - // We have to make sure certain nodes get the background color call directly set - if (specialPropertiesHandling) { - view.backgroundColor = [UIColor colorWithCGColor:backgroundColor]; - } else { - // Set the background color to the layer as in the UIView bridge we use this value as background color - layer.backgroundColor = backgroundColor; - } + view.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; } if (flags.setTintColor) - view.tintColor = self.tintColor; + view.tintColor = tintColor; - if (flags.setOpaque) - layer.opaque = opaque; + if (flags.setOpaque) { + view.opaque = _flags.opaque; + layer.opaque = _flags.opaque; + } if (flags.setHidden) - view.hidden = isHidden; + view.hidden = _flags.hidden; if (flags.setAlpha) view.alpha = alpha; @@ -1011,11 +1127,11 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr view.contentMode = contentMode; if (flags.setUserInteractionEnabled) - view.userInteractionEnabled = userInteractionEnabled; + view.userInteractionEnabled = _flags.userInteractionEnabled; #if TARGET_OS_IOS if (flags.setExclusiveTouch) - view.exclusiveTouch = exclusiveTouch; + view.exclusiveTouch = _flags.exclusiveTouch; #endif if (flags.setShadowColor) @@ -1040,35 +1156,35 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr view.autoresizingMask = autoresizingMask; if (flags.setAutoresizesSubviews) - view.autoresizesSubviews = autoresizesSubviews; + view.autoresizesSubviews = _flags.autoresizesSubviews; if (flags.setNeedsDisplayOnBoundsChange) - layer.needsDisplayOnBoundsChange = needsDisplayOnBoundsChange; + layer.needsDisplayOnBoundsChange = _flags.needsDisplayOnBoundsChange; if (flags.setAllowsGroupOpacity) - layer.allowsGroupOpacity = allowsGroupOpacity; + layer.allowsGroupOpacity = _flags.allowsGroupOpacity; if (flags.setAllowsEdgeAntialiasing) - layer.allowsEdgeAntialiasing = allowsEdgeAntialiasing; + layer.allowsEdgeAntialiasing = _flags.allowsEdgeAntialiasing; if (flags.setEdgeAntialiasingMask) layer.edgeAntialiasingMask = edgeAntialiasingMask; if (flags.setAsyncTransactionContainer) - view.asyncdisplaykit_asyncTransactionContainer = asyncTransactionContainer; + view.asyncdisplaykit_asyncTransactionContainer = _flags.asyncTransactionContainer; if (flags.setOpaque) - ASDisplayNodeAssert(layer.opaque == opaque, @"Didn't set opaque as desired"); + ASDisplayNodeAssert(layer.opaque == _flags.opaque, @"Didn't set opaque as desired"); if (flags.setLayoutMargins) view.layoutMargins = layoutMargins; if (flags.setPreservesSuperviewLayoutMargins) - view.preservesSuperviewLayoutMargins = preservesSuperviewLayoutMargins; + view.preservesSuperviewLayoutMargins = _flags.preservesSuperviewLayoutMargins; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (flags.setInsetsLayoutMarginsFromSafeArea) { - view.insetsLayoutMarginsFromSafeArea = insetsLayoutMarginsFromSafeArea; + view.insetsLayoutMarginsFromSafeArea = _flags.insetsLayoutMarginsFromSafeArea; } } @@ -1077,7 +1193,7 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr } if (flags.setIsAccessibilityElement) - view.isAccessibilityElement = isAccessibilityElement; + view.isAccessibilityElement = _flags.isAccessibilityElement; if (flags.setAccessibilityLabel) view.accessibilityLabel = accessibilityLabel; @@ -1088,7 +1204,7 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr if (flags.setAccessibilityValue) view.accessibilityValue = accessibilityValue; - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { if (flags.setAccessibilityAttributedLabel) { view.accessibilityAttributedLabel = accessibilityAttributedLabel; } @@ -1110,20 +1226,24 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr view.accessibilityLanguage = accessibilityLanguage; if (flags.setAccessibilityElementsHidden) - view.accessibilityElementsHidden = accessibilityElementsHidden; + view.accessibilityElementsHidden = _flags.accessibilityElementsHidden; if (flags.setAccessibilityViewIsModal) - view.accessibilityViewIsModal = accessibilityViewIsModal; + view.accessibilityViewIsModal = _flags.accessibilityViewIsModal; if (flags.setShouldGroupAccessibilityChildren) - view.shouldGroupAccessibilityChildren = shouldGroupAccessibilityChildren; + view.shouldGroupAccessibilityChildren = _flags.shouldGroupAccessibilityChildren; if (flags.setAccessibilityIdentifier) view.accessibilityIdentifier = accessibilityIdentifier; if (flags.setAccessibilityNavigationStyle) view.accessibilityNavigationStyle = accessibilityNavigationStyle; - + + if (flags.setAccessibilityCustomActions) { + view.accessibilityCustomActions = accessibilityCustomActions; + } + #if TARGET_OS_TV if (flags.setAccessibilityHeaderElements) view.accessibilityHeaderElements = accessibilityHeaderElements; @@ -1173,7 +1293,7 @@ + (_ASPendingState *)pendingViewStateFromLayer:(CALayer *)layer pendingState.contentsScale = layer.contentsScale; pendingState.rasterizationScale = layer.rasterizationScale; pendingState.clipsToBounds = layer.masksToBounds; - pendingState.backgroundColor = layer.backgroundColor; + pendingState.backgroundColor = [UIColor colorWithCGColor:layer.backgroundColor]; pendingState.opaque = layer.opaque; pendingState.hidden = layer.hidden; pendingState.alpha = layer.opacity; @@ -1214,7 +1334,7 @@ + (_ASPendingState *)pendingViewStateFromView:(UIView *)view pendingState.contentsScale = layer.contentsScale; pendingState.rasterizationScale = layer.rasterizationScale; pendingState.clipsToBounds = view.clipsToBounds; - pendingState.backgroundColor = layer.backgroundColor; + pendingState.backgroundColor = view.backgroundColor; pendingState.tintColor = view.tintColor; pendingState.opaque = layer.opaque; pendingState.hidden = view.hidden; @@ -1240,20 +1360,18 @@ + (_ASPendingState *)pendingViewStateFromView:(UIView *)view pendingState.semanticContentAttribute = view.semanticContentAttribute; pendingState.layoutMargins = view.layoutMargins; pendingState.preservesSuperviewLayoutMargins = view.preservesSuperviewLayoutMargins; - if (AS_AVAILABLE_IOS(11)) { + if (AS_AVAILABLE_IOS_TVOS(11, 11)) { pendingState.insetsLayoutMarginsFromSafeArea = view.insetsLayoutMarginsFromSafeArea; } pendingState.isAccessibilityElement = view.isAccessibilityElement; pendingState.accessibilityLabel = view.accessibilityLabel; pendingState.accessibilityHint = view.accessibilityHint; pendingState.accessibilityValue = view.accessibilityValue; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 if (AS_AVAILABLE_IOS_TVOS(11, 11)) { pendingState.accessibilityAttributedLabel = view.accessibilityAttributedLabel; pendingState.accessibilityAttributedHint = view.accessibilityAttributedHint; pendingState.accessibilityAttributedValue = view.accessibilityAttributedValue; } -#endif pendingState.accessibilityTraits = view.accessibilityTraits; pendingState.accessibilityFrame = view.accessibilityFrame; pendingState.accessibilityLanguage = view.accessibilityLanguage; @@ -1262,6 +1380,7 @@ + (_ASPendingState *)pendingViewStateFromView:(UIView *)view pendingState.shouldGroupAccessibilityChildren = view.shouldGroupAccessibilityChildren; pendingState.accessibilityIdentifier = view.accessibilityIdentifier; pendingState.accessibilityNavigationStyle = view.accessibilityNavigationStyle; + pendingState.accessibilityCustomActions = view.accessibilityCustomActions; #if TARGET_OS_TV pendingState.accessibilityHeaderElements = view.accessibilityHeaderElements; #endif @@ -1272,90 +1391,26 @@ + (_ASPendingState *)pendingViewStateFromView:(UIView *)view - (void)clearChanges { - _flags = (ASPendingStateFlags){ 0 }; + _stateToApplyFlags = kZeroFlags; } - (BOOL)hasSetNeedsLayout { - return _flags.needsLayout; + return _stateToApplyFlags.needsLayout; } - (BOOL)hasSetNeedsDisplay { - return _flags.needsDisplay; + return _stateToApplyFlags.needsDisplay; } - (BOOL)hasChanges { - ASPendingStateFlags flags = _flags; - - return (flags.setAnchorPoint - || flags.setPosition - || flags.setZPosition - || flags.setFrame - || flags.setBounds - || flags.setPosition - || flags.setTransform - || flags.setSublayerTransform - || flags.setContents - || flags.setContentsGravity - || flags.setContentsRect - || flags.setContentsCenter - || flags.setContentsScale - || flags.setRasterizationScale - || flags.setClipsToBounds - || flags.setBackgroundColor - || flags.setTintColor - || flags.setHidden - || flags.setAlpha - || flags.setCornerRadius - || flags.setContentMode - || flags.setUserInteractionEnabled - || flags.setExclusiveTouch - || flags.setShadowOpacity - || flags.setShadowOffset - || flags.setShadowRadius - || flags.setShadowColor - || flags.setBorderWidth - || flags.setBorderColor - || flags.setAutoresizingMask - || flags.setAutoresizesSubviews - || flags.setNeedsDisplayOnBoundsChange - || flags.setAllowsGroupOpacity - || flags.setAllowsEdgeAntialiasing - || flags.setEdgeAntialiasingMask - || flags.needsDisplay - || flags.needsLayout - || flags.setAsyncTransactionContainer - || flags.setOpaque - || flags.setSemanticContentAttribute - || flags.setLayoutMargins - || flags.setPreservesSuperviewLayoutMargins - || flags.setInsetsLayoutMarginsFromSafeArea - || flags.setIsAccessibilityElement - || flags.setAccessibilityLabel - || flags.setAccessibilityAttributedLabel - || flags.setAccessibilityHint - || flags.setAccessibilityAttributedHint - || flags.setAccessibilityValue - || flags.setAccessibilityAttributedValue - || flags.setAccessibilityTraits - || flags.setAccessibilityFrame - || flags.setAccessibilityLanguage - || flags.setAccessibilityElementsHidden - || flags.setAccessibilityViewIsModal - || flags.setShouldGroupAccessibilityChildren - || flags.setAccessibilityIdentifier - || flags.setAccessibilityNavigationStyle - || flags.setAccessibilityHeaderElements - || flags.setAccessibilityActivationPoint - || flags.setAccessibilityPath); + return memcmp(&_stateToApplyFlags, &kZeroFlags, sizeof(ASPendingStateFlags)); } - (void)dealloc { - CGColorRelease(backgroundColor); - if (shadowColor != blackColorRef) { CGColorRelease(shadowColor); } diff --git a/Example/Pods/Texture/Source/Private/_ASScopeTimer.h b/Example/Pods/Texture/Source/Private/_ASScopeTimer.h index 543e7c2..523599d 100644 --- a/Example/Pods/Texture/Source/Private/_ASScopeTimer.h +++ b/Example/Pods/Texture/Source/Private/_ASScopeTimer.h @@ -18,14 +18,14 @@ { // some scope - ASDisplayNode::ScopeTimer t(placeToStoreTiming); + AS::ScopeTimer t(placeToStoreTiming); DoPotentiallySlowWork(); MorePotentiallySlowWork(); } */ -namespace ASDN { +namespace AS { struct ScopeTimer { NSTimeInterval begin; NSTimeInterval &outT; diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitAttributes.h b/Example/Pods/Texture/Source/TextKit/ASTextKitAttributes.h index d8c21db..cf09ad6 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitAttributes.h +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitAttributes.h @@ -17,12 +17,12 @@ #import -AS_EXTERN NSString *const ASTextKitTruncationAttributeName; +ASDK_EXTERN NSString *const ASTextKitTruncationAttributeName; /** Use ASTextKitEntityAttribute as the value of this attribute to embed a link or other interactable content inside the text. */ -AS_EXTERN NSString *const ASTextKitEntityAttributeName; +ASDK_EXTERN NSString *const ASTextKitEntityAttributeName; /** All NSObject values in this struct should be copied when passed into the TextComponent. @@ -84,6 +84,10 @@ struct ASTextKitAttributes { */ NSArray *pointSizeScaleFactors; + /** + The tint color to use in drawing the text foreground color. Only applied if the attributedString does not define foreground color + */ + UIColor *tintColor; /** We provide an explicit copy function so we can use aggregate initializer syntax while providing copy semantics for the NSObjects inside. @@ -102,6 +106,7 @@ struct ASTextKitAttributes { shadowOpacity, shadowRadius, pointSizeScaleFactors, + [tintColor copy] }; }; @@ -119,7 +124,8 @@ struct ASTextKitAttributes { && ASObjectIsEqual(avoidTailTruncationSet, other.avoidTailTruncationSet) && ASObjectIsEqual(shadowColor, other.shadowColor) && ASObjectIsEqual(attributedString, other.attributedString) - && ASObjectIsEqual(truncationAttributedString, other.truncationAttributedString); + && ASObjectIsEqual(truncationAttributedString, other.truncationAttributedString) + && ASObjectIsEqual(tintColor, other.tintColor); } size_t hash() const; diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitComponents.mm b/Example/Pods/Texture/Source/TextKit/ASTextKitComponents.mm index eeff176..95ae1db 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitComponents.mm +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitComponents.mm @@ -9,7 +9,6 @@ #import #import -#import #import diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitContext.h b/Example/Pods/Texture/Source/TextKit/ASTextKitContext.h index 82a40b7..df9d0a0 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitContext.h +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitContext.h @@ -30,6 +30,7 @@ AS_SUBCLASSING_RESTRICTED Initialization of TextKit components is a globally locking operation so be careful of bottlenecks with this class. */ - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString + tintColor:(UIColor *)tintColor lineBreakMode:(NSLineBreakMode)lineBreakMode maximumNumberOfLines:(NSUInteger)maximumNumberOfLines exclusionPaths:(NSArray *)exclusionPaths diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitContext.mm b/Example/Pods/Texture/Source/TextKit/ASTextKitContext.mm index 75582f4..8c24644 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitContext.mm +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitContext.mm @@ -14,12 +14,10 @@ #import #import -#include - @implementation ASTextKitContext { // All TextKit operations (even non-mutative ones) must be executed serially. - std::shared_ptr __instanceLock__; + std::shared_ptr __instanceLock__; NSLayoutManager *_layoutManager; NSTextStorage *_textStorage; @@ -27,6 +25,7 @@ @implementation ASTextKitContext } - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString + tintColor:(UIColor *)tintColor lineBreakMode:(NSLineBreakMode)lineBreakMode maximumNumberOfLines:(NSUInteger)maximumNumberOfLines exclusionPaths:(NSArray *)exclusionPaths @@ -34,19 +33,19 @@ - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString { if (self = [super init]) { + static AS::Mutex *mutex = NULL; static dispatch_once_t onceToken; - static ASDN::Mutex *mutex; + // Concurrently initialising TextKit components crashes (rdar://18448377) so we use a global lock. dispatch_once(&onceToken, ^{ - mutex = new ASDN::Mutex(); + mutex = new AS::Mutex(); }); + if (mutex != NULL) { + mutex->lock(); + } - // Concurrently initialising TextKit components crashes (rdar://18448377) so we use a global lock. - ASDN::MutexLocker l(*mutex); - - __instanceLock__ = std::make_shared(); + __instanceLock__ = std::make_shared(); // Create the TextKit component stack with our default configuration. - _textStorage = [[NSTextStorage alloc] init]; _layoutManager = [[ASLayoutManager alloc] init]; _layoutManager.usesFontLeading = NO; @@ -54,8 +53,19 @@ - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString // Instead of calling [NSTextStorage initWithAttributedString:], setting attributedString just after calling addlayoutManager can fix CJK language layout issues. // See https://github.com/facebook/AsyncDisplayKit/issues/2894 - if (attributedString) { + if (attributedString && attributedString.length > 0) { [_textStorage setAttributedString:attributedString]; + + // Apply tint color if specified and if foreground color is undefined for attributedString + NSRange limit = NSMakeRange(0, attributedString.length); + // Look for previous attributes that define foreground color + UIColor *attributeValue = (UIColor *)[attributedString attribute:NSForegroundColorAttributeName atIndex:limit.location effectiveRange:NULL]; + if (attributeValue == nil) { + // None are found, apply tint color if available. Fallback to "black" text color + if (tintColor) { + [_textStorage addAttributes:@{ NSForegroundColorAttributeName : tintColor } range:limit]; + } + } } _textContainer = [[NSTextContainer alloc] initWithSize:constrainedSize]; @@ -65,6 +75,10 @@ - (instancetype)initWithAttributedString:(NSAttributedString *)attributedString _textContainer.maximumNumberOfLines = maximumNumberOfLines; _textContainer.exclusionPaths = exclusionPaths; [_layoutManager addTextContainer:_textContainer]; + + if (mutex != NULL) { + mutex->unlock(); + } } return self; } @@ -73,7 +87,7 @@ - (void)performBlockWithLockedTextKitComponents:(NS_NOESCAPE void (^)(NSLayoutMa NSTextStorage *, NSTextContainer *))block { - ASDN::MutexLocker l(*__instanceLock__); + AS::MutexLocker l(*__instanceLock__); if (block) { block(_layoutManager, _textStorage, _textContainer); } diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.h b/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.h index 9a8f480..0da484d 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.h +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.h @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN - kCTUnderlineColorAttributeName @result Whether attributeName is an unsupported Core Text attribute. */ -AS_EXTERN BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attributeName); +ASDK_EXTERN BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attributeName); /** @@ -54,14 +54,14 @@ AS_EXTERN BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attri - kCTUnderlineColorAttributeName @result An NSDictionary of attributes for use by NSAttributedString. */ -AS_EXTERN NSDictionary *NSAttributedStringAttributesForCoreTextAttributes(NSDictionary *coreTextAttributes); +ASDK_EXTERN NSDictionary *NSAttributedStringAttributesForCoreTextAttributes(NSDictionary *coreTextAttributes); /** @abstract Returns an NSAttributedString whose Core Text attributes have been converted, where possible, to NSAttributedString attributes. @param dirtyAttributedString An NSAttributedString that may contain Core Text attributes. @result An NSAttributedString that's preserved as many CFAttributedString attributes as possible. */ -AS_EXTERN NSAttributedString *ASCleanseAttributedStringOfCoreTextAttributes(NSAttributedString *dirtyAttributedString); +ASDK_EXTERN NSAttributedString *ASCleanseAttributedStringOfCoreTextAttributes(NSAttributedString *dirtyAttributedString); #pragma mark - #pragma mark - diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.mm b/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.mm index e98b236..a6c72d5 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.mm +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitCoreTextAdditions.mm @@ -14,8 +14,6 @@ #import #import -#import - #pragma mark - Public BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attributeName) { @@ -68,16 +66,9 @@ BOOL ASAttributeWithNameIsUnsupportedCoreTextAttribute(NSString *attributeName) // kCTFontAttributeName -> NSFontAttributeName if ([coreTextKey isEqualToString:(NSString *)kCTFontAttributeName]) { + // Its reference type, CTFontRef, is toll-free bridged with UIFont in iOS and NSFont in OS X CTFontRef coreTextFont = (__bridge CTFontRef)coreTextValue; - NSString *fontName = (__bridge_transfer NSString *)CTFontCopyPostScriptName(coreTextFont); - CGFloat fontSize = CTFontGetSize(coreTextFont); - UIFont *font = [UIFont fontWithName:fontName size:fontSize]; - ASDisplayNodeCAssertNotNil(font, @"unable to load font %@ with size %f", fontName, fontSize); - if (font == nil) { - // Gracefully fail if we were unable to load the font. - font = [UIFont systemFontOfSize:fontSize]; - } - cleanAttributes[NSFontAttributeName] = font; + cleanAttributes[NSFontAttributeName] = (__bridge UIFont *)coreTextFont; } // kCTKernAttributeName -> NSKernAttributeName else if ([coreTextKey isEqualToString:(NSString *)kCTKernAttributeName]) { diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitFontSizeAdjuster.mm b/Example/Pods/Texture/Source/TextKit/ASTextKitFontSizeAdjuster.mm index fed70c6..30591a8 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitFontSizeAdjuster.mm +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitFontSizeAdjuster.mm @@ -13,7 +13,6 @@ #if AS_ENABLE_TEXTNODE #import -#import #import #import @@ -33,7 +32,7 @@ @implementation ASTextKitFontSizeAdjuster ASTextKitAttributes _attributes; BOOL _measured; CGFloat _scaleFactor; - ASDN::Mutex __instanceLock__; + AS::Mutex __instanceLock__; } @synthesize sizingLayoutManager = _sizingLayoutManager; @@ -127,7 +126,7 @@ - (CGSize)boundingBoxForString:(NSAttributedString *)attributedString - (NSLayoutManager *)sizingLayoutManager { - ASDN::MutexLocker l(__instanceLock__); + AS::MutexLocker l(__instanceLock__); if (_sizingLayoutManager == nil) { _sizingLayoutManager = [[ASLayoutManager alloc] init]; _sizingLayoutManager.usesFontLeading = NO; diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitRenderer.mm b/Example/Pods/Texture/Source/TextKit/ASTextKitRenderer.mm index b724d70..34895cc 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitRenderer.mm +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitRenderer.mm @@ -17,8 +17,6 @@ #import #import #import -#import -#import //#define LOG(...) NSLog(__VA_ARGS__) #define LOG(...) @@ -61,6 +59,7 @@ - (instancetype)initWithTextKitAttributes:(const ASTextKitAttributes &)attribute CGSize shadowConstrainedSize = [[self shadower] insetSizeWithConstrainedSize:_constrainedSize]; _context = [[ASTextKitContext alloc] initWithAttributedString:attributes.attributedString + tintColor:attributes.tintColor lineBreakMode:attributes.lineBreakMode maximumNumberOfLines:attributes.maximumNumberOfLines exclusionPaths:attributes.exclusionPaths diff --git a/Example/Pods/Texture/Source/TextKit/ASTextKitTailTruncater.mm b/Example/Pods/Texture/Source/TextKit/ASTextKitTailTruncater.mm index b81e27b..0fd8a1c 100644 --- a/Example/Pods/Texture/Source/TextKit/ASTextKitTailTruncater.mm +++ b/Example/Pods/Texture/Source/TextKit/ASTextKitTailTruncater.mm @@ -65,6 +65,7 @@ - (NSUInteger)_calculateCharacterIndexBeforeTruncationMessage:(NSLayoutManager * // Calculate the bounding rectangle for the truncation message ASTextKitContext *truncationContext = [[ASTextKitContext alloc] initWithAttributedString:_truncationAttributedString + tintColor:nil lineBreakMode:NSLineBreakByWordWrapping maximumNumberOfLines:1 exclusionPaths:nil diff --git a/Example/Pods/Texture/Source/UIImage+ASConvenience.h b/Example/Pods/Texture/Source/UIImage+ASConvenience.h index b24c97d..e662a6a 100644 --- a/Example/Pods/Texture/Source/UIImage+ASConvenience.h +++ b/Example/Pods/Texture/Source/UIImage+ASConvenience.h @@ -9,6 +9,7 @@ #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -68,7 +69,20 @@ NS_ASSUME_NONNULL_BEGIN */ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius cornerColor:(nullable UIColor *)cornerColor - fillColor:(UIColor *)fillColor NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + fillColor:(UIColor *)fillColor NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use as_resizableRoundedImageWithCornerRadius:cornerColor:fillColor:traitCollection: instead"); + +/** + * This generates a flat-color, rounded-corner resizeable image + * + * @param cornerRadius The radius of the rounded-corner + * @param cornerColor The fill color of the corners (For Alpha corners use clearColor) + * @param fillColor The fill color of the rounded-corner image + * @param traitCollection The trait collection. + */ ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(nullable UIColor *)cornerColor + fillColor:(UIColor *)fillColor + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; /** * This generates a flat-color, rounded-corner resizeable image with a border @@ -83,7 +97,43 @@ NS_ASSUME_NONNULL_BEGIN cornerColor:(UIColor *)cornerColor fillColor:(UIColor *)fillColor borderColor:(nullable UIColor *)borderColor - borderWidth:(CGFloat)borderWidth NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + borderWidth:(CGFloat)borderWidth NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use as_resizableRoundedImageWithCornerRadius:cornerColor:fillColor:borderColor:borderWidth:traitCollection: instead"); + +/** + * This generates a flat-color, rounded-corner resizeable image with a border + * + * @param cornerRadius The radius of the rounded-corner + * @param cornerColor The fill color of the corners (For Alpha corners use clearColor) + * @param fillColor The fill color of the rounded-corner image + * @param borderColor The border color. Set to nil for no border. + * @param borderWidth The border width. Dummy value if borderColor = nil. + * @param traitCollection The trait collection. + */ ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(nullable UIColor *)borderColor + borderWidth:(CGFloat)borderWidth traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + +/** + * This generates a flat-color, rounded-corner resizeable image with a border + * + * @param cornerRadius The radius of the rounded-corner + * @param cornerColor The fill color of the corners (For Alpha corners use clearColor) + * @param fillColor The fill color of the rounded-corner image + * @param borderColor The border color. Set to nil for no border. + * @param borderWidth The border width. Dummy value if borderColor = nil. + * @param roundedCorners Select individual or multiple corners to round. Set to UIRectCornerAllCorners to round all 4 corners. + * @param scale The number of pixels per point. Provide 0.0 to use the screen scale. + */ ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(nullable UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(nullable UIColor *)borderColor + borderWidth:(CGFloat)borderWidth + roundedCorners:(UIRectCorner)roundedCorners + scale:(CGFloat)scale NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT ASDISPLAYNODE_DEPRECATED_MSG("Use as_resizableRoundedImageWithCornerRadius:cornerColor:fillColor:borderColor:borderWidth:roundedCorners:traitCollection: instead"); +; /** * This generates a flat-color, rounded-corner resizeable image with a border @@ -95,6 +145,7 @@ NS_ASSUME_NONNULL_BEGIN * @param borderWidth The border width. Dummy value if borderColor = nil. * @param roundedCorners Select individual or multiple corners to round. Set to UIRectCornerAllCorners to round all 4 corners. * @param scale The number of pixels per point. Provide 0.0 to use the screen scale. + * @param traitCollection The trait collection. */ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius cornerColor:(nullable UIColor *)cornerColor @@ -102,7 +153,9 @@ NS_ASSUME_NONNULL_BEGIN borderColor:(nullable UIColor *)borderColor borderWidth:(CGFloat)borderWidth roundedCorners:(UIRectCorner)roundedCorners - scale:(CGFloat)scale NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; + scale:(CGFloat)scale + traitCollection:(ASPrimitiveTraitCollection) traitCollection +NS_RETURNS_RETAINED AS_WARN_UNUSED_RESULT; @end diff --git a/Example/Pods/Texture/Source/UIImage+ASConvenience.mm b/Example/Pods/Texture/Source/UIImage+ASConvenience.mm index 936514c..cc5896b 100644 --- a/Example/Pods/Texture/Source/UIImage+ASConvenience.mm +++ b/Example/Pods/Texture/Source/UIImage+ASConvenience.mm @@ -9,8 +9,6 @@ #import #import -#import -#import #pragma mark - ASDKFastImageNamed @@ -32,7 +30,12 @@ @implementation UIImage (ASDKFastImageNamed) NSString *imageKey = imageName; if (traitCollection) { char imageKeyBuffer[256]; - snprintf(imageKeyBuffer, sizeof(imageKeyBuffer), "%s|%ld|%ld", imageName.UTF8String, (long)traitCollection.horizontalSizeClass, (long)traitCollection.verticalSizeClass); + if (@available(iOS 12.0, tvOS 10.0, *)) { + snprintf(imageKeyBuffer, sizeof(imageKeyBuffer), "%s|%ld|%ld|%ld", imageName.UTF8String, (long)traitCollection.horizontalSizeClass, (long)traitCollection.verticalSizeClass, (long)traitCollection.userInterfaceStyle); + } else { + // Fallback on earlier versions + snprintf(imageKeyBuffer, sizeof(imageKeyBuffer), "%s|%ld|%ld", imageName.UTF8String, (long)traitCollection.horizontalSizeClass, (long)traitCollection.verticalSizeClass); + } imageKey = [NSString stringWithUTF8String:imageKeyBuffer]; } @@ -76,6 +79,38 @@ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius scale:0.0]; } ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED +{ + return [self as_resizableRoundedImageWithCornerRadius:cornerRadius + cornerColor:cornerColor + fillColor:fillColor + borderColor:nil + borderWidth:1.0 + roundedCorners:UIRectCornerAllCorners + scale:0.0 + traitCollection:traitCollection]; +} + ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(UIColor *)borderColor + borderWidth:(CGFloat)borderWidth + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED { + return [self as_resizableRoundedImageWithCornerRadius:cornerRadius + cornerColor:cornerColor + fillColor:fillColor + borderColor:borderColor + borderWidth:borderWidth + roundedCorners:UIRectCornerAllCorners + scale:0.0 + traitCollection:traitCollection]; +} + + + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius cornerColor:(UIColor *)cornerColor fillColor:(UIColor *)fillColor @@ -97,7 +132,27 @@ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth roundedCorners:(UIRectCorner)roundedCorners - scale:(CGFloat)scale NS_RETURNS_RETAINED + scale:(CGFloat)scale NS_RETURNS_RETAINED { + + return [self as_resizableRoundedImageWithCornerRadius:cornerRadius + cornerColor:cornerColor + fillColor:fillColor + borderColor:borderColor + borderWidth:borderWidth + roundedCorners:roundedCorners + scale:scale + traitCollection:ASPrimitiveTraitCollectionMakeDefault()]; +} + + ++ (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius + cornerColor:(UIColor *)cornerColor + fillColor:(UIColor *)fillColor + borderColor:(UIColor *)borderColor + borderWidth:(CGFloat)borderWidth + roundedCorners:(UIRectCorner)roundedCorners + scale:(CGFloat)scale + traitCollection:(ASPrimitiveTraitCollection) traitCollection NS_RETURNS_RETAINED { static NSCache *__pathCache = nil; static dispatch_once_t onceToken; @@ -131,37 +186,35 @@ + (UIImage *)as_resizableRoundedImageWithCornerRadius:(CGFloat)cornerRadius // We should probably check if the background color has any alpha component but that // might be expensive due to needing to check mulitple color spaces. - ASGraphicsBeginImageContextWithOptions(bounds.size, cornerColor != nil, scale); - - BOOL contextIsClean = YES; - if (cornerColor) { - contextIsClean = NO; - [cornerColor setFill]; - // Copy "blend" mode is extra fast because it disregards any value currently in the buffer and overrides directly. - UIRectFillUsingBlendMode(bounds, kCGBlendModeCopy); - } - - BOOL canUseCopy = contextIsClean || (CGColorGetAlpha(fillColor.CGColor) == 1); - [fillColor setFill]; - [path fillWithBlendMode:(canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal) alpha:1]; - - if (borderColor) { - [borderColor setStroke]; - - // Inset border fully inside filled path (not halfway on each side of path) - CGRect strokeRect = CGRectInset(bounds, borderWidth / 2.0, borderWidth / 2.0); - - // It is rarer to have a stroke path, and our cache key only handles rounded rects for the exact-stretchable - // size calculated by cornerRadius, so we won't bother caching this path. Profiling validates this decision. - UIBezierPath *strokePath = [UIBezierPath bezierPathWithRoundedRect:strokeRect - byRoundingCorners:roundedCorners - cornerRadii:cornerRadii]; - [strokePath setLineWidth:borderWidth]; - BOOL canUseCopy = (CGColorGetAlpha(borderColor.CGColor) == 1); - [strokePath strokeWithBlendMode:(canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal) alpha:1]; - } - - UIImage *result = ASGraphicsGetImageAndEndCurrentContext(); + UIImage *result = ASGraphicsCreateImage(traitCollection, bounds.size, cornerColor != nil, scale, nil, nil, ^{ + BOOL contextIsClean = YES; + if (cornerColor) { + contextIsClean = NO; + [cornerColor setFill]; + // Copy "blend" mode is extra fast because it disregards any value currently in the buffer and overrides directly. + UIRectFillUsingBlendMode(bounds, kCGBlendModeCopy); + } + + BOOL canUseCopy = contextIsClean || (CGColorGetAlpha(fillColor.CGColor) == 1); + [fillColor setFill]; + [path fillWithBlendMode:(canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal) alpha:1]; + + if (borderColor) { + [borderColor setStroke]; + + // Inset border fully inside filled path (not halfway on each side of path) + CGRect strokeRect = CGRectInset(bounds, borderWidth / 2.0, borderWidth / 2.0); + + // It is rarer to have a stroke path, and our cache key only handles rounded rects for the exact-stretchable + // size calculated by cornerRadius, so we won't bother caching this path. Profiling validates this decision. + UIBezierPath *strokePath = [UIBezierPath bezierPathWithRoundedRect:strokeRect + byRoundingCorners:roundedCorners + cornerRadii:cornerRadii]; + [strokePath setLineWidth:borderWidth]; + BOOL canUseCopy = (CGColorGetAlpha(borderColor.CGColor) == 1); + [strokePath strokeWithBlendMode:(canUseCopy ? kCGBlendModeCopy : kCGBlendModeNormal) alpha:1]; + } + }); UIEdgeInsets capInsets = UIEdgeInsetsMake(cornerRadius, cornerRadius, cornerRadius, cornerRadius); result = [result resizableImageWithCapInsets:capInsets resizingMode:UIImageResizingModeStretch]; diff --git a/Example/Pods/Texture/Source/UIResponder+AsyncDisplayKit.mm b/Example/Pods/Texture/Source/UIResponder+AsyncDisplayKit.mm index 8c3ec24..957e64b 100644 --- a/Example/Pods/Texture/Source/UIResponder+AsyncDisplayKit.mm +++ b/Example/Pods/Texture/Source/UIResponder+AsyncDisplayKit.mm @@ -10,7 +10,6 @@ #import "UIResponder+AsyncDisplayKit.h" #import -#import #import @implementation UIResponder (AsyncDisplayKit) diff --git a/Example/Zoomy.xcodeproj/project.pbxproj b/Example/Zoomy.xcodeproj/project.pbxproj index 8413d32..51d7f36 100644 --- a/Example/Zoomy.xcodeproj/project.pbxproj +++ b/Example/Zoomy.xcodeproj/project.pbxproj @@ -412,7 +412,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0930; - LastUpgradeCheck = 1030; + LastUpgradeCheck = 1250; ORGANIZATIONNAME = CocoaPods; TargetAttributes = { 607FACCF1AFB9204008FA782 = { @@ -691,6 +691,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -716,7 +717,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -747,6 +748,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -765,7 +767,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -780,7 +782,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = P6ZSWCNHR5; INFOPLIST_FILE = Zoomy/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; @@ -796,7 +798,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = P6ZSWCNHR5; INFOPLIST_FILE = Zoomy/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; @@ -860,7 +862,7 @@ DEVELOPMENT_TEAM = P6ZSWCNHR5; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Zoomy_ExampleUITests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "MennoLovink.Zoomy-ExampleUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -885,7 +887,7 @@ DEVELOPMENT_TEAM = P6ZSWCNHR5; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Zoomy_ExampleUITests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "MennoLovink.Zoomy-ExampleUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Example/Zoomy.xcodeproj/xcshareddata/xcschemes/Zoomy-Example.xcscheme b/Example/Zoomy.xcodeproj/xcshareddata/xcschemes/Zoomy-Example.xcscheme index 4c6bf8d..972f77e 100644 --- a/Example/Zoomy.xcodeproj/xcshareddata/xcschemes/Zoomy-Example.xcscheme +++ b/Example/Zoomy.xcodeproj/xcshareddata/xcschemes/Zoomy-Example.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -63,17 +72,6 @@ - - - - - - - - , MosaicCollectionViewLayoutDelegate, ASCollectionDataSource, ASCollectionDelegate { +class ImageCollectionTextureViewController: ASDKViewController, MosaicCollectionViewLayoutDelegate, ASCollectionDataSource, ASCollectionDelegate { var _sections = [[UIImage]]() let _collectionNode: ASCollectionNode let _layoutInspector = MosaicCollectionViewLayoutInspector() - init() { + override init() { let layout = MosaicCollectionViewLayout() layout.numberOfColumns = 3; layout.headerHeight = 44; diff --git a/Example/Zoomy/SingleImageTextureViewController.swift b/Example/Zoomy/SingleImageTextureViewController.swift index c6a9d35..a50fa93 100644 --- a/Example/Zoomy/SingleImageTextureViewController.swift +++ b/Example/Zoomy/SingleImageTextureViewController.swift @@ -10,12 +10,12 @@ import UIKit import AsyncDisplayKit import Zoomy -class SingleImageTextureViewController: ASViewController { +class SingleImageTextureViewController: ASDKViewController { let backgroundNode = ASDisplayNode() let imageNode = ASImageNode() - init() { + override init() { super.init(node: backgroundNode) } diff --git a/Package.swift b/Package.swift index 350abe1..dad5599 100644 --- a/Package.swift +++ b/Package.swift @@ -10,7 +10,7 @@ let package = Package( .library(name: "Zoomy", targets: ["Zoomy"]) ], dependencies: [ - .package(url: "https://github.com/lvnkmn/InjectableLoggers", from: "2.1.0"), + .package(url: "https://github.com/CuratoOpenSource/InjectableLoggers", from: "2.1.0"), ], targets: [ .target( diff --git a/README.md b/README.md index cbb81ef..879c7ec 100644 --- a/README.md +++ b/README.md @@ -120,12 +120,7 @@ There may not always be time for personal support on how to implement Zoomy in d ## Installation -Zoomy is available through [CocoaPods](http://cocoapods.org). To install -it, simply add the following line to your Podfile: - -```ruby -pod 'Zoomy' -``` +Zoomy is available through [Swift Package Manager](https://swift.org/package-manager/). To install it, simply add it to your project using this repository's URL as explained [here](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app). ## Credits & Acknowledgements diff --git a/Zoomy.podspec b/Zoomy.podspec index 4577bac..bb53066 100644 --- a/Zoomy.podspec +++ b/Zoomy.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.author = { 'Menno Lovink' => 'mclovink@me.com' } s.source = { :git => 'https://github.com/lvnkmn/Zoomy.git', :tag => s.version.to_s } - s.ios.deployment_target = '8.0' + s.ios.deployment_target = '9.0' s.source_files = 'Zoomy/Classes/**/*' diff --git a/Zoomy/Classes/ExtendedProtocols/HasImageZoomControllers.swift b/Zoomy/Classes/ExtendedProtocols/HasImageZoomControllers.swift index 4c37369..8a215dd 100644 --- a/Zoomy/Classes/ExtendedProtocols/HasImageZoomControllers.swift +++ b/Zoomy/Classes/ExtendedProtocols/HasImageZoomControllers.swift @@ -1,6 +1,6 @@ import UIKit -public protocol HasImageZoomControllers: class { +public protocol HasImageZoomControllers: AnyObject { var imageZoomControllers: [UIView: ImageZoomController] { get set } } diff --git a/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerDelegate.swift b/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerDelegate.swift index 34457b5..a627381 100644 --- a/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerDelegate.swift +++ b/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerDelegate.swift @@ -1,6 +1,6 @@ import UIKit -public protocol ImageZoomControllerDelegate: class { +public protocol ImageZoomControllerDelegate: AnyObject { func didBeginPresentingOverlay(for imageView: Zoomable) func didEndPresentingOverlay(for imageView: Zoomable) diff --git a/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerState.swift b/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerState.swift index 56af73f..ea01fee 100644 --- a/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerState.swift +++ b/Zoomy/Classes/ExtendedProtocols/ImageZoomControllerState.swift @@ -1,6 +1,6 @@ import UIKit -internal protocol ImageZoomControllerState: class { +internal protocol ImageZoomControllerState: AnyObject { func presentOverlay() func dismissOverlay() func zoomToFit() diff --git a/Zoomy/Classes/Protocols/Zoomable.swift b/Zoomy/Classes/Protocols/Zoomable.swift index c127c26..f4e36ea 100644 --- a/Zoomy/Classes/Protocols/Zoomable.swift +++ b/Zoomy/Classes/Protocols/Zoomable.swift @@ -1,6 +1,6 @@ import UIKit -public protocol Zoomable: class { +public protocol Zoomable: AnyObject { var image: UIImage? { get } var view: UIView { get }