9

iOS 10 で動作するように localnotifications を更新していますが、nextTrigger 関数が「トリガー条件が満たされる次の日付」ではないと思われる問題に遭遇しました。代わりに、現在の日時に UNTimeInvervalNotificationTrigger を最初に設定したものを加えたものを返します。

したがって、トリガーを 60 秒でオフにするように設定した場合、ドキュメントから、nextTriggerDate() を呼び出すと、トリガー + 60 秒を設定したときの日付時刻が返されることが期待されます。したがって、12:00:00 に設定すると、nextTriggerDate() は 12:01:00 になると予想されます。しかし、私が経験しているのは、現在の日付が + 60 秒であるものを返すということです。

UNTimeIntervalNotificationTrigger をスケジュールし、nextTriggerDate() を毎秒出力するサンプルを作成しました。これを実行すると、毎秒新しい nextTriggerDate が取得されます。このような:

            //Optional(2016-11-03 21:26:31 +0000)
            //Optional(2016-11-03 21:26:32 +0000)
            //Optional(2016-11-03 21:26:33 +0000)
            //Optional(2016-11-03 21:26:34 +0000)
            //Optional(2016-11-03 21:26:35 +0000)
            //Optional(2016-11-03 21:26:36 +0000)

Apple で TSI を開きましたが… ご存知のように… しばらく時間がかかります。だから、ここにいる誰かが何か洞察を持っているかどうか見てみようと思った。これはバグだと思います。さらに情報が得られたら、これを更新します。

これは、問題を説明するために使用したコードです。

import UIKit
import UserNotifications

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    @IBOutlet weak var setButton: UIButton!

    @IBOutlet weak var timePicker: UIPickerView!

    weak var timer: Timer?

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func setButtonAction(_ sender: UIButton) {
        var mySecond = pickerSelection

        // build notification
        let content = UNMutableNotificationContent()
        content.title = "Title of notification"
        content.body = "This is the body of the notification"
        content.sound = UNNotificationSound.default()
        content.categoryIdentifier = "myCategory"

        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: Double(mySecond), repeats: false)

        let request = UNNotificationRequest(identifier: "test notification", content: content, trigger: trigger)

        UNUserNotificationCenter.current().add(request) {(error) in
            if let error = error {
                print("Uh oh! We had an error: \(error)")
            }
        }

        self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.tick), userInfo: nil, repeats: true)
    }

    let pickerData = [":00",":01",":02",":03",":04",":05",":06",":07",":08",":09",":10",":11",":12",":13",":14",":15",":16",":17",":18",":19",":20",":21",":22",":23",":24",":25",":26",":27",":28",":29",":30",":31",":32",":33",":34",":35",":36",":37",":38",":39",":40",":41",":42",":43",":44",":45",":46",":47",":48",":49",":50",":51",":52",":53",":54",":55",":56",":57",":58",":59"]


    var pickerSelection = 0


    override func viewDidLoad() {
        super.viewDidLoad()
        self.timePicker.dataSource = self
        self.timePicker.delegate = self
        self.timePicker.selectRow(pickerSelection, inComponent: 0, animated: false)
    }

    // The number of columns of data
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    // The number of rows of data
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count
    }

    // The data to return for the row and component (column) that's being passed in
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerData[row]
    }

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let pickerLabel = UILabel()
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Futura", size: 44.0)!])
        pickerLabel.attributedText = myTitle
        pickerLabel.textAlignment = .center

        return pickerLabel
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        pickerSelection = row
    }

    func tick() {
        let center = UNUserNotificationCenter.current()
        center.getPendingNotificationRequests(completionHandler: { (scheduledLocalNotifications) in
            for localNotice in scheduledLocalNotifications {
                var localTrigger = localNotice.trigger as! UNTimeIntervalNotificationTrigger

                var localTime = localTrigger.nextTriggerDate()
                // ** This output shows something like this:

                //Optional(2016-11-03 21:26:31 +0000)
                //Optional(2016-11-03 21:26:32 +0000)
                //Optional(2016-11-03 21:26:33 +0000)
                //Optional(2016-11-03 21:26:34 +0000)
                //Optional(2016-11-03 21:26:35 +0000)
                //Optional(2016-11-03 21:26:36 +0000)
                print("\(localTime)")     
            }
        })
    }
}
4

1 に答える 1

9

Apple DTS から返事があり、私が説明した機能はどのように機能するように設計されているかということでした。ドキュメンテーションでは別の説明がされていると思っていましたが、「実装を考えると、ドキュメンテーションは楽観的でした」とのことでした。とにかく、コードで発火日を追跡することで回避しました。この回答が、私と同じ問題を抱えている他の誰かに役立つことを願っています。

于 2016-11-09T20:12:40.773 に答える