【问题标题】:Sending a NSMutableURLRequest request with "Body Requests"发送带有“正文请求”的 NSMutableURLRequest 请求
【发布时间】:2014-07-06 12:55:46
【问题描述】:

我目前正在使用 YouTube API 并允许用户订阅其他频道,但是现在我应该发送一个包含“请求正文”的 POST 方法。

这是我应该发送的请求:

POST https://www.googleapis.com/youtube/v3/subscriptions?part=snippet&key={YOUR_API_KEY}


//The Request Body

{
 "snippet": {
  "resourceId": {
   "channelId": "UCJZ7f6NQzGKZnFXzFW9y9UQ"
  }
 }
}

这是我当前的代码

+(void)subscribeToChannel:(NSString *)channelID {
    GTMOAuth2Authentication *auth;
    auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName clientID:clientIDclientSecret:clientSecret];


    NSString *urlStr;
    NSMutableURLRequest *request;        
    urlStr = [NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/subscriptions?id=%@&key=mykey", channelID];

    [request setHTTPBody:[@"{ \"snippet\": { \"resourceId\": { \"channelId\": \"UCJZ7f6NQzGKZnFXzFW9y9UQ\" } } }" dataUsingEncoding:NSUTF8StringEncoding]];

    NSURL *url = [NSURL URLWithString:urlStr];
    request = [NSMutableURLRequest requestWithURL:url];

    [request setHTTPMethod:@"POST"];


    [auth authorizeRequest:request
         completionHandler:^(NSError *error) {

             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                                      (unsigned long)NULL), ^(void) {


                 NSString *output = nil;
                 if (error) {
                     output = [error description];
                     NSLog(@"ERRO LOADING INFO : %@", output);
                 } else {
                     NSURLResponse *response = nil;
                     NSData *data = [NSURLConnection sendSynchronousRequest:request
                                                          returningResponse:&response
                                                                      error:nil];

                     if (data) {
                         output = [[NSString alloc] initWithData:data
                                                        encoding:NSUTF8StringEncoding];

                     } else {
                         output = [error description];
                     }
                 }



             });
         }];
}

我很肯定我在 [request setHTTPBody] 中做错了什么,但这是我唯一能想到的。

【问题讨论】:

    标签: ios objective-c youtube-api


    【解决方案1】:

    您在分配NSMutableURLRequest 的实例之前尝试设置NSMutableURLRequest 的HTTPBody。

        NSString *urlStr;
        // The request is nil
        NSMutableURLRequest *request;        
        urlStr = [NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/subscriptions?id=%@&key=mykey", channelID];
    
        // At this point the request is still nil so you are attempting to set the HTTPBody on a nil object
        [request setHTTPBody:[@"{ \"snippet\": { \"resourceId\": { \"channelId\": \"UCJZ7f6NQzGKZnFXzFW9y9UQ\" } } }" dataUsingEncoding:NSUTF8StringEncoding]]
    

    您还在评论中提到您收到“此 API 不支持解析表单编码输入”。错误。您可能会收到此错误,因为您没有设置内容类型(我通过谷歌搜索错误得出了这个结论。我可能错了)。

    这应该可行:

        NSString * urlStr = [NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/subscriptions?id=%@&key=mykey", channelID];
    
        NSURL *url = [NSURL URLWithString:urlStr];
        NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    
        [request setHTTPMethod:@"POST"];
    
        // Set the content type
        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
        // Create the dictionary that you will be using in the HTTPBody
        NSDictionary * httpBody = @{
                                  @"snippet": @{
                                        @"resourceId": @{
                                                @"channelId": channelID
                                                }
                                        }
                                  };
    
        // Make sure that the above dictionary can be converted to JSON data
        if([NSJSONSerialization isValidJSONObject:httpBody])
        {
            // Convert the JSON object to NSData
            NSData * httpBodyData = [NSJSONSerialization dataWithJSONObject:httpBody options:0 error:nil];
            // set the http body
            [request setHTTPBody:httpBodyData]; 
        }
    

    我在使用 Google Places API 搜索地点时会这样做,但它的工作原理应该是一样的。

    【讨论】:

    • 非常感谢,不过我现在收到此错误消息:“必需参数:部分”:(
    • 我傻了,我只是忘了在 url 中添加 ?part=sn-p。
    • 我也经常犯简单的错误,不用担心。我很高兴它对你有用!
    【解决方案2】:

    试试这个:-

    NSMutableDictionary *channelId = [[NSMutableDictionary alloc]init];
    [channelId setObject:@"UCJZ7f6NQzGKZnFXzFW9y9UQ" forKey:@"channelId"];
    NSMutableDictionary *resourceId = [[NSMutableDictionary alloc]init];
    [resourceId setObject:channelId forKey:@"resourceId"];
    
    NSDictionary * postDictionary = [NSDictionary dictionaryWithObject:resourceId forKey:@"snippet"];
    
    NSError * error = nil;
    NSData * jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:NSJSONWritingPrettyPrinted error:&error];
    [request setHTTPBody:jsonData];
    

    【讨论】:

    • 仍然无法正常工作:(,不过我认为您的方法是正确的。
    • "error": { "errors": [ { "domain": "global", "reason": "parseError", "message": "此 API 不支持解析表单编码的输入。” } ], "code": 400, "message": "此 API 不支持解析表单编码输入。" } }
    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 2017-08-31
    • 2016-02-11
    • 1970-01-01
    • 2019-06-05
    • 2016-08-24
    • 2019-03-15
    • 2022-01-25
    相关资源
    最近更新 更多