JavaScript与Object-C交互

Object-C部分##

1、导入框架和对应的头文件

JavaScriptCore.framework  // 框架
#import   //头文件

2、创建类文件,继承NSObject
3、编写类JSAndOCMutually.h代码
创建协议JSAndOCMutuallyProtocol,协议遵循
创建的类遵循创建的
代码示例如下:

#import 
@protocol JSAndOCMutuallyProtocol 
// JavaScript中调用Object-C的方法都写在此处,否则JS将找不到对应的方法
// 无参数
-(void)FunctionNoParameter;
// 一个参数
-(void)FunctionOneParameter:(NSString *)message;
// 两个参数
-(void)FunctionTwoParametersWithFirstParameter:(NSString *)message1 SecondParameter:(NSString *)message2;

@end

@interface JSAndOCMutually : NSObject 

@end

4、实现类JSAndOCMutually.h遵循协议中对应的方法
代码示例如下:

@implementation JSAndOCMutually

-(void)FunctionNoParameter{
    NSLog(@"this is iOS FunctionNoParameter");
}
-(void)FunctionOneParameter:(NSString *)message{
    NSLog(@"this is iOS FunctionOneParameter,FirstParameter=%@",message);
}
-(void)FunctionTwoParametersWithFirstParameter:(NSString *)message1 SecondParameter:(NSString *)message2{
    NSLog(@"this is iOS FunctionTwoParametersWithFirstParameter,FirstParameter=%@  SecondParameter=%@",message1,message2);
}

@end

5、WebView的代理中需要编写的代码
5.1、在遵循的ViewController中导入创建的类头文件以及库头文件

#import 
#import "JSAndOCMutually.h"

5.2、在UIWebViewDelegate代理的结束加载方法中,编写以下代码,

 - (void)webViewDidFinishLoad:(UIWebView *)webView{
    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    JSAndOCMutually *jsandOC = [JSAndOCMutually new];
    context[@"test"] = jsandOC;  // test 就是即将注入JavaScript中的对象
// block 方式
//   context[@"test"] = ^() {
//       block代码块,个人认为不赞成使用此种方式。
//   };
//  模拟JS调用OC的方法
//  NSString *jsStr1=@"test.TestNOParameter()";
//  [context evaluateScript:jsStr1];
}

至此,Object-C部分的代码基本结束,接下来就是在JavaScript中通过注入的“test”对象进行方法的调用。

JavaScript部分##

在WebView加载的HTML文件中JS代码部分
var message1 = "MeaasgeOne";
var message2 = "MeaasgeTwo";
// 无参数方法的调用
window.test.FunctionNoParameter();
// 一个参数方法的调用
window.test.FunctionOneParameter(message1);
// 两个参数方法的调用
window.test.FunctionTwoParametersWithFirstParameterSecondParameter(message1,message2);
// 如果有返回值,只需要声明一个变量接收返回值即可。

至此,简单的JS与OC的交互就结束了。

下面将是重点、重点、重点。#

现在,为了进行热更新,许多的APP开始使用iOS的壳加H5的内容,在我们的项目中H5请求后台数据时,需要通过JS与OC的交互获取原生态代码中的一些参数。
这时就出现了一个重要的问题。
问题描述:页面A与页面B,两个页面均需要进行网络请求,网络请求传给后台的参数均需要原生态的一些参数,当用WebView加载页面A时数据可以完美的呈现,点击跳转按钮,跳转到页面B,发现数据没有出现,然后返回页面A,发现页面A后台获取的数据也没有了。
由于页面A没有做数据缓存,因此每次的页面数据都必须通过网络请求到后台获取。这还不是最重要的。
经过测试发现,数据获取不到的最重要的原因:跳转页面B以及返回页面A都需要JS与OC进行交互,JS调用OC的方法获取原生态参数,而由于调转不是由原生态进行控制,只有第一次加载页面时,对象test注入到JS中,调用原生态方法成功;而后续的页面跳转以及网络请求均发生在对象test注入到JS加载之前,导致JS代码已经加载完成,而对象test还没有注入,因此调用原生态方法的失败。
解决方法:在JS代码中,将获取原生态参数的方法以及网络请求方法放到延迟方法中。
代码示例如下:

setTimeout(function () {
   window.test.TestTowParameterSecondParameter(message1,message2);
}, 100);
// 经过测试100毫秒的延迟,就可以达到效果,足够对象iOS注入到JS中。

你可能感兴趣的:(JavaScript与Object-C交互)