ios 混合开发(js请求网络,原生处理数据)

之前公司提出这样的需求,就是把原生的网络请求转换到用js来请求,打包成sdk,然而这样的需求在我看来,我不懂为什么,,。。当然,这是他们的问题。和我们好像没什么太大的关系,算了这些都是白说,主要的就是要改需求,然后再打包成sdk;

直接代码解释吧。。。。。

代码中的核心问题就是创建一个网络请求类,
首先创建一个网络请求类,

@interface msdk ()
//加载web页面的,主要的目的是要加载那些请求的js代码进来
@property (nonatomic , strong) UIWebView *webView;
//处理js用到的
@property (nonatomic , strong) JSContext *jsContext;
//加载url
@property (nonatomic , strong) NSString *urlPath;
//判断url是加载本地的还是加载网络上的
@property (nonatomic , assign) BOOL isLocal;
@end

首先我们要把这个类定义为一个单例:

static msdk *_instance;
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
            _instance.webView = [[UIWebView alloc]initWithFrame:CGRectZero];
            _instance.webView.delegate = _instance;
        }
    });
    return _instance;
}
+(instancetype)ShareInstance{
    //return _instance;
    return [[self alloc]init];
}

-(id)copyWithZone:(NSZone *)zone
{
    return _instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}

当然肯定是要设置代理的,这样的话就可以在加载完web页面之后就可以获取该webView的js上下文了

-(void)webViewDidFinishLoad:(UIWebView *)webView{
    //获取该UIWebview的javascript上下文
    self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    if (_isLocal && self.srv) {
           [self msdk_setSer:self.srv];
    }
}

加载本地web(当然你肯定是要设置请求地址的ip)

-(void)msdk_loadLocalWEB:(NSString *)urlPath{
    self.isLocal = YES;
    self.urlPath = urlPath;
    NSString * htmlPath = [[NSBundle mainBundle] pathForResource:urlPath
                                                          ofType:nil];
    NSURL *url = [NSURL URLWithString:htmlPath];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
}

加载网络web

-(void)msdk_loadNetworkWEB:(NSString *)urlPath{
    self.isLocal = NO;
    self.urlPath = urlPath;
    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlPath]]];
}

前方高能,最主要的是地方

- (void)msdk_ctr:(NSMutableDictionary*)paramter success:(void (^) (NSDictionary* result))success failure:(void (^)(NSString *error))failure;{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    //标明是ios的请求
    paramter[@"platform"] = @"ios";
    // 请求的接口是哪一个
    dic[@"type"] = paramter[@"func"];
    dic[@"data"] = paramter;
    NSString *type = dic[@"type"];
    //添加一个方法名为type的js方法
    [self.jsContext evaluateScript:[NSString stringWithFormat:@"function %@(a){}",type]];
    //把js方法替换成oc原生的方法,当调用type的js方法,就会转化为调用下面block里面的方法,下面的value就是调用的参数
    self.jsContext[type] = ^(JSValue *value){
        NSDictionary *dic = [value toObject];
        if (success &&[dic[@"result"] isEqualToString:@""]){
            dispatch_async(dispatch_get_main_queue(), ^{
                success(dic);
            });
        }
        else if (failure && ![dic[@"result"] isEqualToString:@""]){
            dispatch_async(dispatch_get_main_queue(), ^{
                failure(dic[@"result"]);
            });
        }
    };
    NSData * paramter_data = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
    NSString * js_paramter = [[NSString alloc] initWithData:paramter_data encoding:NSUTF8StringEncoding];
//调用js请求方法
    [self.jsContext evaluateScript:[NSString stringWithFormat:@"msdk_ctrl('%@');",js_paramter]];
}

好了,大概就是这样了
使用的时候再介绍一下吧

//需要在AppDelegate 里面设置,
 msdk *msdk_agent = [msdk ShareInstance];
//这是加载本地的
[_msdk_agent msdk_loadLocalWEB:@"web/mobile.debug.htm"];

//data是一个字典
    [self.msdk_agent msdk_ctr:data success:^(NSDictionary *result) {
      //请求成功
    } failure:^(NSString *error) {
    //请求失败
    }];

不好意思,项目还没拆分,,所以就没上传代码,,过段时间上传代码。。。

你可能感兴趣的:(ios 混合开发(js请求网络,原生处理数据))