2011-12-11 7 views
11

AFHTTPClientでjsonを投稿する方法の例をお探しください。私はNSDictionaryを取るpostPathメソッドがあり、AFJSONEncodeメソッドはNSDataを返すことがわかります。オブジェクトをNSDictionaryにシリアル化する簡単な方法はありますか?それとも、jsonkitを使う方が簡単ですか?には、AFNetworkingでjsonを投稿するAFHTTPClientの例がありますか?

オブジェクトをjsonとしてREST APIに送信するだけで済みます。

更新日:私は辞書を渡してみましたが、ネストされた配列のシリアライズを破るようです。例えば

、私はオブジェクトがある場合:

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

} 

シリアライズはあからさまに失敗するか、またはジオとしてシリアライズされません。辞書は、以下のようなデータを持ってもらうだ

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]; 

を配列ではなく文字列リテラルのように("37.78583", "-122.4064");

答えて

26

JSON REST APIに投稿する場合は、オブジェクトプロパティからJSONキーへの特定のマッピングですか?つまり、サーバーは特定の名前付きフィールドに特定の情報が必要です。

あなたがしたいことは、APIで使用されるキーとそれに対応する値でNSDictionaryまたはNSMutableDictionaryを構成することです。次に、辞書をAFHTTPClientの任意の要求メソッドのparameters引数に渡します。クライアントのparameterEncodingプロパティがAFJSONParameterEncodingに設定されている場合、リクエストの本文は自動的にJSONとしてエンコードされます。

+0

ちょっとマット、私は早くそれを試みていて、ネストされたnsarrayに問題がありました。 2つのNSNumbersのNSArrayである私の地理プロパティを取るまで、それは正常に動作するようです。それはエスケープ文字で引用された文字列として渡されるので、 "(\ n 43.1、\ n -70.0)"として送信されます。 – MonkeyBonkey

+0

jsonのシリアル化を設定しなかった場合、シリアライズNSDateをシリアライズする際にエラーが発生します。日付フォーマッタに渡すことはできますか?それをAFNetworkingに渡す前に辞書で文字列にフォーマットする必要がありますか? – MonkeyBonkey

+1

は、NSDatesをJSONDataWithOptionsメソッドに処理するためのブロックを渡すことで、jsonkitとシリアル化を行いました。これをafnetworkingリクエストに戻すにはどうすればよいでしょうか? – MonkeyBonkey

7

これを行う最も簡単な方法は、AFHTTPClientをサブクラス化することです。 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); 
} 

オブジェクトを呼び出す

使用このコードスニペット

はNSArrayの(あなたがNSDictonaryにそれを変更することができます)で、中にエンコードされますJSON形式

+0

AFNetworkingの最新バージョンでは動作しないようです。 postPathはNSDictionaryをパラメータとして想定しています。 –

0
- (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]; 
+0

あなたのコードをフォーマットしようとしました(過度に成功した;-) - 編集して改善してください – kleopatra

関連する問題