0

I need to querying some data from Parse API. The code below is the example of CURL from Parse :

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

Then, this is my code to achieve that :

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

After executing, i've got some error :

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.)"}

What would be the Objective-C equivalent for accomplishing the past CURL code? Or what do you suggest?

Thanks in advance.

Alann Maulana
  • 1,170
  • 12
  • 15

2 Answers2

1

You need to use a PFQuery. Information for that can be found in Parse's iOS/OS X Documentation.

Here's some sample code for doing what you're attempting above. It should be a direct replacement for that cURL code:

- (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

        }
    }
     ];
}

Just don't forget that you need to initialize your Parse connection in your app before you can make calls. That way, you don't need to pass your keys with each request, as you do in your cURL code. You'd do that in your AppDelegate object's -didFinishLaunchingWithOptions: method, like so:

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

}
mbm29414
  • 11,558
  • 6
  • 56
  • 87
  • 1
    It doesn't look like OP is using the Parse SDK. The question is more about building a url request to match one done in `cURL` – Chris Jan 16 '15 at 15:54
  • He asked what we would recommend. If he's writing in iOS (since the question is flagged `Objective-C`), I'd **recommend** doing it with their platform-specific SDK. I think they would, too. It's also much more straightforward and less error-prone than hand-coding each of the `cURL` requests. – mbm29414 Jan 16 '15 at 17:36
  • Valid point. I overlooked the part of the question asking for an alternate suggestion. Being that's the case, you're completely right on this being the better approach to communicating with Parse. There's no reason to write a wrapper when it's already done in a more efficient manner – Chris Jan 16 '15 at 17:44
  • @Chris Yeah, I figure they know the best way to optimize and secure the communications. Plus, I don't have time to re-invent the wheel! ;-) Also, I think his question highlights **exactly** why I prefer to use their SDK. My code is a lot more accessible to me than figuring out all of the HTTP communications, since that's not my background. – mbm29414 Jan 16 '15 at 17:46
  • Thanks for your answer @mbm29414, anyway this is my school task about how to send an http get request. And I choose parse.com as my cloud server. So I won't use parse sdk to solve my task, sorry. Any help would be appreciated :) – Alann Maulana Jan 16 '15 at 23:44
1

NSURLErrorDomain error -1002 means the URL is unsupported. My guess is that you need to URL encode your json for the where argument. Maybe change making your URL to this:

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

If this doesn't work, have you tried logging fullUrl and try to cURL it?

Chris
  • 7,270
  • 19
  • 66
  • 110
  • Thanks for answering, now I'm forcing new error : `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.)"}` – Alann Maulana Jan 16 '15 at 23:48
  • LoL folowing this [thread](http://stackoverflow.com/questions/25797339/nsurlconnection-get-request-returns-1005-the-network-connection-was-lost) after restarting my iOS simulator, the error is gone :) – Alann Maulana Jan 17 '15 at 00:02