2015-06-04 2 views
0

Приведенный ниже код im используется для отправки данных на сервер, он работает fine.but иногда приложение собирается сбой и im получение этой ошибки "'NSInvalidArgumentException', reason: 'data parameter is nil'". Я проверил с подключением к Интернету, но интернет-соединение в порядке, без сомнения, о подключении. Как решить эту проблему.IOS 'NSInvalidArgumentException', причина: 'data parameter is nil'

NSString *url = [NSString stringWithFormat:@"http://myurl.com/test"]; 

NSString *username = [_emailLoginString 
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

NSString *password = [_passwordLoginString 
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

NSMutableString* requestURL = [[NSMutableString alloc] initWithString:url]; 

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: [NSString stringWithString:requestURL]]]; 
[request setHTTPMethod: @"POST"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"]; 
[request setHTTPBody:[[NSString stringWithFormat:@"username=%@&password=%@", 
username,password] dataUsingEncoding:NSUTF8StringEncoding]]; 

NSURLResponse *response; 
NSError *err; 

NSData *responseData = [NSURLConnection sendSynchronousRequest:request 
returningResponse:&response error:&err]; 

NSString *serverRplyLoginString = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding]; 

NSDictionary *dictobj=[NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&err]; 
    _serverRplyLoginString=[dictobj objectForKey:@"error"]; 

NSLog(@"Login Response Is :%@",_serverRplyLoginString); 

ответ

1

Прежде всего, я рекомендую вам всегда иметь Exception точку останова Enabled:

enter image description here

enter image description here

За исключением точек останова гораздо легче исправить сбой, так как приложение будет приостановлена ​​на точной строке, которая вызвала исключение. Теперь давайте вернемся к сбою:

Ваше приложение выходит из строя, потому что, как говорится в сообщении, параметр данных равен нулю. Где? Здесь:

NSDictionary *dictobj=[NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&err]; 

В то время как вы можете создать NSString с параметром данных ноля:

NSString *serverRplyLoginString = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding]; 

Вы не можете создать NSDictionary с помощью JSON сериализации с нулевым параметром данных. Я рекомендую вам проверить, соответствует ли ответ нулю и надлежащим образом обрабатывать эту ситуацию.

О, и последнее. Я настоятельно рекомендую вам использовать асинхронные запросы по сравнению с синхронизацией, потому что последний собирается заморозить основную очередь (т. Е. Сделать ваше приложение заикающимся). Вы можете сделать простой запрос асинхронной так:

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
    if (error || data == nil) { 
     // handle the error 
    } else { 
     // process the response data 
    } 
}]; 
+0

какая разница между асинхронными и синхронный запрос –

+0

Синхронная операция блокирует процесс до завершения операции. Асинхронная операция не блокируется и только инициирует операцию. Здесь: http://www.cs.unc.edu/~dewan/242/s07/notes/ipc/node9.html – Teo

0

Ваш код, который делает запрос:

NSString *url = [NSString stringWithFormat:@"http://myurl.com/test"]; 

NSString *username = [_emailLoginString 
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

NSString *password = [_passwordLoginString 
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

NSMutableString* requestURL = [[NSMutableString alloc] initWithString:url]; 

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: [NSString stringWithString:requestURL]]]; 
[request setHTTPMethod: @"POST"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"]; 
[request setHTTPBody:[[NSString stringWithFormat:@"username=%@&password=%@", 
username,password] dataUsingEncoding:NSUTF8StringEncoding]]; 

Modified для лучшей обработки ошибок

// declared so that chunk data will be handled 
__block NSMutableData *fragmentData = [NSMutableData data]; 

[[NSOperationQueue mainQueue] cancelAllOperations]; 

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
{ 
    //in case your data is chunked 
    [fragmentData appendData:data]; 

    if ([data length] == 0 && error == nil) 
    { 
     NSLog(@"No response from server"); 
    } 
    else if (error != nil && error.code == NSURLErrorTimedOut) 
    { 
     NSLog(@"Request time out"); 
    } 
    else if (error != nil) 
    { 
     NSLog(@"Unexpected error occur: %@", error.localizedDescription); 
    } 
    // response of the server without error will be handled here 
    else if ([data length] > 0 && error == nil) 
    { 
     // if all the data was successfully gather without error 
     if ([fragmentData length] == [response expectedContentLength]) 
     { 
      // finished loading all your data 

      // handle your response data here, in this example it's `fragmentData` 

      NSString *serverRplyLoginString = [[NSString alloc] initWithData:fragmentData/*responseData*/ encoding:NSASCIIStringEncoding]; 

      NSDictionary *dictobj=[NSJSONSerialization JSONObjectWithData:fragmentData/*responseData*/ options:kNilOptions error:&err]; 

      NSLog(@"Login Response Is :%@",serverRplyLoginString); 

      NSLog(@"dictobj :%@",dictobj); 
     } 
     // if fragmentDatas length is not equal to server response's expectedContentLength 
     // that means it is a chunked data and the other half of the data will be reloaded and `[fragmentData appendData:data];` will handle that 
    } 
}]; 
+0

Предположим, если я отправляю некоторые данные на сервер, используя Asynchronous, как получить ответ, bcz я должен показать ответ на пользователя. В этом случае можно использовать асинхронный. –

+0

под 'else if ([длина данных]> 0 && error == nil)' statement .. Я уже зарегистрировал его. NSLog (@ "Вход в систему:% @", serverRplyLoginString); NSLog (@ "dictobj:% @", dictobj); – 0yeoj