Skip to content

Commit bf6a2a1

Browse files
committed
fix(iOS): Images don't render on iOS 14 with RN < 0.63.2
This change monkey patches React Native on versions prior to 0.63.2 to fix a bug with images not rendering when on iOS 14. See facebook/react-native#29420.
1 parent 7c39ea5 commit bf6a2a1

File tree

5 files changed

+83
-41
lines changed

5 files changed

+83
-41
lines changed

ios/ReactTestApp.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10-
1914199A234B2DD800D856AE /* RCTDevSupport+UIScene.m in Sources */ = {isa = PBXBuildFile; fileRef = 19141999234B2DD800D856AE /* RCTDevSupport+UIScene.m */; };
10+
19ECD0D6232ED425003D8557 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D5232ED425003D8557 /* AppDelegate.swift */; };
11+
19ECD0DA232ED425003D8557 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D9232ED425003D8557 /* ContentView.swift */; };
1112
192DD201240FCAF5004E9CEB /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 192DD200240FCAF5004E9CEB /* Manifest.swift */; };
12-
196C22622490CB7600449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22602490CB7600449D3C /* React+Compatibility.m */; };
13-
196C7215232F1788006556ED /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196C7214232F1788006556ED /* ReactInstance.swift */; };
1413
196C724123319A85006556ED /* QRCodeReaderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196C724023319A85006556ED /* QRCodeReaderDelegate.swift */; };
15-
1988284524105BEC005057FF /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1988284424105BEC005057FF /* UIViewController+ReactTestApp.m */; };
16-
19ECD0D6232ED425003D8557 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D5232ED425003D8557 /* AppDelegate.swift */; };
14+
196C7215232F1788006556ED /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196C7214232F1788006556ED /* ReactInstance.swift */; };
1715
19ECD0D8232ED425003D8557 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D7232ED425003D8557 /* SceneDelegate.swift */; };
18-
19ECD0DA232ED425003D8557 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0D9232ED425003D8557 /* ContentView.swift */; };
16+
1914199A234B2DD800D856AE /* RCTDevSupport+UIScene.m in Sources */ = {isa = PBXBuildFile; fileRef = 19141999234B2DD800D856AE /* RCTDevSupport+UIScene.m */; };
17+
196C22622490CB7600449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22602490CB7600449D3C /* React+Compatibility.m */; };
18+
1988284524105BEC005057FF /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1988284424105BEC005057FF /* UIViewController+ReactTestApp.m */; };
1919
19ECD0DC232ED427003D8557 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 19ECD0DB232ED427003D8557 /* Assets.xcassets */; };
2020
19ECD0E2232ED427003D8557 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 19ECD0E0232ED427003D8557 /* LaunchScreen.storyboard */; };
2121
19ECD0ED232ED428003D8557 /* ReactTestAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ECD0EC232ED428003D8557 /* ReactTestAppTests.swift */; };
@@ -220,8 +220,8 @@
220220
19ECD0CA232ED425003D8557 /* Project object */ = {
221221
isa = PBXProject;
222222
attributes = {
223-
LastSwiftUpdateCheck = 1100;
224-
LastUpgradeCheck = 1220;
223+
LastSwiftUpdateCheck = 1230;
224+
LastUpgradeCheck = 1230;
225225
ORGANIZATIONNAME = Microsoft;
226226
TargetAttributes = {
227227
19ECD0D1232ED425003D8557 = {

ios/ReactTestApp/RCTDevSupport+UIScene.m

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,9 @@
1414
#import <React/RCTUtils.h>
1515
#import <React/RCTVersion.h>
1616

17-
#if DEBUG
17+
#import "React+Compatibility.h"
1818

19-
void swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector)
20-
{
21-
Method originalMethod = class_getInstanceMethod(class, originalSelector);
22-
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
23-
24-
BOOL didAddMethod = class_addMethod(class,
25-
originalSelector,
26-
method_getImplementation(swizzledMethod),
27-
method_getTypeEncoding(swizzledMethod));
28-
if (didAddMethod) {
29-
class_replaceMethod(class,
30-
swizzledSelector,
31-
method_getImplementation(originalMethod),
32-
method_getTypeEncoding(originalMethod));
33-
} else {
34-
method_exchangeImplementations(originalMethod, swizzledMethod);
35-
}
36-
}
19+
#if DEBUG
3720

3821
// MARK: - RCTRedBoxWindow
3922

@@ -56,11 +39,11 @@ + (void)load
5639
static dispatch_once_t onceToken;
5740
dispatch_once(&onceToken, ^{
5841
Class class = [self class];
59-
swizzleSelector(class,
60-
@selector(showErrorMessage:withStack:isUpdate:),
61-
@selector(rta_showErrorMessage:withStack:isUpdate:));
62-
swizzleSelector(class, @selector(dismiss), @selector(rta_dismiss));
63-
swizzleSelector(class, @selector(makeKeyAndVisible), @selector(rta_makeKeyAndVisible));
42+
RTASwizzleSelector(class,
43+
@selector(showErrorMessage:withStack:isUpdate:),
44+
@selector(rta_showErrorMessage:withStack:isUpdate:));
45+
RTASwizzleSelector(class, @selector(dismiss), @selector(rta_dismiss));
46+
RTASwizzleSelector(class, @selector(makeKeyAndVisible), @selector(rta_makeKeyAndVisible));
6447
});
6548
}
6649

@@ -103,9 +86,9 @@ + (void)initialize
10386
}
10487

10588
if (@available(iOS 13.0, *)) {
106-
swizzleSelector([self class],
107-
@selector(showMessage:color:backgroundColor:),
108-
@selector(rta_showMessage:color:backgroundColor:));
89+
RTASwizzleSelector([self class],
90+
@selector(showMessage:color:backgroundColor:),
91+
@selector(rta_showMessage:color:backgroundColor:));
10992
}
11093
}
11194

ios/ReactTestApp/React+Compatibility.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@
99

1010
@class RCTBridge;
1111

12+
void RTASwizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector);
13+
1214
void RTATriggerReloadCommand(RCTBridge *, NSString *reason);

ios/ReactTestApp/React+Compatibility.m

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,31 @@
99

1010
#include <TargetConditionals.h>
1111

12+
#import <objc/runtime.h>
13+
1214
#import <React/RCTBridge.h>
1315

16+
void RTASwizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector)
17+
{
18+
Method originalMethod = class_getInstanceMethod(class, originalSelector);
19+
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
20+
21+
BOOL didAddMethod = class_addMethod(class,
22+
originalSelector,
23+
method_getImplementation(swizzledMethod),
24+
method_getTypeEncoding(swizzledMethod));
25+
if (didAddMethod) {
26+
class_replaceMethod(class,
27+
swizzledSelector,
28+
method_getImplementation(originalMethod),
29+
method_getTypeEncoding(originalMethod));
30+
} else {
31+
method_exchangeImplementations(originalMethod, swizzledMethod);
32+
}
33+
}
34+
35+
// MARK: - [0.62] RCTTriggerReloadCommandListeners replaces -[RCTBridge reload]
36+
1437
// `RCTReloadCommand.h` is excluded from `react-native-macos`
1538
// See https://github.com/microsoft/react-native-macos/blob/v0.61.39/React-Core.podspec#L66
1639
#if REACT_NATIVE_VERSION >= 6200
@@ -25,3 +48,37 @@ void RTATriggerReloadCommand(RCTBridge *bridge, NSString *reason)
2548
RCTTriggerReloadCommandListeners(reason);
2649
#endif
2750
}
51+
52+
// MARK: - [0.63.2] Images do not render on iOS 14
53+
// See https://github.com/facebook/react-native/pull/29420
54+
55+
#if REACT_NATIVE_VERSION < 6302
56+
57+
#import <React/RCTUIImageViewAnimated.h>
58+
59+
@implementation RCTUIImageViewAnimated (ReactTestApp)
60+
61+
+ (void)initialize
62+
{
63+
if ([self class] != [RCTUIImageViewAnimated class]) {
64+
return;
65+
}
66+
67+
if (@available(iOS 14.0, *)) {
68+
RTASwizzleSelector([self class], @selector(displayLayer:), @selector(rta_displayLayer:));
69+
}
70+
}
71+
72+
- (void)rta_displayLayer:(CALayer *)layer
73+
{
74+
if ([self respondsToSelector:@selector(currentFrame)] &&
75+
[self performSelector:@selector(currentFrame)] == nil) {
76+
[super displayLayer:layer];
77+
} else {
78+
[self rta_displayLayer:layer];
79+
}
80+
}
81+
82+
@end
83+
84+
#endif

macos/ReactTestApp.xcodeproj/project.pbxproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88

99
/* Begin PBXBuildFile section */
1010
193EF063247A736200BE8C79 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF062247A736200BE8C79 /* AppDelegate.swift */; };
11-
193EF065247A736200BE8C79 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF064247A736200BE8C79 /* ViewController.swift */; };
12-
193EF067247A736300BE8C79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 193EF066247A736300BE8C79 /* Assets.xcassets */; };
13-
193EF06A247A736300BE8C79 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 193EF068247A736300BE8C79 /* Main.storyboard */; };
1411
193EF08F247A799D00BE8C79 /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF08E247A799D00BE8C79 /* Manifest.swift */; };
15-
193EF093247A830200BE8C79 /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 193EF091247A830200BE8C79 /* UIViewController+ReactTestApp.m */; };
1612
193EF098247B130700BE8C79 /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF097247B130700BE8C79 /* ReactInstance.swift */; };
13+
193EF065247A736200BE8C79 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF064247A736200BE8C79 /* ViewController.swift */; };
1714
196C22652490CBAB00449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22632490CBAB00449D3C /* React+Compatibility.m */; };
15+
193EF093247A830200BE8C79 /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 193EF091247A830200BE8C79 /* UIViewController+ReactTestApp.m */; };
16+
193EF067247A736300BE8C79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 193EF066247A736300BE8C79 /* Assets.xcassets */; };
17+
193EF06A247A736300BE8C79 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 193EF068247A736300BE8C79 /* Main.storyboard */; };
1818
19E791C024B08E1400FA6468 /* ReactTestAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E791BF24B08E1400FA6468 /* ReactTestAppTests.swift */; };
1919
19E791C324B08E4D00FA6468 /* ReactTestAppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E791C224B08E4D00FA6468 /* ReactTestAppUITests.swift */; };
2020
/* End PBXBuildFile section */
@@ -211,8 +211,8 @@
211211
193EF057247A736100BE8C79 /* Project object */ = {
212212
isa = PBXProject;
213213
attributes = {
214-
LastSwiftUpdateCheck = 1150;
215-
LastUpgradeCheck = 1220;
214+
LastSwiftUpdateCheck = 1230;
215+
LastUpgradeCheck = 1230;
216216
ORGANIZATIONNAME = Microsoft;
217217
TargetAttributes = {
218218
193EF05E247A736100BE8C79 = {

0 commit comments

Comments
 (0)