How to check if NSURLSessionDataTask is complete? - objective-c

I am getting a n number of json data, and once the whole thing is downloaded or the process of getting the json is complete I need to update the UI of the tableView
for(int i = 1;i <= self.numberOfEpisodes;i++)
{
NSString *endPoint = [[[[urlJson stringByAppendingString:getEpisodes]stringByAppendingString:title]stringByAppendingString:#"&episodeNumber="]stringByAppendingString:[NSString stringWithFormat:#"%i",i]];
endPoint = [endPoint stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSLog(#"End point %#",endPoint);
[downloadJson:endPoint WithHandler:^(__weak id result)
{
NSArray *episodeArray =result;
if(episodeArray && episodeArray.count > 0)
{
for(NSDictionary *dictionary in episodeArray)
{
//parse stuff here
}
}
if(i == self.numberOfEpisodes)
{
//update UI
}
}];
}
The problem is in this line if(i == self.numberOfEpisodes). I don't know why the integer i is not arranged from 1 to the self.numberOfEpisodes. Instead it is a random number from 1 to self.numberOfEpisodes. So is there another way how to check if the getting of the json is complete?
(void)getJson:(NSString *)urlString WithHandler:(void(^)(__weak id result))handler
{
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSURL * url = [NSURL URLWithString:urlString];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[urlRequest setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[urlRequest setHTTPMethod:#"GET"];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error == nil)
{
id returnedObject = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error:nil];
handler(returnedObject);
}
else{
NSLog(#"error %#",error);
}
}];
[dataTask resume];
}

Yes there is one way to achieve this by dispatch_group_t
//Creat group
dispatch_group_t group = dispatch_group_create();
for(int i = 1;i <= self.numberOfEpisodes;i++)
{
//Enter group
dispatch_group_enter(group);
NSString *endPoint = [[[[urlJson stringByAppendingString:getEpisodes]stringByAppendingString:title]stringByAppendingString:#"&episodeNumber="]stringByAppendingString:[NSString stringWithFormat:#"%i",i]];
endPoint = [endPoint stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSLog(#"End point %#",endPoint);
[downloadJson:endPoint WithHandler:^(__weak id result)
{
NSArray *episodeArray =result;
if(episodeArray && episodeArray.count > 0)
{
for(NSDictionary *dictionary in episodeArray)
{
//parse stuff here
}
}
// Then Leave group
dispatch_group_leave(group);
}];
}
//Here you will be notified after it's done
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// Do whatever you need to do when all requests are finished
//Update UI
});

Related

synchronous NSURLSessionDataTask using objective-c

I'm try to do synchronous NSURLSessionDataTask with the below code but unable to proceed.
__block NSData *rData = nil;
__block BOOL taskDone = NO;
__block NSData *rError = nil;
NSURL *url = [NSURL URLWithString:dataURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:1 timeoutInterval:30];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:nil delegateQueue:nil];
NSURLSessionDataTask *taskData = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
rData = [NSData dataWithData:data];
rError = [error copy];
taskDone = YES;
}];
[taskData resume];
while (taskDone == NO) {
if (_close == YES) {
[taskData cancel];
return nil;
}
usleep(20000);
}
I need to synchronous call so that I can remove the while loop which is not needed.
Below is my code with synchronous call using semaphore
dispatch_semaphore_t sem;
__block NSData *rData = nil;
__block BOOL taskDone = NO;
__block NSData *rError = nil;
NSURL *url = [NSURL URLWithString:dataURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:1 timeoutInterval:30];
// creating semaphore
    sem = dispatch_semaphore_create(0);
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:nil delegateQueue:nil];
NSURLSessionDataTask *taskData = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
rData = [NSData dataWithData:data];
rError = [error copy];
taskDone = YES;
//call semaphore
        dispatch_semaphore_signal(sem);
}];
[taskData resume];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
// THIS part not sure... how can we accommodate this below code
while (taskDone == NO) {
if (_close == YES) {
[taskData cancel];
return nil;
}
usleep(20000);
}
above code could be correct ?
I understand that what you want to do is wait for the DataTask to be completed before continue with you code, the best way is to put your request in a function with a completionHandler.
First create a function that will return a NSURLSessionDataTask with a completion handler:
-(NSURLSessionDataTask*)startSessionDataTaskWithCompletionHandler:(void (^)(NSData *myData))completionBlock {
//Set your request
NSString *dataURL = #"www.yoururl.com";
NSURL *url = [NSURL URLWithString:dataURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:1 timeoutInterval:30];
// I recommend to use sharedSession because is a simple request, so its not needed a specific session configuration.
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest: request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
if (completionBlock){
completionBlock(data);
return;
//When you call this function, the completionBlock will use this data
}
} else {
//Error handle
return;
}
}];
[dataTask resume];
return dataTask;
}
Then you can call this function from anywhere:
NSURLSessionTask *task = [self startSessionDataTaskWithCompletionHandler:^(NSData *myData) {
// put whatever code you want to perform when the asynchronous data task finish, for example:
rData = [NSData dataWithData:myData];
}];
if (!task) {
// handle failure to create task any way you want
}
You can make NSURLSessionDataTask synchronous with PromiseKit. Install it manually or add the following line to the Podfile if you use CocoaPods (tested with CocoaPods 1.7.3):
pod "PromiseKit", "6.10.0"
Add the following line to the top of the code file:
#import PromiseKit;
Then create a wrapper for your task:
- (AnyPromise*)promiseToLoadData:(NSString*)dataURL {
return [AnyPromise promiseWithResolverBlock:^(PMKResolver _Nonnull resolver) {
NSURL *url = [NSURL URLWithString:dataURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:1 timeoutInterval:30];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:nil delegateQueue:nil];
NSURLSessionDataTask *taskData = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error != nil) {
resolver([error copy]);
} else {
resolver([NSData dataWithData:data]);
}
}];
[taskData resume];
}];
}
Use wait to resolve the promise synchronously:
id value = [self promiseToLoadData:#"http://your.url"].wait;
if ([value isKindOfClass:[NSData class]]) {
NSLog(#"%#", [[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding]);
}

Issue in POST request using Objective C

i'm hiting an API in postman there i get result fine, this how i'm making POST request in postman,
But when i hit same API in my application using objective c, i got errors, i'm passing parameters fine but result is not coming true, i'm confuse that why it is not showing results true, This is my code for POST request,
- (void)sendRequest
{
NSArray *userArray = [NSArray arrayWithObjects: #"ishaqshafiq#hotmail.com",nil];
NSDictionary *emp = #{#"lstUsers": userArray,
#"message":#"Your Order is Booked",
#"data": #{
#"type":#"text",
}};
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSString *urlLinkA=#"http://sajjenweb.azurewebsites.net/api/HubConnection/PostMobileNotification";
NSURL * url = [NSURL URLWithString:urlLinkA];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
NSString *parameters = [NSString stringWithFormat:#"%#",emp];
NSLog(#"parameter %#",parameters);
[urlRequest setHTTPMethod:#"POST"];
//[urlRequest setHTTPBody:[parameters dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# ", response);
NSLog(#"Error is %#",error);
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
// NSLog(#"DDD %#",dictionary);
NSString *res = [dictionary valueForKey:#"recipients"];
NSLog(#"RR: %#", res);
NSString *msg=#"Successfully Submitted";
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Success"
message:msg
preferredStyle:UIAlertControllerStyleAlert];
int duration = 2; // duration in seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[alert dismissViewControllerAnimated:YES completion:nil];
});
}];
NSLog(#"network error :");
[dataTask resume];
}

Getting error while fetching data from server using NSURLSession Datatask in objective c

I was trying to load data for the table using values from server.I am using NSURLSession datatask with completion handler. Whenever it reaches the nsurlsession, it shows error.This is the code which i used for getting data.
- (void)geturl:(NSString *)urlvalue datavalues:(NSString *)string fetchGreetingcompletion:(void (^)(NSDictionary *dictionary, NSError *error))completion{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#?%#",common.getUrlPort,urlvalue,common.getappversion]];
NSLog(#"url=%#",url);
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[urlRequest addValue:common.getauthtoken forHTTPHeaderField:#"Authorization"];
//Create POST Params and add it to HTTPBody
[urlRequest setHTTPMethod:#"GET"];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError) {
NSLog(#"Response:%# %#\n", response, connectionError);
if (data.length > 0 && connectionError == nil)
{
NSDictionary *greeting = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSString *code = [NSString stringWithFormat:#"%#",[greeting valueForKey:#"code"]];
if([code isEqualToString:#"-1"]){
[self loaderrorview:greeting];
}
else{
if (completion)
completion(greeting, connectionError);
}
}
else if(data == nil){
NSDictionary *errorDict=[[NSDictionary alloc]initWithObjectsAndKeys:#"Server Connection Failed",#"error", nil];
if (completion)
completion(errorDict,connectionError);
}
else
{
NSDictionary *greeting = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
if (completion)
completion(greeting, connectionError);
}
}];
[dataTask resume];
}
The code which i used for getting data from server:
-(void)getdataexplore{
if (!common.checkIfInternetIsAvailable) {
[self.view makeToast:Nointernetconnection];
} else {
NSLog(#"There is internet connection");
[SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeBlack];
[SVProgressHUD showWithStatus:#"Loading..."];
[apiservice geturl:loadexploredata datavalues:nil fetchGreetingcompletion:^(NSDictionary *dictionary, NSError *error) {
//NSLog(#"Test %# Error %#",dictionary,error);
if(error == nil){
authDictionary = dictionary;
[self loaddata];
}
else{
[SVProgressHUD dismiss];
[view_business makeToast:#"Request timed out" duration:2.0 position:CSToastPositionCenter];
}
}];
}
}
The code which i used for storing server data to array:
-(void)loaddata
{
[SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeBlack];
[SVProgressHUD showWithStatus:#"Loading..."];
//[SVProgressHUD dismiss];
NSString *msg = [authDictionary valueForKey:#"msg"];
NSString *code = [NSString stringWithFormat:#"%#",[authDictionary valueForKey:#"code"]];
if([code isEqualToString:#"201"]){
NSDictionary *explore = [authDictionary valueForKey:#"explore_obj"];
arr_CBcategories = [explore valueForKey:#"cb_categories"];
[common setarrCBCaterory:arr_CBcategories];
arr_CBcategoryid = [arr_CBcategories valueForKey:#"id"];
[common setarrCateroryID:arr_CBcategoryid];
arr_CBcategorytitle = [arr_CBcategories valueForKey:#"title"];
[common setarrCaterorytitle:arr_CBcategorytitle];
arr_CBcategoryslug = [arr_CBcategories valueForKey:#"slug"];
[common setarrCateroryslug:arr_CBcategoryslug];
arr_CBcategoryimage = [arr_CBcategories valueForKey:#"image"];
[common setarrCateroryimage:arr_CBcategoryimage];
arr_CBcategorycode = [arr_CBcategories valueForKey:#"code"];
}
I am getting error like "Unable to run main thread". Any solution for this.

objective c invisible array out of function param request

I'm triyng to get array from server. But it doesn't work. I'm mean in the function everything is okay with my array but out of it it's null. How to fix?
for(int i=1; i<5; i++){
NSString *category = [NSString stringWithFormat:#"%d",i];
NSString *encrypt = #"encrypt=93mrLIMApU1lNM619WzZje4S9EeI4L2L";
NSString *latitude = #"latitude=32.794044";
NSString *longtitude = #"longitude=34.989571";
NSString *params = [NSString stringWithFormat:#"%#&category=%#&%#&%#&area=CENTER",
encrypt,category,latitude,longtitude];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://admin.t-club.co.il/api/get-buissness"]];
NSData *postBody = [params dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError)
{
if(!connectionError)
{
_myDict =[NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
_tmpArray = [_myDict objectForKey:#"result"];
NSLog(#"my array %#",_tmpArray);//here array isn't null
}
}];
[_myArray addObjectsFromArray:_tmpArray];
}
NSLog(#"my array %#",_tmpArray);//here is null
It looks like what you're aiming for is to make several async requests in sequence. This can be done by adding a little abstraction.
First, a method that makes just one request and provides a dictionary in response of the parsed JSON result...
- (void)makeRequestWithParams:(NSString *)params completion:(void (^)(NSDictionary *, NSError *))completion {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://admin.t-club.co.il/api/get-buissness"]];
NSData *postBody = [params dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
if(!connectionError) {
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
completion(dictionary, nil);
} else {
completion(nil, connectionError);
}
}];
}
Please note that the NSURLConnnection methods have been replaced by NSSession, so this code will need to change to that soon.
Now something that calls that first method over and over. This one takes an array of request parameters as input, fills a mutable array with the dictionary results, and calls a completion block when its done...
- (void)makeManyRequestsWithParams:(NSArray *)arrayOfParams fillingArray:(NSMutableArray *)result completion:(void (^)(BOOL))completion {
if (arrayOfParams.count == 0) return completion(YES);
NSString *nextParams = arrayOfParams[0];
[self makeRequestWithParams:nextParams completion:^(NSDictionary *dictionary, NSError *error) {
if (!error && dictionary) {
[result addObject:dictionary];
NSArray *remainingParams = [arrayOfParams subarrayWithRange:NSMakeRange(1, arrayOfParams.count-1)];
[self makeManyRequestsWithParams:remainingParams fillingArray:result completion:completion];
} else {
completion(NO);
}
}];
}
Finally, your original loop's job is now limited to just assembling the parameters. Once those are in an array, call to make the requests...
- (void)test {
NSMutableArray *arrayOfParams = [NSMutableArray array];
for(int i=1; i<5; i++){
NSString *category = [NSString stringWithFormat:#"%d",i];
NSString *encrypt = #"encrypt=93mrLIMApU1lNM619WzZje4S9EeI4L2L";
NSString *latitude = #"latitude=32.794044";
NSString *longtitude = #"longitude=34.989571";
NSString *params = [NSString stringWithFormat:#"%#&category=%#&%#&%#&area=CENTER",
encrypt,category,latitude,longtitude];
[arrayOfParams addObject:params];
}
NSMutableArray *result = [NSMutableArray array];
[self makeManyRequestsWithParams:arrayOfParams fillingArray:result completion:^(BOOL success) {
if (success) {
NSLog(#"all done, result is %#", result);
} else {
NSLog(#"sadness");
}
}];
// don't expect results to be ready here. they won't be.
// see how they are logged above in the completion block?
}
NSURLConnection sendAsynchronousRequest is asynchronous meaning it will be moved to a background thread and execution will continue without waiting for the task to complete. So by the time it gets to your bottom NSLog, the request will still be processing and the value of _tmpArray will be null.
You can use sendSynchronousRequest to have the request complete before moving on.
http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/#synchronous

Simple objective-c GET request

Most of the information here refers to the abandoned ASIHTTPREQUEST project so forgive me for asking again.
Effectively, I need to swipe a magnetic strip and send the track 2 data to a webservice that returns "enrolled" or "notenrolled" (depending on the status of the card...)
So my data comes in simply as
NSData *data = [notification object];
And then I need to pass this to a url to the order of
http://example.com/CardSwipe.cfc?method=isenrolled&track2=data
And then just receive a response string...
I've searched a ton and there seems to be some conflicting answers as to whether this should be accomplished simply with AFNetworking, RESTkit, or with the native NSURL/NSMutableURLRequest protocols.
The options for performing HTTP requests in Objective-C can be a little intimidating. One solution that has worked well for me is to use NSMutableURLRequest. An example (using ARC, so YMMV) is:
- (NSString *) getDataFrom:(NSString *)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:[NSURL URLWithString:url]];
NSError *error = nil;
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
if([responseCode statusCode] != 200){
NSLog(#"Error getting %#, HTTP status code %i", url, [responseCode statusCode]);
return nil;
}
return [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
}
Update:
Your question's title, and tagging say POST, but your example URL would indicate a GET request. In the case of a GET request, the above example is sufficient. For a POST, you'd change it up as follows:
- (NSString *) getDataFrom:(NSString *)url withBody:(NSData *)body{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:body];
[request setValue:[NSString stringWithFormat:#"%d", [body length]] forHTTPHeaderField:#"Content-Length"];
[request setURL:[NSURL URLWithString:url]];
/* the same as above from here out */
}
Update for iOS 9:
So, [NSURLConnection sendSynchronousRequest] is deprecated starting from iOS 9. Here's how to do a GET request using NSURLSession starting from iOS 9
GET Request
// making a GET request to /init
NSString *targetUrl = [NSString stringWithFormat:#"%#/init", baseUrl];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:[NSURL URLWithString:targetUrl]];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
^(NSData * _Nullable data,
NSURLResponse * _Nullable response,
NSError * _Nullable error) {
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Data received: %#", myString);
}] resume];
POST Request
// making a POST request to /init
NSString *targetUrl = [NSString stringWithFormat:#"%#/init", baseUrl];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
//Make an NSDictionary that would be converted to an NSData object sent over as JSON with the request body
NSDictionary *tmp = [[NSDictionary alloc] initWithObjectsAndKeys:
#"basic_attribution", #"scenario_type",
nil];
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:tmp options:0 error:&error];
[request setHTTPBody:postData];
[request setHTTPMethod:#"POST"];
[request setURL:[NSURL URLWithString:targetUrl]];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
^(NSData * _Nullable data,
NSURLResponse * _Nullable response,
NSError * _Nullable error) {
NSString *responseStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Data received: %#", responseStr);
}] resume];
Tested 100% working
Only for Objective C
-(void)fetchData
{
NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];
// Setup the request with URL
NSURL *url = [NSURL URLWithString:#"https://test.orgorg.net/ios/getStory.php?"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
// Convert POST string parameters to data using UTF8 Encoding
NSString *postParams = #"";
NSData *postData = [postParams dataUsingEncoding:NSUTF8StringEncoding];
// Convert POST string parameters to data using UTF8 Encoding
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:postData];
// Create dataTask
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
//JSON Parsing....
NSString *message = results[#"Message"];
BOOL status = results[#"Status"];
if (status){
// Here you go for data....
}else{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"App"
message:message
preferredStyle:UIAlertControllerStyleAlert]; // 1
UIAlertAction *firstAction = [UIAlertAction actionWithTitle:#"Ok"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
NSLog(#"You pressed button one");
}]; // 2
[alert addAction:firstAction]; // 4
[self presentViewController:alert animated:YES completion:nil];
}
}];
// Fire the request
[dataTask resume];
}
For Objective c :
-(void)loadData:(NSString*)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"https://jsonplaceholder.typicode.com/posts"]];
[request setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableArray *jsonArray = (NSMutableArray *)[NSJSONSerialization JSONObjectWithData:data options:NSASCIIStringEncoding error:&error];
if([self.delegate respondsToSelector:#selector(loadingData:)]){
[self.delegate loadingData:jsonArray];
}
}] resume];
}
Swift 5.5:
// MARK: - Posts
func getPosts(endPath : String, completion: #escaping ([Post]) -> ()) {
let urlPath = Constants.Network.BASE_URL + endPath
guard let url = URL(string: urlPath) else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = Constants.Network.HTTPS_METHOD
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode([Post].self, from: data) {
DispatchQueue.main.async {
completion(decodedResponse)
}
return
}
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
}
**Simply Call and get your JSON Data.**
-(void)getJSONData
{
NSURL *url = [NSURL URLWithString:#"http://itunes.apple.com/us/rss/topaudiobooks/limit=10/json"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *data = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSError *erro = nil;
if (data!=nil) {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&erro ];
if (json.count > 0) {
for(int i = 0; i<10 ; i++){
[arr addObject:[[[json[#"feed"][#"entry"] objectAtIndex:i]valueForKeyPath:#"im:image"] objectAtIndex:0][#"label"]];
}
}
}
dispatch_sync(dispatch_get_main_queue(),^{
[table reloadData];
});
}];
[data resume];
}