Problems with dispatch iOS - ios

I'm new to iOS and I have trouble understanding and applying well dispatch ... I have an application I need to query a website (api) within a for loop, the end of that cycle I need to make further inquiries in another cycle, and finally, at the end of both cycles need to switch views.
I now have this code (after much trial and error but still does not work):
dispatch_queue_t queue = dispatch_queue_create("threadServicios", DISPATCH_QUEUE_SERIAL);
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(queue, ^(void) {
NSLog(#"llego a buscar servicios por local");
for (NSDictionary *local in _arrLocalesTmp) {
[self getListaServiciosPorLocal:[local objectForKey:#"idLocal"]];
//this function calls another function that consumes a web service and get a json
}
procced = YES;
NSLog(#"llego a buscar profesionales por local");
for (NSDictionary *local in _arrLocalesTmp) {
[self getListaProfesionalesPorLocal:[local objectForKey:#"idLocal"]];
//this function calls another function that consumes a web service and get a json
}
procced2 = YES;
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(),^{
NSLog(#"dispatch procced 1");
if (procced && procced2) {
[self setFormularioConsultaCompleto];
}
});
The function [self getListaServiciosPorLocal: [Local objectForKey: # "idLocal"]]; is as follows:
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSURL *url = [NSURL URLWithString:urlConnection];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.timeoutIntervalForRequest = 30;
sessionConfiguration.timeoutIntervalForResource = 60;
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
__block NSError *jsonError;
NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *) response;
if(!error) {
if(urlResponse.statusCode == 200) {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&jsonError];
if(response) {
NSString *resp = [NSString stringWithFormat:#"%#", [dataResponse objectForKey:#"resp"]];
if([resp isEqualToString:#"1"]) {
_json = [dataResponse objectForKey:#"data"];
[_arrServiciosTmp addObjectsFromArray:(NSArray *)_json];
} else {
NSString *message = [dataResponse objectForKey:#"description"];
}
} else {
self.lblMensaje.text = #"Ha ocurrido un error al obtener la informaciĆ³n, por favor, vuelva a intentarlo en unos momentos.";
}
} else {
completion(nil);
}
} else {
NSLog(#"Error en Task");
}
});
And the function [self getListaProfesionalesPorLocal: [Local objectForKey: # "idLocal"]]; is similar but obtains other information
The problem is that the app calls this function [self setFormularioConsultaCompleto]; (changing the view) but the above functions still do not quite get all the data from webservice.
Sorry for this, but I gave up, I hope can help me!
Thanks!

The below uses dispatch groups to hold off starting another block till the groups work has been completed.
First change your data methods to not be wrapped in dispatch_async and accept a completion block, calling that at the end of the NSURLSessionDataTasks completionHandler:
-(void)getListaServiciosPorLocal:(id)whatEver withCompletionBlock:(dispatch_block_t)block
{
NSURL *url = [NSURL URLWithString:urlConnection];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.timeoutIntervalForRequest = 30;
sessionConfiguration.timeoutIntervalForResource = 60;
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
__block NSError *jsonError;
NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *) response;
if(!error) {
if(urlResponse.statusCode == 200) {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&jsonError];
if(response) {
NSString *resp = [NSString stringWithFormat:#"%#", [dataResponse objectForKey:#"resp"]];
if([resp isEqualToString:#"1"]) {
_json = [dataResponse objectForKey:#"data"];
[_arrServiciosTmp addObjectsFromArray:(NSArray *)_json];
} else {
NSString *message = [dataResponse objectForKey:#"description"];
}
} else {
self.lblMensaje.text = #"Ha ocurrido un error al obtener la informaciĆ³n, por favor, vuelva a intentarlo en unos momentos.";
}
} else {
completion(nil);
}
} else {
NSLog(#"Error en Task");
}
block(); // Notify completion block
});
}
Now when you call these methods:
dispatch_group_t group = dispatch_group_create();
dispatch_async(queue, ^(void) {
NSLog(#"llego a buscar servicios por local");
for (NSDictionary *local in _arrLocalesTmp) {
dispatch_group_enter(group);
[self getListaServiciosPorLocal:[local objectForKey:#"idLocal"] withCompletionBlock:^{
dispatch_group_leave(group);
}];
}
NSLog(#"llego a buscar profesionales por local");
for (NSDictionary *local in _arrLocalesTmp) {
dispatch_group_enter(group);
[self getListaProfesionalesPorLocal:[local objectForKey:#"idLocal"] withCompletionBlock:^{
dispatch_group_leave(group);
}];
}
});
dispatch_group_notify(group, dispatch_get_main_queue(),^{
[self setFormularioConsultaCompleto];
});
(Adapted from this answer)

Related

Obtaining an JSON Token using Authentication in Objective-C

Hi fairly new to iOS just trying to connect the app to an API and get my token using Authentication. I have tried a lot of different options and just can't seem to get my head around it. All i'm trying to do is obtain my token. Can anyone see where I'm going wrong? The API documentation is here: https://simplybook.me/en/api/developer-api
NSURL *url = [NSURL URLWithString:#"http://user-api.simplybook.me/login/"];
NSURLSession *session = [NSURLSession sharedSession];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"myloginname" forHTTPHeaderField:#"X-Company-Login"];
[request setValue:#"mytokenhere" forHTTPHeaderField:#"X-Token"];
NSURLSessionDataTask *downloadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray * resultDict =[json objectForKey:#"name"];
NSLog(#"%#", resultDict);
} else {
NSLog(#"%#", error);
}
}];
[downloadTask resume];
Instead of declaring NSURLSession like this:
NSURLSession *session = [NSURLSession sharedSession];
Try this instead:
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:#"https://user-api.simplybook.me/login/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
And also, make sure you've declared the NSURLSessionDelegate protocol in your header file.
I will give you sample code for getting token but this is regarding to the access and refresh token.You can understand it very clearly now.
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)actionLogin:(id)sender {
[self loginForGettingAccessandRefreshToken];
}
-(void)loginForGettingAccessandRefreshToken
{
#try {
NSString *strUserName = [textUsername.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *strPassword = [textPassword.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *strParameters = [NSString stringWithFormat:#"client_id=roclient&client_secret=secret&grant_type=password&username=%#&password=%#&scope=dataEventRecords offline_access", strUserName, strPassword];
id param = strParameters;
NSLog(#"The param is - %#",param);
[GlobalShareClass postLoginDataToServer:BASEURL_LOGIN passParameters:param success:^(id res)
{
if([res isKindOfClass:[NSDictionary class]]){
NSDictionary *dictRes = [res copy];
NSString *strErrDesc = [NSString stringWithFormat:#"%#",[dictRes objectForKey:#"error_description"]];
if([[dictRes allKeys] containsObject:#"error_description"]){
dispatch_async(dispatch_get_main_queue(), ^{
//Dispaly UI
});
}
else{
NSString *strAccessToken = [dictRes objectForKey:#"access_token"];
NSString *strRefreshToken = [dictRes objectForKey:#"refresh_token"];
NSString *strTokenType = [dictRes objectForKey:#"token_type"];
NSString *sstrExpiresIn = [dictRes objectForKey:#"expires_in"];
[[NSUserDefaults standardUserDefaults] setObject:globalShare.strRefreshToken forKey:#"refresh_token"];
[[NSUserDefaults standardUserDefaults] setObject:globalShare.strAccessToken forKey:#"access_token"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSDictionary *responseDict = [GlobalShareClass getDataFromToken:globalShare.strAccessToken];
NSString *strFetchedSub = [[NSUserDefaults standardUserDefaults] stringForKey:#"loginIdSub"];
globalShare.loginId = [responseDict objectForKey:#"sub"];
}
}
else{
NSLog(#"The res starts with array");
}
} failure:^(NSError *error) {
// error handling here ...
NSLog(#"%#", [error localizedDescription]);
dispatch_async(dispatch_get_main_queue(), ^{
//Showing Error
});
} passViewController:self];
}
#catch(NSException *exception){
NSLog(#"%#",[exception description]);
}
#finally{
}
}
}
GlobalShareClass.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface GlobalShareClass : NSObject{
NSMutableArray *arr;
}
#property (strong, nonatomic) NSMutableArray *arr;
+ (GlobalShareClass *)sharedInstance;
+ (void)postLoginDataToServer:(NSString *)url passParameters:(id)parameter success:(void (^)(id res))successPost failure:(void(^)(NSError* error))failurePost passViewController:(UIViewController *)vc;
+ (NSDictionary *)getDataFromToken:(NSString *)strToken;
+ (NSDictionary *)urlBase64Decode:(NSString *)strToParse;
#end
GlobalShareClass.m
#import "GlobalShareClass.h"
#implementation GlobalShareClass
#synthesize arr;
+ (GlobalShareClass *)sharedInstance {
static GlobalShareClass* _shareInstane = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_shareInstane = [[GlobalShareClass alloc] init];
//Incase array of initialization
_shareInstane.arr = [[NSMutableArray alloc] init];
});
return _shareInstane;
}
+ (void)postLoginDataToServer:(NSString *)url passParameters:(id)parameter success:(void (^)(id res))successPost failure:(void(^)(NSError* error))failurePost passViewController:(UIViewController *)vc{
GlobalShareClass *globalShare = [GlobalShareClass sharedInstance];
__block id jsonResp;
NSData *data = [parameter dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionUploadTask *dataTask = [session uploadTaskWithRequest: request
fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(data == nil && error){
NSLog(#"uploadTaskWithRequest error: %#", error);
failurePost(error);
}
else{
jsonResp = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSString *strStatusCode = [NSString stringWithFormat:#"%ld",(long)[((NSHTTPURLResponse *)response) statusCode]];
if([strStatusCode isEqualToString:#"400"]){
successPost(jsonResp);
}
NSString *strStatusCodeResponse = [self strGetStatusResponseCode:strStatusCode];
if([strStatusCodeResponse length] > 0){
dispatch_async(dispatch_get_main_queue(), ^{
// Showing error
});
}else{
jsonResp = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
if([jsonResp objectForKey:#"error"] || jsonResp == nil){
dispatch_async(dispatch_get_main_queue(), ^{
[self showAlertController:#"Error" :[jsonResp objectForKey:#"error_description"] passViewController:vc];
});
}
else
successPost(jsonResp);
}
}
}];
[dataTask resume];
}
+ (NSDictionary *)getDataFromToken:(NSString *)strToken {
NSDictionary *data;
NSString *encoded = [strToken componentsSeparatedByString:#"."][1];
data = [GlobalShareClass urlBase64Decode:encoded];
return data;
}
+ (NSDictionary *)urlBase64Decode:(NSString *)strToParse {
#try {
NSDictionary *returnDict;
NSString *output = [strToParse stringByReplacingOccurrencesOfString:#"-" withString:#"+"];
output = [output stringByReplacingOccurrencesOfString:#"_" withString:#"/"];
switch (output.length % 4) {
case 0:
case 1:
break;
case 2:
output = [output stringByAppendingString:#"=="];
break;
case 3:
output = [output stringByAppendingString:#"="];
break;
default:
break;
}
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:output options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
NSLog(#"%#", decodedString);
NSData *data = [decodedString dataUsingEncoding:NSUTF8StringEncoding];
returnDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
return returnDict;
}
#catch (NSException *exception) {
NSLog(#"%#", [exception description]);
}
}
#end

Activity Indicator while calling API

I want to display the activity indicator while waiting for the API to return. The problem is after all the result I get from API, then the spinner only display. The result I want is while waiting for API call, then the spinner will running.
I'm calling this method in here
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
[self startLoadingSpinner]
//Calling API...
[self stopLoadingSpinner]
}
Here is the method for the activity indicator
-(void)startLoadingSpinner {
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 70, 70)];
self.activityIndicator.opaque = YES;
self.activityIndicator.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.4f];
self.activityIndicator.center = self.view.center;
self.activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
[self.activityIndicator setColor:[UIColor whiteColor]];
[self.view addSubview:self.activityIndicator];
[self.activityIndicator startAnimating];
}
This is how I stop the activity indicator
-(void)stopLoadingSpinner {
[self.activityIndicator performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:0.5];
}
Don't add activity indicators in tableview datasource method - numberOfRowsInSection .
Add these two functions calling in the same method where you are making an API call. Make an API call in ViewDidLoad, some life cycle method or in action methods.
Below is the example of using it.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:#"http://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[self startLoadingSpinner]
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
NSLog(#"%# %#", response, responseObject);
}
[self stopLoadingSpinner]
}];
[dataTask resume];
In Swift
func makeAPIRequest(to endPoint: String) {
// here you can showActivetyIndicator start progressing here
self.startLoadingSpinner()
Alamofire.request(endPoint).responseJSON{ response in
if let value = response.result.value {
let responseInJSON = JSON(value)
self._responseInJSON = responseInJSON
}
// here you can hide Your ActivetyIndicator here
self.stopLoadingSpinner()
}
}
My detailed answer is below
-(void)simpleGetResponse{
#try {
//Call the Activity Indicator show method here
[self startLoadingSpinner];
NSString *strURL = #"Your URL";
NSURL *urlStr = [NSURL URLWithString:strURL];
NSMutableURLRequest *mutaURL = [NSMutableURLRequest requestWithURL:urlStr];
[mutaURL setHTTPMethod:#"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:mutaURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if(httpResponse.statusCode == 200)
{
NSError *parseError = nil;
id response = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if(response != nil){
if([response isKindOfClass:[NSDictionary class]]){
NSLog(#"response is in dictionary format %#",response);
NSDictionary *dictRes = [response copy];
NSLog(#"The dictRes is - %#",dictRes);
}
else{
NSLog(#"response is in array format %#",response);
NSDictionary *arrRes = [response copy];
NSLog(#"The arrRes is - %#",arrRes);
}
dispatch_async(dispatch_get_main_queue(), ^{
//Call the Activity Indicator hidden method inside the dispatch_main_queue method
[self stopLoadingSpinner]
[yourTableView reloadData];
});
}
}
else
{
NSLog(#"Error");
}
}];
[dataTask resume];
}
#catch (NSException *exception) {
NSLog(#"%#", [exception description]);
}
#finally {
}
}

Google Place api URL iOS

I am creating an app that uses Google Place. Before I used to use Yahoo's api and had to use a url that was responsible for local search that was provided by yahoo. The url was following:
http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=SF0DVEvV34G4GnXEDU4SXniaDebJ_UvC1G1IuikVz3vpOJrBpyD.VqCJCVJHMh99He3iFz1Rzoqxb0b7Z.0-
Now since yahoo's api is discontinued I have decided to switch over to Google Place. But I cannot find an Url to use. I just dowlod the framework and use the api key. Where can I find such url for Google Place.
Register for the Google Places API by following the linke provided below:
https://code.google.com/apis/console
Refer Code Link for places Auto Search
https://github.com/AdamBCo/ABCGooglePlacesAutocomplete
NSString *const apiKey = #"*****23xAHRvnOf2BVG8o";
NSString * searchWord = #"search some place "
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%#&types=establishment|geocode&radius=500&language=en&key=%#",searchWord,apiKey];
pragma mark - Network Methods
-(void)retrieveGooglePlaceInformation:(NSString *)searchWord withCompletion:(void (^)(BOOL isSuccess, NSError *error))completion {
if (!searchWord) {
return;
}
searchWord = searchWord.lowercaseString;
self.searchResults = [NSMutableArray array];
if ([self.searchResultsCache objectForKey:searchWord]) {
NSArray * pastResults = [self.searchResultsCache objectForKey:searchWord];
self.searchResults = [NSMutableArray arrayWithArray:pastResults];
completion(YES, nil);
} else {
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%#&types=establishment|geocode&radius=500&language=en&key=%#",searchWord,apiKey];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *jSONresult = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (error || [jSONresult[#"status"] isEqualToString:#"NOT_FOUND"] || [jSONresult[#"status"] isEqualToString:#"REQUEST_DENIED"]){
if (!error){
NSDictionary *userInfo = #{#"error":jSONresult[#"status"]};
NSError *newError = [NSError errorWithDomain:#"API Error" code:666 userInfo:userInfo];
completion(NO, newError);
return;
}
completion(NO, error);
return;
} else {
NSArray *results = [jSONresult valueForKey:#"predictions"];
for (NSDictionary *jsonDictionary in results) {
}
//[self.searchResultsCache setObject:self.searchResults forKey:searchWord];
completion(YES, nil);
}
}];
[task resume];
}
}

iOS - Why is this method so slow?

I have an iOS method that is now deprecated --NSURLConnection sendSynchronousRequest. This method worked and was fast.
I must be doing something wrong with the new method, as it is unacceptably slow.
The new method code I'm showing the whole routine is:
- (void)getData {
NSLog(#"%s", __FUNCTION__);
pathString = #"https://api.wm.com/json/jRoutes/.......";
NSURL *url = [NSURL URLWithString:pathString......];
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if ([response respondsToSelector:#selector(statusCode)]) {
if ([(NSHTTPURLResponse *) response statusCode] == 404) {
dispatch_async(dispatch_get_main_queue(), ^{
// alert
NSLog(#" NO DATA");
return;
});
}
}
// 4: Handle response here
[self processResponseUsingData:data];
}];
[downloadTask resume];
}
- (void)processResponseUsingData:(NSData*)data {
NSLog(#"%s", __FUNCTION__);
NSError *error = nil;
NSMutableDictionary* json = nil;
if(nil != data)
{
json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
}
if (error || !json)
{
NSLog(#"Could not parse loaded json with error:%#", error);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
allRoutesArray = [json valueForKey:#"Routes"];
NSLog(#"allRoutesArray count: %lu", (unsigned long)allRoutesArray.count);
[self.tableView reloadData];
});
}
}

Make periodic server requests with NSURLSessionDataTask and dispatch_source timer

Need some help and explanation, because i'm really stuck in my question. i need to make this:
1) I make one request to the server, get some response and then i want to make another request every 7 seconds(example). also get some response. if it satisfy several conditions -> stop timer and do some stuff.
Main problem is that timer never stops, despite the fact that all in all i get response right. i assume that i use GCD incorrectly. because in debug this code behaves really strange.
What i have done:
This is my request function(it became like this after i read about 50 links how to do similar things)
-(void)makeRequestWithURL:(NSString*)urlString andParams:(NSString*)params andCompletionHandler:(void(^)(NSDictionary *responseData, NSError *error))completionHnadler{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
request.HTTPMethod = #"POST";
request.HTTPBody = [params dataUsingEncoding:NSUTF8StringEncoding];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (completionHnadler) {
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
completionHnadler(nil, error);
});
} else {
NSError *parseError;
json = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&parseError];
dispatch_async(dispatch_get_main_queue(), ^{
completionHnadler(json, parseError);
});
}
}
}];
[postDataTask resume]; }
I create my timer like this:
dispatch_source_t CreateDispatchTimer(uint64_t interval,
uint64_t leeway,
dispatch_queue_t queue ,
dispatch_block_t block) {
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer) {
// Use dispatch_time instead of dispatch_walltime if the interval is small
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
dispatch_source_set_event_handler(timer, block);
dispatch_resume(timer);
}
return timer; }
and called it like this:
-(void)checkForPassenger {
timerSource = CreateDispatchTimer(7ull * NSEC_PER_SEC, 1ull * NSEC_PER_SEC, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if([self getNotificationsRequest] == YES) {
dispatch_source_cancel(timerSource);
} else {
NSLog(#"go on timer");
}
NSLog(#"Driver checked for passenger!");
}); }
this is the code of periodic response:
-(BOOL)getNotificationsRequest {
NSString *urlString = #"http://primetime.by/temproad/do";
NSString *params = [NSString stringWithFormat:#"event={\"type\": \"in.getNotifications\"}&session_id=%#",session_id];
[self makeRequestWithURL:urlString andParams:params andCompletionHandler:^(NSDictionary *responseData, NSError *error) {
if ([[responseData objectForKey:#"rc"] intValue] == 0) {
NSArray *temp_notifications = [responseData objectForKey:#"notifications"];
if (temp_notifications.count != 0) {
notification = [[Notification alloc] initWithNotification:[[responseData objectForKey:#"notifications"] objectAtIndex:0]];
}
}
}];
if (notification) {
return YES;
} else {
return NO;
} }
and this is what i do in main request:
[self makeRequestWithURL:urlString andParams:params andCompletionHandler:^(NSDictionary *responseData, NSError *error) {
if ([[responseData objectForKey:#"rc"] intValue] == 0) {
route = [[Route alloc] initWithData:responseData];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self checkForPassenger];
});
}
}];
NSLog(#"bye");
maybe explanation is bad so i can answer any question.
thx

Resources