web-dev-qa-db-ja.com

afnetworking 3.0の移行:ヘッダーとHTTP本文でPOSTを実行する方法

Youtube APIへのHTTPHeaderフィールドとHTTPボディを持つPOSTリクエストを作成しようとしています。

以前は、AFNetworkingのバージョン2.0では、この方法でこれを実行していました。

NSDictionary *parameters = @{@"snippet": @{@"textOriginal":self.commentToPost.text,@"parentId":self.commentReplyingTo.commentId}};

NSString *url = [NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/comments?part=snippet&access_token=%@",[[LoginSingleton sharedInstance] getaccesstoken]];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters
   options:0
     error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

// And finally, add it to HTTP body and job done.
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];



AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer.timeoutInterval=[[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request progress:nil success:^(NSURLSessionTask *task, id responseObject) {
    NSLog(@"Reply JSON: %@", responseObject);


    }
} failure:^(NSURLSessionTask *operation, NSError *error) {
    NSLog(@"Error: %@, %@, %@, %@, %@", error, operation.responseObject, operation.responseData, operation.responseString, operation.request);

}];
[operation start];

バージョン3.0の移行ドキュメントはAFHTTPRequestOperationManagerAFHTTPSessionManagerに置き換えますが、HTTPRequestOperationWithRequestAFHTTPSessionManagerメソッドが見つからないようです。

constructingBodyWithBlockを使用してみましたが、正しく実行していないために動作しない可能性があります。

これは私がこれまでに持っているもので、うまくいきません:

NSDictionary *body = @{@"snippet": @{@"topLevelComment":@{@"snippet":@{@"textOriginal":self.commentToPost.text}},@"videoId":self.videoIdPostingOn}};

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body
   options:0
     error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
serializer.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue];
[serializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[serializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];


[manager POST:[NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/commentThreads?part=snippet&access_token=%@",[[LoginSingleton sharedInstance] getaccesstoken]] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {

    [formData appendPartWithHeaders:nil body:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];

}  progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"Reply JSON: %@", responseObject);

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"Error: %@, %@, %@, %@, %@", error, operation.responseObject, operation.responseData, operation.responseString, operation.request);

}];
27
Pranoy C

私はこれを自分で理解することができました。

これが解決策です。

最初に、NSMutableURLRequestからAFJSONRequestSerializerを作成する必要があります。最初に、メソッドタイプをPOSTに設定できます。

このリクエストでは、setHTTPBodyを設定した後、HTTPHeaderFieldsに到達します。 content-typeのヘッダーフィールドを設定した後、必ず本文を設定してください。設定しないと、APIが400エラーを返します。

次に、マネージャーで、上記のdataTaskWithRequestを使用してNSMutableURLRequestを作成します。最後にdataTaskをresumeすることを忘れないでください。さもないと、まだ何も送信されません。これが私のソリューションコードです。うまくいけば誰かがこれをうまく使うことができます:

NSDictionary *body = @{@"snippet": @{@"topLevelComment":@{@"snippet":@{@"textOriginal":self.commentToPost.text}},@"videoId":self.videoIdPostingOn}};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:[NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/commentThreads?part=snippet&access_token=%@",[[LoginSingleton sharedInstance] getaccesstoken]] parameters:nil error:nil];

req.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue];
[req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[req setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[req setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];


[[manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {

    if (!error) {
        NSLog(@"Reply JSON: %@", responseObject);

        if ([responseObject isKindOfClass:[NSDictionary class]]) {
              //blah blah
        }
    } else {
        NSLog(@"Error: %@, %@, %@", error, response, responseObject);
    }
}] resume];
33
Pranoy C

AFNetworking 3.0でPOSTメソッドを呼び出す別の方法は次のとおりです。

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

[manager POST:url parameters:parametersDictionary progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"success!");
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"error: %@", error);
    }];

それが役に立てば幸い!

64
Bruna Garcia

JSONを使用するHTTPBodyの場合

[sessionManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[sessionManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, id parameters, NSError * __autoreleasing * error) {

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:error];
    NSString *argString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    return argString;
}];

[sessionManager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {

    if (completion) {
        completion(responseObject, nil);
    }

} failure:^(NSURLSessionDataTask *task, NSError *error) {

    if (completion) {
        NSData *errorData = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.data"];
        NSDictionary *responseErrorObject = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingAllowFragments error:nil];
        completion(responseErrorObject, error);
    }
}];

カスタムストリング形式のHTTPBodyの場合

[sessionManager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[sessionManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, id parameters, NSError * __autoreleasing * error) {

    NSString *argString = [self dictionaryToString:parameters];
    return argString;
}];

[sessionManager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {

    if (completion) {
        completion(responseObject, nil);
    }

} failure:^(NSURLSessionDataTask *task, NSError *error) {

    if (completion) {
        NSData *errorData = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.data"];
        NSDictionary *responseErrorObject = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingAllowFragments error:nil];
        completion(responseErrorObject, error);
    }
}];
7
Igor Bachek
 -(void)postRequest:(NSString *)urlStr parameters:(NSDictionary *)parametersDictionary completionHandler:(void (^)(NSString*, NSDictionary*))completionBlock{
        NSURL *URL = [NSURL URLWithString:urlStr];

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        [manager POST:URL.absoluteString parameters:parametersDictionary progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            NSError* error;
            NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseObject
                                                                 options:kNilOptions
                                                                   error:&error];

            completionBlock(@"Success",json);
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"Error: %@", error);
            completionBlock(@"Error",nil);
        }];
    }

この方法は、AFNetworking 3.0では正常に機能しています。

6
Dolly Vaish

AFNetworking 3.0でWenservicesを呼び出すために共通のNSObject Classメソッドを使用するこれは私の重複回答ですが、それは AFNetworking 3.0で更新最初にNSObject Class LikeWebservice.hおよびWebservice.m

Webservice.h

@interface Webservice : NSObject

+  (void)requestPostUrl:(NSString *)strURL parameters:(NSDictionary *)dictParams success:(void (^)(NSDictionary *responce))success failure:(void (^)(NSError *error))failure;

@end

Webservice.mnsobject.mファイルは次のようになります。(。mファイルに2つの関数を追加します

#import "Webservice.h"

#define kDefaultErrorCode 12345

@implementation Webservice

+  (void)requestPostUrl:(NSString *)strURL parameters:(NSDictionary *)dictParams success:(void (^)(NSDictionary *responce))success failure:(void (^)(NSError *error))failure {

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager setResponseSerializer:[AFHTTPResponseSerializer serializer]];

    [manager POST:strURL parameters:dictParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if([responseObject isKindOfClass:[NSDictionary class]]) {
            if(success) {
                success(responseObject);
            }
        }
        else {
            NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];
            if(success) {
                success(response);
            }
        }

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if(failure) {
            failure(error);
        }

    }];
}

@end

応答コールバック関数の処理のために、辞書キーをsuccessおよびmessageに置き換える必要があることを確認してください

このように使用するanyviewcontroller.mおよびanyからこの共通メソッドを呼び出す任意のviewControllersのメソッド。一時的には、このWSの呼び出しにviewDidLoadを使用しています。

 - (void)viewDidLoad {
        [super viewDidLoad];

        NSDictionary *dictParam = @{@"parameter1":@"value1",@"parameter1":@"value2"};

        [Webservice requestPostUrl:@"add your webservice URL here" parameters:dictParam success:^(NSDictionary *responce) {
            //Success
            NSLog(@"responce:%@",responce);
            //do code here
        } failure:^(NSError *error) {
            //error
        }];
    }

上記の方法でパラメーター、値、およびWebサービスURLを追加します。このNSObjcetクラスを簡単に使用できます。詳細については、 AFNetworking 3. または AFNetworking 2.0を使用した私の古い不安 をご覧ください。

5
Vvk
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:log.text, @"email", pass.text, @"password", nil];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];

[manager POST:@"add your webservice URL here" parameters:dict progress:nil success:^(NSURLSessionTask *task, id responseObject) {
    NSLog(@"%@", responseObject);   
} 
failure:^(NSURLSessionTask *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];
4
Fuzuli

#Pranoy Cの受け入れられた回答はAFNetworking 3.0に変換されます

    NSError *writeError = nil;

    NSData* jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&writeError];
    NSString* jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData  timeoutInterval:120];

    [request setHTTPMethod:@"POST"];
    [request setValue: @"application/json; encoding=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setValue: @"application/json" forHTTPHeaderField:@"Accept"];
    [request setHTTPBody: [jsonString dataUsingEncoding:NSUTF8StringEncoding]];

    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

    [[manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {

        if (!error) {
            NSLog(@"Reply JSON: %@", responseObject);

            if ([responseObject isKindOfClass:[NSDictionary class]]) {
                //blah blah
            }
        } else {

            NSLog(@"Error: %@", error);
            NSLog(@"Response: %@",response);
            NSLog(@"Response Object: %@",responseObject);

        }
    }] resume];
4
nadim
/**
 *  Services gateway
 *  Method  get response from server
 *  @parameter              -> object: request josn object ,apiName: api endpoint
 *  @returm                 -> void
 *  @compilationHandler     -> success: status of api, response: respose from server, error: error handling
 */
+ (void)getDataWithObject:(NSDictionary *)object onAPI:(NSString *)apiName withController:(UIViewController*)controller
                         :(void(^)(BOOL success,id response,NSError *error))compilationHandler {


    controller = controller;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    // set request type to json
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];


    // post request to server
    [manager POST:apiName parameters:object success:^(AFHTTPRequestOperation *operation, id responseObject) {

        // NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject
                                                           options:0
                                                             error:&error];

        //NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
        //// 

        // check the status of API
        NSDictionary *dict = responseObject;
        NSString *statusOfApi = [[NSString alloc]initWithFormat:@"%@"
                                 ,[dict objectForKey:@"OK"]];

        // IF Status is OK -> 1 so complete the handler
        if ([statusOfApi isEqualToString:@"1"] ) {

            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            compilationHandler(TRUE,responseObject,nil);

        } else {

            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

            NSArray *errorMessages = [responseObject objectForKey:@"messages"];
            NSString *message = [errorMessages objectAtIndex:0];

            [Utilities showAlertViewWithTitle:apiName message:message];

            compilationHandler(FALSE,responseObject,nil);
        }

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSString *message = [NSString stringWithFormat:@"%@",[error localizedDescription]];
        NSLog(@"Message is %@", message);

        NSString *errorMessage = [NSString stringWithFormat:@"%@",[error localizedDescription]];
        if (!([message rangeOfString:@"The request timed out."].location == NSNotFound)) {
            [Utilities showAlertViewWithTitle:apiName message:errorMessage];
        }

        compilationHandler(FALSE,errorMessage,nil);
    }];

}