1 #import <UIKit/UIKit.h> 2 3 @interface TWFXViewController : UIViewController 4 5 @property (retain,nonatomic) NSMutableData *weatherData; 6 7 @property (retain, nonatomic) IBOutlet UILabel *outlet_weatherInfo; 8 9 - (IBAction)btnClick_getWeather:(UIButton *)sender; 10 11 @end
1 // 2 // TWFXViewController.m 3 // DemoConnection 4 // 5 // Created by Lion User on 13-1-24. 6 // Copyright (c) 2013年 Lion User. All rights reserved. 7 // 8 9 #import "TWFXViewController.h" 10 11 @interface TWFXViewController () 12 13 @end 14 15 @implementation TWFXViewController 16 17 - (void)viewDidLoad 18 { 19 [super viewDidLoad]; 20 // Do any additional setup after loading the view, typically from a nib. 21 22 //label多行顯示 23 self.outlet_weatherInfo.numberOfLines = 0; 24 25 } 26 27 - (void)didReceiveMemoryWarning 28 { 29 [super didReceiveMemoryWarning]; 30 // Dispose of any resources that can be recreated. 31 } 32 33 - (IBAction)btnClick_getWeather:(UIButton *)sender { 34 35 NSString *strURL = @"http://m.weather.com.cn/data/101180601.html"; 36 37 //創建URL 38 NSURL *url = [[NSURL alloc] initWithString:strURL]; 39 40 //根據URL創建 NSURLRequest 請求 41 NSURLRequest *request = [[NSURLRequest alloc] 42 initWithURL:url 43 cachePolicy:NSURLRequestReloadIgnoringCacheData 44 timeoutInterval:60]; 45 46 //參數cachePolicy表示緩存策略,枚舉類型,值有以下幾種: 47 // 48 // enum 49 // { 50 // NSURLRequestUseProtocolCachePolicy = 0 NSURLRequest默認的cache policy,使用Protocol協議定義。是最能保持一致性的協議。 51 // NSURLRequestReloadIgnoringCacheData = 1 忽略緩存直接從原始地址下載 = NSURLRequestReloadIgnoringCacheData 52 // NSURLRequestReturnCacheDataElseLoad = 2 只有在cache中不存在data時才從原始地址下載 53 // NSURLRequestReturnCacheDataDontLoad = 3 只使用cache數據,如果不存在cache,請求失敗;用於沒有建立網絡連接離線模式; 54 // NSURLRequestReloadIgnoringLocalAndRemoteCacheData =4, 忽略本地和遠程的緩存數據,直接從原始地址下載,與NSURLRequestReloadIgnoringCacheData類似。 55 // NSURLRequestReloadRevalidatingCacheData = 5 驗證本地數據與遠程數據是否相同,如果不同則下載遠程數據,否則使用本地數據。 56 // }; 57 // typedef NSUInteger NSURLRequestCachePolicy; 58 59 60 61 //創建連接,該消息一發送下載會立即開始 62 //在代理(得了噶個)收到connectionDidFinishLoading:或者didFailWithError:消息之前 可以通過給連接發送一個cancel:消息來中斷下載 63 NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 64 65 [url release]; 66 [request release]; 67 68 if (connection) 69 { 70 //此時才創建NSMutableData 的實例,是否已晚?下載已經異步開始了 71 if (!_weatherData) { 72 73 self.weatherData = [NSMutableData data]; 74 } 75 } 76 else 77 { 78 NSLog(@"創建網絡連接失敗!"); 79 } 80 81 } 82 83 84 //當服務器提供了足夠客戶程序創建NSURLResponse對象的信息時,代理對象會收到 85 //一個connection:didReceiveResponse:消息,在消息內可以檢查NSURLResponse 86 //對象和確定數據的預期長途,mime類型,文件名以及其他服務器提供的元信息 87 88 //要注意,一個簡單的連接也可能會收到多個connection:didReceiveResponse:消息 89 //當服務器連接重置或者一些罕見的原因(比如多組mime文檔),代理都會收到該消息 90 //這時候應該重置進度指示,丟棄之前接收的數據 91 92 //反正當收到該信息就表示下載開始了(或者是重新開始了),把之前的數據清空即可 93 -(void)connection:connection didReceiveResponse:(NSURLResponse *)response 94 { 95 [self.weatherData setLength:0]; 96 97 //int expectedLength = [response expectedContentLength]; 該方法可以獲取將要下載的信息的大小(字節長度) 98 } 99 100 101 //當下載開始的時候,每當有數據接收,代理會定期收到connection:didReceiveData:消息 102 //代理應當在實現中儲存新接收的數據,下面的例子既是如此 103 //在下面的方法實現中,可以加入一個進度指示器,提示用戶下載進度 104 -(void)connection:connection didReceiveData:(NSData *)data 105 { 106 [self.weatherData appendData:data]; 107 108 // [data length]; 表示每次接收的信息的大小(字節長度) 109 } 110 111 112 //當下載的過程中有錯誤發生的時候,代理會收到一個connection:didFailWithError消息 113 //消息參數里面的NSError對象提供了具體的錯誤細節,它也能提供在用戶信息字典里面失敗的 114 //url請求(使用NSErrorFailingURLStringKey) 115 116 //當代理接收到連接的connection:didFailWithError消息后,該連接不會再收到任何消息,所以應該release掉 117 118 -(void)connection:connection didFailWithError:(NSError *)error 119 { 120 [connection release]; 121 122 // [_weatherData release]; 123 NSLog(@"Connection failed! Error - %@ %@", 124 [error localizedDescription], 125 [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]); 126 } 127 128 129 //最后,如果連接請求成功的下載,代理會接收connectionDidFinishLoading:消息 130 //該消息之后代理不會再收到其他任何的消息了,在消息的實現中,應該釋放掉連接 131 - (void)connectionDidFinishLoading: (NSURLConnection *) connection 132 { 133 //do something with the data 134 135 NSLog(@"succeeded %d byte receive",[self.weatherData length]); 136 [connection release]; 137 138 //調用函數解析下載到的json格式的數據 139 [self readJsonData]; 140 } 141 142 143 //解析下載到的json格式的數據 144 - (void)readJsonData 145 { 146 // NSJSONSerialization提供了將JSON數據轉換為Foundation對象(一般都是NSDictionary和NSArray) 147 //和Foundation對象轉換為JSON數據(可以通過調用isValidJSONObject來判斷Foundation對象是否可以轉換為JSON數據)。 148 149 NSError *error; 150 NSDictionary *weatherDic = [NSJSONSerialization JSONObjectWithData:self.weatherData 151 options:NSJSONReadingMutableContainers 152 error:&error]; 153 154 //option參數說明. 155 // enum { 156 // NSJSONReadingMutableContainers = (1UL << 0), //返回的容器是可變類型的(Array和Dictionary) 157 // NSJSONReadingMutableLeaves = (1UL << 1), //返回的葉子NSString是可變類型的; 158 // NSJSONReadingAllowFragments = (1UL << 2) //允許頂層的界面不是NSArray或NSDictionary; 159 // }; 160 // typedef NSUInteger NSJSONReadingOptions; 161 162 NSDictionary *weatherInfo = [weatherDic objectForKey:@"weatherinfo"]; 163 164 self.outlet_weatherInfo.text = [NSString stringWithFormat:@"今天是 %@ %@ %@ 的天氣狀況是:%@ %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]]; 165 166 } 167 168 -(void) dealloc 169 { 170 [_weatherData release]; 171 [_outlet_weatherInfo release]; 172 [super dealloc]; 173 } 174 175 176 @end