首页 > 技术文章 > Weex 实现文件的下载

sunjianfei 2017-08-04 14:50 原文

需求:在使用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})

                });

 大功告成!!!

 

 

推荐阅读