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:
Two images below will help explain about the http headers (authorisation header and content-type header) and also that the value matches expected value
'Internship > 2020 year-end summer internship' 카테고리의 다른 글
[Long post] Create a unit test for asynchronous method (NSURLSessionDataTask) in Objective C (0) | 2021.01.28 |
---|---|
Simplest code for creating a post request (0) | 2021.01.18 |
How to retrieve response code from nsurlrequest (0) | 2021.01.18 |
How to make a get request with Objective c (0) | 2021.01.14 |
Json serialisation on Objective-C (0) | 2021.01.14 |