Objective-CでAFNetworking
を使用してJSON投稿を設定し、次のコードでサーバーにデータを送信しています。
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"name": deviceName, @"model": modelName, @"pin": pin};
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:@"Content-Type" forHTTPHeaderField:@"application/json"];
[manager POST:@"SENSORED_OUT_URL" parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(@"JSON: %@", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"Error: %@", error);
}];
同じリクエストで情報を受信していますが、データをNSString
に送信します。 AFNetworking
でそれを行うにはどうすればよいですか?
responseObject
はNSArrayまたはNSDictionaryです。実行時にisKindOfClass:
を使用して確認できます。
if ([responseObject isKindOfClass:[NSArray class]]) {
NSArray *responseArray = responseObject;
/* do something with responseArray */
} else if ([responseObject isKindOfClass:[NSDictionary class]]) {
NSDictionary *responseDict = responseObject;
/* do something with responseDict */
}
JSONの文字列が本当に必要な場合は、operation.responseString
を調べることで利用できます。
この場合、WebサービスがJSON
で応答すると、AFNetworking
がシリアル化を行い、responseObject
はおそらくNSArray
またはNSDictionary
オブジェクト。
このようなオブジェクトは、JSON
コンテンツを含む文字列よりも便利です。
私の場合、それは(多分それは助けることができる)のように見えます
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:url parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *jsonDict = (NSDictionary *) responseObject;
//!!! here is answer (parsed from mapped JSON: {"result":"STRING"}) ->
NSString *res = [NSString stringWithFormat:@"%@", [jsonDict objectForKey:@"result"]];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//....
}
];
また、応答オブジェクトのタイプをチェックするのも素晴らしいでしょう(例 https://stackoverflow.com/a/21962445/3628317 answer)
私は次のようにAFHTTPClientをサブクラス化するのが最も効果的だと思います:
// MyHTTPClient.h
#import <AFNetworking/AFHTTPClient.h>
@interface MyHTTPClient : AFHTTPClient
+ (instancetype)sharedClient;
@end
// MyHTTPClient.m
#import "MyHTTPClient.h"
#import <AFNetworking/AFJSONRequestOperation.h>
static NSString *kBaseUrl = @"http://api.blah.com/yada/v1/";
@implementation MyHTTPClient
+ (instancetype)sharedClient {
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (id)init {
if (self = [super initWithBaseURL:[NSURL URLWithString:kBaseUrl]]) {
self.parameterEncoding = AFJSONParameterEncoding;
[self setDefaultHeader:@"Accept" value:@"application/json"]; // So AFJSONRequestOperation becomes eligible for requests.
[self registerHTTPOperationClass:[AFJSONRequestOperation class]]; // So that it gets used for postPath etc.
}
return self;
}
@end
重要なビットは次のとおりです。
その後、次のように使用できます。
#import "MyHTTPClient.h"
@implementation UserService
+ (void)createUserWithEmail:(NSString *)email completion:(CreateUserCompletion)completion {
NSDictionary *params = @{@"email": email};
[[MyHTTPClient sharedClient] postPath:@"user" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
completion([responseObject[@"userId"] intValue], YES);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completion(0, NO);
}];
}
@end
この美しさは、responseObjectが自動的にJSON解析されて辞書(または配列)になることです。非常にきれいな。
(これはafnetworking 1.x用です)