開源一個封裝AFNetworking的網路框架 - SJNetwork

J_Knight_發表於2017-12-27

介紹

該框架是一個通用的網路層,可以供給不同app的業務層呼叫。該框架封裝了AFNetworking,而且有些地方借鑑了YTKNetwork的設計思路:以物件的形式封裝並管理請求。

它在功能上支援:

  • 傳送請求方法為GET,POST,PUT,DELETE的普通網路請求的功能
  • 上傳圖片功能(單張與多張上傳,指定上傳前的圖片壓縮比率)
  • 下載功能(支援斷點續傳和後臺下載)
  • 快取管理(寫入,讀取,清除快取,計算大小)功能
  • 請求管理(檢視正在進行的請求的狀態,請求的單個與批量取消)功能
  • 設定請求體裡的預設鍵值對(eg.需要新增版本號進行版本控制)
  • 新增請求頭(eg.針對一些需要使用token的服務)
  • 設定伺服器地址
  • 設定debug模式(除錯時列印出便於除錯的log,比如讀取快取失敗的具體原因)

GitHub連結:SJNetwork

專案裡面附有demo:SJNetworkDemo專案資料夾

架構

在看架構圖之前,先簡單介紹一下該框架裡每個類的職責:

職責劃分

類名 職責
SJNetwork 總標頭檔案,只需要引入該檔案即可使用該框架所有功能
SJNetworkProtocol 定製了請求結束後的處理方法,今後可能還會擴充套件
SJNetworkHeader 定義了回撥block和一些列舉型別
SJNetworkManager 與業務層直接對接的類,包含了除配置介面外所有關於網路請求功能的介面
SJNetworkBaseEngine 所有負責傳送請求類的基類
SJNetworkRequestEngine 傳送(GET,POST,PUT,DELETE)請求的類:支援設定快取有效期,讀,寫和清理快取
SJNetworkUploadEngine 傳送上傳請求的類:支援設定圖片型別和壓縮上傳,批量上傳
SJNetworkDownloadEngine 傳送下載請求的類:支援斷點續傳和後臺下載
SJNetworkRequestModel 請求物件類:持有某個網路請求的一些資料;比如請求url,請求體等)
SJNetworkCacheManager 快取處理類:快取的寫入,讀取,刪除
SJNetworkConfig 配置類:配置伺服器地址,debug模式等
SJNetworkUtils 工具類:可以用於生成快取路徑,app版本號等
SJNetworkRequestPool 請求物件池:用於存放正在進行的請求物件
SJNetworkCacheInfo 快取後設資料:記錄其對應快取資料的資訊(版本號,快取過期時間)
SJNetworkDownloadResumeDataInfo 未下載完成資料的後設資料:記錄未下載完成資料的資訊(已經下載的比例,下載資料的總長度,已經下載資料的長度)

架構圖

architecture

從架構圖中可以看出:

  • 業務方呼叫SJNetworkManager的介面來傳送請求(或進行操作請求等操作),而實際進行工作的類其實是SJNetworkRequestEngine,SJNetworkUploadEngine,SJNetworkDownloadEngineSJNetworkCacheManager這些類。
  • 所有的請求都會被封裝成一個SJNetworkRequestModel例項來管理,其管理者為SJNetworkRequestPool
  • 在該框架內,SJNetworkConfigSJNetworkUtils是可以在任意地方呼叫的,因為要經常獲取使用者所做的一些配置以及呼叫一些常用的工具類方法。

使用方法

Step1:下載與匯入框架

通過Cocoa pods:

pod 'SJNetwork'

最新的版本號為1.2.0

或者 手動將 SJNetwork資料夾拖入到工程裡面。

Step2:引入標頭檔案:

如果是使用了Cocoapods:

import <SJNetwork/SJNetwork.h>
複製程式碼

如果是手動拖入:

#import "SJNetwork.h"
複製程式碼

功能介紹

基本的配置

因為配置物件是一個單例(SJNetworkConfig),所以可以在專案任何地方來使用。看一下該框架支援哪些配置項:

伺服器地址:

[SJNetworkConfig sharedConfig].baseUrl = @"http://v.juhe.cn";
複製程式碼

預設引數:

[SJNetworkConfig sharedConfig].defailtParameters = @{@"app_version":[SJNetworkUtils appVersionStr],
                                                        @"platform":@"iOS"};
複製程式碼

預設引數會拼接在所有請求的請求體中;

如果是GET請求,則拼接在url裡面。

超時時間:

[SJNetworkConfig sharedConfig].timeoutSeconds = 30;
複製程式碼

超時時間預設為20s。

Debug模式:

[SJNetworkConfig sharedConfig].debugMode = YES;//預設為NO
複製程式碼

如果設定debug模式為YES,則會列印出很多詳細的log,便於除錯。

如果設定為NO,則沒有log。

新增請求頭鍵值對:

[[SJNetworkConfig sharedConfig] addCustomHeader:@{@"token":@"2j4jd9s74bfm9sn3"}];
複製程式碼

或者

[[SJNetworkManager sharedManager] addCustomHeader:@{@"token":@"2j4jd9s74bfm9sn3"}];//實際上呼叫了SJNetworkConfig的addCustomHeader方法
複製程式碼

新增的請求頭鍵值對會自動新增到所有的請求頭中;

如果鍵值對原來不存在,則新增;如果原來存在,則替換原有的。

普通網路請求

在這裡定義GET,POST,PUT,DELETE請求為普通的網路請求,是由SJNetworkRequestManager實現的。所有的這些普通的網路請求都支援寫入和讀取快取,但是預設是不支援的,由使用者來決定是否寫入,讀取快取。

傳送一個不支援寫入和讀取快取的POST請求:

[[SJNetworkManager sharedManager] sendPostRequest:@"toutiao/index"
                                       parameters:@{@"type":@"top",
                                                    @"key" :@"0c60"}
                                          success:^(id responseObject) {

      NSLog(@"request succeed:%@",responseObject);

  } failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode) {

      NSLog(@"request failed:%@",error);
  }];
複製程式碼

傳送一個支援寫入有效時間為180秒並在快取有效時讀取快取的POST請求:

[[SJNetworkManager sharedManager] sendPostRequest:@"toutiao/index"
                                       parameters:@{@"type":@"top",
                                                    @"key" :@"0c60"}
                                        loadCache:YES
                                    cacheDuration:180
                                          success:^(id responseObject) {

     NSLog(@"request succeed:%@",responseObject);

 } failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode) {

     NSLog(@"request failed:%@",error);
 }];
複製程式碼

cacheDuration:快取有效的時間,單位為秒。

  • 如果大於0,則進行快取。
  • 如果小於等於0,則不進行快取。

loadCache:如果設定為YES,則在發起請求前,先檢視是否快取有效(如果設定為NO,則無論有沒有快取,都進行網路請求):

  • 如果快取存在並有效,則返回快取,不進行網路請求;
  • 如果快取不存在,或者存在但失效(時間過期)則刪除快取(如果快取存在)並進行網路請求。

完整的帶有快取判斷的普通網路請求的流程圖:

request

快取管理

快取管理是由SJNetworkCacheManager的單例來實現的,功能分為快取的讀取,刪除和計算。先來看一下快取的讀取:

快取的讀取

該框架支援單個快取的讀取和多個快取的讀取:

  • 單個快取的讀取只返回某個快取物件(字典,或陣列)或nil。
  • 多個快取的讀取返回的是一個陣列或nil。

單個快取的讀取:

如果知道這個快取對應的請求url,method,請求體,就能嘗試獲取它所對應的快取物件:

舉個例子,如果想獲取上面有寫入快取的網路請求的快取,就可以用如下API:

[[SJNetworkManager sharedManager] loadCacheWithUrl:@"toutiao/index"
                                            method:@"POST"
                                        parameters:@{@"type":@"top",
                                                   @"key" :@"0c60"}
                                   completionBlock:^(id  _Nullable cacheObject) {
                               
    NSLog(@"%@",cacheObject);
                               
}];
複製程式碼

注意,在快取的讀取過程中會有以下幾種情況:

  • 如果這個請求對應的快取不存在,則會從block裡傳過來nil。

  • 如果這個請求對應的快取存在,但是失效了(有效期過了),則這個快取就會被清除掉,並會在block裡傳過來nil。

  • 如果這個請求對應的快取存在並有效,則會從block裡傳過來快取物件。

多個快取的讀取:

如果有些請求使用的是同一個url(但是不同的請求方法或者引數)並做了快取,那麼通過如下方法可以獲取它們的快取:

[[SJNetworkManager sharedManager] loadCacheWithUrl:@"toutiao/index"
                                   completionBlock:^(NSArray * _Nullable cacheArr) {
    NSLog(@"%@",cacheArr);
}];
複製程式碼

如果有些請求使用的是同一個url以及請求方法,但是請求引數不同,那麼通過如下方法可以獲取它們的快取(用陣列儲存):

[[SJNetworkManager sharedManager] loadCacheWithUrl:@"toutiao/index"
                                            method:@"POST"
                                   completionBlock:^(NSArray * _Nullable cacheArr) {
     NSLog(@"%@",cacheArr);
}];
複製程式碼

現在我們知道這個框架在快取的讀取上支援單個與批量讀取,接下來看一下快取的刪除:

快取的刪除

同樣地,該框架也支援快取的單個與批量刪除。

如果你想刪除屬於某個特定url,method,請求引數的請求的快取,可以使用下面這個API:

[[SJNetworkManager sharedManager] clearCacheWithUrl:@"toutiao/index"
                                             method:@"POST"
                                         parameters:@{@"type":@"top",
                                                      @"key" :@"0c60"}
                                    completionBlock:^(BOOL isSuccess) {

     if (isSuccess) {
       NSLog(@"Clearing cache successfully!");
     }
}];
複製程式碼

如果你想刪除使用的是同一個url(但是不同的請求方法或者引數)的請求的快取,可以使用下面這個API:

[[SJNetworkManager sharedManager] clearCacheWithUrl:@"toutiao/index"
                                    completionBlock:^(BOOL isSuccess) {

     if (isSuccess) {
       NSLog(@"Clearing cache successfully!");
     }
}];
複製程式碼

如果你想刪除使用同一個url和method,但是不同請求引數的的請求的快取,可以使用下面這個API:

[[SJNetworkManager sharedManager] clearCacheWithUrl:@"toutiao/index"
                                             method:@"POST"
                                withCompletionBlock:^(BOOL isSuccess) {
     if (isSuccess) {
        NSLog(@"Clearing cache successfully!");
     }
  }];
複製程式碼

看完了快取的讀取和刪除,我們來看一下快取的計算:

快取的計算

快取的計算只提供了一個介面,在block回撥的時候會回傳一個檔案個數,所有快取的大小,以及帶有KB或MB的字串:

[[SJNetworkManager sharedManager] calculateCacheSizeWithCompletionBlock:^(NSUInteger fileCount, NSUInteger totalSize, NSString *totalSizeString) {
        
        NSLog(@"file count :%lu and total size:%lu total size string:%@",(unsigned long)fileCount,(unsigned long)totalSize, totalSizeString);
 }];
複製程式碼

fileCount:快取檔案的個數,為整數

total size:單位為位元組

totalSizeString:帶有KB和MB轉化的字串:在1024*1024位元組以內以KB為單位;以外以MB為單位。例如:file count :5 and total size:1298609 total size string:1.2385 MB

**注意:**所計算的快取包括所有普通請求的快取以及未下載完成,以後需要繼續下載的資料。

上傳功能

上傳圖片的功能是由SJNetworkUploadManager`類的單例實現的:支援上傳單個與多個UIImage``物件,可以設定壓縮比率(不設定時預設為1,不壓縮)。

單張圖片,原圖上傳

上傳單個UIImage物件,上傳前不對圖片進行壓縮:

[[SJNetworkManager sharedManager]  sendUploadImageRequest:@"api"
                                               parameters:nil
                                                    image:image_1
                                                     name:@"color"
                                                 mimeType:@"png"
                                                 progress:^(NSProgress *uploadProgress) 
{

    self.progressView.observedProgress = uploadProgress;

} success:^(id responseObject) {

    NSLog(@"upload succeed");

} failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode, NSArray<UIImage *> *uploadFailedImages) {

    NSLog(@"upload failed, failed images:%@",uploadFailedImages);

}];
複製程式碼

多張圖片,壓縮一半

上傳多個UIImage物件,壓縮比率為0.5:

[[SJNetworkManager sharedManager]  sendUploadImagesRequest:@"api"
                                                parameters:nil
                                                    images:@[image_1,image_2]
                                             compressRatio:0.5
                                                      name:@"images"
                                                  mimeType:@"jpg"
                                                  progress:^(NSProgress *uploadProgress) 
{

    self.progressView.observedProgress = uploadProgress;

} success:^(id responseObject) {

    NSLog(@"upload succeed");

} failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode, NSArray<UIImage *> *uploadFailedImages) {

    NSLog(@"upload failed, failed images:%@",uploadFailedImages);
}];
複製程式碼

這裡的mimeType可以設定為jpg/JPG, png/PNG, jpeg/JPEG,作為圖片上傳到伺服器時的型別。需要注意的是,如果mimeType為png/PNG的時候,設定的壓縮比率就是無效的,將會一定以原圖大小上傳。

忽略設定過的BaseUrl

考慮到上傳圖片的伺服器可能與普通請求的伺服器不同,特意增加了一個引數:ignoreBaseUrl。如果該布林值設定為YES,則在SJNetworkConfig單例裡面設定的baseUrl就會被忽略掉,使用者需要在請求的第一個引數裡面將完整的請求url寫進去:

[[SJNetworkManager sharedManager]  sendUploadImagesRequest:@"http://uploads.im/api"
                                               ignoreBaseUrl:YES
                                                  parameters:nil
                                                      images:@[image_1,image_2]
                                               compressRatio:0.5
                                                        name:@"images"
                                                    mimeType:@"jpg"
                                                    progress:^(NSProgress *uploadProgress) 
  {

      self.progressView.observedProgress = uploadProgress;

  } success:^(id responseObject) {

      NSLog(@"upload succeed");

  } failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode, NSArray<UIImage *> *uploadFailedImages) {

      NSLog(@"upload failed, failed images:%@",uploadFailedImages);

  }];
複製程式碼

還有一個方法,就是強制更改SJNetworkConfig單例設定的baseUrl:

[SJNetworkConfig sharedConfig].baseUrl = @"http://uploads.im";
[[SJNetworkManager sharedManager]  sendUploadImagesRequest:@"api"
                                             ignoreBaseUrl:NO
                                                parameters:nil
                                                    images:@[image_3,image_4]
                                             compressRatio:0.5
                                                      name:@"color"
                                                  mimeType:@"png"
                                                  progress:^(NSProgress *uploadProgress) 
{

    self.progressView.observedProgress = uploadProgress;

} success:^(id responseObject) {

    NSLog(@"upload succeed");

} failure:^(NSURLSessionTask *task, NSError *error, NSInteger statusCode, NSArray<UIImage *> *uploadFailedImages) {

    NSLog(@"upload failed, failed images:%@",uploadFailedImages);

}];
複製程式碼

雖然看上去不是很優雅,但卻也是可行的:在請求所有普通網路請求之前將baseUrl再次改回去即可。

暫時該框架還無法支援多個baseUrl的功能,以後如果有研究到的話就會新增上去。

下載功能

下載功能是由SJNetworkDownloadManager的單例來實現的,支援斷點續傳以及後臺下載。

  • 如果設定為支援後臺下載,則在內部生成的task類為:NSURLSessionDownloadTask。在手機退出前臺,進入後臺後後仍然可以下載。
  • 如果設定為不支援後臺下載,則在內部生成的task類為:NSURLSessionDataTask。在手機退出前臺後無法繼續下載,但是通過框架內部的自動恢復下載機制,在回到前臺後就會繼續之前的下載。而且結合了NSOutputStream例項,將下載下來的資料一點一點的寫在沙盒裡面,減少了記憶體的壓力,也就是支援大檔案下載。
  • 如果支援斷點續傳,則由於斷網或者取消請求等造成的下載失敗後會儲存未下載完成的資料。在後來啟動該下載任務後,會繼續下載。
  • 如果不支援斷點續傳,則不會保留未下載完成的資料。在後來啟動該下載後只能從頭開始下載。

綜上會是由四種情況:

支援斷點續傳 不支援斷點續傳
支援後臺下載
不支援後臺下載

預設配置為:支援斷點續傳,不支援後臺下載(因為除非是音樂視訊類等特殊app,後臺下載的操作可能會被Apple拒掉)。

下載介面

預設的下載功能(支援斷點續傳,不支援後臺下載):

[[SJNetworkManager sharedManager] sendDownloadRequest:@"wallpaper.jpg"
                                     downloadFilePath:_imageFileLocalPath
                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)
{
       self.progressView.progress = progress;

} success:^(id responseObject) {

      NSLog(@"Download succeed!");

} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {

      NSLog(@"Download failed!");

}];
複製程式碼

如果支援斷點續傳,在返回失敗的回撥裡面會傳過來未下載完成資料的路徑:resumableDataPath

不支援斷點續傳,不支援後臺下載:

[[SJNetworkManager sharedManager] sendDownloadRequest:@"half-eatch.jpg"
                                     downloadFilePath:_imageFileLocalPath
                                            resumable:NO
                                    backgroundSupport:NO
                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress) 
{

    self.progressView.progress = progress;

} success:^(id responseObject) {

    NSLog(@"Download succeed!");

} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {

    NSLog(@"Download failed!");
    
}];
複製程式碼

支援斷點續傳,支援後臺下載:

[[SJNetworkManager sharedManager] sendDownloadRequest:@"universe.jpg"
                                     downloadFilePath:_imageFileLocalPath
                                            resumable:YES
                                    backgroundSupport:YES
                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)
{

    self.progressView.progress = progress;

} success:^(id responseObject) {

     NSLog(@"Download succeed!");

} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {

    NSLog(@"Download failed!");

}];
複製程式碼

不支援斷點續傳,支援後臺下載:

[[SJNetworkManager sharedManager] sendDownloadRequest:@"iceberg.jpg"
                                     downloadFilePath:_imageFileLocalPath
                                            resumable:NO
                                    backgroundSupport:YES
                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)
{

    self.progressView.progress = progress;

 } success:^(id responseObject) {

     NSLog(@"Download succeed!");

 } failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {

      NSLog(@"Download failed!");

 }];
複製程式碼

和上傳一樣,下載介面也都支援是否忽略baseUrl:

[[SJNetworkManager sharedManager] sendDownloadRequest:@"http://oih3a9o4n.bkt.clouddn.com/wallpaper.jpg"
                                        ignoreBaseUrl:YES
                                     downloadFilePath:_imageFileLocalPath
                                             progress:^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress)
{
      self.progressView.progress = progress;

} success:^(id responseObject) {

      NSLog(@"Download succeed!");

} failure:^(NSURLSessionTask *task, NSError *error, NSString *resumableDataPath) {

      NSLog(@"Download failed!");

}];
複製程式碼

下載的暫停,恢復和取消

所有的下載請求都支援暫停,恢復和取消操作。並且這些操作都支援單獨與批量操作:

下載的暫停

暫停單獨的下載請求:

[[SJNetworkManager sharedManager] suspendDownloadRequest:@"universe.jpg"];
複製程式碼

暫停多個下載請求:

[[SJNetworkManager sharedManager] suspendDownloadRequests:@[@"universe.jpg",@"wallpaper.jpg"]];
複製程式碼

暫停所有下載請求:

[[SJNetworkManager sharedManager] suspendAllDownloadRequests];
複製程式碼

下載的恢復

恢復單獨的正在暫停的下載請求:

[[SJNetworkManager sharedManager] resumeDownloadReqeust:@"universe.jpg"];
複製程式碼

恢復多個正在暫停的下載請求:

[[SJNetworkManager sharedManager] resumeDownloadReqeusts:@[@"universe.jpg",@"wallpaper.jpg"]];
複製程式碼

恢復所有正在暫停的下載請求:

[[SJNetworkManager sharedManager] resumeAllDownloadRequests];
複製程式碼

下載的取消

取消單獨的下載請求:

[[SJNetworkManager sharedManager] cancelDownloadRequest:@"universe.jpg"];
複製程式碼

取消多個下載請求:

[[SJNetworkManager sharedManager] cancelDownloadRequests:@[@"universe.jpg",@"wallpaper.jpg"]];
複製程式碼

取消所有下載請求:

[[SJNetworkManager sharedManager] cancelAllDownloadRequests];
複製程式碼

請求的管理

在該框架中,無論是普通的下載請求,上傳請求和下載請求,在傳送請求之前都將使用者傳入的引數儲存在專門的請求物件SJNetworkRequestModel的例項裡面。而這些例項的管理工作交給了SJNetworkRequestPool類的單例:

  • 在請求開始之前,將請求例項放入其中的一個字典裡管理。
  • 當請求結束以後,將所對應的請求例項移除。

除了新增和移除請求物件以外,SJNetworkRequestPool對請求的管理還包括:

  • 對正在進行的請求狀況的查詢
  • 對正在進行的請求的取消。

請求狀況的查詢

是否仍然有正在進行的請求:

BOOL remaining =  [[SJNetworkManager sharedManager] remainingCurrentRequests];
if (remaining) {
    NSLog(@"There is remaining request");
}
複製程式碼

正在進行的請求個數:

NSUInteger count = [[SJNetworkManager sharedManager] currentRequestCount];
if (count > 0) {
    NSLog(@"There is %lu requests",(unsigned long)count);
}
複製程式碼

列印所有正在進行的請求物件:

[[SJNetworkManager sharedManager] logAllCurrentRequests];
複製程式碼

請求的取消

請求的取消也分為單個和批量的取消:

取消某個請求:

[[SJNetworkManager sharedManager] cancelCurrentRequestWithUrl:@"toutiao/index"
                                                           method:@"POST"
                                                       parameters:@{@"type":@"top",
                                                                    @"key" :@"0c60"}];
複製程式碼

取消相同url的請求:

[[SJNetworkManager sharedManager] cancelCurrentRequestWithUrl:@"toutiao/index"];
複製程式碼

取消多個指定url的請求:

[[SJNetworkManager sharedManager] cancelDownloadRequests:@[@"toutiao/index",@"weixin/query"]];
複製程式碼

取消所有正在進行的請求:

[[SJNetworkManager sharedManager] cancelAllCurrentRequests];
複製程式碼

Log輸出

如果將debug模式設定為YES,則會列印出很多便於除錯的log:

[SJNetworkConfig sharedConfig].debugMode = YES;
複製程式碼

請求物件的log

由於重寫了SJNetworkRequestModeldescription方法,所以在列印該物件的時候,普通的網路請求,上傳請求,下載請求都有屬於自己的log,在這裡舉一個普通請求的log:

{
   <SJNetworkRequestModel: 0x6040001fc100>
   type:             ordinary request
   method:          GET
   url:             http://v.juhe.cn/toutiao/index
   parameters:      {
    "app_version" = "1.0";
    key = 0c60;
    platform = iOS;
    type = top;
}
   loadCache:       YES
   cacheDuration:   5 seconds
   requestIdentifer:b4b36793efabad54a14389cf09bc8133_a6a72ddee1dd86825cb5707c500784f5_7b65261ff298c6a386c89a632bd17b39_30c9b994c268547f38a2f9af6f8c171f
   task:            <__NSCFLocalDataTask: 0x7f8e075320a0>{ taskIdentifier: 1 } { completed }
} 
複製程式碼

請求和快取的log

舉一個需要獲取快取的網路請求但是遇到快取過期的情況:

=========== Load cache info failed, reason:Cache is expired, begin to clear cache...
=========== Load cache failed: Cache info is invalid 
=========== Faild to load cache, start to sending network request...
=========== Start requesting...
=========== url:http://v.juhe.cn/toutiao/index
=========== method:GET
=========== parameters:{
    "app_version" = "1.0";
    key = 0c60;
    platform = iOS;
    type = top;
}
=========== Request succeed! 
=========== Request url:http://v.juhe.cn/toutiao/index
=========== Response object:{
  code = 200,
  msg = "",
  data = {}
}
=========== Write cache succeed!
=========== cache object: {
  code = 200,
  msg = "",
  data = {}
}
=========== Cache path: /Users/****/***/***/*******.cacheData
=========== Available duration: 180 seconds
複製程式碼

感謝

在除錯這個框架的時候使用了很多網路資源,也看了好多文章,獲得了很多幫助,所以不得不提一下:

API服務

使用和參考的框架

參考文章

最後的話

現在社群裡二次封裝AFNetworking,上傳圖片,以及下載器的框架有很多,但是因為總是想寫一個屬於自己程式碼風格的框架,而且網路層對我自己還是有些挑戰的,所以想試一試。

除去中間間隔的時間,整個框架基本成型的時間用了有一個多月,但是寫全英文的註釋,最後的重構(修改了架構,分離了一些類),命名的規範,修改bug,優化等事情又花去了半個月。特別是由於自己對下載這一塊不熟,尤其是斷點續傳,後臺下載這兩方面更是沒有實戰經驗,在寫的時候也花了不少時間。

希望能多給出寶貴意見和建議,我自己發現有不足的地方也會更新~


本篇已同步到個人部落格:傳送門

---------------------------- 2018年7月17日更新 ----------------------------

注意注意!!!

筆者在近期開通了個人公眾號,主要分享程式設計,讀書筆記,思考類的文章。

  • 程式設計類文章:包括筆者以前釋出的精選技術文章,以及後續釋出的技術文章(以原創為主),並且逐漸脫離 iOS 的內容,將側重點會轉移到提高程式設計能力的方向上。
  • 讀書筆記類文章:分享程式設計類思考類心理類職場類書籍的讀書筆記。
  • 思考類文章:分享筆者平時在技術上生活上的思考。

因為公眾號每天釋出的訊息數有限制,所以到目前為止還沒有將所有過去的精選文章都發布在公眾號上,後續會逐步釋出的。

而且因為各大部落格平臺的各種限制,後面還會在公眾號上釋出一些短小精幹,以小見大的乾貨文章哦~

掃下方的公眾號二維碼並點選關注,期待與您的共同成長~

公眾號:程式設計師維他命

相關文章