2015年1月21日 星期三

[Objective-C] 使用NSURLConnection - 來取得網站資料(NSURLConnectionDataDelegate)

使用NSURLConnection來取得網站資料有許多作法。

在此介紹使用NSURLConnectionDataDelegate Protocol來完成此目標

此方法是非同步下載,因此可以給使用者較好的體驗(不會卡住整個APP)

這個例子我們會從網站下載一個JSON文件,JSON文件的網址如下:

http://data.taipei.gov.tw/opendata/apply/json/RkRDNjk0QzUtNzdGRC00ODFCLUJBNDktNEJCMUVCMDc3ODFE

先加入NSURLConnectionDataDelegate到你的類別之中,並把你要下載的網站網址先準備好,最後再增加一個全域變數來接收資料。

static NSString * const KJSON = @"http://data.taipei.gov.tw/opendata/apply/json/RkRDNjk0QzUtNzdGRC00ODFCLUJBNDktNEJCMUVCMDc3ODFE";
@interface ViewController ()<NSURLConnectionDataDelegate>
{
    NSMutableData *datas;
}

加入一個Button,當按下它時,開始下載資料。
- (IBAction)btnPressed:(id)sender {
    NSURL *url = [NSURL URLWithString:KJSON];
    NSURLRequest *reques = [NSURLRequest requestWithURL:url];
    [NSURLConnection connectionWithRequest:reques delegate:self];
}

接著你必須實作NSURLConnectionDataDelegate的方法,在此選用這四個。

當你取得網站回應時會呼叫此方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

當你取得網站資料時會呼叫此方法
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

當遇到錯誤或失敗時會呼叫此方法
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;

當完成時會呼叫此方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;


一個一個來實作:

當取得網站回應的時候,把NSMutableData裡面的資料清空,從頭開始以保證資料完整性。
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"取得網站回應");
    [datas setLength:0];
}

取得資料的時候,將他加入NSMutableData之中。
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"取得資料");
    [datas appendData:data];
}

如果遇到失敗或錯誤,那一樣把資料先清空再說。
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"發生錯誤!");
    [datas setLength:0];
}

最後,下載完成的話,就可以拿這個資料來使用了。
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"下載完成");
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:datas options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"%@" , dict);
}