diff --git a/ios/ReactTestApp.xcodeproj/project.pbxproj b/ios/ReactTestApp.xcodeproj/project.pbxproj index 208dd7464..f5f8449e9 100644 --- a/ios/ReactTestApp.xcodeproj/project.pbxproj +++ b/ios/ReactTestApp.xcodeproj/project.pbxproj @@ -7,15 +7,15 @@ objects = { /* Begin PBXBuildFile section */ - 1914199A234B2DD800D856AE /* RCTDevSupport+UIScene.m in Sources */ = {isa = PBXBuildFile; fileRef = 19141999234B2DD800D856AE /* RCTDevSupport+UIScene.m */; }; + 19ECD0D6232ED425003D8557 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D5232ED425003D8557 /* AppDelegate.swift */; }; + 19ECD0DA232ED425003D8557 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D9232ED425003D8557 /* ContentView.swift */; }; 192DD201240FCAF5004E9CEB /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 192DD200240FCAF5004E9CEB /* Manifest.swift */; }; - 196C22622490CB7600449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22602490CB7600449D3C /* React+Compatibility.m */; }; - 196C7215232F1788006556ED /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196C7214232F1788006556ED /* ReactInstance.swift */; }; 196C724123319A85006556ED /* QRCodeReaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196C724023319A85006556ED /* QRCodeReaderDelegate.swift */; }; - 1988284524105BEC005057FF /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1988284424105BEC005057FF /* UIViewController+ReactTestApp.m */; }; - 19ECD0D6232ED425003D8557 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D5232ED425003D8557 /* AppDelegate.swift */; }; + 196C7215232F1788006556ED /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196C7214232F1788006556ED /* ReactInstance.swift */; }; 19ECD0D8232ED425003D8557 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D7232ED425003D8557 /* SceneDelegate.swift */; }; - 19ECD0DA232ED425003D8557 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D9232ED425003D8557 /* ContentView.swift */; }; + 1914199A234B2DD800D856AE /* RCTDevSupport+UIScene.m in Sources */ = {isa = PBXBuildFile; fileRef = 19141999234B2DD800D856AE /* RCTDevSupport+UIScene.m */; }; + 196C22622490CB7600449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22602490CB7600449D3C /* React+Compatibility.m */; }; + 1988284524105BEC005057FF /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1988284424105BEC005057FF /* UIViewController+ReactTestApp.m */; }; 19ECD0DC232ED427003D8557 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 19ECD0DB232ED427003D8557 /* Assets.xcassets */; }; 19ECD0E2232ED427003D8557 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 19ECD0E0232ED427003D8557 /* LaunchScreen.storyboard */; }; 19ECD0ED232ED428003D8557 /* ReactTestAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0EC232ED428003D8557 /* ReactTestAppTests.swift */; }; @@ -220,8 +220,8 @@ 19ECD0CA232ED425003D8557 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1100; - LastUpgradeCheck = 1220; + LastSwiftUpdateCheck = 1230; + LastUpgradeCheck = 1230; ORGANIZATIONNAME = Microsoft; TargetAttributes = { 19ECD0D1232ED425003D8557 = { diff --git a/ios/ReactTestApp/RCTDevSupport+UIScene.m b/ios/ReactTestApp/RCTDevSupport+UIScene.m index 019591e9f..1a3a70f3f 100644 --- a/ios/ReactTestApp/RCTDevSupport+UIScene.m +++ b/ios/ReactTestApp/RCTDevSupport+UIScene.m @@ -14,26 +14,9 @@ #import #import -#if DEBUG +#import "React+Compatibility.h" -void swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) -{ - Method originalMethod = class_getInstanceMethod(class, originalSelector); - Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); - - BOOL didAddMethod = class_addMethod(class, - originalSelector, - method_getImplementation(swizzledMethod), - method_getTypeEncoding(swizzledMethod)); - if (didAddMethod) { - class_replaceMethod(class, - swizzledSelector, - method_getImplementation(originalMethod), - method_getTypeEncoding(originalMethod)); - } else { - method_exchangeImplementations(originalMethod, swizzledMethod); - } -} +#if DEBUG // MARK: - RCTRedBoxWindow @@ -56,11 +39,11 @@ + (void)load static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; - swizzleSelector(class, - @selector(showErrorMessage:withStack:isUpdate:), - @selector(rta_showErrorMessage:withStack:isUpdate:)); - swizzleSelector(class, @selector(dismiss), @selector(rta_dismiss)); - swizzleSelector(class, @selector(makeKeyAndVisible), @selector(rta_makeKeyAndVisible)); + RTASwizzleSelector(class, + @selector(showErrorMessage:withStack:isUpdate:), + @selector(rta_showErrorMessage:withStack:isUpdate:)); + RTASwizzleSelector(class, @selector(dismiss), @selector(rta_dismiss)); + RTASwizzleSelector(class, @selector(makeKeyAndVisible), @selector(rta_makeKeyAndVisible)); }); } @@ -103,9 +86,9 @@ + (void)initialize } if (@available(iOS 13.0, *)) { - swizzleSelector([self class], - @selector(showMessage:color:backgroundColor:), - @selector(rta_showMessage:color:backgroundColor:)); + RTASwizzleSelector([self class], + @selector(showMessage:color:backgroundColor:), + @selector(rta_showMessage:color:backgroundColor:)); } } diff --git a/ios/ReactTestApp/React+Compatibility.h b/ios/ReactTestApp/React+Compatibility.h index 1e3ae39e0..07697e5ce 100644 --- a/ios/ReactTestApp/React+Compatibility.h +++ b/ios/ReactTestApp/React+Compatibility.h @@ -9,4 +9,6 @@ @class RCTBridge; +IMP RTASwizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector); + void RTATriggerReloadCommand(RCTBridge *, NSString *reason); diff --git a/ios/ReactTestApp/React+Compatibility.m b/ios/ReactTestApp/React+Compatibility.m index 2392fca81..cd048151f 100644 --- a/ios/ReactTestApp/React+Compatibility.m +++ b/ios/ReactTestApp/React+Compatibility.m @@ -9,8 +9,33 @@ #include +#import + #import +IMP RTASwizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) +{ + Method originalMethod = class_getInstanceMethod(class, originalSelector); + IMP originalImpl = method_getImplementation(originalMethod); + + Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); + + BOOL didAddMethod = class_addMethod(class, + originalSelector, + method_getImplementation(swizzledMethod), + method_getTypeEncoding(swizzledMethod)); + if (didAddMethod) { + const char *type = method_getTypeEncoding(originalMethod); + class_replaceMethod(class, swizzledSelector, originalImpl, type); + } else { + method_exchangeImplementations(originalMethod, swizzledMethod); + } + + return originalImpl; +} + +// MARK: - [0.62] RCTTriggerReloadCommandListeners replaces -[RCTBridge reload] + // `RCTReloadCommand.h` is excluded from `react-native-macos` // See https://github.com/microsoft/react-native-macos/blob/v0.61.39/React-Core.podspec#L66 #if REACT_NATIVE_VERSION >= 6200 @@ -25,3 +50,64 @@ void RTATriggerReloadCommand(RCTBridge *bridge, NSString *reason) RCTTriggerReloadCommandListeners(reason); #endif } + +// MARK: - [0.63.2] Images do not render on iOS 14 +// See https://github.com/facebook/react-native/pull/29420 + +#if !TARGET_OS_OSX && REACT_NATIVE_VERSION < 6302 + +#import + +@implementation RCTUIImageViewAnimated (ReactTestApp) + +static void (*orig_displayLayer)(id, SEL, CALayer *); + ++ (void)initialize +{ + if ([self class] != [RCTUIImageViewAnimated class]) { + return; + } + + if (@available(iOS 14.0, *)) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + IMP impl = RTASwizzleSelector( + [self class], @selector(displayLayer:), @selector(rta_displayLayer:)); + orig_displayLayer = (void (*)(id, SEL, CALayer *))impl; + }); + } +} + +- (void)rta_displayLayer:(CALayer *)layer +{ + /* The fix for images not rendering is to let UIImageView handle it when we + * are not animating. The following change was made in react-native#29420: + * + * diff --git a/Libraries/Image/RCTUIImageViewAnimated.m b/Libraries/Image/RCTUIImageViewAnimated.m + * index 93c6a2f02f5..f6fb5bc60cc 100644 + * --- a/Libraries/Image/RCTUIImageViewAnimated.m + * +++ b/Libraries/Image/RCTUIImageViewAnimated.m + * @@ -285,6 +285,8 @@ static NSUInteger RCTDeviceFreeMemory() { + * if (_currentFrame) { + * layer.contentsScale = self.animatedImageScale; + * layer.contents = (__bridge id)_currentFrame.CGImage; + * + } else { + * + [super displayLayer:layer]; + * } + * } + * + * The patch calls `super` when `_currentFrame` is `nil`. For our monkey + * patch, we'll invert the logic to let the original method handle the case + * where `_currentFrame` is missing. + */ + if ([self respondsToSelector:@selector(currentFrame)] && + [self performSelector:@selector(currentFrame)] == nil) { + [super displayLayer:layer]; + } else { + orig_displayLayer(self, @selector(displayLayer:), layer); + } +} + +@end + +#endif diff --git a/macos/ReactTestApp.xcodeproj/project.pbxproj b/macos/ReactTestApp.xcodeproj/project.pbxproj index 2d3b73b94..ff6db9c9d 100644 --- a/macos/ReactTestApp.xcodeproj/project.pbxproj +++ b/macos/ReactTestApp.xcodeproj/project.pbxproj @@ -8,13 +8,13 @@ /* Begin PBXBuildFile section */ 193EF063247A736200BE8C79 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF062247A736200BE8C79 /* AppDelegate.swift */; }; - 193EF065247A736200BE8C79 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF064247A736200BE8C79 /* ViewController.swift */; }; - 193EF067247A736300BE8C79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 193EF066247A736300BE8C79 /* Assets.xcassets */; }; - 193EF06A247A736300BE8C79 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 193EF068247A736300BE8C79 /* Main.storyboard */; }; 193EF08F247A799D00BE8C79 /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF08E247A799D00BE8C79 /* Manifest.swift */; }; - 193EF093247A830200BE8C79 /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 193EF091247A830200BE8C79 /* UIViewController+ReactTestApp.m */; }; 193EF098247B130700BE8C79 /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF097247B130700BE8C79 /* ReactInstance.swift */; }; + 193EF065247A736200BE8C79 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF064247A736200BE8C79 /* ViewController.swift */; }; 196C22652490CBAB00449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22632490CBAB00449D3C /* React+Compatibility.m */; }; + 193EF093247A830200BE8C79 /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 193EF091247A830200BE8C79 /* UIViewController+ReactTestApp.m */; }; + 193EF067247A736300BE8C79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 193EF066247A736300BE8C79 /* Assets.xcassets */; }; + 193EF06A247A736300BE8C79 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 193EF068247A736300BE8C79 /* Main.storyboard */; }; 19E791C024B08E1400FA6468 /* ReactTestAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E791BF24B08E1400FA6468 /* ReactTestAppTests.swift */; }; 19E791C324B08E4D00FA6468 /* ReactTestAppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E791C224B08E4D00FA6468 /* ReactTestAppUITests.swift */; }; /* End PBXBuildFile section */ @@ -211,8 +211,8 @@ 193EF057247A736100BE8C79 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1150; - LastUpgradeCheck = 1220; + LastSwiftUpdateCheck = 1230; + LastUpgradeCheck = 1230; ORGANIZATIONNAME = Microsoft; TargetAttributes = { 193EF05E247A736100BE8C79 = {