I followed many tutorials about interactive notifications and I don't know what is missing in my code. I can receive a simple push notification and I know that I have to swipe to make the buttons appear.
I have an iPhone 4S on iOS 9.2.1 and I use Mixpanel to send a notification.
I also tried local notification but it's not working either. (simulator 8.4, 9.2, iPhone 4S) I've got the message but no buttons.
Payload : { "aps" : { "category" : "RATING_CATEGORY", "alert" : "rate the app" }}
AppDelegate:
func registerForNotifications() {
if #available(iOS 8.0, *) {
let notificationActionRate :UIMutableUserNotificationAction = UIMutableUserNotificationAction()
notificationActionRate.identifier = "RATE_IDENTIFIER"
notificationActionRate.title = NSLocalizedString("Rate.Button.Title", comment: "Rate the app")
notificationActionRate.destructive = false
notificationActionRate.authenticationRequired = false
notificationActionRate.activationMode = UIUserNotificationActivationMode.Background
let notificationActionNotNow :UIMutableUserNotificationAction = UIMutableUserNotificationAction()
notificationActionNotNow.identifier = "NOT_NOW_IDENTIFIER"
notificationActionNotNow.title = NSLocalizedString("NotNow.Button.Title", comment: "Not now")
notificationActionNotNow.destructive = true
notificationActionNotNow.authenticationRequired = false
notificationActionNotNow.activationMode = UIUserNotificationActivationMode.Background
let notificationCategoryRating: UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
notificationCategoryRating.identifier = "RATING_CATEGORY"
notificationCategoryRating.setActions([notificationActionRate, notificationActionNotNow], forContext: UIUserNotificationActionContext.Default)
notificationCategoryRating.setActions([notificationActionRate, notificationActionNotNow], forContext: UIUserNotificationActionContext.Minimal)
let categories = Set([notificationCategoryRating])
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: categories))
UIApplication.sharedApplication().registerForRemoteNotifications()
} else {
UIApplication.sharedApplication().registerForRemoteNotificationTypes([.NewsstandContentAvailability, .Badge,.Sound,.Alert])
}
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
registerForNotifications()
return true
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
if identifier == "RATE_IDENTIFIER" {
let itunesLink = NSURL(string: "http://google.com")
UIApplication.sharedApplication().openURL(itunesLink!)
}
completionHandler()
}
Related
Not sure, what's missing, but I'm stuck with a weird problem!!!
Notification sounds, but isn't displayed.
I have registered the app to only display alerts and sounds, and strangely it never is displayed. I can see that the notification is added successfully. But, there seems to be something trivial that I'm not able to comprehend.
Even removing the notification works.
import Foundation
import NotificationCenter
import UserNotifications
class NotificationManager: NSObject {
private let categoryIdentifier = "notificationCategory"
private var toDateComponents = NSDateComponents()
private enum actionIdentifier : String {
case openApp = "openApp"
case playMusic = "playMusic"
}
// MARK: - Register for notifications
func registerForNotifications(application: UIApplication) {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.currentNotificationCenter().getNotificationSettingsWithCompletionHandler { notificationSettings in
switch notificationSettings.authorizationStatus {
case .NotDetermined:
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Alert, .Sound]) { (granted, error) in
// Enable or disable features based on authorization
if granted {
print("Access requested and was granted for sending notifications")
UNUserNotificationCenter.currentNotificationCenter().setNotificationCategories([])
UNUserNotificationCenter.currentNotificationCenter().delegate = self
self.setupNotificationActions()
} else {
print("Access requested and was denied for sending notifications")
print(error?.localizedDescription)
}
}
case .Denied:
print("Notifications are turned off!!")
break // nothing to do, pointless to go on
case .Authorized:
self.setupNotificationActions()
}
}
} else {
// Nothing to do here
print("iOS 9 says, Let's get started...")
self.setupNotificationActions()
}
}
// MARK: - Setup notification actions
private func setupNotificationActions() {
// Initialize and specify the notification actions
if #available(iOS 10.0, *) {
let openAppAction = UNNotificationAction(identifier: actionIdentifier.openApp.rawValue, title: "Open App", options: [.AuthenticationRequired, .Foreground])
let playMusicAction = UNNotificationAction(identifier: actionIdentifier.playMusic.rawValue, title: "Play Music", options: [])
let notificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: [openAppAction, playMusicAction], intentIdentifiers: [], options: [.CustomDismissAction])
UNUserNotificationCenter.currentNotificationCenter().setNotificationCategories([notificationCategory])
} else {
// Specify the notification actions
let openAppAction = UIMutableUserNotificationAction()
openAppAction.identifier = actionIdentifier.openApp.rawValue
openAppAction.title = "Open App"
openAppAction.activationMode = UIUserNotificationActivationMode.Foreground
openAppAction.destructive = false
let playMusicAction = UIMutableUserNotificationAction()
playMusicAction.identifier = actionIdentifier.playMusic.rawValue
playMusicAction.title = "Play Music"
playMusicAction.activationMode = UIUserNotificationActivationMode.Background
playMusicAction.destructive = false
playMusicAction.authenticationRequired = false
// Specify the category related to the above actions
let notificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = categoryIdentifier
notificationCategory.setActions([openAppAction, playMusicAction], forContext: UIUserNotificationActionContext.Default)
notificationCategory.setActions([playMusicAction], forContext: UIUserNotificationActionContext.Minimal)
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: NSSet(object: notificationCategory) as? Set<UIUserNotificationCategory>)
// if (notificationSettings.types != UIUserNotificationType.None){
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
// }
}
}
And, in AppDelegate...
private let notificationManager = NotificationManager()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
notificationManager.registerForNotifications(application)
}
Whenever are you sending rich notification be sure about payload, must contain "mutable-content": 1,
payload like,
{
"aps": {
"alert": "Test Rich Notification",
"mutable-content": 1,
"badge": "1"
},
"mediaUrl": "https://www.awaragroup.com/wp-content/uploads/2015/05/it-specialist.jpg",
"mediaType": "jpg"
}
Delegate should be assigned correctly. Although, I wasn't able to zero in on why this happened, below changes ensured that notifications went through.
AppDelegate,
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
private let notificationManager = NotificationManager()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UNUserNotificationCenter.currentNotificationCenter().delegate = self
notificationManager.registerForNotifications()
}
}
Insert the delegate methods in AppDelegate, itself.
I am trying to test my app and I noticed that handleActionWithIdentifier: forLocalNotification does not fire. While the app is in the foreground, this delegate method should fire after the user clicks on the action. I have read other posts about this, but most of them refer to the completionHandler() at the bottom of the method. I cannot seem to find a solution. If I put my app in the background, didReceiveLocalNotification does fire correctly. I am truly stumped. Here is my code...
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationActionOk = UIMutableUserNotificationAction()
notificationActionOk.identifier = "ALARM_IDENTIFIER"
notificationActionOk.title = "Ok"
notificationActionOk.destructive = false
notificationActionOk.authenticationRequired = false
notificationActionOk.activationMode = UIUserNotificationActivationMode.Background
let notificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = "ALARM_CATEGORY"
notificationCategory.setActions([notificationActionOk], forContext: UIUserNotificationActionContext.Default)
notificationCategory.setActions([notificationActionOk], forContext: UIUserNotificationActionContext.Minimal)
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: [notificationCategory])
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
return true
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
print("Handle action \(identifier)")
completionHandler()
//I cannot get this method to fire.
}
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
print("Received local notification")
//This method fires correctly
}
}
I am working with Push notification and local notification also but in foreground notification working fine but when terminate app in this condition i can not able to redirect specific view when tap on notifications.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Check if launched from notification
// 1
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
// 2
let aps = notification["aps"] as! [String: AnyObject]
//Redirect to notification view
handlePushMessage(aps)
}else if let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? [String: AnyObject] {
// 2
self.postData = notification["aps"] as! [String: AnyObject]
//Redirect to notification view
didTapNotification()
}else{
//Session
//Redirect to Main view
checkUserSession()
}
return true
}
I am facing this facing this problem from both APNS notification and local notification when app is Inactive or terminate.Please help me fro find the solution.
How about you try in didReceiveRemoteNotification function?
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if(application.applicationState == UIApplicationStateBackground){
}else if(application.applicationState == UIApplicationStateInactive){
}
}
try this code, you can modify it according to you requirement. if you have any problem understanding this logic let me know. didReceiveRemoteNotification with completionHandler works both in background and in foreground. Don't forget to do appropriate changes in plist to support background fetch and background notification.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
notificationDataDict = notification;
}
return true
}
func handleRemoteNotificationWithUserInfo(application:UIApplication, userInfo:NSDictionary){
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print(userInfo)
if application.applicationState != .Inactive{
notificationDataDict = userInfo;
if let navigationController = self.window?.rootViewController as? UINavigationController{
if application.applicationState == .Active{
if application.backgroundRefreshStatus == .Available{
completionHandler(.NewData)
self.handleRemoteNotificationWithUserInfo(application, userInfo: userInfo)
}
else
{
completionHandler(.NoData)
}
}
else{
completionHandler(.NewData)
self.handleRemoteNotificationWithUserInfo(application, userInfo: userInfo)
}
}
}
}
Finally i got the solution for Manage APNS Push notification and Local notification, its working fine now.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
//Register here For Notification
if #available(iOS 9, *) {
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
}else{
UIApplication.sharedApplication().registerUserNotificationSettings(
UIUserNotificationSettings(forTypes: .Alert, categories: nil))
application.registerForRemoteNotifications()
}
dispatch_async(dispatch_get_main_queue()) {
// Check if launched from notification
// 1
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
// 2
let aps = notification["aps"] as! [String: AnyObject]
handlePushMessage(aps)
}else if let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
// 2
self.postData = notification.userInfo as! [String: AnyObject]
didTapNotification()
}else{
//Session
checkUserSession()
}
}
}
I am creating local notification when app receiving Push notification. these local notification generating when app in foreground and when i am creating local notification at the same time didReceiveLocalNotification method is calling and getting difficulties to manage local notification and clicking/tap on location same event calling twice.I need to avoids duplicate Local notifications also.
Please help me for solve this issue.
//MARK: - Delegate Method For APNS Notification
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Notification Message \(userInfo)")
let aps = userInfo["aps"] as! [String: AnyObject]
// 1
if userInfo["postData"] != nil {
// Refresh Promotions
print("Got it...")
// Clear Previous Value Data
postData.removeAll()
//Adding New Post Data here
if (userInfo["postData"] != nil){
self.postData = userInfo["postData"]! as! [String : AnyObject]
print(self.postData)
}
//Condition here for Notification
if appInForeground == false {
//Goto Promo List
//Set Boolean for View
notiDetails = true
//Navigation
gotoPromoListView()
}else{
let systemSoundID: SystemSoundID = 1016
// to play sound
AudioServicesPlaySystemSound (systemSoundID)
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
let notification = UILocalNotification()
notification.alertBody = (aps["alert"] as? String)!
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = userInfo["postData"]! as! [String : AnyObject]
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
How to manage this method for local notification
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
// Do something serious in a real app.
print("Received Local Notification:")
print(notification.userInfo)
self.postData = notification.userInfo as! [String : AnyObject]
didTapNotification()
}
Could you please show your code, where you register your remote notifications?
If you want to show alert and badge, when receive push notifications, you can make like this:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationTypes: UIUserNotificationType = [.Alert, .Badge, .Sound]
let notificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
UIApplication.sharedApplication().registerForRemoteNotifications()
}
After that you can add custom actions to method:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject :
}
If you need local notifications, you should set fire property, when you schedule notification:
let localNotification = UILocalNotification()
localNotification.fireDate = NSDate()
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.alertBody = text
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
I'm trying to redirect the user to a ViewController when he touches the Push Notification. This is working fine when the user has the App open in background, but it's not working when it has to open the App.
After some research, I have learned when the App opens due tu a push notification, it only reads the "didFinishLaunchingWithOptions".
So, I assume now I need to make some "if" statement to make the segue when the push notification is set, but I don't know how to detect the push notification because it's my first time using notifications in my app.
Here is my code:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId(MY_APP_ID, clientKey: MY_CLIENT_KEY)
// Registramos la Push Notification
if application.applicationState != UIApplicationState.Background {
let preBackgroundPush = !application.respondsToSelector("backgroundRefreshStatus")
let oldPushHandlerOnly = !self.respondsToSelector("application:didReceiveRemoteNotification:fetchCompletionHandler:")
var pushPayload = false
if let options = launchOptions {
pushPayload = options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil
}
if (preBackgroundPush || oldPushHandlerOnly || pushPayload) {
PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
}
}
if application.respondsToSelector("registerUserNotificationSettings:") {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
else {
//let types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Alert | UIRemoteNotificationType.Sound
//application.registerForRemoteNotificationTypes(types)
// Access the storyboard and fetch an instance of the view controller
}
// Change navigation bar appearance
UINavigationBar.appearance().barTintColor = UIColor(hex: 0x00B7BB)
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor()]
if let barFont = UIFont(name: "Avenir Next", size: 20.0) {
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor(), NSFontAttributeName:barFont]
}
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackground()
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
if error.code == 3010 {
print("Push notifications are not supported in the iOS Simulator.")
} else {
print("application:didFailToRegisterForRemoteNotificationsWithError: %#", error)
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
// Access the storyboard and fetch an instance of the view controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewControllerWithIdentifier("UltimaMarca")
// Then push that view controller onto the navigation stack
let rootViewController = self.window!.rootViewController as! UINavigationController
rootViewController.pushViewController(viewController, animated: true)
}
Do you know some tutorial, guideline or code to show me? Because I have found some lines of code in Objective-C but they are very old and I cannot use it.
Thanks,