Instantly share code, notes, and snippets.
Created
June 7, 2018 02:31
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(2)
2
You must be signed in to fork a gist
-
Save hite/e64fd705874550e6ef8928c5f323a2fe to your computer and use it in GitHub Desktop.
WKWebview 设置cookie 的代码示例
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CICAppHostViewController.m | |
// myApp | |
// | |
// 需要h5和native 相互调用接口 页面使用此viewcontroller。 | |
// | |
// Created by hite on 9/22/15. | |
// Copyright © 2015 netease. All rights reserved. | |
// | |
#import "CICAppHostViewController.h" | |
#import "CICUserDefaults.h" | |
#import "Reachability.h" | |
#import "CICTemplateCacheManager.h" | |
#import "CICUDID.h" | |
#import "CICURLChecker.h" | |
#import "CICViewController+ErrorView.h" | |
#import "CICUserService.h" | |
#import "CICWebViewScrollPositionManager.h" | |
#import "CICCommonUI.h" | |
#import "CICNavigationBarResponse.h" | |
#import "CICAppLoggerResponse.h" | |
#import "CICAppHostCookie.h" | |
#import "CICScriptMessageDelegate.h" | |
@interface CICAppHostViewController () <UIScrollViewDelegate, WKNavigationDelegate, WKUIDelegate, CICErrorViewTapRefreshDelegate, WKScriptMessageHandler> | |
@property (nonatomic, strong) NSTimer *timer; | |
// 以下是页面加载的进度条 | |
@property (nonatomic, strong) NSTimer *progressorTimer; | |
@property (nonatomic, strong) NSTimer *clearProgressorTimer; | |
@property (nonatomic, strong) UIProgressView *progressorView; | |
@property (nonatomic, assign) BOOL isProgressorDone; | |
/** | |
wkwebview 加载本地文件 | |
*/ | |
@property (nonatomic, strong) NSString *localJavaScriptFile; | |
// 以下是注册 response 使用的属性 | |
/** | |
可处理 h5 action 的 response类的 NSString 形式。 | |
*/ | |
@property (nonatomic, strong) NSArray<NSString *> *responseClassNames; | |
/** | |
response类的 实例的缓存。 | |
*/ | |
@property (nonatomic, strong) NSMutableDictionary *responseClassObjs; | |
/** | |
提前初始化,需要在 加载的时候使用 | |
*/ | |
@property (nonatomic, strong) CICNavigationBarResponse *navBarResponse; | |
@end | |
static NSString *const kCICRequestProtocal = @"jsbridge://formyApp?param="; | |
static NSString *const kCICRequestItmsApp = @"itms-apps://"; | |
static NSString *const kCICRequestmyAppProtocal = @"myApp://"; | |
static NSString *const kCICScriptHandlerName = @"kCICScriptHandlerName"; | |
// 是否将客户端的 cookie 同步到 WKWebview 的 cookie 当中 | |
// 作为写 cookie 的假地址 | |
static NSString * _Nonnull kFakeCookieWebPageURLString = @"http://your.domain.com/xhr/user/getUid.do?26u-KQa-fKQ-3BD"; | |
@implementation CICAppHostViewController | |
- (void)viewDidAppear:(BOOL)animated | |
{ | |
[super viewDidAppear:animated]; | |
NSString *urlStr = nil; | |
if (self.webview && !self.webview.isLoading) { | |
urlStr = [[self.webview URL] absoluteString]; | |
} | |
if (urlStr.length == 0) { | |
urlStr = self.loadUrl; | |
} | |
[self sendMessageToWebPage:@"pageshow" param:@{ @"url" : urlStr?:@"null" }]; | |
} | |
- (void)viewDidDisappear:(BOOL)animated | |
{ | |
[super viewDidDisappear:animated]; | |
NSString *urlStr = [[self.webview URL] absoluteString]; | |
if (urlStr.length == 0) { | |
urlStr = self.loadUrl; | |
} | |
[self sendMessageToWebPage:@"pagehide" param:@{ @"url" : urlStr?:@"null" }]; | |
// | |
[self.timer invalidate]; | |
self.timer = nil; | |
[self.progressorTimer invalidate]; | |
self.progressorTimer = nil; | |
[self.clearProgressorTimer invalidate]; | |
self.clearProgressorTimer = nil; | |
} | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
if (self.isFullScreenWebview) { | |
self.automaticallyAdjustsScrollViewInsets = NO; | |
self.extendedLayoutIncludesOpaqueBars = YES; | |
} | |
[self initViews]; | |
} | |
- (void)initViews | |
{ | |
self.view.backgroundColor = [UIColor whiteColor]; | |
if (self.webview == nil) { | |
self.webview = [self getWebView]; | |
[self.view addSubview:self.webview]; | |
} | |
// | |
DDLogInfo(@"[JSBridge] load urltext: %@", self.loadUrl); | |
NSURL *actualUrl = [CICURL URLWithString:self.loadUrl]; | |
if (actualUrl == nil) { | |
[self showTextTip:@"请求地址为空,加载失败。" hideAfterDelay:5]; | |
DDLogError(@"[JSBridge] loadUlr 异常 = %@", self.loadUrl); | |
return; | |
} | |
// 添加url加载进度条。 | |
[self addWebviewProgressor]; | |
if ([CICAppHostCookie loginCookieHasBeenSynced] == NO) { | |
// | |
NSURL *cookieURL = [NSURL URLWithString:kFakeCookieWebPageURLString]; | |
NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:cookieURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:120]; | |
WKWebView *cookieWebview = [self getCookieWebview]; | |
[self.view addSubview:cookieWebview]; | |
[cookieWebview loadRequest:mutableRequest]; | |
DDLogInfo(@"[JSBridge] preload cookie for url = %@", self.loadUrl); | |
} else { | |
[self loadWebPage]; | |
} | |
} | |
- (void)addWebviewProgressor | |
{ | |
// 仿微信进度条 | |
self.progressorView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 20.0f)]; | |
// self.progressorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; | |
self.progressorView.trackTintColor = NYQColorFromRGB(0xffffff); | |
[self.view addSubview:self.progressorView]; | |
} | |
- (void)didReceiveMemoryWarning | |
{ | |
[super didReceiveMemoryWarning]; | |
// Dispose of any resources that can be recreated. | |
[[CICWebViewScrollPositionManager sharedInstance] clearAllCache]; | |
} | |
- (void)dealloc | |
{ | |
[self.webview.configuration.userContentController removeScriptMessageHandlerForName:kCICScriptHandlerName]; | |
self.webview.navigationDelegate = nil; | |
self.webview.scrollView.delegate = nil; | |
[self.webview stopLoading]; | |
[self.webview removeFromSuperview]; | |
self.webview = nil; | |
// 清理 response | |
[self.responseClassObjs enumerateKeysAndObjectsUsingBlock:^(NSString *key, id _Nonnull obj, BOOL * _Nonnull stop) { | |
obj = nil; | |
}]; | |
[self.responseClassObjs removeAllObjects]; | |
self.responseClassObjs = nil; | |
} | |
#pragma mark - public | |
- (void)setLocalFilePath:(NSString *)fileName javaScriptFileName:(NSString *)jsFileName | |
{ | |
self.loadUrl = fileName; | |
NSString *jsPath = [self.loadUrl stringByDeletingLastPathComponent]; | |
self.localJavaScriptFile = [jsPath stringByAppendingPathComponent:jsFileName]; | |
} | |
#pragma mark - UI相关 | |
- (void)loadWebPage | |
{ | |
NSURL *url = [CICURL URLWithString:self.loadUrl]; | |
if (url == nil) { | |
DDLogError(@"loadUrl is nil,loadUrl = %@", self.loadUrl); | |
[self showTextTip:@"加载网页地址错误"]; | |
return; | |
} | |
//检查网络是否联网; | |
DDLogDebug(@"[JSBridge] reachability check started"); | |
long startTime = [[[NSDate alloc] init] timeIntervalSince1970] * 1000; | |
Reachability *reachability = [Reachability reachabilityForInternetConnection]; | |
if ([reachability isReachable]) { | |
long endTime = [[[NSDate alloc] init] timeIntervalSince1970] * 1000; | |
DDLogDebug(@"[JSBridge] reachability check cosumed: %ld", endTime - startTime); | |
// | |
if ([CICURL isHttpOrHttpsUrl:url]) { | |
NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:120]; | |
[self.webview loadRequest:mutableRequest]; | |
} else { // 本地资源 | |
[self renderWebViewWithLocalFile:url]; | |
} | |
// 需要全屏但未设置,设置下 | |
if (self.isFullScreenWebview && self.isTransparentTopBar) { | |
[self.navigationController setNavigationBarHidden:YES animated:NO]; | |
} | |
[self toggleErrorView:NO title:nil subTitle:nil]; | |
} else { | |
[self toggleErrorView:YES title:nil subTitle:nil]; | |
} | |
} | |
/** | |
强制显示 加载失败页面 | |
@param show 是否显示 | |
@param title 第一行大字文案,可以为nil,默认显示加载失败 | |
@param subTitle 第二行文字,可以为nil,默认显示 点击屏幕,重新加载 | |
*/ | |
- (void)toggleErrorView:(BOOL)show title:(NSString *)title subTitle:(NSString *)subTitle | |
{ | |
if (show) { | |
if (self.errorView == nil) { | |
self.errorView = [self getErrorView:CICErrorViewOffline]; | |
[self.view addSubview:self.errorView]; | |
self.errorViewTapRefreshDelegate = self; | |
} | |
self.errorView.hidden = NO; | |
self.webview.hidden = YES; | |
if (!title) { | |
title = @"加载失败"; | |
} | |
if (!subTitle) { | |
subTitle = @"点击屏幕, 重新加载"; | |
} | |
[self configureErrorGuidTitle:title subTitle:subTitle]; | |
} else { | |
self.errorView.hidden = YES; | |
self.webview.hidden = NO; | |
} | |
} | |
- (void)renderWebViewWithLocalFile:(NSURL *)url | |
{ | |
NSError *err = nil; | |
NSString *appHtml = [NSString stringWithContentsOfFile:[url absoluteString] encoding:NSUTF8StringEncoding error:&err]; | |
if (err) { | |
DDLogError(@"[JSBridge] renderWebViewWithLocalFile failed.err = %@, url = %@", err, url); | |
} else { | |
NSString *baseUrlString = [url absoluteString]; | |
baseUrlString = [baseUrlString stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"/%@", baseUrlString.lastPathComponent] withString:@""]; | |
NSURL *baseUrl = [NSURL fileURLWithPath:baseUrlString isDirectory:YES]; | |
[self.webview loadHTMLString:appHtml baseURL:baseUrl]; | |
} | |
} | |
#pragma makr - errorView Tap | |
- (void)didTapErrorViewRefresh | |
{ | |
[self showLoading:@""]; | |
// | |
self.errorView.hidden = YES; | |
[self loadWebPage]; | |
// | |
[self hideHUD]; | |
} | |
#pragma mark - core | |
- (void)dispatchParsingParameterContent:(NSDictionary *)contentJSON | |
{ // 解析是否包含了日志 | |
NSMutableDictionary *paramDict = [[contentJSON objectForKey:@"param"] mutableCopy]; | |
id native_logs = [paramDict objectForKey:@"native_logs"]; | |
if (native_logs && [native_logs isKindOfClass: NSDictionary.class]){// 如果包含了logs的数组 | |
// 去掉日志数据,防止干扰 | |
[paramDict removeObjectForKey:@"native_logs"]; | |
// 检查是否需要发送log | |
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ | |
NSString *key = @"CICAppLoggerResponse"; | |
CICAppLoggerResponse *loggerResp = [self.responseClassObjs objectForKey:key]; | |
if (loggerResp == nil) { | |
Class responseClass = NSClassFromString(key); | |
loggerResp = [[responseClass alloc] initWithAppHost:self]; | |
// 缓存住 | |
[self.responseClassObjs setObject:loggerResp forKey:key]; | |
[loggerResp sendLogOfDiscoveryToBI:native_logs]; | |
} | |
}); | |
} | |
// 增加对异常参数的catch | |
@try { | |
[self dispatchRequest:[contentJSON objectForKey:@"action"] parameter:paramDict]; | |
} @catch (NSException *exception) { | |
[self showTextTip:@"H5接口异常"]; | |
DDLogError(@"[JSBridge] h5接口解析异常,接口数据:%@", contentJSON); | |
} @finally { | |
} | |
} | |
// 延迟初始化; 短路判断 | |
- (void)dispatchRequest:(NSString *)action parameter:(NSDictionary *)paramDict | |
{ | |
BOOL catched = NO; | |
// 先过内置的 action handler | |
if ([@"showErrorView" isEqualToString:action]) { | |
[self toggleErrorView:YES title:[paramDict objectForKey:@"title"] subTitle:[paramDict objectForKey:@"subTitle"]]; | |
catched = YES; | |
} else { | |
// 进入第三方的response | |
for (NSInteger i = 0; i < self.responseClassNames.count; i++) { | |
NSString *key = [self.responseClassNames objectAtIndex:i]; | |
Class responseClass = NSClassFromString(key); | |
if ([responseClass isSupportedAction:action]) { | |
// 先判断是否可以响应,再决定初始化。 | |
id<CICAppHostProtocol> vc = [self.responseClassObjs objectForKey:key]; | |
if (vc == nil) { | |
vc = [[responseClass alloc] initWithAppHost:self]; | |
// 缓存住 | |
[self.responseClassObjs setObject:vc forKey:key]; | |
} | |
[vc handleAction:action withParam:paramDict]; | |
catched = YES; | |
break; | |
} | |
} | |
} | |
// | |
if (catched == NO) { | |
DDLogError(@"[JSBridge] action (%@) not supported yet.", action); | |
} | |
} | |
#pragma mark - wkwebview uidelegate | |
- (WKWebView *)webView:(WKWebView *)webView | |
createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration | |
forNavigationAction:(WKNavigationAction *)navigationAction | |
windowFeatures:(WKWindowFeatures *)windowFeatures | |
{ | |
if (!navigationAction.targetFrame.isMainFrame) { | |
[webView loadRequest:navigationAction.request]; | |
} | |
NSLog(@"%@", NSStringFromSelector(_cmd)); | |
return nil; | |
} | |
#pragma mark - wkwebview navigation delegate | |
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler | |
{ | |
DDLogDebug(@"%@", NSStringFromSelector(_cmd)); | |
NSURLRequest *request = navigationAction.request; | |
//此url解析规则自己定义 | |
NSString *rurl = [[request URL] absoluteString]; | |
[self logRequestAndResponse:rurl type:@"request"]; | |
WKNavigationActionPolicy policy = WKNavigationActionPolicyAllow; | |
if ([self isValidmyAppRequest:rurl]) { //使用myApp协议打开 | |
[CICNavHelper openURL:[CICURL URLWithString:rurl]]; | |
policy = WKNavigationActionPolicyCancel; | |
} else if ([self isValidRequest:rurl]) { | |
NSURL *actualUrl = [CICURL URLWithString:self.loadUrl]; | |
if (![[CICURLChecker sharedManager] checkURL:actualUrl forAuthorizationType:CICAuthorizationTypeAppHost]) { | |
DDLogError(@"invalid url visited : %@", self.loadUrl); | |
} else { | |
NSString *param = [rurl stringByReplacingOccurrencesOfString:kCICRequestProtocal withString:@""]; | |
NSDictionary *contentJSON = nil; | |
NSError *contentParseError; | |
if (param) { | |
param = [NSString stringDecodeURIComponent:param]; | |
contentJSON = [NSJSONSerialization JSONObjectWithData:[param dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&contentParseError]; | |
} | |
[self dispatchParsingParameterContent:contentJSON]; | |
} | |
// DDLogInfo(@"web view called > %@", param); | |
policy = WKNavigationActionPolicyCancel; | |
} else if ([self isItmsAppsRequest:rurl]) { //遇到 itms-apps://itunes.apple.com/cn/app/id992055304 主动 pop出去 | |
// URL Scheme and App Store links won't work https://github.com/ShingoFukuyama/WKWebViewTips#url-scheme-and-app-store-links-wont-work | |
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(popOutImmediately) userInfo:nil repeats:NO]; | |
[[UIApplication sharedApplication] openURL:[request URL]]; | |
policy = WKNavigationActionPolicyCancel; | |
} | |
// | |
decisionHandler(policy); | |
} | |
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation | |
{ | |
DDLogDebug(@"[JSBridge] didReceiveServerRedirectForProvisionalNavigation = %@", navigation); | |
} | |
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(nonnull WKNavigationResponse *)navigationResponse decisionHandler:(nonnull void (^)(WKNavigationResponsePolicy))decisionHandler | |
{ | |
NSURLResponse *resp = navigationResponse.response; | |
NSURL *url = [resp URL]; | |
DDLogDebug(@"[JSBridge] navigationResponse.url = %@", url); | |
decisionHandler(WKNavigationResponsePolicyAllow); | |
} | |
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation | |
{ | |
DDLogDebug(@"[JSBridge] didCommitNavigation = %@", navigation); | |
} | |
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation | |
{ | |
if (self.disabledProgressor) { | |
self.progressorView.hidden = YES; | |
} else { | |
// 清理旧的timer | |
[self.progressorTimer invalidate]; | |
self.progressorView.progress = 0; | |
self.isProgressorDone = NO; | |
self.progressorView.hidden = NO; | |
// 0.01667 is roughly 1/60, so it will update at 60 FPS | |
self.progressorTimer = [NSTimer scheduledTimerWithTimeInterval:0.01667 target:self selector:@selector(fakeProgressor) userInfo:nil repeats:YES]; | |
} | |
DDLogDebug(@"%@", NSStringFromSelector(_cmd)); | |
} | |
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation | |
{ | |
if (webView.isLoading) { | |
return; | |
} | |
NSURL *targetURL = webView.URL; | |
if ([CICAppHostCookie loginCookieHasBeenSynced] == NO && targetURL.query.length > 0 && [kFakeCookieWebPageURLString containsString:targetURL.query]) { | |
[CICAppHostCookie setLoginCookieHasBeenSynced:YES]; | |
// 加载真正的页面;此时已经有 App 的 cookie 存在了。 | |
[webView removeFromSuperview]; | |
[self loadWebPage]; | |
return; | |
} | |
//如果是全新加载页面,而不是从历史里弹出的情况下,需要渲染导航 | |
if (![self.webview canGoForward]) { | |
[self.navBarResponse initNavigationBarButtons]; | |
} | |
// | |
[self.navBarResponse initNavigationBarTitle]; | |
[self insertData:@{ @"ios" : @YES } intoPageWithVarName:@"platform"]; | |
//设置发现的后台接口; | |
NSDictionary *inserted = [self supportListByNow]; | |
[inserted enumerateKeysAndObjectsUsingBlock:^(NSString *keyStr, id obj, BOOL *stop) { | |
[self insertData:obj intoPageWithVarName:keyStr]; | |
}]; | |
[self sendMessageToWebPage:@"onready" param:@{}]; | |
self.isProgressorDone = YES; | |
// 防止内存飙升 | |
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"]; | |
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"]; | |
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"]; | |
[[NSUserDefaults standardUserDefaults] synchronize]; | |
// | |
[self dealWithViewHistory]; | |
DDLogDebug(@"%@", NSStringFromSelector(_cmd)); | |
} | |
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message | |
{ | |
if ([message.name isEqualToString:kCICScriptHandlerName]) { | |
// | |
DDLogDebug(@"%@",message.body); | |
NSDictionary *contentJSON = message.body; | |
[self dispatchParsingParameterContent:contentJSON]; | |
} else { | |
#if CIC_TEST == 1 | |
[self showTextTip:@"没有实现的接口"]; | |
#endif | |
DDLogError(@"[JSBridge] unknown methods : %@", message.name); | |
} | |
} | |
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error | |
{ | |
self.isProgressorDone = YES; | |
DDLogDebug(@"%@", NSStringFromSelector(_cmd)); | |
} | |
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error | |
{ | |
self.isProgressorDone = YES; | |
DDLogDebug(@"%@", NSStringFromSelector(_cmd)); | |
[self showTextTip:@"加载页面内容时出错"]; | |
DDLogInfo(@"[JSBridge] load page error = %@", error); | |
} | |
- (void)popOutImmediately | |
{ | |
if (self.fromPresented) { | |
[self dismissViewControllerAnimated:NO completion:nil]; | |
} else { | |
[self.navigationController popViewControllerAnimated:NO]; | |
} | |
} | |
- (void)fakeProgressor | |
{ | |
// DDLogDebug(@"[JSBridge] progress = %f", self.webview.estimatedProgress); | |
if (self.isProgressorDone) { | |
[self.progressorView setProgress:1 animated:YES]; | |
[self.progressorTimer invalidate]; | |
// 完成之后clear进度 | |
self.clearProgressorTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(clearProgressor) userInfo:nil repeats:NO]; | |
} else { | |
self.progressorView.progress = self.webview.estimatedProgress; | |
} | |
} | |
- (void)clearProgressor | |
{ | |
self.progressorView.hidden = YES; | |
[self.clearProgressorTimer invalidate]; | |
} | |
#pragma mark - supportType | |
- (void)executeJavaScriptString:(NSString *)javaScriptString | |
{ | |
[self.webview evaluateJavaScript:javaScriptString completionHandler:nil]; | |
} | |
#pragma mark - innner | |
- (BOOL)isValidRequest:(NSString *)url | |
{ | |
return [url hasPrefix:kCICRequestProtocal]; | |
} | |
- (BOOL)isItmsAppsRequest:(NSString *)url | |
{ | |
// itms-appss://itunes.apple.com/cn/app/id992055304 | |
// https://itunes.apple.com/cn/app/id992055304 | |
NSArray<NSString *> *prefixs = @[ kCICRequestItmsApp, @"itms-appss://", @"itms-services://", @"itmss://" ]; | |
BOOL __block pass = NO; | |
[prefixs enumerateObjectsUsingBlock:^(NSString *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { | |
if ([url hasPrefix:obj]) { | |
pass = YES; | |
*stop = YES; | |
} | |
}]; | |
return pass; | |
} | |
- (BOOL)isValidmyAppRequest:(NSString *)url | |
{ | |
return [url hasPrefix:kCICRequestmyAppProtocal]; | |
} | |
- (void)callbackFunctionOnWebPage:(NSString *)actionName param:(NSDictionary *)paramDict | |
{ | |
[self __sendMessageToWebPage:actionName funcName:@"__callback" param:paramDict]; | |
} | |
- (void)sendMessageToWebPage:(NSString *)actionName param:(NSDictionary *)paramDict | |
{ | |
[self __sendMessageToWebPage:actionName funcName:@"__fire" param:paramDict]; | |
} | |
- (void)__sendMessageToWebPage:(NSString *)actionName funcName:(NSString *)funcName param:(NSDictionary *)paramDict | |
{ | |
NSData *objectOfJSON = nil; | |
NSError *contentParseError; | |
objectOfJSON = [NSJSONSerialization dataWithJSONObject:paramDict options:NSJSONWritingPrettyPrinted error:&contentParseError]; | |
NSString *jsCode = [NSString stringWithFormat:@"window.appHost.%@('%@',%@);", funcName, actionName, [[NSString alloc] initWithData:objectOfJSON encoding:NSUTF8StringEncoding]]; | |
[self logRequestAndResponse:jsCode type:@"response"]; | |
jsCode = [jsCode stringByReplacingOccurrencesOfString:@"\n" withString:@""]; | |
[self executeJavaScriptString:jsCode]; | |
// DDLogInfo(@"invoke js: %@", jsCode); | |
} | |
- (void)logRequestAndResponse:(NSString *)str type:(NSString *)type | |
{ | |
NSUInteger toIndex = MIN(500, str.length); | |
DDLogDebug(@"[JSBridge] debug type: %@ , url : %@", type, [str substringToIndex:toIndex]); | |
} | |
#pragma mark - getter | |
- (CICNavigationBarResponse *)navBarResponse | |
{ | |
if (_navBarResponse == nil) { | |
// 先检测是否存在于缓存里 | |
_navBarResponse = [self.responseClassObjs objectForKey:@"CICNavigationBarResponse"]; | |
// 预初始化 | |
if (_navBarResponse == nil) { | |
_navBarResponse = [[CICNavigationBarResponse alloc] initWithAppHost:self]; | |
[self.responseClassObjs setObject:_navBarResponse forKey:@"CICNavigationBarResponse"]; | |
} | |
} | |
return _navBarResponse; | |
} | |
- (WKWebView *)getCookieWebview | |
{ | |
// 设置加载页面完毕后,里面的后续请求,如 xhr 请求使用的cookie | |
WKUserContentController *userContentController = [WKUserContentController new]; | |
WKWebViewConfiguration *webViewConfig = [[WKWebViewConfiguration alloc] init]; | |
webViewConfig.userContentController = userContentController; | |
webViewConfig.processPool = [CICAppHostCookie sharedPoolManager]; | |
NSMutableArray<NSString *> *oldCookies = [CICAppHostCookie cookieJavaScriptArray]; | |
[oldCookies enumerateObjectsUsingBlock:^(NSString *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { | |
NSString *setCookie = [NSString stringWithFormat:@"document.cookie='%@';", obj]; | |
WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:setCookie injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; | |
[userContentController addUserScript:cookieScript]; | |
}]; | |
#if CIC_TEST == 1 | |
DDLogInfo(@"[JSBridge] getWebView. oldCookies = %@", oldCookies); | |
#endif | |
WKWebView *webview = [[WKWebView alloc] initWithFrame:CGRectMake(0, -1, SCREEN_WIDTH,ONE_PIXEL) configuration:webViewConfig]; | |
webview.navigationDelegate = self; | |
webview.UIDelegate = self; | |
return webview; | |
} | |
- (WKWebView *)getWebView | |
{ | |
// 设置加载页面完毕后,里面的后续请求,如 xhr 请求使用的cookie | |
WKUserContentController *userContentController = [WKUserContentController new]; | |
__weak typeof(self) weakSelf = self; | |
[userContentController addScriptMessageHandler:[[CICScriptMessageDelegate alloc] initWithDelegate:weakSelf] name:kCICScriptHandlerName]; | |
WKWebViewConfiguration *webViewConfig = [[WKWebViewConfiguration alloc] init]; | |
webViewConfig.userContentController = userContentController; | |
webViewConfig.allowsInlineMediaPlayback = YES; | |
webViewConfig.processPool = [CICAppHostCookie sharedPoolManager]; | |
if (self.localJavaScriptFile.length > 0) { | |
NSError *err = nil; | |
NSString *jScript = [NSString stringWithContentsOfFile:self.localJavaScriptFile encoding:NSUTF8StringEncoding error:&err]; | |
if (err == nil) { | |
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; | |
[userContentController addUserScript:wkUScript]; | |
} else { | |
DDLogDebug(@"[JSBridge] Load local javaScript file failed. erro = %@", err); | |
} | |
} | |
WKWebView *webview = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - (self.isTransparentTopBar ? 0 : NAVIGATION_BAR_HEIGHT)) configuration:webViewConfig]; | |
webview.scrollView.contentSize = CGSizeMake(CGRectGetWidth(webview.frame), CGRectGetHeight(webview.frame)); | |
webview.navigationDelegate = self; | |
webview.UIDelegate = self; | |
webview.scrollView.delegate = self; | |
return webview; | |
} | |
#pragma mark - vc settings | |
/** | |
* 导航栏是否显示。这里透明导航栏是使用自定义的导航实现。 | |
* 所以接口需要透明导航的时候,其实是不显示导航,显示自定义导航。 | |
* | |
* @return | |
*/ | |
- (BOOL)shouldShowNavigationBar | |
{ | |
Reachability *reachability = [Reachability reachabilityForInternetConnection]; | |
if (![reachability isReachable]) { | |
return YES; | |
} | |
return !self.isTransparentTopBar; | |
} | |
- (BOOL)shouldHidesBottomBarWhenPushed | |
{ | |
return !self.showBottomBar; | |
} | |
- (UIStatusBarStyle)preferredStatusBarStyle | |
{ | |
return self.navBarStyle; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment