Obj-C POST JSON(正文?到端点问题

Obj-C POST JSON (body?)to endpoint problems

提问人:malaki1974 提问时间:4/30/2022 更新时间:4/30/2022 访问量:35

问:

在我的 Mac 上使用 Postman,我已经确认 GET/POST 适用于我的端点。在我的 iPad 上,我正在尝试做同样的事情,但只有 GET 连接并返回数据(仅用于 测试)。

在 Postman 中,我有设备的密钥和值 [{“name”:“1”,“values”:[121,182,243]}] 从 Postman 我可以发送,物理对象响应,服务器返回所有设备的数组,没有其他任何东西(我不需要,但就是这样)。Postman 在 Body 下确实有 x-www-form-urlencoded。这与 Postman 的预期一样工作。

在我的 iPad 上,以下代码总是返回错误 400,我认为这意味着我提供了服务器不期望的东西。

+(void)makeRequest {

NSError *error = nil;

storedURL = [[NSUserDefaults standardUserDefaults] objectForKey:@"eb-ipaddress-saved"];
NSString *urlstring = [NSString stringWithFormat:@"http://%@",storedURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlstring] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

NSString *jsonPostBody = @"{\"devices\":[{\"name\":\"1\",\"values\":[121,182,243]}]}";
NSData *postData = [jsonPostBody dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    if(httpResponse.statusCode == 200)
    {
        NSError *parseError = nil;
        NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
        NSLog(@"The response is - %@",responseDictionary);
        NSInteger success = [[responseDictionary objectForKey:@"success"] integerValue];
        if(success == 1)
        {
            NSLog(@"SUCCESS");
        }
        else
        {
            NSLog(@"FAILURE");
        }
    }
    else
    {
        NSLog(@"Error");
    }
}];
[dataTask resume];

}

我上面的 4 条日志(为清楚起见而删除)返回: urlstring http://192.168.90.55:3000/dmx/set jsonPostBody {“devices”:[{“name”:“1”,“values”:[121,182,243]}]} http响应 400 错误

在生产中,我最终会切换到 POST 中的变量。

谢谢

json objective-c 发布 nsurlsession

评论

1赞 Larme 4/30/2022
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];:您说您将以 URLEncoded 的形式发送参数,但您以 JSON 格式发送它们......我想这就是问题所在。这就像在说:我会用法语给你寄信,而你寄的实际上是中文......请注意,Postman 可以生成 Objective-C 代码,这些代码可以帮助您找到差异。
0赞 malaki1974 4/30/2022
我尝试了你的第一个想法,但仍然没有骰子。但是 - 你的结束语就是答案。Postman 生成的代码(不知道它可以做到这一点)在对添加 http:// 进行一次小的更正后起作用。

答:

0赞 malaki1974 4/30/2022 #1

多亏了 Larme 的回答,我使用了 Postman 的代码,并且奏效了。

+(void)makeRequest 
{

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.90.55:3000/dmx/set"]
  cachePolicy:NSURLRequestUseProtocolCachePolicy
  timeoutInterval:10.0];
NSDictionary *headers = @{
  @"Content-Type": @"application/x-www-form-urlencoded"
};

[request setAllHTTPHeaderFields:headers];
NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"devices=[{\"name\":\"1\",\"values\":[121,182,243]}]" dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postData];

[request setHTTPMethod:@"POST"];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  if (error) {
    NSLog(@"%@", error);
    dispatch_semaphore_signal(sema);
  } else {
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
    NSError *parseError = nil;
    NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
    NSLog(@"%@",responseDictionary);
    dispatch_semaphore_signal(sema);
  }
}];
[dataTask resume];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}

评论

0赞 Larme 5/1/2022
删除信号量,只需替换以前的代码,这样会更好。NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"devices=[{\"name\":\"1\",\"values\":[121,182,243]}]" dataUsingEncoding:NSUTF8StringEncoding]];