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

 

posted @ 2019-04-03 15:41  sundaysios  阅读(1129)  评论(0)    收藏  举报