簡體   English   中英

未調用NSURLConnection委托方法

[英]NSURLConnection delegate methods are not being called

我正在嘗試使用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上針對此類問題的其他答案,也放入“ [the connection 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被解雇了,但是它的委托方法仍然沒有被解雇?

如果在其他線程中創建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);
}

}

當我想在並發的NSOperation中啟動NSURLConnection時,我也遇到了這個問題。 在主線程上執行連接可以幫助我解決問題。

- (void)start {

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

另外,在[NSRunLoop currentRunLoop]中安排連接的時間有助於我解決問題:

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

您可以在CSUtils框架的CSMessage類中了解它是如何完成的。 隨意使用給定的代碼: https : //github.com/cloverstudio/CSUtils

將委托放在您的class.h中,例如:

@interface InitViewController : UIViewController<NSURLConnectionDelegate,NSURLConnectionDataDelegate>

最后,我重新編寫了全堂課,並讓代表們解雇了。

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)並將其保存在設備上。

只需更改此行,並保持代碼中的原樣。 也保留scheduleInRunLoop行。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM