OC WebView 与JavaScript 交互

Native 开发 和 H5  谁优谁劣,不在这边展开讨论。目前的开发过程中经常会遇到 原生应用 和web 交互的 需求。接下来我们就聊聊吧。

需求点

首页 运营一个活动,一个大转盘,转呀转呀,送 各种礼品呐。一个人一天可以转三次,分享到社交软件增加一次抽奖机会。


开始

iOS 应用 和web 页面交互 有以下 几种方法:

1、挺有名的第三方框架 WebViewJavaScriptBridge

2、iOS7 之后自带的 JavaScriptCore

3、据说还可以 拦截协议

第一种 和 第三种方法 这里就不详细介绍了(其实是我不会!!!)

方法一 作为 一个 知名的第三方框架,肯定会有 其他同行小伙伴介绍的,

传送门 :http://kittenyang.com/webview-javascript-bridge/

反正我也写不过他!

我选择方法二!

OC WebView 与JavaScript 交互_第1张图片

因为简单...

JavaScriptCore框架


OC WebView 与JavaScript 交互_第2张图片

JSContext:给JavaScript提供运行的上下文环境

JSValue:JavaScript和Objective-C数据和方法的桥梁

JSManagedValue:管理数据和方法的类

JSVirtualMachine:处理线程相关

JSExport:一个协议,接下来会介绍到

直接看代码

@interfaceTWWebViewController()

@property(nonatomic,strong)UIWebView*webView;

@property(nonatomic,strong)JSContext*jContext;

@property(nonatomic,strong)TWWebCallBackFunctionHelper*helper;

@end

考虑到 需求经常变化,我用 TWWebCallBackFunctionHelper 统一处理 OC 和 JS 制定的 方法。

- (void)viewDidLoad

{

[superviewDidLoad];

self.helper= [[TWWebCallBackFunctionHelperalloc]init];[self.viewaddSubview:self.webView];[self.webViewloadRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:self.webUrl]]];

}

加载  webView  和生成  TWWebCallBackFunctionHelper 对象。

#pragma mark - UIWebViewDelegate

- (BOOL)webView:(UIWebView*)webView

shouldStartLoadWithRequest:(NSURLRequest*)request

navigationType:(UIWebViewNavigationType)navigationType

{

returnYES;

}

- (void)webViewDidStartLoad:(UIWebView*)webView

{

if(!_jContext) {

self.jContext=

[webViewvalueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

self.jContext[@"toApp"] =_helper;

}

}

- (void)webViewDidFinishLoad:(UIWebView*)webView

{

if(!self.webTitle.length) {

//获取当前页面的title

NSString*webTitle = [webViewstringByEvaluatingJavaScriptFromString:@"document.title"];

self.title= webTitle;

}

}

- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error

{

NSLog(@"didFailLoadWithError = %@", error);

}

在 webView 开始加载的时候 获取 JavaScript 上下文,和前端的小伙伴约定 toApp 为回调对象名(也有一些叫法 桥梁对象 ),helper 为实现协议对象。

接下来实现 TWWebCallBackFunctionHelper

#import

@protocol webViewJsDelegate

JSExportAs(sharered, -(void)sharered

: (NSString *)url shareContent

: (NSString *)content linkUrl

: (NSString *)lUrl);

@end

JSExport 是 一个 协议, 自定义的  webViewJsDelegate 协议 需要遵守此协议。

我们来看下  JSExportAs 宏定义

OC WebView 与JavaScript 交互_第3张图片

PropertyName  类似 一个 key,和 对应的 例子里是 sharered,其 对应 要实现的方法是

-(void)sharered:shareContent:linkUrl;其中 'key' 对应的 sharered 需要和 web 约定一致。

//遵守 webViewJsDelegate 协议

@interfaceTWWebCallBackFunctionHelper()

@end

@implementationTWWebCallBackFunctionHelper

- (void)sharered:(NSString*)url shareContent:(NSString*)content linkUrl:(NSString*)lUrl

{

//TODO:

//实现业务逻辑,调起 分享 功能

}

@end

好了,差不多就这样了,在运行过程中,偶现一个bug,点击分享 按钮没有 丝毫 反应,也就是 分享UI组件 没有 调用起来。这是什么鬼呀!

好吧,直接断点 调试,-(void)sharered:shareContent:linkUrl 方法是跑到了,也就是 调用 UI 时没有 反应。考虑是不是线程问题,看了JavaStript 相关定义,果然,“avaScript引擎是单线程运行的”,“JavaStript调用本地方法是在子线程中执行的” ,so...

- (void)sharered:(NSString*)url shareContent:(NSString*)content linkUrl:(NSString*)lUrl

{

//TODO:

//实现业务逻辑,调起 分享 功能

//主线程中去 刷新 UI 等功能

dispatch_async(dispatch_get_main_queue(), ^{

}

});

}

结论

这边只是简单的介绍 JavaScriptCore  最基础的 用法,很轻量。更多的 JavaScriptCore API 可以去查 苹果官方文档。另外在网上搜了下,发现一篇 类似 介绍 OC WebView 与JavaScript 交互 文章,除了 介绍JavaScriptCore  还介绍了 iOS8之后的WKWebView  和 第三点 拦截协议,介绍的都 比我 的详细,贴出来 给大家参考:http://www.jianshu.com/p/f896d73c670a?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weibo

你可能感兴趣的:(OC WebView 与JavaScript 交互)