菜鸟教程小白 发表于 2022-12-11 19:47:46

ios - CLLocationManager 不监控区域


                                            <p><p>我很困惑...我今天有这个工作,现在我不知道发生了什么。它不是我的 iBeacon,因为我可以使用 <code>Locate</code> iOS 应用程序找到它。我正在创建自己的位置管理器,但不确定您是否将其称为子类,因为我正在继承 NSObject。这里是:</p>

<pre><code>//
//LocationManager.swift
//onebeacon
//
//Created by Eamon White on 2/24/18.
//Copyright © 2018 EamonWhite. All rights reserved.
//

import Foundation
import CoreLocation

protocol LocationManagerDelegate: class {
    func locationManagerDidUpdateLocation(_ locationManager: LocationManager, location: CLLocation)
    func locationManagerDidUpdateHeading(_ locationManager: LocationManager, heading: CLHeading, accuracy: CLLocationDirection)
    func locationManagerDidEnterRegion(_ locationManager: LocationManager, didEnterRegion region: CLRegion)
    func locationManagerDidExitRegion(_ locationManager: LocationManager, didExitRegion region: CLRegion)
    func locationManagerDidDetermineState(_ locationManager: LocationManager, didDetermineState state: CLRegionState, region: CLRegion)
    func locationManagerDidRangeBeacons(_ locationManager: LocationManager, beacons: , region: CLBeaconRegion)
}


class LocationManager: NSObject, CLLocationManagerDelegate {
    private var locationManager: CLLocationManager!
    weak var delegate: LocationManagerDelegate?
    var beaconsToRange:
    var currentLocation: CLLocation!

    override init() {
      self.beaconsToRange = []
      super.init()

      self.locationManager = CLLocationManager()
      self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
      self.locationManager.distanceFilter = kCLDistanceFilterNone
      self.locationManager.headingFilter = kCLHeadingFilterNone
      self.locationManager.pausesLocationUpdatesAutomatically = false
      self.locationManager.delegate = self

      self.enableLocationServices()
    }

    func enableLocationServices() {
      self.checkStatus(status: CLLocationManager.authorizationStatus())
    }

    func checkStatus(status: CLAuthorizationStatus) {
      switch status {
      case .notDetermined:
            // Request when-in-use authorization initially
            locationManager.requestAlwaysAuthorization()
            break

      case .restricted, .denied:
            // Disable location features
            print(&#34;send an alert that the app will not function&#34;)
            break

      case .authorizedWhenInUse:
            locationManager.requestAlwaysAuthorization()
            // Enable basic location features
            break

      case .authorizedAlways:
            locationManager.startUpdatingLocation()
            locationManager.startUpdatingHeading()
            self.monitorBeacons()
            // Enable any of your app&#39;s location features
            break
      }
    }

    func monitorBeacons() {
      print(&#34;monitorBeacons()&#34;)
      if CLLocationManager.isMonitoringAvailable(for:
            CLBeaconRegion.self) {
            print(&#34;monitorBeacons().monitoringIsAvailable&#34;)
            // Match all beacons with the specified UUID
            let proximityUUID = UUID(uuidString:
                &#34;12345678-B644-4520-8F0C-720EAF059935&#34;)

            let beaconRegion = CLBeaconRegion(
                proximityUUID: proximityUUID!,
                major: 0x0001,
                minor: 0x0002,
                identifier: &#34;iBeacon&#34;)

            beaconRegion.notifyEntryStateOnDisplay = true;

            self.locationManager?.startMonitoring(for: beaconRegion)
            print(&#34;\(String(describing: self.locationManager?.monitoredRegions)) + monitoredRegions&#34;)
      }
    }

    //MARK: - CLLocationManagerDelegate

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: ) {
      for location in locations {
            self.delegate?.locationManagerDidUpdateLocation(self, location: location)
      }

      self.currentLocation = manager.location
    }

    func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
      self.delegate?.locationManagerDidUpdateHeading(self, heading: newHeading, accuracy: newHeading.headingAccuracy)
    }

    func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
      if region is CLBeaconRegion {
            // Start ranging only if the feature is available.
            if CLLocationManager.isRangingAvailable() {
                locationManager?.startRangingBeacons(in: region as! CLBeaconRegion)

                // Store the beacon so that ranging can be stopped on demand.
                beaconsToRange.append(region as! CLBeaconRegion)
            }
      }
      self.delegate?.locationManagerDidEnterRegion(self, didEnterRegion: region)
    }

    func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
      self.delegate?.locationManagerDidExitRegion(self, didExitRegion: region)
    }

    func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
      if region is CLBeaconRegion {
            print(&#34;determined state of beacon&#34;)
            // Start ranging only if the feature is available.
            if CLLocationManager.isRangingAvailable() {
                print(&#34;determined state of beacon and started ranging&#34;)
                locationManager?.startRangingBeacons(in: region as! CLBeaconRegion)
                // Store the beacon so that ranging can be stopped on demand.
                beaconsToRange.append(region as! CLBeaconRegion)
            }
      }

      self.delegate?.locationManagerDidDetermineState(self, didDetermineState: state, region: region)
    }

    func locationManager(_ manager: CLLocationManager,
                         didRangeBeacons beacons: ,
                         in region: CLBeaconRegion) {
      self.delegate?.locationManagerDidRangeBeacons(self, beacons: beacons, region: region)
    }

    func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -&gt; Bool {
      return true
    }

    func locationManager(_ manager: CLLocationManager,
                         didChangeAuthorization status: CLAuthorizationStatus) {
      self.checkStatus(status: status)
    }
}
</code></pre>

<p>在我的 <code>ViewController</code> 中,我以非常直接的方式使用它(顶部:委托(delegate)方法......对于问题来说有点无关紧要,底部:实例化):</p >

<pre><code>import UIKit
import SceneKit
import ARKit
import CoreLocation

class ViewController: UIViewController, ARSCNViewDelegate, LocationManagerDelegate {

    func locationManagerDidUpdateLocation(_ locationManager: LocationManager, location: CLLocation) {

    }

    func locationManagerDidUpdateHeading(_ locationManager: LocationManager, heading: CLHeading, accuracy: CLLocationDirection) {

    }

    func locationManagerDidEnterRegion(_ locationManager: LocationManager, didEnterRegion region: CLRegion) {

    }

    func locationManagerDidExitRegion(_ locationManager: LocationManager, didExitRegion region: CLRegion) {

    }

    func locationManagerDidDetermineState(_ locationManager: LocationManager, didDetermineState state: CLRegionState, region: CLRegion) {

    }

    func locationManagerDidRangeBeacons(_ locationManager: LocationManager, beacons: , region: CLBeaconRegion) {
      print(&#34;\(beacons) + beacons for ranging&#34;)
      if beacons.count &gt; 0 {
            let nearestBeacon = beacons.first!
            let major = CLBeaconMajorValue(truncating: nearestBeacon.major)
            let minor = CLBeaconMinorValue(truncating: nearestBeacon.minor)

            print(&#34;major: \(major)&#34;)
            print(&#34;minor: \(minor)&#34;)
            print(&#34;accuracy: \(nearestBeacon.accuracy)&#34;)

            switch nearestBeacon.proximity {
            case .immediate:
                print(&#34;--- immediate ---&#34;)
            case .near:
                print(&#34;--- near ---&#34;)
            case .far:
                print(&#34;--- far ---&#34;)
            case .unknown:
                print(&#34;--- proximity unknown ---&#34;)
            }
      }
    }


    var sceneView: ARSCNView!
    var locationManager: LocationManager!

    override func viewDidLoad() {
      super.viewDidLoad()
      sceneView = ARSCNView()

      locationManager = LocationManager()
      locationManager.delegate = self

      ...
</code></pre>

<p>我的控制台输出是:</p>

<pre><code>2018-02-24 20:40:30.927542-0500 onebeacon platform initialization successful
2018-02-24 20:40:32.799470-0500 onebeacon Metal GPU Frame Capture Enabled
2018-02-24 20:40:32.801237-0500 onebeacon Metal API Validation Enabled
monitorBeacons()
monitorBeacons().monitoringIsAvailable
Optional(Set()) + monitoredRegions
</code></pre>

<p>所有 iBeacon 细节都是正确的,它们不可能从今天早些时候改变,因为它一直被插入并且没有被访问。问题总结:似乎将该区域添加到“要监控的区域”列表中,但监控似乎从未开始,因为我没有收到中继 iBeacon 信息的控制台消息。</p>

<p><strong>更新</strong></p>

<p>我会留下我提供的答案,因为它可能是其中的一部分(也许不是)......但现在它似乎开始了两次:</p>

<pre><code>2018-02-24 21:35:13.341162-0500 onebeacon platform initialization successful
2018-02-24 21:35:16.504017-0500 onebeacon Metal GPU Frame Capture Enabled
2018-02-24 21:35:16.505384-0500 onebeacon Metal API Validation Enabled
monitorBeacons()
monitorBeacons().monitoringIsAvailable
Optional(Set()) + monitoredRegions
2018-02-24 21:35:16.747004-0500 onebeacon System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2018-02-24 21:35:16.747969-0500 onebeacon Reading from public effective user settings.
monitorBeacons()
monitorBeacons().monitoringIsAvailable
Optional(Set()) + monitoredRegions
</code></pre>

<p>如您所见,<code>monitorBeacons()...</code> 行出现了两次,我检查以确保没有 LocationManager 的其他实例化,也没有。</p>

<p><strong>更新</strong></p>

<p>我缩小了范围...问题似乎是 <code>didDetermineState</code> 函数最初没有触发,我必须走出信标的范围(或靠近它)...然后往回走,<code>didDetermineState</code> 方法触发,有谁知道为什么当我在信标的半径范围内开始时它没有触发?</p>

<p><strong>更新</strong></p>

<p>我的手机似乎正在识别它在一个区域中,因为当我走出该区域时,<code>didExitRegion</code> 方法会触发,然后是 <code>didDetermineState</code> 方法。 ..odd 因为如果 <code>didExitRegion</code> 方法正在触发,则应该已经确定了状态:</p>

<pre><code>2018-02-24 23:01:09.650445-0500 onebeacon if we&#39;re in the real pre-commit handler we can&#39;t actually add any new fences due to CA restriction
2018-02-24 23:01:09.651978-0500 onebeacon if we&#39;re in the real pre-commit handler we can&#39;t actually add any new fences due to CA restriction
2018-02-24 23:01:15.007844-0500 onebeacon if we&#39;re in the real pre-commit handler we can&#39;t actually add any new fences due to CA restriction
2018-02-24 23:01:15.007893-0500 onebeacon if we&#39;re in the real pre-commit handler we can&#39;t actually add any new fences due to CA restriction
2018-02-24 23:02:00.002451-0500 onebeacon Status bar could not find cached time string image. Rendering in-process.

...(put in for easier reading)...

did exit region --- CLBeaconRegion (identifier:&#39;iBeacon&#39;, uuid:12345678-B644-4520-8F0C-720EAF059935, major:1, minor:2)
determined state of beacon
determined state of beacon and started ranging
[] + beacons for ranging
[] + beacons for ranging
[] + beacons for ranging
[] + beacons for ranging
[] + beacons for ranging
[] + beacons for ranging
[] + beacons for ranging
</code></pre>

<p>什么是预提交处理程序警告?这些是否相关?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我的 <code>didDetermineState</code> 函数在应用程序的初始加载时停止工作。如果我走出信标的范围,然后回到范围 - <code>didDetermineState</code> 方法会触发(以及 <code>enter/exit</code> 区域方法)。我购买了另一个 iBeacon……它运行良好……而且,奇怪的是,当我同时使用两个信标时,<code>didDetermineState</code> 在初始加载时检测到两个信标。我不确定为什么 <code>didDetermineState</code> 在单独使用时停止为一个信标工作。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - CLLocationManager 不监控区域,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/48969476/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/48969476/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - CLLocationManager 不监控区域