Последующие NSURLConnections не запускают методы делегатов - PullRequest
1 голос
/ 10 августа 2011

Я искал ответы на этот вопрос повсюду и видел много подобных проблем, но решения, похоже, не относились к моей ситуации. Я очень новичок в разработке для iOS, поэтому любая помощь будет оценена.

Текущее приложение ищет события, происходящие в городе, на основе 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 =@"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;

} 

}

Не уверен, может ли из этого кода быть очевидным, в чем заключается проблема, но если нужен какой-либо дополнительный код / ​​необходимо разъяснение того, что я пытаюсь выполнить, пожалуйста, дайте мне знать.

Спасибо

редактировать для ясности Просто чтобы уточнить, NSLog из newEventsNeeded запускается, но только методы делегата не запускаются.

1 Ответ

2 голосов
/ 11 августа 2011

Убедитесь, что поток, начинающий NSURLConnection s, имеет цикл запуска.Асинхронные обратные вызовы NSURLConnection отправляются в поток выполнения вызывающих потоков.Если вызывающий поток (в данном случае это очередь NSOperation) не имеет цикла выполнения или если он не работает в режиме цикла выполнения по умолчанию, вы не увидите никаких обратных вызовов делегата.Ваш первый вызов [self timeStampCheck] находится в главном потоке, так что все в порядке.Ваши последующие вызовы поступают из очереди операций, которая, возможно, не имеет цикла выполнения.

Соответствующий фрагмент из документации :

делегат

Объект делегата для соединения.Делегат будет получать сообщения делегата по мере загрузки.Сообщения делегату будут отправлены в потоке, который вызывает этот метод.Для правильной работы соединения цикл выполнения вызывающего потока должен работать в режиме цикла выполнения по умолчанию.

...