H5与iOS交互
发布日期:2022-04-05 00:52:16 浏览次数:3 分类:博客文章

本文共 6111 字,大约阅读时间需要 20 分钟。

H5页面与原生交互项目中经常遇到,今天做个小结。

从iOS原生的角度讲,我们可以使用UIWebViewWKWebView组件来展示H5页面,那么两者有什么区别呢?

讲述UIWebView只是让大家了解下这个历史,按现在的情况我们主要使用WKWebView

一、推出时间

UIWebView从iOS2.0推出到iOS12.0废弃,WKWebView从iOS8.0推出

UIWebView ios(2.0, 12.0)  、WKWebView ios(8.0)

UIWebView 

UIKIT_EXTERN API_DEPRECATED("No longer supported; please adopt WKWebView.", ios(2.0, 12.0)) API_UNAVAILABLE(tvos, macos) @interface UIWebView : UIView 

WKWebView

#if TARGET_OS_IPHONEWK_EXTERN API_AVAILABLE(macos(10.10), ios(8.0))@interface WKWebView : UIView#elseWK_EXTERN API_AVAILABLE(macos(10.10), ios(8.0))@interface WKWebView : NSView#endif

二、性能对比

UIWebView

占用过多内存,且内存峰值更是夸张。说白了就是性能低

WKWebView

1、网页加载速度快,内存消耗低。

2、更多的支持HTML5的特性,

3、高达60fps的滚动刷新率以及内置手势,

4、Safari相同的JavaScript引擎(但就这一点性能完胜),

5、增加了进度属性estimatedProgress等特性

三、交互

UIWebView

1、OC调用JS

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

2、JS调用OC

<1>iOS原生拦截URL

拦截到指定URL做响应操作

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType API_DEPRECATED("No longer supported.", ios(2.0, 12.0));

<2>使用JavaScriptCore实现(要注意循环引用的问题)

JSDelegate
#import 
#import
/** * H5会通过对象Bridge调用协议中的方法 */@protocol JSDelegate
// 关闭页面- (void)finishPage;@end
JSObject(中间对象,解决循环引用的问题,不直接让WebViewController遵守JSDelegate的原因)
#import 
#import "JSDelegate.h"#import "WebViewController.h"@interface JSObject : NSObject
@property(nonatomic, weak) WebViewController *h5VC;@end
- (void)finishPage {        dispatch_async(dispatch_get_main_queue(), ^{            [self.h5VC pop];        });}
WebViewController
@property (strong, nonatomic) JSContext *jsContext;
// 获取JSContext,并注入对象- (void)creatJscontext{    //  获取js上下文(JSContext)    self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];    // 遵守JSExport协议的对象(符合JSExport的对象都将转换为JavaScript包装器对象)    JSObject *obj = [[JSObject alloc] init];    obj.h5VC = self;    //  注入交互对象Bridge,H5通过Bridge对象调用JSExport中的方法    self.jsContext[@"Bridge"] = obj;}

H5端将通过Bridge.finishPage()调用原生方法

备注:

JSContext
/*!@interface@discussion A JSContext is a JavaScript execution environment. All JavaScript execution takes place within a context, and all JavaScript values are tied to a context.*/JS_EXPORT API_AVAILABLE(macos(10.9), ios(7.0))@interface JSContext : NSObject

UIWebView什么时机创建JSContext环境

什么时候UIWebView会创建JSContext环境,分两种方式,

第一在渲染网页时遇到<script标签时,就会创建JSContext环境去运行JavaScript代码

第二就是使用方法[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]去获取JSContext环境时,

这时无论是否遇到<script标签,都会去创造出来一个JSContext环境,而且和遇到<script标签再创造环境是同一个。

JSExport
All objects that conform to JSExport convert to JavaScript wrapper objects, even if they subclass classes that would otherwise behave differently. For example, if a subclass of NSString conforms to JSExport, it converts to JavaScript as a wrapper object rather than a JavaScript string.*/@protocol JSExport

 

 
WKWebView
1、OC调用JS
/* @abstract Evaluates the given JavaScript string. @param javaScriptString The JavaScript string to evaluate. @param completionHandler A block to invoke when script evaluation completes or fails. @discussion The completionHandler is passed the result of the script evaluation or an error.*/- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

2、JS调用OC

<1>iOS原生拦截URL

/*! @abstract Decides whether to allow or cancel a navigation. @param webView The web view invoking the delegate method. @param navigationAction Descriptive information about the action triggering the navigation request. @param decisionHandler The decision handler to call to allow or cancel the navigation. The argument is one of the constants of the enumerated type WKNavigationActionPolicy. @discussion If you do not implement this method, the web view will load the request or, if appropriate, forward it to another application. */- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;

<2>使用MessageHandler(WKScriptMessageHandler)实现

WKWebView 初始化时,有一个参数叫configuration

它是WKWebViewConfiguration类型的参数,而WKWebViewConfiguration有一个属性叫userContentController

它又是WKUserContentController类型的参数。

WKUserContentController对象有一个方法- addScriptMessageHandler:name:,我把这个功能简称为MessageHandler。

添加或者删除消息处理

/*! @abstract Adds a script message handler. @param scriptMessageHandler The message handler to add. @param name The name of the message handler. @discussion Adding a scriptMessageHandler adds a function window.webkit.messageHandlers.
.postMessage(
) for all frames. */- (void)addScriptMessageHandler:(id
)scriptMessageHandler name:(NSString *)name;/*! @abstract Removes a script message handler. @param name The name of the message handler to remove. */- (void)removeScriptMessageHandlerForName:(NSString *)name;

 

收到H5发送的消息

#import 
NS_ASSUME_NONNULL_BEGIN@class WKScriptMessage;@class WKUserContentController;/*! A class conforming to the WKScriptMessageHandler protocol provides a method for receiving messages from JavaScript running in a webpage. */@protocol WKScriptMessageHandler
@required/*! @abstract Invoked when a script message is received from a webpage. @param userContentController The user content controller invoking the delegate method. @param message The script message received. */- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;@end

H5端调用

window.webkit.messageHandlers.
.postMessage(
)

综上所述:

最优的方案就是使用WKWebView,交互使用MessageHandler

 参考:

https://www.jianshu.com/p/94bd66874dba

https://www.jianshu.com/p/939db6215436

https://www.jianshu.com/p/f896d73c670a

https://blog.csdn.net/lyyo_cd/article/details/84304864

https://www.jianshu.com/p/79e329ff8953

https://blog.csdn.net/u011619283/article/details/52135988

转载地址:https://www.cnblogs.com/lijianyi/p/14581030.html 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Vue filters\filter、computed、methods、watch对比
下一篇:React Native 监听属性值

发表评论

最新留言

不错!
[***.144.177.141]2024年04月13日 15时37分02秒