基于NSURLSession 封裝的一個多線程斷點續(xù)傳下載Demo

最近工作不是很忙,表示最近也在一直的學習理論知識,但是光是單純的看書和看面試題崩掘,感覺有點大學期末考試的趕腳吼驶,所以還是想著要把理論和實踐多結合惩激,所以陸續(xù)把工作中的用到的東西整理成一個個Demo 這樣,和盡量的封裝一下子蟹演,這樣也算是平時的一點積累风钻。

首先是覺得可以把網(wǎng)絡的小模塊搞一搞,雖然AFN在ios界是神作酒请,地位不可動搖骡技,但是我們這還是不能單單只會AFN,必備的網(wǎng)絡知識還是要了解羞反,題外話圖解HTTP這本書還是很不錯的布朦,生動形象,簡單易懂的講解了網(wǎng)絡知識昼窗,強烈像我一樣半路出家的人看一看是趴,百度云鏈接。大神請繞行
廢話說了一筐還是直接說代碼吧澄惊,先看一下目錄結構

Demo目錄結構.png

其實東西很簡單唆途,主要就是實現(xiàn)一個多線程下載的功能,在DownloadManagment 類中有一個字典掸驱,每次調用下載的時候都會建立一個NSURLSessionDownloadTask 下載任務窘哈,然后以URL為Key 把他存到字典中,這樣這樣可以防止重復執(zhí)行下載任務亭敢,而且下載過程中可以暫停任務也就是支持斷點續(xù)傳滚婉,而且可以把執(zhí)行多個任務,還有在任務之間進行切換帅刀。不過之前源代碼實在不敢吐槽让腹,居然把下載的一些緩存啥的都存到了數(shù)據(jù)庫里远剩,感覺好突兀,所以自己改成了存成歸檔文件骇窍,怎么存都可以隨你喜歡啦瓜晤,只不過不喜歡那么搞而已。大概把功能說道這里腹纳,下面就是最激動人心的貼代碼時間痢掠。

首先是DownloadManagment類,負責對外管理類這么搞其實并說不清具體用到了什么設計模式嘲恍,只不過各個牛逼的框架都會這么用足画。

@interface DownloadManagment  ()

@property(nonatomic, strong)NSMutableDictionary *downloadDic;//把不同的任務都存到了這個字典里方便管理

@end

@implementation DownloadManagment
+ (instancetype)shareDownloadManagment
{
    static DownloadManagment *downloadManagment = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        downloadManagment = [[DownloadManagment alloc]init];
    });
    return downloadManagment;
}

// 初始化方法
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.downloadDic = [NSMutableDictionary dictionary];
    }
    return self;
}

// 根據(jù)URL添加一個下載類
- (Download *)addDownloadWithUrl:(NSString *)url
{
    // 先從字典里面取到對應的下載
    Download *download = self.downloadDic[url];
    if (download == nil) {// 如果字典里面沒有 我們就創(chuàng)建一個
        download = [[Download alloc]initWithURL:url];
        //添加到我們的字典當中
        [self.downloadDic setObject:download forKey:url];
    }
    // 下載完成以后 讓單例不再持有著下載類 從字典里面移除
    [download downloadCompleted:^(NSString *url) {
        [self.downloadDic removeObjectForKey:url];
        NSLog(@"下載完成");
    
    }];
    return download;
}

// 根據(jù)URL找到一個下載類
- (Download *)findDownloadWithURL:(NSString *)url
{
    return self.downloadDic[url];
}

// 返回所有正在下載的類
- (NSArray *)allDownlod
{
    return [self.downloadDic allValues];
}

其次是DownloadingManagment類,不知道原框架為什么會這么起佃牛,這其實就是一個Model累嘛淹辞,叫的人心都醉了。

@interface DownloadingManagment : NSObject<NSCoding>

@property(nonatomic, copy)NSString *resumeDataStr;

@property(nonatomic, copy)NSString *fileSize;

@property(nonatomic, copy)NSString *filePath;

@property(nonatomic, copy)NSString * progress;

@property(nonatomic, copy)NSString *url;

@property(nonatomic, copy)NSString * time;

@property(nonatomic, copy)NSString * DownLoadType;
@end

重頭戲是Download 類俘侠,所有的網(wǎng)絡有關的東西都在這個類里實現(xiàn)
最開始是初始化類

- (id)initWithURL:(NSString *)url
{
    self = [super init];
    if (self) {
        
//        + (NSURLSessionConfiguration *)defaultSessionConfiguration;
//        //返回標準配置象缀,這實際上與NSURLConnection的網(wǎng)絡協(xié)議棧是一樣的,具有相同的共享NSHTTPCookieStorage爷速,共享NSURLCache和共享NSURLCredentialStorage央星。
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        
        //設置請求超時為10秒鐘
        config.timeoutIntervalForRequest = 10;
        
        //在蜂窩網(wǎng)絡情況下是否繼續(xù)請求(上傳或下載)
        config.allowsCellularAccess = NO;
        
        
        self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        
//        創(chuàng)建任務,把配置的信息惫东,加到任務里莉给,然后開始執(zhí)行
        self.task = [_session downloadTaskWithURL:[NSURL URLWithString:url]];
        
        _url = url;
        
        // 先去數(shù)據(jù)庫中查找是否已經(jīng)下載了 如果已經(jīng)下載了 我們就把_isFirst賦值為yes 防止重復添加數(shù)據(jù)
        _isFirst =[self findDownloadingWithURL:url];
        
        if (_isFirst) {
            // 如果已經(jīng)下載了 我們更換我們的task
            self.task = [self.session downloadTaskWithResumeData:[self resumeDataWithURL:url]];
        } 
    }
    return self;
}

里面涉及到NSURLSessionConfiguration,具體的可以查看http://www.cnblogs.com/liugengqun/p/5140296.html 博客寫的很詳細 如何配置

接下來斷點續(xù)傳主要功能凿蒜,把下載了的

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSURLSessionDownloadURL</key> //資源的 URL
    <string>http://dlhjhx.xicp.net:13081/firmware/E302620170303.pkg</string>
    <key>NSURLSessionResumeBytesReceived</key>//錄下來了已經(jīng)下載完成的字節(jié)數(shù)
    <integer>68441</integer>
    <key>NSURLSessionResumeCurrentRequest</key>//當前請求時的 NSURLRequest 對象
    <data>
    YnBsaXN0MDDUAQIDBAUGdXZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
     //省略一萬字
    BcMF0AXTBeAF8gX1BhMAAAAAAAACAQAAAAAAAAB5AAAAAAAAAAAAAAAAAAAGFQ==
    </data>
    <key>NSURLSessionResumeEntityTag</key>
    <string>W/"492894-1488511050000"</string>
    <key>NSURLSessionResumeInfoTempFileName</key>//下載過程中臨時文件所存儲的位置,存儲在應用程序 tmp 文件夾下
    <string>CFNetworkDownload_kv1UKk.tmp</string>
    <key>NSURLSessionResumeInfoVersion</key>
    <integer>2</integer>
    <key>NSURLSessionResumeOriginalRequest</key>//初始請求時的 NSURLRequest 對象
    <data>
    YnBsaXN0MDDUAQIDBAUGUFFYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
    //省略一萬字
    BAwEEQQeBCEELgRABEMEYQAAAAAAAAIBAAAAAAAAAFQAAAAAAAAAAAAAAAAAAARj
    </data>
    <key>NSURLSessionResumeServerDownloadDate</key>
    <string>Fri, 03 Mar 2017 03:17:30 GMT</string>
</dict>
</plist>

每次啟動的時候如果遇到未下載完成的任務就會替換任務Data中的已下載的字節(jié)胁黑,然后繼續(xù)添加到任務重繼續(xù)執(zhí)行废封,這樣就可以執(zhí)行斷點續(xù)傳啦

/**
 恢復下載替換resumeDataStr 中生于的下載的字節(jié)

 @param url url description
 @return return value description
 */
- (NSData *)resumeDataWithURL:(NSString *)url
{
    // 1.找到下載中的model
    DownloadingManagment *downloading = [self findDownloadingWithURL:url];
    // 給progress賦初始值
    _progress = downloading.progress;
    NSLog(@"%@",downloading);
    // 2.獲取當前下載的文件
    NSFileManager *fm = [NSFileManager defaultManager];
    
    NSString *fileSize = [NSString stringWithFormat:@"%llu", [fm attributesOfItemAtPath:downloading.filePath error:nil].fileSize];
    
    // 3.對resumeDataStr進行替換
    downloading.resumeDataStr = [downloading.resumeDataStr stringByReplacingOccurrencesOfString:downloading.fileSize withString:fileSize];
    // 4.生成NSData進行返回
    
    return [downloading.resumeDataStr dataUsingEncoding:NSUTF8StringEncoding];
}

最后沒啥可說的了,下載完成后轉移數(shù)據(jù)啥的丧蘸,這玩意關鍵要根據(jù)實際的業(yè)務需求來啦漂洋,剩下的GitHub上有例子,有興趣的童鞋可以下載看一下力喷,我這水平有限刽漂,也就是拋磚引玉,大神請繞行弟孟。GitHub Demo

最后感慨最近體弱多病呀贝咙,藥加起來吃的是我N年的和呀,告誡大家要多強身健體呀拂募,我這體會到身體是革命的本錢庭猩,沒有好身體啥都搞不了窟她,如配圖呀,三月不努力蔼水,四月徒傷悲震糖,五月就沒臉見人啦。要個當一個能撐得起世界的男人

雙臂可以撐得起世界的男人
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末趴腋,一起剝皮案震驚了整個濱河市吊说,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌优炬,老刑警劉巖颁井,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異穿剖,居然都是意外死亡蚤蔓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門糊余,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秀又,“玉大人,你說我怎么就攤上這事贬芥⊥抡蓿” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵蘸劈,是天一觀的道長昏苏。 經(jīng)常有香客問我,道長威沫,這世上最難降的妖魔是什么贤惯? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮棒掠,結果婚禮上孵构,老公的妹妹穿的比我還像新娘。我一直安慰自己烟很,他們只是感情好颈墅,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雾袱,像睡著了一般恤筛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芹橡,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天毒坛,我揣著相機與錄音,去河邊找鬼林说。 笑死粘驰,一個胖子當著我的面吹牛屡谐,可吹牛的內容都是我干的。 我是一名探鬼主播蝌数,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼愕掏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了顶伞?” 一聲冷哼從身側響起饵撑,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唆貌,沒想到半個月后滑潘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡锨咙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年语卤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酪刀。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡粹舵,死狀恐怖,靈堂內的尸體忽然破棺而出骂倘,到底是詐尸還是另有隱情眼滤,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布历涝,位于F島的核電站诅需,受9級特大地震影響,放射性物質發(fā)生泄漏荧库。R本人自食惡果不足惜堰塌,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望分衫。 院中可真熱鬧场刑,春花似錦、人聲如沸丐箩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屎勘。三九已至,卻和暖如春居扒,著一層夾襖步出監(jiān)牢的瞬間概漱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工喜喂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓤摧,地道東北人竿裂。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像照弥,于是被迫代替她去往敵國和親腻异。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內容