iOS之UIWebView的坑
iOS之UIWebView的坑
背景:我廠這個版本在開發航拍圖,是一個H5頁面,但是就是一個H5頁面竟然引起了APP的crash。在當前航拍圖頁面,app進入後臺,會直接crash。掛在gpus_returnnotpermittedkillclient
這個bug是iOS10.8以後就有的,特大好訊息就是,iOS11蘋果就把這個bug修復了,所以iOS11不會出現。
原因是,iOS進入後臺禁止呼叫webGL,一幀都不允許,而這個H5還在呼叫,所以直接崩潰。而且遊戲裡面使用的openGL,在進入後臺的時候是直接停止的
失敗方案:
參考連結:其中一個解決方案
[https://forums.developer.apple.com/thread/30896]
1.webView loadRequest 之間呼叫,set bEnable NO,但是會引起webView上整張圖都載入不出來。
2.進入後臺的時候 set bEnable NO,進入前臺 set bEnable YES,但是依然沒有什麼用。
typedef void (*CallFuc)(id, SEL, BOOL);
typedef BOOL (*GetFuc)(id, SEL);
-(BOOL)webView:(UIWebView*)view enableGL:(BOOL)bEnable
{
BOOL bRet = NO;
do
{
Ivar internalVar = class_getInstanceVariable([view class], "_internal");
if (!internalVar)
{
NSLog(@"enable GL _internal invalid!");
break;
}
UIWebViewInternal* internalObj = object_getIvar(view, internalVar);
Ivar browserVar = class_getInstanceVariable(object_getClass(internalObj), "browserView");
if (!browserVar)
{
NSLog(@"enable GL browserView invalid!");
break;
}
id webbrowser = object_getIvar(internalObj, browserVar);
Ivar webViewVar = class_getInstanceVariable(object_getClass(webbrowser), "_webView");
if (!webViewVar)
{
NSLog(@"enable GL _webView invalid!");
break;
}
id webView = object_getIvar(webbrowser, webViewVar);
if (!webView)
{
NSLog(@"enable GL webView obj nil!");
}
if(object_getClass(webView) != NSClassFromString(@"WebView"))
{
NSLog(@"enable GL webView not WebView!");
break;
}
SEL selector = NSSelectorFromString(@"_setWebGLEnabled:");
IMP impSet = [webView methodForSelector:selector];
CallFuc func = (CallFuc)impSet;
func(webView, selector, bEnable);
SEL selectorGet = NSSelectorFromString(@"_webGLEnabled");
IMP impGet = [webView methodForSelector:selectorGet];
GetFuc funcGet = (GetFuc)impGet;
BOOL val = funcGet(webView, selector);
bRet = (val == bEnable);
}while(NO);
return bRet;
}
最終解決方案有兩個:
1.H5協議,暴露出可以停止繪製和重新繪製的方法,app端在進前臺和後臺的時候呼叫。
2.用WKWebView把UIWebView替換掉。
參考文件:[https://developer.apple.com/documentation/webkit/wkwebview]
一些我用到的WKWebView代理如下,詳細的參考官方文件;
- (void)loadWebViewWithURL:(NSString *)urlString
{
NSURL *url = [self rtCreateWebViewURL:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:[AIFAppContext sharedInstance].appName forHTTPHeaderField:@"X-AJK-APP"];
NSString *cv = [[AJKSettingsManager sharedInstance] getAppVersion]?[[AJKSettingsManager sharedInstance] getAppVersion]:@"";
[request setValue:cv forHTTPHeaderField:@"X-AJK-CV"];
[self.webView loadRequest:request];
}
- (NSURL *)rtCreateWebViewURL:(NSString *)urlString
{
return [NSURL URLWithString:urlString];
}
pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
[self routeHandleWithRequest:webView.URL];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
weakify(self);
[webView evaluateJavaScript:@"document.title" completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
if (obj) {
strongify(self);
NSString *title = [NSString stringWithFormat:@"%@",obj];
self.title = title;
}
}];
NSURL *requestURL = webView.URL;
NSString *host = [requestURL host];
if ([host rangeOfString:@"anjuke.com" options:NSCaseInsensitiveSearch].location != NSNotFound
|| [host rangeOfString:@"58.com" options:NSCaseInsensitiveSearch].location != NSNotFound
|| [host rangeOfString:@"anjuke.test" options:NSCaseInsensitiveSearch].location != NSNotFound) {
weakify(self);
[webView evaluateJavaScript:[NSString stringWithFormat:@"getShareContents()"] completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
if (obj) {
strongify(self);
NSString *str = [NSString stringWithFormat:@"%@",obj];
if (str.length > 0) {
NSArray *shares = [str JSONValue];
if ([shares isKindOfClass:[NSArray class]] && shares.count > 0) {
[self setShareDicFromArray:shares];
[self showShareBtn];
}
}
}
}];
}
[self.activity removeFromSuperview];
}
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
if (![self checkNetwork]) {
[self.errorView showInView:self.view type:RTMessageTypeNoNetWork target:self action:@selector(reloadWebView)];
}
[self.activity removeFromSuperview];
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
}
pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
}
html的alert不彈的問題
需要實現WKWebView的UIDelegate
#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = defaultText;
}];
[alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
所以下版本計劃將原本app裡面的ADViewController的UIWebView替換成WKWebView,希望沒有什麼新坑!
相關文章
- 【問題收集】UIWebView的坑UIWebView
- iOS與JS互動之UIWebView-JavaScriptCore框架iOSJSUIWebViewJavaScript框架
- iOS Cell巢狀UIWebView(內附UIWebView詳解)iOS巢狀UIWebView
- iOS UIWebView、WKWebView注入CookieiOSUIWebViewCookie
- iOS 中UIWebView與WKWebViewiOSUIWebView
- iOS與JS互動之UIWebView協議攔截iOSJSUIWebView協議
- ios uiwebview wkwebview注意點小記iOSUIWebView
- IOS開發系列——UIWebView專題iOSUIWebView
- iOS UIWebview仿微信進度條iOSUIWebView
- 【iOS開發】從UIWebView到WKWebViewiOSUIWebView
- [iOS]貝聊 IAP 實戰之見坑填坑iOS
- ios UIWebView 載入網頁、檔案、 htmliOSUIWebView網頁HTML
- ReactNative 踩坑之 iOS 原生元件ReactiOS元件
- iOS初學之填坑總結iOS
- iOS 踩坑之 "YYYY-MM-dd"iOS
- ios,framework的坑iOSFramework
- iOS UIWebView載入時新增進度條01iOSUIWebView
- iOS UIWebView記憶體暴漲問題的解決方法iOSUIWebView記憶體
- iOS下JS與OC互相呼叫(五)--UIWebView + WebViewJavascriptBridgeiOSJSUIWebViewJavaScript
- iOS AVPlayer的那些坑iOS
- iOS開發之UIRefreshControl使用踩坑iOSUI
- iOS下JS與OC互相呼叫(一)--UIWebView 攔截URLiOSJSUIWebView
- UIWebView的使用小結UIWebView
- iOS開發:給UIWebview的導航欄新增返回、關閉按鈕iOSUIWebView
- iOS開發的那些坑iOS
- iOS 11 適配的坑iOS
- iOS Swift UITableView的scrollToRow的”坑”iOSSwiftUIView
- iOS Swift UITableView的scrollToRow的"坑"iOSSwiftUIView
- iOS UIScrollVIew UITableView UIwebView WKWebView 截全圖,生成全圖方法iOSUIWebView
- iOS開發之AFNetWorking初次使用會報錯的坑iOS
- UIWebview 與WKWebviewUIWebView
- 關於UIWebView的總結UIWebView
- iOS開發的那些坑(貳)iOS
- iOS坑:UIView的frame和transfromiOSUIView
- 【iOS】那些年,遇到的小坑iOS
- iOS 和 H5 互動那些事 (UIWebView、WKWebView 總結篇)iOSH5UIWebView
- React Native學習之Image載入本地圖片的坑(iOS)React Native地圖iOS
- 從 UIWebView 到 WKWebViewUIWebView