iOS开发--OC调用JS篇
https://www.cnblogs.com/gchlcc/p/6154844.html
OC调用JS篇
其中相对应的html部分如下:
<html>
<header>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function secondClick() {
share('分享的标题','分享的内容','图片地址');
}
function showAlert(message){
alert(message);
}
</script>
</header>
<body>
<h2> 这里是第二种方式 </h2>
<br/>
<br/>
<button type="button" onclick="secondClick()">Click Me!</button>
</body>
</html>
方式一
NSString *jsStr = [NSString stringWithFormat:@"showAlert('%@')",@"这里是JS中alert弹出的message"];
[_webView stringByEvaluatingJavaScriptFromString:jsStr];
注意:该方法会同步返回一个字符串,因此是一个同步方法,可能会阻塞UI。
方式二 (推荐这种)
使用JavaScriptCore库来做JS交互。
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString *textJS = @"showAlert('这里是JS中alert弹出的message')";
[context evaluateScript:textJS];
原文链接:http://www.jianshu.com/p/d19689e0ed83
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
@interface WeakScriptMessageDelegate : NSObject<WKScriptMessageHandler>
@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
@end
#import "WeakScriptMessageDelegate.h"
@implementation WeakScriptMessageDelegate
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate
{
self = [super init];
if (self) {
_scriptDelegate = scriptDelegate;
}
return self;
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
[self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
}
@end
#import <WebKit/WebKit.h>
#import "WeakScriptMessageDelegate.h"
ClassViewController()
<WKNavigationDelegate, WKScriptMessageHandler>
{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:self.url]];
[self.webView loadRequest:request];
// 注册供JS调用的方法
// 返回首页
[self.webView.configuration.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"leftAction"];
// 上传作品
[self.webView.configuration.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"uploadPhoto_"];
// 编辑作品
[self.webView.configuration.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"editPhotoWithWorkId_activityId_"];
//downloadFileWithTitle_size_type_urlStr_
//点击选项
[self.webView.configuration.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"downloadFileWithTitle_size_type_urlStr_"];
// 他们每到新页面还需要调一下这个方法:setFlagNum(int flag) flag:列表页传1,详情页传2,查看作品传3,评分传4。 还需提供三个方法给我们调用:从列表也返回首页javascript:goHome();从详情页返回到列表页:javascript:goIndex() ; 从查看作品页返回到详情页:javascript:goDetailes()
}
#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
if (self.topView.hidden) {
self.topView.hidden = NO;
}
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
[MBProgressHUD showError:@"网络繁忙,请稍后再试" toView:self.view];
DLog(@"%@", error);
}
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
// 方法名
NSString *methodName = [message.name stringByReplacingOccurrencesOfString:@"_" withString:@":"];
NSArray *params = message.body;
// 参数(确保传入的是数组)
if ([params isKindOfClass:[NSString class]]) {
params = @[message.body];
}
if ([params isKindOfClass:[NSNull class]]) {
params = nil;
}
[self performSelector:NSSelectorFromString(methodName) withObjects:params];
}
// 上传作品
- (void)uploadPhoto:(NSString *)activityId
{
DLog(@"上传作品")
UIViewController *vc = [[CBUploadExhibitiUIViewControlleronViewController alloc] init];
vc.activityId = [activityId intValue];
vc.delegate = self;
[self.navigationController pushViewController:vc animated:YES];
}
// 编辑作品
- (void)editPhotoWithWorkId:(NSString *)workId activityId:(NSString *)activityId
{
DLog(@"编辑作品")
UIViewController *vc = [[UIViewController alloc] init];
vc.activityId = [activityId intValue];
vc.workId = [workId intValue];
vc.isEditing = YES;
vc.delegate = self;
[self.navigationController pushViewController:vc animated:YES];
}
//点击选项 下载
- (void)downloadFileWithTitle:(NSString *)title size:(NSString *)size type:(NSString *)type urlStr:(NSString *)urlStr{
UIViewController *vc = [UIViewController loadFromNib];
vc.title = title;
vc.length = size;
vc.type = type;
vc.fileUrl = urlStr;
[self.navigationController pushViewController:vc animated:YES];
}
#import "NSObject+Extension.h"
@implementation NSObject (Extension)
- (id)performSelector:(SEL)selector withObjects:(NSArray *)objects
{
// 方法签名(方法的描述)
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
if (signature == nil) {
return nil;
}
// NSInvocation:利用一个NSInvocation对象包装一次方法调用(方法调用者、方法名、方法参数、方法返回值)
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.target = self;
invocation.selector = selector;
if (![objects isKindOfClass:[NSNull class]]) {
// 设置参数
NSInteger paramsCount = signature.numberOfArguments - 2; // 除self、_cmd以外的参数个数
paramsCount = MIN(paramsCount, objects.count);
for (NSInteger i = 0; i < paramsCount; i++) {
id object = objects[i];
if ([object isKindOfClass:[NSNull class]]) continue;
[invocation setArgument:&object atIndex:i + 2];
}
}
// 调用方法
[invocation invoke];
// 获取返回值
id returnValue = nil;
if (signature.methodReturnLength) { // 有返回值类型,才去获得返回值
[invocation getReturnValue:&returnValue];
}
return returnValue;
}
@end