【问题标题】:Sending HTTP GET Request using Objective-C使用 Objective-C 发送 HTTP GET 请求
【发布时间】:2015-03-15 00:37:35
【问题描述】:

我需要从 Parse API 查询一些数据。下面的代码是 Parse 的 CURL 示例:

curl -X GET \
  -H "X-Parse-Application-Id: XXXXX" \
  -H "X-Parse-REST-API-Key: XXXXX" \
  -G \
  --data-urlencode 'where={"key1":"value1","key2":"value2"}' \
  https://api.parse.com/1/classes/ClassName

那么,这是我实现这一目标的代码:

NSDictionary *dictionary = @{@"key1": @"value1", @"key1": @"value2"};
NSError *error = nil;
NSString *jsonString = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:kNilOptions error:&error];

if (!jsonData)
    NSLog(@"Got an error: %@", error);
else
    jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

NSString *fullUrl = [NSString stringWithFormat:@"https://api.parse.com/1/classes/ClassName?where=%@", jsonString];

NSURL *url = [NSURL URLWithString:fullUrl];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"GET"];
[request addValue:@"XXXXX" forHTTPHeaderField:@"X-Parse-Application-Id"];
[request addValue:@"XXXXX" forHTTPHeaderField:@"X-Parse-REST-API-Key"];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (!error) {
        NSLog(@"Data: %@", data);
        NSLog(@"Response: %@", response);
    }else{
        NSLog(@"Error: %@", error);
    }
}];
[task resume];

执行后,我遇到了一些错误:

2015-01-16 18:19:57.532 ParseTest[37964:1018046] 
Error: Error Domain=NSURLErrorDomain Code=-1002 
"The operation couldn’t be completed. (NSURLErrorDomain error -1002.)" 
UserInfo=0x7d17d320 {NSUnderlyingError=0x7d051f70 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1002.)"}

完成过去的 CURL 代码的 Objective-C 等效项是什么?或者你有什么建议?

提前致谢。

【问题讨论】:

    标签: objective-c curl parse-platform http-get


    【解决方案1】:

    NSURLErrorDomain error -1002 表示该 URL 不受支持。我的猜测是您需要对 where 参数的 json 进行 URL 编码。也许改变你的网址:

    if (!jsonData)
        NSLog(@"Got an error: %@", error);
    else
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    jsonString = [jsonString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    NSString *fullUrl = [NSString stringWithFormat:@"https://api.parse.com/1/classes/ClassName?where=%@", jsonString];
    

    如果这不起作用,您是否尝试过记录fullUrl 并尝试cURL

    【讨论】:

    • 感谢您的回答,现在我正在强制执行新错误:Error Domain=NSURLErrorDomain Code=-1005 "The operation couldn’t be completed. (NSURLErrorDomain error -1005.)" UserInfo=0x7aaa2160 {NSErrorFailingURLStringKey=https://api.parse.com/1/class/ClassName?where=%7B%22key1%22:%22value1%22,%22key2%22:%22value2%22%7D, _kCFStreamErrorCodeKey=57, NSErrorFailingURLKey=https://api.parse.com/1/class/ClassName?where=%7B%22key1%22:%22value1%22,%22key2%22:%22value2%22%7D, _kCFStreamErrorDomainKey=1, NSUnderlyingError=0x7ae494b0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1005.)"}
    • LoL 跟随 thread 重启我的 iOS 模拟器后,错误消失了 :)
    【解决方案2】:

    您需要使用PFQuery。相关信息可以在Parse's iOS/OS X Documentation 中找到。

    这里有一些示例代码,用于执行您在上面尝试的操作。它应该是该 cURL 代码的直接替代品:

    - (void)runQuery {
        PFQuery *query = [PFQuery queryWithClassName:@"ClassName"];
        [query whereKey:@"key1" equalTo:value1];
        [query whereKey:@"key2" equalTo:value2];
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (error != nil) {
                // Do error handling here
    
            } else {
                // You have a valid query result
    
            }
        }
         ];
    }
    

    请不要忘记,您需要先在应用中初始化 Parse 连接,然后才能拨打电话。这样,您就不需要像在 cURL 代码中那样在每个请求中传递您的密钥。您可以在 AppDelegate 对象的 -didFinishLaunchingWithOptions: 方法中执行此操作,如下所示:

    #import <Parse/Parse.h>
    @implementation AppDelegate
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Initialize Parse.
        [Parse
          setApplicationId:@"<App Id>"
          clientKey:@"<Client Key>"];
    
    }
    

    【讨论】:

    • 看起来 OP 并没有使用 Parse SDK。问题更多是关于构建一个 url 请求以匹配在 cURL 中完成的请求
    • 他问我们会推荐什么。如果他在 iOS 中写作(因为问题标记为 Objective-C),我会建议使用他们特定于平台的 SDK 来完成。我想他们也会。它也比手动编码每个 cURL 请求更简单,更不容易出错。
    • 有效点。我忽略了问题的一部分,要求提供替代建议。既然如此,您完全正确地认为这是与 Parse 进行通信的更好方法。当包装器已经以更有效的方式完成时,没有理由编写它
    • @Chris 是的,我认为他们知道优化和保护通信的最佳方式。另外,我没有时间重新发明轮子! ;-) 另外,我认为他的问题正是突出了我更喜欢使用他们的 SDK 的原因。我的代码比弄清楚所有 HTTP 通信更容易访问,因为这不是我的背景。
    • 感谢您的回答@mbm29414,无论如何这是我的学校任务,关于如何发送http get 请求。我选择 parse.com 作为我的云服务器。所以我不会使用 parse sdk 来解决我的任务,对不起。任何帮助将不胜感激:)
    猜你喜欢
    • 1970-01-01
    • 2016-04-26
    • 2023-04-02
    • 1970-01-01
    • 2023-03-18
    • 2016-01-25
    • 2020-08-24
    • 2013-02-15
    • 1970-01-01
    相关资源
    最近更新 更多