Help me choose
Internship/2020 year-end summer internship

JSON post request on Objective C

by hajinny 2021. 1. 15.

Yeah, post request; one of the tasks that requires certain level of understanding of what http request requires (header (including auth, content type) and body (json)), but also some expertise of the language. I've managed to make a json post request on objective c, though the asynchronous behaviour was only awaited through while loop (-.-). But asynchronous handling is not the most important part anyway, so let me just focus on the part where post request is implemented.

 

First of all, I have a main function (this main.m file is generated on making the project)

//main.m
#import <Foundation/Foundation.h>
#import "JsonUtil.h"
#import "Post.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Post *post = [[Post alloc] init];
        [post postRequestTo:@"https://dev.windcave.com/api/v1/transactions"];
        
    }
    return 0;
}

And I have some helper class for generating json and reading json with dictionary (I've just put them in one code block, but the top one belongs to JsonUtil.h and the bottom one belongs to JsonUtil.m; note the comments below).

// JsonUtil.h

@interface JsonUtil : NSObject

+ (NSString *)jsonToReadable:(NSData *)json;
- (NSDictionary *) makeJsonBodyInDictionary;
- (NSData *) dictionaryToJsonNSData:(NSDictionary *)dictionary;
- (NSString *) NSDataToString:(NSData *)data;
- (NSDictionary *)jsonNSDataToDictionary:(NSData *)data;
@end

// JsonUtil.m

#import <Foundation/Foundation.h>
#import "JsonUtil.h"

@implementation JsonUtil:NSObject

+ (NSString *)jsonToReadable:(NSData *)json{
    NSString *string = [[NSString alloc] initWithData:json encoding:(NSStringEncoding)NSUTF8StringEncoding];
    return string;
}
// make dictionary object for testing purpose
- (NSDictionary *)makeJsonBodyInDictionary{
    return @{
        @"type": @"purchase",
        @"amount": @"10.00",
        @"currency": @"NZD",
        @"card": @{
                @"cardNumber": @"4111111111111111",
                @"dateExpiryYear": @"23",
                @"dateExpiryMonth": @"10",
                @"cvc2": @"000"
        }
    };
}

// dictionary to NSData json (readable by endpoints
- (NSData *)dictionaryToJsonNSData:(NSDictionary *)dictionary{
    return [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
}

// helper method to see NSData in string. more preferrable to use jsonNSDataToDictionary
- (NSString *)NSDataToString:(NSData *)data{
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

//NSData json is converted to dictionary
- (NSDictionary *)jsonNSDataToDictionary:(NSData *)data{
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    return dictionary;
}

@end

Then I have a Post.h & Post.m files that actually makes the request.

// Post.h
@interface Post : NSObject
- (void) postRequestTo:(NSString *)url;
@end

// Post.m

#import <Foundation/Foundation.h>
#import "Post.h"
#import "JsonUtil.h"
@implementation Post

- (void) postRequestTo:(NSString *)url{
    JsonUtil *util = [[JsonUtil alloc] init];
    NSData *requestData = [util dictionaryToJsonNSData:[util makeJsonBodyInDictionary]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
    
    [request setHTTPMethod: @"POST"];
    [request setValue: @"application/json" forHTTPHeaderField: @"content-type"];
    [request setValue: @"Basic SGFqaW5LOjVlZGYzNzIyZmFjMjE1M2IwYzRmZjQyOGM2MDM5MjYwNjE5ZDI0N2M3Yzc3YWQ0Mzc5MThkZDUwNDMyMTc1MmU=" forHTTPHeaderField:@"Authorization"];
    [request setHTTPBody: requestData];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
        NSLog(@"%@", [JsonUtil jsonToReadable:data]);
        NSLog(@"%@", response.description);
    }];
    [dataTask resume];
    while(true){}
}



@end

To explain how post request is made, firstly focus on postRequestTo method of Post.m.

- Firstly, make an NSData (json raw) out of NSDictionary (how this is implemented is shown in JsonUtil.m's helper functions)

- Make a NSMutableURLRequest using

1. NSURL object

2. and other two options that just have to be there

- Then add more information to the request

1. set HTTP method to be post

2. set 'application/json' for HTTPHeader 'content-type'

3. set 'Basic SGFqaW5LOjVlZGYzNzIyZmFjMjE1M2IwYzRmZjQyOGM2MDM5MjYwNjE5ZDI0N2M3Yzc3YWQ0Mzc5MThkZDUwNDMyMTc1MmU=' for HTTPHeader 'Authorization'

- Then create a session

- Using that session, make a datatask that makes a request with completion handler. The completion handler handles the data returned (in my case, reads the response and data)

- resume the datatask, and block. (using while(true){})

This is the output:

Output

 

Two images below will help explain about the http headers (authorisation header and content-type header) and also that the value matches expected value