2014-01-08 43 views
3

我的iOS應用程序獲取內部代碼(例如101),並通過該代碼讀取服務器上的JSON文件(例如101.json)並讀取其中的數據。一切工作都很好,但如果服務器上沒有文件(對於那個代碼),如何做到這一點(現在如果找不到文件,它只顯示沒有數據),如果沒有互聯網連接只是從應用程序中的JSON文件中獲取數據?這是我的代碼:NSURLConnection獲取JSON文件

NSString *baseURLStr = @"http://myserverurl/"; 
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL 
                 URLWithString:[baseURLStr stringByAppendingFormat:@"%d/%d.json", int1, int2]]]; 
NSData *data = [NSURLConnection sendSynchronousRequest:request 
            returningResponse:nil error:nil]; 
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 

我發現如果沒有互聯網連接,應該如何閱讀應用程序中的文件。

if (data == nil){ 

    NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"FAILED" ofType:@"json"]]; 
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 
    self.members = json[@"data"]; 

} 
else { 

    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; 
    self.members = json[@"data"]; 

} 
+1

'sendSynchronousRequest:returningResponse:ERROR'我想'NSError'可以放,或檢查如果'NSData'不是零可以幫助... – Larme

+0

是的,你可以實際檢查'錯誤'(儘管我知道這是對「沒有淨」編程原則)。 –

回答

1

對於檢查互聯網連接是否可用,有很多資源你會得到這個。我通常使用的reachebility

if(reachable){ 

    // **Checking the file exist are not** 

    NSURLRequest *request; 
    NSURLResponse *response = nil; 
    NSError **error=nil; 
    NSData *data=[[NSData alloc] initWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:error]]; 
    NSString* retVal = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    // you can use retVal , ignore if you don't need. 
    NSInteger httpStatus = [((NSHTTPURLResponse *)response) statusCode]; 
    NSLog(@"responsecode:%d", httpStatus); 
    // there will be various HTTP response code (status) 

    if(httpStatus == 404) 
    { 
     // Url Not Exist 
    }else{ 
     // do your stuff 
    } 
} 
0
NSString *post = [NSString stringWithFormat:@"username=%@&pw=%@",@"username",@"raja"]; 
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[post length]]; 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://localhost/promos/index.php"]]; 


    [request setHTTPMethod:@"POST"]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setHTTPBody:postData]; 

    // NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:request delegate:self]; 
    // if(theConnection){ 
     // indicator.hidden = NO; 
     mutableData = [[NSMutableData alloc]init]; 
    // } 


    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 

    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
    { 
     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 
     if ([data length] >0 && error == nil && [httpResponse statusCode] == 200) 
     { 


      NSArray *dictionary = [NSJSONSerialization JSONObjectWithData:data   options:kNilOptions error:&error]; 

    } 

} 
9

有三種類型的問題,你可能要檢查:

  • 連接錯誤:檢查以確保連接沒有失敗;如果確實失敗,則數據將爲nil,並且將填充NSError對象;典型的原因是URL中的服務器名稱無效,服務器關閉,或根本沒有互聯網連接);

  • HTTP錯誤:如果做一個HTTP請求,要檢查Web服務器成功報道檢索頁/資源,即您收到的200 HTTP狀態代碼;一個錯誤情況的例子可能是一個404 - 找不到的錯誤(更多完整列表見HTTP Status Code Definitions);和

  • 服務器代碼中的錯誤:檢查,以確保服務器具有有效的JSON迴應,即檢查是否收到可以成功地解析爲JSON響應(你要確保有一個在服務器沒問題生成JSON的代碼,例如服務器代碼中的錯誤)。

因此:

NSURLRequest *request = nil; 
NSURLResponse *response = nil; 
NSError *error = nil; 
NSData *data = [NSURLConnection sendSynchronousRequest:request 
            returningResponse:&response 
               error:&error]; 
if (!data) { 
    NSLog(@"%s: sendSynchronousRequest error: %@", __FUNCTION__, error); 
    return; 
} else if ([response isKindOfClass:[NSHTTPURLResponse class]]) { 
    NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 
    if (statusCode != 200) { 
     NSLog(@"%s: sendSynchronousRequest status code != 200: response = %@", __FUNCTION__, response); 
     return; 
    } 
} 

NSError *parseError = nil; 
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; 
if (!dictionary) { 
    NSLog(@"%s: JSONObjectWithData error: %@; data = %@", __FUNCTION__, parseError, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); 
    return; 
} 

// now you can use your `dictionary` object 

顯然,如果它是NSArray的,改變上述JSONObjectWithData線返回陣列,但概念是相同的。

或者,更好,使用異步連接(如你不應該使用在主隊列同步連接):

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
    if (!data) { 
     NSLog(@"%s: sendAynchronousRequest error: %@", __FUNCTION__, connectionError); 
     return; 
    } else if ([response isKindOfClass:[NSHTTPURLResponse class]]) { 
     NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 
     if (statusCode != 200) { 
      NSLog(@"%s: sendAsynchronousRequest status code != 200: response = %@", __FUNCTION__, response); 
      return; 
     } 
    } 

    NSError *parseError = nil; 
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; 
    if (!dictionary) { 
     NSLog(@"%s: JSONObjectWithData error: %@; data = %@", __FUNCTION__, parseError, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); 
     return 
    } 

    // now you can use your `dictionary` object 
}]; 

// Note, with asynchronous connection, do not try to use `data` 
// or the object you parsed from theJSON after the block, here. 
// Use it above, inside the block. 
+0

我是新來的隊列等,我看到你說「你永遠不應該在主隊列上使用同步連接」,這對我來說很有意義,但是在你最後的代碼中,你告訴它是異步的,但是你提供' NSOperationQueue mainQueue]'..?這不就是同步使用它嗎?我們不應該提供另一個隊列嗎? – Sti

+2

該隊列參數是完成塊的隊列。請求仍然同步運行,但我們只是指定完成塊應該在主隊列上運行(如果(a)更新UI;或者(b)更新任何模型對象,這一點很重要)。如果你在這個完成塊中做的事情特別慢,你不會使用'[NSOperationQueue mainQueue]',而是使用其他一些隊列,並且只將最終的UI更新(或者你有什麼)分派到主隊列中。但在這種情況下,我們可能只需在主隊列上擁有完整的完成塊。 – Rob

+0

你是iOS的功夫大師 – Sayka