(1)使用 NSURLConnection 直接方式緩存
(2)使用 NSURLConnection 代理方式服務器
(3)使用 NSURLSession 直接方式cookie
(4)使用 NSURLSession 代理方式網絡
(5)使用 AFNetworking 方式session
附加功能:app
(1)使用 AFNetworking 中的 AFNetworkReachabilityManager 來檢查網絡狀況:異步
AFNetworkReachabilityStatusReachableViaWiFi:Wi-Fi 網絡下async
AFNetworkReachabilityStatusReachableViaWWAN:2G/3G/4G 蜂窩移動網絡下ide
AFNetworkReachabilityStatusNotReachable:未鏈接網絡ui
(2)使用 AFNetworking 中的 AFNetworkActivityIndicatorManager 來啓動網絡活動指示器:
1 #import "AFNetworkActivityIndicatorManager.h" 2 3 //啓動網絡活動指示器;會根據網絡交互狀況,實時顯示或隱藏網絡活動指示器;他經過「通知與消息機制」來實現 [UIApplication sharedApplication].networkActivityIndicatorVisible 的控制 4 [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
效果以下:
ViewController.h
1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UITableViewController 4 @property (copy, nonatomic) NSArray *arrSampleName; 5 6 - (instancetype)initWithSampleNameArray:(NSArray *)arrSampleName; 7 8 @end
ViewController.m
1 #import "ViewController.h" 2 #import "NSURLConnectionViewController.h" 3 #import "NSURLConnectionDelegateViewController.h" 4 #import "NSURLSessionViewController.h" 5 #import "NSURLSessionDelegateViewController.h" 6 #import "AFNetworkingViewController.h" 7 8 @interface ViewController () 9 - (void)layoutUI; 10 @end 11 12 @implementation ViewController 13 - (void)viewDidLoad { 14 [super viewDidLoad]; 15 16 [self layoutUI]; 17 } 18 19 - (void)didReceiveMemoryWarning { 20 [super didReceiveMemoryWarning]; 21 // Dispose of any resources that can be recreated. 22 } 23 24 - (instancetype)initWithSampleNameArray:(NSArray *)arrSampleName { 25 if (self = [super initWithStyle:UITableViewStyleGrouped]) { 26 self.navigationItem.title = @"多種方式實現文件下載功能"; 27 self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil]; 28 29 _arrSampleName = arrSampleName; 30 } 31 return self; 32 } 33 34 - (void)layoutUI { 35 } 36 37 #pragma mark - UITableViewController相關方法重寫 38 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 39 return 0.1; 40 } 41 42 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 43 return 1; 44 } 45 46 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 47 return [_arrSampleName count]; 48 } 49 50 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 51 static NSString *cellIdentifier = @"cell"; 52 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 53 if (!cell) { 54 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 55 } 56 cell.textLabel.text = _arrSampleName[indexPath.row]; 57 return cell; 58 } 59 60 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 61 switch (indexPath.row) { 62 case 0: { 63 NSURLConnectionViewController *connectionVC = [NSURLConnectionViewController new]; 64 [self.navigationController pushViewController:connectionVC animated:YES]; 65 break; 66 } 67 case 1: { 68 NSURLConnectionDelegateViewController *connectionDelegateVC = [NSURLConnectionDelegateViewController new]; 69 [self.navigationController pushViewController:connectionDelegateVC animated:YES]; 70 break; 71 } 72 case 2: { 73 NSURLSessionViewController *sessionVC = [NSURLSessionViewController new]; 74 [self.navigationController pushViewController:sessionVC animated:YES]; 75 break; 76 } 77 case 3: { 78 NSURLSessionDelegateViewController *sessionDelegateVC = [NSURLSessionDelegateViewController new]; 79 [self.navigationController pushViewController:sessionDelegateVC animated:YES]; 80 break; 81 } 82 case 4: { 83 AFNetworkingViewController *networkingVC = [AFNetworkingViewController new]; 84 [self.navigationController pushViewController:networkingVC animated:YES]; 85 break; 86 } 87 default: 88 break; 89 } 90 } 91 92 @end
PrefixHeader.pch
1 #define kFileURLStr @"http://files.cnblogs.com/files/huangjianwu/metro_demo使用Highcharts實現圖表展現.zip" 2 3 #define kTitleOfNSURLConnection @"使用 NSURLConnection 直接方式" 4 #define kTitleOfNSURLConnectionDelegate @"使用 NSURLConnection 代理方式" 5 #define kTitleOfNSURLSession @"使用 NSURLSession 直接方式" 6 #define kTitleOfNSURLSessionDelegate @"使用 NSURLSession 代理方式" 7 #define kTitleOfAFNetworking @"使用 AFNetworking 方式" 8 9 #define kApplication [UIApplication sharedApplication]
UIButton+BeautifulButton.h
1 #import <UIKit/UIKit.h> 2 3 @interface UIButton (BeautifulButton) 4 /** 5 * 根據按鈕文字顏色,返回對應文字顏色的圓角按鈕 6 * 7 * @param tintColor 按鈕文字顏色;nil 的話就爲深灰色 8 */ 9 - (void)beautifulButton:(UIColor *)tintColor; 10 11 @end
UIButton+BeautifulButton.m
1 #import "UIButton+BeautifulButton.h" 2 3 @implementation UIButton (BeautifulButton) 4 5 - (void)beautifulButton:(UIColor *)tintColor { 6 self.tintColor = tintColor ?: [UIColor darkGrayColor]; 7 self.layer.masksToBounds = YES; 8 self.layer.cornerRadius = 10.0; 9 self.layer.borderColor = [UIColor grayColor].CGColor; 10 self.layer.borderWidth = 1.0; 11 } 12 13 @end
NSURLConnectionViewController.h
1 #import <UIKit/UIKit.h> 2 3 @interface NSURLConnectionViewController : UIViewController 4 @property (strong, nonatomic) IBOutlet UILabel *lblFileName; 5 @property (strong, nonatomic) IBOutlet UILabel *lblMessage; 6 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile; 7 8 @end
NSURLConnectionViewController.m
1 #import "NSURLConnectionViewController.h" 2 #import "UIButton+BeautifulButton.h" 3 4 @interface NSURLConnectionViewController () 5 - (void)layoutUI; 6 - (void)saveDataToDisk:(NSData *)data; 7 @end 8 9 @implementation NSURLConnectionViewController 10 11 - (void)viewDidLoad { 12 [super viewDidLoad]; 13 14 [self layoutUI]; 15 } 16 17 - (void)didReceiveMemoryWarning { 18 [super didReceiveMemoryWarning]; 19 // Dispose of any resources that can be recreated. 20 } 21 22 - (void)layoutUI { 23 self.navigationItem.title = kTitleOfNSURLConnection; 24 self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000]; 25 26 [_btnDownloadFile beautifulButton:nil]; 27 } 28 29 - (void)saveDataToDisk:(NSData *)data { 30 //數據接收完保存文件;注意蘋果官方要求:下載數據只能保存在緩存目錄(/Library/Caches) 31 NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 32 savePath = [savePath stringByAppendingPathComponent:_lblFileName.text]; 33 [data writeToFile:savePath atomically:YES]; //writeToFile: 方法:若是 savePath 文件存在,他會執行覆蓋 34 } 35 36 - (IBAction)downloadFile:(id)sender { 37 _lblMessage.text = @"下載中..."; 38 39 NSString *fileURLStr = kFileURLStr; 40 //編碼操做;對應的解碼操做是用 stringByRemovingPercentEncoding 方法 41 fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 42 NSURL *fileURL = [NSURL URLWithString:fileURLStr]; 43 44 //建立請求 45 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL]; 46 47 //建立鏈接;Apple 提供的處理通常請求的兩種方法,他們不須要進行一系列的 NSURLConnectionDataDelegate 委託協議方法操做,簡潔直觀 48 //方法一:發送一個同步請求;不建議使用,由於當前線程是主線程的話,會形成線程阻塞,通常比較少用 49 // NSURLResponse *response; 50 // NSError *connectionError; 51 // NSData *data = [NSURLConnection sendSynchronousRequest:request 52 // returningResponse:&response 53 // error:&connectionError]; 54 // if (!connectionError) { 55 // [self saveDataToDisk:data]; 56 // NSLog(@"保存成功"); 57 // 58 // _lblMessage.text = @"下載完成"; 59 // } else { 60 // NSLog(@"下載失敗,錯誤信息:%@", connectionError.localizedDescription); 61 // 62 // _lblMessage.text = @"下載失敗"; 63 // } 64 65 //方法二:發送一個異步請求 66 [NSURLConnection sendAsynchronousRequest:request 67 queue:[NSOperationQueue mainQueue] 68 completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 69 if (!connectionError) { 70 [self saveDataToDisk:data]; 71 NSLog(@"保存成功"); 72 73 _lblMessage.text = @"下載完成"; 74 75 } else { 76 NSLog(@"下載失敗,錯誤信息:%@", connectionError.localizedDescription); 77 78 _lblMessage.text = @"下載失敗"; 79 } 80 }]; 81 } 82 83 @end
NSURLConnectionViewController.xib
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3 <dependencies> 4 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/> 5 </dependencies> 6 <objects> 7 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NSURLConnectionViewController"> 8 <connections> 9 <outlet property="btnDownloadFile" destination="mwt-p9-tRE" id="ZVc-6S-ES3"/> 10 <outlet property="lblFileName" destination="dlB-Qn-eOO" id="NdS-9n-7KX"/> 11 <outlet property="lblMessage" destination="qlQ-nM-BXU" id="tRe-SR-AQE"/> 12 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> 13 </connections> 14 </placeholder> 15 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> 16 <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> 17 <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> 18 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 19 <subviews> 20 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="metro_demo使用Highcharts實現圖表展現.zip" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dlB-Qn-eOO"> 21 <rect key="frame" x="145" y="104" width="309.5" height="18"/> 22 <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> 23 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> 24 <nil key="highlightedColor"/> 25 </label> 26 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mwt-p9-tRE"> 27 <rect key="frame" x="250" y="520" width="100" height="40"/> 28 <constraints> 29 <constraint firstAttribute="width" constant="100" id="I5D-tA-ffH"/> 30 <constraint firstAttribute="height" constant="40" id="Y8C-D4-IVr"/> 31 </constraints> 32 <state key="normal" title="下載"> 33 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 34 </state> 35 <connections> 36 <action selector="downloadFile:" destination="-1" eventType="touchUpInside" id="MK4-Yk-IOk"/> 37 </connections> 38 </button> 39 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qlQ-nM-BXU"> 40 <rect key="frame" x="145" y="140" width="37.5" height="18"/> 41 <fontDescription key="fontDescription" type="system" pointSize="15"/> 42 <color key="textColor" red="0.0" green="0.50196081399917603" blue="1" alpha="1" colorSpace="calibratedRGB"/> 43 <nil key="highlightedColor"/> 44 <userDefinedRuntimeAttributes> 45 <userDefinedRuntimeAttribute type="string" keyPath="text" value=""/> 46 </userDefinedRuntimeAttributes> 47 </label> 48 </subviews> 49 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> 50 <constraints> 51 <constraint firstAttribute="centerX" secondItem="dlB-Qn-eOO" secondAttribute="centerX" id="gNK-NO-rth"/> 52 <constraint firstItem="dlB-Qn-eOO" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="104" id="hwU-O2-Fed"/> 53 <constraint firstAttribute="centerX" secondItem="mwt-p9-tRE" secondAttribute="centerX" id="teN-3t-8Gc"/> 54 <constraint firstItem="qlQ-nM-BXU" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="140" id="w3g-ej-P18"/> 55 <constraint firstItem="dlB-Qn-eOO" firstAttribute="leading" secondItem="qlQ-nM-BXU" secondAttribute="leading" constant="0.5" id="wMU-pU-z9f"/> 56 <constraint firstAttribute="bottom" secondItem="mwt-p9-tRE" secondAttribute="bottom" constant="40" id="yBq-He-Jv8"/> 57 </constraints> 58 </view> 59 </objects> 60 </document>
NSURLConnectionDelegateViewController.h
1 #import <UIKit/UIKit.h> 2 3 @interface NSURLConnectionDelegateViewController : UIViewController 4 @property (strong, nonatomic) NSMutableData *mDataReceive; 5 @property (assign, nonatomic) NSUInteger totalDataLength; 6 7 @property (strong, nonatomic) IBOutlet UILabel *lblFileName; 8 @property (strong, nonatomic) IBOutlet UIProgressView *progVDownloadFile; 9 @property (strong, nonatomic) IBOutlet UILabel *lblMessage; 10 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile; 11 12 @end
NSURLConnectionDelegateViewController.m
1 #import "NSURLConnectionDelegateViewController.h" 2 #import "UIButton+BeautifulButton.h" 3 4 @interface NSURLConnectionDelegateViewController () 5 - (void)layoutUI; 6 - (BOOL)isExistCacheInMemory:(NSURLRequest *)request; 7 - (void)updateProgress; 8 @end 9 10 @implementation NSURLConnectionDelegateViewController 11 12 - (void)viewDidLoad { 13 [super viewDidLoad]; 14 15 [self layoutUI]; 16 } 17 18 - (void)didReceiveMemoryWarning { 19 [super didReceiveMemoryWarning]; 20 // Dispose of any resources that can be recreated. 21 } 22 23 - (void)layoutUI { 24 self.navigationItem.title = kTitleOfNSURLConnectionDelegate; 25 self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000]; 26 27 [_btnDownloadFile beautifulButton:nil]; 28 } 29 30 - (BOOL)isExistCacheInMemory:(NSURLRequest *)request { 31 BOOL isExistCache = NO; 32 NSURLCache *cache = [NSURLCache sharedURLCache]; 33 [cache setMemoryCapacity:1024 * 1024]; //1M 34 35 NSCachedURLResponse *response = [cache cachedResponseForRequest:request]; 36 if (response != nil) { 37 NSLog(@"內存中存在對應請求的響應緩存"); 38 isExistCache = YES; 39 } 40 return isExistCache; 41 } 42 43 - (void)updateProgress { 44 NSUInteger receiveDataLength = _mDataReceive.length; 45 if (receiveDataLength == _totalDataLength) { 46 _lblMessage.text = @"下載完成"; 47 kApplication.networkActivityIndicatorVisible = NO; 48 } else { 49 _lblMessage.text = @"下載中..."; 50 kApplication.networkActivityIndicatorVisible = YES; 51 _progVDownloadFile.progress = (float)receiveDataLength / _totalDataLength; 52 } 53 } 54 55 - (IBAction)downloadFile:(id)sender { 56 /* 57 此例子更多的是但願你們瞭解代理方法接收響應數據的過程,實際開發中也不可能使用這種方法進行文件下載。這種下載有個致命的問題:沒法進行大文件下載。由於代理方法在接收數據時雖然表面看起來是每次讀取一部分響應數據,事實上它只有一次請求而且也只接收了一次服務器響應,只是當響應數據較大時系統會重複調用數據接收方法,每次將已讀取的數據拿出一部分交給數據接收方法而已。在這個過程當中其實早已經將響應數據所有拿到,只是分批交給開發者而已。這樣一來對於幾個G的文件若是進行下載,那麼不用說是真機下載了,就算是模擬器恐怕也是不現實的。 58 實際開發文件下載的時候不論是經過代理方法仍是靜態方法執行請求和響應,咱們都會分批請求數據,而不是一次性請求數據。假設一個文件有1G,那麼只要每次請求1M的數據,請求1024次也就下載完了。那麼如何讓服務器每次只返回1M的數據呢? 59 在網絡開發中能夠在請求的頭文件中設置一個Range信息,它表明請求數據的大小。經過這個字段配合服務器端能夠精確的控制每次服務器響應的數據範圍。例如指定bytes=0-1023,而後在服務器端解析Range信息,返回該文件的0到1023之間的數據的數據便可(共1024Byte)。這樣,只要在每次發送請求控制這個頭文件信息就能夠作到分批請求。 60 固然,爲了讓整個數據保持完整,每次請求的數據都須要逐步追加直到整個文件請求完成。可是如何知道整個文件的大小?其實在此例子經過頭文件信息獲取整個文件大小,他請求整個數據,這樣作對分段下載就沒有任何意義了。所幸在WEB開發中咱們還有另外一種請求方法「HEAD」,經過這種請求服務器只會響應頭信息,其餘數據不會返回給客戶端,這樣一來整個數據的大小也就能夠獲得了。 61 */ 62 63 64 NSString *fileURLStr = kFileURLStr; 65 //編碼操做;對應的解碼操做是用 stringByRemovingPercentEncoding 方法 66 fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 67 NSURL *fileURL = [NSURL URLWithString:fileURLStr]; 68 69 /*建立請求 70 cachePolicy:緩存策略 71 一、NSURLRequestUseProtocolCachePolicy 協議緩存,根據 response 中的 Cache-Control 字段判斷緩存是否有效,若是緩存有效則使用緩存數據不然從新從服務器請求 72 二、NSURLRequestReloadIgnoringLocalCacheData 不使用緩存,直接請求新數據 73 三、NSURLRequestReloadIgnoringCacheData 等同於 NSURLRequestReloadIgnoringLocalCacheData 74 四、NSURLRequestReturnCacheDataElseLoad 直接使用緩存數據不論是否有效,沒有緩存則從新請求 75 五、NSURLRequestReturnCacheDataDontLoad 直接使用緩存數據不論是否有效,沒有緩存數據則失敗 76 77 timeoutInterval:超時時間設置(默認60s) 78 */ 79 NSURLRequest *request = [[NSURLRequest alloc] initWithURL:fileURL 80 cachePolicy:NSURLRequestUseProtocolCachePolicy 81 timeoutInterval:60.0]; 82 if ([self isExistCacheInMemory:request]) { 83 request = [[NSURLRequest alloc] initWithURL:fileURL 84 cachePolicy:NSURLRequestReturnCacheDataDontLoad 85 timeoutInterval:60.0]; 86 } 87 88 //建立鏈接,異步操做 89 NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request 90 delegate:self]; 91 [connection start]; //啓動鏈接 92 } 93 94 #pragma mark - NSURLConnectionDataDelegate 95 - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response { 96 NSLog(@"即將發送請求"); 97 98 return request; 99 } 100 101 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 102 NSLog(@"已經接收到響應"); 103 104 _mDataReceive = [NSMutableData new]; 105 _progVDownloadFile.progress = 0.0; 106 107 //經過響應頭中的 Content-Length 獲取到整個響應的總長度 108 /* 109 { 110 "Accept-Ranges" = bytes; 111 "Cache-Control" = "max-age=7776000"; 112 "Content-Length" = 592441; 113 "Content-Type" = "application/x-zip-compressed"; 114 Date = "Wed, 02 Sep 2015 13:17:01 GMT"; 115 Etag = "\"d8f617371f9cd01:0\""; 116 "Last-Modified" = "Mon, 01 Jun 2015 03:58:27 GMT"; 117 Server = "Microsoft-IIS/7.5"; 118 "X-Powered-By" = "ASP.NET"; 119 } 120 */ 121 NSDictionary *dicHeaderField = [(NSHTTPURLResponse *)response allHeaderFields]; 122 _totalDataLength = [[dicHeaderField objectForKey:@"Content-Length"] integerValue]; 123 } 124 125 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 126 NSLog(@"已經接收到響應數據,數據長度爲%lu字節...", (unsigned long)[data length]); 127 128 [_mDataReceive appendData:data]; //連續接收數據 129 [self updateProgress]; //連續更新進度條 130 } 131 132 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 133 NSLog(@"已經接收完全部響應數據"); 134 135 NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 136 savePath = [savePath stringByAppendingPathComponent:_lblFileName.text]; 137 [_mDataReceive writeToFile:savePath atomically:YES]; 138 } 139 140 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 141 //若是鏈接超時或者鏈接地址錯誤可能就會報錯 142 NSLog(@"鏈接錯誤,錯誤信息:%@", error.localizedDescription); 143 144 _lblMessage.text = @"鏈接錯誤"; 145 } 146 147 @end
NSURLConnectionDelegateViewController.xib
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3 <dependencies> 4 <deployment identifier="iOS"/> 5 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/> 6 </dependencies> 7 <objects> 8 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NSURLConnectionDelegateViewController"> 9 <connections> 10 <outlet property="btnDownloadFile" destination="mwt-p9-tRE" id="ZVc-6S-ES3"/> 11 <outlet property="lblFileName" destination="dlB-Qn-eOO" id="vJk-jh-Y2c"/> 12 <outlet property="lblMessage" destination="qlQ-nM-BXU" id="tRe-SR-AQE"/> 13 <outlet property="progVDownloadFile" destination="Me3-m2-iC4" id="PtK-m7-j5N"/> 14 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> 15 </connections> 16 </placeholder> 17 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> 18 <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> 19 <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> 20 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 21 <subviews> 22 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="metro_demo使用Highcharts實現圖表展現.zip" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dlB-Qn-eOO"> 23 <rect key="frame" x="145" y="104" width="309.5" height="18"/> 24 <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> 25 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> 26 <nil key="highlightedColor"/> 27 </label> 28 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mwt-p9-tRE"> 29 <rect key="frame" x="250" y="520" width="100" height="40"/> 30 <constraints> 31 <constraint firstAttribute="width" constant="100" id="I5D-tA-ffH"/> 32 <constraint firstAttribute="height" constant="40" id="Y8C-D4-IVr"/> 33 </constraints> 34 <state key="normal" title="下載"> 35 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 36 </state> 37 <connections> 38 <action selector="downloadFile:" destination="-1" eventType="touchUpInside" id="iGc-6N-bsZ"/> 39 </connections> 40 </button> 41 <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Me3-m2-iC4"> 42 <rect key="frame" x="145" y="160" width="310" height="2"/> 43 <constraints> 44 <constraint firstAttribute="height" constant="2" id="I50-Zx-DwT"/> 45 <constraint firstAttribute="width" constant="310" id="wdS-eD-Tkc"/> 46 </constraints> 47 </progressView> 48 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qlQ-nM-BXU"> 49 <rect key="frame" x="145" y="180" width="37.5" height="18"/> 50 <fontDescription key="fontDescription" type="system" pointSize="15"/> 51 <color key="textColor" red="0.0" green="0.50196081399917603" blue="1" alpha="1" colorSpace="calibratedRGB"/> 52 <nil key="highlightedColor"/> 53 <userDefinedRuntimeAttributes> 54 <userDefinedRuntimeAttribute type="string" keyPath="text" value=""/> 55 </userDefinedRuntimeAttributes> 56 </label> 57 </subviews> 58 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> 59 <constraints> 60 <constraint firstAttribute="centerX" secondItem="Me3-m2-iC4" secondAttribute="centerX" id="Ya8-bM-TaA"/> 61 <constraint firstItem="Me3-m2-iC4" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="160" id="bOY-B5-is2"/> 62 <constraint firstAttribute="centerX" secondItem="dlB-Qn-eOO" secondAttribute="centerX" id="gNK-NO-rth"/> 63 <constraint firstItem="dlB-Qn-eOO" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="104" id="hwU-O2-Fed"/> 64 <constraint firstItem="qlQ-nM-BXU" firstAttribute="leading" secondItem="Me3-m2-iC4" secondAttribute="leading" id="lus-oi-9SA"/> 65 <constraint firstAttribute="centerX" secondItem="mwt-p9-tRE" secondAttribute="centerX" id="teN-3t-8Gc"/> 66 <constraint firstItem="qlQ-nM-BXU" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="180" id="w3g-ej-P18"/> 67 <constraint firstAttribute="bottom" secondItem="mwt-p9-tRE" secondAttribute="bottom" constant="40" id="yBq-He-Jv8"/> 68 </constraints> 69 </view> 70 </objects> 71 </document>
NSURLSessionViewController.h
1 #import <UIKit/UIKit.h> 2 3 @interface NSURLSessionViewController : UIViewController 4 @property (strong, nonatomic) IBOutlet UILabel *lblFileName; 5 @property (strong, nonatomic) IBOutlet UILabel *lblMessage; 6 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile; 7 8 @end
NSURLSessionViewController.m
1 #import "NSURLSessionViewController.h" 2 #import "UIButton+BeautifulButton.h" 3 4 @interface NSURLSessionViewController () 5 - (void)layoutUI; 6 @end 7 8 @implementation NSURLSessionViewController 9 10 - (void)viewDidLoad { 11 [super viewDidLoad]; 12 13 [self layoutUI]; 14 } 15 16 - (void)didReceiveMemoryWarning { 17 [super didReceiveMemoryWarning]; 18 // Dispose of any resources that can be recreated. 19 } 20 21 - (void)layoutUI { 22 self.navigationItem.title = kTitleOfNSURLSession; 23 self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000]; 24 25 [_btnDownloadFile beautifulButton:nil]; 26 } 27 28 - (IBAction)downloadFile:(id)sender { 29 _lblMessage.text = @"下載中..."; 30 31 NSString *fileURLStr = kFileURLStr; 32 //編碼操做;對應的解碼操做是用 stringByRemovingPercentEncoding 方法 33 fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 34 NSURL *fileURL = [NSURL URLWithString:fileURLStr]; 35 36 //建立請求 37 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL]; 38 39 //建立會話(這裏使用了一個全局會話) 40 NSURLSession *session = [NSURLSession sharedSession]; 41 42 //建立下載任務,而且啓動他;在非主線程中執行 43 NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) { 44 __block void (^updateUI)(); //聲明用於主線程更新 UI 的代碼塊 45 46 if (!error) { 47 NSLog(@"下載後的臨時保存路徑:%@", location); 48 49 NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 50 savePath = [savePath stringByAppendingPathComponent:_lblFileName.text]; 51 NSURL *saveURL = [NSURL fileURLWithPath:savePath]; 52 NSError *saveError; 53 NSFileManager *fileManager = [NSFileManager defaultManager]; 54 //判斷是否存在舊的目標文件,若是存在就先移除;避免沒法複製問題 55 if ([fileManager fileExistsAtPath:savePath]) { 56 [fileManager removeItemAtPath:savePath error:&saveError]; 57 if (saveError) { 58 NSLog(@"移除舊的目標文件失敗,錯誤信息:%@", saveError.localizedDescription); 59 60 updateUI = ^ { 61 _lblMessage.text = @"下載失敗"; 62 }; 63 } 64 } 65 if (!saveError) { 66 //把源文件複製到目標文件,當目標文件存在時,會拋出一個錯誤到 error 參數指向的對象實例 67 //方法一(path 不能有 file:// 前綴) 68 // [fileManager copyItemAtPath:[location path] 69 // toPath:savePath 70 // error:&saveError]; 71 72 //方法二 73 [fileManager copyItemAtURL:location 74 toURL:saveURL 75 error:&saveError]; 76 77 if (!saveError) { 78 NSLog(@"保存成功"); 79 80 updateUI = ^ { 81 _lblMessage.text = @"下載完成"; 82 }; 83 } else { 84 NSLog(@"保存失敗,錯誤信息:%@", saveError.localizedDescription); 85 86 updateUI = ^ { 87 _lblMessage.text = @"下載失敗"; 88 }; 89 } 90 } 91 92 } else { 93 NSLog(@"下載失敗,錯誤信息:%@", error.localizedDescription); 94 95 updateUI = ^ { 96 _lblMessage.text = @"下載失敗"; 97 }; 98 } 99 100 dispatch_async(dispatch_get_main_queue(), updateUI); //使用主隊列異步方式(主線程)執行更新 UI 的代碼塊 101 }]; 102 [downloadTask resume]; //恢復線程,啓動任務 103 } 104 105 @end
NSURLSessionViewController.xib
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3 <dependencies> 4 <deployment identifier="iOS"/> 5 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/> 6 </dependencies> 7 <objects> 8 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NSURLSessionViewController"> 9 <connections> 10 <outlet property="btnDownloadFile" destination="mwt-p9-tRE" id="ZVc-6S-ES3"/> 11 <outlet property="lblFileName" destination="dlB-Qn-eOO" id="NdS-9n-7KX"/> 12 <outlet property="lblMessage" destination="qlQ-nM-BXU" id="tRe-SR-AQE"/> 13 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> 14 </connections> 15 </placeholder> 16 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> 17 <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> 18 <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> 19 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 20 <subviews> 21 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="metro_demo使用Highcharts實現圖表展現.zip" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dlB-Qn-eOO"> 22 <rect key="frame" x="145" y="104" width="309.5" height="18"/> 23 <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> 24 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> 25 <nil key="highlightedColor"/> 26 </label> 27 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mwt-p9-tRE"> 28 <rect key="frame" x="250" y="520" width="100" height="40"/> 29 <constraints> 30 <constraint firstAttribute="width" constant="100" id="I5D-tA-ffH"/> 31 <constraint firstAttribute="height" constant="40" id="Y8C-D4-IVr"/> 32 </constraints> 33 <state key="normal" title="下載"> 34 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 35 </state> 36 <connections> 37 <action selector="downloadFile:" destination="-1" eventType="touchUpInside" id="MK4-Yk-IOk"/> 38 </connections> 39 </button> 40 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qlQ-nM-BXU"> 41 <rect key="frame" x="145" y="140" width="37.5" height="18"/> 42 <fontDescription key="fontDescription" type="system" pointSize="15"/> 43 <color key="textColor" red="0.0" green="0.50196081399917603" blue="1" alpha="1" colorSpace="calibratedRGB"/> 44 <nil key="highlightedColor"/> 45 <userDefinedRuntimeAttributes> 46 <userDefinedRuntimeAttribute type="string" keyPath="text" value=""/> 47 </userDefinedRuntimeAttributes> 48 </label> 49 </subviews> 50 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> 51 <constraints> 52 <constraint firstAttribute="centerX" secondItem="dlB-Qn-eOO" secondAttribute="centerX" id="gNK-NO-rth"/> 53 <constraint firstItem="dlB-Qn-eOO" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="104" id="hwU-O2-Fed"/> 54 <constraint firstAttribute="centerX" secondItem="mwt-p9-tRE" secondAttribute="centerX" id="teN-3t-8Gc"/> 55 <constraint firstItem="qlQ-nM-BXU" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="140" id="w3g-ej-P18"/> 56 <constraint firstItem="dlB-Qn-eOO" firstAttribute="leading" secondItem="qlQ-nM-BXU" secondAttribute="leading" constant="0.5" id="wMU-pU-z9f"/> 57 <constraint firstAttribute="bottom" secondItem="mwt-p9-tRE" secondAttribute="bottom" constant="40" id="yBq-He-Jv8"/> 58 </constraints> 59 </view> 60 </objects> 61 </document>
NSURLSessionDelegateViewController.h
1 #import <UIKit/UIKit.h> 2 3 @interface NSURLSessionDelegateViewController : UIViewController <NSURLSessionDownloadDelegate> 4 @property (strong, nonatomic) NSURLSessionDownloadTask *downloadTask; 5 6 @property (strong, nonatomic) IBOutlet UILabel *lblFileName; 7 @property (strong, nonatomic) IBOutlet UIProgressView *progVDownloadFile; 8 @property (strong, nonatomic) IBOutlet UILabel *lblMessage; 9 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFile; 10 @property (strong, nonatomic) IBOutlet UIButton *btnCancel; 11 @property (strong, nonatomic) IBOutlet UIButton *btnSuspend; 12 @property (strong, nonatomic) IBOutlet UIButton *btnResume; 13 14 @end
NSURLSessionDelegateViewController.m
1 #import "NSURLSessionDelegateViewController.h" 2 #import "UIButton+BeautifulButton.h" 3 4 @interface NSURLSessionDelegateViewController () 5 - (void)layoutUI; 6 - (NSURLSession *)defaultSession; 7 - (NSURLSession *)backgroundSession; 8 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength; 9 @end 10 11 @implementation NSURLSessionDelegateViewController 12 13 - (void)viewDidLoad { 14 [super viewDidLoad]; 15 16 [self layoutUI]; 17 } 18 19 - (void)didReceiveMemoryWarning { 20 [super didReceiveMemoryWarning]; 21 // Dispose of any resources that can be recreated. 22 } 23 24 - (void)layoutUI { 25 self.navigationItem.title = kTitleOfNSURLSessionDelegate; 26 self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000]; 27 28 [_btnDownloadFile beautifulButton:nil]; 29 [_btnCancel beautifulButton:[UIColor redColor]]; 30 [_btnSuspend beautifulButton:[UIColor purpleColor]]; 31 [_btnResume beautifulButton:[UIColor orangeColor]]; 32 } 33 34 - (NSURLSession *)defaultSession { 35 /* 36 NSURLSession 支持進程三種會話: 37 一、defaultSessionConfiguration:進程內會話(默認會話),用硬盤來緩存數據。 38 二、ephemeralSessionConfiguration:臨時的進程內會話(內存),不會將 cookie、緩存儲存到本地,只會放到內存中,當應用程序退出後數據也會消失。 39 三、backgroundSessionConfiguration:後臺會話,相比默認會話,該會話會在後臺開啓一個線程進行網絡數據處理。 40 */ 41 42 //建立會話配置「進程內會話」 43 NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 44 sessionConfiguration.timeoutIntervalForRequest = 60.0; //請求超時時間;默認爲60秒 45 sessionConfiguration.allowsCellularAccess = YES; //是否容許蜂窩網絡訪問(2G/3G/4G) 46 sessionConfiguration.HTTPMaximumConnectionsPerHost = 4; //限制每次最多鏈接數;在 iOS 中默認值爲4 47 48 //建立會話 49 NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration 50 delegate:self 51 delegateQueue:nil]; 52 return session; 53 } 54 55 - (NSURLSession *)backgroundSession { 56 static NSURLSession *session; 57 static dispatch_once_t onceToken; 58 dispatch_once(&onceToken, ^{ //應用程序生命週期內,只執行一次;保證只有一個「後臺會話」 59 //建立會話配置「後臺會話」 60 NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"KMDownloadFile.NSURLSessionDelegateViewController"]; 61 sessionConfiguration.timeoutIntervalForRequest = 60.0; //請求超時時間;默認爲60秒 62 sessionConfiguration.allowsCellularAccess = YES; //是否容許蜂窩網絡訪問(2G/3G/4G) 63 sessionConfiguration.HTTPMaximumConnectionsPerHost = 4; //限制每次最多鏈接數;在 iOS 中默認值爲4 64 sessionConfiguration.discretionary = YES; //是否自動選擇最佳網絡訪問,僅對「後臺會話」有效 65 66 //建立會話 67 session = [NSURLSession sessionWithConfiguration:sessionConfiguration 68 delegate:self 69 delegateQueue:nil]; 70 }); 71 return session; 72 } 73 74 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength; { 75 dispatch_async(dispatch_get_main_queue(), ^{ //使用主隊列異步方式(主線程)執行更新 UI 操做 76 if (receiveDataLength == totalDataLength) { 77 _lblMessage.text = @"下載完成"; 78 kApplication.networkActivityIndicatorVisible = NO; 79 } else { 80 _lblMessage.text = @"下載中..."; 81 kApplication.networkActivityIndicatorVisible = YES; 82 _progVDownloadFile.progress = (float)receiveDataLength / totalDataLength; 83 } 84 }); 85 } 86 87 - (IBAction)downloadFile:(id)sender { 88 NSString *fileURLStr = kFileURLStr; 89 //編碼操做;對應的解碼操做是用 stringByRemovingPercentEncoding 方法 90 fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 91 NSURL *fileURL = [NSURL URLWithString:fileURLStr]; 92 93 //建立請求 94 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL]; 95 96 //建立會話「進程內會話」;如要用「後臺會話」就使用自定義的[self backgroundSession] 方法 97 NSURLSession *session = [self defaultSession]; 98 99 //建立下載任務,而且啓動他;在非主線程中執行 100 _downloadTask = [session downloadTaskWithRequest:request]; 101 [_downloadTask resume]; 102 103 /* 104 會話任務狀態 105 typedef NS_ENUM(NSInteger, NSURLSessionTaskState) { 106 NSURLSessionTaskStateRunning = 0, //正在執行 107 NSURLSessionTaskStateSuspended = 1, //已掛起 108 NSURLSessionTaskStateCanceling = 2, //正在取消 109 NSURLSessionTaskStateCompleted = 3, //已完成 110 } NS_ENUM_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0); 111 */ 112 } 113 114 - (IBAction)cancel:(id)sender { 115 [_downloadTask cancel]; 116 } 117 118 - (IBAction)suspend:(id)sender { 119 [_downloadTask suspend]; 120 kApplication.networkActivityIndicatorVisible = NO; 121 } 122 123 - (IBAction)resume:(id)sender { 124 [_downloadTask resume]; 125 } 126 127 #pragma mark - NSURLSessionDownloadDelegate 128 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { 129 NSLog(@"已經接收到響應數據,數據長度爲%lld字節...", totalBytesWritten); 130 131 [self updateProgress:totalBytesWritten totalDataLength:totalBytesExpectedToWrite]; 132 } 133 134 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { 135 //下載文件會臨時保存,正常流程下系統最終會自動清除此臨時文件;保存路徑目錄根據會話類型而有所不一樣: 136 //「進程內會話(默認會話)」和「臨時的進程內會話(內存)」,路徑目錄爲:/tmp,能夠經過 NSTemporaryDirectory() 方法獲取 137 //「後臺會話」,路徑目錄爲:/Library/Caches/com.apple.nsurlsessiond/Downloads/com.kenmu.KMDownloadFile 138 NSLog(@"已經接收完全部響應數據,下載後的臨時保存路徑:%@", location); 139 140 __block void (^updateUI)(); //聲明用於主線程更新 UI 的代碼塊 141 142 NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 143 savePath = [savePath stringByAppendingPathComponent:_lblFileName.text]; 144 NSURL *saveURL = [NSURL fileURLWithPath:savePath]; 145 NSError *saveError; 146 NSFileManager *fileManager = [NSFileManager defaultManager]; 147 //判斷是否存在舊的目標文件,若是存在就先移除;避免沒法複製問題 148 if ([fileManager fileExistsAtPath:savePath]) { 149 [fileManager removeItemAtPath:savePath error:&saveError]; 150 if (saveError) { 151 NSLog(@"移除舊的目標文件失敗,錯誤信息:%@", saveError.localizedDescription); 152 153 updateUI = ^ { 154 _lblMessage.text = @"下載失敗"; 155 }; 156 } 157 } 158 if (!saveError) { 159 //把源文件複製到目標文件,當目標文件存在時,會拋出一個錯誤到 error 參數指向的對象實例 160 //方法一(path 不能有 file:// 前綴) 161 // [fileManager copyItemAtPath:[location path] 162 // toPath:savePath 163 // error:&saveError]; 164 165 //方法二 166 [fileManager copyItemAtURL:location 167 toURL:saveURL 168 error:&saveError]; 169 170 if (!saveError) { 171 NSLog(@"保存成功"); 172 173 updateUI = ^ { 174 _lblMessage.text = @"下載完成"; 175 }; 176 } else { 177 NSLog(@"保存失敗,錯誤信息:%@", saveError.localizedDescription); 178 179 updateUI = ^ { 180 _lblMessage.text = @"下載失敗"; 181 }; 182 } 183 } 184 185 dispatch_async(dispatch_get_main_queue(), updateUI); //使用主隊列異步方式(主線程)執行更新 UI 的代碼塊 186 } 187 188 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { 189 NSLog(@"不管下載成功仍是失敗,最終都會執行一次"); 190 191 if (error) { 192 NSString *desc = error.localizedDescription; 193 NSLog(@"下載失敗,錯誤信息:%@", desc); 194 195 dispatch_async(dispatch_get_main_queue(), ^{ //使用主隊列異步方式(主線程)執行更新 UI 操做 196 _lblMessage.text = [desc isEqualToString:@"cancelled"] ? @"下載已取消" : @"下載失敗"; 197 kApplication.networkActivityIndicatorVisible = NO; 198 _progVDownloadFile.progress = 0.0; 199 }); 200 } 201 } 202 203 @end
NSURLSessionDelegateViewController.xib
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3 <dependencies> 4 <deployment identifier="iOS"/> 5 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/> 6 </dependencies> 7 <objects> 8 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NSURLSessionDelegateViewController"> 9 <connections> 10 <outlet property="btnCancel" destination="yMY-kU-iKL" id="QHP-ls-q8P"/> 11 <outlet property="btnDownloadFile" destination="mwt-p9-tRE" id="ZVc-6S-ES3"/> 12 <outlet property="btnResume" destination="YSM-n6-UM4" id="RyL-54-rFB"/> 13 <outlet property="btnSuspend" destination="5kz-pB-9nK" id="1Jj-zV-DXM"/> 14 <outlet property="lblFileName" destination="dlB-Qn-eOO" id="vJk-jh-Y2c"/> 15 <outlet property="lblMessage" destination="qlQ-nM-BXU" id="tRe-SR-AQE"/> 16 <outlet property="progVDownloadFile" destination="Me3-m2-iC4" id="PtK-m7-j5N"/> 17 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> 18 </connections> 19 </placeholder> 20 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> 21 <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> 22 <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> 23 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 24 <subviews> 25 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="metro_demo使用Highcharts實現圖表展現.zip" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dlB-Qn-eOO"> 26 <rect key="frame" x="145" y="104" width="309.5" height="18"/> 27 <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> 28 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> 29 <nil key="highlightedColor"/> 30 </label> 31 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mwt-p9-tRE"> 32 <rect key="frame" x="145" y="520" width="70" height="40"/> 33 <constraints> 34 <constraint firstAttribute="width" constant="70" id="I5D-tA-ffH"/> 35 <constraint firstAttribute="height" constant="40" id="Y8C-D4-IVr"/> 36 </constraints> 37 <state key="normal" title="下載"> 38 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 39 </state> 40 <connections> 41 <action selector="downloadFile:" destination="-1" eventType="touchUpInside" id="iGc-6N-bsZ"/> 42 </connections> 43 </button> 44 <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Me3-m2-iC4"> 45 <rect key="frame" x="145" y="160" width="310" height="2"/> 46 <constraints> 47 <constraint firstAttribute="height" constant="2" id="I50-Zx-DwT"/> 48 <constraint firstAttribute="width" constant="310" id="wdS-eD-Tkc"/> 49 </constraints> 50 </progressView> 51 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qlQ-nM-BXU"> 52 <rect key="frame" x="145" y="180" width="37.5" height="18"/> 53 <fontDescription key="fontDescription" type="system" pointSize="15"/> 54 <color key="textColor" red="0.0" green="0.50196081399917603" blue="1" alpha="1" colorSpace="calibratedRGB"/> 55 <nil key="highlightedColor"/> 56 <userDefinedRuntimeAttributes> 57 <userDefinedRuntimeAttribute type="string" keyPath="text" value=""/> 58 </userDefinedRuntimeAttributes> 59 </label> 60 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5kz-pB-9nK"> 61 <rect key="frame" x="305" y="520" width="70" height="40"/> 62 <constraints> 63 <constraint firstAttribute="width" constant="70" id="IOm-ve-DPG"/> 64 <constraint firstAttribute="height" constant="40" id="Kwn-EW-gDl"/> 65 </constraints> 66 <state key="normal" title="掛起"> 67 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 68 </state> 69 <connections> 70 <action selector="suspend:" destination="-1" eventType="touchUpInside" id="O6j-t2-7Lv"/> 71 </connections> 72 </button> 73 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="YSM-n6-UM4"> 74 <rect key="frame" x="385" y="520" width="70" height="40"/> 75 <constraints> 76 <constraint firstAttribute="width" constant="70" id="LhS-5f-cG4"/> 77 <constraint firstAttribute="height" constant="40" id="kzz-1h-4DP"/> 78 </constraints> 79 <state key="normal" title="恢復"> 80 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 81 </state> 82 <connections> 83 <action selector="resume:" destination="-1" eventType="touchUpInside" id="ms9-R9-B9B"/> 84 </connections> 85 </button> 86 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yMY-kU-iKL"> 87 <rect key="frame" x="225" y="520" width="70" height="40"/> 88 <constraints> 89 <constraint firstAttribute="height" constant="40" id="S7b-Pl-qKI"/> 90 <constraint firstAttribute="width" constant="70" id="gY7-vp-PUz"/> 91 </constraints> 92 <state key="normal" title="取消"> 93 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 94 </state> 95 <connections> 96 <action selector="cancel:" destination="-1" eventType="touchUpInside" id="ITC-zg-bfP"/> 97 </connections> 98 </button> 99 </subviews> 100 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> 101 <constraints> 102 <constraint firstItem="5kz-pB-9nK" firstAttribute="centerY" secondItem="YSM-n6-UM4" secondAttribute="centerY" id="4zt-gy-k65"/> 103 <constraint firstItem="qlQ-nM-BXU" firstAttribute="leading" secondItem="mwt-p9-tRE" secondAttribute="leading" id="RYu-qM-O8P"/> 104 <constraint firstAttribute="centerX" secondItem="Me3-m2-iC4" secondAttribute="centerX" id="Ya8-bM-TaA"/> 105 <constraint firstItem="Me3-m2-iC4" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="160" id="bOY-B5-is2"/> 106 <constraint firstItem="yMY-kU-iKL" firstAttribute="centerY" secondItem="5kz-pB-9nK" secondAttribute="centerY" id="dBh-1A-sIk"/> 107 <constraint firstItem="YSM-n6-UM4" firstAttribute="leading" secondItem="5kz-pB-9nK" secondAttribute="trailing" constant="10" id="fYW-Jv-ro2"/> 108 <constraint firstAttribute="centerX" secondItem="dlB-Qn-eOO" secondAttribute="centerX" id="gNK-NO-rth"/> 109 <constraint firstItem="dlB-Qn-eOO" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="104" id="hwU-O2-Fed"/> 110 <constraint firstItem="mwt-p9-tRE" firstAttribute="centerY" secondItem="yMY-kU-iKL" secondAttribute="centerY" id="lGv-fH-Fh7"/> 111 <constraint firstItem="qlQ-nM-BXU" firstAttribute="leading" secondItem="Me3-m2-iC4" secondAttribute="leading" id="lus-oi-9SA"/> 112 <constraint firstItem="5kz-pB-9nK" firstAttribute="leading" secondItem="yMY-kU-iKL" secondAttribute="trailing" constant="10" id="oge-T7-1td"/> 113 <constraint firstItem="qlQ-nM-BXU" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="180" id="w3g-ej-P18"/> 114 <constraint firstItem="yMY-kU-iKL" firstAttribute="leading" secondItem="mwt-p9-tRE" secondAttribute="trailing" constant="10" id="xCX-1F-xOv"/> 115 <constraint firstAttribute="bottom" secondItem="mwt-p9-tRE" secondAttribute="bottom" constant="40" id="yBq-He-Jv8"/> 116 </constraints> 117 </view> 118 </objects> 119 </document>
AFNetworkingViewController.h
1 #import <UIKit/UIKit.h> 2 #import "MBProgressHUD.h" 3 4 @interface AFNetworkingViewController : UIViewController 5 @property (strong, nonatomic) MBProgressHUD *hud; 6 7 @property (strong, nonatomic) IBOutlet UILabel *lblFileName; 8 @property (strong, nonatomic) IBOutlet UILabel *lblMessage; 9 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFileByConnection; 10 @property (strong, nonatomic) IBOutlet UIButton *btnDownloadFileBySession; 11 12 @end
AFNetworkingViewController.m
1 #import "AFNetworkingViewController.h" 2 #import "AFNetworking.h" 3 #import "AFNetworkActivityIndicatorManager.h" 4 #import "UIButton+BeautifulButton.h" 5 6 @interface AFNetworkingViewController () 7 - (void)showAlert:(NSString *)msg; 8 - (void)checkNetwork; 9 - (void)layoutUI; 10 - (NSMutableURLRequest *)downloadRequest; 11 - (NSURL *)saveURL:(NSURLResponse *)response deleteExistFile:(BOOL)deleteExistFile; 12 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength; 13 @end 14 15 @implementation AFNetworkingViewController 16 17 - (void)viewDidLoad { 18 [super viewDidLoad]; 19 20 [self layoutUI]; 21 } 22 23 - (void)didReceiveMemoryWarning { 24 [super didReceiveMemoryWarning]; 25 // Dispose of any resources that can be recreated. 26 } 27 28 - (void)showAlert:(NSString *)msg { 29 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"網絡狀況" 30 message:msg 31 delegate:self 32 cancelButtonTitle:nil 33 otherButtonTitles:@"肯定", nil]; 34 [alert show]; 35 } 36 37 - (void)checkNetwork { 38 NSURL *baseURL = [NSURL URLWithString:@"http://www.baidu.com/"]; 39 AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL]; 40 41 NSOperationQueue *operationQueue = manager.operationQueue; 42 [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { 43 switch (status) { 44 case AFNetworkReachabilityStatusReachableViaWiFi: 45 [self showAlert:@"Wi-Fi 網絡下"]; 46 [operationQueue setSuspended:NO]; 47 break; 48 case AFNetworkReachabilityStatusReachableViaWWAN: 49 [self showAlert:@"2G/3G/4G 蜂窩移動網絡下"]; 50 [operationQueue setSuspended:YES]; 51 break; 52 case AFNetworkReachabilityStatusNotReachable: 53 default: 54 [self showAlert:@"未鏈接網絡"]; 55 [operationQueue setSuspended:YES]; 56 break; 57 } 58 }]; 59 60 [manager.reachabilityManager startMonitoring]; 61 } 62 63 - (void)layoutUI { 64 self.navigationItem.title = kTitleOfAFNetworking; 65 self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.000]; 66 67 //條件表達式中,「?:」能夠表示在條件不成立的狀況,才使用後者賦值,不然使用用於條件判斷的前者賦值 68 //如下語句等同於:UIButton *btn = _btnDownloadFileByConnection ? _btnDownloadFileByConnection : [UIButton new]; 69 //在 .NET 中,至關於使用「??」;在 JavaScript 中,至關於使用「||」來實現這種相似的判斷 70 UIButton *btn = _btnDownloadFileByConnection ?: [UIButton new]; 71 [btn beautifulButton:nil]; 72 [_btnDownloadFileBySession beautifulButton:[UIColor orangeColor]]; 73 74 //進度效果 75 _hud = [[MBProgressHUD alloc] initWithView:self.view]; 76 _hud.mode = MBProgressHUDModeDeterminate; 77 _hud.labelText = @"下載中..."; 78 [_hud hide:YES]; 79 [self.view addSubview:_hud]; 80 81 //檢查網絡狀況 82 [self checkNetwork]; 83 84 //啓動網絡活動指示器;會根據網絡交互狀況,實時顯示或隱藏網絡活動指示器;他經過「通知與消息機制」來實現 [UIApplication sharedApplication].networkActivityIndicatorVisible 的控制 85 [AFNetworkActivityIndicatorManager sharedManager].enabled = YES; 86 } 87 88 - (NSMutableURLRequest *)downloadRequest { 89 NSString *fileURLStr = kFileURLStr; 90 //編碼操做;對應的解碼操做是用 stringByRemovingPercentEncoding 方法 91 fileURLStr = [fileURLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 92 NSURL *fileURL = [NSURL URLWithString:fileURLStr]; 93 94 //建立請求 95 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:fileURL]; 96 return request; 97 } 98 99 - (NSURL *)saveURL:(NSURLResponse *)response deleteExistFile:(BOOL)deleteExistFile { 100 NSString *fileName = response ? [response suggestedFilename] : _lblFileName.text; 101 102 //方法一 103 // NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 104 // savePath = [savePath stringByAppendingPathComponent:fileName]; 105 // NSURL *saveURL = [NSURL fileURLWithPath:savePath]; 106 107 //方法二 108 NSURL *saveURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; 109 saveURL = [saveURL URLByAppendingPathComponent:fileName]; 110 NSString *savePath = [saveURL path]; 111 112 if (deleteExistFile) { 113 NSError *saveError; 114 NSFileManager *fileManager = [NSFileManager defaultManager]; 115 //判斷是否存在舊的目標文件,若是存在就先移除;避免沒法複製問題 116 if ([fileManager fileExistsAtPath:savePath]) { 117 [fileManager removeItemAtPath:savePath error:&saveError]; 118 if (saveError) { 119 NSLog(@"移除舊的目標文件失敗,錯誤信息:%@", saveError.localizedDescription); 120 } 121 } 122 } 123 124 return saveURL; 125 } 126 127 - (void)updateProgress:(int64_t)receiveDataLength totalDataLength:(int64_t)totalDataLength; { 128 dispatch_async(dispatch_get_main_queue(), ^{ //使用主隊列異步方式(主線程)執行更新 UI 操做 129 _hud.progress = (float)receiveDataLength / totalDataLength; 130 131 if (receiveDataLength == totalDataLength) { 132 _lblMessage.text = receiveDataLength < 0 ? @"下載失敗" : @"下載完成"; 133 //kApplication.networkActivityIndicatorVisible = NO; 134 [_hud hide:YES]; 135 } else { 136 _lblMessage.text = @"下載中..."; 137 //kApplication.networkActivityIndicatorVisible = YES; 138 [_hud show:YES]; 139 } 140 }); 141 } 142 143 - (IBAction)downloadFileByConnection:(id)sender { 144 //建立請求 145 NSMutableURLRequest *request = [self downloadRequest]; 146 147 //建立請求操做 148 AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 149 NSString *savePath = [[self saveURL:nil deleteExistFile:NO] path]; 150 151 [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { 152 NSLog(@"已經接收到響應數據,數據長度爲%lld字節...", totalBytesRead); 153 154 [self updateProgress:totalBytesRead totalDataLength:totalBytesExpectedToRead]; 155 }]; 156 157 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 158 NSLog(@"已經接收完全部響應數據"); 159 160 NSData *data = (NSData *)responseObject; 161 [data writeToFile:savePath atomically:YES]; //responseObject 的對象類型是 NSData 162 163 [self updateProgress:100 totalDataLength:100]; 164 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 165 NSLog(@"下載失敗,錯誤信息:%@", error.localizedDescription); 166 167 [self updateProgress:-1 totalDataLength:-1]; 168 }]; 169 170 //啓動請求操做 171 [operation start]; 172 } 173 174 - (IBAction)downloadFileBySession:(id)sender { 175 //建立請求 176 NSMutableURLRequest *request = [self downloadRequest]; 177 178 //建立會話配置「進程內會話」 179 NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 180 sessionConfiguration.timeoutIntervalForRequest = 60.0; //請求超時時間;默認爲60秒 181 sessionConfiguration.allowsCellularAccess = YES; //是否容許蜂窩網絡訪問(2G/3G/4G) 182 sessionConfiguration.HTTPMaximumConnectionsPerHost = 4; //限制每次最多鏈接數;在 iOS 中默認值爲4 183 184 //建立會話管理器 185 AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration]; 186 187 //建立會話下載任務,而且啓動他;在非主線程中執行 188 NSURLSessionDownloadTask *task = [sessionManager 189 downloadTaskWithRequest:request 190 progress:nil 191 destination:^ NSURL*(NSURL *targetPath, NSURLResponse *response) { 192 //當 sessionManager 調用 setDownloadTaskDidFinishDownloadingBlock: 方法,而且方法代碼塊返回值不爲 nil 時(優先級高),下面的兩句代碼是不執行的(優先級低) 193 NSLog(@"下載後的臨時保存路徑:%@", targetPath); 194 return [self saveURL:response deleteExistFile:YES]; 195 } completionHandler:^ (NSURLResponse *response, NSURL *filePath, NSError *error) { 196 if (!error) { 197 NSLog(@"下載後的保存路徑:%@", filePath); //爲上面代碼塊返回的路徑 198 199 [self updateProgress:100 totalDataLength:100]; 200 } else { 201 NSLog(@"下載失敗,錯誤信息:%@", error.localizedDescription); 202 203 [self updateProgress:-1 totalDataLength:-1]; 204 } 205 206 [_hud hide:YES]; 207 }]; 208 209 //相似 NSURLSessionDownloadDelegate 的方法操做 210 //- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite; 211 [sessionManager setDownloadTaskDidWriteDataBlock:^ (NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { 212 NSLog(@"已經接收到響應數據,數據長度爲%lld字節...", totalBytesWritten); 213 214 [self updateProgress:totalBytesWritten totalDataLength:totalBytesExpectedToWrite]; 215 }]; 216 217 //- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location; 218 [sessionManager setDownloadTaskDidFinishDownloadingBlock:^ NSURL*(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location) { 219 NSLog(@"已經接收完全部響應數據,下載後的臨時保存路徑:%@", location); 220 return [self saveURL:nil deleteExistFile:YES]; 221 }]; 222 223 [task resume]; 224 } 225 226 @end
AFNetworkingViewController.xib
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3 <dependencies> 4 <deployment identifier="iOS"/> 5 <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/> 6 </dependencies> 7 <objects> 8 <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AFNetworkingViewController"> 9 <connections> 10 <outlet property="btnDownloadFileByConnection" destination="IkH-un-SOz" id="gDd-6X-uxU"/> 11 <outlet property="btnDownloadFileBySession" destination="mwt-p9-tRE" id="5Qk-Zm-V3w"/> 12 <outlet property="lblFileName" destination="dlB-Qn-eOO" id="NdS-9n-7KX"/> 13 <outlet property="lblMessage" destination="qlQ-nM-BXU" id="tRe-SR-AQE"/> 14 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> 15 </connections> 16 </placeholder> 17 <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> 18 <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> 19 <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> 20 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 21 <subviews> 22 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="metro_demo使用Highcharts實現圖表展現.zip" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dlB-Qn-eOO"> 23 <rect key="frame" x="145" y="104" width="309.5" height="18"/> 24 <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> 25 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> 26 <nil key="highlightedColor"/> 27 </label> 28 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mwt-p9-tRE"> 29 <rect key="frame" x="175" y="520" width="250" height="40"/> 30 <constraints> 31 <constraint firstAttribute="width" constant="250" id="I5D-tA-ffH"/> 32 <constraint firstAttribute="height" constant="40" id="Y8C-D4-IVr"/> 33 </constraints> 34 <state key="normal" title="基於 NSURLSession 的下載"> 35 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 36 </state> 37 <connections> 38 <action selector="downloadFileBySession:" destination="-1" eventType="touchUpInside" id="z6s-cq-dag"/> 39 </connections> 40 </button> 41 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qlQ-nM-BXU"> 42 <rect key="frame" x="145" y="140" width="37.5" height="18"/> 43 <fontDescription key="fontDescription" type="system" pointSize="15"/> 44 <color key="textColor" red="0.0" green="0.50196081399917603" blue="1" alpha="1" colorSpace="calibratedRGB"/> 45 <nil key="highlightedColor"/> 46 <userDefinedRuntimeAttributes> 47 <userDefinedRuntimeAttribute type="string" keyPath="text" value=""/> 48 </userDefinedRuntimeAttributes> 49 </label> 50 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IkH-un-SOz"> 51 <rect key="frame" x="174" y="460" width="250" height="40"/> 52 <constraints> 53 <constraint firstAttribute="width" constant="250" id="3a7-Og-iWa"/> 54 <constraint firstAttribute="height" constant="40" id="mc0-yK-hWE"/> 55 </constraints> 56 <state key="normal" title="基於 NSURLConnection 的下載"> 57 <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> 58 </state> 59 <connections> 60 <action selector="downloadFileByConnection:" destination="-1" eventType="touchUpInside" id="1ko-jP-kCo"/> 61 </connections> 62 </button> 63 </subviews> 64 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> 65 <constraints> 66 <constraint firstItem="mwt-p9-tRE" firstAttribute="top" secondItem="IkH-un-SOz" secondAttribute="bottom" constant="20" id="Sye-JW-gux"/> 67 <constraint firstAttribute="centerX" secondItem="dlB-Qn-eOO" secondAttribute="centerX" id="gNK-NO-rth"/> 68 <constraint firstItem="dlB-Qn-eOO" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="104" id="hwU-O2-Fed"/> 69 <constraint firstAttribute="centerX" secondItem="IkH-un-SOz" secondAttribute="centerX" constant="1" id="lF1-Yf-Axs"/> 70 <constraint firstAttribute="centerX" secondItem="mwt-p9-tRE" secondAttribute="centerX" id="teN-3t-8Gc"/> 71 <constraint firstItem="qlQ-nM-BXU" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="140" id="w3g-ej-P18"/> 72 <constraint firstItem="dlB-Qn-eOO" firstAttribute="leading" secondItem="qlQ-nM-BXU" secondAttribute="leading" constant="0.5" id="wMU-pU-z9f"/> 73 <constraint firstAttribute="bottom" secondItem="mwt-p9-tRE" secondAttribute="bottom" constant="40" id="yBq-He-Jv8"/> 74 </constraints> 75 </view> 76 </objects> 77 </document>
AppDelegate.h
1 #import <UIKit/UIKit.h> 2 3 @interface AppDelegate : UIResponder <UIApplicationDelegate> 4 5 @property (strong, nonatomic) UIWindow *window; 6 @property (strong, nonatomic) UINavigationController *navigationController; 7 8 @end
AppDelegate.m
1 #import "AppDelegate.h" 2 #import "ViewController.h" 3 4 @interface AppDelegate () 5 6 @end 7 8 @implementation AppDelegate 9 10 11 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 12 _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 13 ViewController *viewController = [[ViewController alloc] 14 initWithSampleNameArray:@[ kTitleOfNSURLConnection, 15 kTitleOfNSURLConnectionDelegate, 16 kTitleOfNSURLSession, 17 kTitleOfNSURLSessionDelegate, 18 kTitleOfAFNetworking]]; 19 _navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 20 _window.rootViewController = _navigationController; 21 //[_window addSubview:_navigationController.view]; //當_window.rootViewController關聯時,這一句無關緊要 22 [_window makeKeyAndVisible]; 23 return YES; 24 } 25 26 - (void)applicationWillResignActive:(UIApplication *)application { 27 } 28 29 - (void)applicationDidEnterBackground:(UIApplication *)application { 30 } 31 32 - (void)applicationWillEnterForeground:(UIApplication *)application { 33 } 34 35 - (void)applicationDidBecomeActive:(UIApplication *)application { 36 } 37 38 - (void)applicationWillTerminate:(UIApplication *)application { 39 } 40 41 @end