2011-08-10 29 views
1

我已經查看了所有問題的答案,並且看到了很多類似的問題,但解決方案似乎與我的情況無關。我對iOS開發非常陌生,所以不勝感激。後續的NSURLConnections不會觸發委託方法

目前的應用程序正在尋找基於他們的網站生成的XML提要顯示城市中發生的事件。我將事件存儲在plist中,並在應用程序加載時明確檢查新事件。目前的過程如下:

  • 應用程序啓動並使NSURLConnection檢查服務器的時間戳並下載它。
  • 檢查新下載的時間戳與本地時間戳,看看它是否更大。如果是,它會重寫包含plist的文件並觸發一個需要新事件的通知。

這是第二個NSURLConnection似乎沒有觸發的地方。回調方法本身觸發,但它似乎不像委託方法之後觸發。

奇怪的是,如果我同時調用兩個連接而不是另一個連接,他們都會觸發並調用委託方法。

下面是一些類有一些爲了清楚起見移除膽量的代碼:

應用程序委託:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

// Set up analytics account 

// Set the tab bar controller as the window's root view controller and display. 
self.window.rootViewController = self.tabBarController; 
[self.window makeKeyAndVisible]; 

//Set up listeners for event handling 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(timeStampResponse:) name:@"TimeStampResponse" object:nil];  

//Set app loading screen 

//Create new OperationQueue, set ActivityIndicator and run TimeStamp Check 
parseQueue = [NSOperationQueue new];  
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 
[self timeStampCheck]; 
return YES; 
} 
-(void)timeStampCheck { 
NSLog(@"Time Stamp Check, Creating Connection"); 
NSURLRequest *timeStampURLRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:kTimeStampURL]]; 
self.timeStampConnection = [[NSURLConnectionWithTag alloc] initWithRequest:timeStampURLRequest delegate:self startImmediately:YES tag:1]; 
} 

-(void)newEventsNeeded { 
NSLog(@"Event File Doesn't Exists or New File Needed, Creating Connection"); 
NSURLRequest *feedURLRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:kEventFeedURL]]; 
self.eventsFeedConnection = [[NSURLConnectionWithTag alloc] initWithRequest:feedURLRequest delegate:self startImmediately:YES tag:0]; 
} 

//Callback from DateStampParser 
-(void)timeStampResponse:(NSNotification *)notif { 
NSString *response = [[notif userInfo] objectForKey:@"TimeStampResponse"]; 
if ([response isEqualToString:@"NewEvents"]) { 
    [self newEventsNeeded]; 
    self.appLoadingViewController.loadingLabel.text = @"New Events Found..."; 
} else if ([response isEqualToString:@"NoNewEvents"]){ 
    [self allEventsLoaded]; 
} 
} 

而NSURLConnection的委託方法

-(void)connection:(NSURLConnectionWithTag *)connection didFailWithError:(NSError *)error { 
if (connection.tag == 0) { 
    NSLog(@"Connection failed on Event Feed"); 
} else if (connection.tag == 1) { 
    NSLog(@"Connection failed on Time Stamp Check"); 
} 
} 

-(void)connection:(NSURLConnectionWithTag *)connection didReceiveResponse:(NSURLResponse *)response{ 
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 
NSLog(@"connection:didRecieveResponse:NSHTTPURLResponse"); 
if ((([httpResponse statusCode]/100) == 2)) { 
    //Handling for eventsFeedConnection 
    if (connection.tag == 0) { 

     NSLog(@"Connection tag = 0"); 
     self.eventsData = [NSMutableData data]; 

    } else if (connection.tag == 1) { 

     NSLog(@"Connection tag = 1"); 
     //NSLog(@"Timestamp connection received response"); 
     self.timeStampData = [NSMutableData data]; 

    } 

} else { 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Network Error" message:@"No Response from the Server" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 
} 
} 

-(void)connection:(NSURLConnectionWithTag *)connection didReceiveData:(NSData *)data{ 
//Handling for eventsFeedConnection 
if (connection.tag == 0) { 

    self.appLoadingViewController.loadingLabel.text = @"Downloading Events..."; 
    [eventsData appendData:data]; 

} else if (connection.tag == 1) { 

    self.appLoadingViewController.loadingLabel.text [email protected]"Checking for New Events..."; 
    [timeStampData appendData:data]; 

} 
} 

-(void)connectionDidFinishLoading:(NSURLConnectionWithTag *)connection{ 
//Handling for eventsFeedConnection 
if (connection.tag == 0) { 

    NSLog(@"EventFeed Connection Finished"); 
    self.eventsFeedConnection = nil; 
    [eventsFeedConnection release]; 
    ParserOperation *parser = [[ParserOperation alloc] initWithData:self.eventsData]; 
    [parseQueue addOperation:parser]; 
    [parser release]; 
    self.eventsData = nil; 
    //[eventCategoryListViewController reenableRefreshButton]; 

} else if (connection.tag ==1){ 

    NSLog(@"TimeStamp Connection Finished"); 
    self.timeStampConnection = nil; 
    [timeStampConnection release]; 
    DateStampParser *parser = [[DateStampParser alloc] initWithData:self.timeStampData]; 
    [parseQueue addOperation:parser]; 
    [parser release]; 
    self.timeStampData = nil; 

} 

} 

不知道這個代碼是否顯而易見,或者不是w問題是,但如果需要任何額外的代碼/澄清我想要完成什麼,請讓我知道。

感謝

編輯爲清楚起見 只是爲了澄清,在從NSLog的火災newEventsNeeded,只是委託方法不被解僱。

+0

我無法看到您觸發通知的位置。它是否在你的問題中沒有顯示的代碼中? – Codo

+0

notif位於DateStampParser操作的末尾。它會觸發由timeStampResponse收到的notif。 – Chris

+0

我知道這是一個真正的舊帖子,但我只想提到我最終修復它的方式,只是通過使用ASI HTTP庫來規避真正的問題。 – Chris

回答

2

確保啓動NSURLConnection的線程有一個runloop。將NSURLConnection的異步回調分派到調用線程runloop上。如果調用線程(在這種情況下,它似乎是一個NSOperation隊列)沒有runloop,或者它沒有以默認運行循環模式運行,您將看不到任何委託回調。您的第一個電話[self timeStampCheck]在主線程中,所以這很好。以後的調用來自操作隊列,可能沒有runloop。

the documentation相關片段:

代表

用於連接的委託對象。隨着加載的進行,代表將收到 委託消息。到代理 的消息將在調用此方法的線程上發送。爲使連接 正常工作,調用線程的運行循環必須在 的默認運行循環模式下運行。

相關問題