diff --git a/Source/ASControlNode.mm b/Source/ASControlNode.mm index 6336d994..4bc0ae60 100644 --- a/Source/ASControlNode.mm +++ b/Source/ASControlNode.mm @@ -15,6 +15,9 @@ #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 diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 45f3df87..20643f95 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -436,7 +436,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__); - (void)asyncTraitCollectionDidChangeWithPreviousTraitCollection:(ASPrimitiveTraitCollection)previousTraitCollection { - if (@available(iOS 13.0, *)) { + 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(); diff --git a/Source/ASViewController.mm b/Source/ASViewController.mm index 672d9042..8b889dfc 100644 --- a/Source/ASViewController.mm +++ b/Source/ASViewController.mm @@ -286,7 +286,7 @@ ASVisibilityDepthImplementation; - (UIEdgeInsets)additionalSafeAreaInsets { - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { return super.additionalSafeAreaInsets; } @@ -295,7 +295,7 @@ ASVisibilityDepthImplementation; - (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; diff --git a/Source/Details/ASGraphicsContext.mm b/Source/Details/ASGraphicsContext.mm index fbd23ddc..8f543e06 100644 --- a/Source/Details/ASGraphicsContext.mm +++ b/Source/Details/ASGraphicsContext.mm @@ -15,7 +15,7 @@ #if AS_AT_LEAST_IOS13 #define ASPerformBlockWithTraitCollection(work, traitCollection) \ - if (@available(iOS 13.0, *)) { \ + if (@available(iOS 13.0, tvOS 13.0, *)) { \ UITraitCollection *uiTraitCollection = ASPrimitiveTraitCollectionToUITraitCollection(traitCollection); \ [uiTraitCollection performAsCurrentTraitCollection:^{ \ work(); \ diff --git a/Source/Details/ASRecursiveUnfairLock.mm b/Source/Details/ASRecursiveUnfairLock.mm index b3297333..d6eb1886 100644 --- a/Source/Details/ASRecursiveUnfairLock.mm +++ b/Source/Details/ASRecursiveUnfairLock.mm @@ -18,16 +18,19 @@ #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"); } diff --git a/Source/Details/ASThread.h b/Source/Details/ASThread.h index cb840e16..0ef3d325 100644 --- a/Source/Details/ASThread.h +++ b/Source/Details/ASThread.h @@ -159,7 +159,11 @@ namespace AS { 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) { @@ -180,7 +184,11 @@ namespace AS { 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(); @@ -199,7 +207,11 @@ namespace AS { 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; } } @@ -225,7 +237,11 @@ namespace AS { 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(); diff --git a/Source/Details/ASTraitCollection.mm b/Source/Details/ASTraitCollection.mm index 39c1615d..8a697ecc 100644 --- a/Source/Details/ASTraitCollection.mm +++ b/Source/Details/ASTraitCollection.mm @@ -33,7 +33,7 @@ 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; @@ -48,7 +48,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionMakeDefault() { } #endif - if (AS_AVAILABLE_IOS(13)) { + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { tc.accessibilityContrast = UIAccessibilityContrastUnspecified; tc.legibilityWeight = UILegibilityWeightUnspecified; } @@ -62,7 +62,7 @@ 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; @@ -79,7 +79,7 @@ ASPrimitiveTraitCollection ASPrimitiveTraitCollectionFromUITraitCollection(UITra } #endif - if (AS_AVAILABLE_IOS(13)) { + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { environmentTraitCollection.accessibilityContrast = traitCollection.accessibilityContrast; environmentTraitCollection.legibilityWeight = traitCollection.legibilityWeight; } @@ -95,7 +95,7 @@ AS_EXTERN UITraitCollection * ASPrimitiveTraitCollectionToUITraitCollection(ASPr [UITraitCollection traitCollectionWithForceTouchCapability:traitCollection.forceTouchCapability], ]]; - if (AS_AVAILABLE_IOS(10)) { + 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]]; @@ -191,8 +191,9 @@ ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUIUserInterfaceStyle(UIUserInterfa } } +#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)) API_UNAVAILABLE(tvos) +API_AVAILABLE(ios(13)) ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentUserInterfaceLevel(UIUserInterfaceLevel userInterfaceLevel) { switch (userInterfaceLevel) { case UIUserInterfaceLevelBase: @@ -203,6 +204,7 @@ ASDISPLAYNODE_INLINE NSString *AS_NSStringFromUITraitEnvironmentUserInterfaceLev 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)) @@ -242,7 +244,7 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai if (AS_AVAILABLE_IOS_TVOS(12, 10)) { [props addObject:@{ @"userInterfaceStyle": AS_NSStringFromUIUserInterfaceStyle(traits.userInterfaceStyle) }]; } - if (AS_AVAILABLE_IOS(10)) { + if (AS_AVAILABLE_IOS_TVOS(10, 10)) { [props addObject:@{ @"layoutDirection": AS_NSStringFromUITraitEnvironmentLayoutDirection(traits.layoutDirection) }]; if (traits.preferredContentSizeCategory != nil) { [props addObject:@{ @"preferredContentSizeCategory": traits.preferredContentSizeCategory }]; @@ -256,7 +258,7 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai } #endif - if (AS_AVAILABLE_IOS(13)) { + if (AS_AVAILABLE_IOS_TVOS(13, 13)) { [props addObject:@{ @"accessibilityContrast": AS_NSStringFromUITraitEnvironmentAccessibilityContrast(traits.accessibilityContrast) }]; [props addObject:@{ @"legibilityWeight": AS_NSStringFromUITraitEnvironmentLegibilityWeight(traits.legibilityWeight) }]; } @@ -272,7 +274,7 @@ NSString *NSStringFromASPrimitiveTraitCollection(ASPrimitiveTraitCollection trai + (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; diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 50641d80..42dbbfcb 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -1005,7 +1005,7 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo { _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; } @@ -1029,7 +1029,7 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo _flags.fallbackInsetsLayoutMarginsFromSafeArea = insetsLayoutMarginsFromSafeArea; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (!_flags.layerBacked) { _setToViewOnly(insetsLayoutMarginsFromSafeArea, insetsLayoutMarginsFromSafeArea); } @@ -1106,7 +1106,7 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo - (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); } diff --git a/Source/Private/ASIGListAdapterBasedDataSource.mm b/Source/Private/ASIGListAdapterBasedDataSource.mm index 2f89b42c..10f51f37 100644 --- a/Source/Private/ASIGListAdapterBasedDataSource.mm +++ b/Source/Private/ASIGListAdapterBasedDataSource.mm @@ -166,7 +166,7 @@ typedef struct { { NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; UIView *contentView = node.view.superview; - UICollectionViewCell *cell = contentView.superview; + UICollectionViewCell *cell = (UICollectionViewCell *)contentView.superview; if (cell == nil || indexPath == nil) { return; @@ -179,7 +179,7 @@ typedef struct { { NSIndexPath *indexPath = [collectionNode.view indexPathForNode:node]; UIView *contentView = node.view.superview; - UICollectionViewCell *cell = contentView.superview; + UICollectionViewCell *cell = (UICollectionViewCell *)contentView.superview; if (cell == nil || indexPath == nil) { return; diff --git a/Source/Private/_ASPendingState.mm b/Source/Private/_ASPendingState.mm index 8593bd58..a9d760e9 100644 --- a/Source/Private/_ASPendingState.mm +++ b/Source/Private/_ASPendingState.mm @@ -1182,7 +1182,7 @@ static CGColorRef blackColorRef = NULL; if (flags.setPreservesSuperviewLayoutMargins) view.preservesSuperviewLayoutMargins = _flags.preservesSuperviewLayoutMargins; - if (AS_AVAILABLE_IOS(11.0)) { + if (AS_AVAILABLE_IOS_TVOS(11.0, 11.0)) { if (flags.setInsetsLayoutMarginsFromSafeArea) { view.insetsLayoutMarginsFromSafeArea = _flags.insetsLayoutMarginsFromSafeArea; } diff --git a/Source/UIImage+ASConvenience.mm b/Source/UIImage+ASConvenience.mm index 567a377c..cc5896b4 100644 --- a/Source/UIImage+ASConvenience.mm +++ b/Source/UIImage+ASConvenience.mm @@ -30,7 +30,7 @@ UIImage *cachedImageNamed(NSString *imageName, UITraitCollection *traitCollectio NSString *imageKey = imageName; if (traitCollection) { char imageKeyBuffer[256]; - if (@available(iOS 12.0, *)) { + 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 diff --git a/Texture.podspec b/Texture.podspec index 51f637aa..d1df1c90 100644 --- a/Texture.podspec +++ b/Texture.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # Subspecs spec.subspec 'Core' do |core| - core.compiler_flags = '-fno-exceptions -Wno-implicit-retain-self' + core.compiler_flags = '-fno-exceptions' core.public_header_files = [ 'Source/*.h', 'Source/Details/**/*.h', diff --git a/build.sh b/build.sh index b2115aa5..3f4fb278 100755 --- a/build.sh +++ b/build.sh @@ -66,7 +66,7 @@ function build_example { # Lint subspec function lint_subspec { - set -o pipefail && pod env && pod lib lint --allow-warnings --subspec="$1" + set -o pipefail && pod env && pod lib lint --subspec="$1" } function cleanup { @@ -218,7 +218,7 @@ framework|all) cocoapods-lint|all) echo "Verifying that podspec lints." - set -o pipefail && pod env && pod lib lint --allow-warnings + set -o pipefail && pod env && pod lib lint success="1" ;;