NSURLConnection委托方法未被调用

时间:2014-01-31 08:35:32

标签: ios objective-c cocoa-touch nsurlconnection

我正在尝试使用NSURLConnection从Web服务器下载一组文件,但是在建立连接时,连接的委托方法永远不会被触发,因此文件永远不会被下载。我已经阅读了很多关于SO和其他来源的答案,并尝试过已经建议的修复但没有用,这让我觉得我在这里犯了一个不同的错误。

我有一个viewController(InitViewController.m),它加载另一个类的方法:

GetData *getDataInstance = [[GetData alloc] init];
[getDataInstance startUpdate]; 

然后GetData.m进行一些检查并运行负责获取文件的类:

GetFiles *getFilesInstance = [[GetFiles alloc] init];
[getFilesInstance doFilesNeedDownloading];

doFilesNeedDowngoading方法检查我们是否需要该文件,然后运行getFiles:

-(void)getFile//:(NSString *) fullURL
{

    // I have checked if the connection is run on the main thread and it is
    NSLog(@"Is%@ main thread", ([NSThread isMainThread] ? @"" : @" NOT"));

    NSURL *downloadURL = [NSURL URLWithString:fullURL];

    NSMutableURLRequest *dlRequest = [NSMutableURLRequest requestWithURL:downloadURL];
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:dlRequest delegate:self];

    [theConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

    [theConnection start];

    if(theConnection) { //me checking for connection which is 'true'
        NSLog(@"Connection for %@ worked", fullURL);
    } else {
        NSLog(@"Connection for %@ failed", fullURL);
    }

}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    responseData = [[NSMutableData alloc] init];
    NSString *fileName = [[NSURL URLWithString:fullURL] lastPathComponent];
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) objectAtIndex:0]stringByAppendingPathComponent:fileName];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
    file = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    [file seekToEndOfFile];

}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    [responseData appendData:data];
    [file seekToEndOfFile];
    [file writeData:data];

}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

    [file closeFile];

}

我最初在更新中的单独线程中触发了getDataInstance startUpdate,以使应用程序的“获取数据”部分与应用程序的“UI构建”部分分开,并认为这可能是问题但是现在我删除它,甚至根据SO上的这类问题的其他答案输入'[theConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]。

我确信我会错过一些非常明显的想法吗?

谢谢,

修改

我现在再次尝试了这个代码但是在initViewController中,所以这几乎是应用程序加载时触发的第一件事。这不再是在另一个类或线程等中。:

-(void)getFile
{
    fullURL = @"http://myURL.com/terms-and-conditions.txt";
    NSURL *downloadURL = [NSURL URLWithString:fullURL];
    NSMutableURLRequest *dlRequest = [NSMutableURLRequest requestWithURL:downloadURL];
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:dlRequest delegate:self];

    [theConnection start];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    responseData = [[NSMutableData alloc] init];
    NSString *fileName = [[NSURL URLWithString:fullURL] lastPathComponent];
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) objectAtIndex:0]stringByAppendingPathComponent:fileName];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
    file = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    [file seekToEndOfFile];   
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    [responseData appendData:data];
    [file seekToEndOfFile];
    [file writeData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

    [file closeFile];
}

getFile被解雇但是它的委托方法仍然没有被解雇?

5 个答案:

答案 0 :(得分:1)

如果在其他线程中创建NSURLConnection,则必须手动启动运行循环。

试试这个:

-(void)getFile
{

NSURL *downloadURL = [NSURL URLWithString:fullURL];

NSMutableURLRequest *dlRequest = [NSMutableURLRequest requestWithURL:downloadURL];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:dlRequest delegate:self];

[theConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run]; 
[theConnection start];

if(theConnection) { //me checking for connection which is 'true'
    NSLog(@"Connection for %@ worked", fullURL);
} else {
    NSLog(@"Connection for %@ failed", fullURL);
}

}

答案 1 :(得分:0)

当我想在并发NSOperation中启动NSURLConnection时,我也遇到了这个问题。 在主线程上执行连接帮助我解决了这个问题。

- (void)start {

    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(start)
                               withObject:nil
                            waitUntilDone:NO];
        return;
    }
}

在[NSRunLoop currentRunLoop]中安排sonnection也帮助我解决了这个问题:

self.connection = [[NSURLConnection alloc] initWithRequest:request
                                                  delegate:self
                                          startImmediately:NO];
[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
                           forMode:NSRunLoopCommonModes];
[self.connection start];

您可以看看它是如何在CSMtilage框架中的CSMessage类中完成的。您可以自己使用给定的代码:https://github.com/cloverstudio/CSUtils

答案 2 :(得分:0)

将委托放在class.h中,如:

@interface InitViewController : UIViewController<NSURLConnectionDelegate,NSURLConnectionDataDelegate>

答案 3 :(得分:0)

最后,我重写了整个班级并让代表们解雇。

NSString *currentURL = [NSString stringWithFormat:@"%@/api/sync", apiURL];
NSLog(@"URL = %@", currentURL);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:currentURL]];
[request addValue:@"application/json" forHTTPHeaderField:(@"Accept")];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

以下是现在解雇的代表:

- (void)connection:(FileURLConnection*)connection didReceiveResponse:(NSURLResponse *)response
{
    NSString *fileName = [[response URL] lastPathComponent];
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]stringByAppendingPathComponent:fileName];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
    connection.file = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
}
- (void)connection:(FileURLConnection *)connection didReceiveData:(NSData *)data
{
    [connection.file writeData:data];
}
- (NSCachedURLResponse *)connection:(FileURLConnection *)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse
{
    return nil;
}
- (void)connectionDidFinishLoading:(FileURLConnection *)connection
{
    [connection.file closeFile];
}
- (void)connection:(FileURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"GetFiles - didFailWithError - error : %@ for URL %@", error, connection.currentRequest.URL);
}

该课程现在下载文件(来自我自己的API)并将其保存在设备上。

答案 4 :(得分:-1)

只需更改此行并在代码中保持原样。保留scheduleInRunLoop行。

NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:request
                                                               delegate:self startImmediately:NO];