iOS与H5交互

iOS与H5的交互方案:

第一种方法比较简单,通过字符串的比对。这种方式iOS端代码比较简单,网页加载完成后后台需要重新定义网页url,将移动端需要的参数拼接到url上返回,或者按照和后台约定好的字段来进行字符串比对以达到调用iOS方法的目的。

第二种方法,JSContext注入模型,JS直接用oc方法名来调用oc方法,类似于安卓.addJavascriptInterface(new JsObject(), "Android")方法,头文件需要导入#import <JavaScriptCore/JavaScriptCore.h>。

个人认为第二种方式比较好,两边可以直接进行互调。


参考文章:这里边写的已经很清楚了(http://www.jianshu.com/p/f896d73c670a/comments/1335187)。


项目中的代码:


#import <Foundation/Foundation.h>

#import <JavaScriptCore/JavaScriptCore.h>

//JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用
@protocol JSObjcDelegate <JSExport>


//是否登录,点击收藏的时候H5调用的
- (BOOL)isLogin;

//点击活动详情H5页面的立即报名
- (void)applyAction:(BOOL)isApply;

@end



@interface JSModel : NSObject<JSObjcDelegate>

@property (nonatomic, strong) JSContext *jsContext;

@end

#import "JSModel.h"

@implementation JSModel

- (BOOL)isLogin{
    
    NSLog(@"JS调用本地isLogin方法");
    
    if (![LoginViewController isLogin]) {
        //没登录
        [LoginViewController checkLogin:^(id result) {
    
                ;
        }];
        
        //JS调用完OC方法后,执行下边的JS回调方法,并回传响应的参数
        //isLoginCallback : H5那边约定的回调方法
        //@[@"0"]] :回传的参数
        JSValue *shareCallback = self.jsContext[@"isLoginCallback"];
        [shareCallback callWithArguments:@[@"0"]];
        return NO;
        
        }else{
        //登录了,直接给H5回传1
        JSValue *shareCallback = self.jsContext[@"isLoginCallback"];
        [shareCallback callWithArguments:@[@"1"]];
        return YES;
        }

}

- (void)applyAction:(BOOL)isApply{
    
    NSLog(@"JS调用本地applyAction方法");
    
    //如果是点击活动详情的立即报名按钮
    if (![LoginViewController isLogin]) {
        //没登录
        [LoginViewController checkLogin:^(id result) {

            ;
        }];
    }else{
        //登录了
        if (isApply) {
            //报名了
            [JFTools showTipOnHUD:@"您已报名此活动!"];
        }else{
            //没报名
            [JFTools callCustomerService];
        }
    }

}
@end


在 (void)webViewDidFinishLoad:(UIWebView *)webView 方法中加入下面的代码,即可。

 //获得JavaScript提供运行的上下文环境
    self.jsModel.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    
    //LinkModel :对象名,这个和H5约定好,那边调用方法就使用这个对象
    self.jsModel.jsContext[@"LinkModel"] = self.jsModel;
    
    //异常信息
    self.jsModel.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
        context.exception = exceptionValue;
        NSLog(@"JS交互异常信息:%@", exceptionValue);
    };


大概就是这些东西了,今天有时间总结了一下,有需要的朋友可以参考一下。。。。。。


更新:2018年3月

第三种方法:使用WKWebView

lazy var webView : WKWebView = {

        /// 自定义配置

        var conf = WKWebViewConfiguration()

        conf.userContentController = WKUserContentController()//用来做native与JavaScript的交互管理

        conf.preferences.javaScriptEnabled = true

        

        //MARK:将于H5约定好的方法名,加到子类中

        //在子类中添加和移除约定的交互方法,避免内存泄露


        let web = WKWebView( frame: self.view.frame,configuration:conf)

        self.view.addSubview(web)

        return web

    }()


子类实现:

class NoticeWebViewController: BaseWebViewController {


    override func viewDidLoad() {

        super.viewDidLoad()


    }


    override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)

        //在这里添加与web页交互的方法

        //公告点击查看附件 方法

        webView.configuration.userContentController.add(self as WKScriptMessageHandler, name: "JLModel")

    }

    override func viewWillDisappear(_ animated: Bool) {

        //在这里移除与web页交互的方法,不移除的话会造成内存泄露

        webView.configuration.userContentController.removeScriptMessageHandler(forName: "JLModel")

    }

    deinit {

       

        printDebug(content: "控制器销毁")

    }

    

    //用于与JS交互

    override func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

        

        // JLModel:是和Web约定的方法

        if(message.name == "JLModel") {

            

            printDebug(content: "JavaScript is sending a message \(message.body)")

            //传过来的文件的url地址

            let fileUrl = message.body as? String

            let fileScanWebVC = BaseWebViewController()

            fileScanWebVC.title = "附件详情"

            fileScanWebVC.str_URL = fileUrl

            kCurNavController?.pushViewController(fileScanWebVC, animated: true)

        }

        

    }

    

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值