scheduleLocalNotification doesn't work for jailbreak apps? - iphone

I have an app that calls scheduleLocalNotification, but it doesn't work when I install it to /Applications instead of /var/mobile/Applications:
- (void) doNotify
{
// this doesn't work when app is in /Applications but does in /var/mobile/Applications
UILocalNotification * theNotification = [[UILocalNotification alloc] init];
theNotification.alertBody = #"Finished processing.";
theNotification.alertAction = #"Ok";
theNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
[[UIApplication sharedApplication] scheduleLocalNotification:theNotification];
NSLog(#"notification scheduled: %#", theNotification);
}
I tried presentLocalNotification instead in case it was a timing issue.
I implemented didReceiveLocalNotification in app delegate to see if that was being called instead, but it wasn't, it was only called when app is in foreground like it should.
If I put the app back in /var/mobile/Applications, it works as it should.
I'm using Xcode 4.2.1 and running iOS 5.1.1 on an iPhone 4S and iPod Touch 4g
EDIT: App can run in the background because it is a music app

I met the same problem just now. And I already solve this problem through the official document.
In fact, you should regist the notification to get access to use notification:
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
[[UIApplication shareApplication] registerUserNotificationSettings: settings];

Register for Notifications
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:UIUserNotificationTypeAlert| UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];
}
[launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
}
Schedule Notification
- (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.
NSLog(#"startLocalNotification");
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
notification.alertBody = #"notification Message ";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
//notification.applicationIconBadgeNumber = 10;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

Related

UILocalNotification does not fire after 10 minutes in background

I have a VoIP application. Which is working fine. Call is working in foreground and background.
Following steps are done:
UIBackgroundModes => voip in Info.plist
Configured one of the app’s sockets for VoIP usage.
Before moving to the background, setKeepAliveTimeout:handler: is called
Configured audio session to handle transitions to and from active use.
To ensure a better user experience on iPhone, used the Core Telephony framework to adjust behavior in relation to cell-based phone calls;
To ensure good performance for VoIP app, used the System Configuration framework to detect network changes and allow app to sleep as much as possible.
Now the thing is when application is in background and a call comes then UILocalNotification fires for the following. And user can see a notification with two buttons CANCEL and RECEIVE
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask: bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_main_queue(), ^{
while ([application backgroundTimeRemaining] > 1.0) {
NSString *friend = [self checkForIncomingChat];
if ([friend length]>0) {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif) {
localNotif.alertBody = [NSString stringWithFormat: NSLocalizedString(#"%#", nil), friend];
localNotif.alertAction = NSLocalizedString(#"Receive", nil);
localNotif.soundName = #"alarmsound.caf";
localNotif.applicationIconBadgeNumber = 1;
[application presentLocalNotificationNow:localNotif];
friend = nil;
}
}
sleep(1);
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
- (NSString *) checkForIncomingChat {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *incall = [prefs objectForKey:#"incall"];
if ([incall length]>0) {
[prefs setObject:#"" forKey:#"incall"];
return incall;
}
return #"";
};
Now the problem is:
After going to the background by pressing home button application fires UILocalNotification if any call comes within 10 minutes.
After 10 minutes if any call comes it is running in the background. UILocalNotification does not fire, so user can not know anything.
It happens because background task stops after 10 minutes.
How can I manage it or extend background task for long running or restart background task.
More and more answer I have found after searching but nothing works for long running background task.
Please anybody help me. I am trying it since 2 weeks.
It sounds like you have a VoIP socket that you are receiving the call on, so rather than looping and polling for call state, you can just present the local notification at the point that you read the data off the socket.
If the VoIP control socket is TCP, and marked with the appropriate ...NetworkServiceTypeVoIP key, your app will automatically get woken up from suspension for 10 seconds, at which point you can present the local notification.
See Configuring Sockets for VoIP Usage for more information.
Once that is done, all of the code that you shared above can be removed.

startMonitoringSignificantLocationChanges if can terminated my app

i am want to use startMonitoringSignificantLocationChanges in my app,but i have some question,i hope get some help:
for a common app if app enter background,after 10mins ,system can kill the app.if i used startMonitoringSignificantLocationChanges ,when i enter background two hours,my app not terminated,because i click the icon,app will enter the last quit page 。if app is killed,when you click the icon you will first see the default page. so my question is use startMonitoringSignificantLocationChanges my app not killed by system after enter background 10 mins?
if i close mobile,and restart the mobile,when significant location change,my app if can be activate ,i look apple develop document it answer yes.so i test:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if([CLLocationManager significantLocationChangeMonitoringAvailable]){
[self log:#"sigAvailable=YES"];
}
// Override point for customizatio-n after application launch.
id locationValue = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey];
if (locationValue)
{
// create a new manager and start checking for sig changes
[self log:#"didFinishLaunchingWithOptions location key"];
m_locManager = [[CLLocationManager alloc] init];
[self log:#"didFinishLaunchingWithOptions created manager"];
m_locManager.delegate = self;
[self log:#"didFinishLaunchingWithOptions set delegate"];
[m_locManager startMonitoringSignificantLocationChanges];
[self log:#"didFinishLaunchingWithOptions monitoring sig changes"];
// do send local notification
return YES;
}
[self log:#"didFinishLaunchingWithOptions"];
return YES;
}
my question: when restart mobile and local notification,above code is run and log "didFinishLaunchingWithOptions location key" and so on,if i send local notification at the above code, if user will receive?
in ios 6 there is new feature for maps, which stops location updates
It helps to wake app to recieve location updates.link
locationManager.pausesLocationUpdatesAutomatically
Also see all others.
Your app can start on device boot if its VOIP.
see this apple doc
for local notification add to
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// creating local notification
Class cls = NSClassFromString(#"UILocalNotification");
if (cls)
{
UILocalNotification *notification = [launchOptions objectForKey:
UIApplicationLaunchOptionsLocalNotificationKey];
if (notification)
{
NSString *reminderText = [notification.userInfo
objectForKey:kRemindMeNotificationDataKey];
NSLog(#"notification text:%#",reminderText);
// [viewController._msgTextView setText:reminderText];
}
}
application.applicationIconBadgeNumber = 0;
and you can handle them in
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"application:didReceiveLocalNotification:");
}
you can schedule your local notification in
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil)
{
UILocalNotification *notif = [[cls alloc] init];
notif.fireDate = notifyDate;
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = AlertMsg;
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
notif.alertAction = #"Show me";
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
}
}

How can I use local notifications to wake my app?

i want that my app will run in the background and do check on somethings.
and if so the local notification will show.
i use this code in the method that check:
UIApplication *app = [UIApplication sharedApplication];
UILocalNotification *notification = [[UILocalNotification alloc] init];
NSArray *oldNotifications = [app scheduledLocalNotifications];
if ([oldNotifications count] > 0) {
[app cancelAllLocalNotifications];
}
if (notification == nil)
return;
NSDate *notificationDate = [NSDate dateWithTimeIntervalSinceNow:10];
notification.fireDate = notificationDate;
notification.timeZone = [NSTimeZone systemTimeZone];
notification.alertBody = #"Test Body";
[app scheduleLocalNotification:notification];
[notification release];
the problem is that when the app is in the foreground it show the alert, but if the app is in the background the notification not show to the screen.
the check that i do is running on uiwebview and reload every 10 seconds, so he need to run in the background too.
Your app won't run in background, except certain cases. Look in to this How to run the application in the background? post.

About Push Notification

I am developing an app ,where I need to provide the notification to the user, when he is say x meter from the location.I have implemented the map,the logic for all that.Now I want to implement the push notification in that.I have read here on the stack overflow but didn't find the solution.I knew that I need to provide the methods in the app delegate.But i want to know how my server will come to know that the user is x meters from the destination.Do I also need to parse the webservice and send the data in the didupdatetoUserLocation.Or the server will take care of that.If server would that then how the server will come to know.
Any help would be appreciated
Thanks All......
you would have to send all the location-information to your server and your server would have to calculate, whether the push service shall become active or not. That would just work, if the application is active in the background and would cause a lot of communication stack.
I would suggest to use the local push service. By calling a function in the background on the device you can track the location and compare it to the "push"-location. If the push shall be shown, continue with UILocalNotification which is available since iOS 4:
http://developer.apple.com/library/ios/#documentation/iphone/Reference/UILocalNotification_Class/Reference/Reference.html
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
{
return;
}
localNotif.fireDate = [NSDate date];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(#"Hey there, you are here: %#\n%#", nil), #"Country", #"Town"];
localNotif.alertAction = NSLocalizedString(#"W00t show me", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1344] forKey:#"LocationPush"];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
Since you need a server based push service, implement the following methods in your appdelegates method applicationDidFinishLaunching, thats how you can register the device for the service:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound)];
Further on you can implement the following methods for detailed settings:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
{
}
Since I'm not that familiar with server-based push notification I can't tell you more, all I know about is, that you need to set up a server with the key, that you generated and registered in the provision profile of apple:
http://developer.apple.com/ios/manage/bundles/index.action

Setting Local Notifications on a new thread?

I need to know if it is possible to create a new thread to handle setting local notifications.
My app depends heavily on these notifications, so I want to make the app work while the phone sets the notifications.
Example:
(now)
you launch the app, the app hangs at the splash screen to set the local notifications, then it launches.
(I want)
The app launches and is usable while the Local notifications are set.
I need some sample code, too, please :)
(for the record, i am setting 60 local notifications each time the app enters foreground for my own reasons...)
Thanks!!
Yes this can be done, I do it all the time:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Add the navigation controller's view to the window and display.
[NSThread detachNewThreadSelector:#selector(scheduleLocalNotifications) toTarget:self withObject:nil];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
-(void) scheduleLocalNotifications
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < 60; i++)
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
NSDate *sleepDate = [[NSDate date] dateByAddingTimeInterval:i * 60];
NSLog(#"Sleepdate is: %#", sleepDate);
localNotif.fireDate = sleepDate;
NSLog(#"fireDate is %#",localNotif.fireDate);
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(#"This is local notification %i"), i];
localNotif.alertAction = NSLocalizedString(#"View Details", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
NSLog(#"scheduledLocalNotifications are %#", [[UIApplication sharedApplication] scheduledLocalNotifications]);
[localNotif release];
}
[pool release];
}
Taken from a project I am working on now, I can confirm that It works as expected.
EDIT:
Example was leaking in scheduleLocalNotifications because handling the NSAutoreleasePool was missing – now it's added to the example.
One way to do threads is with is with performSelectorInBackground.
For example:
[myObj performSelectorInBackground:#selector(doSomething) withObject:nil];
You should note, however, that Apple is pretty strongly recommending that you use higher-level concepts like NSOperations and Dispatch Queues instead of explicitly spawning threads. See the Concurrency Programming Guide