Rohan Vasishth
Rohan Vasishth

Reputation: 417

Calendar Based Local Notification Not Working - Swift 3

I have setup a local notification system so that I can fire a notification at a certain time every day. This time is determined by the user and I store it as a string. I will break down all the steps I have done in the code to follow but basically, my problem is that the notification won't fire.

Step 1: In this step I setup an alert to ask permission to send a notification:

let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
center.requestAuthorization(options: options) { (granted, error) in
    if granted {
        application.registerForRemoteNotifications()
    }
}

Step 2: In this step I setup the function I call to send a notification:

static func sendNotification(stringDate: String) {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "HH:mm"

        let content = UNMutableNotificationContent()
        content.title = "Title"
        content.body = "Detail"
        content.badge = 1

        if let date = dateFormatter.date(from: stringDate) {
            let calendar = Calendar.current

            let hour = calendar.component(.hour, from: date)
            let minute = calendar.component(.minute, from: date)

            var dateComponents = DateComponents()
            dateComponents.hour = hour
            dateComponents.minute = minute

            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
            let request = UNNotificationRequest(identifier: "dateDone", content: content, trigger: trigger)

            UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
        }
    }

Step 3: I then call this function in my app delegate file like so:

func applicationDidEnterBackground(_ application: UIApplication) {
    let defaults = UserDefaults.standard
    if defaults.object(forKey: "currentUser") != nil {
        if User.current.desiredTimeForNews.characters.contains("A") {
            let stringToBeConverted = User.current.desiredTimeForNews.replacingOccurrences(of: "AM", with: "")
            HelperFunctions.sendNotification(stringDate: stringToBeConverted)

        } else {
            let stringToBeConverted = User.current.desiredTimeForNews.replacingOccurrences(of: "PM", with: "")
            HelperFunctions.sendNotification(stringDate: stringToBeConverted)
        }
    }
}

IMPORTANT: As you can see within my function I take in a "stringDate" parameter. This variable has a string value of my date. I then convert this to a date value. Through using breakpoints and print statements I have seen that all my values including the date, hour, minute, etc are all NOT nil.

Overall, my problem is that the notification is never sent. However I know for a fact that it is called as I have used breakpoints to prove that. Any help would be appreciated!

Upvotes: 0

Views: 790

Answers (2)

t1ser
t1ser

Reputation: 1624

The code seems to be ok. Should work on the device and also on the simulator. My guess is that the trigger time just happens at a different time, then what you would expect. Insert this check below after your setup to see the details:

UNUserNotificationCenter.current()
.getPendingNotificationRequests(completionHandler: { requests in
  for (index, request) in requests.enumerated() {
  print("notification: \(index) \(request.identifier) \(request.trigger)")
  }
  })

note 1:Why do you have this line in the code?

application.registerForRemoteNotifications()

note 2:You should check if the requestAuthorization went through ok. With something like this:

UNUserNotificationCenter.current().getNotificationSettings { (settings) in

    guard (settings.authorizationStatus == .authorized ) 
        else { print("notifsetup not authorized");return }

    guard (settings.soundSetting == .enabled) else { 
        print("notifsetup sound not enabled");return } 
}

Upvotes: 1

Rohan Vasishth
Rohan Vasishth

Reputation: 417

For me personally, I ran it on a real device and it worked. Although it should work on a simulator it didn't for me. So I would try and run it on a real device before looking at anything else!

Upvotes: 1

Related Questions