实现WKScriptMessageHandler,约定交互Handler
Apple要求新发布的app不能使用UIWebView。交互只总结WKWebView。
首先要约定 ScriptMessageHandler
的name,例如:lvJSCallNativeHandler
,具体细节不用说了,
主要回调逻辑实现在
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
复制代码
用Safari浏览器的Develop功能可以调试app内置的H5页面。在console里输入
window.webkit.messageHandlers.lvJSCallNativeHandler
,可以打出原生添加的Handler对象。
约定UserAgent
设置customUserAgent
来让H5可以区分运行环境,是否在App内,版本是多少,设备型号等。
在需要适配的时候有得用就行了。
标题和加载进度监测
- 由于WKWebview的
estimatedProgress
属性是支持KVO的,方便progressView显示加载进度。为了体验更好一点一般会有一个默认值,比如0.15,给用户一个加载快的假象。 title
属性也是支持KVO的,可以同步修改原生导航条的标题
约定App生命周期里的各个时机的通知方法
例如UIViewController的viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.webView evaluateJavaScript:@"window.viewWillAppear && viewWillAppear();" completionHandler:nil];
}
复制代码
原生事件 | 调js方法,通知H5 |
---|---|
viewWillAppear | viewWillAppear() |
viewWillDisappear | viewWillDisappear() |
UIApplicationWillEnterForegroundNotification | willEnterForeground() |
原生返回按钮 | lvNativeBackCheck() |
原生登录成功 | loginOnsuccess() |
原生登录失败 | loginOnfail() |
登录状态打通
原生的登录状态应该在H5里能获得才行。
比如约定H5通过Cookie里的lvsessionid来判断登录状态,那就把lvsessionid
写入Cookie
,
注意域名的写法
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:
@{NSHTTPCookieDomain: @".example.com",
NSHTTPCookiePath: @"/",
NSHTTPCookieName: @"lvsessionid",
NSHTTPCookieValue: lvsessionid}];
WKHTTPCookieStore *cookieStore = self.webView.configuration.websiteDataStore.httpCookieStore;
[cookieStore setCookie:cookie completionHandler:nil];
复制代码
常用约定方法,参数都是字典,返回值也都是字典
- 显示Loading lvJSShowLoading; 隐藏Loading lvJSHideLoading
- 获取位置 lvJSGetLocation
- 打开相机扫描二维码 lvJSOpenQRCodeScan
- 打开通讯录 lvJSOpenContacts 没有权限返回错误
- 读取NSUserDefault存储信息 lvJSGetUserDefaultWithKey; 设置本地存储信息 lvJSSetUserDefaultWithKey
- 页面跳转 lvJSGoClass, 根据参数className类反射来判断跳哪个页面
- 浏览历史 lvJSSaveHistory
- 获取屏幕尺寸和状态栏高度 lvJSGetScreenSize
- 跳转到iOS系统APP设置页 lvJSGoAppSettingPage
- 隐藏导航条 lvJSHideNativeNavigationBar;显示导航条 lvJSShowNativeNavigationBar
- 设置webView是否可以回弹 lvJSSetWebViewBounces
- 复制文本到剪切板 lvJSCopyToPasteboard
其他特殊约定
- App拦截特定规则的URL到原生页面的例外约定。
比如:门票详情的URL,piao后是产品id。
https://m.example.com/ticket/piao-983253
复制代码
但是一些id是不能拦截的。这就需要约定例外规则,参数requireh5=1
https://m.example.com/ticket/piao-983253?requireh5=1
复制代码
App在拦截时判断包含requireh5=1,就不会拦截。直接用WebView打开
- WebView是否多开(点击链接时在新的Controller里打开,而不是在当前controller里刷新)
WebView多开让HybirdApp变得更像原生的。约定参数newtab=1
注意原生实现多开时要用copy和传递request(不要传递url,会丢失部分请求信息)同时也可以约定多开的展示方式,push还是present等