项目中 Hybrid 部分的设计

交互方式选择, 通用 API, 基础&全面 API, cookie, scheme, itunes 白名单

Posted by poos on December 11, 2018

容器

是使用WKWebView还是UIWebView

使用 WKWebview,虽然他有诸多的坑,但是带来的优化是很多的:

iOS WKWebView与UIWebView的比较替换

WKWebView 那些坑

虽然传说 WK 有很多坑,我碰到的都算是可以接受的。并且是可以通用的解决的,所以我们的项目中完全使用的是 WKWebview。

原生与 H5 交互的方式

有两篇 味精 的博客介绍的非常清楚了

从零收拾一个hybrid框架(一)– 从选择JS通信方案开始

从零收拾一个hybrid框架(二)– WebView容器基础功能设计思路

选择JS通信方案

介绍各种通讯方式,最后作者提出建议的通讯方式为

1
2
3
4
5
6
7
8
9
聊了这么多这个方式,如果换做我们项目,我会选择啥?

iOS:MessageHandler注入/Prompt弹框拦截(JSToNative) + evaluatingJavaScript
(NativeToJS)
经过修正,异步返回采用MessageHandler 同步返回采用Prompt弹框拦截(JSToNative)


安卓: 拦截弹窗(JSToNative)+loadUrl(NativeToJS)

注意 js 注入 要在页面销毁时候 移除,否则会造成内存泄露。

一些不同

实际项目中,我们在 jump 页面这里通用了推送的 scheme 判断方式,并且保底提示更新至最新版。

容器基础功能设计思路

第二篇介绍了很多部分的设计

  • 调用和回调模块

  • 业务扩展模块

  • UserAgent

  • Cookie

  • JS 脚本注入

  • 常规扩展,比较多列举一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Common 组件:我们的示例代码就是 Common 组件的一些基础操作
  复制剪切板
  获取设备信息
  打客户端Log,上报日志
  打客户端Crash追踪Log,随Crash上报
  ……打开你的想象力

CommonUI 组件:也有一些 Common 并且与 UI 相关的基础操作
  showTips 展示客户端文字浮层
  showDialog 展示客户端确认弹框,回调用户选择按钮
  pullRefresh 采用客户端的下拉刷新,但配合 H5 进行数据加载
  Router 跳转任意 App 内路由页面
  NaviBarControl 可以让前端来定制客户端顶部 NaviBar
  share Button 增加原生分享按钮,点击后出发原生分享
  Other Button 增加任意原生按钮,点击后跳转任意 App 内路由页面
  ……打开你的想象力

NetWork 组件:判断浏览器调试环境下走 AJAX 网络请求,判断是客户端就通过客户端发起原生网络请求,请求结果回调 JS (为什么做?一般原生会封装网络请求,有更精细粒度的cache控制 ,和通用无痕日志埋点)
  Get 不解释了
  Post 不解释了
  ……打开你的想象力

Storage 组件:前端的存储只能使用 LocalStorage 和 Cookie 这二者都有很大的缺陷
  Key - Value Plist Storage : 可以让前端把 Key Value 发给客户端,让客户端通过本地Plist 存储/读取/删除
  File Storage:可以让前端把大段需要存储的字符串,发给客户端,让客户端在App沙盒内开辟文件路径,saveToFile存储成文件,并且提供目录操作能力,创建目录/删除目录/创建文件/删除文件/读取文件
  ……打开你的想象力

Push组件:可以让前端有能力写本地Push闹铃到App 或者上报远程Push Token
  本地 Push 设置
  远程 Push 获取 Token

基本上是比较全面了,想象力灰常大。

项目实践

项目实践时候才会看出真实需要的内容。

跳转的 scheme

我们使用了的 scheme 模式,类似推送消息的跳转。然后在保底时候提示软件需要更新。

1
2
xx/jump/

理由:

  1. 方便
  2. 页面跳转本来就是一个单向的过程,且项目中一般都会有跳转路由类,对接即可

非单向的跳转,或者动作

使用上边的 同步/异步 交互方式,根据需要选择

添加通用的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 刷新
// 虽然有 系统方法,但是wk 时候不好用
func reload()

// 更新
// 有些没有用户交互,但是需要版本更新,就可以使用这个
func update()

// Title
// 从 html title 取还是fangfshez设置

// Pop
// 退出页面

// 登录和成功传入用户信息

// 仅允许白名单的 itunes 跳转

// 仅允许白名单的网址添加 cookie

总结

总结几个要点

  • Hybrid 模块设计通常需要的是通用的解决方案,否则就会导致灵活性大大降低,版本依赖太强。

  • 要有预见性,在早版本提前埋好相关的功能。

  • 要使用交互的方式来提高用户体验,不要产生点击没反应的情况。