2

I am trying to get a simple GET request to work for my api. But it doesnt seem to work, and I am not sure why.

My code is as follows

Edit, also tried NSURLCredential But that does not seem to work either

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSString *urlAsString = @"https://www.test.com/api/v1/user/logout/";
    NSURL *url = [NSURL URLWithString:urlAsString];
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; [urlRequest setTimeoutInterval:30.0f];
    [urlRequest setHTTPMethod:@"GET"];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response,NSData *data, NSError *error) {
        if ([data length] >0 && error == nil){
            NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"HTML = %@", html); }
        else if ([data length] == 0 && error == nil){
            NSLog(@"Nothing was downloaded."); }
        else if (error != nil){
            NSLog(@"Error happened = %@", error); }
    }];

}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

My API spits out json. So I should be getting a json object back that says

success: False
reason: 'Already Logged out'

But instead it gives me the following error

2013-03-07 16:24:44.038 test[8957:1d03] Error happened = Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x715db20 {NSErrorFailingURLKey=https://www.test.com/api/v1/user/logout/, NSErrorFailingURLStringKey=https://www.test.com/api/v1/user/logout/, NSUnderlyingError=0x7181cb0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)"}

Method 2

after some reseach, I found another way of sending get requests, and this method seems to work fine

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSError *error = nil;
        NSURL *url = [NSURL URLWithString:@"https://www.test.com/api/v1/user/logout/"];
        NSString *json = [NSString stringWithContentsOfURL:url
                                                  encoding:NSASCIIStringEncoding
                                                     error:&error];
        if(!error) {
            NSData *jsonData = [json dataUsingEncoding:NSASCIIStringEncoding];
            NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                     options:kNilOptions
                                                                       error:&error];
            BOOL success = [[jsonDict objectForKey:@"success"] boolValue];
            if (!success) {
                NSString *reason = [jsonDict objectForKey:@"reason"];
                NSLog(@"Cannot log out, as user %@", reason);
            }
            //NSLog(@"JSON: %@", jsonDict);
        }else{
            NSLog(@"\nJSON: %@ \n Error: %@", json, error);
        }
    });
Jonathan
  • 2,728
  • 10
  • 43
  • 73
  • the `ErrorCode` 1012 correspond to `NSURLErrorUserCancelledAuthentication`, you will have to implement the method `connection:willSendRequestForAuthenticationChallenge:` of `NSURLConnectionDelegate`, see the [documentation](https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSURLConnectionDelegate/connection:willSendRequestForAuthenticationChallenge:) – tkanzakic Mar 07 '13 at 20:28
  • @tkanzakic thank you I will look into it. also is my approach correct for json fetching? – Jonathan Mar 07 '13 at 20:45
  • yes, it is, the *problem* is that you are using a secure protocol, you will have to manage the certificate validation, take a look the [this other question](http://stackoverflow.com/questions/10722272/ios5-willsendrequestforauthenticationchallenge-method-is-running-recursive), you will also find more info about it here in SO – tkanzakic Mar 07 '13 at 20:57
  • @tkanzakic last question, since this is just a logout request, and it does not require any authentication on the server's end, do I still have to use this? as this requires sending a username and password – Jonathan Mar 07 '13 at 21:25
  • this authentication is related to the `https` protocol, not about user authentication, you will have to validate the server certificate – tkanzakic Mar 07 '13 at 21:31
  • @tkanzakic I am sorry for bothering you so much, but please have a look at the edit I just made. I am extremely confused which is the right way to go about it. – Jonathan Mar 07 '13 at 21:36
  • there is no problem with the way you are performing the request, both of them are valid, the **problem** is that you are using a secure protocol (`https`), when using this protocol you have to validate the certificate, and is that is what is *failing* – tkanzakic Mar 07 '13 at 21:57
  • @tkanzakic but with the second method, it seems to work just fine. So if I stick with the second method, can I make post and delete requests with that? – Jonathan Mar 07 '13 at 22:01
  • @tkanzakic also, all the examples I am looking at for Authentication Challenge, they all send username and password. I am not sure how can I implement that in my senario. Can you please guide me in the right direction – Jonathan Mar 07 '13 at 22:09
  • @tkanzakic please have a look at the edit. – Jonathan Mar 07 '13 at 22:30
  • no, you can only send POST, PUT, DELETE, ... verbs using a `NSMutableURLRequest` – tkanzakic Mar 08 '13 at 09:39

1 Answers1

1

The solution to the problem was in the API itself. The API was supposed to send HTTPUnauthorized signal if the user is already logged out. And since that was the case, iOS was showing all these exceptions. when I dropped that and just sent back a simple json response, everything got fixed.

Jonathan
  • 2,728
  • 10
  • 43
  • 73