IOS——簡化Web服務的鏈接

給NSURLConnection包一層更簡單的接口,就能夠減小每次的下載工做,省去大量的重複。
XYConnection繼承自NSURLConnection,這個類管理臨時的數據結構,並管理一般由控制器對象負責的進度,這樣發起調用的代碼只需在下載完成,數據準備好以後進行響應就好了。也建立了可選的掛鉤機制,能夠見識下載進度。
包含的其餘信息有: 數據結構

1,目標URL
2,起始NSURLRequest
3,預計的下載大小
4,目前一完成的下載量 app

代碼,XYConnection.h: 大數據

#import <Foundation/Foundation.h>
@class XYConnection;
typedef void (^XYConnectionProgressBlock)(XYConnection *connection);
typedef void (^XYConnectionCompletionBlock)(XYConnection *connection, NSError *error);

@interface XYConnection : NSURLConnection<NSURLConnectionDataDelegate>

@property (nonatomic, copy, readonly) NSURL *url;
@property (nonatomic, copy, readonly) NSURLRequest *urlRequest;
@property (nonatomic, assign, readonly) NSInteger contentLength;
@property (nonatomic, retain, readonly) NSMutableData *downloadData;
@property (nonatomic, assign, readonly) float percentComplete;
@property (nonatomic, assign) NSUInteger progressThreshold;

+ (id)connectionWithURL:(NSURL *)requestURL progressBlock:(XYConnectionProgressBlock)progress completionBlock:(XYConnectionCompletionBlock)completion;
+ (id)connectionWithRequest:(NSURLRequest *)request progressBlock:(XYConnectionProgressBlock)progress completionBlock:(XYConnectionCompletionBlock)completion;

- (id)initWithURL:(NSURL *)requestURL progressBlock:(XYConnectionProgressBlock)progress completionBlock:(XYConnectionCompletionBlock)completion;

- (id)initWithRequest:(NSURLRequest *)request progressBlock:(XYConnectionProgressBlock)progress completionBlock:(XYConnectionCompletionBlock)completion;

- (void)start;
- (void)stop;

@end

咱們可直接傳入目標URL和可選的用於處理下載進度、完成、失敗的Block,建立鏈接。-start和-stop方法用於顯式的開始或取消鏈接。Block部分,一個報告進度的增長,另外一個報告完成或失敗。 atom

contentLength屬性表示鏈接的相應頭中的Content-Length值。這個值是在接收到標準的NSURLContent委託方法-connection:didReceiveResponse:的調用時設置的。 url

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    if ([response isKindOfClass:[NSHTTPURLResponse class]]){
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        if ([httpResponse statusCode] == 200){
            NSDictionary *header = [httpResponse allHeaderFields];
            NSString *contentLen = [header valueForKey:@"Content-Lenght"];
            NSInteger length = self.contentLength = [contentLen integerValue];
            self.downloadData = [NSMutableData dataWithCapacity:length];
        }
    }
}

使用這個值和已下載的數據量計算percentComplete屬性 code

- (float)percentComplete{
    if (self.contentLength <= 0) return 0;
    return (([self.downloadData length] * 1.0f) / self.contentLength) * 100;
}

每當percentComplete達到制定的progressThreshold的倍數時,報告進的的Block就會被調用。 對象

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [self.downloadData appendData:data];
    float pctComplete = floorf([self percentComplete]);
    if ((pctComplete - self.previousMilestone) >= self.progressThreshold){
        self.previousMilestone = pctComplete;
        if  (self.progressBlock) self.progressBlock(self);
    }
}

注意,對於大數據量的下載,須要準備一個NSInputStream,拿到數據時就把它寫到固態硬盤,以防止內存不足。 繼承

還有關於內存管理,本博文的完整代碼在內存管理上作的不太好,能改進的地方請指正。 接口

相關文章
相關標籤/搜索