论 iOS 开发中 JS 与 Native 的交互方式Word文件下载.docx
- 文档编号:17509241
- 上传时间:2022-12-06
- 格式:DOCX
- 页数:8
- 大小:18.44KB
论 iOS 开发中 JS 与 Native 的交互方式Word文件下载.docx
《论 iOS 开发中 JS 与 Native 的交互方式Word文件下载.docx》由会员分享,可在线阅读,更多相关《论 iOS 开发中 JS 与 Native 的交互方式Word文件下载.docx(8页珍藏版)》请在冰豆网上搜索。
这里编写了一个demo仅供参考:
-(void)webViewDidFinishLoad:
(UIWebView*)webView
{
NSString*str=[self.webViewstringByEvaluatingJavaScriptFromString:
@"
pageDidLoad()"
];
NSLog(@"
%@"
str);
}
当WebView加载完毕的时候调用JS中的pageDidLoad方法,并在控制台打印JS的执行结果。
JS调用Native:
使用WebView方法/代理方法完成JS调用Native要稍微复杂一点,需要Native前端和web前端的良好配合,主要原理是通过UIWebVIew的代理方法截取web前端的跳转请求,通过识别与web前端约定好的自定义协议头来判断本次请求是否为JS调用Native的请求,来调用对应的Native方法。
其中涉及到的UIWebView代理方法为:
-(BOOL)webView:
(UIWebView*)webViewshouldStartLoadWithRequest:
(NSURLRequest*)requestnavigationType:
(UIWebViewNavigationType)navigationType;
下面通过例子来进行演示:
JavaScript代码:
functionbtnOnClickBaidu(){
varurl="
"
;
alert("
马上跳转的页面是:
+url);
window.location.href=url;
}
functionbtnOnClickNative(){
DZBridge:
//printSomeWords"
functionbtnOnClickNativeWithConfig(){
//printSomeWords?
{\"
string\"
:
\"
HelloWorld\"
}"
functionpageDidLoad(){
页面加载完毕!
);
return11;
OC代码:
(UIWebView*)webViewshouldStartLoadWithRequest:
(NSURLRequest*)requestnavigationType:
(UIWebViewNavigationType)navigationType
//dzbridge为约定好的协议头,如果是,则页面不进行跳转
if([request.URL.schemeisEqualToString:
dzbridge"
]){
//截取字符串来判断是否存在参数
NSArray&
lt;
NSString*&
gt;
*arr=[request.URL.absoluteStringcomponentsSeparatedByString:
?
if(arr.count&
1){
NSString*str=[arr[1]stringByRemovingPercentEncoding];
NSDictionary*dict=[NSJSONSerializationJSONObjectWithData:
[strdataUsingEncoding:
NSUTF8StringEncoding]options:
0error:
NULL];
dict[@"
string"
]);
else{
没有参数的打印"
returnNO;
//不是自定义协议头,跳转页面
returnYES;
WKWebView控件
iOS8以后,苹果推出了新框架WKWebKit,其中提供了可以替换UIWebView的组件WKWebView。
原来UIWebView的各种问题得到了改善,速度更快了,占用内存少了(模拟器加载XX与开源中国网站时,WKWebView占用23M,而UIWebView占用85M),目前来看,WKWebView是App内部加载网页更佳的选择!
WKWebView相对UIWebView做了较大幅度的重构,将UIWebViewDelegate与UIWebView重构成了14类与3个协议,因此,在WKWebView中进行JS与Native的交互与UIWebView相比也有较大的不同。
在WKWebView中Native调用JS的方式与UIWebview中比较相似,也是通过自己本身的一个对象方法:
//javaScriptString为待执行的JS语句
//completionHandler为执行JS完毕后的回调,block的第一个参数为执行结果,第二个参数为错误
-(void)evaluateJavaScript:
(NSString*)javaScriptStringcompletionHandler:
(void(^__nullable)(__nullableid,NSError*__nullableerror))completionHandler;
看下面一个小例子:
#pragmamark-----WKNavigationDelegate-----
-(void)webView:
(WKWebView*)webViewdidFinishNavigation:
(WKNavigation*)navigation
[self.webViewevaluateJavaScript:
completionHandler:
^(id_Nullablevalue,NSError*_Nullableerror){
value);
}];
WKWebView中JS调用Native与UIWebView有着比较大的不同,首先需要介绍几个类(/协议/属性):
WKWebViewConfiguration:
是WKWebView初始化时的配置类,里面存放着初始化WK的一系列属性;
WKUserContentController:
为JS提供了一个发送消息的通道并且可以向页面注入JS的类;
WKScriptMessageHandler:
一个协议,协议中只有一个方法,这个方法是页面执行特定JS的一个回调,这个特定的JS格式为:
window.webkit.messageHandlers.&
name&
.postMessage(&
messageBody&
);
WKWebViewConfiguration作为WK的配置类,其中有一个属性为
@property(nonatomic,strong)WKUserContentController*userContentController;
是WKUserContentController的一个实例,WKUserContentController有一个对象方法为:
/*!
@abstractAddsascriptmessagehandler.
@paramscriptMessageHandlerThemessagehandlertoadd.
@paramnameThenameofthemessagehandler.
@discussionAddingascriptMessageHandleraddsafunction
window.webkit.messageHandlers.&
)forall
frames.
*/
-(void)addScriptMessageHandler:
(id&
WKScriptMessageHandler&
)scriptMessageHandlername:
(NSString*)name;
从苹果给出的注释来看,通过该方法能够添加一个脚本消息的处理器,即(id&
)scriptMessageHandler,另外还能发现,添加脚本处理器后,需要在JS中添加window.webkit.messageHandlers.&
)才能起作用。
demo:
//创建并配置WKWebView的相关参数
WKWebViewConfiguration*config=[[WKWebViewConfigurationalloc]init];
WKUserContentController*userContent=[[WKUserContentControlleralloc]init];
//self指代的对象需要遵守WKScriptMessageHandler协议
[userContentaddScriptMessageHandler:
selfname:
test"
config.userContentController=userContent;
在页面上的JS执行window.webkit.messageHandlers.&
)时,被添加的ScriptMessageHandler就会执行实现的WKScriptMessageHandler协议的方法,例如:
#pragmamark-----WKScriptMessageHandler-----
/**
*JS调用OC时webview会调用此方法
*
*@paramuserContentControllerwebview中配置的userContentController信息
*@parammessagejs执行传递的消息
-(void)userContentController:
(WKUserContentController*)userContentControllerdidReceiveScriptMessage:
(WKScriptMessage*)message
message);
在代理方法中实现相应的Native代码,即完成了JS调用Native的过程。
二、JavaScriptCore
OSXMavericks和iOS7引入了JavaScriptCore库,把WebKit的JavaScript引擎用Objective-C封装,提供了简单,快速以及安全的方式接入JavaScript。
JavaScriptCore中类及协议
JSContext:
JavaScript运行的上下文环境JSValue:
JavaScript和Objective-C数据和方法的桥梁JSExport:
这是一个协议,如果采用协议的方法交互,自己定义的协议必须遵守此协议JSManagedValue:
管理数据和方法的类JSVirtualMachine:
处理线程相关,使用较少
JavaScript调用Native
使用JavaScriptCore进行JS和Native的交互,无论想要实现什么样的效果都需要获得一个有效的JSContext实例,即一个有效的JS运行的上下文(这一步骤以下不再重复提及)。
获得当前的JSContext:
可以在页面加载完毕后,采用KVC的方式从webView中获得,如下:
JSContext*jsContext=[webViewvalueForKeyPath:
documentView.webView.mainFrame.javaScriptContext"
将想要被暴露给JS的方法抽象成为一个协议(protocol),该协议需要遵守JSExport协议:
@protocolJSObjcDelegate&
JSExport&
-(void)callCamera;
-(NSString*)share:
(NSString*)shareString;
@end
将要暴露给JS的对象的类需要遵守自定义的协议,如上:
JSObjcDelegate;
将OC对象桥接到JS环境中,并设置异常处理
//将本对象与JS中的DZBridge对象桥接在一起,在JS中DZBridge代表本对象
[self.jsContextsetObject:
selfforKeyedSubscript:
DZBridge"
self.jsContext.exceptionHandler=^(JSContext*context,JSValue*exceptionValue){
context.exception=exceptionValue;
异常信息:
exceptionValue);
};
在JS中通过DZBridge调用本对象暴露出的方法:
varcallShare=function(){
varshareInfo=JSON.stringify({"
title"
"
标题"
"
desc"
内容"
shareUrl"
});
varstr=DZBridge.share(shareInfo);
alert(str);
Native调用JavaScript
第一种方式同UIWebView中类似,都是直接执行JS字符串,通过JSContext执行JS代码:
[self.jsContextevaluateScript:
alert(\"
执行JS\"
)"
另一种方式适用于执行web页面上已有的方法,通过JSValue来调用JS中的方法,JSValue是JavaScript中值得一个引用,他可能包装着一个JavaScript的方法,通过callWithArguments:
方法进行调用,例如:
JSValue*picCallback=self.jsContext[@"
picCallback"
[picCallbackcallWithArguments:
@[@"
photos"
]];
推荐拓展阅读著作权归作者所有如果觉得我的文章对您有用,请随意打赏。
您的支持将鼓励我继续创作!
¥打赏支持喜欢
4
分享到微博
分享到微信
更多分享
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- iOS 开发中 JS Native 的交互方式 开发 交互 方式