local notification not appearing (Swift4)

2019-08-29 04:48发布

问题:

My code below is supposed to act as an alarm clock. When the date and time matches nothing is happening but I am seeing my print in the log file. Please try this code and test what I am doing it wrong. It seemed liked it worked before. This is supposed to still go off in the background if the user is not using the app.

      import UIKit;import AVFoundation;import UserNotifications
class ViewController: UIViewController, UNUserNotificationCenterDelegate {var timer = Timer();var isGrantedAccess = false;var player: AVAudioPlayer?
    var passingDate : Date?
    @IBOutlet var dptext: UITextField!
    let datePicker = UIDatePicker()
    @IBOutlet var taskIDo: UITextView!



    override func viewWillAppear(_ animated: Bool)
    {
    createDatePicker()
        timer  = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(ViewController.testDate), userInfo: nil, repeats: true)
    }

    func playSound() {
        let url = Bundle.main.url(forResource: "fc", withExtension: "mp3")!
        do {
            player = try AVAudioPlayer(contentsOf: url)
            guard let player = player else { return }

            player.prepareToPlay();player.play()} catch let error as NSError {print(error.description)}}


func createDatePicker() {
    datePicker.datePickerMode = .dateAndTime
let toolbar = UIToolbar()
    toolbar.sizeToFit() 

    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
    toolbar.setItems([doneButton], animated: false)

    dptext.inputAccessoryView = toolbar;dptext.inputView = datePicker
  }


    func testDate() {
        if Calendar.current.isDate(datePicker.date, equalTo: Date(), toGranularity: .minute) {
            if let passingDate = passingDate, Calendar.current.isDate(datePicker.date, equalTo: passingDate, toGranularity: .minute)
            {
                                    return
            }

            passingDate = datePicker.date


          if dptext.text != ""
            {

                let c = UNMutableNotificationContent()
                c.title = "Lets Roll"


                let t = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
                let r = UNNotificationRequest(identifier: "any", content: c, trigger: t)

                UNUserNotificationCenter.current().add(r, withCompletionHandler: nil)
                /////


                let when = DispatchTime.now() + 20
                DispatchQueue.main.asyncAfter(deadline: when) {



                }

            } else {
            print("No its not empty")}}}


func donePressed() {

    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .short
    dateFormatter.timeStyle = .short
    dptext.text = dateFormatter.string(from: datePicker.date)
    self.view.endEditing(true)



    }}

回答1:

A few things:

  • Make sure you are setting the UNUserNotificationCenter.current().delegate in your ViewController.
  • If you expect this to show when the app is in the foreground this isn't correct. You need to minimize the app in order to see the internal notification.
  • Request permissions for notifications in your app delegate:

    center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
                // Enable or disable features based on authorization.
            }
    

Here's the code I used to test your configuration:

import UIKit
import AVFoundation
import UserNotifications

let center = UNUserNotificationCenter.current() // usernotification center

class ViewController: UIViewController, UNUserNotificationCenterDelegate {
    var timer = Timer()
    var isGrantedAccess = false
    var player: AVAudioPlayer?
    var passingDate : Date?
    @IBOutlet var dptext: UITextField!
    let datePicker = UIDatePicker()
    @IBOutlet var taskIDo: UITextView!

    override func viewWillAppear(_ animated: Bool) {

        center.delegate = self
        createDatePicker()
        timer  = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(testDate), userInfo: nil, repeats: true)

    }

    func playSound() {
        let url = Bundle.main.url(forResource: "fc", withExtension: "mp3")!
        do {
            player = try AVAudioPlayer(contentsOf: url)
            guard let player = player else { return }

            player.prepareToPlay();player.play()} catch let error as NSError {print(error.description)}}


    func createDatePicker() {
        datePicker.datePickerMode = .dateAndTime
        let toolbar = UIToolbar()
        toolbar.sizeToFit()

        let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
        toolbar.setItems([doneButton], animated: false)

        dptext.inputAccessoryView = toolbar;dptext.inputView = datePicker
    }

    @objc func testDate() {
        print("in testDate")
        if Calendar.current.isDate(datePicker.date, equalTo: Date(), toGranularity: .minute) {
            if let passingDate = passingDate, Calendar.current.isDate(datePicker.date, equalTo: passingDate, toGranularity: .minute)
            {
                print("in return")
                return
            }

            passingDate = datePicker.date

            let content = UNMutableNotificationContent()
            content.badge = true
            content.title = "Test"
            content.body = "Lets Roll!"
            content.sound = UNNotificationSound.default

            let t = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
            let r = UNNotificationRequest(identifier: "any", content: content, trigger: t)

            UNUserNotificationCenter.current().add(r, withCompletionHandler: { (error) in
                dump(error)
            })

        }
    }

    @objc func donePressed() {

        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .short
        dateFormatter.timeStyle = .short
        dptext.text = dateFormatter.string(from: datePicker.date)
        self.view.endEditing(true)

    }
}