I'm working on an app that alerts the user when he is close to some landmarks using the region monitoring. Everything works fine but when the app is in the background I don't get the alerts. When I open the app I get all the alerts popping up. What I wanted was to get them when the app is in the background. I'm wondering if it's possible or does the app needs to be running to get alerts? Any help would be greatly appreciated.
Update:
The problem seems to be that I used Alerts instead of local notifications. Here's the code I used:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Entered Region - %#", region.identifier);
[self showRegionAlert:#"You are near: " forRegion:region.identifier];
}
How can I change this to local notifications?
Check the "testing your apps region monitoring" section in
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/RegionMonitoring/RegionMonitoring.html
If you switch back and forth between foreground and background the threshold conditions might not be met and trigger before you bring the app to the foreground again.
Also when the backgrounded app gets a notification there is only a small window for processing the message. Trying to do network requests might time out...
Check your plist settings - declare location as UIBackgroundModes only required if you need high precision positioning. The significant location changes works even without location defined.
Check that locationManager:didUpdateLocations: and locationManager:didFailWithError: are being called and no errors are posted.
Check that you haven't set ApplicationRunsInBackground to NO in your plist.
Try implementing the AppDelegates applicationDidEnterBackground:, application:didFinishLaunchingWithOptions: and friends to spot where in the app lifecycle you are at a given time.
For geofencing solution, you can refer the answer given by #Niels Castle.
For local notification, you can refer below code:
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = #"I'M IN THE REGION";
localNotification.userInfo = [[NSDictionary alloc]initWithObjectsAndKeys:#"nearBy",#"type", nil];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Yes! Welcome to %#",region.identifier);
UILocalNotification* notify = [UILocalNotification new];
notify.alertBody = [NSString stringWithFormat:#"Welcome to %#",region.identifier];
notify.soundName = UILocalNotificationDefaultSoundName;
if (notify.applicationIconBadgeNumber == 0) {
notify.applicationIconBadgeNumber = 1;
}
[[UIApplication sharedApplication] presentLocalNotificationNow:notify];
}
Related
I am a little bit confused if i have to do that,or the system :
Using the iBeacon there is a method that is fired when app is in background or closed.
There , i would like to write the code that will show the user a push notification on the iPhone home screen, to let him know about it .
How would i do such a simple thing ?
//happens in background when user inside a place
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"***********************ENTER");
//here show notification !
You could try something like this. This will schedule a local notification to fire at a set date and time (you need to provide the NSDate and message).
...
NSDate *fireDate = // whatever date and time you want to fire the notification
NSString alertMessage = #“Alert message!";
[self addNotification:fireDate mymessage:alertMessage];
...
-(void)addNotification:(NSDate *)mydate mymessage:(NSString *)mymessage
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = mydate;
localNotification.alertBody = mymessage;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
Im working on an app that does some computationally heavy tasks that take a long time. I want to notify the user with a local push notification when the task is done. Is this possible? The only information I have been able to find online is to do with triggering notifications at certain times/dates or if the app has entered the background or terminated, all of which is done in the appDelegate. Is there a way to do this in my own classes?
Thanks.
I'm not 100% certain you're looking for a UILocalNotification example because the post title mentions push notifications. Either way, you can schedule local notifications from any class you want
- (void)throwLocalNotificationWithMessage:(NSString*)message {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
NSDate *now = [NSDate date];
localNotification.fireDate = now;
localNotification.alertBody = message;
localNotification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[UIApplication sharedApplication].applicationIconBadgeNumber++;
}
Also, for my needs I throw these local notifications when region monitoring detects boundary enter/exit changes. This code runs while my app is in the background, as well, and in that case they appear like push notifications.
The above answer by Aaron works fine but don't forget to ask permission for Local Notification. In my case case I ask permission at AppDelegate under -
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
and here is the code for iOS8 and iOS9
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
I've been struggling for the past few days on the local notifications on my app.
Basically the goal is to pop a notification when the user approches an address.
here is the code:
NSMutableArray *notifications = [#[] mutableCopy];
for (CCAddress *address in results) {
CCCategory *category = [address.categories.allObjects firstObject];
NSDictionary *userInfo = #{#"addressId" : address.identifier};
UILocalNotification *localNotification = [UILocalNotification new];
if (category == nil)
localNotification.alertBody = [NSString stringWithFormat:#"Vous êtes proche de %#", address.name];
else
localNotification.alertBody = [NSString stringWithFormat:#"Vous êtes proche de %#, %#", address.name, category.name];
localNotification.alertAction = #"Linotte";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.userInfo = userInfo;
[notifications addObject:localNotification];
address.lastnotif = [NSDate date];
}
[managedObjectContext saveToPersistentStore:NULL];
[UIApplication sharedApplication].scheduledLocalNotifications = notifications;
The result is actually totally random, but there is something I know for sure: the geofencing works well, as you can see I set the date of the notification in lastNotif, so I know when they are fired.
Sometimes I see the notification pop, but doesn't stay in the notification center, but most times nothing happens, even if I see by the date that It actually fired, and sometimes everything goes fine.
I tried many things, like using presentLocalNotificationNow, setting a fireDate with a 1 second delay between each, and other things I don't even remember...
So, obviously there is something I missed in the documentation, but what ?
thanks.
PS: the app is in background or off when it happens, I'm aware of didReceiveLocalNotification.
PS2: I actually don't know if those that I don't see at all actually fired, because they don't show up in the notification center, so maybe they fired but I have absolutely no way to see them if I don't have my phone's screen in sight when they do.
EDIT: So, I've been doing some tests around my house, phone closed, screen locked. The real syndrom is that when a notification pops, it only turns the screen on, and the phone vibrates (I was sound off), then nothing...
I don't see that you're setting a fireDate. I can't recall what that defaults to.
Ok, so as intended, it was kind of stupid.
Before the code I posted I had:
if ([results count] == 0) {
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
return;
}
But, when you set applicationIconBadgeNumber to 0, it removes all notifications from notification center !
The documentation says nothing about this (https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/Reference/Reference.html).
You need to add registerUserNotificationSettings in didFinishLaunchingWithOptions it give us notification Alert
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification) {
application.applicationIconBadgeNumber = 0;
}
return YES;
}
I am working on such a project where apps do the following things:
1.Getting user current location.
2. Get local notifications when user enters or nearby the particular locations i provided.
What i have done is:
I have downloaded the regions sample code(apple provided) to find out my current location using IOS corelocation framework.It works fine.here's the code below:
// Create a new region based on the center of the map view.
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(regionsMapView.centerCoordinate.latitude, regionsMapView.centerCoordinate.longitude);
CLRegion *newRegion = [[CLRegion alloc] initCircularRegionWithCenter:coord radius:2.0 identifier:[NSString stringWithFormat:#"%f, %f", regionsMapView.centerCoordinate.latitude, regionsMapView.centerCoordinate.longitude]];
Now, my question is how to add specific regions with latitude& longitude to get notified?
Help is highly appreciated.Anybody knows any example or tutorial.
The SetSDK should help make this super easy, https://cocoapods.org/pods/SetSDK. It allows you to setup notifications for user arrival and departure from locations. It currently learns those locations on the fly, but there is a coming release that includes arbitrary location subscription. Your app will receive a notification and you can execute whatever handler you want from there. It would look something like this,
SetSDK.instance.onArrival(to: .any) { newArrival in
/* Compare the new location with the one of interest (50m) */
if newArrival.location.distance(from: placeOfInterest) < 50 {
/* do your things here */
}
}
Explore the location-based services provided by the iOS Core Location framework.
here are some good tutorials. It may help you
Geofencing with Core Location
Geofencing on iOS
iOS Geofencing API Tutorial Using Core Location Framework
1.Getting user current location.
I have lengthy post and sample codes that I posted on my blog and Github on how to get location for iOS 7.
Background Location Update Programming for iOS 7
Github Project: Background Location Update Programming for iOS 7
2. Get local notifications when user enters or nearby the particular locations i provided.
You will have to use startMonitoringForRegion to monitor the region that you created.
CLLocationCoordinate2D regionCentre = CLLocationCoordinate2DMake(latitude, longitude);
CLCircularRegion *region= [[CLCircularRegion alloc] initWithCenter:regionCentre radius:radius identifier:#"Name"];
[locationManager startMonitoringForRegion:region];
From the locationManager delegate, you will be notified when you enter the region.
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region{
NSString* message = [NSString stringWithFormat:#"Message";
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateBackground || state == UIApplicationStateInactive)
{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate date];
NSTimeZone* timezone = [NSTimeZone defaultTimeZone];
notification.timeZone = timezone;
notification.alertBody = message;
notification.alertAction = #"Show";
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
}
I'm firing a Local notification when user enters a region via geofencing. But when I press the home button to see the local Notification in action it does get shown but there is no sound. I tried to disable and enable the "Play user interface sounds.." within the mac settings, close and reopen xcode, clean the project and finally restart the mac. nothing worked..
What am I missing?
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Entered Region - %#", region.identifier);
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
[localNotification setAlertBody:#"You are about to enter.."];
[localNotification setSoundName:#"Voicemail.caf"];
UIApplication *application = [UIApplication sharedApplication];
[application presentLocalNotificationNow:localNotification];
}
Here you can pass your sound file name
UILocalNotification *notifThreshold = [[UILocalNotification alloc]init];
if(notifThreshold)
{
notifThreshold.alertBody = statusMsg;
notifThreshold.alertAction= #"Open";
notifThreshold.userInfo = userInfo;
notifThreshold.soundName = UILocalNotificationDefaultSoundName;
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateBackground)
{
notifThreshold.applicationIconBadgeNumber = [[UIApplication sharedApplication]
applicationIconBadgeNumber]+1;
}
[[UIApplication sharedApplication] presentLocalNotificationNow:notifThreshold];
}
Go to Build Phases and add your .caf file to Copy Bundle Resources. It helped me
Please make sure the sound of your app in notification center is enabled , And instead of using cap extension try to use wav extension for example "beep.wav" or "Default.wav" ...