Skip to content

Commit 9df47ef

Browse files
authored
use WKWebview instead (#20103)
UIWebView is removed in iOS 13.
1 parent d9e6c74 commit 9df47ef

File tree

3 files changed

+101
-85
lines changed

3 files changed

+101
-85
lines changed

cmake/Modules/CocosConfigDepend.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ macro(cocos2dx_depend)
6969
find_library(CORE_GRAPHICS_LIBRARY CoreGraphics)
7070
find_library(AV_FOUNDATION_LIBRARY AVFoundation)
7171
find_library(Z_LIBRARY z)
72+
find_library(WEBKIT_LIBRARY WebKit)
7273
list(APPEND PLATFORM_SPECIFIC_LIBS
7374
${UIKIT_LIBRARY}
7475
${OPENGLES_LIBRARY}
@@ -80,6 +81,7 @@ macro(cocos2dx_depend)
8081
${CORE_GRAPHICS_LIBRARY}
8182
${AV_FOUNDATION_LIBRARY}
8283
${Z_LIBRARY}
84+
${WEBKIT_LIBRARY}
8385
${COCOS_APPLE_LIBS}
8486
)
8587
endif()

cocos/ui/UIWebView/UIWebViewImpl-ios.mm

Lines changed: 98 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,17 @@ of this software and associated documentation files (the "Software"), to deal
2828
// Webview not available on tvOS
2929
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
3030

31+
#import <WebKit/WKWebView.h>
32+
#import <WebKit/WKUIDelegate.h>
33+
#import <WebKit/WKNavigationDelegate.h>
34+
3135
#include "ui/UIWebView/UIWebViewImpl-ios.h"
36+
#include "ui/UIWebView/UIWebView.h"
3237
#include "renderer/CCRenderer.h"
3338
#include "base/CCDirector.h"
3439
#include "platform/CCGLView.h"
3540
#include "platform/ios/CCEAGLView-ios.h"
3641
#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-
}
6242

6343
@interface UIWebViewWrapper : NSObject
6444
@property (nonatomic) std::function<bool(std::string url)> shouldStartLoading;
@@ -107,8 +87,9 @@ - (void)setScalesPageToFit:(const bool)scalesPageToFit;
10787
@end
10888

10989

110-
@interface UIWebViewWrapper () <UIWebViewDelegate>
111-
@property(nonatomic, retain) UIWebView *uiWebView;
90+
@interface UIWebViewWrapper () <WKUIDelegate, WKNavigationDelegate>
91+
@property(nonatomic, retain) WKWebView *wkWebView;
92+
11293
@property(nonatomic, copy) NSString *jsScheme;
11394
@end
11495

@@ -123,7 +104,7 @@ + (instancetype) newWebViewWrapper {
123104
- (instancetype)init {
124105
self = [super init];
125106
if (self) {
126-
self.uiWebView = nil;
107+
self.wkWebView = nil;
127108
self.shouldStartLoading = nullptr;
128109
self.didFinishLoading = nullptr;
129110
self.didFailLoading = nullptr;
@@ -132,56 +113,58 @@ - (instancetype)init {
132113
}
133114

134115
- (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;
139121
self.jsScheme = nil;
140122
[super dealloc];
141123
}
142124

143125
- (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;
147130
}
148-
if (!self.uiWebView.superview) {
131+
if (!self.wkWebView.superview) {
149132
auto view = cocos2d::Director::getInstance()->getOpenGLView();
150133
auto eaglview = (CCEAGLView *) view->getEAGLView();
151-
[eaglview addSubview:self.uiWebView];
134+
[eaglview addSubview:self.wkWebView];
152135
}
153136
}
154137

155138
- (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;
158141
}
159142

160143
- (void)setBounces:(bool)bounces {
161-
self.uiWebView.scrollView.bounces = bounces;
144+
self.wkWebView.scrollView.bounces = bounces;
162145
}
163146

164147
- (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];
168151
}
169152

170153
-(float) getOpacityWebView{
171-
return self.uiWebView.alpha;
154+
return self.wkWebView.alpha;
172155
}
173156

174157
-(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]];
178161
}
179162

180163
- (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];}
182165
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);
185168
}
186169
}
187170

@@ -190,19 +173,26 @@ - (void)setJavascriptInterfaceScheme:(const std::string &)scheme {
190173
}
191174

192175
- (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()]
194181
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];
197184
}
198185

199186
- (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];
202192
}
203193

204194
- (void)loadUrl:(const std::string &)urlString cleanCachedData:(BOOL) needCleanCachedData {
205-
if (!self.uiWebView) {[self setupWebView];}
195+
if (!self.wkWebView) {[self setupWebView];}
206196
NSURL *url = [NSURL URLWithString:@(urlString.c_str())];
207197

208198
NSURLRequest *request = nil;
@@ -211,83 +201,107 @@ - (void)loadUrl:(const std::string &)urlString cleanCachedData:(BOOL) needCleanC
211201
else
212202
request = [NSURLRequest requestWithURL:url];
213203

214-
[self.uiWebView loadRequest:request];
204+
[self.wkWebView loadRequest:request];
215205
}
216206

217-
218-
219207
- (void)loadFile:(const std::string &)filePath {
220-
if (!self.uiWebView) {[self setupWebView];}
208+
if (!self.wkWebView) {[self setupWebView];}
221209
NSURL *url = [NSURL fileURLWithPath:@(filePath.c_str())];
222210
NSURLRequest *request = [NSURLRequest requestWithURL:url];
223-
[self.uiWebView loadRequest:request];
211+
[self.wkWebView loadRequest:request];
224212
}
225213

226214
- (void)stopLoading {
227-
[self.uiWebView stopLoading];
215+
[self.wkWebView stopLoading];
228216
}
229217

230218
- (void)reload {
231-
[self.uiWebView reload];
219+
[self.wkWebView reload];
232220
}
233221

234222
- (BOOL)canGoForward {
235-
return self.uiWebView.canGoForward;
223+
return self.wkWebView.canGoForward;
236224
}
237225

238226
- (BOOL)canGoBack {
239-
return self.uiWebView.canGoBack;
227+
return self.wkWebView.canGoBack;
240228
}
241229

242230
- (void)goBack {
243-
[self.uiWebView goBack];
231+
[self.wkWebView goBack];
244232
}
245233

246234
- (void)goForward {
247-
[self.uiWebView goForward];
235+
[self.wkWebView goForward];
248236
}
249237

250238
- (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];
253241
}
254242

255243
- (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.
258247
}
259248

260249

261250

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]) {
266255
self.onJsCallback([url UTF8String]);
267-
return NO;
256+
decisionHandler(WKNavigationActionPolicyCancel);
257+
return;
268258
}
269259
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;
271266
}
272-
return YES;
267+
268+
decisionHandler(WKNavigationActionPolicyAllow);
273269
}
274270

275-
- (void)webViewDidFinishLoad:(UIWebView *)webView {
271+
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
276272
if (self.didFinishLoading) {
277-
NSString *url = [[webView.request URL] absoluteString];
273+
NSString *url = [webView.URL absoluteString];
278274
self.didFinishLoading([url UTF8String]);
279275
}
280276
}
281277

282-
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
278+
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
283279
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]);
287283
}
288284
}
289285
}
290286

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+
291305
@end
292306

293307

tests/cpp-empty-test/proj.android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ PROP_TARGET_SDK_VERSION=28
3131
# Available architextures (armeabi-v7a | arm64-v8a | x86)
3232
# To build for multiple architexture, use the `:` between them
3333
# Example - PROP_APP_ABI=armeabi-v7a:arm64-v8a:x86
34-
PROP_APP_ABI=armeabi-v7a
34+
PROP_APP_ABI=x86
3535

3636
# uncomment it and fill in sign information for release mode
3737
#RELEASE_STORE_FILE=file path of keystore

0 commit comments

Comments
 (0)