NSURLConnection没有回应

时间:2012-02-20 15:06:37

标签: iphone objective-c ios5 nsurlconnection nsurlrequest

我正在尝试从URL获取一些数据,但出于某种原因,当我执行以下操作时没有任何反应。达不到didReceiveResponse:didReceiveData:didFailWithError:connectionDidFinishLoading:,除非我通过执行此操作向我的请求添加超时:[request setTimeoutInterval:10.0]

这就是我正在做的事情:

-(void)getConfigFromServer{
    [self getContentAtURL:kUrlGetUser];
}

//Va chercher le contenu à l'URL passée en paramètre
- (void)getContentAtURL: (NSURL *)url {

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSString * userLogin = [userDefaults objectForKey:@"UserLogin"];
    NSString * userPassword = [userDefaults objectForKey:@"UserPassword"];
    NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:@"%@", url]];
    NSLog(@"Request : %@", [NSString stringWithFormat:@"%@", url]);
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:urlFinal];  
    [request setHTTPShouldHandleCookies:NO];
    [request setTimeoutInterval:10.0];

    NSString *sourceString = [NSString stringWithFormat:@"%@:%@", userLogin, userPassword]; 
    NSData * sourceData = [sourceString dataUsingEncoding:NSUTF8StringEncoding];  
    NSString *authString = [sourceData base64EncodedString];  

    authString = [NSString stringWithFormat: @"Basic %@", authString];
    [request setValue:authString forHTTPHeaderField:@"Authorization"];
    [request setValue:@"text/xml" forHTTPHeaderField:@"Accept"];
    NSURLConnection * connection=[NSURLConnection connectionWithRequest:request delegate:self];

    if(connection){
        NSLog(@"Connection started");
        receivedData = [NSMutableData data];
    }else{
        NSLog(@"Error while trying to initiate the connection");
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [receivedData setLength:0];
    if ([response respondsToSelector:@selector(statusCode)])
    {
        int statusCode = [((NSHTTPURLResponse *)response) statusCode];
        if (statusCode >= 400)
        {
            [connection cancel];  // stop connecting; no more delegate messages
            NSDictionary *errorInfo
                = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:
                NSLocalizedString(@"Server returned status code %d",@""),
                statusCode]
                    forKey:NSLocalizedDescriptionKey];
            NSError *statusError = [NSError errorWithDomain:@"Error"
                code:statusCode
                userInfo:errorInfo];
            [self connection:connection didFailWithError:statusError];
        }
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    NSLog(@"Connection failed! Error - %@ %@",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self fetchedData:receivedData];
}
编辑:我仍然遇到这个问题,现在也在实际的设备上。正如我在评论中所说,我第一次在这个应用程序上使用ARC,而我正在使用XCode 4.2。

有什么想法吗?

5 个答案:

答案 0 :(得分:5)

这是旧帖子,但这个答案仍然可以帮助那些人。

如果你在后台线程中调用它,请在调用委托之前检查线程是否正在退出。

尝试这样做。

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

[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] 
                      forMode:NSDefaultRunLoopMode];
[connection start];

答案 1 :(得分:0)

您正在将NSURL传递给您的getContentAtURL,但之后将其视为一个字符串:

NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:@"%@", url]];

尝试将其更改为:

NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:@"%@", [url absoluteString]]];
不过,你知道你没有使用你的登录名和密码吗?

编辑:

当你说receivedData = [NSMutableData data];什么是数据?

我认为这可能是问题所在。

我倾向于在数据首次到达时使用以下方法设置数据对象:

- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
    if (receivedData ==nil) { receivedData = [[NSMutableData alloc] initWithCapacity:2048]; } 
    [receivedData appendData:incrementalData];
}

答案 2 :(得分:0)

我认为问题出在服务器端。尝试将TimeoutInterval增加到60,这样就有更多时间从服务器获取数据。 10秒后你没有收到“连接超时”消息吗?

修改

嗨,我想你仍然没有找到解决方案。当我详细阅读代码时,我发现一些陈述令人困惑。

1)[request setValue:@"text/xml" forHTTPHeaderField:@"Accept"];替换为

    [request setValue:@"text/plain" forHTTPHeaderField:@"Accept"];

还包括,

    [request setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];

最后......

错误“连接超时”表示iPhone未从服务器接收任何数据。一旦iPhone获得数据再见,它就会调用- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data。尝试在每个语句之后放置NSLog以验证变量是否保持所需的值。在发送之前尝试检查数据的长度 - sourceData -

答案 3 :(得分:0)

正如您在评论中所说的那样,错误消息表示请求已超时。 我确信如果你删除超时行,你会在60秒后获得相同的响应或实际数据。确保你有足够的时间,因为如果由于某种原因你的连接非常弱,请求可能会在60秒后超时,因为它一直在下载数据。

启动时,您的应用是否处于前台?确保你没有暂停它。

此外,您说服务器在线,但您的代码已超时。毕竟意味着你的连接可能有问题。

在另一条评论中,你说它有时会起作用。甚至更多地指出连接弱/不可靠或分手的事实。

答案 4 :(得分:0)

这里有一些想法:

  1. 不要在UserDefaults中存储密码,使用钥匙串(也许你只是在测试,我只是想提到这个)
  2. 为什么要通过在网址上调用NSURL将您的NSURL网址转换为新的stringWithFormat:? (哦,我看到@ade已经提到过了)
  3. 这是一个 ARC 启用的应用程序吗?如果没有,您的NSMutableData将会过早自动释放,使用self.receivedData = [NSMutableData data]您将看到崩溃。
  4. 尝试将NSURLConnection变为实例变量并坚持下去。我认为它应该按照你现在的方式工作,但我倾向于坚持下去,从来没有遇到你在这里提到的问题。
  5. 很奇怪您的10秒超时似乎有效,我无法让它工作,并发现在iPhone上,超时不能低于240秒。是的,我也对此感到困惑,但是:https://stackoverflow.com/a/3611383/148335