2010-10-05 21 views
1

我查詢過這個論壇幾個小時尋找我的問題的想法/答案/解決方案,但每次都空出來。取消iPhone SDK中的SynchronousRequest。 (超時間隔不工作)

我已經使用以下創建的SynchronousRequest:

NSMutableURLRequest *theRequest = [[NSMutableURLRequest alloc] initWithURL:url]; 
    NSString *msgLength = [NSString stringWithFormat:@"%d", [params length]]; 
    [theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"]; 
    [theRequest setHTTPMethod:@"POST"]; 
    [theRequest setTimeoutInterval:3.0]; 
    [theRequest setCachePolicy:NSURLRequestReturnCacheDataElseLoad]; 
    [theRequest setHTTPBody: [params dataUsingEncoding:NSUTF8StringEncoding]]; 
    NSData *aData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error]; 

的連接被建立,並且該數據被成功地檢索到ADATA。 但是,當有連接問題,或者服務器不可用時,請求正在嘗試連接75秒這對於超時間隔來說太長時間了, 我已經添加了setTimeoutInterval參數(3秒)但它不影響連接,

我看到一些人說我應該使用NSTimer和runLoop, 一些答案,但我不清楚這應該如何實現。

請幫助!

用戶在得到超時錯誤消息之前等待75秒!這是可笑的

感謝您的幫助。

回答

4

在iPhone上,最小超時間隔是硬編碼到框架中的,您不能將超時設置爲低於75秒。蘋果公司這樣做是因爲在處理蜂窩數據連接時,經常會出現大量的延遲。

想要在中做什麼大多數情況下使用異步網絡連接(以便您的GUI不凍結),並允許請求在超時之前超過75秒。

閱讀Apple's instructions瞭解如何建立異步連接,這是一個很好的開始。

如果你確實要設置一個非常短的超時時間,你可以使用一個NSTimer這樣的:

- (void)loadURL:(NSURL *)url { 
    /* Set up the NSURLConnection here */ 

    [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(cancelURLConnection:) userInfo:nil repeats:NO]; 
} 

- (void)cancelURLConnection:(NSTimer)timer { 
    [self.connection cancel] 
} 

我不是在我的桌面上,這樣的代碼可能是越野車,它絕對是不完整的。另請注意,由於同步請求會阻止runloop,並且定時器在請求完成之前不會觸發,所以您不能輕鬆使用定時器來終止同步Web請求。

+0

謝謝你,我會檢查它,並讓你知道 – 2010-10-05 16:09:23

+1

+1:很好的答案甜蜜的堅果。 – Alan 2011-03-21 21:07:52

1

我可以建議看看simpleURLconnections的示例代碼嗎? 從該代碼中,NSMutableURLRequest使用

self.connection = [NSURLConnection connectionWithRequest:request delegate:self]; 

兩者檢索和發送數據發送(但看看的代碼的其餘部分)。也許問題在於sendSynchronousRequest,你可以避免使用它?

問候

+0

是的,問題是'sendSynchronousRequest:'。如果您在主線程上運行它,整個應用程序將阻塞,直到響應完成或請求失敗。這意味着主運行循環被阻塞,所以沒有定時器或響應事件。 – JeremyP 2010-10-05 15:28:51

+0

這正是我想要的,主線程 - 同步請求, – 2010-10-05 16:07:44

+0

因此,connectionWithRequest將無濟於事,因爲它將執行一個同步請求。 – 2010-10-05 16:08:09

0

你可以使用如下(從一個應用程序我正在拍攝)一些代碼 - isFinished是一個全局變量:

- (void)someMethod { 
    [[WSXMLRPCController sharedInstance] validateLicenseWithServiceURL:serviceUrl username:username password:password delegate:self]; 

    isFinished = NO; 
    NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:10]; // break the loop after 10 seconds and not finished with the request from the call above ... 
    while(!isFinished && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate]){ 
     if([endDate compare:[NSDate date]] == NSOrderedAscending){ 
      [self connection:nil didFailWithError:nil forMethod:nil]; 
     } 
    }  
} 


- (void)connection: (XMLRPCConnection *)connection didFailWithError: (NSError *)error forMethod: (NSString *)method { 
    isFinished = YES; 
} 

- (void)connection: (XMLRPCConnection *)connection didReceiveResponse: (XMLRPCResponse *)response forMethod: (NSString *)method { 
    isFinished = YES; 
} 

也許不是最乾淨的解決方案,但它作品。順便說一句,這段代碼正在使用WordPress XMLRPCConnection類和委託方法,但如果可能的話使用NSURLConnection類和委託方法。

+0

嘿,我看到你使用連接委託方法,(didReceiveResponse ...),因此它意味着你正在工作異步,而不是同步,它將與sendaSynchronousRequest一起工作? – 2010-10-05 16:11:42

+0

是否有任何特定的原因,你會更喜歡在你的情況下使用異步方法的同步方法? – 2010-10-07 06:56:21