WatchKit handleActionWithIdentifier : forRemoteNotification is not called - push-notification

I have a Simple Static Interface for the apple watch notification as follow:
and in the PushNotificationPayload are as follow:
{
"aps": {
"alert": {
"body": "123You have a new message",
"title": "myApp"
},
"category": "respond"
},
"WatchKit Simulator Actions": [
{
"title": "View Message",
"identifier": "viewMsgBtn"
}
],
"customKey": "customKey"
}
and implement the method in InterfaceController
- (void)handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)remoteNotification
{
NSLog(#"Handling remote notification: %# with identifier: %#", remoteNotification, identifier);
// [self.lbTest setText:[NSString stringWithFormat:#"Notification: %#",remoteNotification.description]];
}
and I run the simulator with notification:
the awakeWithContext method in InterfaceController is called, and after clicking the View Message button and it loads to my apple watch app interface.
the willActivate method in InterfaceController is called.
but the handleActionWithIdentifier forRemoteNotification is not called...
any idea?

I was experiencing something similar (in Swift) but then realized I had implemented
handleActionWithIdentifier(identifier: String?, forRemoteNotification remoteNotification: [NSObject : AnyObject], withResponseInfo responseInfo: [NSObject : AnyObject])
instead of
handleActionWithIdentifier(identifier: String?, forRemoteNotification remoteNotification: [NSObject : AnyObject])
The former is for cases where the user provides a text response, which is not applicable here.

You need to implement not only A short-look interface(Static Interface) also The Long-Look Interface (Dynamic Interface). This guide is perfect : https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/WatchKitProgrammingGuide/BasicSupport.html#//apple_ref/doc/uid/TP40014969-CH18-SW1
Basically in your NotificationController.m you have this method:
- (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler {
// This method is called when a remote notification needs to be presented.
// Implement it if you use a dynamic notification interface.
// Populate your dynamic notification interface as quickly as possible.
//
// After populating your dynamic notification interface call the completion block.
completionHandler(WKUserNotificationInterfaceTypeCustom);
}
When you see the type is WKUserNotificationInterfaceTypeCustom. if you do this populate quickly (< 10 seconds) apple watch show Long-Look Interface (Dynamic interface) that permit implement actions. Otherwise short-look (static interface).
regards.

Related

SwiftUI ask Push Notifications Permissions again

So I have push notifications implemented in my App and when the app first starts up, its asks users if they would like to allow push notifications (this implementation works fine as expected).
If this user disallows the push notifications, is it possible to have a button in the app which allows the user to click on and it would ask to allow permissions again?
This is what im trying to achieve:
SettingsView
//IF PUSH NOTIFICATIONS NOT ENABLED, SHOW THIS SECTION
Section (header: Text("Push Notifications")) {
HStack {
Image(systemName: "folder")
.resizable()
.frame(width: 20, height: 20)
VStack(alignment: .leading) {
Text("Enable Push Notifications").font(.callout).fontWeight(.medium)
}
Spacer()
Button(action: {
checkPushNotifications()
}) {
Text("View").font(.system(size:12))
}
}
}
In my Push Notification Function:
class PushNotificationService: NSObject, MessagingDelegate {
static let shared = PushNotificationService()
private let SERVER_KEY = "myserverkey"
private let NOTIFICATION_URL = URL(string: "https://fcm.googleapis.com/fcm/send")!
private let PROJECT_ID = "my project name"
private override init() {
super.init()
Messaging.messaging().delegate = self
}
func askForPermission() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted: Bool, error: Error?) in
if granted {
self.refreshFCMToken()
} else {
// Maybe tell the user to go to settings later and re-enable push notifications
}
}
}
func refreshFCMToken() {
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print("Error fetching remote instance ID: \(error)")
} else if let result = result {
print("Remote instance ID token: \(result.token)")
self.updateFCMToken(result.token)
}
}
}
func updateFCMToken(_ token: String) {
guard let currentUser = Auth.auth().currentUser else { return }
let firestoreUserDocumentReference = Firestore.firestore().collection("users").document(currentUser.uid)
firestoreUserDocumentReference.updateData([
"fcmToken" : token
])
}
}
What im trying to achieve is if the user HAS NOT enabled notification only then ask them the option to reenable in SettingsView.
No you cannot. However, a good UI/UX design will be careful before burning the one-time chance of asking for permissions. Instead, use a user friendly UI to explain why you need certain permissions. For example, I often found it frustrating to implement a permission display view, and handle various async permission requests in a seperate view model. So I recently made a SwiftUI package:
PermissionsSwiftUI
                  
PermissionSwiftUI is a package to beautifully display and handle permissions.
EmptyView()
.JMPermissions(showModal: $showModal, for: [.locationAlways, .photo, .microphone])
For a SINGLE line of code, you get a beautiful UI and the permission dialogs.
It already supports 7 OUT OF 12 iOS system permissions. More features coming 🙌
Full example
struct ContentView: View {
#State var showModal = false
var body: some View {
Button(action: {showModal=true},
label: {Text("Ask user for permissions")})
.JMPermissions(showModal: $showModal, for: [.locationAlways, .photo, .microphone])
}
}
To use PermissionsSwiftUI, simply add the JMPermission modifier to any view.
Pass in a Binding to show the modal view, and add whatever permissions you want to show.
The short answer is no, you can't ask the user again if he once disabled the push-notifications for your app.
What you can do, is navigating the user to the settings in their phone to allow push-notifications again.
The code snippet in SwiftUI for the button would be:
Button(action: {
guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}, label: {
Text("Allow Push")
})
I would also refer to this question: How to ask notifications permissions if denied?

Phonegap manage notification when the app is foreground

i am building mobile application using cordova and phonegap.
I want to display a popup on device screen when the notification reaches.Is there any plugin in cordova for this.
From https://programmingistheway.wordpress.com/2017/07/19/devextremephonegap-how-to-manage-push-notifications-with-fcm/
The 3 events registration, notification and error are managed only if the app is opened.
Registration: the APP registers itself to the push service, receiving
a unique registrationId. This event is useful if you want to store
this value to send notifications to single devices;
Notification: instead of show the classic notification pop up (depending on the
phone), the event notication shows a little pop up (using DevExtreme
feature) to read the message, if the APP is open (if the app is
closed, you will get the notification in the classic way);
Error: if the APP is open and the notification throws some error, here you can manage it.
So, the event you have to mangage is notification. This event is raised when a notification is delivered with the app in foreground (so, when the app is running).
Insert this code in the deviceReady event:
var push = PushNotification.init({
android: {
},
ios: {
alert: "true",
badge: "true",
sound: "true",
clearBadge: "true"
},
windows: {}
});
push.on('registration', function (data) {
// data.registrationId
DevExpress.ui.notify("Device registered " + data.registrationId, "success", 3000);
});
push.on('notification', function (data) {
// data.message,
// data.title,
// data.count,
// data.sound,
// data.image,
// data.additionalData
// mostra la notifica se l'app è aperta
DevExpress.ui.notify(data.message, "info", 10000);
});
push.on('error', function (e) {
// e.message
// sarà da togliere, utilissimo in fase di debug
DevExpress.ui.notify(e.message, "error", 10000);
});
and insert the code you need in the notification event. In this case, DevExtreme is used, but if you don't use it you can just show an alert or look for what you need (example)enter link description here.

cordova-plugin-fcm - FCMPlugin is not defined

I am using Ionic 2, and am trying to get Push Notifications working.
I have registered my app with Firebase, and can push notifications to it successfully.
I now need to set up, so that I can push notifications from my app. So I decided to use the following Cordova Plugin (cordova-plugin-fcm).
Question 1
When I follow it's instructions, by doing the following in my Ionic app:
app.ts
declare var FCMPlugin;
...
initializeApp() {
this.platform.ready().then(() => {
...
FCMPlugin.getToken(
function (token) {
....
I get the following Error at runtime:
EXCEPTION: Error: Uncaught (in promise): ReferenceError: FCMPlugin is
not defined
How do I solve this please?
Question 2
In order to send notifications from your app, the Cordova Plugin (cordova-plugin-fcm) instructs the following:
//POST: https://fcm.googleapis.com/fcm/send
//HEADER: Content-Type: application/json
//HEADER: Authorization: key=AIzaSy*******************
{
"notification":{
"title":"Notification title", //Any value
"body":"Notification body", //Any value
"sound":"default", //If you want notification sound
"click_action":"FCM_PLUGIN_ACTIVITY", //Must be present for Android
"icon":"fcm_push_icon" //White icon Android resource
},
"data":{
"param1":"value1", //Any data to be retrieved in the notification callback
"param2":"value2"
},
"to":"/topics/topicExample", //Topic or single device
"priority":"high", //If not set, notification won't be delivered on completely closed iOS app
"restricted_package_name":"" //Optional. Set for application filtering
}
This is not even Typescript or Javascript. So where does it go? I just don't understand. Any advise appreciated.
You should have FCMPlugin.js included in your HTML index file
find the path for js file into plugins directory of the app
Example : MyFCM\plugins\cordova-plugin-fcm\www\FCMPlugin.js
app.controller('AppCtrl', function(FCMPlugin,$scope,$cordovaToast,$cordovaDialogs,ionPlatform) {
// call to register automatically upon device ready
ionPlatform.ready.then(function (device) {
console.log('I am working');
FCMPlugin.onNotification(
function(data){
if(data.wasTapped){
//Notification was received on device tray and tapped by the user.
$cordovaDialogs.alert(data.notification.body);
}else{
//Notification was received in foreground. Maybe the user needs to be notified.
$cordovaDialogs.alert(data.notification.body);
//$cordovaToast.showShortCenter( JSON.stringify(data) );
}
},
function(msg){
$cordovaToast.showShortCenter('onNotification callback successfully registered: ' + msg);
},
function(err){
$cordovaToast.showShortCenter('Error registering onNotification callback: ' + err);
}
);
});
})

Send template push notification message using azure notification hub

Hi i want to send Template notification using azure notification hub. I want to send json object (key value pair) in notification and from app site they will process it and will display. I tried using bellow code but i am not getting notification !
var notificationMessage = new Dictionary<string, string> { { "PushType", "0" }, { "Id","6" }, { "Type", "0"}, { "SubType", "0" }, { "Title", "test" } };
await instance.SendTemplateNotificationAsync(notificationMessage, user.UserID.ToString());
It's hard to tell exactly what is happening without knowing details about code and configuration.
But I would recommend going through the following to troubleshoot:
Azure Notification Hubs - Diagnosis guidelines
Using Azure Notification Hubs Templates
Let me know if you cannot find a solution using links above.

Increment app badge on recieving ACS push while app on background: Titanium

My application uses ACS Push Notification. I have implemented app badge in my application. But the problem is the appBadge doesn't incrementing automatically while receiving a push notification. I have used the following code in my app
var deviceToken;
Titanium.Network.registerForPushNotifications({
types: [
Titanium.Network.NOTIFICATION_TYPE_BADGE,
Titanium.Network.NOTIFICATION_TYPE_ALERT,
Titanium.Network.NOTIFICATION_TYPE_SOUND
],
success:function(e)
{
deviceToken = e.deviceToken;
SubscribeToPush(channelName, deviceToken, type);
},
error:function(e)
{
alert("Error: "+ ((e.error && e.message) || JSON.stringify(e.error)));
},
callback:function(e)
{
var badgeCount = Ti.UI.iPhone.getAppBadge();
badgeCount = badgeCount + 1;
Ti.UI.iPhone.setAppBadge(badgeCount);
}
});
I read here that "callback function" invoked upon receiving a new push notification. So I set the following code as callback to increment the badge.
callback:function(e)
{
var badgeCount = Ti.UI.iPhone.getAppBadge(); //Will return the app badges
badgeCount = badgeCount + 1; //Incrementing the appbadge
Ti.UI.iPhone.setAppBadge(badgeCount); //Setting new appbadge
}
It works while the app is open and when it receives a notification, callback get fired and when the app go to background, the badge get appeared. But I want to increment the badge number when the app is in background or exited. Can anyone help me to resolve this issue?
After lots of research I have created a sample application to increment the appBadge while receiving a server push notification. You can download the code from Increment the ios appBadge Titanium. Please follow the steps after downloading the resources folder.
Create a new mobile application project in Titanium.
Replace the resources folder with the one you downloaded.
Login to www.appcelerator.com, go to your app then go to Manage ACS
Create a new user as admin, set user as admin
Create a new Access Control List(ACS) using the admin user and give the ACL Name as 'SampleApp'
Upload the p12 certificate for push notification
Now Install the application to your iPhone and run the app...
Each user of the app should have a custom object which stores the number of notifications. I'm updating them while sending a push and clears it while I resume/open the application. I tested it with my iPhone devices and it works perfect. However it takes some delays since I have to call ACS multiple times.
UPDATE : Latest Titanium SDKs Support this feature by default.
What you need to do is to change the payload as follows:
var payload = {"alert":"Hi, This is a test notification", badge: "+1"};
/*+1 will increment the current appbadge by 1, number of appbadge will be saved in the ACS*/
Cloud.PushNotifications.notify({
channel: 'friend_request',
payload: payload
}, function (e) {
if (e.success) {
alert('Success');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
And this will increase the appbadge by one. And you need to reset the appbadge when you resume/open of your application as follows
Cloud.PushNotifications.resetBadge({
device_token : myDeviceToken
}, function(e){
if(e.success){
Ti.UI.iPhone.setAppBadge(0);
} else {
//Error callback
}
})

Resources