다운로드, 샘플 코드 작은 파일 :
// NSURLSession的下载 [[[NSURLSession sharedSession] dataTaskWithURL [NSURL URLWithString : @ " http://gss0.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/lvpics/w=600/sign=1350023d79899e51788e391472a5d990/b21bb051f819861810d03e4448ed2e738ad4e65f.jpg " ] completionHandler ^ (*을 NSData _Nullable 데이터 NSURLResponse * _Nullable 응답 NSError * _Nullable 에러) { // 回到主线程刷新界面 dispatch_async (dispatch_get_main_queue () ^ { self.imageView.image = [있는 UIImage imageWithData : 데이터] }); }] 이력서] ;
코드 예제의 큰 파일을 다운로드 :
# import에 " ViewController.h " 의 ViewController @interface () <NSURLSessionDataDelegate> @property (약한 비 원자)의 UIImageView 함께 IBOutlet * 이미지 뷰; @property (비 원자 강한) NSMutableData * FILEDATA; @property (비 원자 할당) NSInteger totalSize를; @property (비 원자 할당) NSInteger currentSize을; @property (약한 비 원자) 함께 IBOutlet UIProgressView * progressView; @end @implementation의 ViewController - ( 무효 ) touchesBegan : (NSSet <UITouch *> *)는 withEvent 접촉 (의 UIEvent *) 이벤트 { // 1确定资源路径 * = URL NSURL [NSURL URLWithString : @ " http://meiye-mbs.oss-cn-shenzhen.aliyuncs.com/mbsFiles/0e3d0e4a0d5d4da5963e9e7617e8de101565841097849.mp4 " ]; // 2는 요청 객체 생성 = NSURLRequest * 요청 [NSURLRequest requestWithURL : URL]; // 3 세션 개체가 생성됩니다. 스레드가 전달되지 기본 하위 스레드 처리 NSURLSession 세션 * = [NSURLSession sessionWithConfiguration : [NSURLSessionConfiguration defaultSessionConfiguration] 대리인 : 자기 delegateQueue : [NSOperationQueue mainQueue]]; // . (4)를 만들 수있는 다운로드 요청 작업 * = dataTask NSURLSessionDataTask [세션 dataTaskWithRequest : 신청]; // . 5 전송 요청 [dataTask 재개] } 의 #pragma 마크 - 프록시 방법 // 응답이 수신 될 때 호출 - ( 무효 ) URLSession (NSURLSession *) dataTask 세션 (NSURLSessionDataTask *) dataTask didReceiveResponse (NSURLResponse *) :( 응답 CompletionHandler 공극 (^ ) (NSURLSessionResponseDisposition) ) CompletionHandler { // 요청 된 데이터의 현재 파일 크기를 얻을 self.totalSize = response.expectedContentLength; // 데이터 받아야하는 시스템에게 CompletionHandler (NSURLSessionResponseAllow을); } // 호출 할 때 2가 서버에 반환 데이터를 수신, 그것을 호출 할 수있는 다중를 CI - ( 무효 ) URLSession : (NSURLSession *) dataTask 세션 : (NSURLSessionDataTask *) dataTask didReceiveData : (을 NSData * ) 데이터 { //접합 데이터 [self.fileData 대한 appendData : 데이터]; // 계산하고 다운로드 된 데이터 / 파일의 전체 크기 = 다운로드 진행 파일을 표시 self.currentSize + = data.length입니다; CGFloat 진행 = 1.0 * self.currentSize / 셀프. totalSize, self.progressView.progress = 진행; NSLog ( @ " % f를 " , 진행); } // 3 다운로드가 완료하거나 전화 실패 - ( 무효 ) URLSession : (NSURLSession *) 작업 세션 : (NSURLSessionTask *) 작업 didCompleteWithError :합니다 (NSError * ) 오류 { // 문서를 얻을 : 헤더 정보는 권장되는 파일 이름에 대한 응답 헤더 정보를 획득, 요청에 대한 응답으로 얻은 * 파일 이름을있는 NSString =[task.response suggestedFileName]; // 파일 경로 접합 (샌드 박스로 캐쉬 파일 이름 +) 저장 는 NSString * 캐시 = [NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES) lastObject] // 다운로드 경로 는 NSString fullpath에 * = [캐시 stringByAppendingPathComponent Filename 참조]; // 디스크 좋은 기록 데이터를 다운로드 [self.fileData writeToFile 님에 원자 주위 fullpath에 : YES] NSLog ( @ " 적인 filePath = % @ " , fullpath에) } - (NSMutableData * ) FILEDATA { IF ( ! _fileData) { _fileData = [NSMutableData, 데이터] } 리턴_fileData; }
당신은 위의 코드 부분을 수행하면 기능을 실현 할 수 있지만, 거기에 문제는, 메모리가 획기적으로 향상 될 것입니다. 이 문제를 해결하려면 데이터에 직접 얻을 샌드 박스를 작성,
다음과 같이 논리는 다음과 같습니다
// 파일 핸들 (포인터) NSFileHandle / * * 특징 : 쓰기 데이터 쓰기 데이터 위치를 이동하면서 때 의 단계를 사용하여 : (1) 빈 문서를 만들 (2) 파일 핸들에 파일 포인터를 만들 수 있습니다 (3) 수신 된 데이터를 핸들이 데이터를 기록 할 때 사용되는 모든 데이터가 끝나면 (4), 손잡이가 폐쇄되어야 포인터 / *
다음과 같이 개정 :
# import에 " ViewController.h " @ 인터페이스의 ViewController () <NSURLSessionDataDelegate> @property (비 원자, 할당) NSInteger totalSize 단계; @property (비 원자 할당) NSInteger currentSize을; @property (약한 비 원자) 함께 IBOutlet UIProgressView * progressView; @property (비 원자 강한) NSFileHandle * 핸들; @end @implementation의 ViewController - ( 무효 ) touchesBegan : (NSSet <UITouch *> *)는 withEvent 접촉 (의 UIEvent *) 이벤트 { // 1确定资源路径 NSURL URL * = [NSURL URLWithString : @ "http://meiye-mbs.oss-cn-shenzhen.aliyuncs.com/mbsFiles/0e3d0e4a0d5d4da5963e9e7617e8de101565841097849.mp4 " ]; // 2 요청 객체 생성 NSURLRequest 요청 * = [NSURLRequest requestWithURL : URL]을 // . 3 세션 객체가 생성된다 : 스레드 서브 스레드 처리에서, 기본 통과하지 NSURLSession 세션 * = [NSURLSession sessionWithConfiguration [NSURLSessionConfiguration defaultSessionConfiguration] 대리인 : 자기 delegateQueue는 [NSOperationQueue mainQueue]]; // 4는 다운로드 요구 태스크 생성 NSURLSessionDataTask * dataTask = [세션 dataTaskWithRequest : 요청] ; // 5 전송 요청 [dataTask 재개] } 의 #pragma 마크 - 프록시 방법 //응답 통화를 수신하면 - ( 무효 ) URLSession : (NSURLSession *) dataTask 세션 : (NSURLSessionDataTask *) dataTask didReceiveResponse : (NSURLResponse *) :( 응답 CompletionHandler의 무효 (^ ) (NSURLSessionResponseDisposition)) CompletionHandler를 { // 파일을 얻을 이름 : 헤더 정보가 권장 파일명에 응답 헤더 정보 획득 요청에 응답하여 얻어진 는 NSString * fileName에 = [반응 suggestedFileName]; // 파일 경로 접합 (샌드 경로 캐시 + 파일 이름)를 저장 는 NSString * 캐시 = [NSSearchPathForDirectoriesInDomains을 ( NSCachesDirectory, NSUserDomainMask, YES) lastObject]; // 다운로드 경로 는 NSString fullpath에 * = [캐시 stringByAppendingPathComponent Filename 참조] // (1)의 빈 파일을 작성 [[DefaultManager NSFileManager를] createFileAtPath : fullpath에 내용은 : 무 속성 : 무]; // (2) 파일에 파일 핸들 포인터를 만들 self.handle =을 [NSFileHandle fileHandleForWritingAtPath : fullpath에]; // 요청 된 데이터의 현재 파일 크기를 얻을 자체. = totalSize response.expectedContentLength; // 데이터 받아야하는 시스템을 말해 CompletionHandler (NSURLSessionResponseAllow을); } // 호출이 여러 번 호출 할 수있는 경우이 서버에 의해 반환 된 데이터를 수신 - ( 무효 ) URLSession : (NSURLSession *) 세션 dataTask을 :( * NSURLSessionDataTask) dataTask didReceiveData (을 NSData * ) 데이터 { [self.handle writeData는 : 데이터]; // 다운로드 데이터 / 파일의 전체 크기 = 다운로드 진행 파일을 계산하고 표시 self.currentSize + =data.length입니다; CGFloat 진행 = 1.0 * self.currentSize / self.totalSize, self.progressView.progress = 진행; NSLog ( @ " % F " , 진행); } // . 3 다운로드가 완료 또는 전화를 실패 - ( 무효 ) URLSession (NSURLSession *) 작업 세션 (NSURLSessionTask *) 작업 didCompleteWithError (NSError * ) 오류 { // . (4)의 모든 데이터가 완료되면, 핸들 포인터 닫아야 [self.handle CloseFile] }