在应用程序运行且关闭时,如何在检测到iBeacon后向用户显示通知?

时间:2016-12-20 11:17:11

标签: swift notifications ibeacon

在我的swift 3应用程序中,我有2个iBeacons应该执行不同的任务。其中一个应该打开并播放视频文件,另一个应该向用户发送通知。当我将iPhone关闭到​​播放音频文件的信标时,一切正常,但是当我测试发送通知的另一个信标时, app仅发送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{ $0.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){}
            }

1 个答案:

答案 0 :(得分:1)

问题是您不能多次呈现视图控制器。这是我在这里回答的同一个基本问题:How to play a video after iBeacon detection?

澄清一下,虽然问题提到“通知”,但问题实际上是一个警告对话框。 (iOS上的通知通常具有更具体的含义,它指的是可以显示在锁定屏幕上的NSNotificaitonCenter项目。)

在初始化let videos时加载类时,将构造一次警告对话框实例。然后它会在unc locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)方法内呈现给用户,该方法每秒调用一次。

您无法每秒重新呈现警报对话框的完全相同的实例。您只能呈现一次,否则您将收到错误。只有在用户不再显示错误后,您才能再次显示。