0

I have been learning objective-C for a few months now. In that time i have been able to do a basic post request however i saw today a header of a post request that contains a nested dictionary. I am not sure how to pass data to such an API.

My question is how can i go about posting data to this API. I would appreciate if you could point to relevant reading material and tutorials with examples such as this complex API requests or give answers.

The API header looks like this:

    { "header":
   { "id": "2312b24c-5b83-46f0-8670-5edc2b1d1672",
     "parentId": "3gyy-w325e-bebd-ddsfsdf",
     "countryCode": "IRELAND",
     "timestamp": "2017-10-13T08:39:14.638Z" },
  "myinfo":
   { "User": "intro",
     "contactPerson": "Newbee",
     "contact": "00000000",
     "notes": "hey guys i am new"
       
   }
    
}

This is my code i need help with the multiple dictionaries.

    __block NSMutableDictionary *resultsDictionary;
      SMAMobileAPI *api = [SMAMobileAPI sharedSMAMobileAPI];
      NSMutableDictionary *bodyParams = [[NSMutableDictionary alloc]init];

      NSMutableDictionary *header = [[NSMutableDictionary alloc]init];
      [header setValue:@"2312b23c-5b83-46f0-8670-5edc2b1d1672" forKey:@"id"];
      [header setValue:@"2e3a015e-bebd-ddsfsdf" forKey:@"parentId"];
      [header setValue:@“IRELAND" forKey:@"countryCode"];
      [header setValue:@"2017-10-13T08:39:14.638Z" forKey:@"timeStamp"];

      NSMutableDictionary *myinfo = [[NSMutableDictionary alloc]init];
      [Case setValue:@“intro" forKey:@“User"];
      [Case setValue:@“newbie" forKey:@"contactPerson"];
      [Case setValue:@"+254 724474140" forKey:@"contactPersonNo"];
      [Case setValue:@"iOS case" forKey:@"notes"];

      [bodyParams setValue:header forKey:@"header"];
      [bodyParams setValue:myinfo forKey:@“myinfo"];

    if ([NSJSONSerialization isValidJSONObject:bodyParams]) {//validate it
        NSError* error = nil;
        NSData* jsonData = [NSJSONSerialization dataWithJSONObject:bodyParams options:NSJSONWritingPrettyPrinted error: &error];
        NSString *jsonString = [[NSString alloc] initWithData:jsonData 
 encoding:NSUTF8StringEncoding];
        NSURL* url = [NSURL URLWithString:@“my URL"];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
        [request setHTTPMethod:@"POST"];//use POST
        [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        [request setValue:[NSString stringWithFormat:@"%lu",(unsigned long)[jsonData length]] forHTTPHeaderField:@"Content-length"];
        [request setHTTPBody:jsonData];//set data
        __block NSError *error1 = nil;

        //use async way to connect network
        [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse* response,NSData* data,NSError* error)
        {
            if ([data length]>0 && error == nil) {
                resultsDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error1];
                NSLog(@"resultsDictionary is %@",resultsDictionary);
               [self hideLoading];

            } else if ([data length]==0 && error ==nil) {
                NSLog(@" download data is null");
                [self hideLoading];
            } else if( error!=nil) {
                NSLog(@" error is %@",error);
                [self hideLoading];
            }
        }];
    }
}
kaddie
  • 233
  • 1
  • 5
  • 27
  • AFNetworking makes things easier for Objective-C. See https://stackoverflow.com/questions/21487184/posting-json-data-using-afnetworking-2-0. – Mick Nov 28 '17 at 12:42
  • Thank you for the suggestion but i am still new to the language and i would like to understand how to do it the native way before i move to libraries. – kaddie Nov 28 '17 at 12:45
  • Valid request. Counter proposal: try to do a simple GET request with Objective-C and you might find it is not worth dealing with native networking. – Mick Nov 28 '17 at 12:56
  • I have done a GET and a POST using NSURLSession and NSURLSessionDataTask so far they dont really seem as bad. However these where all simple examples. But when it gets to these nested dictionaries i am not sure how i pass the dictionaries. – kaddie Nov 28 '17 at 13:01
  • With content-type "application/json" and the body would just be the plain text representation. The AFJSONRequestSerializer will take an Objective-C object and serialize it to JSON. Without that and without that concept of request serializers, you will have to do this step yourself. Serialize your object to JSON and use that JSON text as your request body. – Mick Nov 28 '17 at 13:08
  • Do u mean something like this – kaddie Nov 28 '17 at 13:21
  • NSString *stringData = [NSString stringWithFormat:@"id=%@&parentId=%@&countryCode=%@&timestamp=%@&User=%@&contactPerson=%@&contact=%@&notes=%@", value1 ,value2,value3,value4,value5,value6,value7,value8]; – kaddie Nov 28 '17 at 13:22
  • the problem i am having is constructing the second dictionary which is myinfo – kaddie Nov 28 '17 at 13:23
  • Apple already did this for you ;) https://developer.apple.com/documentation/foundation/jsonserialization – Mick Nov 28 '17 at 13:33
  • i have uploaded the code that works with other simple HTTP requests , however i just need help with the dictionary part – kaddie Nov 28 '17 at 13:55

1 Answers1

2

Seems like converting the NSDictionary to JSON is your actual problem. See documentation https://developer.apple.com/documentation/foundation/jsonserialization

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:yourDictionary
     options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData 
     encoding:NSUTF8StringEncoding];
Mick
  • 954
  • 7
  • 17
  • Thanks @Mick but i am also looking at this part NSDictionary *dict = @{@"key": value}; The creation of the dictionary or nested dictionaries from that header JSON is the first part i need to help with. I appreciate your help – kaddie Nov 28 '17 at 14:09
  • like this? *dict = @{@"key": @{@"nestedKey": nestedValue}} – Mick Nov 28 '17 at 14:28
  • let me implement it and get back to u – kaddie Nov 28 '17 at 14:32
  • i updated my code with your recommended code and it still doesnt work, it returns – kaddie Nov 29 '17 at 09:13
  • resultsDictionary is { message = "Internal server error"; } – kaddie Nov 29 '17 at 09:13
  • turns out my code is fine however i was just given a wrong url. Thank you once again for your answer. – kaddie Nov 29 '17 at 11:00