我正在安排一个我想推送通知的计时器。需要注意的是,我的#selector是一个单例的函数,如下面的代码所示。但是,当发出计时器信号,并且调用#selector(NotificationManager.instance.pushNotification(timer :))时,我会得到下面概述的异常转储。当我采用相同的功能并将其放置在视图控制器中时,一切都在世界上并且没有问题。有任何想法吗?
2017-12-09 20:33:47.439754-0500 Accumoo[3404:2488862] -[MyApp.MainViewController pushNotificationWithTimer:]: unrecognized selector sent to instance 0x107077800
2017-12-09 20:33:47.440181-0500 Accumoo[3404:2488862] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyApp.MainViewController pushNotificationWithTimer:]: unrecognized selector sent to instance 0x107077800'
*** First throw call stack:
(0x184c89d04 0x183ed8528 0x184c971c8 0x18e47f110 0x184c8f6b0 0x184b7501c 0x18567bd24 0x184c3292c 0x184c32650 0x184c31e50 0x184c2fa38 0x184b4ffb8 0x1869e7f84 0x18e1242e8 0x104b3f624 0x18467256c)
libc++abi.dylib: terminating with uncaught exception of type NSException
这是代码......
在我的View Controller中......
// Send user a local notification if they have the app running in the background...
let userInfo = ["title" : "Title", "body" : "Body", "timeIntervalSeconds" : Double(0), "repeats" : false] as [String : Any]
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)
在我的NotificationManager类中......
class NotificationManager /*: PushNotificationProtocol*/ {
static let instance = NotificationManager()
private init() {
}
@objc public func pushNotification(timer:Timer) {
guard let userInfo = timer.userInfo as? Dictionary<String, Any> else { return }
let title = (userInfo["title"] as? String).valueOrDefault()
let body = (userInfo["body"] as? String).valueOrDefault()
let timeIntervalSeconds = (userInfo["timeIntervalSeconds"] as? Double) ?? 0
let repeats = (userInfo["repeats"] as? Bool) ?? false
self.pushNotification(sender: nil, title: title, body: body, timeIntervalSeconds: timeIntervalSeconds, repeats: repeats)
}
public func pushNotification(sender:Any?, title:String, body:String) {
self.pushNotification(sender: sender, title: title, body: body, timeIntervalSeconds: 0, repeats: false)
}
public func pushNotification(sender:Any?, title:String, body:String, timeIntervalSeconds:Double, repeats:Bool) {
// Center
let center = UNUserNotificationCenter.current()
// Content...
let content = UNMutableNotificationContent()
content.title = title
content.body = body
content.sound = UNNotificationSound.default()
// Trigger
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeIntervalSeconds, repeats: repeats)
// Push it...
// Does this need to be unique?
let identifier = "NotificationManagerIdentification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
if let error = error {
print("Something went wrong: \(error)")
}
})
}
}
** *更新* **
事实证明,对Timer.scheduleTimer的调用需要像这样编码(参见@ maddy的答案):
// Send user a local notification if they have the app running in the background...
let userInfo = ["title" : "Title", "body" : "Body", "timeIntervalSeconds" : Double(10), "repeats" : false] as [String : Any]
Timer.scheduledTimer(timeInterval: 0.5, target: NotificationManager.instance, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)
您将错误的目标传递给计时器。
更改:
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)
至:
Timer.scheduledTimer(timeInterval: 0.5, target: NotificationManager.instance, selector: #selector(NotificationManager.instance.pushNotification(timer:)), userInfo: userInfo, repeats: false)
请记住,目标需要实际实现要指定的选择器的类的实例。您正在传递self
,它是视图控制器。