iBeacon检测后如何播放视频?

How to play a video after iBeacon detection?

我是 iBeacon 和 Swift 开发的新手,我的应用程序有一些问题。在下面的代码中,我试图检测 iBeacon,当我检测到信标的次要值时,我将其附加到我想播放的 link。当我启动程序时出现问题。视频开始播放一秒钟,然后整个应用程序停止并出现以下错误:

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:“应用程序试图以模态方式呈现活动控制器 .libc++abi.dylib:终止并出现 NSException 类型的未捕获异常。

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"),


                ]



   func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {

    let knownBeacons = beacons.filter{ [=10=].proximity != CLProximity.unknown }
    if (knownBeacons.count > 0) {
        let closestBeacon = knownBeacons[0] as CLBeacon

        if let url = self.videos[closestBeacon.minor.intValue] {


            self.avPlayer = AVPlayer(url: url as! URL)
            self.avPlayerViewController.player = self.avPlayer

        }
        self.present(self.avPlayerViewController,animated: true) { () -> Void in
            self.avPlayerViewController.player?.play()
        }
    }
}

你能告诉我如何解决这个错误吗?

问题是 func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) ranging 回调每秒都会被调用一次。 因此,您用于显示视频播放器的代码将每秒执行一次。这可能第一次有效,但第二次,您会收到错误消息,因为对 self.present(...) 的调用试图呈现您已经呈现的相同视图控制器。 您不能一遍又一遍地呈现相同的视图控制器。

解决方案取决于您希望它如何工作。您只希望此演示发生一次吗?如果是这样,你可以这样做:

if (knownBeacons.count > 0) {
    let closestBeacon = knownBeacons[0] as CLBeacon

    if let url = self.videos[closestBeacon.minor.intValue] {

        // 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()
            }
        }
    }
}