2012-03-22 48 views
2

我的應用程序中有以下代碼,用於從我的API加載一些數據。它工作正常,事實上在iOS 5中很好,但在iOS 4上,我收到很多狀態爲204的響應。iOS上的GCD網絡請求失敗4

這隻發生在iOS 4上,這可能被視爲API錯誤,但它的工作原理很好瀏覽器,Rested.app,iOS 5等...只有iOS 4失敗,它在模擬器和設備(iPhone 4)上失敗。

我每次將一個單元格加載到表視圖中時都會調用此代碼。我有一個帶有加載狀態的核心數據對象,如果它沒有被加載,那麼最初設置爲no。我執行這個代碼,如果它被加載,我跳過這段代碼。與此同時,我在桌子視圖的單元格內顯示一個微調框。

我相信它與在iOS 4

在GCD多個請求的問題任何人都可以點什麼毛病我的代碼片段?

-(void)myFunction{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     // query users participations (Network) 

     NSError * _urlError = nil; 
     NSString * url = [NSString stringWithFormat:@"my api url"]; 
     NSMutableURLRequest * loginHTTPRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 
     [loginHTTPRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 

     NSLog(@"Description: %@", [loginHTTPRequest description]); 

     NSHTTPURLResponse * _responseHeaders = nil; 
     NSData    * responseData  = [NSURLConnection sendSynchronousRequest:loginHTTPRequest 
                     returningResponse:&_responseHeaders 
                        error:&_urlError]; 
     if(_urlError != nil){ 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       // alert network connection error 
      }); 
      return; 
     } 

     NSString *json_string = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 

     SBJsonParser *parser = [[SBJsonParser alloc] init]; 
     NSDictionary * jsonData = [NSDictionary dictionaryWithDictionary:[parser objectWithString:json_string]]; 
     [json_string release]; 
     [parser release]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      // here [_responseHeaders statusCode] keeps returning 204 and there is nothing in responseData 

      // do some Core Data stuff 
     }); 

    }); 
} 

UPDATE

注意,如果連一個for循環反覆調用這個代碼工作正常,問題是,當我援引的tableView這個方法:的cellForRowAtIndexPath:

我有核心數據帶有屬性「isLoaded」的對象設置爲NO,並在遠程加載時將其更改爲YES。當我的tableview的數據源爲每個對象加載單元格時,如果對象的「isLoaded」屬性爲NO,tableView:cellForRowAtIndexPath:方法將調用此函數。

我懷疑問題可能是因爲有兩個或兩個以上的同時調用API發生在表加載和重新加載時。每個來自api的成功加載都會爲該tableview調用reloadData。

這讓我有一個預先填充的旋轉器tableview和異步加載在我的數據,因爲我需要它在屏幕上,這是很好,因爲我可以有效地使用NSFetchedResultsController與惰性加載我的對象的核心數據。我有一個端點爲所有我的對象返回一個對象id的數組 - 我創建的核心數據對象只有ID的,所有其餘的數據,名稱,日期等等等不會加載,直到它需要) 。

當我開始滾動創建/重用的新單元時,調用此方法,並且它們始終會獲得數據的200響應。它只是導致這個「塊」的第一次加載。

+0

是否有任何不尋常的iOS日誌語句可以看到?根據http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,204響應中的響應數據中不能包含任何內容。你是否控制它連接的服務器?那裏有不同的日誌嗎? – 2012-03-23 13:10:24

+0

另外 - sendSynchronousRequest在處理https方面確實有侷限性,通常你可以通過使用委託異步獲得更多信息(以複雜性爲代價)。這些http或https? – 2012-03-23 13:12:16

+0

嗨,它的HTTPS,我不控制服務器不幸的是,似乎如果我從應用程序委託或一個不同的類調用我的函數它會很好,但不是從我的表格視圖,這是在導航控制器,是什麼我正在執行此操作的上下文有點奇怪...... – Daniel 2012-03-23 15:15:17

回答

1

我想我發現了這個問題,我在一個異步GCD線程上執行同步請求,出於某種原因超時正在發生,但只在iOS 4的請求中,可能標頭與iOS 4稍有不同導致API花更長的時間來回應?或者,在異步線程中同步發送來自不同線程的多個請求(如同時發生的毫秒)請求在發送之前會在系統中發生衝突?

不管怎樣...這似乎並沒有這樣的情況叫google.com,甚至我自己的私人服務器,所以它必須是與頭和多個請求......

我使用來自github的asi http,它的工作效率更高,現在我不使用GCD來處理這些請求,只是一個ASI隊列。

有關iOS 4同步請求在異步GCD線程上執行的任何最終想法,可能的超時不受尊重並提前返回狀態204?

0

好的 - 如果是https,那麼你可能無法脫身使用sendSynchronousRequest。該文件指出,之類的東西[NSURLConnection connection:didReceiveAuthenticationChallenge:]不會調用一些關鍵的東西,即:

如果認證是爲了下載請求所需,所需要的憑據必須被指定爲URL的一部分。如果身份驗證失敗或憑據丟失,則連接將嘗試繼續,而無需憑據。

說實話,我仍然很驚訝它在iOS5上工作。我認爲你必須使用異步方法來至少調試它以查明發生了什麼。

+0

我只需要在某些API端點上提供基本身份驗證,但所有http都重定向到https,造成問題的一個是沒有額外頭文件的GET端點。 – Daniel 2012-03-23 16:51:08

+0

如果原因是iOS4沒有像iOS5一樣處理異步期望,則需要移到異步方法來證明它。 – 2012-03-24 00:52:33

+0

嗨,感謝您的反饋,我真的不認爲這是一個問題,我試圖在另一個測試應用程序中重新創建此問題,但我不能,也用更多的細節更新了問題,這是一個非常特殊問題,歡迎任何幫助和想法... – Daniel 2012-03-24 21:53:24

相關問題