1

I've been trying to query Tesco's API Service. Although I've managed comfortably on Python with this, I have been having some trouble with making a request using Objective C. Nothing is being logged on the output. Any help would be appreciated. The program code is shown below:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];

        NSURL *url = [NSURL URLWithString:@"https://dev.tescolabs.com/product/?gtin=4548736003446"];
        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

        NSString *postParams = @"subscription key=93a6e21eed2e4ca3a858a0f1fc5aaf03";
        NSData *postData = [postParams dataUsingEncoding:NSUTF8StringEncoding];

        [urlRequest setHTTPMethod:@"GET"];
        [urlRequest setHTTPBody:postData];

        NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSLog(@"Response: %@",response);
            NSLog(@"Data: %@",data);
            NSLog(@"Error: %@",error);
        }];
        [dataTask resume];
    }
    return 0;
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579

5 Answers5

1

I had no choice but to present an answer ... Notice the runloop code:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];

        NSURL *url = [NSURL URLWithString:@"https://dev.tescolabs.com/product/?gtin=4548736003446"];
        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

        NSString *postParams = @"subscription key=93a6e21eed2e4ca3a858a0f1fc5aaf03";
        NSData *postData = [postParams dataUsingEncoding:NSUTF8StringEncoding];

        [urlRequest setHTTPMethod:@"GET"];
        [urlRequest setHTTPBody:postData];

        __block BOOL done = NO;
        NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSLog(@"Response: %@",response);
            NSLog(@"Data: %@",data);
            NSLog(@"Error: %@",error);
            done = YES;
        }];
        [dataTask resume];

        while (!done) {
            NSDate *date = [[NSDate alloc] initWithTimeIntervalSinceNow:0.1];
            [[NSRunLoop currentRunLoop] runUntilDate:date];
        }
    }
    return 0;
}
Mazyod
  • 22,319
  • 10
  • 92
  • 157
  • Best answer so far. The NSRunLoop works and finally got a response with that. Error is null and has status code of 500. Btw hide the details such as key. Thanks bud. –  May 01 '17 at 13:37
  • 1
    @Benge please read the docs, it says to assign the key as a header field, not in the post body. RTFM ;) https://devportal.tescolabs.com/docs/services/57f247f9e2813e07d8663943/operations/57f2518fe2813e07d8663945 – Mazyod May 01 '17 at 13:41
  • Mazyod, changed it to the header fields. Thank you. –  May 01 '17 at 13:44
  • Status of OK and data is returned. –  May 01 '17 at 13:50
1

Basically you need a run loop to perform a background task.

Your request does not work because the body POST data are not considered using a GET request.
All parameters must be passed in the URL.

To implement the run loop just use CFRunLoopRun() and CFRunLoopStop().

Do not use NSRunLoop ... runUntilDate with a while loop

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];

        NSURL *url = [NSURL URLWithString:@"https://dev.tescolabs.com/product/? ... "];

        NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithURL: url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSLog(@"Response: %@",response);
            NSLog(@"Data: %@",data);
            NSLog(@"Error: %@",error);
            CFRunLoopStop(CFRunLoopGetCurrent());
            exit(EXIT_SUCCESS);
        }];
        [dataTask resume];
    }

    CFRunLoopRun();
    return 0;
}
vadian
  • 274,689
  • 30
  • 353
  • 361
0

-dataTaskWithRequest:completionHandler: is asynchronous. You are queuing up an action which would be completed later then exiting the program before it completes.

You need a mechanism to wait for the data task to complete before exiting the program.

See: https://stackoverflow.com/a/34200617/1298400 for an example waiting mechanism.

Community
  • 1
  • 1
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
0

Try this u need to pass subscription key in header in this request

NSDictionary *headers = @{ @"ocp-apim-subscription-key": @"YourKey"};

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"YourURL"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];
Ravi Panchal
  • 1,285
  • 10
  • 22
0
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];

        NSURL *url = [NSURL URLWithString:@"https://dev.tescolabs.com/product/? ... "];

        NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithURL: url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSLog(@"Response: %@",response);
            NSLog(@"Data: %@",data);
            NSLog(@"Error: %@",error);
            CFRunLoopStop(CFRunLoopGetCurrent());
            exit(EXIT_SUCCESS);
        }];
        [dataTask resume];
    }

    CFRunLoopRun();
    return 0;
}