Commit 9896fcfd cgx

优化WKWebView

1 个父辈 2a9005b2
......@@ -37,11 +37,17 @@ FOUNDATION_EXTERN NSString * const Function_Option;
/// 放松训练
FOUNDATION_EXTERN NSString * const RelaxTrain;
/// 数据统计工具
#pragma mark - 友盟自定义异常
FOUNDATION_EXTERN NSString * const H5Monitor;
/// 数据统计及自定义异常上报工具
@interface DataStatisticsUtil : NSObject
+ (void)event:(NSString *)eventId attributes:(NSDictionary *)attributes;
+(void)reportExceptionWithName:(NSString* _Nonnull)name
reason:(NSString* _Nonnull)reason
stackTrace:(NSArray* _Nonnull)stackTrace;
@end
NS_ASSUME_NONNULL_END
......@@ -7,6 +7,7 @@
#import "DataStatisticsUtil.h"
#import <UMCommon/MobClick.h>
#import <UMAPM/UMCrashConfigure.h>
NSString * const Banner_Click = @"Banner_Click";
NSString * const Relax_Tool_Click = @"Relax_Tool_Click";
......@@ -22,6 +23,8 @@ NSString * const inviteFriends = @"inviteFriends";
NSString * const Function_Option = @"Function_Option";
NSString * const RelaxTrain = @"RelaxTrain";
NSString * const H5Monitor = @"H5Monitor";
@implementation DataStatisticsUtil
+ (void)event:(NSString *)eventId attributes:(NSDictionary *)attributes {
......@@ -32,4 +35,14 @@ NSString * const RelaxTrain = @"RelaxTrain";
#endif
}
+(void)reportExceptionWithName:(NSString* _Nonnull)name
reason:(NSString* _Nonnull)reason
stackTrace:(NSArray* _Nonnull)stackTrace
{
#if DSRELEASE == 1
DSLog(@"name:%@, reason:%@", name, reason);
[UMCrashConfigure reportExceptionWithName:name reason:reason stackTrace:stackTrace];
#endif
}
@end
......@@ -21,8 +21,12 @@
@property (nonatomic, strong) ExceptionDefaultView *exceptionView;
/// 白天/夜间模式导航栏返回按钮
@property (nonatomic, strong) UIButton *dkBackBtn;
/// 遮罩
@property (nonatomic, strong) DsMaskView *dsMaskView;
/// 邀请好友悬浮框
@property (nonatomic, strong) UIView *inviteView;
/// 是否已获取当前webview的title
@property (assign, nonatomic) BOOL webViewLoadTitle;
@end
@implementation DsWebController
......@@ -64,6 +68,26 @@
}];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
/*
webview已获取到title,但返回时无法获取title:
可能是内存不足造成的,此时需要重新加载同时避免第一次进入重新加载;
*/
if (self.webViewLoadTitle == YES && self.webView.title == nil) {
[self.webView reload];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.webView.title) {
self.webViewLoadTitle = YES;
}
}
- (void)dealloc {
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"AppModel"];
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
......@@ -88,6 +112,13 @@
#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(nonnull WKNavigationAction *)navigationAction decisionHandler:(nonnull void (^)(WKNavigationActionPolicy))decisionHandler {
DSLog(@"通用H5页面入口->跳转链接:%@", navigationAction.request.URL.absoluteString);
// 为了解决跨域问题,每次跳转url时把cookies拼接上
NSMutableURLRequest *request = (NSMutableURLRequest *)navigationAction.request;
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
request.allHTTPHeaderFields = dict;
decisionHandler(WKNavigationActionPolicyAllow);
}
......@@ -110,6 +141,15 @@
if (self.isShowNavi == NO) { self.dkBackBtn.hidden = NO; }
}
// 内存不足出现白屏问题
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
[self.webView reload];
// 友盟自定义异常
NSString *url = self.webView.URL.absoluteString.lastPathComponent ? self.webView.URL.absoluteString.lastPathComponent : @"空链接";
[DataStatisticsUtil reportExceptionWithName:H5Monitor reason:@"webViewWebContentProcessDidTerminate" stackTrace:@[url]];
}
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"AppModel"]) {
......
......@@ -18,7 +18,9 @@
@property (strong, nonatomic) NSMutableURLRequest *request;
@property (strong, nonatomic) UIProgressView *progressView;
@property (strong, nonatomic) ExceptionDefaultView *exceptionView;
@property (nonatomic, strong) DsMaskView *dsMaskView;
@property (strong, nonatomic) DsMaskView *dsMaskView;
/// 是否已获取当前webview的title
@property (assign, nonatomic) BOOL webViewLoadTitle;
@end
@implementation AISleepCoachController
......@@ -36,16 +38,40 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(needUpdateAiCoach) name:NeedUpdateAICoach object:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.dsMaskView display];
/*
webview已获取到title,但返回时无法获取title:
可能是内存不足造成的,此时需要重新加载同时避免第一次进入重新加载;
*/
if (self.webViewLoadTitle == YES && self.aiWebView.title == nil) {
[self.aiWebView reload];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.aiWebView.title) {
self.webViewLoadTitle = YES;
}
}
- (void)dealloc {
[self.aiWebView.configuration.userContentController removeScriptMessageHandlerForName:@"AppModel"];
[self.aiWebView removeObserver:self forKeyPath:@"estimatedProgress"];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NeedUpdateAICoach object:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.dsMaskView display];
- (void)needUpdateAiCoach {
// 拼接Cookies的方式同步cookie
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
self.request.allHTTPHeaderFields = dict;
[self.aiWebView loadRequest:self.request];
}
#pragma mark - DsWebControllerDelegate && RelaxTrainControllerDelegate
......@@ -105,6 +131,15 @@
DSLog(@"加载失败:%@", error);
}
// 内存不足出现白屏问题
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
[self.aiWebView reload];
// 友盟自定义异常
NSString *url = self.aiWebView.URL.absoluteString.lastPathComponent ? self.aiWebView.URL.absoluteString.lastPathComponent : @"空链接";
[DataStatisticsUtil reportExceptionWithName:H5Monitor reason:@"webViewWebContentProcessDidTerminate" stackTrace:@[url]];
}
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"AppModel"]) {
......@@ -155,90 +190,7 @@
default:
break;
}
// 注入js代码用于强制刷新小梦睡眠
// NSString *jsCallBack = @"window.parent.location.reload()";
// [self.aiWebView evaluateJavaScript:jsCallBack completionHandler:^(id _Nullable result, NSError * _Nullable error) {
// [self.aiWebView loadRequest:self.request];
// DSLog(@"注入成功...");
// if (error) {
// DSLog(@"err is %@", error.domain);
// }
// }];
}
}
#pragma mark - 方法1(拼接Cookies的方式)
- (void)needUpdateAiCoach {
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
self.request.allHTTPHeaderFields = dict;
[self.aiWebView loadRequest:self.request];
// 方法2:同步cookie(登录成功后设置,iOS 11及以上,存在部分设备无法同步问题)
// [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
// // 获取cookie信息
// NSDictionary *properties = kGetUserDefaultsObj(DsAppCookie);
// NSMutableDictionary *muProperties = [NSMutableDictionary dictionaryWithDictionary:properties];
// NSURL *url = [NSURL URLWithString:ServerURL];
// NSString *IP = url.host;
// [muProperties setValue:IP forKey:@"Domain"];
// NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:muProperties];
// [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
// // 同步cookie
// WKHTTPCookieStore *cookieStrore = self.aiWebView.configuration.websiteDataStore.httpCookieStore;
// NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
// for (NSHTTPCookie *cookie in cookies) {
// if ([cookie.domain isEqualToString:IP]) {
// [cookieStrore setCookie:cookie completionHandler:^{
// [self.aiWebView loadRequest:self.request];
// }];
// }
// }
// 该方法在部分设备失效(存在部分设备无法同步问题)
// NSHTTPCookie *sidCookie = nil;
// for (NSHTTPCookie *cookie in [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies) {
// // connect.sid是后台下发的cookie字段
// if ([cookie.name isEqualToString:@"connect.sid"]) {
// sidCookie = cookie;
// break;;
// }
// }
// // 将APP获取的cookie同步给wkwebview容器里面的cookie(wkwebview存在cookie不同步的巨坑,该同步API在iOS 11及以后支持)
// [self.aiWebView.configuration.websiteDataStore.httpCookieStore setCookie:sidCookie completionHandler:^{
// [self.aiWebView loadRequest:self.request];
// }];
}
#pragma mark - 方法3:通过js注入cookie(推荐)
- (WKUserScript *)injectCookieScript {
WKUserScript *userScript = [[WKUserScript alloc] initWithSource:[self cookieString] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
return userScript;
}
- (NSString *)cookieString {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
// 获取cookie信息
NSDictionary *properties = kGetUserDefaultsObj(DsAppCookie);
NSMutableDictionary *muProperties = [NSMutableDictionary dictionaryWithDictionary:properties];
NSURL *url = [NSURL URLWithString:ServerURL];
NSString *IP = url.host;
[muProperties setValue:IP forKey:@"Domain"];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:muProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
NSMutableString *script = [NSMutableString string];
[script appendString:@"var cookieNames = document.cookie.split('; ').map(function(cookie) { return cookie.split('=')[0] } );\n"];
for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
if ([cookie.value rangeOfString:@"'"].location != NSNotFound) {
continue;
}
if ([cookie.domain isEqualToString:IP]) {
NSString *string = [NSString stringWithFormat:@"%@=%@;domain=%@;path=%@", cookie.name, cookie.value, cookie.domain, cookie.path ?: @"/"];
[script appendFormat:@"if (cookieNames.indexOf('%@') == -1) {document.cookie='%@'; };\n", cookie.name, string];
}
}
return script;
}
#pragma mark - lazy
......
......@@ -240,14 +240,6 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
/*
// 给我评分
NSString *evaluateStr = [NSString stringWithFormat: @"itms-apps://itunes.apple.com/app/id%@?action=write-review", AppSotreID];
NSURL *url = [NSURL URLWithString:evaluateStr];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}
*/
} else if (indexPath.row == 3) { // 清除缓存
[DsCacheUtils cleanCacheWithSuccess:^(BOOL success) {
}];
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!