I'm using ASIHTTPRequest to download multiple files while the iPhone app is running in the background. I want to present a UILocalNotification when the queue finishes.
The following delegate method isn't called until the app is resumed:
- (void)queueFinished:(ASINetworkQueue *)aQueue
{
NSLog(#"Queue finished");
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = NSLocalizedString(#"All downloads completed");
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
[localNotification release];
}
}
So, how can I make this notification appear?
The reason your delegate isn't getting called is likely because your app is suspended in the background. If you are doing some sort of lengthy network process that continues after the user closes the app, you can use -[UIApplication beginBackgroundTaskWithExpirationHandler:] when you start the network tasks so that your application continues running in the background until you're done with the network tasks. However, it can still expire so you're not guaranteed to get enough time to finish.
From previous SO question notification when program is in background iOS 4
You do realize that when your app is in a suspended state, you won't receive any notifications -- and this is right in the documentation. There are only 3 classes of applications that can receive notifications: Audio applications (like iPod and analogues), location based applications, and voip apps. Your plist has to be set up correctly if your app is one of those applications.
Use this:
UILocalNotification *localNot = [[UILocalNotification alloc] init];
localNot.alertBody = #"Your Text";
localNot.alertAction = #"Name on the button";
localNot.fireDate = [NSDate date];
localNot.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNot];
What you're doing:
Create the LocalNotification
Add the body of your LN
Add the name of the button which appears on the "alert"
Set the fireDate to the actual date and time (maybe you need to increase the actual date with 1 or 2 seconds - for this use: dateByAddingTimeInterval:)
Set the soundName (you could also use a custom sound...)
Schedule / Create the LN
Do you have your queue maxConcurrentOperationCount set to 1?
The method setShouldContinueWhenAppEntersBackground:YES is set on a per request basis, and since you have a bunch of ASIHTTPRequest's inside a queue, only one of them may be executing at a time. This means that the other items in your queue haven't even started when you suspend the app, so the OS doesn't know yet to keep that network request alive.
I'm not sure of a solution, but I think this is the reason for what you're seeing.
Related
I am implementing an iOS8 app that runs in the background and sends a notification that asks a question every 10 mins for 3 hours. I have heard that running timers in the background for 3 hours cannot be done because the app will be suspended after a couple of minutes of going the background state. Is that true? If not will the appstore accept such an app?
There is no point for sending local notificatiosn for 3 hours in background.
Best option would be to prepare a logic which will will create a loop and schedule multiple local notification for 3 hours for example you can schedule n notifications for m duration. This way even your app will be suspended you will be getting local notifications and you can unregister all notification if user open the app.
And regarding your second question:
There is no relation with appstore policy for scheduling local notifications in background.
NSDate *newDate = [[NSDate date] dateByAddingTimeInterval:totalDuration];
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = newDate;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
This is just a rough code that you can schedule localNotifications by creating a loop with certain timeintervals. Just put your own logic i.e. 10 mins for 3 hours and supply newDate by adding time interval - 10*60secs
In iOS 5 When Application Enter background wi-fi connection is lost.
But I want to use wi-fi connection for the next 4-5 minutes before the device sleeps as some tasks can be performed within 4-5 minutes of application enter background.
I think this can be accomplished by using beginBackgroundTaskWithExpirationHandler:, but i am not able to solve the problem
just disable iPhone to go to sleep mode
-(void) sleepModeDisable{
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
}
call this function every 10 second, this might help u
The way I handle this is to use beginBackgroundTaskWithExpirationHandler for every network request I'm sending.
This way I make sure that all my networking will completed even if my app moved to background.
I'm usually using one singleton object to handle all network request, so before the request is sent I call
- (void)startBackgroundTask
{
// ask for extra time if this is called when app go to suspended
UIApplication *application = [UIApplication sharedApplication];
_bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you.
// stopped or ending the task outright.
[application endBackgroundTask:_bgTask];
_bgTask = UIBackgroundTaskInvalid;
}];
}
And after I get a response (success/failure) or if I canceled the request, I call
- (void)stopBackgroudTask
{
UIApplication *app = [UIApplication sharedApplication];
if (_bgTask != UIBackgroundTaskInvalid) {
[app endBackgroundTask:_bgTask];
_bgTask = UIBackgroundTaskInvalid;
}
}
* Don't forget to define UIBackgroundTaskIdentifier *_bgTask;
Also if you are planning to make a massive use of Wi-Fi you should set the Application uses Wi-Fi key in your plist file to YES, otherwise your Wi-Fi will be shut done after 30 minutes even if your app is running.
No rocket science here, this is intended behavior in iOS that to save battery the Wi-Fi shuts off when phone is locked UNLESS you tell iOS that your app needs a persistant Wi-Fi, then it wont close it for you when your app is running.
For that just add UIRequiresPersistentWiFi to your info.plist and mark it YES
Documentation
i wrote like:
[NSTimer scheduledTimerWithTimeInterval:900 target:self selector:#selector(CallGetCounts) userInfo:nil repeats:YES];
that means i want to repeat my timer for every 5 mins but my timer is not repeating, not able to find the reason
can any one please tell me the answer.
I wrote this in "AppDelegate" -> "- (void)applicationDidEnterBackground:(UIApplication *)application" method.
In background your code is suspended and no timer events you will receive until your application comes to the foreground again.
You should go for scheduled local notifications to get waken up from background after a given interval. However they will show a popup or a banner to the user that he has to accept first.
Here are some steps on how to do it:
// When you want to schedule:
UILocalNotification* localNotification = [[[UILocalNotification alloc] init] autorelease];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5]; // seconds
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = #"Body text";
localNotification.alertAction = #"Button text";
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// when it's fired it will call your AppDelegate's didReceiveLocalNotification
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification
{
// you can handle timer event here and eventually re-schedule your local notification
}
Normally when an app enters the background, it is suspended so it doesn't execute at all. In particular, NSTimers don't fire. If you want something to happen in the background, you need to configure your app to run in the background and use one of the approved methods of performing the task you want to do. running NSTimers is not one of the supported tasks.
I suggest you review the iOS Programming Guide and particularly the Background Execution and Multitasking section.
The instance of UILocalNotification fires the pop up box(and waken up your app) whenever it triggered as per the time you set, If you really chosen the UILocalNotification then Here are the good tutorial links discussed in S.O thread. Hope those will help you.
I have a GPS app that registers to run in the background. I also show a UILocalNotification when I have finished a process. This correctly shows, and if the app is open, then it also appears in Notification Center (swipe down from top). But, if I call the UILocalNotification when my app is in the background, or the screen is locked, I DO get the notification, but it does NOT show up in Notification Center.
I am correctly registering for notifications in my app delegate (iOS 5 bug workaround):
// Register for notifications
[[UIApplication sharedApplication]registerForRemoteNotificationTypes:
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound];
Calling the notification:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.alertBody = msg;
localNotif.alertAction = NSLocalizedString(#"View", nil);
localNotif.soundName = #"alert.caf";
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotif];
[localNotif release];
Is this a bug? Why would it show up in Notification Center only when my app is open, even though the notification is shown to the user, and not other times?
Are you also using push notifications? I believe there is no need to call registerForRemoteNotificationTypes: if you are only using local.
Check Here
From the look of the code you posted, it does not look like the code would run in the background. It looks like you are trying to present a Local Notification when an even occurs in the background. You can not do this. Local Notifications are meant to be scheduled while the app is running to go off at a later time when the app is not running, and then they will trigger even when the app is closed.
You need to use Push Notifications. Check out Apple's documentation here.
EDIT: Is your app enabled for the notification center in settings?
have you added the UIBackgroundModes key to your Info.plist file ?
You need to have the UIBackgroundModes Key set to location.
I have implemented one reminder iphone applicaion in which I have used local notification for reminder.
In this application their one functionality alert on/off.
So when user set on then user get notification and if its off then user can get notification.
I have done googling but not got sucess.
Can you give me idea for that is it possible or not.
Thanks in advance
Do you have other notifications in your appln.
If you don't have other notification in your app than,
Do one thing,
When you set OFF
- cancel all the notification
- calculate the time difference of current time & your notification firing time. set this in to some variable.
when you set it ON
- reschedule your Notification based on the time which you have saved earlier.
I am considering that you know how UISwitch works, according to switch position
UILocalNotification *localNotif;
//if switch is on
localNotif = [[UILocalNotification alloc] init];
//else if localNotif is not equal to null then
localNotif = nil;
You can start a timer which continuously check switch position and do the above stuff that depends on your coding.