我一直在寻找这个问题的答案并且看到了很多类似的问题,但解决方案似乎与我的情况无关。我对iOS开发很新,所以任何帮助都会受到赞赏。
当前应用程序希望根据其网站生成的XML Feed显示城市中发生的事件。我将事件存储在plist中并在app load上明确检查新事件。目前的流程如下:
这是第二个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;
}
}
不确定这段代码是否显而易见,或者问题是什么,但是如果需要任何额外的代码/需要澄清我想要完成的事情,请告诉我。
由于
为了清晰起见,编辑 只是为了澄清,来自newEventsNeeded的NSLog会引发火灾,但只是委托方法不会被解雇。
答案 0 :(得分:2)
确保启动NSURLConnection
的线程有一个runloop。 NSURLConnection
的异步回调被分派到调用线程runloop上。如果调用线程(在这种情况下,它似乎是NSOperation
队列)没有runloop,或者它没有在默认的运行循环模式下运行,则不会看到任何委托回调。您对[self timeStampCheck]
的第一次调用是在主线程上,所以没关系。您以后的调用来自操作队列,可能没有runloop。
来自the documentation的相关摘录:
委托
连接的委托对象。代表将收到 在负载进行时委派消息。给代表的消息 将在调用此方法的线程上发送。用于连接 要正常工作,调用线程的运行循环必须在运行 默认的运行循环模式。