¶ÏµãÐø´«¸ÅÊö
¶ÏµãÐø´«¾ÍÊÇ´ÓÎļþÉÏ´ÎÖжϵĵط½¿ªÊ¼ÖØÐÂÏÂÔØ»òÉÏ´«Êý¾Ý£¬¶ø²»ÊÇ´ÓÎļþ¿ªÍ·¡££¨±¾ÎĵĶϵãÐø´«½öÉæ¼°ÏÂÔØ£¬ÉÏ´«²»ÔÚÌÖÂÛÖ®ÄÚ£©µ±ÏÂÔØ´óÎļþµÄʱºò£¬Èç¹ûûÓÐʵÏֶϵãÐø´«¹¦ÄÜ£¬ÄÇôÿ´Î³öÏÖÒì³£»òÕßÓû§Ö÷¶¯µÄÔÝÍ££¬¶¼»áÈ¥ÖØÍ·ÏÂÔØ£¬ÕâÑùºÜÀË·Ñʱ¼ä¡£ËùÒÔÏîÄ¿ÖÐҪʵÏÖ´óÎļþÏÂÔØ£¬¶ÏµãÐø´«¹¦Äܾͱز»¿ÉÉÙÁË¡£µ±È»£¬¶ÏµãÐø´«ÓÐÒ»ÖÖÌØÊâµÄÇé¿ö£¬¾ÍÊÇ
iOS Ó¦Óñ»Óû§ kill µô»òÕßÓ¦Óà crash£¬ÒªÊµÏÖÓ¦ÓÃÖØÆôÖ®ºóµÄ¶ÏµãÐø´«¡£ÕâÖÖÌØÊâÇé¿öÊDZ¾ÎÄÒª½â¾öµÄÎÊÌâ¡£
¶ÏµãÐø´«ÔÀí
ҪʵÏֶϵãÐø´« , ·þÎñÆ÷±ØÐëÖ§³Ö¡£Ä¿Ç°×î³£¼ûµÄÊÇÁ½ÖÖ·½Ê½£ºFTP ºÍ HTTP¡£ÏÂÃæÀ´¼òµ¥½éÉÜ HTTP
¶ÏµãÐø´«µÄÔÀí¡£
HTTP
ͨ¹ý HTTP£¬¿ÉÒԷdz£·½±ãµÄʵÏֶϵãÐø´«¡£¶ÏµãÐø´«Ö÷ÒªÒÀÀµÓÚ HTTP Í·²¿¶¨ÒåµÄ Range À´Íê³É¡£¾ßÌå
Range µÄ˵Ã÷²Î¼û RFC2616ÖÐ 14.35.2 ½Ú£¬ÔÚÇëÇóij·¶Î§ÄÚµÄ×ÊԴʱ£¬¿ÉÒÔ¸üÓÐЧµØ¶Ô´ó×ÊÔ´·¢³öÇëÇó»ò´Ó´«Êä´íÎóÖлָ´ÏÂÔØ¡£ÓÐÁË
Range£¬Ó¦ÓÿÉÒÔͨ¹ý HTTP ÇëÇóÔø¾»ñȡʧ°ÜµÄ×ÊÔ´µÄijһ¸ö·µ»Ø»òÕßÊDz¿·Ö£¬À´»Ö¸´ÏÂÔØ¸Ã×ÊÔ´¡£µ±È»²¢²»ÊÇËùÓеķþÎñÆ÷¶¼Ö§³Ö
Range£¬µ«´ó¶àÊý·þÎñÆ÷ÊÇ¿ÉÒԵġ£Range ÊÇÒÔ×Ö½Ú¼ÆËãµÄ£¬ÇëÇóµÄʱºò²»±Ø¸ø³ö½áβ×Ö½ÚÊý£¬ÒòΪÇëÇó·½²¢²»Ò»¶¨ÖªµÀ×ÊÔ´µÄ´óС¡£Range
µÄ¶¨ÒåÈçͼ 1 Ëùʾ£º
ͼ 1. HTTP-Range

ͼ 2 չʾÁË HTTP request µÄÍ·²¿ÐÅÏ¢£º
ͼ 2. HTTP request Àý×Ó

ÔÚÉÏÃæµÄÀý×ÓÖеġ°Range: bytes=1208765-¡±±íʾÇëÇó×ÊÔ´¿ªÍ· 1208765 ×Ö½ÚÖ®ºóµÄ²¿·Ö¡£
ͼ 3 չʾÁË HTTP response µÄÍ·²¿ÐÅÏ¢£º
ͼ 3. HTTP response Àý×Ó

ÉÏÃæÀý×ÓÖеġ±Accept-Ranges: bytes¡±±íʾ·þÎñÆ÷¶Ë½ÓÊÜÇëÇó×ÊÔ´µÄijһ¸ö·¶Î§£¬²¢ÔÊÐí¶ÔÖ¸¶¨×ÊÔ´½øÐÐ×Ö½ÚÀàÐÍ·ÃÎÊ¡£¡±Content-Range:
bytes 1208765-20489997/20489998¡±ËµÃ÷ÁË·µ»ØÌṩÁËÇëÇó×ÊÔ´ËùÔÚµÄÔʼʵÌåÄÚµÄλÖ㬻¹¸ø³öÁËÕû¸ö×ÊÔ´µÄ³¤¶È¡£ÕâÀïÐèҪעÒâµÄÊÇ
HTTP return code ÊÇ 206 ¶ø²»ÊÇ 200¡£
¶ÏµãÐø´«·ÖÎö -AFHTTPRequestOperation
Á˽âÁ˶ϵãÐø´«µÄÔÀíÖ®ºó£¬ÎÒÃǾͿÉÒÔ¶¯ÊÖÀ´ÊµÏÖ iOS Ó¦ÓÃÖеĶϵãÐø´«ÁË¡£ÓÉÓÚ±ÊÕßÏîÄ¿µÄ×ÊÔ´¶¼ÊDz¿ÊðÔÚ
HTTP ·þÎñÆ÷ÉÏ , ËùÒԶϵãÐø´«¹¦ÄÜÒ²ÊÇ»ùÓÚ HTTP ʵÏֵġ£Ê×ÏÈÀ´¿´ÏµÚÈý·½ÍøÂç¿ò¼Ü AFNetworking
ÖÐÌṩµÄʵÏÖ¡£Çåµ¥ 1 ʾÀý´úÂëÊÇÓÃÀ´ÊµÏֶϵãÐø´«²¿·ÖµÄ´úÂ룺
Çåµ¥ 1. ʹÓà AFHTTPRequestOperation ʵÏֶϵãÐø´«µÄ´úÂë
// 1 Ö¸¶¨ÏÂÔØÎļþµØÖ· URLString // 2 »ñÈ¡±£´æµÄÎļþ·¾¶ filePath // 3 ´´½¨ NSURLRequest NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]]; unsigned long long downloadedBytes = 0;
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// 3.1 Èô֮ǰÏÂÔØ¹ý , ÔòÔÚ HTTP ÇëÇóÍ·²¿¼ÓÈë Range
// »ñÈ¡ÒÑÏÂÔØÎļþµÄ size
downloadedBytes = [self fileSizeForPath:filePath];
// ÑéÖ¤ÊÇ·ñÏÂÔØ¹ýÎļþ
if (downloadedBytes > 0) {
// ÈôÏÂÔØ¹ý , ¶ÏµãÐø´«µÄʱºòÐÞ¸Ä HTTP Í·²¿²¿·ÖµÄ Range
NSMutableURLRequest *mutableURLRequest = [request
mutableCopy];
NSString *requestRange =
[NSString stringWithFormat:@"bytes=%llu-",
downloadedBytes];
[mutableURLRequest setValue:requestRange forHTTPHeaderField:@"Range"];
request = mutableURLRequest;
}
}
// 4 ´´½¨ AFHTTPRequestOperation
AFHTTPRequestOperation *operation
= [[AFHTTPRequestOperation alloc] initWithRequest:request];
// 5 ÉèÖòÙ×÷Êä³öÁ÷ , ±£´æÔÚµÚ 2 ²½µÄÎļþÖÐ
operation.outputStream = [NSOutputStream
outputStreamToFileAtPath:filePath append:YES];
// 6 ÉèÖÃÏÂÔØ½ø¶È´¦Àí block
[operation setDownloadProgressBlock:^(NSUInteger
bytesRead,
long long totalBytesRead, long long totalBytesExpectedToRead)
{
// bytesRead µ±Ç°¶ÁÈ¡µÄ×Ö½ÚÊý
// totalBytesRead ¶ÁÈ¡µÄ×Ü×Ö½ÚÊý , °üº¬¶ÏµãÐø´«Ö®Ç°µÄ
// totalBytesExpectedToRead Îļþ×Ü´óС
}];
// 7 ÉèÖà success ºÍ failure ´¦Àí block
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation
*operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation,
NSError *error) {
}];
// 8 Æô¶¯ operation
[operation start]; |
ʹÓÃÒÔÉÏ´úÂë , ¶ÏµãÐø´«¹¦ÄܾÍʵÏÖÁË£¬Ó¦ÓÃÖØÐÂÆô¶¯»òÕß³öÏÖÒì³£Çé¿öÏ , ¶¼¿ÉÒÔ»ùÓÚÒѾÏÂÔØµÄ²¿·Ö¿ªÊ¼¼ÌÐøÏÂÔØ¡£¹Ø¼üµÄµØ·½¾ÍÊǰÑÒѾÏÂÔØµÄÊý¾Ý³Ö¾Ã»¯¡£½ÓÏÂÀ´¼òµ¥¿´ÏÂ
AFHTTPRequestOperation ÊÇÔõôʵÏֵġ£Í¨¹ý²é¿´Ô´Âë , ÎÒÃÇ·¢ÏÖ AFHTTPRequestOperation
¼Ì³Ð×Ô AFURLConnectionOperation , ¶ø AFURLConnectionOperation
ʵÏÖÁË NSURLConnectionDataDelegate ÐÒé¡£´¦ÀíÁ÷³ÌÈçͼ 4 Ëùʾ£º
ͼ 4. AFURLHTTPrequestOperation ´¦ÀíÁ÷³Ì

ÕâÀï AFNetworking Ϊʲô²ÉÈ¡×ÓÏ̵߳÷Òì²½½Ó¿ÚµÄ·½Ê½ , ÊÇÒòΪֱ½ÓÔÚÖ÷Ï̵߳÷ÓÃÒì²½½Ó¿Ú
, »áÓÐÒ»¸ö Runloop µÄÎÊÌâ¡£µ±Ö÷Ï̵߳÷Óà [[NSURLConnection alloc] initWithRequest:request
delegate:self startImmediately:YES] ʱ , ÇëÇó·¢³öÖ®ºóµÄ¼àÌýÈÎÎñ»á¼ÓÈëµ½Ö÷Ï̵߳Ä
Runloop ÖÐ ,RunloopMode ĬÈÏΪ NSDefaultRunLoopMode, Õâ¸ö±íʾֻÓе±Ç°Ï̵߳Ä
Runloop ´¦Àí NSDefaultRunLoopMode ʱ£¬Õâ¸öÈÎÎñ²Å»á±»Ö´ÐС£¶øµ±Óû§ÔÚ¹ö¶¯
TableView ºÍ ScrollView µÄʱºò£¬Ö÷Ïß³ÌµÄ Runloop ´¦ÓÚ NSEventTrackingRunLoop
ģʽÏ£¬¾Í²»»áÖ´ÐÐ NSDefaultRunLoopMode µÄÈÎÎñ¡£
ÁíÍâÓÉÓÚ²ÉÈ¡×ÓÏ̵߳÷Óýӿڵķ½Ê½ , ËùÒÔÕâ±ßµÄ DownloadProgressBlock,success
ºÍ failure Block ¶¼ÐèÒª»Øµ½Ö÷Ïß³ÌÀ´´¦Àí¡£
¶ÏµãÐø´«ÊµÕ½
Á˽âÁËÔÀíºÍ AFHTTPRequestOperation µÄÀý×ÓÖ®ºó , À´¿´ÏÂʵÏֶϵãÐø´«µÄÈýÖÖ·½Ê½£º
NSURLConnection
»ùÓÚ NSURLConnection ʵÏֶϵãÐø´« , ¹Ø¼üÊÇÂú×ã NSURLConnectionDataDelegate
ÐÒ飬Ö÷ҪʵÏÖÁËÈçÏÂÈý¸ö·½·¨£º
Çåµ¥ 2. NSURLConnection µÄʵÏÖ
// SWIFT // ÇëÇóʧ°Ü´¦Àí func connection(connection: NSURLConnection, didFailWithError error: NSError) { self.failureHandler(error: error) }
// ½ÓÊÕµ½·þÎñÆ÷ÏìÓ¦Êǵ÷ÓÃ
func connection(connection: NSURLConnection,
didReceiveResponse response: NSURLResponse) {
if self.totalLength != 0 {
return
}
self.writeHandle = NSFileHandle(forWritingAtPath:
FileManager.instance.cacheFilePath(self.fileName!))
self.totalLength = response.expectedContentLength
+ self.currentLength
}
// µ±·þÎñÆ÷·µ»ØÊµÌåÊý¾ÝÊǵ÷ÓÃ
func connection(connection: NSURLConnection, didReceiveData
data: NSData) {
let length = data.length
// move to the end of file
self.writeHandle.seekToEndOfFile()
// write data to sanbox
self.writeHandle.writeData(data)
// calculate data length
self.currentLength = self.currentLength + length
print("currentLength\(self.currentLength)-totalLength\(self.totalLength)")
if (self.downloadProgressHandler != nil) {
self.downloadProgressHandler(bytes: length, totalBytes:
self.currentLength, totalBytesExpected: self.totalLength)
}
}
// ÏÂÔØÍê±Ïºóµ÷ÓÃ
func connectionDidFinishLoading(connection: NSURLConnection)
{
self.currentLength = 0
self.totalLength = 0
//close write handle
self.writeHandle.closeFile()
self.writeHandle = nil
let cacheFilePath = FileManager.instance.cacheFilePath(self.fileName!)
let documenFilePath = FileManager.instance.documentFilePath(self.fileName!)
do {
try FileManager.instance.moveItemAtPath(cacheFilePath,
toPath: documenFilePath)
} catch let e as NSError {
print("Error occurred when to move file:
\(e)")
}
self.successHandler(responseObject:fileName!)
} |
Èçͼ 5 Ëùʾ , ˵Ã÷ÁË NSURLConnection µÄÒ»°ã´¦ÀíÁ÷³Ì¡££¨´úÂëÏê¼ûÏÂÔØ°ü£©
ͼ 5. NSURLConnection
Á÷³Ì

¸ù¾Ýͼ 5 µÄÒ»°ãÁ÷³Ì£¬ÔÚ didReceiveResponse Öгõʼ»¯ fileHandler,
ÔÚ didReceiveData ÖÐ , ½«½ÓÊÕµ½µÄÊý¾Ý³Ö¾Ã»¯µÄÎļþÖÐ , ÔÚ connectionDidFinishLoading
ÖУ¬Çå¿ÕÊý¾ÝºÍ¹Ø±Õ fileHandler£¬²¢½«Îļþ±£´æµ½ Document Ŀ¼Ï¡£ËùÒÔµ±ÇëÇó³öÏÖÒì³£»òÓ¦Óñ»Óû§É±µô£¬¶¼¿ÉÒÔͨ¹ý³Ö¾Ã»¯µÄÖмäÎļþÀ´¶ÏµãÐø´«¡£³õʼ»¯
NSURLConnection µÄʱºòҪעÒâÉèÖà scheduleInRunLoop Ϊ NSRunLoopCommonModes£¬²»È»¾Í»á³öÏÖ½ø¶ÈÌõ
UI ÎÞ·¨¸üеÄÏÖÏó¡£ÊµÏÖЧ¹ûÈçͼ 6 Ëùʾ£º
ͼ 6. NSURLConnection
ÑÝʾ

NSURLSessionDataTask
Æ»¹ûÔÚ iOS7 ¿ªÊ¼£¬ÍƳöÁËÒ»¸öеÄÀà NSURLSession, Ëü¾ß±¸ÁË NSURLConnection
Ëù¾ß±¸µÄ·½·¨£¬²¢ÇÒ¸üÇ¿´ó¡£ÓÉÓÚͨ¹ý NSURLConnection ´Ó 2015 Ä꿪ʼ±»ÆúÓÃÁË£¬ËùÒÔ¶ÁÕßÍÆ¼ö»ùÓÚ
NSURLSession ȥʵÏÖÐø´«¡£NSURLConnection ºÍ NSURLSession delegate
·½·¨µÄÓ³Éä¹ØÏµ , Èçͼ 7 Ëùʾ¡£ËùÒԹؼüÊÇÒªÂú×ã NSURLSessionDataDelegate
ºÍ NSURLsessionTaskDelegate¡£
ͼ 7. ÐÒéÖ®¼äÓ³Éä¹ØÏµ

´úÂëÈçÇåµ¥ 3 Ëùʾ , »ù±¾ºÍ NSURLConnection ʵÏÖµÄÒ»Ñù¡£
Çåµ¥ 3. NSURLSessionDataTask µÄʵÏÖ
// SWIFT // ½ÓÊÕÊý¾Ý func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, idReceiveData data: NSData) { //. . . } // ½ÓÊÕ·þÎñÆ÷ÏìÓ¦ func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { // . . . completionHandler(.Allow) }
// ÇëÇóÍê³É
func URLSession(session: NSURLSession, task: NSURLSessionTask,
didCompleteWithError error: NSError?) {
if error == nil {
// . . .
self.successHandler(responseObject:self.fileName!)
} else {
self.failureHandler(error:error!)
}
} |
Çø±ðÔÚÓë didComleteWithError, Ëü½« NSURLConnection ÖÐµÄ connection:didFailWithError:
ºÍ connectionDidFinishLoading: ÕûºÏµ½ÁËÒ»Æð , ËùÒÔÕâ±ßÒª¸ù¾Ý error
Çø·ÖÖ´Ðгɹ¦µÄ Block ºÍʧ°ÜµÄ Block¡£ÊµÏÖЧ¹ûÈçͼ 8 Ëùʾ£º
ͼ 8. NSURLSessionDataTask
ÑÝʾ

NSURLSessionDownTask
×îºóÀ´¿´Ï NSURLSession ÖÐÓÃÀ´ÏÂÔØµÄÀà NSURLSessionDownloadTask£¬¶ÔÓ¦µÄÐÒéÊÇ
NSURLSessionDownloadDelegate£¬Èçͼ 9 Ëùʾ£º
ͼ 9. NSURLSessionDownloadDelegate
ÐÒé

ÆäÖÐÔÚÍ˳ö didFinishDownloadingToURL ºó£¬»á×Ô¶¯É¾³ý temp Ŀ¼Ï¶ÔÓ¦µÄÎļþ¡£ËùÒÔÓйØÎļþ²Ù×÷±ØÐëÒªÔÚÕâ¸ö·½·¨ÀïÃæ´¦Àí¡£Ö®Ç°±ÊÕßÔøÏëÕÒµ½Õâ¸ö
tmp Îļþ , »ùÓÚÕâ¸öÎļþ×ö¶ÏµãÐø´« , ÎÞÄÎÒ»Ö±ÕÒ²»µ½Õâ¸öÎļþµÄ·¾¶¡£µÈÒÔºó SWIFT ¹«²¼ NSURLSession
µÄÔ´ÂëÖ®ºó£¬ÐËÐí»áÓз½·¨ÕÒµ½¡£»ùÓÚ NSURLSessionDownloadTask À´ÊµÏֵϰ , ÐèÒªÔÚ
cancelByProducingResumeData Öб£´æÒѾÏÂÔØµÄÊý¾Ý¡£½ø¶È֪ͨ¾Í·Ç³£¼òµ¥ÁË£¬Ö±½ÓÔÚ
URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:
ʵÏÖ¼´¿É¡£´úÂëÈçÇåµ¥ 4 Ëùʾ£º
Çåµ¥ 4. NSURLSessionDownloadTask µÄʵÏÖ
//SWIFT
//UI ´¥·¢ pause
func pause(){
self.downloadTask?.cancelByProducingResumeData({data
-> Void in
if data != nil {
data!.writeToFile(FileManager.instance.cacheFilePath(self.fileName!),
atomically: false)
}
})
self.downloadTask = nil
}
// MARK: - NSURLSessionDownloadDelegate
func URLSession(session: NSURLSession, downloadTask:
NSURLSessionDownloadTask, didWriteData bytesWritten:
Int64,
totalBytesWritten: Int64, totalBytesExpectedToWrite:
Int64) {
if (self.downloadProgressHandler != nil) {
self.downloadProgressHandler(bytes: Int(bytesWritten),
totalBytes: totalBytesWritten, totalBytesExpected:
totalBytesExpectedToWrite)
}
}
func URLSession(session: NSURLSession, task:
NSURLSessionTask,
didCompleteWithError error: NSError?) {
if error != nil {//real error
self.failureHandler(error:error!)
}
}
func URLSession(session: NSURLSession, downloadTask:
NSURLSessionDownloadTask,
didFinishDownloadingToURL location: NSURL) {
let cacheFilePath = FileManager.instance.cacheFilePath(self.fileName!)
let documenFilePath = FileManager.instance.documentFilePath(self.fileName!)
do {
if FileManager.instance.fileExistsAtPath(cacheFilePath){
try FileManager.instance.removeItemAtPath(cacheFilePath)
}
try FileManager.instance.moveItemAtPath(location.path!,
toPath: documenFilePath)
} catch let e as NSError {
print("Error occurred when to move file:
\(e)")
}
self.successHandler(responseObject:documenFilePath)
} |
ʵÏÖЧ¹ûÈçͼ 10 Ëùʾ£º
ͼ 10. NSURLSessionDownloadTask
ÑÝʾ

×ܽá
±¾ÎĴӶϵãÐø´«¸ÅÊö¿ªÊ¼£¬½éÉÜÁ˶ϵãÐø´«µÄÓ¦Óñ³¾°£¬Í¨¹ýÔÀíµÄÃèÊö£¬ÏàÐŶÁÕ߶ԶϵãÐø´«ÓÐÁË»ù±¾µÄÈÏʶºÍÀí½â¡£½Ó×űÊÕß½éÉÜÁËͨ¹ý
AFHTTPRequestOpeartion ʵÏֵĴúÂ룬²¢¶Ô AFHTTPRequestOpeartion
×öÁ˼òµ¥µÄ·ÖÎö¡£×îºó±ÊÕß½áºÏµÄʵ¼ÊÐèÇ󣬻ùÓÚ NSURLConnection, NSURLSeesionDataTask
ºÍ NSURLSessionDownloadtask¡£Æäʵ£¬ÏÂÔØµÄʵÏÖÔ¶²»Ö¹ÕâЩÄÚÈÝ£¬±¾ÎÄÖ»½éÉÜÁ˼òµ¥µÄʹÓá£Ï£ÍûÔÚ½øÒ»²½µÄѧϰºÍÓ¦ÓÃÖÐÄܼÌÐøÓë´ó¼Ò·ÖÏí¡£ |