I'm trying to add an action to the iOS remote notification.
This is the command I'm sending to houston (https://github.com/nomad/houston)
apn push "APNS_TOKEN_HERE" -c /Users/johannwerner/Desktop/apple_push_notification.pem -P '{"aps":{"alert":{"action-loc-key":"OK","title":"hello","body":"Hello"},"category":"ACTIONABLE"}}'
When the app launches from the push notification and I log launchOptions from the didFinishWithOptions method I get the following
{
UIApplicationLaunchOptionsRemoteNotificationKey = {
aps = {
alert = {
"action-loc-key" = OK;
body = Hello;
title = hello;
};
category = ACTIONABLE;
};
};
}
When I'm registering the notification in the code I'm using the following.
if (NSClassFromString(#"UNUserNotificationCenter")) {
UNNotificationAction* snoozeAction = [UNNotificationAction
actionWithIdentifier:#"SNOOZE_ACTION"
title:#"Snooze"
options:UNNotificationActionOptionNone];
UNNotificationCategory* generalCategory = [UNNotificationCategory
categoryWithIdentifier:#"GENERAL"
actions:#[snoozeAction]
intentIdentifiers:#[#"ACTIONABLE"]
options:UNNotificationCategoryOptionCustomDismissAction];
UNAuthorizationOptions options = (UNAuthorizationOptionBadge | UNAuthorizationOptionSound |UNAuthorizationOptionAlert);
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center setNotificationCategories:[NSSet setWithObjects:generalCategory, nil]];
center.delegate = self;
[center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if( !error ){
[Localytics didRequestUserNotificationAuthorizationWithOptions:options
granted:granted];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
[[NSNotificationCenter defaultCenter] postNotificationName:PUSH_DELEGATE_AFTER_REGISTERED object: nil];
}];
}
I'm getting a push that has my title and body text of "hello" but there is no button or action on the push notification.
I'm been through this guide https://nrj.io/simple-interactive-notifications-in-ios-8/
as well as apples documentation
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW1 for the payload
and https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/SupportingNotificationsinYourApp.html for adding actions to the notification.
Finally found it. In my payload I was sending category as string "actionable". It should be "GENERAL"
Related
I need to display a notification when my app is in background or killed. I have no problem to display FCM 'notification' message on iOS using firebase-cpp-sdk, I tried quickstart-cpp/messaging/testapp and it just worked. But when 'data' message is received when app is in background or foreground - no notification is displayed, I just see it in the log that message is received.
I use "content_available": true in message as suggested by many answers. This helps to actually receive the 'data' message, as I can see in the log, but the message is not displayed.
I tried legacy HTTP and HTTP v1 protocols, the result is the same.
An example of legacy HTTP message is:
{
"data": {
"body": "Entrance door Intrusion at 2 Jun 2020 01:32:08",
"title": "Intrusion"
},
"content_available": true,
"to": "fcm_device_token_here"
}
Do I need to manually create a notification like on Android? Or there are some other ways to do it?
To asnwer my own question - yes, I created a local notification. For that I used qt-notification library since I am using QT, but the code example to show notification is the following (taken from the project):
// create content
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = title.toNSString(); // your title
content.body = caption.toNSString(); // your notification text
content.sound = !sound.isEmpty() ? [UNNotificationSound soundNamed: sound.toNSString()] : [UNNotificationSound defaultSound]; // your sound
// content.sound = [UNNotificationSound criticalSoundNamed: sound.toNSString() withAudioVolume: 1.0]; // For that you need Apple's permission
content.badge = #([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
// create trigger time
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
// unique identifier
NSString* identifierNSString = identifier.toNSString();
// create notification request
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifierNSString
content:content trigger:trigger];
// add request
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = id(m_Delegate);
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(#"Local Notification failed");
}
}];
Did any one ever occur this issue? Should it only be a UI display issue? I mean the Setting.app UI did not refresh it self.
Our "register notification center" codes are as following:
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
if (![FBYPreferences instance].hasRequestAuthorizationForNotification) {
[Taplytics logEvent:#"Accept Notification number" value:#(1) metaData:nil];
}
}else {
[TrackerHelper doTrackEvent:#"Notifiction Not Granted" withCategory:#"Notifiction" withLabel:#""];
if (![FBYPreferences instance].hasRequestAuthorizationForNotification) {
[Taplytics logEvent:#"Decline Notification number" value:#(1) metaData:nil];
}
}
[FBYPreferences instance].hasRequestAuthorizationForNotification = YES;
}];
I look at these codes and think it is OK. Our PM said they can not receive the push notification after they saw the switch is off in Setting.app.
Do you have any suggestion for it. Your idea may solve it and I will really appreciate for it.
Update: we call the above code twice when app launching. Is it possible the reason? We remove the duplicated method call and only call above once.
I’m trying to set a sound for push notification in the project which I am developing but it's not working in the device please tell me, how I can set the alert sound for the notification.
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if( !error )
{
[[UIApplication sharedApplication] registerForRemoteNotifications];
NSLog( #"Push registration success." );
}
else
{
NSLog( #"Push registration FAILED" );
NSLog( #"ERROR: %# - %#", error.localizedFailureReason, error.localizedDescription );
NSLog( #"SUGGESTIONS: %# - %#", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
I am using the above code in "Appdelegate.m" in "didFinishLaunch" method can anyone please tell me where I'm going wrong.
For remote notifications in iOS, you can specify a custom sound that iOS plays when it presents a local or remote notification for an app. The sound files can be in the main bundle of the client app or in the Library/Sounds folder of the app’s data container.
When you send push notification, just add the name of file in JSON payload. Example:
{
"aps" : {
"alert" : "Hey you got a push notification.",
"badge" : 1,
"sound" : "sound.mp3"
}
}
Just put the file (sound.mp3) inside your project bundle (i.e inside the hierarchy of project) and have Copy items if needed option selected while drag and drop.
Hope this will help.
If the user has alert style set to Banners. They can receive more than 1 notification without them being prompted to clear it.
I saw same apps, If the click on the latest one & it opens the App, only clear just this one notification, and remove badge;
If I use
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
It will clear all notifications that have received.
So how to remove badge but not remove all notifications?
Here is another sample should working for iOS 11(code in Swift 4.1):
if #available(iOS 11.0, *) {
let content = UNMutableNotificationContent()
content.badge = -1
let request = UNNotificationRequest(identifier: "clearBadge", content: content, trigger: nil)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else {
UIApplication.shared.applicationIconBadgeNumber = -1
}
OK, I find the answer in this
add new notification which badge is -1.
- (void)applicationDidEnterBackground:(UIApplication *)application {
if (iOS11) {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.badge = #(-1);
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:#"clearBadge" content:content trigger:nil];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
} else {
UILocalNotification *clearEpisodeNotification = [[UILocalNotification alloc] init];
clearEpisodeNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
clearEpisodeNotification.timeZone = [NSTimeZone defaultTimeZone];
clearEpisodeNotification.applicationIconBadgeNumber = -1;
[[UIApplication sharedApplication] scheduleLocalNotification:clearEpisodeNotification];
}
}
Then the badge will be removed,but other notifications not.
Can u help me how to cancel local notification in iOS 10
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removeAllPendingNotificationRequests];
[center removePendingNotificationRequestsWithIdentifiers:#[ CYLInviteCategoryIdentifier ]];
removePendingNotificationRequestsWithIdentifiers i cant understand
While creating a Local notification, you can pass an identifier to each notification. Use the same identifier to remove the local notification.
Code to create local notification:-
NSString *identifier = #"Unique Identifier";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger]
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(#"Something went wrong: %#",error);
}
}];
Code to Cancel Notification:-
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
NSArray *array = [NSArray arrayWithObjects:#"Identifier1",#"Identifier2", nil];
[center removePendingNotificationRequestsWithIdentifiers:array];
Try this
[[UNUserNotificationCenter currentNotificationCenter]getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
NSLog(#"count%lu",(unsigned long)requests.count);
if (requests.count>0) {
UNNotificationRequest *pendingRequest = [requests objectAtIndex:0];
if ([pendingRequest.identifier isEqualToString:#"identifier"]) {
[[UNUserNotificationCenter currentNotificationCenter]removePendingNotificationRequestsWithIdentifiers:#[pendingRequest.identifier]];
}
}
}];
I don't use any of the above solutions. I don't cancel any single notifications. Rather, whenever the user runs the app I cancel ALL the local notifications and run the code that recreates them all with the new parameters, which will cancel any local notifications that need cancelling. Less code surface, less to test, creating notifications is generally an inexpensive operation. Many, many apps use this solution, consider whether you could use this yourself.
You can use below code to remove single local notification.
UIApplication *app = [UIApplication sharedApplication];
NSArray *allLocalNoti = [app scheduledLocalNotifications];
for (int i=0; i<[allLocalNoti count]; i++)
{
UILocalNotification* currentLocalNotification = [allLocalNoti objectAtIndex:i];
NSDictionary *userInfoCurrent = currentLocalNotification.userInfo;
NSString *uid=[NSString stringWithFormat:#"%#",[userInfoCurrent valueForKey:#"uid"]];
if ([uid isEqualToString:uidtodelete])
{
[app cancelLocalNotification:currentLocalNotification];
break;
}
}
Happy Coding...