如何在检测到 iBeacon 后向用户显示通知,而应用程序处于 运行 且处于关闭状态?
How to show a notification to the users after detecting iBeacon, while the app is running and while it is closed?
在我的 swift 3 应用程序中,我有 2 个 iBeacons,它们应该执行不同的任务。其中一个应该打开并播放视频文件,另一个应该向 users.Everything 发送通知,当我将 iPhone 关闭到播放音频文件的信标时工作正常,但是当我测试另一个时发送通知的信标,应用程序仅发送 1 个通知并突然停止工作。我假设我正在尝试无限次地显示相同的通知,但我不知道如何解决该问题。这是我得到的错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <Audio.DEViewController: 0x149f05190>.'
请看下面我的代码:
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var avPlayerViewController = AVPlayerViewController()
var avPlayer:AVPlayer?
let locationManager = CLLocationManager()
let region = CLBeaconRegion(proximityUUID: UUID(uuidString: "8492E75F-4FD6-469D-B132-043FE94921D8")!, identifier: "Estimotes")
let videos = [
19987: NSURL ( string: "http://techslides.com/demos/sample-videos/small.mp4"),
3542: UIAlertController(title:"Permission Required", message:"Location services permission is required.", preferredStyle:.alert)
]
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
let knownBeacons = beacons.filter{ [=12=].proximity != CLProximity.unknown }
if (knownBeacons.count > 0) {
let closestBeacon = knownBeacons[0] as CLBeacon
if let url = self.videos[closestBeacon.minor.intValue] {
let ok = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
}
url.addAction(ok)
self.present(url as UIViewController, animated:true){}
// only execute this code once, if avPlayer not created yet
if self.avPlayer == nil {
self.avPlayer = AVPlayer(url: url as! URL)
self.avPlayerViewController.player = self.avPlayer
self.present(self.avPlayerViewController,animated: true) { () -> Void in
self.avPlayerViewController.player?.play()
}
}
}
}
还有我如何在用户关闭应用程序时发送通知。我添加了
Privacy - Location Always Usage Description
在我的
info.plist
但是当我关闭应用程序并尝试显示通知时,仍然没有任何反应。
if let url = self.colors[closestBeacon.minor.intValue] {
if (NSDate.timeIntervalSinceReferenceDate - self.lastNotificationTime > 10) {
self.lastNotificationTime = NSDate.timeIntervalSinceReferenceDate
let ok = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
}
url.addAction(ok)
self.present(url as UIViewController, animated:true){}
}
问题是您不能多次显示一个视图控制器。这与我在这里回答的基本问题相同:
需要澄清的是,虽然问题提到了 "notification",但问题实际上与警告对话框有关。 (iOS 上的通知通常具有更具体的含义,它指的是可以显示在锁定屏幕上的 NSNotificaitonCenter
项目。)
当 let videos
初始化时 class 加载时构造一次警报对话框实例。然后它在 unc locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)
方法中呈现给用户,每秒调用一次。
您不能每秒都重新呈现完全相同的警报对话框实例。只能展示一次,否则会报错。 不再展示给用户后才能再次展示。
在我的 swift 3 应用程序中,我有 2 个 iBeacons,它们应该执行不同的任务。其中一个应该打开并播放视频文件,另一个应该向 users.Everything 发送通知,当我将 iPhone 关闭到播放音频文件的信标时工作正常,但是当我测试另一个时发送通知的信标,应用程序仅发送 1 个通知并突然停止工作。我假设我正在尝试无限次地显示相同的通知,但我不知道如何解决该问题。这是我得到的错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <Audio.DEViewController: 0x149f05190>.'
请看下面我的代码:
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var avPlayerViewController = AVPlayerViewController()
var avPlayer:AVPlayer?
let locationManager = CLLocationManager()
let region = CLBeaconRegion(proximityUUID: UUID(uuidString: "8492E75F-4FD6-469D-B132-043FE94921D8")!, identifier: "Estimotes")
let videos = [
19987: NSURL ( string: "http://techslides.com/demos/sample-videos/small.mp4"),
3542: UIAlertController(title:"Permission Required", message:"Location services permission is required.", preferredStyle:.alert)
]
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
let knownBeacons = beacons.filter{ [=12=].proximity != CLProximity.unknown }
if (knownBeacons.count > 0) {
let closestBeacon = knownBeacons[0] as CLBeacon
if let url = self.videos[closestBeacon.minor.intValue] {
let ok = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
}
url.addAction(ok)
self.present(url as UIViewController, animated:true){}
// only execute this code once, if avPlayer not created yet
if self.avPlayer == nil {
self.avPlayer = AVPlayer(url: url as! URL)
self.avPlayerViewController.player = self.avPlayer
self.present(self.avPlayerViewController,animated: true) { () -> Void in
self.avPlayerViewController.player?.play()
}
}
}
}
还有我如何在用户关闭应用程序时发送通知。我添加了
Privacy - Location Always Usage Description
在我的
info.plist
但是当我关闭应用程序并尝试显示通知时,仍然没有任何反应。
if let url = self.colors[closestBeacon.minor.intValue] {
if (NSDate.timeIntervalSinceReferenceDate - self.lastNotificationTime > 10) {
self.lastNotificationTime = NSDate.timeIntervalSinceReferenceDate
let ok = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
}
url.addAction(ok)
self.present(url as UIViewController, animated:true){}
}
问题是您不能多次显示一个视图控制器。这与我在这里回答的基本问题相同:
需要澄清的是,虽然问题提到了 "notification",但问题实际上与警告对话框有关。 (iOS 上的通知通常具有更具体的含义,它指的是可以显示在锁定屏幕上的 NSNotificaitonCenter
项目。)
当 let videos
初始化时 class 加载时构造一次警报对话框实例。然后它在 unc locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)
方法中呈现给用户,每秒调用一次。
您不能每秒都重新呈现完全相同的警报对话框实例。只能展示一次,否则会报错。 不再展示给用户后才能再次展示。