で重大な問題が発生してい[NSURLConnection sendAsynchronousRequest: queue: completionHandler:]
ます。ユーザーのログインと認証に REST プロキシを使用しています。ログインに使用するものは次のとおりです。
//Display the progress HUB
[SVProgressHUD showWithStatus:@"Signing Up..." maskType:SVProgressHUDMaskTypeClear];
NSError *error;
[self setUserCredentials];
//assign the parentView controller to the sender and email to the local class variables
parentView = sender;
userEmail = email;
// create json object for a users session
NSDictionary* session = [NSDictionary dictionaryWithObjectsAndKeys:
email, @"email",
password, @"password",
[NSDictionary dictionaryWithObjectsAndKeys:
[[UIDevice currentDevice] model], @"device",
[[UIDevice currentDevice] identifierForVendor].UUIDString, @"device_id",
@"APNS", @"push_to",
[[NSUserDefaults standardUserDefaults] stringForKey:@"push_id"], @"push_id",
nil],
@"mession",
nil];
NSData *jsonSession = [NSJSONSerialization dataWithJSONObject:session options:NSJSONWritingPrettyPrinted error:&error];
NSString *url = [NSString stringWithFormat:@"%@api/v1/messions.json", CoffeeURL];
NSLog(@"URL: %@", url);
NSURL *URL = [NSURL URLWithString:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%d", [jsonSession length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:jsonSession];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(@"Length: %d", data.length);
if (error == nil)
{
//if no error ocours set the user defualts and create the mession and log into the app
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *JSONResponse = [NSJSONSerialization JSONObjectWithData:[dataString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error: &error];
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@"JSON: %@", JSONResponse);
NSLog(@"Response: %d", httpResponse.statusCode);
if (JSONResponse != nil && httpResponse.statusCode == 200)
{
[self setUserDefualts:password sessionToUse:JSONResponse deckController:viewDeck sender:sender];
}
[SVProgressHUD dismiss];
}
else
{
NSLog(@"Error: %@", error);
//Dismiss progress HUB here and inform user that an internal error has occured
[SVProgressHUD dismiss];
NSString *errorString = @"Sorry, an error has occoured while connecting to the Coffee server.";
UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[errorAlertView show];
}
}];
有効なユーザー資格情報でログインすると、このコードは正しく機能します。無効な資格情報を使用すると、サーバーは 401 と null JSON オブジェクトを iOS クライアントに送信します。これは、error = nil
null 以外の有効な応答オブジェクトとともにステータス コード 401 を返す必要があります。何らかの理由でエラーが返され、応答は nil です。
Error: Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed.
(NSURLErrorDomain error -1012.)" UserInfo=0x1cd53b50
{NSErrorFailingURLKey=http://192.155.94.183/api/v1/messions.json,
NSErrorFailingURLStringKey=http://192.155.94.183/api/v1/messions.json,
NSUnderlyingError=0x1cdc2b10 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork
error -1012.)"}
これにより、リクエストの送信中に発生したエラーと、ユーザーの資格情報がバックエンドと一致しない場合にサーバーによって生成された 401 エラーを区別することが非常に難しくなっています。リクエストを作成して処理しようとしたとき:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
および NSURLDelegate:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"Called Outside!");
NSDictionary *jsonSession;
NSUserDefaults *userInfo = [NSUserDefaults standardUserDefaults];
NSLog(@"Succeeded! Received %d bytes of data", [responseData length]);
recievedResponse = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSError *err = nil;
jsonSession = [NSJSONSerialization JSONObjectWithData:[recievedResponse dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&err];
if ([connection.originalRequest.URL isEqual:[NSURL URLWithString:[NSString stringWithFormat:@"%@api/v1/messions.json", CoffeeURL]]])
{
NSLog(@"Status: %d", httpResponse.statusCode);
NSLog(@"JSON: %@", jsonSession);
NSLog(@"Called Inside!");
}
}
返された応答は有効であり、エラーはスローされず、ユーザーが無効な資格情報を入力すると、ステータス コードは 401 になります。なぜこれは機能するのに機能し(void)connectionDidFinishLoading:(NSURLConnection *)connection
ないの[NSURLConnection sendAsynchronousRequest: queue: completionHandler:]
ですか?