I am creating an alarm app that sends udp data when the alarm goes off. At the moment the udp data is sending as soon as the alarm is set, not when the alarm goes off. I was thinking i could do this using an if statement? I think this is the right bit of the code. Please help!!
-(void)scheduleloalNotificationWithDate:(NSDate *)fireDate {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = fireDate;
notification.alertBody = #"Time For Coffee!";
SwitchOn= [sendOn dataUsingEncoding:NSUTF8StringEncoding];
NSString *newIP = [setting IP];
NSLog(#"IP = %#", newIP);
if(!newIP){
[socket sendData: SwitchOn toHost: #"192.168.0.2" port: 5900 withTimeout:-1 tag:1];
// NSLog(#"cancel");
}
else{
[socket sendData:SwitchOn toHost: newIP port: 5900 withTimeout:-1 tag:1];
}
[[UIApplication sharedApplication] scheduleLocalNotification: notification];
[notification release];
}
The application might be terminated after the notification is scheduled but before fired. As a user i could dismiss the notification not opening the app, which means the data will not always be sent. There also will appear a race condition for multiple updates if the user is using the same app with several devices.
If you still want to update the data when the application is fired instead of when it is scheduled, the UILocalNotification overview will help you to understand all the situations you'll have to handle.
PS you've missed c at scheduleloalNotificationWithDate
Related
Can I run firebase listener when app is closed so I could push local notification with out use of back end to send notification
also can I push notification from firebase automatically depends on change of firebase in database
I ran it in back ground so I can push
- (void)applicationDidEnterBackground:(UIApplication *)application {
FIRDatabaseReference *ref = [[FIRDatabase database]reference];
[[[ref child:#"classes"]child:#"classA"]observeEventType:FIRDataEventTypeChildChanged withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
FIRDataSnapshot *child;
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil) return;
NSDate *fireTime = [[NSDate date] addTimeInterval:3];
localNotif.fireDate = fireTime;
localNotif.alertBody = #"Alert! from back ground";
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}];
}
As far as I know, Firebase uses TCP connection to notify the devices that are observing a database path. And for that reason, Firebase can't run in the background, as Apple doesn't allow TCP Connections in the background.
So sadly, what you're trying to do doesn't work.
My title might not accurately depict my question, so I apologize. I have looked for a solution to creating this level of functionality but I am unable to find it.
I am creating a VoIP application for iOS 8. When a user receives a call I am displaying a notification with a 12 second ringtone. While this notification is in progress if the call disconnects I want the Incoming Call notification to disappear and display a Missed Call notification immediately. This level of functionality is possible because Viber does it.
Currently, I am sending a silent push notification when a Incoming Call is available. This is my payload...
aps = {
"content-available" = 1;
};
category = INCOMING;
from = "+15555554220";
Upon receiving the silent push I am creating a Local Notification like this ...
if ([userInfo[#"category"] isEqualToString:#"INCOMING"]) {
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Incoming Call Notification Received");
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Sending Local Notification For Incoming Call");
// Get Caller Contact Info
NSDictionary *contact = [self findContactInfoForNumber:userInfo[#"from"]];
NSString *message = [NSString stringWithFormat:#"Incoming Call: %#",userInfo[#"from"]];
if (contact != nil) {
message = [NSString stringWithFormat:#"Incoming Call: %# %#",contact[#"firstName"],contact[#"lastName"]];
}
UILocalNotification *notification = [[UILocalNotification alloc] init];
NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithObject:#"Incoming Call" forKey:#"type"];
notification.userInfo = infoDict;
notification.category = #"INCOMING_CALL_CATEGORY";
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
notification.alertBody = message;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = #"ring.m4a";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
Then, once the call is disconnected I am sending another silent push notification for a missed call...
aps = {
"content-available" = 1;
};
category = MISSED;
Once received I am canceling all local notifications like this...
if ([userInfo[#"category"] isEqualToString:#"MISSED"]) {
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Missed Call Notification Received");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
The issue I am encountering is that on the lock screen it behaves exactly the way I want it to. I receive the incoming call notification and when the caller hangs up that notification immediately disappears from notification center and a missed call notification is there in the place of it. However when the phone is on the home screen. A banner is shown and then it plays the whole ringtone then displays the missed call. Does anyone know the reason why this is happening? Does anyone have any solutions to achieve this level of functionality? Like I said before the app Vider is a prime example of what I want my app to do.
Thanks you in advance.
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 got my push notification successfully in both background and foreground but my problem is when my application is in active state/foreground and push notification is arrived then i show this pushnotification message on alertview using didReceiveRemoteNotification method,
My alert view have two buttons
1) later
2) Ok.
If I press 1) "later" button then I want add this pushnotification message in notification area so after some time user can see and tap on that particular push notification and go with that and that record of push notification will remove from notification area.
This is not possible. There is no API to access notification are of iOS.
Alternative
What near alternative you can try is Local Notification. When user select later set Local Notification for that thing. You can add this Local Notification when user leave your app so that you don't get notification while user is continue with your application.
Better Approach
The most general approach for this problem is Notification screen in app. Your application has one screen which has list of received notification so that user can check that in you app. I suggest you to go with this. Because this is most common and clear idea.
You need to implement core data for Notifications but it can only happen when your Application is is Active state.
1-create a new identity everytime a new notification arrive.
2-save it.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSDictionary *Notification = userInfo;
NSString *title = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"title"];
NSString *body = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"body"];
XXNotification *objNotification = [XXNotification create];
objNotification.title = title;
objNotification.detail = body;
[XXNotification save:nil];
NSArray *arrNotification =[XXNotification allUnRead:nil];
[UtilityFunctions setApplicationBadgeNumber:[arrNotification count]];//Utility functions is my class for common functions.
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
[UtilityFunctions showAlertView:title message:body delegate:self cancelButtonTitle:#"Ok" otherButtonTitle:#"Cancel" withTag:99 withAccessibilityHint:[NSString stringWithFormat:#"%#:|:%#", title,body]];
}
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateInactive || [[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.userInfo = userInfo;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = body;
localNotification.fireDate = [NSDate date];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
if (![IsLocationSaved isEqualToString:#"NO"])
{
[[NSNotificationCenter defaultCenter]postNotificationName:kNotificationForShowingNotification object: nil userInfo:nil];
}
}
}
On showing the UIAlertView, on its click event either delete that notification in DB or make a bool in it as isRead and make it YES. then save it,
On Notifications list Query the notification from DB or only those whose isRead = NO.
That is the way I did it in My Application.
I have an app where I need to send a UILocationNotification when the app is not in the foreground / Active. If I have my code to do so, it will not send until the app is opened and is active.
Here is my function:
- (void)setLocalNotificationForType:(SPKLocalNotificationType)notificationType fromUser:(NSString *)userName withMessageText:(NSString *)msgText {
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.userInfo = #{#"handle": _convoHandle, #"room": _convoName};
notif.fireDate = [NSDate date];
notif.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
notif.soundName = UILocalNotificationDefaultSoundName;
notif.timeZone = [NSTimeZone defaultTimeZone];
if (notificationType == 1) { // message
notif.alertBody = [NSString stringWithFormat:#"#%# said: \"%#\"", userName, msgText];
} else if (notificationType == 2) { // image
notif.alertBody = [NSString stringWithFormat:#"#%# sent an image", userName];
} else {
return;
}
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
}
}
Update:
It now seems that the problem is that the connection to the server is being "paused" while the app is in the background. Once I then open the app all the data comes in at once. I am using SocketRocket for connecting to my Node.js Primus web socket server. Is this something that normally happens? This is my first time using SocketRocket so I'm not sure.
Update:
I have also enabled Remote Notifications for Background Modes, I have also registered for remote notifications, and on the device, I have also made sure that "banners" and "badges" are enabled.
Update:
I have additionally set the web socket to use a background queue.
[webSocket setDelegateOperationQueue:[NSOperationQueue new]];
The connection is still being paused.
Thanks!
Edit: It looks like SocketRocket uses the main dispatch queue by default, which runs on the application's main thread. When the app is backgrounded, processing on the main thread stops, so it would be worth trying to move the work to a background thread in a background operation queue.
On your SRWebSocket object, try calling:
[webSocket setDelegateOperationQueue:[NSOperationQueue new]];
Without checking the docs, perhaps setting timeZone and fireDate on the UILocalNotification is interfering. You don't need those if you're going to pass the notification to presentLocalNotificationNow:.
I have also found that, even if you're using local notifications exclusively, you must:
Enable Remote notifications for your target on the Capabilities tab under Background Modes
Enable either alerts or banners in the Settings app, in Notification Center settings.
A sample event handler for a background fetch:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
UIBackgroundFetchResult result = UIBackgroundFetchResultNoData;
// ... perform a network request
if (successfulNetworkRequest) {
UILocalNotification* localNotification = [UILocalNotification new];
localNotification.alertAction = #"View";
localNotification.alertBody = #"Stuff";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
localNotification.userInfo = #{#"stuff": #"other stuff"};
[application presentLocalNotificationNow:localNotification];
result = UIBackgroundFetchResultNewData;
} else {
result = UIBackgroundFetchResultFailed;
}
completionHandler(result);
}
I am afraid you are misunderstanding of local notification. I guess what you should do is registering a notification in the future and send it some time after user clicked the home button. But in your code, you registered a alert in CURRENT TIME and did some thing on the notification (sorry but I don't know what you want to do in your code).
You could change it like this to make a sense:
- (void)setLocalNotificationForType:(SPKLocalNotificationType)notificationType fromUser:(NSString *)userName withMessageText:(NSString *)msgText {
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.userInfo = #{#"handle": _convoHandle, #"room": _convoName};
//Set the fire time 10 seconds later
notif.fireDate = [[NSDate date] dateByAddingTimeInterval:10];
notif.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
notif.soundName = UILocalNotificationDefaultSoundName;
notif.timeZone = [NSTimeZone defaultTimeZone];
if (notificationType == 1) { // message
notif.alertBody = [NSString stringWithFormat:#"#%# said: \"%#\"", userName, msgText];
} else if (notificationType == 2) { // image
notif.alertBody = [NSString stringWithFormat:#"#%# sent an image", userName];
} else {
return;
}
//Register this notification
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
And in your app delegate's -applicationDidEnterBackground:, call your -setLocalNotificationForType:fromUser:withMessageText: method to make and register a notification. Then you can expect a local notification 10s after you click the home button.