In ios 10 there is UNUserNotificationCenter class and method getNotificationSettingsWithCompletionHandler which gives you UNNotificationSettings object and you can check is user has been ever asked for push notifications permissions.Is there a way to achieve this for iOS 9 and iOS 8.
You can use something like this:
let notificationType = UIApplication.sharedApplication().currentUserNotificationSettings()!.types
if notificationType == UIUserNotificationType.None {
// Push notifications are disabled in setting by user.
} else {
// Push notifications are enabled in setting by user.
}
if notificationType != UIUserNotificationType.None {
// Push notifications are enabled in setting by user.
}
if notificationType == UIUserNotificationType.Badge {
// the application may badge its icon upon a notification being received
}
if notificationType == UIUserNotificationType.Sound {
// the application may play a sound upon a notification being received
}
if notificationType == UIUserNotificationType.Alert {
// the application may display an alert upon a notification being received
}
There is no way. That functionality is available starting from ios 10.
Related
I want to ask the user to allow notifications only when we prompt the "AskNotification" view and when he click on "Yes".
In order to do that, I did the following :
public static AppDelegate Self { get; private set; }
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
HtmlLabelRenderer.Initialize();
global::Xamarin.Forms.Forms.Init();
// Notifications
Firebase.Core.App.Configure();
//AllowNotifications();
...
LoadApplication(new App());
AppDelegate.Self = this;
return base.FinishedLaunching(app, options);
}
public void AllowNotifications()
{
//In iOS you must request permission to show local / remote notifications first since it is a user interrupting action.
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// Request Permissions
UNUserNotificationCenter.Current.RequestAuthorization(
UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound,
(granted, error) =>
{
// Do something if needed
});
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = this;
// For iOS 10 data message (sent via FCM)
Messaging.SharedInstance.Delegate = this;
}
else
{
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert
| UIUserNotificationType.Badge
| UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings
.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
Messaging.SharedInstance.ShouldEstablishDirectChannel = true;
Console.WriteLine("-------- RegisterForRemoteNotifications");
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
And then on my Code Behind when the user click on the "Allow" button (from my view) I do the following :
AppDelegate appDelegate = AppDelegate.Self;
appDelegate.AllowNotifications();
As you can see, I'm using the Singleton pattern to have an access to the AppDelegate. My problem is when the "AllowNotifications" is called inside the AppDelegate (it's commented on the code above), the system prompt ask for the user and notifications are received.
But when I call the AllowNotification method from another page with the Singleton pattern. The system popup is showing, we the user click "Yes" it allow notification on iOS parameters. But I never get into my "DidReceiveMessage" method.
Thanks for your help
This issue has nothing to do with your code.It is an expected behavior.Because you used firebase (Xamarin.Firebase.iOS.CloudMessaging from NuGet).
For devices running iOS 10 and above, you must assign your delegate object to the UNUserNotificationCenter object to receive display notifications, and the FIRMessaging object to receive data messages, before your app finishes launching. For example, in an iOS app, you must assign it in the method FinishedLaunching.
That is to say,when you register for notifications out the method FinishedLaunching,even if system popup showed,the register will still not working.
For more detail you can refer here.
maybe someone can help me.
In my app I'm using push notifications to inform the users that a new message is written to the database. One user can accept the notification and work with the content or dismiss it. If the user accepts it, a silent push is sent to all other devices which received the notification earlier. Here is my code handling this silent notification:
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary remoteNotification)
{
try
{
if (remoteNotification != null)
{
var alert = remoteNotification[FromObject("aps")];
if (alert != null)
{
string id = ((NSDictionary)alert)[FromObject("deleteId")].Description;
if (!String.IsNullOrEmpty(id))
{
List<string> idents = new List<string>();
UNUserNotificationCenter.Current.GetDeliveredNotifications(completionHandler: (UNNotification[] t) =>
{
foreach (UNNotification item in t)
{
UNNotificationRequest curRequest = item.Request;
var notificationId = ((NSDictionary)curRequest.Content.UserInfo[FromObject("aps")])[FromObject("notificationId")].Description;
if (id == notificationId)
{
idents.Add(curRequest.Identifier);
}
}
UNUserNotificationCenter.Current.RemoveDeliveredNotifications(idents.ToArray());
});
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
The problem is that the notification is still visible in the notification center until the app is brought to foreground. But then it gets deleted.
Is there a way to force the method to delete the notification instantly and not only when the app is (re)opened?
When you want to clear the Notifications send from this app. Set its application's badge to 0 to achieve this.
As you said you send a silent notifications to other users, Then DidReceiveRemoteNotification() will fire. In this event we can clear all notifications:
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
var aps = userInfo["aps"] as NSDictionary;
if (aps["content-available"].ToString() == "1")
{
//check if this is a silent notification.
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
}
completionHandler(UIBackgroundFetchResult.NewData);
}
Please notice that starting with iOS 8.0, your application needs to register for user notifications to be able to set the application icon badge number. So please add the code below in FinishedLaunching():
UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Badge, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
Moreover silent notifications can only be received when your app is on background or foreground. If it's terminated, this will fail.
To remove a notification, you send a silent push notification to all devices with the notification ID as payload that should be removed.
On the clients you implement a UNNotificationServiceExtension which allows you to remove currently displayed notifications by their IDs: UNUserNotificationCenter.current().removeDeliveredNotifications.
This gives you the advantage that you have full control over this logic on the server side.
I can't get GCM notification from background, Although can receive it on foreground such as these:
{
aps = {
alert = {
body = fffff;
title = "\U067e\U06cc\U0627\U0645";
};
badge = 9;
sound = default;
};
"gcm.message_id" = "0:1448218309944532%075c2cd9075c2cd9";
}
Any help?
To get notifications in background, as per apple documentation
"Remote notifications" option needs to be enabled in Background modes under Capabilities in the target settings.
and normally when you receive any notification at that time application:didReceiveRemoteNotification: this method called.
and if you want to call this method in background, then you should sent a silent pushnotification. and for that you have to add content-available key with value 1 into the notification payload.
you JSON response contain that key like below example
{
aps = {
"content-available" : 1,
sound : ""
};
}
I am using Parse Push Notifications with Swift (iOS 8). The problem is when app is closed and you recieve multiple notifications, they will show in notifications alert. When I touch one of the notification it will open my app......but it will clear all notifications in notification alert view (not sure what is called). So as result all of my push notifications are lost. And I need them since they have specific payload that my app needs.
So basicly, all I need is data from received notification (not just from the one I opened).
I am using this code that Parse recommends. When app is closed and is opened with push, this function is called. I use constant let = notificationPayload to get info of payloads from push notifications. But I only get data from one push.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Enable storing and querying data from Local Datastore.
// Remove this line if you don't want to use Local Datastore features or want to use cachePolicy.
Parse.enableLocalDatastore()
// ****************************************************************************
// Uncomment this line if you want to enable Crash Reporting
// ParseCrashReporting.enable()
//
// Uncomment and fill in with your Parse credentials:
Parse.setApplicationId("+++++", clientKey: "++++++++")
//
// If you are using Facebook, uncomment and add your FacebookAppID to your bundle's plist as
// described here: https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/
// Uncomment the line inside ParseStartProject-Bridging-Header and the following line here:
// PFFacebookUtils.initializeFacebook()
// ****************************************************************************
PFUser.enableAutomaticUser()
let defaultACL = PFACL();
// If you would like all objects to be private by default, remove this line.
defaultACL.setPublicReadAccess(true)
PFACL.setDefaultACL(defaultACL, withAccessForCurrentUser:true)
if application.applicationState != UIApplicationState.Background {
// Track an app open here if we launch with a push, unless
// "content_available" was used to trigger a background push (introduced in iOS 7).
// In that case, we skip tracking here to avoid double counting the app-open.
// Extract the notification data.
if let notificationPayload = launchOptions? [UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
// notificationPayload have payload of only one push notification.
}
let preBackgroundPush = !application.respondsToSelector("backgroundRefreshStatus")
let oldPushHandlerOnly = !self.respondsToSelector("application:didReceiveRemoteNotification:fetchCompletionHandler:")
var noPushPayload = false;
if let options = launchOptions {
noPushPayload = options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil;
}
if (preBackgroundPush || oldPushHandlerOnly || noPushPayload) {
PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
}
}
if application.respondsToSelector("registerUserNotificationSettings:") {
let userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound
let settings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
let types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Alert | UIRemoteNotificationType.Sound
application.registerForRemoteNotificationTypes(types)
}
return true
}
Any goot info, webpage, tutorial for this? Parse.com documentation is useless since apparently people get only one notification when app is closed.
If your push notifications contain important payload, you will probably have to save that payload somewhere else (Parse cloud data, for instance).
This way, even if iOS ditches your push notifications (or if the user decided to discard them) - your payload will be always available.
When the application starts up - look up for that payload in the database and act accordingly.
I found what was causing my Notifications to disappeare. I had this code in which would erase notifications:
UIApplication.sharedApplication().applicationIconBadgeNumber = 1
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
UIApplication.sharedApplication().cancelAllLocalNotifications()
I am allowing remote and local notifications in my app, it works perfectly fine for remote notifications but when trying to use local notifications it then does not show the notification, but it is running the code.
Remote notifications work when I am out of the app, but local notifications don't want to show when I am in the app?
Here is the code:
In the didFinishLaunchingWithOptions method:
let notificationTypes:UIUserNotificationType = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
let notificationSettings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
UIApplication.sharedApplication().registerForRemoteNotifications()
and the receiving of the notification:
if(application.applicationState == UIApplicationState.Active) {
var ln: UILocalNotification = UILocalNotification()
ln.userInfo = userInfo
ln.soundName = UILocalNotificationDefaultSoundName
ln.alertBody = notification["alert"] as NSString
ln.fireDate = NSDate()
application.scheduleLocalNotification(ln)
println("local")
} else {
PFPush.handlePush(userInfo)
}
When in the app, it is printing out local.
Any ideas?
It sounds like you don't quite get what a local notification is. The whole point of a local notification is that it is a way for the system to notify the user on your behalf when your app isn't frontmost. If your app is frontmost, there is nothing more for the system to do. Local notifications, therefore, do not fire any alert to the user when the app is frontmost. Instead, if your app is frontmost when a local notification fires, your app is notified and you can alert the user if you like.