将JSON发送到Schematic Ipsum

时间:2014-06-17 06:22:03

标签: ios json

我尝试从http://schematic-ipsum.herokuapp.com/获取一些随机JSON,但我收到了响应代码400.

以下是我使用

的代码
+ (NSArray *)postData:(NSDictionary *)arguments toServer:(NSString *)urlString
{
    NSArray *dataToReturn;

    // if urlString is nil, we default it to our server
    if(!urlString) urlString = JSON_SERVER;

    // of course we need to turn the string into a valid array
    NSURL *url = [NSURL URLWithString:urlString];

    /* 
        prepare the post
    */

    // we need to catch possible errors
    NSError *error;

    // turn our arguments into NSData
    NSData *postData = [NSJSONSerialization dataWithJSONObject:arguments options:0 error:&error];

    // we need the post' length
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];

    // create the url request
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];

    // here we'll check the server response
    NSHTTPURLResponse *response = nil;

    // here's our data from the server
    NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if ([response statusCode] >=200 && [response statusCode] <300)
    {
        // all good, let's see what we've got
        NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
        NSLog(@"Response ==> %@", responseData);

        // parse the response into a friendly format
        dataToReturn = [[NSArray alloc] initWithArray:[self returnJSONFromData:urlData]];
    } else {
        // somethin went wrong
        NSLog(@"Response code: %ld", (long)[response statusCode]);
        // check if it's our fault
        if (error) {
            NSLog(@"Server error: %@", [error localizedDescription]);
        }
    }

    // return our formatted array or nil
    return dataToReturn;
}

+ (NSArray *)returnJSONFromData:(NSData *)urlData
{
    NSArray *dataToReturn;

    NSError *e = nil;
    NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: urlData options: NSJSONReadingMutableContainers error: &e];

    if (!jsonArray) {
        NSLog(@"Error parsing JSON: %@", [e localizedDescription]);
        dataToReturn = @[e];
    } else {
        dataToReturn = [[NSArray alloc] initWithArray:jsonArray];
        NSLog(@"data from json: %@", dataToReturn);
    }

    return dataToReturn;
}

我正在调用它,使用他们网站上的演示JSON:

NSDictionary *post = @{ @"type": @"object", @"properties": @{ @"id": @{ @"type": @"string", @"ipsum": @"id" }, @"name": @{ @"type": @"string", @"ipsum": @"name" }, @"email": @{ @"type": @"string", @"format": @"email" } }};
[RetrieveDataFromServer postData:post toServer:@"http://schematic-ipsum.herokuapp.com/"];

1 个答案:

答案 0 :(得分:1)

你需要尊重&#34; Form Data&#34;的语法。服务器需要。要获得此功能,您可以使用Google Chrome&#34; Inspect Element&#34;,选择&#34; Network&#34;选项卡然后执行请求,您将看到:

enter image description here

查看&#34;表格数据&#34;部分,您将发现您的问题,因为您没有将正确的结构传递给服务器,因此服务器无法理解。 enter image description here

enter image description here

我使用了服务器的默认参数:

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "ipsum": "id"
    },
    "name": {
      "type": "string",
      "ipsum": "name"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "bio": {
      "type": "string",
      "ipsum": "sentence"
    },
    "age": {
      "type": "integer"
    },
    "avatar": {
      "type": "string",
      "ipsum": "small image"
    }
  }
}

因此数据的结构必须如下:

type:object
properties[id][type]:string
properties[id][ipsum]:id
properties[name][type]:string
properties[name][ipsum]:name
properties[email][type]:string
properties[email][format]:email
properties[bio][type]:string
properties[bio][ipsum]:sentence
properties[age][type]:integer
properties[avatar][type]:string
properties[avatar][ipsum]:small image  

并且在将其发送到服务器之前不要忘记编码百分比,否则您将再次失败。 我试图实现一个方法来获取你的字典并返回格式化的表单数据,它适用于这种情况,但我不确定在更一般的上下文中。我会在这里发帖给你作为参考,它真的很乱,对不起,但我没有足够的时间发表评论。

- (NSString *)formatFormData:(NSDictionary *)dictionary
{
    NSMutableArray *arrayPrefix = [NSMutableArray array];
    NSMutableArray *arrayResult = [NSMutableArray array];
    [self structureString:dictionary arrayPrefix:arrayPrefix arrayResult:arrayResult];
    return [arrayResult componentsJoinedByString:@"&"];;
}

- (void)structureString:(NSDictionary *)dictionay arrayPrefix:(NSMutableArray *)arrayPrefix arrayResult:(NSMutableArray *)arrayResult
{
    for(NSString *key in dictionay.allKeys)
    {
        NSObject *obj = [dictionay objectForKey:key];
        if([obj isKindOfClass:[NSDictionary class]])
        {
            [arrayPrefix addObject:key];
            [self structureString:(NSDictionary *)obj arrayPrefix:arrayPrefix arrayResult:arrayResult];
        }
        else
        {
            NSMutableString *string = [[NSMutableString alloc] initWithString:@""];
            for(int i = 0; i < arrayPrefix.count; i++)
            {
                NSString *eachPrefix = arrayPrefix[i];
                if(i == 0)
                {
                    [string appendString:eachPrefix];
                }
                else
                {
                    [string appendString:[NSString stringWithFormat:@"[%@]", eachPrefix]];
                }

            }
            if(arrayResult.count == 0)
            {
                [string appendString:[NSString stringWithFormat:@"%@=%@", key, obj]];
            }
            else
            {
                [string appendString:[NSString stringWithFormat:@"[%@]=%@", key, obj]];
            }

            [arrayResult addObject:string];
        }
    }
}

在您当前的方法中,添加以下行:

- (NSArray *)postData:(NSDictionary *)arguments toServer:(NSString *)urlString
{
    // omitted

    // turn our arguments into NSData
    NSData *postData = [NSJSONSerialization dataWithJSONObject:arguments options:0 error:&error];
    NSString *stringTemp = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
    stringTemp = [self formatFormData:arguments];
    // encode form date before sending to server
    stringTemp = [stringTemp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    postData = [stringTemp dataUsingEncoding:NSUTF8StringEncoding];

    // omitted
}