是否有 AFHTTPClient 使用 AFNetworking 发布 json 的示例?

Posted

技术标签:

【中文标题】是否有 AFHTTPClient 使用 AFNetworking 发布 json 的示例?【英文标题】:is there an example of AFHTTPClient posting json with AFNetworking? 【发布时间】:2011-12-11 22:36:06 【问题描述】:

寻找如何使用AFHTTPClient 发布 json 的示例。我看到有一个 postPath 方法采用NSDictionary,而 AFJSONEncode 方法返回一个NSData。有没有一种简单的方法可以将对象序列化为NSDictionary,或者有没有更简单的方法使用 jsonkit?

我只需要将对象作为 json 发布到 REST API。

更新:所以我尝试传递一个字典,但它似乎在序列化嵌套数组时中断。

例如,如果我有一个对象:

Post* p = [[Post alloc] init];
p.uname = @"mike";
p.likes =[NSNumber numberWithInt:1];
p.geo = [[NSArray alloc] initWithObjects:[NSNumber numberWithFloat:37.78583], [NSNumber numberWithFloat:-122.406417], nil ];
p.place = @"New York City";
p.caption = @"A test caption";
p.date = [NSDate date];

who's get dictionary 的数据如下:


    caption = "A test caption";
    date = "2011-12-13 17:58:37 +0000";
    geo =     (
        "37.78583",
        "-122.4064"
    );
    likes = 1;
    place = "New York City";


序列化要么直接失败,要么 geo 不会被序列化为数组,而是像("37.78583", "-122.4064");这样的字符串字面量

【问题讨论】:

【参考方案1】:

如果您要发布到 JSON REST API,应该有从对象属性到 JSON 键的特定映射,对吧?也就是说,服务器期望某些命名字段中的某些信息。

因此,您要做的是使用 API 中使用的键及其对应的值构造一个 NSDictionaryNSMutableDictionary。然后,只需将该字典传递给AFHTTPClient 中任何请求方法的parameters 参数。如果客户端的parameterEncoding属性设置为AFJSONParameterEncoding,那么请求的正文将自动编码为JSON。

【讨论】:

嘿,马特,我之前尝试过,但在嵌套 nsarray 时遇到了问题。它似乎工作正常,直到我使用我的地理属性,即两个 NSNumber 的 NSArray。它将作为带有转义字符的带引号的字符串传递,因此它被提交为 "(\n 43.1, \n -70.0)" 好的,所以如果我没有设置 json 序列化,我会得到那个有趣的格式,但是使用 json 序列化我在序列化 NSDate 时会出错。我可以将它传递给日期格式化程序,还是应该在将其传递给 AFNetworking 之前将其格式化为字典中的字符串? 通过将处理 NSDates 的块传递到 JSONDataWithOptions 方法中来使用 jsonkit 进行序列化...您认为将其返回到 afnetworking 请求中的最佳方法是什么? 确保将 NSDate 转换为 NSString 与日期格式化程序(查看 ISO8601Formatter),或发送 -description 嘿@mattt 你能看看这个问题***.com/questions/13219006/…【参考方案2】:

最好和最简单的方法是继承 AFHTTPClient。

使用这个代码sn-p

MBHTTPClient

#define YOUR_BASE_PATH @"http://sample.com"
#define YOUR_URL @"post.json"
#define ERROR_DOMAIN @"com.sample.url.error"

/**************************************************************************************************/
#pragma mark - Life and Birth

+ (id)sharedHTTPClient

    static dispatch_once_t pred = 0;
    __strong static id __httpClient = nil;
    dispatch_once(&pred, ^
        __httpClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:YOUR_BASE_PATH]];
        [__httpClient setParameterEncoding:AFJSONParameterEncoding];
        [__httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
        //[__httpClient setAuthorizationHeaderWithUsername:@"" password:@""];
    );
    return __httpClient;


/**************************************************************************************************/
#pragma mark - Custom requests

- (void) post<#Objects#>:(NSArray*)objects
success:(void (^)(AFHTTPRequestOperation *request, NSArray *objects))success
failure:(void (^)(AFHTTPRequestOperation *request, NSError *error))failure

    [self postPath:YOUR_URL
       parameters:objects
          success:^(AFHTTPRequestOperation *request, id JSON)
              NSLog(@"getPath request: %@", request.request.URL);

              if(JSON && [JSON isKindOfClass:[NSArray class]])
              
                  if(success) 
                      success(request,objects);
                  
              
              else 
                  NSError *error = [NSError errorWithDomain:ERROR_DOMAIN code:1 userInfo:nil];
                  if(failure) 
                      failure(request,error);
                  
              
          
          failure:failure];

然后在你的代码中调用

[[MBHTTPClient sharedHTTPClient]  post<#Objects#>:objects
                                          success:^(AFHTTPRequestOperation *request, NSArray *objects) 
    NSLog("OK");

                                          failure:(AFHTTPRequestOperation *request, NSError *error)
    NSLog("NOK %@",error);

objects 是一个 NSArray(你可以把它改成 NSDictonary)并且会被编码成 JSON 格式

【讨论】:

似乎不适用于最新版本的 AFNetworking。 postPath 需要一个 NSDictionary 作为参数。【参考方案3】:
 - (NSMutableURLRequest *)requestByPostWithNSArrayToJSONArray:(NSArray *)parameters

    NSURL *url = [NSURL URLWithString:@"" relativeToURL:self.baseURL];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setAllHTTPHeaderFields:self.defaultHeaders];

    if (parameters)
    
            NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding));
            NSError *error = nil;

            [request setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wassign-enum"
            [request setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error]];
#pragma clang diagnostic pop

            if (error) 
                NSLog(@"%@ %@: %@", [self class], NSStringFromSelector(_cmd), error);
            
    

    return request;

AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:[NSURL         URLWithString:URL_REGISTER_DEVICE]];
NSArray *array = @[@"hello", @"world"];
NSMutableURLRequest *request = [httpClient requestByPostWithNSArrayToJSONArray:array];


AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)

    NSLog(@"network operation succ");

 failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) 
    NSLog(@"network operation fail");

];

[operation start];

【讨论】:

试图格式化你的代码(不是很成功;-) - 请编辑和改进

以上是关于是否有 AFHTTPClient 使用 AFNetworking 发布 json 的示例?的主要内容,如果未能解决你的问题,请参考以下文章

使用GCD中的dispatch_semaphore(信号量)处理一个界面多个请求(把握AFNet网络请求完成的正确时机)

AFNet3.0上传图片

维护 RKObjectManager/AFHTTPClient 请求排序

AFNetworking 替换 - 替换为 AFHTTPClient

使用未声明的标识符 AFHTTPClient

使用 AFHTTPClient 将 JSON 作为 POST 请求的主体发布