尝试发送POST请求时出错

时间:2017-01-17 09:07:06

标签: objective-c nsurlconnection nsurlrequest

我的网络服务器上有一个API,可以为我们的应用提供数据。 POST和GET请求可以与Postman或其他测试一起使用。 GET请求似乎在应用程序中正常工作,但POST请求返回时出现错误(在Xcode 8.2.1上使用iOS 10.2在iPhone 6模拟器上测试)。

Error Domain=NSURLErrorDomain Code=-1012 "(null)" 
UserInfo={NSErrorFailingURLStringKey=https://api.mysite.com/api/Device/Login, 
NSUnderlyingError=0x6000002487f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1012 "(null)" 
UserInfo={_kCFURLErrorAuthFailedResponseKey=<CFURLResponse 0x6000000fde00 [0x108d59df0]>
{url = https://api.mysite.com/api/Device/Login}}}, 
NSErrorFailingURLKey=https://api.mysite.com/api/Device/Login}

domain: @"NSURLErrorDomain" - code: 18446744073709550604

以下是创建POST请求的大部分功能:

-(NSString*)login:(NSString*)username password:(NSString*)password
{

NSString *deviceID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSString *deviceModel = [[UIDevice currentDevice] model];
NSString *deviceOS = [[UIDevice currentDevice] systemVersion];
NSString *deviceOSName = [[UIDevice currentDevice] systemName];
NSString *pushEnabled = @"False";

NSArray *userDictObjects = [NSArray arrayWithObjects:username, password, nil];
NSArray *userDictKeys = [NSArray arrayWithObjects:@"Username", @"Password", nil];
NSDictionary *userDict = [NSDictionary dictionaryWithObjects:userDictObjects forKeys:userDictKeys];

NSArray *deviceDictObjects = [NSArray arrayWithObjects:
                              deviceID,
                              deviceOSName,
                              deviceOS,
                              @"Apple",
                              deviceModel,
                              pushEnabled,
                              @"pushID", nil];
NSArray *deviceDictKeys = [NSArray arrayWithObjects:
                           @"DeviceID",
                           @"OS",
                           @"OSVersion",
                           @"Manufacturer",
                           @"Model",
                           @"PushEnabled",
                           @"PushID", nil];

NSDictionary *deviceDict = [NSDictionary dictionaryWithObjects:deviceDictObjects forKeys:deviceDictKeys];

NSArray *sectionsArrayObjects = [NSArray arrayWithObjects:userDict, deviceDict, nil];
NSArray *sectionsArrayKeys = [NSArray arrayWithObjects:@"User", @"Device", nil];

NSDictionary *sectionsDict = [NSDictionary dictionaryWithObjects:sectionsArrayObjects forKeys:sectionsArrayKeys];

NSLog(@"Json >  %@", sectionsDict);

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:sectionsDict options:0 error:nil];

NSString *conURL = [NSString stringWithFormat:@"%@/api/Device/Login", apiURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:conURL]];
[request setHTTPMethod:@"POST"];
[request addValue:@"application/json" forHTTPHeaderField:(@"content-type")];
[request addValue:@"application/json" forHTTPHeaderField:(@"accept")];
[request setHTTPBody:jsonData];  // This jsonData is populated elsewhere from a dictionary with [NSJSONSerialization dataWithJSONObject:sectionsDict options:0 error:nil];

NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *authenticated = @"No";

if (error == nil) {

    if (response) {

        NSHTTPURLResponse *newResp = (NSHTTPURLResponse*)response;
        NSLog(@"Authenticate - login - Response code - %li", (long)newResp.statusCode);

        if (data.length > 0 && error == nil) {

            NSLog(@"Authenticate - login - Data length - %li", (long)data.length);
            authenticated = @"Yes";

        } else {

            NSLog(@"Authenticate - login - Data length - %li", (long)data.length);
            NSLog(@"Authenticate - login - Error - %@", error);

        }

    } else {

        NSLog(@"Authenticate - login - No response - %@", response);

    }

} else {

    NSLog(@"Authenticate - login - login error - %li", (long)error.code);  // app currently gets here

    if (error.code != -1012) {

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"There was a problem!"
                                                                             message:@"The app is unable to login, the request timed out.  Please make sure there is an Internet connection and try again."
                                                                             delegate:self
                                                                cancelButtonTitle:@"Ok"
                                                               otherButtonTitles:nil];
            [alert setTag:2];
            [alert show];

    } else {

        NSLog(@"Authenticate - login - login error code - %li ", (long)error.code);  // app currently gets here

    }

}

我已尝试过HTTP和HTTPS,这没什么区别。我究竟做错了什么?如何在正文中成功发送包含JSON的POST请求?

更新

我创建了一个非常简单的测试方法来发送POST请求,这很好。我觉得问题与包装我需要发送的JSON以及服务器如何接收它有关。

工作测试:

NSString *string= [NSString stringWithFormat:@"http://api.mysite.com/api/Test/LoginSimplePost?username=%@&password=%@&portalid=%i",username,password,portalid];
NSLog(@"%@",string);
NSURL *url = [NSURL URLWithString:string];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSLog(@"responseData: %@", responseData);
NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(@"responseData: %@", str);

1 个答案:

答案 0 :(得分:0)

以下作品对我来说可能会对你有所帮助。

  - (void)UpdateUser:(NSDictionary *)userdetails {
      NSURL *url = [NSURL URLWithString:@"SOME URL"];
      NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
      request.HTTPMethod = @"POST";
      [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
      [request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
      NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userdetails options:NSJSONWritingPrettyPrinted error:nil]; //don't set error to nil, handle the error
      [request setHTTPBody:jsonData];
      NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
      [connection start];
    }

或其他情况

这是 kCFURLErrorUserCancelledAuthentication 错误,-10xx错误属于CFNetworkErrors枚举。这个常数的名称非常简单。服务器因某种原因取消了身份验证