因为我之前尝试用苹果自带的JSExport写一个UIWebView与js 交互的方法, 写完是能够正确调用, 但如果从webView 中再重定向到其他网页, 那之前写的JSExport就会失效, 也就是之前写的方法不能在同一个UIWebView下的不同网页共用, 在网上找了一位大神写的分类, 加上自己的使用. 下面分享一下.
UIWebView-TS_JavaScriptContext
-
下面我们开始写代码吧.
首先把大神写的分类拖进项目.里面写的也不难, 可以看懂,有兴趣的可以看看(最后有demo)
*使用
#import "JJViewController.h"
#import "UIWebView+TS_JavaScriptContext.h"
#import "JSInterface.h"
// TSWebViewDelegate 中就一个方法, 实现他的方法
@interface JJViewController () <TSWebViewDelegate>
@end
@implementation JJViewController
{
IBOutlet UIWebView* _webView;
JSContext * _ctx;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL* htmlURL = [[NSBundle mainBundle] URLForResource: @"testWebView"
withExtension: @"htm"];
[_webView loadRequest: [NSURLRequest requestWithURL: htmlURL]];
// 代理一定要设置
_webView.delegate = self;
}
- (void)dealloc {
NSLog(@"%s",__func__);
}
- (void)webView:(UIWebView *)webView didCreateJavaScriptContext:(JSContext *)ctx
{
// js中想直接这样调用(<button type='button' onclick='sayHello()'>Say Hello!</button>), 可以把 sayHello , 直接丢给ctx:
ctx[@"sayHello"] = ^{
// 要注意, 它调用时是异步的, 如果想在主线程做事, 需回到主线程
dispatch_async( dispatch_get_main_queue(), ^{
UIAlertView* av = [[UIAlertView alloc] initWithTitle: @"Hello, World!"
message: nil
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[av show];
});
};
// 为防止循环引用, 需要建立一个类来处理你的协议方法
// 在js 中如果想调用JSInterface协议中的方法需要以 'viewController' 开头, 是ctx[@"viewController"]中决定定的.比如js:<button type='button' onclick='viewController.sayGoodbye()'>Say Goodbye!</button>
ctx[@"viewController"] = [[JSInterface alloc]init];
}
@end
- JSInterface.m
#import "JSInterface.h"
@protocol JavaScriptDelegate <JSExport>
- (void) sayGoodbye;
@end
@interface JSInterface() <JavaScriptDelegate>
@end
@implementation JSInterface
- (void) sayGoodbye
{
// 要注意, 它调用时是异步的, 如果想在主线程做事, 需回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView* av = [[UIAlertView alloc] initWithTitle: @"Goodbye, World!"
message: nil
delegate: nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[av show];
});
}
@end
- 至此, js调用原生结束, 如果是同一个UIWebView, 不管怎么redirect多少次, 你定义的协议方法依然可以调用.如果想看原生调用js, 请看我的另一篇文章谈谈swift版的 WKWebView 与js/ts 交互,最后有讲.
- Demo地址