多种方式实现文件下载功能
(1)使用 NSURLConnection 直接方式
(2)使用 NSURLConnection 代理方式
(3)使用 NSURLSession 直接方式
(4)使用 NSURLSession 代理方式
(5)使用 AFNetworking 方式
附加功能:
(1)使用 AFNetworking 中的 AFNetworkReachabilityManager 来检查网络情况:
-
AFNetworkReachabilityStatusReachableViaWiFi:Wi-Fi 网络下
-
AFNetworkReachabilityStatusReachableViaWWAN:2G/3G/4G 蜂窝移动网络下
-
AFNetworkReachabilityStatusNotReachable:未连接网络
(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 1、NSURLRequestUseProtocolCachePolicy 协议缓存,根据 response 中的 Cache-Control 字段判断缓存是否有效,如果缓存有效则使用缓存数据否则重新从服务器请求 72 2、NSURLRequestReloadIgnoringLocalCacheData 不使用缓存,直接请求新数据 73 3、NSURLRequestReloadIgnoringCacheData 等同于 NSURLRequestReloadIgnoringLocalCacheData 74 4、NSURLRequestReturnCacheDataElseLoad 直接使用缓存数据不管是否有效,没有缓存则重新请求 75 5、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>