I am getting warning [UIApplication delegate] must be used from main thread only in the below line of code
((AppDelegate *)[[UIApplication sharedApplication]
delegate]).loginProfile.accessToken;
Following is my code.
+ (NSString *)accessTokenHashForDate:(NSDate *)date withParameters:(NSArray *)params{
NSString *accessToken = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).loginProfile.accessToken;
NSString *paramsStr = [params componentsJoinedByString:#""];
NSString *hashStr = [NSString stringWithFormat:#"%#%#%#%#", [CommonUtil IMEI], [date agileHashFormattedString], (!paramsStr) ? #"" : paramsStr, accessToken];
return hashStr
}
Can anyone tell me how to remove this warning message?
+ (NSString *)accessTokenHashForDate:(NSDate *)date withParameters:(NSArray *)params{
__block NSString *accessToken = NULL;
if ([NSThread isMainThread]) {
accessToken = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).loginProfile.accessToken;
} else {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
accessToken = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).loginProfile.accessToken;
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(semaphore);
}
NSString *paramsStr = [params componentsJoinedByString:#""];
NSString *hashStr = [NSString stringWithFormat:#"%#%#%#%#", [CommonUtil IMEI], [date agileHashFormattedString], (!paramsStr) ? #"" : paramsStr, accessToken];
return hashStr;
}
Related
I need some help in passing data from AppDelegate to another controller which is a Table View Controller. In AppDelegate , i have a server response which i converted it to string. What i want is to pass that string to the another controller(Table View Controller) and display it to the Cell.
This my code in
AppDelegate.m
#import "AppDelegate.h"
#import "ChildListViewController.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
{
#define URL2 #"http://192.168.1.166/bustracking/activation/validateActivationCode"
// NSMutableData *mutData;
// NSString *responseActCode;
// NSString *responseParentID;
// NSString *mess;
}
#synthesize responseActCode, responseParentID,mess,beaconID,Name,trackerID,lat,longi,Status,Image;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIUserNotificationSettings *settings =[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
return YES;
}
//get device token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *device = [deviceToken description];
device = [device stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
device = [device stringByReplacingOccurrencesOfString:#" " withString:#""];
[[NSUserDefaults standardUserDefaults] setObject:device forKey:#"DeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"My device is: %#", device);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userPushInfo
{
application.applicationIconBadgeNumber = 0;
NSDictionary *fetchedDictionary =[userPushInfo objectForKey:#"aps"];
NSDictionary *fetchedDictionaryalert = [fetchedDictionary objectForKey:#"alert"];
NSDictionary *fetchedDictionarybody = [fetchedDictionaryalert objectForKey:#"body"];
NSDictionary *fetchedDictionaryactivation = [fetchedDictionarybody objectForKey:#"activation_code"];
if(fetchedDictionaryactivation != nil)
{
NSDictionary *fetchedDictionaryresult = [fetchedDictionaryactivation objectForKey:#"result"];
for (NSDictionary *user in fetchedDictionaryresult)
{
responseActCode = [user objectForKey:#"activation_code"];
responseParentID = [user objectForKey:#"parent_id"];
NSLog(#"Item actcode: %#", responseActCode);
NSLog(#"Item parentid: %#", responseParentID);
}
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Activation Code"
message:(#"%#", responseActCode)
delegate:self
cancelButtonTitle: #"Ok"
otherButtonTitles: nil];
[alertView show];
alertView.tag = 0;
NSLog(#"dadadad %#", userPushInfo);
}
else
{
NSDictionary *fetchedDictionary =[userPushInfo objectForKey:#"aps"];
NSDictionary *fetchedDictionaryalert = [fetchedDictionary objectForKey:#"alert"];
NSDictionary *fetchedDictionarybody = [fetchedDictionaryalert objectForKey:#"body"];
NSDictionary *fetchedDictionaryresult = [fetchedDictionarybody objectForKey:#"result"];
//NSString *beaconID;
for (NSDictionary *user in fetchedDictionaryresult)
{
beaconID = [user objectForKey:#"beacon_id"];
mess = [user objectForKey:#"message"];
NSLog(#"Item actcode: %#", beaconID);
NSLog(#"Item parentid: %#", mess);
}
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#""
message:(#"%#", mess)
delegate:self
cancelButtonTitle: #"Ok"
otherButtonTitles: nil];
[alertView show];
alertView.tag = 1;
NSLog(#"dadadad %#", userPushInfo);
}
}
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger) buttonIndex
{
if (alertView.tag==0)
{
NSString *parentiD = responseParentID;
NSString *actcode = responseActCode;
NSString *beaconid = #"1458010000B0";
NSMutableURLRequest *request = nil;
NSString *getURL = [NSString stringWithFormat:#"%#?parent_id=%#&beacon_id=%#&activation_code=%#", URL2, parentiD, beaconid, actcode];
getURL = [getURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString: getURL];
request = [NSMutableURLRequest requestWithURL:url];
NSLog(#"link: %#", getURL);
[request setHTTPMethod:#"GET"];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"connection: %#", connection);
if( connection )
{
mutData = [NSMutableData new];
}
else
{
NSLog (#"NO_CONNECTION");
return;
}
}
else if(alertView.tag == 1)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ChildListViewController *childcheck = (ChildListViewController *)[storyboard instantiateViewControllerWithIdentifier:#"ChildStoryBoard"];
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
childcheck.childNameData =[_childNameData objectAtIndex:indexPath.row];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:childcheck];
[self.window makeKeyAndVisible];
NSLog (#"Move to next View controller");
}
}
#pragma mark NSURLConnection delegates
-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
[mutData setLength:0];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
return;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
/*NSString *responseStringWithEncoded = [[NSString alloc] initWithData: mutData encoding:NSUTF8StringEncoding];
NSLog(#"Response from Server : %#", responseStringWithEncoded);
*/
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:mutData options:kNilOptions error:&error];
NSArray *fetchedArr = [json objectForKey:#"child_info"];
for (NSDictionary *user in fetchedArr)
{
beaconID = [user objectForKey:#"beacon_id"];
Name = [user objectForKey:#"name"];
trackerID = [user objectForKey:#"tracker_id"];
lat = [user objectForKey:#"latitude"];
longi = [user objectForKey:#"longitude"];
Status = [user objectForKey:#"status"];
Image = [user objectForKey:#"image"];
NSLog(#"Item beacID: %#", beaconID);
NSLog(#"Item nam: %#", Name);
NSLog(#"Item trackID: %#", trackerID);
NSLog(#"Item lati: %#", lat);
NSLog(#"Item longi: %#", longi);
NSLog(#"Item stat: %#", Status);
NSLog(#"Item ima: %#", Image);
//NSLog(#"Item parentid: %#", [user objectForKey:#"parent_id"]);
//NSLog(#"Item actcode: %#", [user objectForKey:#"activation_code"]);
}
//NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//[defaults setObject:responseActCode forKey:#"HighScore"];
//[defaults synchronize];
//NSLog(#"from data: %#", [defaults objectForKey:#"HighScore"]);
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
//Name = [[NSString alloc]init];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
AppDelegate.h
#import <UIKit/UIKit.h>
#import "ChildListViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
NSMutableData *mutData;
NSString *responseActCode;
NSString *responseParentID;
NSString *mess;
NSString *beaconID;
NSString *Name;
NSString *Status;
NSString *Image;
NSString *trackerID;
NSString *lat;
NSString *longi;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) NSString *responseActCode;
#property (strong, nonatomic) NSString *responseParentID;
#property (strong, nonatomic) NSString *mess;
#property (readonly) NSString *beaconID;
#property (readonly) NSString *Name;
#property (readonly) NSString *trackerID;
#property (readonly) NSString *lat;
#property (readonly) NSString *longi;
#property (readonly) NSString *Status;
#property (readonly) NSString *Image;
U can try this, i'm not sure if it work but hope it help
In AppDelegate.h: Add property to that stuff u want to pass, eg. #property (strong, nonatomic) NSString *string;
In AppDelegate.m: Assign value to it
In YourVC.m:
#import "AppDelegate.h"
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *yourString = [appDelegate string];
You have your data in Appdelegate now. Just create an object of it in file(Table view for you) where you need data and you can access your data now anywhere you want in that project.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSlog(#"appDelegate.fechedArray==%#",appDelegate.fechedArray);
in AppDelegate.h
#define XAppDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#end
and now you can access to your AppDelegate everywhere like this :
XAppDelegate.something
I need to upload an Image to the sever, and have to request in the background in case of the user press the home button.
- (void)uploadImage
{
AppDelegate * app = (AppDelegate *)[UIApplication sharedApplication].delegate;
[app.uploadAndDownManager uploadIDImageWithImage:_im.image];
}
-(void)uploadIDImageWithImage:(UIImage *)image
{
if (!_uploadImage) {
_uploadImage = image;
}
[self uploadImageInBackground];
}
- (void)uploadImageInBackground
{
_uploadImageTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:_uploadImageTask];
_uploadImageTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
// your code
// NSLog(#" %f",[UIApplication sharedApplication].backgroundTimeRemaining);
[self test];
[[UIApplication sharedApplication] endBackgroundTask:_uploadImageTask];
_uploadImageTask = UIBackgroundTaskInvalid;
});
}
-(void)test
{
NSString * userStr = [[NSUserDefaults standardUserDefaults] objectForKey:#"userName"];
NSString * portNumber = [[NSUserDefaults standardUserDefaults] objectForKey:#"portNumber"];
NSString * urlStr = URL_ADDRESS(portNumber, #"uploadAction_execute.action");
NSURL * url = [NSURL URLWithString:urlStr];
NSData * data = UIImageJPEGRepresentation(_uploadImage, 0.8);
//保存本地
[self saveToLocalDocument:data];
ASIFormDataRequest * re = [ASIFormDataRequest requestWithURL:url];
re.delegate = self;
[re setData:data withFileName:[NSString stringWithFormat:#"%#_id_.jpg",userStr] andContentType:#"image/jpg" forKey:#"file"];
[re setRequestMethod:#"POST"];
[re setDidFinishSelector:#selector(finish:)];
[re setDidFailSelector:#selector(failed:)];
// [re startAsynchronous];
[re startSynchronous];
}
In case the request is failed, I let it request automatically:
- (void)failed:(ASIFormDataRequest *)request
{
NSLog(#"error %#",request.error);
[self performSelector:#selector(uploadIDImageWithImage:) withObject:nil afterDelay:REQUEST_AGAIN_TIME];
// [SVProgressHUD showImage:nil status:#"验证提交成功,等待审核"];
}
When I press the home button, it may works but it can be out of time sometimes. When it fails, it won't request again! If the request asynchronous, it won't work until I enter the foreground again.
How can I fix it?
I put the code
[[UIApplication sharedApplication] endBackgroundTask:_uploadImageTask];
_uploadImageTask = UIBackgroundTaskInvalid;
in the success method finish:, it seems worked:
If there are other methods or any problem in this way, please let me know, thanks!
Please help me, I am coding iOS with background location update and send location data to my server.
below is my code:
#import "AppDelegate.h"
#implementation AppDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"Went to Background");
[locationManager startMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier locationUpdateTaskID = [app beginBackgroundTaskWithExpirationHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
if (locationUpdateTaskID != UIBackgroundTaskInvalid) {
[app endBackgroundTask:locationUpdateTaskID];
locationUpdateTaskID = UIBackgroundTaskInvalid;
}
});
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if ([[locations lastObject] horizontalAccuracy] < 100.0f) {
NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
mytoken=[userDefaults stringForKey:#"mytoken"];
if (mytoken==nil) {
mytoken=#"";
}
mybgtype=[userDefaults stringForKey:#"mybgtype"];
if (mybgtype==nil) {
mybgtype=#"all";
[userDefaults setObject:mybgtype forKey:#"mybgtype"];
[userDefaults synchronize];
}
CLLocation *newLocation = [locations lastObject];
CLLocation *oldLocation;
if (locations.count > 1) {
oldLocation = [locations objectAtIndex:locations.count-2];
} else {
oldLocation = nil;
}
NSString *NowLng=[[NSNumber numberWithFloat:newLocation.coordinate.longitude] stringValue];
NSString *NowLat=[[NSNumber numberWithFloat:newLocation.coordinate.latitude] stringValue];
UILocalNotification *scheduleAlert;
[[UIApplication sharedApplication] cancelAllLocalNotifications];
scheduleAlert=[[UILocalNotification alloc] init];
scheduleAlert.applicationIconBadgeNumber=1;
scheduleAlert.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
scheduleAlert.timeZone=[NSTimeZone defaultTimeZone];
scheduleAlert.repeatInterval=NSDayCalendarUnit;
scheduleAlert.soundName=UILocalNotificationDefaultSoundName;
scheduleAlert.alertBody=NowLat;
[[UIApplication sharedApplication] scheduleLocalNotification:scheduleAlert];
if ([mybgtype isEqualToString:#"n"]) {
} else {
[self LoadTaskMyBg:newLocation];
}
}
dispatch_async(dispatch_get_main_queue(), ^{
if (locationUpdateTaskID != UIBackgroundTaskInvalid) {
[app endBackgroundTask:locationUpdateTaskID];
locationUpdateTaskID = UIBackgroundTaskInvalid;
}
});
});
}
-(void) LoadTaskMyBg:(CLLocation *)newLocation
{
NSString *mylat = [NSString stringWithFormat:#"%.8f", newLocation.coordinate.latitude];
NSString *mylng = [NSString stringWithFormat:#"%.8f", newLocation.coordinate.longitude];
NSLog(#"task 1");
receivedDataMyBg=[[NSMutableData alloc] initWithLength:0];
NSString * urlString;
urlString = #"https://www.xx.xx/xx.cshtml";
NSURL * url = [NSURL URLWithString:urlString];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];
[request setHTTPMethod:#"POST"];
NSString *parameterString=[NSString stringWithFormat:#"%#%#%#%#%#%#%#%#", #"pp=a&tt=",#"aa",#"&mylat=",mylat,#"&mylng=",mylng,#"&myalt=",#"0"];
NSData * postData = [parameterString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postData];
connMyBg = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"task 1a");
NSLog(#"%#",parameterString);
if (connMyBg==nil) {
NSLog(#"task 1e");
return;
}
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace{
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
//NSLog(#"received authen challenge");
NSLog(#"task challenge");
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if (connection==connMyBg) {
[receivedDataMyBg setLength:0];
NSLog(#"task connect receive");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
//NSLog(#"got data %#", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
if (connection==connMyBg) {
[receivedDataMyBg appendData:data];
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"error");
if (connection==connMyBg) {
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (connection==connMyBg) {
NSLog(#"task 2");
NSString *response;
NSError *error;
response=[[NSString alloc] initWithData:receivedDataMyBg encoding:NSUTF8StringEncoding];
NSData* data = [response dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSONDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
if([[JSONDic objectForKey:#"bnum"] isEqualToString:#""])
{
} else {
UILocalNotification *scheduleAlert;
[[UIApplication sharedApplication] cancelAllLocalNotifications];
scheduleAlert=[[UILocalNotification alloc] init];
scheduleAlert.applicationIconBadgeNumber=1;
scheduleAlert.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
scheduleAlert.timeZone=[NSTimeZone defaultTimeZone];
scheduleAlert.repeatInterval=NSDayCalendarUnit;
scheduleAlert.soundName=UILocalNotificationDefaultSoundName;
scheduleAlert.alertBody=#"TEST:OK";
}
NSLog(#"%#",[JSONDic objectForKey:#"bnum"]);
}
}
#end
I can get log: "task 1a" ! but why I can't receive "task connect receive" ????
What should I do ?
Thanks.
To use a delegate for either NSURLConnection or CLLocationManager you'll need to create them as properties with a strong reference. Otherwise the delegate implementation will not get called. Since you did not provide the part where you declared those that may be the problem.
NSString* pp =[NSString stringWithFormat:#"xxxx.xx/xx.cshtml, newLocation.coordinate.latitude, newLocation.coordinate.longitude,0.0];
NSURL* response =[NSURL URLWithString:pp];
NSString* response_str =[NSString stringWithContentsOfURL:response encoding:NSUTF8StringEncoding error:nil];
NSLog(#"%#, response of report=%#", pp, response_str);
If I rewrite the code in didUpdateLocations as above,
I can get response_str and it is correct!
But question is: How can it pass ssl https without be challenged ??
even if it ready work very well!
I wonder whether it is possible to have multiple downloads when background fetch is happening (iOS7 Background Fetch).
Currently I have an app which download data from around 6 RESTful api. These API calls use NSURLSession and download data parallelly. This works when the app is in foreground. I have implemented the background fetch feature with my application where app can update while it's in background. Unfortunately when background fetch is happening only the first API is calling six time. I really appreciate if anyone can help me on this.
This is the code for download tasks.
- (void)start {
self.responseData = [NSMutableData data];
self.isLoginRequest = YES;
self.dateFormatter = [[NSDateFormatter alloc] init];
[self.dateFormatter setDateStyle:NSDateFormatterMediumStyle];
self.apiList = [NSMutableArray array];
NSArray *apis = [self fetchAPIData];
for (API *api in apis) {
NSString *fullURL = [NSString stringWithFormat:#"%#/%#",BASE_URL, api.url];
switch ([api.type integerValue]) {
case 1:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestLeadstatus andDownloadSource:fullURL]];
break;
case 2:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestParam andDownloadSource:fullURL]];
break;
case 3:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestLeadprofiles andDownloadSource:fullURL]];
break;
case 4:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestInstallations andDownloadSource:fullURL]];
break;
case 5:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestLeadproviders andDownloadSource:fullURL]];
break;
case 6:
[self.apiList addObject:[[BSJSONInfo alloc] initWithFileType:BSRequestSaleorders andDownloadSource:fullURL]];
break;
default:
break;
}
}
[self startAllDownloads:nil];
}
- (void)startAllDownloads:(id)sender {
self.session = [self backgroundSession];
// Access all download info objects using a loop.
for (int i=0; i<[self.apiList count]; i++) {
BSJSONInfo *jsonInfo = [self.apiList objectAtIndex:i];
// Check if a file is already being downloaded or not.
if (!jsonInfo.isDownloading) {
if (jsonInfo.taskIdentifier == -1) {
jsonInfo.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:jsonInfo.downloadSource]];
}
else{
jsonInfo.downloadTask = [self.session downloadTaskWithResumeData:jsonInfo.taskResumeData];
}
jsonInfo.taskIdentifier = jsonInfo.downloadTask.taskIdentifier;
[jsonInfo.downloadTask resume];
jsonInfo.isDownloading = YES;
}
}
}
-(int)getFileDownloadInfoIndexWithTaskIdentifier:(unsigned long)taskIdentifier{
int index = 0;
for (int i=0; i<[self.apiList count]; i++) {
BSJSONInfo *jsonInfo = [self.apiList objectAtIndex:i];
if (jsonInfo.taskIdentifier == taskIdentifier) {
index = i;
break;
}
}
return index;
}
- (NSURLSession *)backgroundSession
{
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:[NSString stringWithFormat:#"%#", SESSION_STRING]];
configuration.timeoutIntervalForRequest = 30.0;
configuration.timeoutIntervalForResource = 60.0;
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
});
return session;
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [URLs objectAtIndex:0];
NSURL *originalURL = [[downloadTask originalRequest] URL];
NSURL *destinationURL = [documentsDirectory URLByAppendingPathComponent:[originalURL lastPathComponent]];
NSError *errorCopy;
[fileManager removeItemAtURL:destinationURL error:NULL];
BOOL success = [fileManager copyItemAtURL:downloadURL toURL:destinationURL error:&errorCopy];
if (success){
int index = [self getFileDownloadInfoIndexWithTaskIdentifier:downloadTask.taskIdentifier];
BSJSONInfo *jsonInfo = [self.apiList objectAtIndex:index];
jsonInfo.isDownloading = NO;
jsonInfo.downloadComplete = YES;
jsonInfo.taskIdentifier = -1;
jsonInfo.taskResumeData = nil;
//Let parser to parse the JSON
dispatch_async(dispatch_get_main_queue(), ^{
self.responseData = [NSData dataWithContentsOfURL:destinationURL];
[self parsingJSONResponse:self.responseData withType:jsonInfo.type];
});
}
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
if (error != nil) {
self.networkError = error;
[self.delegate downloadingError:[error localizedDescription]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate downloadingError:[NSString stringWithFormat:#"%# for type %lu", [error localizedDescription], self.bsType]];
return;
});
}
self.downloadTask = nil;
}
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
BSAppDelegate *appDelegate = (BSAppDelegate *)[[UIApplication sharedApplication] delegate];
// Check if all download tasks have been finished.
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
if ([downloadTasks count] == 0) {
if (appDelegate.backgroundSessionCompletionHandler != nil) {
void(^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
appDelegate.backgroundSessionCompletionHandler = nil;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionHandler();
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = #"All files have been downloaded!";
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}];
}
}
}];
}
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
// BLog();
}
Thanks
Finally I found an answer by my self. If I use default delegate then the problem is solved. I afraid don't know the reason behind why the background fetch doesn't work with custom delegates when concurrently downloading.
NSURLSession *session = [NSURLSession sharedSession];
for (int i=0; i<[self.apiList count]; i++) {
BSJSONInfo *fdi = [self.apiList objectAtIndex:i];
NSURLSessionTask *downloadTask = [session downloadTaskWithURL:[NSURL URLWithString:fdi.downloadSource] completionHandler:^(NSURL *url, NSURLResponse *response, NSError *error){
NSData *d = [NSData dataWithContentsOfURL:url];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:d options:0 error:nil];
}];
[downloadTask resume];
}
I am trying to call alert view first then go to NSManagedObject. But when i click on button then it skip alert view and call this at the end of rest code.
Any one know's how can i force this uialertview to load first
Thanks
- (IBAction)confirmOrder:(UIButton *)sender
{
#pragma PopUp Alert Box
_alert = [MLTableAlert tableAlertWithTitle:#"Select Your Table" cancelButtonTitle:nil numberOfRows:^NSInteger (NSInteger section)
{
return 6;
}
andCells:^UITableViewCell* (MLTableAlert *anAlert, NSIndexPath *indexPath)
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [anAlert.table dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text = [NSString stringWithFormat:#"Table # %d", indexPath.row];
return cell;
}];
[_alert configureSelectionBlock:^(NSIndexPath *selectedIndex){
NSLog(#"Index is = %d", selectedIndex.row);
selectedTable = [NSString stringWithFormat:#"%d",selectedIndex.row];
#pragma Hit Url For New Order
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"Got udid from appdelegate = %#",appDelegate.passUdid);
NSString *new_order = [NSString stringWithFormat: #"http://localhost/food/submit_new_order.php?id=NULL&customer_id=%#&table_id=%#&order_datetime=%#&customer_instruction=Normal&estimated_time_min=30-45&actual_time=40&created_on=%#&updated_on=NULL&STATUS=new", appDelegate.passUdid,selectedTable,dateStr,dateStr];
NSString* urlTextEscaped = [new_order stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlTextEscaped];
NSData *myNSData=[NSData dataWithContentsOfURL:url];
} andCompletionBlock:^{
NSLog(#"Cancel Button Pressed\nNo Cells Selected");
}];
_alert.height = 260;
[_alert show];
NSManagedObjectContext *context = [self managedObjectContext];
NSError *error=nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"PendingOrder" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
//e
if (![selectedTable isEqualToString:NULL]) {
for (NSManagedObject *info in fetchedObjects) {
NSMutableString *pDishID = [info valueForKey:#"dishid"];
NSMutableString *pDishQuantity = [info valueForKey:#"quantity"];
NSMutableString *time = [info valueForKey:#"time"];
NSManagedObject *newDevices = [NSEntityDescription insertNewObjectForEntityForName:#"RunningOrder" inManagedObjectContext:context];
[newDevices setValue:pDishID forKey:#"dishid"];
[newDevices setValue:pDishQuantity forKey:#"quantity"];
[newDevices setValue:time forKey:#"time"];
NSLog(#"Getting ID From pending Order = %#",[info valueForKey:#"dishid"]);
#pragma Get Order ID from Order_Main
//s
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *ordrMain=#"http://localhost/food/get_order_id.php?id=";
ordrMain = [ordrMain stringByAppendingString:appDelegate.passUdid];
NSURL *urls=[NSURL URLWithString:ordrMain];
NSData *myNSData=[NSData dataWithContentsOfURL:urls];
allItemss = [NSJSONSerialization JSONObjectWithData:myNSData options:kNilOptions error:&error];
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:myNSData options:NSJSONReadingMutableContainers error:nil];
NSString *get_order_id = [[allItemss objectAtIndex:0] objectForKey:#"id"];
NSString *new_order_detail = [NSString stringWithFormat: #"http://localhost/food/order_detail.php?order_id=%#&dish_id=%#&quantity=%#&created_on=%#&updated_on=%#", get_order_id,pDishID,pDishQuantity,dateStr,dateStr];
NSString* urlTextEscaped = [new_order_detail stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:urlTextEscaped];
NSData *myNSDatas=[NSData dataWithContentsOfURL:url];
[context deleteObject:info];
}
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
}
}
[_alert show] displays the alert window and returns immediately. The "selection block"
is then called when an alert item has been pressed, or the "cancel block" is called
when the Cancel button has been pressed.
Therefore you have to move the code that fetches the managed object into the "selection block":
[_alert configureSelectionBlock:^(NSIndexPath *selectedIndex){
NSLog(#"Index is = %d", selectedIndex.row);
// ...
// Fetch object depending on selectedIndex.
// ...
} andCompletionBlock:^{
NSLog(#"Cancel Button Pressed\nNo Cells Selected");
}];