从 Appdelegate 设置 iBeacon 操作和监控

Posted

技术标签:

【中文标题】从 Appdelegate 设置 iBeacon 操作和监控【英文标题】:Setting up iBeacon actions and monitoring from Appdelegate 【发布时间】:2017-01-01 03:50:26 【问题描述】:

我正在制作一个具有多个视图的应用。我希望它能够在所有视图的背景中监视信标。所以,我在 App 委托中设置代码。当代码在应用程序委托中时,它什么也不做。如果我将它移动到要加载的第一个视图控制器,它将要求授权使用位置,但在进入信标区域时不执行操作。这是应用程序委托中的代码。我做错了什么?

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate 

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
        return true
    

    func applicationWillResignActive(_ application: UIApplication) 
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    

    func applicationDidEnterBackground(_ application: UIApplication) 
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    



    func applicationDidFinishLaunchingWithOptions(_ application: UIApplication) 


        let beaconManager = CLLocationManager()


            var locationManager: CLLocationManager!

            var window: UIWindow?


            locationManager = CLLocationManager()

            locationManager.delegate = self

            locationManager.requestAlwaysAuthorization()

            func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) 
                if status == CLAuthorizationStatus.authorizedAlways 
                    if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) 
                        if CLLocationManager.isRangingAvailable() 

                            startScanning()
                        
                    
                
            


            func startScanning() 

                let uuid = NSUUID(uuidString: "2F234454-CF6D-4AOF-ADF2-F4911BA9FFA6")
                let beaconRegion1 = CLBeaconRegion(proximityUUID: uuid as! UUID, major: 0, minor: 1, identifier: "AuschwitzAlbum")
                let beaconRegion2 = CLBeaconRegion(proximityUUID: uuid as! UUID, major: 0, minor: 2, identifier: "Children")

                locationManager.startMonitoring(for: beaconRegion1)
                locationManager.startMonitoring(for: beaconRegion2)
            


            func beaconManager(manager: Any, didEnterRegion: CLBeaconRegion) 

                switch CLBeaconRegion() 

                case beaconRegion1:
                    let storyboard = UIStoryboard(name: "Main", bundle: nil)
                    let controller = storyboard.instantiateViewController(withIdentifier: "exhibitions")
                    self.window?.rootViewController?.present(controller, animated: true, completion: nil)


                case beaconRegion2: break

                default: break

                
            

    


func applicationWillEnterForeground(_ application: UIApplication) 
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.


func applicationDidBecomeActive(_ application: UIApplication) 
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.


func applicationWillTerminate(_ application: UIApplication) 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.




【问题讨论】:

当应用程序进入信标区域时,应该显示一个视图,说明“您已进入XXX区域。您想看有关XXX的展品吗?”如果他们点击是,它将把他们带到适当的视图。如果他们点击否,它只会关闭视图。 创建自己的单例可能比用太多代码覆盖 AppDelegate 更有趣。 【参考方案1】:

为了更容易开始,您可以尝试将调用移至嵌套条件之外的startScanning(),或使用调试器查看代码的进入和退出区域部分是否实际被调用。

这里有一些简化的示例代码可以帮助您入门:

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

    var window: UIWindow?
    var locationManager: CLLocationManager!
    let beaconRegion1 = CLBeaconRegion(proximityUUID: UUID(uuidString: "2F234454-CF6D-4AOF-ADF2-F4911BA9FFA6")!, identifier: "AuschwitzAlbum")

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
        locationManager = CLLocationManager()
        locationManager.delegate = self
        requestLocationAuthorization()
        return true
    

    // Standard AppDelegate implementations here


extension AppDelegate : CLLocationManagerDelegate 

    func requestLocationAuthorization() 
        if CLLocationManager.authorizationStatus() != .authorizedAlways 
            locationManager.requestAlwaysAuthorization()
        
    

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 
        if status == .authorizedAlways 
            startMonitoringRegion()
        
    

    func startMonitoringRegion() 
        locationManager.startMonitoring(for: beaconRegion1)
    

    func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) 
        print("Did enter region \(region.identifier)")
        if region.identifier == beaconRegion1.identifier
            showViewController()
        
    

    func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) 
        print("Did exit region \(region.identifier)")
    

    func showViewController() 
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "exhibitions")
        self.window?.rootViewController?.present(controller, animated: true, completion: nil)
    

【讨论】:

以上是关于从 Appdelegate 设置 iBeacon 操作和监控的主要内容,如果未能解决你的问题,请参考以下文章

从 appdelegate 更新视图控制器 - 最佳实践?

屏幕关闭时的 iBeacon 事件

应用关闭时的 iBeacon 通知

设备重启后的 IOS8 iBeacon 监控

AppDelegate 代码仅在后台运行

从 appdelegate 设置 UIViewController 委托