iBeacon, iOS13, BGAppRefreshTask - PullRequest
1 голос
/ 08 января 2020

Мне нужно реализовать обнаружение iBeacons в фоновом режиме, например, каждые 5 минут, для этого я хочу использовать новую инфраструктуру Apple BackgroundTask

Так я реализую свой подкласс операций

import CoreLocation

class BeaconsRecord: AsyncOperation {

    private let locationManager: CLLocationManager
    private let clBeaconIdentityConstraint: CLBeaconIdentityConstraint
    var beacons = [CLBeacon]()

    init (locationManager: CLLocationManager, uuid: UUID) {
        self.locationManager = locationManager
        self.clBeaconIdentityConstraint = CLBeaconIdentityConstraint(uuid: uuid)
        super.init()
    }

    override func main() {
        locationManager.delegate = self
        locationManager.startRangingBeacons(satisfying: clBeaconIdentityConstraint)
    }
}

extension BeaconsRecord: CLLocationManagerDelegate {

    func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
        self.locationManager.stopRangingBeacons(satisfying: clBeaconIdentityConstraint)
        self.beacons = beacons
        self.state = .Finished
    }
}

, если я использую его с переднего плана, он отлично работает, затем я пытаюсь использовать его из фона, как показано в презентации wwd c, он не работает. Что я скучаю? Моя реализация appdelegate

@ UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var locationManager : CLLocationManager?
let uuid = UUID(uuidString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D")!

lazy var detectBeaconsQueue : OperationQueue = {
    var queue = OperationQueue()
    queue.name = "detectBeaconsQueue"
    queue.maxConcurrentOperationCount = 1
    return queue
}()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    locationManager = CLLocationManager()
    locationManager?.requestAlwaysAuthorization()

    registerBackgroundTaks()
    registerLocalNotification()

    return true
}

//MARK: Register BackGround Tasks
func registerBackgroundTaks() {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: "xxx.xxxxxx.xxxxxxxxxxx", using: nil) { task in
         self.scheduleLocalNotification()
         self.handleAppRefresh(task: task as! BGAppRefreshTask)
      }
}

func applicationDidEnterBackground(_ application: UIApplication) {
    cancelAllPendingBGTask()
    scheduleAppRefresh()
}

}

расширение AppDelegate {

func cancelAllPendingBGTask() {
    BGTaskScheduler.shared.cancelAllTaskRequests()
}

func scheduleAppRefresh() {
       let request = BGAppRefreshTaskRequest(identifier: ""xxx.xxxxxx.xxxxxxxxxxx"")

       // Fetch no earlier than 1 minutes from now
    request.earliestBeginDate = Date(timeIntervalSinceNow: 1 * 60)
       do {
          try BGTaskScheduler.shared.submit(request)
       } catch {
          print("Could not schedule app refresh: \(error)")
       }
    }

func handleAppRefresh(task: BGAppRefreshTask) {
    // Schedule a new refresh task
    scheduleAppRefresh()

    let operation = BeaconsRecord(locationManager: locationManager!,
                                  uuid: uuid)

    task.expirationHandler = {
        operation.cancel()
    }

    operation.completionBlock = {
        task.setTaskCompleted(success: !operation.isCancelled)
    }

    detectBeaconsQueue.addOperation(operation)
}

}

1 Ответ

0 голосов
/ 10 января 2020

После работы над проектами Beacon в течение 2 лет я могу сказать, что нет способа обнаружить iBeacon в фоновом режиме, особенно в вашем сценарии .

В фоновом режиме iOS, задача будет прервана через 3 минуты. Вы запустили задачу, если приступили к определению фона, для экономии заряда батареи. Единственный способ заключается в том, что при работе приложения в режиме ранжирования маяков вы можете вызывать поток каждые 5 минут, чтобы определить последний статус маяка, не прерывая приложение. Экран может быть закрыт, но приложение все еще должно работать. НО Это нелегальный сценарий. Команда Apple по рассмотрению не одобряет ваше приложение для защиты преимуществ пользователей.

Нет проблем с мониторингом маяков в фоновом режиме, , но вы должны только знать, подключен ли сигнал-маяк к устройству или нет в течение 30 секунд.

Вы должны глубоко знать разницу между мониторингом и сканированием области. И если в этом сценарии ваш сценарий не применяется из фонового мониторинга , то нет способа определить статус маяка в фоновом режиме с помощью Диапазон маяка каждые 5 минут.

Для получения дополнительной информации прочитайте его : https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...