@@ -28,37 +28,17 @@ of this software and associated documentation files (the "Software"), to deal
28
28
// Webview not available on tvOS
29
29
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
30
30
31
+ #import < WebKit/WKWebView.h>
32
+ #import < WebKit/WKUIDelegate.h>
33
+ #import < WebKit/WKNavigationDelegate.h>
34
+
31
35
#include " ui/UIWebView/UIWebViewImpl-ios.h"
36
+ #include " ui/UIWebView/UIWebView.h"
32
37
#include " renderer/CCRenderer.h"
33
38
#include " base/CCDirector.h"
34
39
#include " platform/CCGLView.h"
35
40
#include " platform/ios/CCEAGLView-ios.h"
36
41
#include " platform/CCFileUtils.h"
37
- #include " ui/UIWebView/UIWebView.h"
38
-
39
- static std::string getFixedBaseUrl (const std::string& baseUrl)
40
- {
41
- std::string fixedBaseUrl;
42
- if (baseUrl.empty () || baseUrl.at (0 ) != ' /' ) {
43
- fixedBaseUrl = [[[NSBundle mainBundle ] resourcePath ] UTF8String ];
44
- fixedBaseUrl += " /" ;
45
- fixedBaseUrl += baseUrl;
46
- }
47
- else {
48
- fixedBaseUrl = baseUrl;
49
- }
50
-
51
- size_t pos = 0 ;
52
- while ((pos = fixedBaseUrl.find (" " )) != std::string::npos) {
53
- fixedBaseUrl.replace (pos, 1 , " %20" );
54
- }
55
-
56
- if (fixedBaseUrl.at (fixedBaseUrl.length () - 1 ) != ' /' ) {
57
- fixedBaseUrl += " /" ;
58
- }
59
-
60
- return fixedBaseUrl;
61
- }
62
42
63
43
@interface UIWebViewWrapper : NSObject
64
44
@property (nonatomic ) std::function<bool(std::string url)> shouldStartLoading;
@@ -107,8 +87,9 @@ - (void)setScalesPageToFit:(const bool)scalesPageToFit;
107
87
@end
108
88
109
89
110
- @interface UIWebViewWrapper () <UIWebViewDelegate>
111
- @property (nonatomic , retain ) UIWebView *uiWebView;
90
+ @interface UIWebViewWrapper () <WKUIDelegate , WKNavigationDelegate >
91
+ @property (nonatomic , retain ) WKWebView *wkWebView;
92
+
112
93
@property (nonatomic , copy ) NSString *jsScheme;
113
94
@end
114
95
@@ -123,7 +104,7 @@ + (instancetype) newWebViewWrapper {
123
104
- (instancetype )init {
124
105
self = [super init ];
125
106
if (self) {
126
- self.uiWebView = nil ;
107
+ self.wkWebView = nil ;
127
108
self.shouldStartLoading = nullptr ;
128
109
self.didFinishLoading = nullptr ;
129
110
self.didFailLoading = nullptr ;
@@ -132,56 +113,58 @@ - (instancetype)init {
132
113
}
133
114
134
115
- (void )dealloc {
135
- self.uiWebView .delegate = nil ;
136
- [self .uiWebView removeFromSuperview ];
137
- [self .uiWebView release ];
138
- self.uiWebView = nil ;
116
+ self.wkWebView .UIDelegate = nil ;
117
+ self.wkWebView .navigationDelegate = nil ;
118
+ [self .wkWebView removeFromSuperview ];
119
+ [self .wkWebView release ];
120
+ self.wkWebView = nil ;
139
121
self.jsScheme = nil ;
140
122
[super dealloc ];
141
123
}
142
124
143
125
- (void )setupWebView {
144
- if (!self.uiWebView ) {
145
- self.uiWebView = [[UIWebView alloc ] init ];
146
- self.uiWebView .delegate = self;
126
+ if (!self.wkWebView ) {
127
+ self.wkWebView = [[WKWebView alloc ] init ];
128
+ self.wkWebView .UIDelegate = self;
129
+ self.wkWebView .navigationDelegate = self;
147
130
}
148
- if (!self.uiWebView .superview ) {
131
+ if (!self.wkWebView .superview ) {
149
132
auto view = cocos2d::Director::getInstance ()->getOpenGLView ();
150
133
auto eaglview = (CCEAGLView *) view->getEAGLView ();
151
- [eaglview addSubview: self .uiWebView ];
134
+ [eaglview addSubview: self .wkWebView ];
152
135
}
153
136
}
154
137
155
138
- (void )setVisible : (bool )visible {
156
- if (!self.uiWebView ) {[self setupWebView ];}
157
- self.uiWebView .hidden = !visible;
139
+ if (!self.wkWebView ) {[self setupWebView ];}
140
+ self.wkWebView .hidden = !visible;
158
141
}
159
142
160
143
- (void )setBounces : (bool )bounces {
161
- self.uiWebView .scrollView .bounces = bounces;
144
+ self.wkWebView .scrollView .bounces = bounces;
162
145
}
163
146
164
147
- (void )setOpacityWebView : (float )opacity {
165
- if (!self.uiWebView ) {[self setupWebView ];}
166
- self.uiWebView .alpha = opacity;
167
- [self .uiWebView setOpaque: NO ];
148
+ if (!self.wkWebView ) { [self setupWebView ]; }
149
+ self.wkWebView .alpha = opacity;
150
+ [self .wkWebView setOpaque: YES ];
168
151
}
169
152
170
153
-(float ) getOpacityWebView {
171
- return self.uiWebView .alpha ;
154
+ return self.wkWebView .alpha ;
172
155
}
173
156
174
157
-(void ) setBackgroundTransparent {
175
- if (!self.uiWebView ) {[self setupWebView ];}
176
- [self .uiWebView setOpaque: NO ];
177
- [self .uiWebView setBackgroundColor: [UIColor clearColor ]];
158
+ if (!self.wkWebView ) {[self setupWebView ];}
159
+ [self .wkWebView setOpaque: NO ];
160
+ [self .wkWebView setBackgroundColor: [UIColor clearColor ]];
178
161
}
179
162
180
163
- (void )setFrameWithX : (float )x y : (float )y width : (float )width height : (float )height {
181
- if (!self.uiWebView ) {[self setupWebView ];}
164
+ if (!self.wkWebView ) {[self setupWebView ];}
182
165
CGRect newFrame = CGRectMake (x, y, width, height);
183
- if (!CGRectEqualToRect (self.uiWebView .frame , newFrame)) {
184
- self.uiWebView .frame = CGRectMake (x, y, width, height);
166
+ if (!CGRectEqualToRect (self.wkWebView .frame , newFrame)) {
167
+ self.wkWebView .frame = CGRectMake (x, y, width, height);
185
168
}
186
169
}
187
170
@@ -190,19 +173,26 @@ - (void)setJavascriptInterfaceScheme:(const std::string &)scheme {
190
173
}
191
174
192
175
- (void )loadData : (const std::string &)data MIMEType : (const std::string &)MIMEType textEncodingName : (const std::string &)encodingName baseURL : (const std::string &)baseURL {
193
- [self .uiWebView loadData: [NSData dataWithBytes: data.c_str () length: data.length ()]
176
+ auto path = [[NSBundle mainBundle ] resourcePath ];
177
+ path = [path stringByAppendingPathComponent: @(baseURL.c_str () )];
178
+ auto url = [NSURL fileURLWithPath: path];
179
+
180
+ [self .wkWebView loadData: [NSData dataWithBytes: data.c_str () length: data.length ()]
194
181
MIMEType: @(MIMEType.c_str ())
195
- textEncodingName : @(encodingName.c_str ())
196
- baseURL: [ NSURL URLWithString: @( getFixedBaseUrl (baseURL). c_str ())] ];
182
+ characterEncodingName : @(encodingName.c_str ())
183
+ baseURL: url ];
197
184
}
198
185
199
186
- (void )loadHTMLString : (const std::string &)string baseURL : (const std::string &)baseURL {
200
- if (!self.uiWebView ) {[self setupWebView ];}
201
- [self .uiWebView loadHTMLString: @(string.c_str ()) baseURL: [NSURL URLWithString: @(getFixedBaseUrl (baseURL).c_str ())]];
187
+ if (!self.wkWebView ) {[self setupWebView ];}
188
+ auto path = [[NSBundle mainBundle ] resourcePath ];
189
+ path = [path stringByAppendingPathComponent: @(baseURL.c_str () )];
190
+ auto url = [NSURL fileURLWithPath: path];
191
+ [self .wkWebView loadHTMLString: @(string.c_str ()) baseURL: url];
202
192
}
203
193
204
194
- (void )loadUrl : (const std::string &)urlString cleanCachedData : (BOOL ) needCleanCachedData {
205
- if (!self.uiWebView ) {[self setupWebView ];}
195
+ if (!self.wkWebView ) {[self setupWebView ];}
206
196
NSURL *url = [NSURL URLWithString: @(urlString.c_str ())];
207
197
208
198
NSURLRequest *request = nil ;
@@ -211,83 +201,107 @@ - (void)loadUrl:(const std::string &)urlString cleanCachedData:(BOOL) needCleanC
211
201
else
212
202
request = [NSURLRequest requestWithURL: url];
213
203
214
- [self .uiWebView loadRequest: request];
204
+ [self .wkWebView loadRequest: request];
215
205
}
216
206
217
-
218
-
219
207
- (void )loadFile : (const std::string &)filePath {
220
- if (!self.uiWebView ) {[self setupWebView ];}
208
+ if (!self.wkWebView ) {[self setupWebView ];}
221
209
NSURL *url = [NSURL fileURLWithPath: @(filePath.c_str ())];
222
210
NSURLRequest *request = [NSURLRequest requestWithURL: url];
223
- [self .uiWebView loadRequest: request];
211
+ [self .wkWebView loadRequest: request];
224
212
}
225
213
226
214
- (void )stopLoading {
227
- [self .uiWebView stopLoading ];
215
+ [self .wkWebView stopLoading ];
228
216
}
229
217
230
218
- (void )reload {
231
- [self .uiWebView reload ];
219
+ [self .wkWebView reload ];
232
220
}
233
221
234
222
- (BOOL )canGoForward {
235
- return self.uiWebView .canGoForward ;
223
+ return self.wkWebView .canGoForward ;
236
224
}
237
225
238
226
- (BOOL )canGoBack {
239
- return self.uiWebView .canGoBack ;
227
+ return self.wkWebView .canGoBack ;
240
228
}
241
229
242
230
- (void )goBack {
243
- [self .uiWebView goBack ];
231
+ [self .wkWebView goBack ];
244
232
}
245
233
246
234
- (void )goForward {
247
- [self .uiWebView goForward ];
235
+ [self .wkWebView goForward ];
248
236
}
249
237
250
238
- (void )evaluateJS : (const std::string &)js {
251
- if (!self.uiWebView ) {[self setupWebView ];}
252
- [self .uiWebView stringByEvaluatingJavaScriptFromString : @(js.c_str ())];
239
+ if (!self.wkWebView ) {[self setupWebView ];}
240
+ [self .wkWebView evaluateJavaScript : @(js.c_str ()) completionHandler: nil ];
253
241
}
254
242
255
243
- (void )setScalesPageToFit : (const bool )scalesPageToFit {
256
- if (!self.uiWebView ) {[self setupWebView ];}
257
- self.uiWebView .scalesPageToFit = scalesPageToFit;
244
+ // TODO: there is not corresponding API in WK.
245
+ // https://stackoverflow.com/questions/26295277/wkwebview-equivalent-for-uiwebviews-scalespagetofit/43048514 seems has a solution,
246
+ // but it doesn't support setting it dynamically. If we want to set this feature dynamically, then it will be too complex.
258
247
}
259
248
260
249
261
250
262
- #pragma mark - UIWebViewDelegate
263
- - (BOOL )webView : (UIWebView *)webView shouldStartLoadWithRequest : ( NSURLRequest *)request navigationType : (UIWebViewNavigationType) navigationType {
264
- NSString *url = [[request URL ] absoluteString ];
265
- if ([[[request URL ] scheme ] isEqualToString: self .jsScheme]) {
251
+ #pragma mark - WKNavigationDelegate
252
+ - (void )webView : (WKWebView *)webView decidePolicyForNavigationAction : ( WKNavigationAction *)navigationAction decisionHandler : ( void (^)( WKNavigationActionPolicy )) decisionHandler {
253
+ NSString *url = [webView. URL absoluteString ];
254
+ if ([[webView. URL scheme ] isEqualToString: self .jsScheme]) {
266
255
self.onJsCallback ([url UTF8String ]);
267
- return NO ;
256
+ decisionHandler (WKNavigationActionPolicyCancel );
257
+ return ;
268
258
}
269
259
if (self.shouldStartLoading && url) {
270
- return self.shouldStartLoading ([url UTF8String ]);
260
+ if (self.shouldStartLoading ([url UTF8String ]) )
261
+ decisionHandler (WKNavigationActionPolicyAllow );
262
+ else
263
+ decisionHandler (WKNavigationActionPolicyCancel );
264
+
265
+ return ;
271
266
}
272
- return YES ;
267
+
268
+ decisionHandler (WKNavigationActionPolicyAllow );
273
269
}
274
270
275
- - (void )webViewDidFinishLoad : (UIWebView *)webView {
271
+ - (void )webView : ( WKWebView *)webView didFinishNavigation : ( WKNavigation *) navigation {
276
272
if (self.didFinishLoading ) {
277
- NSString *url = [[ webView.request URL ] absoluteString ];
273
+ NSString *url = [webView.URL absoluteString ];
278
274
self.didFinishLoading ([url UTF8String ]);
279
275
}
280
276
}
281
277
282
- - (void )webView : (UIWebView *)webView didFailLoadWithError : (NSError *)error {
278
+ - (void )webView : (WKWebView *)webView didFailProvisionalNavigation : ( WKNavigation *) navigation withError : (NSError *)error {
283
279
if (self.didFailLoading ) {
284
- NSString *url = error.userInfo [NSURLErrorFailingURLStringErrorKey ];
285
- if (url ) {
286
- self.didFailLoading ([url UTF8String ]);
280
+ NSString *errorInfo = error.userInfo [NSURLErrorFailingURLStringErrorKey ];
281
+ if (errorInfo ) {
282
+ self.didFailLoading ([errorInfo UTF8String ]);
287
283
}
288
284
}
289
285
}
290
286
287
+ #pragma WKUIDelegate
288
+
289
+ // Implement js alert function.
290
+ - (void )webView : (WKWebView *)webView runJavaScriptAlertPanelWithMessage : (NSString *)message initiatedByFrame : (WKFrameInfo *)frame completionHandler : (void (^)())completionHandler
291
+ {
292
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle: message
293
+ message: nil
294
+ preferredStyle: UIAlertControllerStyleAlert];
295
+ [alertController addAction: [UIAlertAction actionWithTitle: @" Ok"
296
+ style: UIAlertActionStyleCancel
297
+ handler: ^(UIAlertAction *action) {
298
+ completionHandler ();
299
+ }]];
300
+
301
+ auto rootViewController = [UIApplication sharedApplication ].keyWindow .rootViewController ;
302
+ [rootViewController presentViewController: alertController animated: YES completion: ^{}];
303
+ }
304
+
291
305
@end
292
306
293
307
0 commit comments