设置监控

时间:2017-02-28 21:36:37

标签: ios swift xcode ibeacon

我一直在使用swift 3和Xcode 8.2.1在iOS 10上检测iBeacons。

我一直在关注this教程,到目前为止我已经能够在前台检测到信标了。 但是,我需要的是在背景中以及应用程序关闭时检测到信标。

我已在NSLocationAlwaysUsageDescription中设置了密钥info.plist,并在应用Location updates中添加了Background Modes

我还要求用户requestAlwaysAuthorization

一切正常,直到我在代码中添加以下语句:locationManager.startMonitoring(for: beaconRegion)

在我添加上述语句并运行代码后,我的应用程序检测到前台的信标并向我打印一条消息。但是,一旦我最小化应用程序并重新打开它,应用程序似乎无法找到灯塔。如果我对该线路进行注释然后重新运行我的程序,该应用程序将检测到前景中的信标,以及当我最小化并再次重新打开应用程序时。 我不明白我做错了什么。

这是我的ViewController代码:

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {
    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.pausesLocationUpdatesAutomatically = false
        locationManager.allowsBackgroundLocationUpdates = true
        locationManager.requestAlwaysAuthorization()
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedAlways {
            if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
                if CLLocationManager.isRangingAvailable() {
                    startScanning()
                }
            }
        }
    }

    func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
        if beacons.count > 0 {
            NSLog("Found beacon")
        } else {
            NSLog("Beacon not found")
        }
    }

    func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
        let beaconRegion = region as! CLBeaconRegion
        print("Did enter region: " + (beaconRegion.major?.stringValue)!)
    }

    func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
        let beaconRegion = region as! CLBeaconRegion
        print("Did exit region: " + (beaconRegion.major?.stringValue)!)
    }

    func startScanning() {
        let uuid = UUID(uuidString: "2f234454-cf6d-4a0f-adf2-f4911ba9ffa6")!
        let beaconRegion = CLBeaconRegion(proximityUUID: uuid, major: CLBeaconMajorValue(0), minor: CLBeaconMinorValue(1), identifier: "MyBeacon")

        beaconRegion.notifyEntryStateOnDisplay = true
        beaconRegion.notifyOnEntry = true
        beaconRegion.notifyOnExit = true

        //        locationManager.startMonitoring(for: beaconRegion)
        locationManager.startRangingBeacons(in: beaconRegion)
    }
}

这是我的日志的样子:

Found beacon
Found beacon
Found beacon
// App minimised and reopened here
Found beacon
Found beacon
Found beacon
Found beacon
Found beacon
Found beacon
Beacon not found
Beacon not found
Beacon not found
Beacon not found
Beacon not found
Beacon not found

2 个答案:

答案 0 :(得分:1)

尝试添加监控委托回调didEnter(region: region)didExit(region: region)。不确定为什么它会改变一些事情,代码开始监视但不具备它们是不寻常的。

编辑:看到更新后的代码后,我怀疑问题可能就是测距的开始方式。不要在didChangeAuthorization回调中启动它,只需在viewDidLoad中启动即可。如果没有给出授权,代码不会崩溃。它实际上不会扫描直到它。

答案 1 :(得分:0)

与iBeacons的交互可以通过范围监控来完成。对信标进行测距可以为您提供iBeacon的价值/数据,例如uuid,major&未成年人。 范围问题是苹果在后台仅接受几个(大约10秒)的测距时间。监控可以在后台完成。你应该检查你是否可以在后台(打印/日志)范围内,如果检测到ibeacon是问题。

ps:当您在区域内开始测距时,不会调用didEnter委托方法,因为您已经在该区域内。