Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web View 与 Hybrid #32

Open
ShannonChenCHN opened this issue Apr 27, 2017 · 8 comments
Open

Web View 与 Hybrid #32

ShannonChenCHN opened this issue Apr 27, 2017 · 8 comments

Comments

@ShannonChenCHN
Copy link
Owner

ShannonChenCHN commented Apr 27, 2017

  • UIWebView

  • WKWebView

  • Web view 与 JavaScript 的交互处理

    • WebViewJavaScriptBridge
    • 通过在 - webView: shouldStartLoadWithRequest: navigationType: 方法中进行拦截 url 再进行处理
    • 借助 JavaScriptCore 框架
  • UIWebView 中如何加载 webp 图片

    • 借助 NSURLProtocol 拦截 web view 中的图片下载请求
    • 借助 google 的 webp 解码库进行解码
    • 缓存图片以提高 web view 性能
  • cookie 同步问题

  • Web View 生成快照

  • JavaScriptCore

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented May 16, 2017

UIWebView 介绍和使用

1.API

属性:

@property (nullable, nonatomic, assign) id <UIWebViewDelegate> delegate;

@property (nonatomic, readonly, strong) UIScrollView *scrollView NS_AVAILABLE_IOS(5_0);
@property (nullable, nonatomic, readonly, strong) NSURLRequest *request;

@property (nonatomic, readonly, getter=canGoBack) BOOL canGoBack;
@property (nonatomic, readonly, getter=canGoForward) BOOL canGoForward;
@property (nonatomic, readonly, getter=isLoading) BOOL loading;

@property (nonatomic) BOOL scalesPageToFit;

@property (nonatomic) BOOL detectsPhoneNumbers NS_DEPRECATED_IOS(2_0, 3_0);
@property (nonatomic) UIDataDetectorTypes dataDetectorTypes NS_AVAILABLE_IOS(3_0);

@property (nonatomic) BOOL allowsInlineMediaPlayback NS_AVAILABLE_IOS(4_0); 
@property (nonatomic) BOOL mediaPlaybackRequiresUserAction NS_AVAILABLE_IOS(4_0); 

@property (nonatomic) BOOL mediaPlaybackAllowsAirPlay NS_AVAILABLE_IOS(5_0); 

@property (nonatomic) BOOL suppressesIncrementalRendering NS_AVAILABLE_IOS(6_0);

@property (nonatomic) BOOL keyboardDisplayRequiresUserAction NS_AVAILABLE_IOS(6_0); 

@property (nonatomic) UIWebPaginationMode paginationMode NS_AVAILABLE_IOS(7_0);
@property (nonatomic) UIWebPaginationBreakingMode paginationBreakingMode NS_AVAILABLE_IOS(7_0);
@property (nonatomic) CGFloat pageLength NS_AVAILABLE_IOS(7_0);
@property (nonatomic) CGFloat gapBetweenPages NS_AVAILABLE_IOS(7_0);
@property (nonatomic, readonly) NSUInteger pageCount NS_AVAILABLE_IOS(7_0);

@property (nonatomic) BOOL allowsPictureInPictureMediaPlayback NS_AVAILABLE_IOS(9_0);
@property (nonatomic) BOOL allowsLinkPreview 

方法:

- (void)loadRequest:(NSURLRequest *)request;
- (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL;


- (void)reload;
- (void)stopLoading;

- (void)goBack;
- (void)goForward;

- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;


2. webViewDidFinishLoad 方法的一些问题

2.1 webViewDidFinishLoad 什么时候被调用

2.2 为什么会出现 loadRequest 一次,webViewDidFinishLoad 却被多次调用的情况?

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented May 16, 2017

WKWebView 的介绍和使用

1.背景介绍

  • WebKit 和 Nitro 引擎
  • URL Loading System

2.API 和基本使用,与 UIWebView 的对比

3.与 JavaScript 的交互处理

4. Web 技术相关

4.1 Cookie 管理

  • 使用 WKWebView 时,如何同步 cookie?

  • 登录/登出时,如何同步 cookie 信息到 WKWebView?

    • 原生登录成功后,需要通过执行 JS 脚本手动将 cookie 同步到 WKWebView 中
    • 在原生退出登录时,因为 WKWebView 在 iOS 9 之前,即使刷新页面或者重新 loadRequest,都不能自动清掉 cookie,所以只能销毁掉当前的 webView,再重新新建一个新的 webView
  • 几个问题:

    • 为什么第一个 request 的 cookie 太大会导致 400 ?WKWebView 是如何发起请求的?
    • request header 中的 cookie 格式应该是什么样的?跟 response header 中的 cookie 有什么区别?

4.2 UserAgent

4.3 Local Storage

5.系统缓存

  • WKWebView 在加载时会缓存数据吗?缓存哪些了数据呢?
  • 如何清除系统缓存

6.与 UIWebView 的性能比较

7.缺陷

8.兼容 iOS7 的封装,以及 WKWebView/UIWebView 相关开源代码

  • 针对 UIWebView 中的 mediaPlaybackRequiresUserActionallowsInlineMediaPlaybackscalesPageToFit 属性的兼容性处理

8.实践

  • Hybrid 框架
  • 优雅地使用 WebViewJavaScriptBridge
  • 调试
  • 在 UIWebView 中加载 WebP 图片(NSURLProtocol)

9.性能调优

  • 缓存
  • 预加载
  • 刷新

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Jun 9, 2017

常见问题

1.如何调试 UIWebView 和 WKWebView

1.1 Safari

1.2 查看 h5 中的请求

1.3 调试工具

@ShannonChenCHN ShannonChenCHN changed the title 【专题】Web View 与 JavaScript 【专题】Web View 与 Hybrid Jun 25, 2017
@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Jun 26, 2017

豆瓣的混合开发框架 -- Rexxar

1.混合开发

  • 混合开发:在原生应用中,基于 web 技术,使用 WebView 来实现展示和功能。
  • Web 技术的优势:
    • 高效率的界面开发
    • 跨平台
    • 热更新
  • Web 技术具有这些优势的原因: Web 技术是一个开放标准。

2.Rexxar 的背景

  • 为什么推行混合开发:不影响 App 的性能前提下,在合适的地方使用 Web 技术部分地提高开发效率。
  • 适合使用 Web 技术来实现:重度展示,轻度交互
  • 为什么开源 Rexxar:一方面,是为了给大家提供一些借鉴的方向;另一方面,是为了提高项目本身的质量。

3.Rexxar 的介绍

  • Rexxar 主要由以下三部分组成:

    • Rexxar Route:我们使用 URL 来标识每一个页面。在 App 中通过指明 URL 跳转到此页面。所以,需要一个路由表。通过路由表可以根据 URL 找到一个 Rexxar Web 的对应资源来正确展示相应页面;
    • Rexxar Web:前端代码库,由 HTML、CSS、JavaScript、Image 等组成,用来提供在移动客户端使用的用户页面;其主要包括三部分内容:
      • 工具
      • 公共的前端组件
      • 对 Rexxar Container 实现的 原生功能 的调用
    • Rexxar Container:一个前端代码的运行容器。它其实是一个内嵌的浏览器(WebView),我们为内嵌浏览器提供了一些必要的原生端支持,包括 API 的 OAuth 授权、图片缓存、Native UI 组件的调用等。
      • 页面与页面之间的逻辑:为了保证使用体验,我们把 App 里页面切换留给了 Native。每个页面都是一个 Container。
      • 页面内的逻辑:
        • Rexxar Route 路由表的更新,已经在客户端的保存;
        • 为 Rexxar Web 前端代码发出的 API 请求提供包装。带上必要的 OAuth 参数;
        • 缓存 Rexxar Web 前端代码所需要的静态文件,包括 HTML、CSS、JavaScript、Image(图片素材)等;
        • 缓存 Rexxar Web 中所需要加载的资源文件,例如图片等;
        • 通过协议为 Rexxar Web 提供一些原生支持的功能:包括 Native UI 组件调用,获取 Native 的计算结果。
  • Rexxar Container 和 Rexxar Web 之间的交互

    • 实现方案:Native 和 Web 之间协议是由 URL 定义的。Rexxar Web 访问某个特定的 URL, Rexxar Container 截获这些 URL 请求,调用 Native 代码完成相应的功能。
    • 前端实现:在 DOM 中加入一个 iframe 来加载此 URL,以来完成对 Rexxar Container 的通知。
    • 为什么选择这种方案:我们希望 Native 和 Web 之间的通信是可定义的,可控的。有这种期望的原因是,我们以 Rexxar 完成的页面,前端业务代码无需太多改动,即可迁移到移动 Web 和桌面 Web 端。
  • Rexxar Container 的技术实现

    • Rexxar Container 主要的工作是截获 Rexxar Web 的数据请求和原生功能请求。本质上就是在 Web 和 Native 之间实现了一个 Proxy。Web 发出的请求会被 Proxy 预先处理。要么是修改后再发出去,要么是由 Rexxar Container 自己处理。
    • Rexxar Container 截获请求之后,做相应的反应。这种 Native 和 Web 的交互被抽象成三种接口:
      • Decorator:修改数据请求。例如,数据请求加上 OAuth 认证信息。
      • Widget: 调用某些 Native UI 组件。例如,调起一个 Toast。
      • ContainerAPI:给 Web 一个 Native 的计算结果。例如,给出当前位置信息。
    • 优点:这三种接口都是由 Rexxar Web 发起某种形式的 URL 调用的。Rexxar Web 的业务代码在 App 的 Rexxar Container 内工作方式,和在普通浏览器里差别不大。因此,移植到 Web 平台,在各种浏览器中,代码无需做太多修改就可以正确运行。以 URL 作为协议,也为 Web 和 Native 划定了清晰的边界和数据传递方式。
  • Rexxar 页面执行过程

    • 打开一个 URL
    • 根据 URL 查询路由
    • 加载 HTML、CSS、图片等资源文件
    • 拦截并修改 API 请求
    • 根据 API 返回的结果,展示响应的页面
    • Rexxar Web 前端代码请求 URL ,与原生进行交互

4.Rexxar 的问题

  • 性能
    • 当性能问题会明显影响到用户体验时,我们就不使用 web 技术来做,而是使用传统 Native 老老实实写两份代码。
    • 在 iOS 端,使用 WKWebView 替代 UIWebView
  • 错误报告:对于 JavaScript 的相关错误,和浏览器相关的错误,难以找到根本原因来针对性解决。

@ShannonChenCHN ShannonChenCHN changed the title 【专题】Web View 与 Hybrid Web View 与 Hybrid Jul 4, 2017
@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Jul 9, 2017

《唐巧:基于 UIWebView 的混合编程》

一、混合编程(Hybrid)简介

实际应用中,基于 UIWebView 的界面的共同特点:
1.排版复杂。
2.界面的变化需求频繁。
3.界面对用户的交互需求不复杂。

二、使用模板引擎渲染 HTML 界面

1.HTML 片段的基本处理
相关 API:

- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL

HTML 片段格式化:

- (NSString *)demoFormatWithName:(NSString *)name value:(NSString *)value {
    NSString *html =
    @"<HTML>"
    "<HEAD>"
    "</HEAD>"
    "<BODY>"
    "<H1>%@</H1>"
    "<p>%@</p>"
    "</BODY>"
    "</HTML>";
    
    NSString *content = [NSString stringWithFormat:html, name, value];
    return content;
}

三、Objective-C 语言和 JavaScript 语言相互调用

四、如何传递参数

五、同步和异步

六、注意事项

1.线程阻塞问题
2.主线程的问题
3.键盘控制
4.CommonJS 规范

七、使用 Safari 进行调试

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Jul 19, 2017

Hybrid 改进计划

当前要解决的问题:

  • 项目中的 web view 五花八门
  • JS<->Native 交互定义不规范,没有清晰的规则
  • h5 中调用 Native 比较麻烦,目前采用的 Custom URL Scheme 的方式来做的,不方便传数据

期望的目标:

工作点:

  • 统一规范
  • Web 容器的统一
  • JS<->Native 桥接
  • Cookie 管理
  • 通用的交互逻辑
  • 其他
    • 预加载
    • 缓存

@ShannonChenCHN
Copy link
Owner Author

长按保存 UIWebView 中的图片

  • 监听长按手势,获取点击位置的图片的src属性,获取到图片 URL,最后再在 Native 端下载
  • 可不可以直接从 h5 端将图片数据(比如 base64 形式的字符串)传给 Native 端?(待验证)

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant