Просмотр исходного кода

WIP: WebView extraction - renamed RNC to RCTWebView

Jamon Holmgren 6 лет назад
Родитель
Сommit
6123deaf12

ios/RNCWebView.xcodeproj/project.pbxproj → ios/RCTWebView.xcodeproj/project.pbxproj Просмотреть файл

@@ -24,7 +24,7 @@
24 24
 /* End PBXCopyFilesBuildPhase section */
25 25
 
26 26
 /* Begin PBXFileReference section */
27
-		134814201AA4EA6300B7C361 /* libRNCWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCWebView.a; sourceTree = BUILT_PRODUCTS_DIR; };
27
+		134814201AA4EA6300B7C361 /* libRCTWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTWebView.a; sourceTree = BUILT_PRODUCTS_DIR; };
28 28
 		E91B351921446E6C00F9801F /* RCTWKWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWKWebViewManager.h; sourceTree = "<group>"; };
29 29
 		E91B351A21446E6C00F9801F /* RCTWKWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWKWebView.h; sourceTree = "<group>"; };
30 30
 		E91B351B21446E6C00F9801F /* RCTWKWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWKWebViewManager.m; sourceTree = "<group>"; };
@@ -45,7 +45,7 @@
45 45
 		134814211AA4EA7D00B7C361 /* Products */ = {
46 46
 			isa = PBXGroup;
47 47
 			children = (
48
-				134814201AA4EA6300B7C361 /* libRNCWebView.a */,
48
+				134814201AA4EA6300B7C361 /* libRCTWebView.a */,
49 49
 			);
50 50
 			name = Products;
51 51
 			sourceTree = "<group>";
@@ -64,9 +64,9 @@
64 64
 /* End PBXGroup section */
65 65
 
66 66
 /* Begin PBXNativeTarget section */
67
-		58B511DA1A9E6C8500147676 /* RNCWebView */ = {
67
+		58B511DA1A9E6C8500147676 /* RCTWebView */ = {
68 68
 			isa = PBXNativeTarget;
69
-			buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */;
69
+			buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTWebView" */;
70 70
 			buildPhases = (
71 71
 				58B511D71A9E6C8500147676 /* Sources */,
72 72
 				58B511D81A9E6C8500147676 /* Frameworks */,
@@ -76,9 +76,9 @@
76 76
 			);
77 77
 			dependencies = (
78 78
 			);
79
-			name = RNCWebView;
79
+			name = RCTWebView;
80 80
 			productName = RCTDataManager;
81
-			productReference = 134814201AA4EA6300B7C361 /* libRNCWebView.a */;
81
+			productReference = 134814201AA4EA6300B7C361 /* libRCTWebView.a */;
82 82
 			productType = "com.apple.product-type.library.static";
83 83
 		};
84 84
 /* End PBXNativeTarget section */
@@ -95,7 +95,7 @@
95 95
 					};
96 96
 				};
97 97
 			};
98
-			buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */;
98
+			buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTWebView" */;
99 99
 			compatibilityVersion = "Xcode 3.2";
100 100
 			developmentRegion = English;
101 101
 			hasScannedForEncodings = 0;
@@ -107,7 +107,7 @@
107 107
 			projectDirPath = "";
108 108
 			projectRoot = "";
109 109
 			targets = (
110
-				58B511DA1A9E6C8500147676 /* RNCWebView */,
110
+				58B511DA1A9E6C8500147676 /* RCTWebView */,
111 111
 			);
112 112
 		};
113 113
 /* End PBXProject section */
@@ -217,7 +217,7 @@
217 217
 				);
218 218
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
219 219
 				OTHER_LDFLAGS = "-ObjC";
220
-				PRODUCT_NAME = RNCWebView;
220
+				PRODUCT_NAME = RCTWebView;
221 221
 				SKIP_INSTALL = YES;
222 222
 			};
223 223
 			name = Debug;
@@ -233,7 +233,7 @@
233 233
 				);
234 234
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
235 235
 				OTHER_LDFLAGS = "-ObjC";
236
-				PRODUCT_NAME = RNCWebView;
236
+				PRODUCT_NAME = RCTWebView;
237 237
 				SKIP_INSTALL = YES;
238 238
 			};
239 239
 			name = Release;
@@ -241,7 +241,7 @@
241 241
 /* End XCBuildConfiguration section */
242 242
 
243 243
 /* Begin XCConfigurationList section */
244
-		58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */ = {
244
+		58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTWebView" */ = {
245 245
 			isa = XCConfigurationList;
246 246
 			buildConfigurations = (
247 247
 				58B511ED1A9E6C8500147676 /* Debug */,
@@ -250,7 +250,7 @@
250 250
 			defaultConfigurationIsVisible = 0;
251 251
 			defaultConfigurationName = Release;
252 252
 		};
253
-		58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */ = {
253
+		58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTWebView" */ = {
254 254
 			isa = XCConfigurationList;
255 255
 			buildConfigurations = (
256 256
 				58B511F01A9E6C8500147676 /* Debug */,

ios/RNCWebView.xcworkspace/contents.xcworkspacedata → ios/RCTWebView.xcworkspace/contents.xcworkspacedata Просмотреть файл

@@ -3,7 +3,7 @@
3 3
 <Workspace
4 4
    version = "1.0">
5 5
    <FileRef
6
-      location = "group:RNCWebView.xcodeproj">
6
+      location = "group:RCTWebView.xcodeproj">
7 7
    </FileRef>
8 8
 </Workspace>
9 9
   

+ 265
- 0
ios/archive/RCTWKWebView.xcodeproj/project.pbxproj Просмотреть файл

@@ -0,0 +1,265 @@
1
+// !$*UTF8*$!
2
+{
3
+	archiveVersion = 1;
4
+	classes = {
5
+	};
6
+	objectVersion = 46;
7
+	objects = {
8
+
9
+/* Begin PBXBuildFile section */
10
+		E91B3466214383EF00F9801F /* RCTWKWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B3464214383EF00F9801F /* RCTWKWebViewManager.m */; };
11
+		E91B3467214383EF00F9801F /* RCTWKWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B3465214383EF00F9801F /* RCTWKWebView.m */; };
12
+/* End PBXBuildFile section */
13
+
14
+/* Begin PBXCopyFilesBuildPhase section */
15
+		58B511D91A9E6C8500147676 /* CopyFiles */ = {
16
+			isa = PBXCopyFilesBuildPhase;
17
+			buildActionMask = 2147483647;
18
+			dstPath = "include/$(PRODUCT_NAME)";
19
+			dstSubfolderSpec = 16;
20
+			files = (
21
+			);
22
+			runOnlyForDeploymentPostprocessing = 0;
23
+		};
24
+/* End PBXCopyFilesBuildPhase section */
25
+
26
+/* Begin PBXFileReference section */
27
+		134814201AA4EA6300B7C361 /* libRCTWKWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTWKWebView.a; sourceTree = BUILT_PRODUCTS_DIR; };
28
+		E91B3462214383EF00F9801F /* RCTWKWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWKWebViewManager.h; sourceTree = "<group>"; };
29
+		E91B3463214383EF00F9801F /* RCTWKWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWKWebView.h; sourceTree = "<group>"; };
30
+		E91B3464214383EF00F9801F /* RCTWKWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWKWebViewManager.m; sourceTree = "<group>"; };
31
+		E91B3465214383EF00F9801F /* RCTWKWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWKWebView.m; sourceTree = "<group>"; };
32
+/* End PBXFileReference section */
33
+
34
+/* Begin PBXFrameworksBuildPhase section */
35
+		58B511D81A9E6C8500147676 /* Frameworks */ = {
36
+			isa = PBXFrameworksBuildPhase;
37
+			buildActionMask = 2147483647;
38
+			files = (
39
+			);
40
+			runOnlyForDeploymentPostprocessing = 0;
41
+		};
42
+/* End PBXFrameworksBuildPhase section */
43
+
44
+/* Begin PBXGroup section */
45
+		134814211AA4EA7D00B7C361 /* Products */ = {
46
+			isa = PBXGroup;
47
+			children = (
48
+				134814201AA4EA6300B7C361 /* libRCTWKWebView.a */,
49
+			);
50
+			name = Products;
51
+			sourceTree = "<group>";
52
+		};
53
+		58B511D21A9E6C8500147676 = {
54
+			isa = PBXGroup;
55
+			children = (
56
+				E91B3463214383EF00F9801F /* RCTWKWebView.h */,
57
+				E91B3465214383EF00F9801F /* RCTWKWebView.m */,
58
+				E91B3462214383EF00F9801F /* RCTWKWebViewManager.h */,
59
+				E91B3464214383EF00F9801F /* RCTWKWebViewManager.m */,
60
+				134814211AA4EA7D00B7C361 /* Products */,
61
+			);
62
+			sourceTree = "<group>";
63
+		};
64
+/* End PBXGroup section */
65
+
66
+/* Begin PBXNativeTarget section */
67
+		58B511DA1A9E6C8500147676 /* RCTWKWebView */ = {
68
+			isa = PBXNativeTarget;
69
+			buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTWKWebView" */;
70
+			buildPhases = (
71
+				58B511D71A9E6C8500147676 /* Sources */,
72
+				58B511D81A9E6C8500147676 /* Frameworks */,
73
+				58B511D91A9E6C8500147676 /* CopyFiles */,
74
+			);
75
+			buildRules = (
76
+			);
77
+			dependencies = (
78
+			);
79
+			name = RCTWKWebView;
80
+			productName = RCTDataManager;
81
+			productReference = 134814201AA4EA6300B7C361 /* libRCTWKWebView.a */;
82
+			productType = "com.apple.product-type.library.static";
83
+		};
84
+/* End PBXNativeTarget section */
85
+
86
+/* Begin PBXProject section */
87
+		58B511D31A9E6C8500147676 /* Project object */ = {
88
+			isa = PBXProject;
89
+			attributes = {
90
+				LastUpgradeCheck = 0830;
91
+				ORGANIZATIONNAME = Facebook;
92
+				TargetAttributes = {
93
+					58B511DA1A9E6C8500147676 = {
94
+						CreatedOnToolsVersion = 6.1.1;
95
+					};
96
+				};
97
+			};
98
+			buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTWKWebView" */;
99
+			compatibilityVersion = "Xcode 3.2";
100
+			developmentRegion = English;
101
+			hasScannedForEncodings = 0;
102
+			knownRegions = (
103
+				en,
104
+			);
105
+			mainGroup = 58B511D21A9E6C8500147676;
106
+			productRefGroup = 58B511D21A9E6C8500147676;
107
+			projectDirPath = "";
108
+			projectRoot = "";
109
+			targets = (
110
+				58B511DA1A9E6C8500147676 /* RCTWKWebView */,
111
+			);
112
+		};
113
+/* End PBXProject section */
114
+
115
+/* Begin PBXSourcesBuildPhase section */
116
+		58B511D71A9E6C8500147676 /* Sources */ = {
117
+			isa = PBXSourcesBuildPhase;
118
+			buildActionMask = 2147483647;
119
+			files = (
120
+				E91B3466214383EF00F9801F /* RCTWKWebViewManager.m in Sources */,
121
+				E91B3467214383EF00F9801F /* RCTWKWebView.m in Sources */,
122
+			);
123
+			runOnlyForDeploymentPostprocessing = 0;
124
+		};
125
+/* End PBXSourcesBuildPhase section */
126
+
127
+/* Begin XCBuildConfiguration section */
128
+		58B511ED1A9E6C8500147676 /* Debug */ = {
129
+			isa = XCBuildConfiguration;
130
+			buildSettings = {
131
+				ALWAYS_SEARCH_USER_PATHS = NO;
132
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
133
+				CLANG_CXX_LIBRARY = "libc++";
134
+				CLANG_ENABLE_MODULES = YES;
135
+				CLANG_ENABLE_OBJC_ARC = YES;
136
+				CLANG_WARN_BOOL_CONVERSION = YES;
137
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
138
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
139
+				CLANG_WARN_EMPTY_BODY = YES;
140
+				CLANG_WARN_ENUM_CONVERSION = YES;
141
+				CLANG_WARN_INFINITE_RECURSION = YES;
142
+				CLANG_WARN_INT_CONVERSION = YES;
143
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
144
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
145
+				CLANG_WARN_UNREACHABLE_CODE = YES;
146
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
147
+				COPY_PHASE_STRIP = NO;
148
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
149
+				ENABLE_TESTABILITY = YES;
150
+				GCC_C_LANGUAGE_STANDARD = gnu99;
151
+				GCC_DYNAMIC_NO_PIC = NO;
152
+				GCC_NO_COMMON_BLOCKS = YES;
153
+				GCC_OPTIMIZATION_LEVEL = 0;
154
+				GCC_PREPROCESSOR_DEFINITIONS = (
155
+					"DEBUG=1",
156
+					"$(inherited)",
157
+				);
158
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
159
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
160
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
161
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
162
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
163
+				GCC_WARN_UNUSED_FUNCTION = YES;
164
+				GCC_WARN_UNUSED_VARIABLE = YES;
165
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
166
+				MTL_ENABLE_DEBUG_INFO = YES;
167
+				ONLY_ACTIVE_ARCH = YES;
168
+				SDKROOT = iphoneos;
169
+			};
170
+			name = Debug;
171
+		};
172
+		58B511EE1A9E6C8500147676 /* Release */ = {
173
+			isa = XCBuildConfiguration;
174
+			buildSettings = {
175
+				ALWAYS_SEARCH_USER_PATHS = NO;
176
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
177
+				CLANG_CXX_LIBRARY = "libc++";
178
+				CLANG_ENABLE_MODULES = YES;
179
+				CLANG_ENABLE_OBJC_ARC = YES;
180
+				CLANG_WARN_BOOL_CONVERSION = YES;
181
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
182
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
183
+				CLANG_WARN_EMPTY_BODY = YES;
184
+				CLANG_WARN_ENUM_CONVERSION = YES;
185
+				CLANG_WARN_INFINITE_RECURSION = YES;
186
+				CLANG_WARN_INT_CONVERSION = YES;
187
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
188
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
189
+				CLANG_WARN_UNREACHABLE_CODE = YES;
190
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
191
+				COPY_PHASE_STRIP = YES;
192
+				ENABLE_NS_ASSERTIONS = NO;
193
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
194
+				GCC_C_LANGUAGE_STANDARD = gnu99;
195
+				GCC_NO_COMMON_BLOCKS = YES;
196
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
197
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
198
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
199
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
200
+				GCC_WARN_UNUSED_FUNCTION = YES;
201
+				GCC_WARN_UNUSED_VARIABLE = YES;
202
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
203
+				MTL_ENABLE_DEBUG_INFO = NO;
204
+				SDKROOT = iphoneos;
205
+				VALIDATE_PRODUCT = YES;
206
+			};
207
+			name = Release;
208
+		};
209
+		58B511F01A9E6C8500147676 /* Debug */ = {
210
+			isa = XCBuildConfiguration;
211
+			buildSettings = {
212
+				HEADER_SEARCH_PATHS = (
213
+					"$(inherited)",
214
+					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
215
+					"$(SRCROOT)/../../../React/**",
216
+					"$(SRCROOT)/../../react-native/React/**",
217
+				);
218
+				LIBRARY_SEARCH_PATHS = "$(inherited)";
219
+				OTHER_LDFLAGS = "-ObjC";
220
+				PRODUCT_NAME = RCTWKWebView;
221
+				SKIP_INSTALL = YES;
222
+			};
223
+			name = Debug;
224
+		};
225
+		58B511F11A9E6C8500147676 /* Release */ = {
226
+			isa = XCBuildConfiguration;
227
+			buildSettings = {
228
+				HEADER_SEARCH_PATHS = (
229
+					"$(inherited)",
230
+					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
231
+					"$(SRCROOT)/../../../React/**",
232
+					"$(SRCROOT)/../../react-native/React/**",
233
+				);
234
+				LIBRARY_SEARCH_PATHS = "$(inherited)";
235
+				OTHER_LDFLAGS = "-ObjC";
236
+				PRODUCT_NAME = RCTWKWebView;
237
+				SKIP_INSTALL = YES;
238
+			};
239
+			name = Release;
240
+		};
241
+/* End XCBuildConfiguration section */
242
+
243
+/* Begin XCConfigurationList section */
244
+		58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTWKWebView" */ = {
245
+			isa = XCConfigurationList;
246
+			buildConfigurations = (
247
+				58B511ED1A9E6C8500147676 /* Debug */,
248
+				58B511EE1A9E6C8500147676 /* Release */,
249
+			);
250
+			defaultConfigurationIsVisible = 0;
251
+			defaultConfigurationName = Release;
252
+		};
253
+		58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTWKWebView" */ = {
254
+			isa = XCConfigurationList;
255
+			buildConfigurations = (
256
+				58B511F01A9E6C8500147676 /* Debug */,
257
+				58B511F11A9E6C8500147676 /* Release */,
258
+			);
259
+			defaultConfigurationIsVisible = 0;
260
+			defaultConfigurationName = Release;
261
+		};
262
+/* End XCConfigurationList section */
263
+	};
264
+	rootObject = 58B511D31A9E6C8500147676 /* Project object */;
265
+}

+ 9
- 0
ios/archive/RCTWKWebView.xcworkspace/contents.xcworkspacedata Просмотреть файл

@@ -0,0 +1,9 @@
1
+// !$*UTF8*$!
2
+<?xml version="1.0" encoding="UTF-8"?>
3
+<Workspace
4
+   version = "1.0">
5
+   <FileRef
6
+      location = "group:RCTWKWebView.xcodeproj">
7
+   </FileRef>
8
+</Workspace>
9
+  

+ 39
- 0
ios/archive/RNCWebView.h Просмотреть файл

@@ -0,0 +1,39 @@
1
+#import <React/RCTView.h>
2
+
3
+@class RNCWebView;
4
+
5
+/**
6
+ * Special scheme used to pass messages to the injectedJavaScript
7
+ * code without triggering a page load. Usage:
8
+ *
9
+ *   window.location.href = RNCJSNavigationScheme + '://hello'
10
+ */
11
+extern NSString *const RNCJSNavigationScheme;
12
+
13
+@protocol RNCWebViewDelegate <NSObject>
14
+
15
+- (BOOL)webView:(RNCWebView *)webView
16
+shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
17
+   withCallback:(RCTDirectEventBlock)callback;
18
+
19
+@end
20
+
21
+@interface RNCWebView : RCTView
22
+
23
+@property (nonatomic, weak) id<RNCWebViewDelegate> delegate;
24
+
25
+@property (nonatomic, copy) NSDictionary *source;
26
+@property (nonatomic, assign) UIEdgeInsets contentInset;
27
+@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
28
+@property (nonatomic, assign) BOOL messagingEnabled;
29
+@property (nonatomic, copy) NSString *injectedJavaScript;
30
+@property (nonatomic, assign) BOOL scalesPageToFit;
31
+
32
+- (void)goForward;
33
+- (void)goBack;
34
+- (void)reload;
35
+- (void)stopLoading;
36
+- (void)postMessage:(NSString *)message;
37
+- (void)injectJavaScript:(NSString *)script;
38
+
39
+@end

+ 343
- 0
ios/archive/RNCWebView.m Просмотреть файл

@@ -0,0 +1,343 @@
1
+#import "RNCWebView.h"
2
+
3
+// #import <UIKit/UIKit.h>
4
+#import <React/RCTAutoInsetsProtocol.h>
5
+#import <React/RCTConvert.h>
6
+#import <React/RCTEventDispatcher.h>
7
+#import <React/RCTLog.h>
8
+#import <React/RCTUtils.h>
9
+#import <React/RCTView.h>
10
+#import <React/UIView+React.h>
11
+
12
+NSString *const RNCJSNavigationScheme = @"react-js-navigation";
13
+
14
+static NSString *const kPostMessageHost = @"postMessage";
15
+
16
+@interface RNCWebView () <UIWebViewDelegate, RCTAutoInsetsProtocol>
17
+
18
+@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
19
+@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish;
20
+@property (nonatomic, copy) RCTDirectEventBlock onLoadingError;
21
+@property (nonatomic, copy) RCTDirectEventBlock onShouldStartLoadWithRequest;
22
+@property (nonatomic, copy) RCTDirectEventBlock onMessage;
23
+
24
+@end
25
+
26
+@implementation RNCWebView
27
+{
28
+  UIWebView *_webView;
29
+  NSString *_injectedJavaScript;
30
+}
31
+
32
+- (void)dealloc
33
+{
34
+  _webView.delegate = nil;
35
+}
36
+
37
+- (instancetype)initWithFrame:(CGRect)frame
38
+{
39
+  if ((self = [super initWithFrame:frame])) {
40
+    super.backgroundColor = [UIColor clearColor];
41
+    _automaticallyAdjustContentInsets = YES;
42
+    _contentInset = UIEdgeInsetsZero;
43
+    _webView = [[UIWebView alloc] initWithFrame:self.bounds];
44
+    _webView.delegate = self;
45
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
46
+    if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
47
+      _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
48
+    }
49
+#endif
50
+    [self addSubview:_webView];
51
+  }
52
+  return self;
53
+}
54
+
55
+RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
56
+
57
+- (void)goForward
58
+{
59
+  [_webView goForward];
60
+}
61
+
62
+- (void)goBack
63
+{
64
+  [_webView goBack];
65
+}
66
+
67
+- (void)reload
68
+{
69
+  NSURLRequest *request = [RCTConvert NSURLRequest:self.source];
70
+  if (request.URL && !_webView.request.URL.absoluteString.length) {
71
+    [_webView loadRequest:request];
72
+  }
73
+  else {
74
+    [_webView reload];
75
+  }
76
+}
77
+
78
+- (void)stopLoading
79
+{
80
+  [_webView stopLoading];
81
+}
82
+
83
+- (void)postMessage:(NSString *)message
84
+{
85
+  NSDictionary *eventInitDict = @{
86
+    @"data": message,
87
+  };
88
+  NSString *source = [NSString
89
+    stringWithFormat:@"document.dispatchEvent(new MessageEvent('message', %@));",
90
+    RCTJSONStringify(eventInitDict, NULL)
91
+  ];
92
+  [_webView stringByEvaluatingJavaScriptFromString:source];
93
+}
94
+
95
+- (void)injectJavaScript:(NSString *)script
96
+{
97
+  [_webView stringByEvaluatingJavaScriptFromString:script];
98
+}
99
+
100
+- (void)setSource:(NSDictionary *)source
101
+{
102
+  if (![_source isEqualToDictionary:source]) {
103
+    _source = [source copy];
104
+
105
+    // Check for a static html source first
106
+    NSString *html = [RCTConvert NSString:source[@"html"]];
107
+    if (html) {
108
+      NSURL *baseURL = [RCTConvert NSURL:source[@"baseUrl"]];
109
+      if (!baseURL) {
110
+        baseURL = [NSURL URLWithString:@"about:blank"];
111
+      }
112
+      [_webView loadHTMLString:html baseURL:baseURL];
113
+      return;
114
+    }
115
+
116
+    NSURLRequest *request = [RCTConvert NSURLRequest:source];
117
+    // Because of the way React works, as pages redirect, we actually end up
118
+    // passing the redirect urls back here, so we ignore them if trying to load
119
+    // the same url. We'll expose a call to 'reload' to allow a user to load
120
+    // the existing page.
121
+    if ([request.URL isEqual:_webView.request.URL]) {
122
+      return;
123
+    }
124
+    if (!request.URL) {
125
+      // Clear the webview
126
+      [_webView loadHTMLString:@"" baseURL:nil];
127
+      return;
128
+    }
129
+    [_webView loadRequest:request];
130
+  }
131
+}
132
+
133
+- (void)layoutSubviews
134
+{
135
+  [super layoutSubviews];
136
+  _webView.frame = self.bounds;
137
+}
138
+
139
+- (void)setContentInset:(UIEdgeInsets)contentInset
140
+{
141
+  _contentInset = contentInset;
142
+  [RCTView autoAdjustInsetsForView:self
143
+                    withScrollView:_webView.scrollView
144
+                      updateOffset:NO];
145
+}
146
+
147
+- (void)setScalesPageToFit:(BOOL)scalesPageToFit
148
+{
149
+  if (_webView.scalesPageToFit != scalesPageToFit) {
150
+    _webView.scalesPageToFit = scalesPageToFit;
151
+    [_webView reload];
152
+  }
153
+}
154
+
155
+- (BOOL)scalesPageToFit
156
+{
157
+  return _webView.scalesPageToFit;
158
+}
159
+
160
+- (void)setBackgroundColor:(UIColor *)backgroundColor
161
+{
162
+  CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor);
163
+  self.opaque = _webView.opaque = (alpha == 1.0);
164
+  _webView.backgroundColor = backgroundColor;
165
+}
166
+
167
+- (UIColor *)backgroundColor
168
+{
169
+  return _webView.backgroundColor;
170
+}
171
+
172
+- (NSMutableDictionary<NSString *, id> *)baseEvent
173
+{
174
+  NSMutableDictionary<NSString *, id> *event = [[NSMutableDictionary alloc] initWithDictionary:@{
175
+    @"url": _webView.request.URL.absoluteString ?: @"",
176
+    @"loading" : @(_webView.loading),
177
+    @"title": [_webView stringByEvaluatingJavaScriptFromString:@"document.title"],
178
+    @"canGoBack": @(_webView.canGoBack),
179
+    @"canGoForward" : @(_webView.canGoForward),
180
+  }];
181
+
182
+  return event;
183
+}
184
+
185
+- (void)refreshContentInset
186
+{
187
+  [RCTView autoAdjustInsetsForView:self
188
+                    withScrollView:_webView.scrollView
189
+                      updateOffset:YES];
190
+}
191
+
192
+#pragma mark - UIWebViewDelegate methods
193
+
194
+- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
195
+ navigationType:(UIWebViewNavigationType)navigationType
196
+{
197
+  BOOL isJSNavigation = [request.URL.scheme isEqualToString:RNCJSNavigationScheme];
198
+
199
+  static NSDictionary<NSNumber *, NSString *> *navigationTypes;
200
+  static dispatch_once_t onceToken;
201
+  dispatch_once(&onceToken, ^{
202
+    navigationTypes = @{
203
+      @(UIWebViewNavigationTypeLinkClicked): @"click",
204
+      @(UIWebViewNavigationTypeFormSubmitted): @"formsubmit",
205
+      @(UIWebViewNavigationTypeBackForward): @"backforward",
206
+      @(UIWebViewNavigationTypeReload): @"reload",
207
+      @(UIWebViewNavigationTypeFormResubmitted): @"formresubmit",
208
+      @(UIWebViewNavigationTypeOther): @"other",
209
+    };
210
+  });
211
+
212
+  // skip this for the JS Navigation handler
213
+  if (!isJSNavigation && _onShouldStartLoadWithRequest) {
214
+    NSMutableDictionary<NSString *, id> *event = [self baseEvent];
215
+    [event addEntriesFromDictionary: @{
216
+      @"url": (request.URL).absoluteString,
217
+      @"navigationType": navigationTypes[@(navigationType)]
218
+    }];
219
+    if (![self.delegate webView:self
220
+      shouldStartLoadForRequest:event
221
+                   withCallback:_onShouldStartLoadWithRequest]) {
222
+      return NO;
223
+    }
224
+  }
225
+
226
+  if (_onLoadingStart) {
227
+    // We have this check to filter out iframe requests and whatnot
228
+    BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
229
+    if (isTopFrame) {
230
+      NSMutableDictionary<NSString *, id> *event = [self baseEvent];
231
+      [event addEntriesFromDictionary: @{
232
+        @"url": (request.URL).absoluteString,
233
+        @"navigationType": navigationTypes[@(navigationType)]
234
+      }];
235
+      _onLoadingStart(event);
236
+    }
237
+  }
238
+
239
+  if (isJSNavigation && [request.URL.host isEqualToString:kPostMessageHost]) {
240
+    NSString *data = request.URL.query;
241
+    data = [data stringByReplacingOccurrencesOfString:@"+" withString:@" "];
242
+    data = [data stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
243
+
244
+    NSMutableDictionary<NSString *, id> *event = [self baseEvent];
245
+    [event addEntriesFromDictionary: @{
246
+      @"data": data,
247
+    }];
248
+
249
+    NSString *source = @"document.dispatchEvent(new MessageEvent('message:received'));";
250
+
251
+    [_webView stringByEvaluatingJavaScriptFromString:source];
252
+
253
+    _onMessage(event);
254
+  }
255
+
256
+  // JS Navigation handler
257
+  return !isJSNavigation;
258
+}
259
+
260
+- (void)webView:(__unused UIWebView *)webView didFailLoadWithError:(NSError *)error
261
+{
262
+  if (_onLoadingError) {
263
+    if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) {
264
+      // NSURLErrorCancelled is reported when a page has a redirect OR if you load
265
+      // a new URL in the WebView before the previous one came back. We can just
266
+      // ignore these since they aren't real errors.
267
+      // http://stackoverflow.com/questions/1024748/how-do-i-fix-nsurlerrordomain-error-999-in-iphone-3-0-os
268
+      return;
269
+    }
270
+
271
+    if ([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102) {
272
+      // Error code 102 "Frame load interrupted" is raised by the UIWebView if
273
+      // its delegate returns FALSE from webView:shouldStartLoadWithRequest:navigationType
274
+      // when the URL is from an http redirect. This is a common pattern when
275
+      // implementing OAuth with a WebView.
276
+      return;
277
+    }
278
+
279
+    NSMutableDictionary<NSString *, id> *event = [self baseEvent];
280
+    [event addEntriesFromDictionary:@{
281
+      @"domain": error.domain,
282
+      @"code": @(error.code),
283
+      @"description": error.localizedDescription,
284
+    }];
285
+    _onLoadingError(event);
286
+  }
287
+}
288
+
289
+- (void)webViewDidFinishLoad:(UIWebView *)webView
290
+{
291
+  if (_messagingEnabled) {
292
+    #if RCT_DEV
293
+    // See isNative in lodash
294
+    NSString *testPostMessageNative = @"String(window.postMessage) === String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage')";
295
+    BOOL postMessageIsNative = [
296
+      [webView stringByEvaluatingJavaScriptFromString:testPostMessageNative]
297
+      isEqualToString:@"true"
298
+    ];
299
+    if (!postMessageIsNative) {
300
+      RCTLogError(@"Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined");
301
+    }
302
+    #endif
303
+    NSString *source = [NSString stringWithFormat:
304
+      @"(function() {"
305
+        "window.originalPostMessage = window.postMessage;"
306
+
307
+        "var messageQueue = [];"
308
+        "var messagePending = false;"
309
+
310
+        "function processQueue() {"
311
+          "if (!messageQueue.length || messagePending) return;"
312
+          "messagePending = true;"
313
+          "window.location = '%@://%@?' + encodeURIComponent(messageQueue.shift());"
314
+        "}"
315
+
316
+        "window.postMessage = function(data) {"
317
+          "messageQueue.push(String(data));"
318
+          "processQueue();"
319
+        "};"
320
+
321
+        "document.addEventListener('message:received', function(e) {"
322
+          "messagePending = false;"
323
+          "processQueue();"
324
+        "});"
325
+      "})();", RNCJSNavigationScheme, kPostMessageHost
326
+    ];
327
+    [webView stringByEvaluatingJavaScriptFromString:source];
328
+  }
329
+  if (_injectedJavaScript != nil) {
330
+    NSString *jsEvaluationValue = [webView stringByEvaluatingJavaScriptFromString:_injectedJavaScript];
331
+
332
+    NSMutableDictionary<NSString *, id> *event = [self baseEvent];
333
+    event[@"jsEvaluationValue"] = jsEvaluationValue;
334
+
335
+    _onLoadingFinish(event);
336
+  }
337
+  // we only need the final 'finishLoad' call so only fire the event when we're actually done loading.
338
+  else if (_onLoadingFinish && !webView.loading && ![webView.request.URL.absoluteString isEqualToString:@"about:blank"]) {
339
+    _onLoadingFinish([self baseEvent]);
340
+  }
341
+}
342
+
343
+@end

+ 24
- 0
ios/archive/RNCWebView.podspec Просмотреть файл

@@ -0,0 +1,24 @@
1
+
2
+Pod::Spec.new do |s|
3
+  s.name         = "RNCWebView"
4
+  s.version      = "1.0.0"
5
+  s.summary      = "RNCWebView"
6
+  s.description  = <<-DESC
7
+                  RNCWebView
8
+                   DESC
9
+  s.homepage     = ""
10
+  s.license      = "MIT"
11
+  # s.license      = { :type => "MIT", :file => "FILE_LICENSE" }
12
+  s.author             = { "author" => "author@domain.cn" }
13
+  s.platform     = :ios, "7.0"
14
+  s.source       = { :git => "https://github.com/author/RNCWebView.git", :tag => "master" }
15
+  s.source_files  = "RNCWebView/**/*.{h,m}"
16
+  s.requires_arc = true
17
+
18
+
19
+  s.dependency "React"
20
+  #s.dependency "others"
21
+
22
+end
23
+
24
+  

+ 5
- 0
ios/archive/RNCWebViewManager.h Просмотреть файл

@@ -0,0 +1,5 @@
1
+#import <React/RCTViewManager.h>
2
+
3
+@interface RNCWebViewManager : RCTViewManager
4
+
5
+@end

+ 151
- 0
ios/archive/RNCWebViewManager.m Просмотреть файл

@@ -0,0 +1,151 @@
1
+#import "RNCWebViewManager.h"
2
+
3
+#import <React/RCTBridge.h>
4
+#import <React/RCTUIManager.h>
5
+#import <React/UIView+React.h>
6
+#import "RNCWebView.h"
7
+
8
+@interface RNCWebViewManager () <RNCWebViewDelegate>
9
+
10
+@end
11
+
12
+@implementation RNCWebViewManager
13
+{
14
+  NSConditionLock *_shouldStartLoadLock;
15
+  BOOL _shouldStartLoad;
16
+}
17
+
18
+RCT_EXPORT_MODULE()
19
+
20
+- (UIView *)view
21
+{
22
+  RNCWebView *webView = [RNCWebView new];
23
+  webView.delegate = self;
24
+  return webView;
25
+}
26
+
27
+RCT_EXPORT_VIEW_PROPERTY(source, NSDictionary)
28
+RCT_REMAP_VIEW_PROPERTY(bounces, _webView.scrollView.bounces, BOOL)
29
+RCT_REMAP_VIEW_PROPERTY(scrollEnabled, _webView.scrollView.scrollEnabled, BOOL)
30
+RCT_REMAP_VIEW_PROPERTY(decelerationRate, _webView.scrollView.decelerationRate, CGFloat)
31
+RCT_EXPORT_VIEW_PROPERTY(scalesPageToFit, BOOL)
32
+RCT_EXPORT_VIEW_PROPERTY(messagingEnabled, BOOL)
33
+RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
34
+RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets)
35
+RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL)
36
+RCT_EXPORT_VIEW_PROPERTY(onLoadingStart, RCTDirectEventBlock)
37
+RCT_EXPORT_VIEW_PROPERTY(onLoadingFinish, RCTDirectEventBlock)
38
+RCT_EXPORT_VIEW_PROPERTY(onLoadingError, RCTDirectEventBlock)
39
+RCT_EXPORT_VIEW_PROPERTY(onMessage, RCTDirectEventBlock)
40
+RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock)
41
+RCT_REMAP_VIEW_PROPERTY(allowsInlineMediaPlayback, _webView.allowsInlineMediaPlayback, BOOL)
42
+RCT_REMAP_VIEW_PROPERTY(mediaPlaybackRequiresUserAction, _webView.mediaPlaybackRequiresUserAction, BOOL)
43
+RCT_REMAP_VIEW_PROPERTY(dataDetectorTypes, _webView.dataDetectorTypes, UIDataDetectorTypes)
44
+
45
+RCT_EXPORT_METHOD(goBack:(nonnull NSNumber *)reactTag)
46
+{
47
+  [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNCWebView *> *viewRegistry) {
48
+    RNCWebView *view = viewRegistry[reactTag];
49
+    if (![view isKindOfClass:[RNCWebView class]]) {
50
+      RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view);
51
+    } else {
52
+      [view goBack];
53
+    }
54
+  }];
55
+}
56
+
57
+RCT_EXPORT_METHOD(goForward:(nonnull NSNumber *)reactTag)
58
+{
59
+  [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
60
+    id view = viewRegistry[reactTag];
61
+    if (![view isKindOfClass:[RNCWebView class]]) {
62
+      RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view);
63
+    } else {
64
+      [view goForward];
65
+    }
66
+  }];
67
+}
68
+
69
+RCT_EXPORT_METHOD(reload:(nonnull NSNumber *)reactTag)
70
+{
71
+  [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNCWebView *> *viewRegistry) {
72
+    RNCWebView *view = viewRegistry[reactTag];
73
+    if (![view isKindOfClass:[RNCWebView class]]) {
74
+      RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view);
75
+    } else {
76
+      [view reload];
77
+    }
78
+  }];
79
+}
80
+
81
+RCT_EXPORT_METHOD(stopLoading:(nonnull NSNumber *)reactTag)
82
+{
83
+  [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNCWebView *> *viewRegistry) {
84
+    RNCWebView *view = viewRegistry[reactTag];
85
+    if (![view isKindOfClass:[RNCWebView class]]) {
86
+      RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view);
87
+    } else {
88
+      [view stopLoading];
89
+    }
90
+  }];
91
+}
92
+
93
+RCT_EXPORT_METHOD(postMessage:(nonnull NSNumber *)reactTag message:(NSString *)message)
94
+{
95
+  [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNCWebView *> *viewRegistry) {
96
+    RNCWebView *view = viewRegistry[reactTag];
97
+    if (![view isKindOfClass:[RNCWebView class]]) {
98
+      RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view);
99
+    } else {
100
+      [view postMessage:message];
101
+    }
102
+  }];
103
+}
104
+
105
+RCT_EXPORT_METHOD(injectJavaScript:(nonnull NSNumber *)reactTag script:(NSString *)script)
106
+{
107
+  [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNCWebView *> *viewRegistry) {
108
+    RNCWebView *view = viewRegistry[reactTag];
109
+    if (![view isKindOfClass:[RNCWebView class]]) {
110
+      RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view);
111
+    } else {
112
+      [view injectJavaScript:script];
113
+    }
114
+  }];
115
+}
116
+
117
+#pragma mark - Exported synchronous methods
118
+
119
+- (BOOL)webView:(__unused RNCWebView *)webView
120
+shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
121
+   withCallback:(RCTDirectEventBlock)callback
122
+{
123
+  _shouldStartLoadLock = [[NSConditionLock alloc] initWithCondition:arc4random()];
124
+  _shouldStartLoad = YES;
125
+  request[@"lockIdentifier"] = @(_shouldStartLoadLock.condition);
126
+  callback(request);
127
+
128
+  // Block the main thread for a maximum of 250ms until the JS thread returns
129
+  if ([_shouldStartLoadLock lockWhenCondition:0 beforeDate:[NSDate dateWithTimeIntervalSinceNow:.25]]) {
130
+    BOOL returnValue = _shouldStartLoad;
131
+    [_shouldStartLoadLock unlock];
132
+    _shouldStartLoadLock = nil;
133
+    return returnValue;
134
+  } else {
135
+    RCTLogWarn(@"Did not receive response to shouldStartLoad in time, defaulting to YES");
136
+    return YES;
137
+  }
138
+}
139
+
140
+RCT_EXPORT_METHOD(startLoadWithResult:(BOOL)result lockIdentifier:(NSInteger)lockIdentifier)
141
+{
142
+  if ([_shouldStartLoadLock tryLockWhenCondition:lockIdentifier]) {
143
+    _shouldStartLoad = result;
144
+    [_shouldStartLoadLock unlockWithCondition:0];
145
+  } else {
146
+    RCTLogWarn(@"startLoadWithResult invoked with invalid lockIdentifier: "
147
+               "got %lld, expected %lld", (long long)lockIdentifier, (long long)_shouldStartLoadLock.condition);
148
+  }
149
+}
150
+
151
+@end