IOS 从服务器下载文件

来源:互联网 发布:固态用软件优化 编辑:程序博客网 时间:2024/04/30 09:44

项目中需要从服务器下载一个update.zip文件,用http协议下载,刚接触IOS什么都不懂,网上查了下,说,用三方库代码写起来比用原生API来写简单。现在网络的三方库大家都在用AFNetworking。首先,依靠网络的力量写了一个测试的代码:

-(void)downLoad{

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURL *URL = [NSURL URLWithString:@"http://fex.wheatek.com:8080/testFile/2M.rar"];

    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    [manager setDownloadTaskDidFinishDownloadingBlock:^NSURL *(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location) {
        NSLog(@"setDownloadTaskDidFinishDownloadingBlock location==%@",location.description);
       
        NSURL *dirURL  = [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
        NSLog(@"AAAAAAA path==%@",dirURL.path);
        //return dirURL;
        return [dirURL URLByAppendingPathComponent:@"t1.file"];
    }];


    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        //NSLog(@"downloadProgress =%llu,%llu",downloadProgress.totalUnitCount,downloadProgress.completedUnitCount);
        CGFloat tempPercent = ((CGFloat)downloadProgress.completedUnitCount)/((CGFloat)downloadProgress.totalUnitCount)*100;
        NSLog(@"AAAAA = %f",tempPercent);
        
        
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"self.flashFlag = %f",tempPercent);
            self.lblPercent.text = [NSString stringWithFormat:@"%f",tempPercent];
        });
    } destination:nil completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        NSLog(@"File downloaded to: %@", filePath);
        NSLog(@"Error: %@", error.description);
        NSLog(@"NSURLResponse : %@", response.description);
        //[manager invalidateSessionCancelingTasks:YES ];
        [manager.session invalidateAndCancel];
        [self unZipFileTest:filePath.path];
    }];

    [downloadTask resume];

}

URL:直接下载服务器上的文件,下载到本地命名为:t1.file。但是,问题来了,服务器不是以这种方式来提供下载的,需要首先向服务器发出请求,然后服务器返回给客户端的是数据流。 这下又蒙了。 不管了,还是先写测试demo吧!

-(void)downloadSourceFile:(NSString *)fileName filePath:(NSString *)filePath downloadURL:(NSString *)downloadURL{
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

    
    NSError *error = NULL;
    NSDictionary *requestBody = @{@"name":@"b_download_version",
                                  @"details":@{
                                          @"protocol":@"1.0",
                                          @"fileName":fileName,
                                          @"filePath":filePath,
                                          }
                                  };
    NSMutableURLRequest *urlRequest = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:SERVER_URL parameters:requestBody error:&error];
    
    [manager setDownloadTaskDidFinishDownloadingBlock:^NSURL *(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location) {
        wtkLog(@"setDownloadTaskDidFinishDownloadingBlock location==%@",location.description);
        
        NSURL *dirURL  = [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
        wtkLog(@"AAAAAAA path==%@",dirURL.path);
        //return dirURL;
        return [dirURL URLByAppendingPathComponent:@"update.zip"];
    }];
    
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:urlRequest progress:^(NSProgress * _Nonnull downloadProgress) {
        //wtkLog(@"downloadProgress =%llu,%llu",downloadProgress.totalUnitCount,downloadProgress.completedUnitCount);
        CGFloat tempPercent = ((CGFloat)downloadProgress.completedUnitCount)/((CGFloat)downloadProgress.totalUnitCount)*100;
        wtkLog(@"AAAAA = %f",tempPercent);
        
        
        dispatch_async(dispatch_get_main_queue(), ^{
            wtkLog(@"self.flashFlag = %f",tempPercent);
            self.progressView.progress = tempPercent;
        });
    } destination:nil completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        [self removeProgressDialog];
        wtkLog(@"File downloaded to: %@", filePath);
        wtkLog(@"Error: %@", error.description);
        wtkLog(@"NSURLResponse : %@", response.description);
        if (error) {

            [constants showMessage:NSLocalizedString(@"DOWNLOAD_FAILED", @"download failed") posY:-1];
            return;
        }
        
        //[manager invalidateSessionCancelingTasks:YES ];
        [manager.session invalidateAndCancel];
        [self unZipFileTest:filePath.path];
    }];

    [downloadTask resume];
}

发现下载下来的文件不对(其实是对的,我以为不对,所以这段代码完全可以正常工作),所以,又到网上查资料,最后,还是看了苹果官网的AIP介绍,用原生的API又实现了一遍:

-(void)downloadDataFlow:(NSString *)fileName filePath:(NSString *)filePath{
   
    NSError *error = NULL;
    NSDictionary *bodyStr = @{@"name":@"b_download_version",
                              @"details":@{
                                      @"protocol":@"1.0",
                                      @"fileName":fileName,
                                      @"filePath":filePath,
                                      }
                              };
    NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:SERVER_URL parameters:bodyStr error:&error];
    NSLog(@"request==%@",request);
    
    ///NSURLSession *session = [NSURLSession sharedSession];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
    
    [task resume];
}

下面几个方法是NSURLSessionDataDelegate协议方法
//1.接收到服务器响应的时候调用该方法
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    //在该方法中可以得到响应头信息,即response
    NSLog(@"didReceiveResponse--%@",[NSThread currentThread]);
    
    //注意:需要使用completionHandler回调告诉系统应该如何处理服务器返回的数据
    //默认是取消的
    /*
            59         NSURLSessionResponseCancel = 0,        默认的处理方式,取消
            60         NSURLSessionResponseAllow = 1,         接收服务器返回的数据
            61         NSURLSessionResponseBecomeDownload = 2,变成一个下载请求
            62         NSURLSessionResponseBecomeStream        变成一个流
            63      */
   
      completionHandler(NSURLSessionResponseAllow);
}

//2.接收到服务器返回数据的时候会调用该方法,如果数据较大那么该方法可能会调用多次
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    NSLog(@"didReceiveData--%@",[NSThread currentThread]);
    NSLog(@"NSData==%@",data);
    
    //拼接服务器返回的数据
    //self.responseData appendData:data];
    
    [updateMbandData appendData:data];
}

//3.当请求完成(成功|失败)的时候会调用该方法,如果请求失败,则error有值
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"didCompleteWithError--%@",[NSThread currentThread]);
    
    if(error == nil)
    {
        //解析数据,JSON解析请参考http://www.cnblogs.com/wendingding/p/3815303.html
        //NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:nil];
        //NSLog(@"%@",dict);
        [self createDir];
        NSString *path = [self createFile];
        NSLog(@"updateMbandData==%@",updateMbandData);
        [updateMbandData writeToFile:path atomically:NO];
    }
}

-(void)handleData:(NSData *)data{
    
}

//创建文件夹
-(void)createDir{
    NSString *documentsPath =[self dirLib];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"mband"];
    // 创建目录
    BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];
    if (res) {
        NSLog(@"文件夹创建成功");
    }else{
        NSLog(@"文件夹创建失败");
    }
}

-(NSString *)createFile{
    NSString *documentsPath =[self dirLib];
    NSString *mbandDirectory = [documentsPath stringByAppendingPathComponent:@"mband"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *mbandPath = [mbandDirectory stringByAppendingPathComponent:@"update.zip"];
    BOOL res=[fileManager createFileAtPath:mbandPath contents:nil attributes:nil];
    if (res) {
        NSLog(@"文件创建成功: %@" ,mbandPath);
        return mbandPath;
    }else{
        NSLog(@"文件创建失败");
        return  nil;
    }
}

//获取Library目录
-(NSString *)dirLib{
    //[NSHomeDirectory() stringByAppendingPathComponent:@"Library"];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *libraryDirectory = [paths objectAtIndex:0];
    NSLog(@"app_home_lib: %@",libraryDirectory);
    return libraryDirectory;
}  

0 0
原创粉丝点击