How to manage Local Notification in swift - ios

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)

Related

Not able to play the music when recived LocalNotification, when app is in background state in swift

I'm scheduling up a Local Notification as an alarm for an app, where I'm setting music and vibration when local notification is received. When app is in foreground state everything is working fine, music is playing, vibration is there.
But when app is in background state only the default notification music i.e once only not in repeat and single vibration is occurring.
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
//show an alert window
var isSnooze: Bool = false
var soundName: String = ""
var index: Int = -1
if let userInfo = notification.userInfo {
isSnooze = userInfo["snooze"] as! Bool
soundName = userInfo["soundName"] as! String
index = userInfo["index"] as! Int
}
playSound(soundName)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainVC = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController
mainVC?.notification = notification
mainVC?.isFromNotificationDelegate = true
let nav = UINavigationController(rootViewController: mainVC!)
self.window?.rootViewController = nav
}
Register for notifications in AppDellegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Sound | .Alert | .Badge, categories: nil))
return true
}
Now, schedule your notification using following func, it will automatically play your custom sound whenever notification receieves
func localnotification (firedate:NSDate) {
var localNotification:UILocalNotification = UILocalNotification()
localNotification.fireDate = firedate
localNotification.alertBody = "time to woke up"
localNotification.soundName = "alarm.wav"
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}

how to get FCM message in a UIViewController in Swift3?

I am using swift3. I want to show FCM message to tableview in a UIViewController when My app receive FCM message data.I have got my fcm data using bellow code in appDelegate..But I don't know how to get data in UIViewController.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (_ options: UNNotificationPresentationOptions) -> Void) {
let message : UNNotificationPresentationOptions = .alert
//GlobalVariables.notification_message = getAlert(notification: .alert)
if UIApplication.shared.applicationState == .active { // In iOS 10 if app is in foreground do nothing.
print("active****")
print("\(notification.request.content.userInfo)")
completionHandler([message, .sound])
} else {
print("Not active****")
completionHandler([message, .badge, .sound])
}
}
Please help me
Thanks advance
Set a variable on your AppDelegate, then use it from either:
AppDelegate's didFinishLaunchingWithOptions on window?.rootViewController
Your view controller by calling (UIApplication.shared.delegate as? AppDelegate)?.yourVariable
I recommend setting variable in AppDelegate to nil after using it, to prevent using same notification data twice.
In app delegate change your code like this
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.sandbox)
// FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.prod)
}
func applicationWillTerminate(_ application: UIApplication) {
UserDefaults.standard.removeObject(forKey: "check")
UserDefaults.standard.removeObject(forKey: "userid")
UserDefaults.standard.removeObject(forKey: "patient_no")
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
let state: UIApplicationState = UIApplication.shared.applicationState
if state == .active{
UIApplication.shared.applicationIconBadgeNumber = 0
if let notification = userInfo["aps"] as? [AnyHashable: Any],
let alert = notification["alert"] as? String {
print(alert)
message = alert
let localNotification = UILocalNotification()
localNotification.alertBody = alert
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.shared.scheduleLocalNotification(localNotification)
print("Active----")
}
}else if state == .inactive{
if let notification = userInfo["aps"] as? [AnyHashable: Any],let alert = notification["alert"] as? String {
print(alert)
message = alert
let localNotification = UILocalNotification()
localNotification.alertBody = alert
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.shared.scheduleLocalNotification(localNotification)
print("Inactive----")
}
}else if state == .background{
if let notification = userInfo["aps"] as? [AnyHashable: Any],let alert = notification["alert"] as? String,let sound = notification["sound"] as? String{
print(alert)
message = alert
var localNotification = UILocalNotification()
localNotification.alertBody = alert
localNotification.soundName = sound
UIApplication.shared.applicationIconBadgeNumber = number!+1
print(number!+1)
UIApplication.shared.scheduleLocalNotification(localNotification)
print("Background----")
}
}
}
then add this where you want the message back
let delegate = UIApplication.shared.delegate as! AppDelegate
let message = delegate.message
This is a sample only you want to add some condition

Remote notification when app is terminated

I am new to iOS and Swift. I am implementing remote notification in my app. Everything works fine when the app is active or in the background. But my notification does not show up when the app is terminated. All I am getting is the alert sound of the notification.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
if #available(iOS 10.0, *){
}else{
let notification = UILocalNotification()
notification.alertTitle = "my Title"
notification.alertBody = "My Message"
notification.category = "customCategory"
notification.soundName = UILocalNotificationDefaultSoundName
application.scheduleLocalNotification(notification)
}
}
Below AppDelegate method will be called When you receive a notification and application is in killed state
didFinishLaunchingWithOptions
So you should handle it properly from here when app is in killed state.
Below code helps to identify the Remote/push or Local notification in didFinishLaunchingWithOptions method:
if let launchOpts = launchOptions as [UIApplicationLaunchOptionsKey: Any]? {
if let notificationPayload = launchOpts[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary {
//Handle push notification here
}
else if let notification = (launchOpts as NSDictionary).object(forKey: "UIApplicationLaunchOptionsLocalNotificationKey") as? UILocalNotification {
//Handle local notification here
}

Why not able to handle APNS Push notification and Local notification?

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()
}
}
}

Swift - How creating first time app launch local notification?

I have added these in didFinishLaunchingWithOptions
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
self.createLocalNotification()
And then, calling below function.
func createLocalNotification() {
let localNotification = UILocalNotification()
localNotification.fireDate = NSDate(timeIntervalSinceNow: 3)
// localNotification.applicationIconBadgeNumber = 1
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.userInfo = [
"id": "not_id0",
"message": "Check notification"
]
localNotification.alertBody = "Check notification"
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
To cancel this notification, I have tried below in didReceiveLocalNotification But still display notification every App launching.
let app:UIApplication = UIApplication.sharedApplication()
for oneEvent in app.scheduledLocalNotifications! {
let notification = oneEvent as UILocalNotification
let userInfoCurrent = notification.userInfo! as! [String:AnyObject]
let id = userInfoCurrent["id"]! as! String
if id == "not_id0" {
//Cancelling local notification
app.cancelLocalNotification(notification)
break;
}
}
How Can I create first time local notification? If someone explain It would be great.
You could use NSUserDefaults as such:
In didFinishLaunchingWithOptions: in your AppDelegate:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
if let haveShownFirstRunNotification = NSUserDefaults.standardUserDefaults().boolForKey("haveShownFirstRunNotification") {
if !haveShownFirstRunNotification {
createLocalNotification()
}
}
...
}
And in createLocalNotification:
func createLocalNotification() {
...
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "haveShownFirstRunNotification")
}
Add flag in in userDefaults and then check if
NSUserDefaults.standardUserDefaults().boolForKey("notified")
if not, open notification method and there place
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "notified")

Resources