需求:在使用weex框架时,我们使用vue文件写页面,在native端加载服务器端的js页面时由于网络状态的不确定性,我们需要在第一次加载的时候对js页面进行本地存储。也就是说我们需要把js文件下载到本地,然后进行加载,这样可以避免出现网络环境不好的情况下卡顿白屏等问题。
解决办法:查了一些文档,发现直接在vue页面内添加下载逻辑不太方便,所以使用的是原生端扩展的方法进行文件的下载,关于原生端的扩展可以在这里进行查看http://weex-project.io/cn/references/advanced/extend-to-ios.html
逻辑:
注意:文件路径的规范,详情参考上一篇博客。
native端(ios)
原生类文件:
.h
// JSDownloaderModule.h // weidaikuan // // Created by JianF.Sun on 17/7/31. // Copyright © 2017年 ever. All rights reserved. // #import <Foundation/Foundation.h> #import <WeexSDK/WeexSDK.h> @interface JSDownloaderModule : NSObject -(void)jydownloadJSFile:(NSString *)urlStr callback:(void(^)(NSString* path))callback; @end
.m
// // JSDownloaderModule.m // weidaikuan // // Created by JianF.Sun on 17/7/31. // Copyright © 2017年 ever. All rights reserved. // #import "JSDownloaderModule.h" #import "AppDelegate.h" #import "JYLoadingView.h" #import "NSString+Utils.h" @implementation JSDownloaderModule WX_EXPORT_METHOD(@selector(jydownloadJSFile:callback:)) //file:///var/mobile/Containers/Bundle/Application/{id}/WeexDemo.app/ ///var/mobile/Containers/Data/Application/D99A000B-5E21-451C-B701-3350098EBFA3/Documents/infomation.js -(void)jydownloadJSFile:(NSString *)urlStr callback:(void(^)(NSString* path))callback{ JYLoadingView *loading = [JYLoadingView new]; [loading jyShowLoadingview:@"正在加载"]; NSLog(@"download----url----%@",urlStr); if ([urlStr hasPrefix:@"file:///"]) {//本地路径直接返回 [loading jyRemoveLoadingview:@"0"]; callback(urlStr); } //http类型 NSString *fileName = [self getFileName:urlStr];//待加密 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docDir = [paths objectAtIndex:0]; NSString *dirpath = [NSString stringWithFormat:@"%@/JS",docDir]; NSString *filepath = [NSString stringWithFormat:@"%@/%@",dirpath,fileName]; if (![[NSFileManager defaultManager]fileExistsAtPath:dirpath]) { [[NSFileManager defaultManager] createDirectoryAtPath:dirpath withIntermediateDirectories:YES attributes:nil error:nil]; }else{ NSLog(@"有这个文件了"); } if ([[NSFileManager defaultManager] fileExistsAtPath:filepath]) { NSString *pathNew = [NSString stringWithFormat:@"file://%@",filepath]; dispatch_async(dispatch_get_main_queue(), ^{ [loading jyRemoveLoadingview:@"0"]; callback(pathNew); }); }else{ //1.网址 NSURL *url=[NSURL URLWithString:urlStr]; //2.请求 NSURLRequest *request=[NSURLRequest requestWithURL:url]; //3.队列 NSOperationQueue *queue=[[NSOperationQueue alloc]init]; //4.发送异步请求 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError) { if (![data writeToFile:filepath atomically:YES]) { NSLog(@"文件写入错误"); dispatch_async(dispatch_get_main_queue(), ^{ [loading jyRemoveLoadingview:@"0"]; }); }else{ NSString *pathNew = [NSString stringWithFormat:@"file://%@",filepath]; dispatch_async(dispatch_get_main_queue(), ^{ [loading jyRemoveLoadingview:@"0"]; callback(pathNew); }); } }]; } } //去掉http前缀,获取存储文件的名称 -(NSString*)getFileName:(NSString*)urlStr{ int length=(int)urlStr.length; // NSLog(@"length===%d",length); NSString *result=@""; for (int i=length-1; i>-1; i--) { if ([[urlStr substringWithRange:NSMakeRange(i, 1)] isEqualToString:@"/"]) { NSString *tem=[urlStr substringWithRange:NSMakeRange(i+1, length-i-1)]; result=tem; return [result md5]; } } return result; } @end
注册自定义module:
[WXSDKEngine registerModule:@"jsdownloader" withClass:[JSDownloaderModule class]];
weex(js端)
获取module
const jsdownloader = weex.requireModule('jsdownloader')
调用native端口
jsdownloader.jydownloadJSFile(config.jsURL('face.js'),function (e) { console.log('callback'+e); var url = e; var params = { 'url': url, 'animated' : 'true', } navigator.push(params, function () {}); // modal.toast({message: this.platform, duration:2}) });
大功告成!!!