应用程序在后台 ios 中时地理围栏不起作用
Posted
技术标签:
【中文标题】应用程序在后台 ios 中时地理围栏不起作用【英文标题】:Geofence not working while app is in background ios 【发布时间】:2019-06-04 06:18:56 【问题描述】:我正在尝试为我的应用程序进行地理围栏。当我的应用程序正在运行并且我模拟位置时。它收到了地理围栏,但是当它在后台时它没有收到任何地理围栏。 (我已按照本教程进行地理围栏Geofencing with core location
但我正在使用谷歌地图根据要求显示地图)
有我的AppDelegate的代码
import GoogleMaps
import GooglePlaces
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
var window: UIWindow?
let locationManager = CLLocationManager()
private let BLE_UUID_NUS_SERVICE = CBUUID(string: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E")//Nordic UART Service
private let BLE_UUID_NUS_RX_CHARACTERISTIC = CBUUID(string: "6E400002-B5A3-F393-E0A9-E50E24DCCA9E") //write
private let BLE_UUID_NUS_TX_CHARACTERISTIC = CBUUID(string: "6E400003-B5A3-F393-E0A9-E50E24DCCA9E") // notify
var centralManager:CBCentralManager? = nil
var currentLuminKeyIdentifire = ""
var lumnKeyPeripheral:CBPeripheral? = nil
var Rx_Write_Characteristic:CBCharacteristic? = nil
var Tx_Notify_Characteristic:CBCharacteristic? = nil
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
// location manager delegage
GMSServices.provideAPIKey(Constant.googleApiKey)
GMSPlacesClient.provideAPIKey(Constant.googleApiKey)
locationManager.requestAlwaysAuthorization()
locationManager.delegate = self
let options: UNAuthorizationOptions = [.badge, .sound, .alert]
UNUserNotificationCenter.current()
.requestAuthorization(options: options) success, error in
if let error = error
print("Error: \(error)")
return true
func applicationWillResignActive(_ application: UIApplication)
print("AppDelegate Application applicationWillResignActive")
func applicationDidEnterBackground(_ application: UIApplication)
print("AppDelegate Application applicationDidEnterBackground ")
func applicationWillEnterForeground(_ application: UIApplication)
print("AppDelegate Application applicationWillEnterForeground ")
func applicationDidBecomeActive(_ application: UIApplication)
application.applicationIconBadgeNumber = 0
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
print("AppDelegate Application applicationDidBecomeActive ")
ReachabilityManager.shared.startMonitoring()
func applicationWillTerminate(_ application: UIApplication)
print("AppDelegate Application applicationWillTerminate ")
func handleEvent(for region: CLRegion!)
// currentLuminKeyIdentifire = region.identifier
//
// self.centralManager = CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey : NSNumber(value: true)])
//
// print("AppDelegate Geofence triggered! and \(currentLuminKeyIdentifire)")
if UIApplication.shared.applicationState == .active
print("Active")
else
// Otherwise present a local notification
let notificationContent = UNMutableNotificationContent()
notificationContent.body = "Geo fence Triggred for lumin key"
notificationContent.sound = UNNotificationSound.default
notificationContent.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: "location_change_geofence",
content: notificationContent,
trigger: trigger)
UNUserNotificationCenter.current().add(request) error in
if let error = error
print("Error: \(error)")
extension AppDelegate: CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didEnterRegion
region: CLRegion)
if region is CLCircularRegion
handleEvent(for: region)
extension AppDelegate:CBCentralManagerDelegate
//start of central Manager Did update
func centralManagerDidUpdateState(_ central: CBCentralManager)
switch central.state
case .unknown:
print("AppDelegate central.state is .unknown")
case .resetting:
print("AppDelegate central.state is .resetting")
case .unsupported:
print("AppDelegate central.state is .unsupported")
case .unauthorized:
print("AppDelegate central.state is .unauthorized")
case .poweredOff:
// self.scheduleNotification(title: "Lumin Key Geofence",
// message: "Bluetooth is off ,Turn on for furthur ")
print("AppDelegate central.state is .poweredOff")
// send notification
case .poweredOn:
// scanBLEDevices()
print("AppDelegate central.state is .poweredOn")
if(!currentLuminKeyIdentifire.isEmpty)
let peripheralUUID = UUID(uuidString:currentLuminKeyIdentifire) ?? UUID()
print("AppDelegate peripheralUUID = \(peripheralUUID)")
let perif = central.retrievePeripherals(withIdentifiers:[peripheralUUID])
if(perif.count > 0)
for cbPeripheral in perif
if(cbPeripheral.identifier.uuidString == currentLuminKeyIdentifire)
lumnKeyPeripheral = cbPeripheral
lumnKeyPeripheral?.delegate = self
// connect to lumin key
centralManager?.connect(self.lumnKeyPeripheral!)
break
else
print("AppDelegate No retrievePeripherals :(")
//End of central Manager Did update
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
// toast(message: "Found bles didDiscover ")
//
// // show list of peripherals
// // get these peripheral
// self.lumnKeyPeripheral=peripheral
//
// self.lumnKeyPeripheral?.delegate = self
// // stop scanning
// centralManager?.stopScan()
// // connect to lumin key
// centralManager?.connect(self.lumnKeyPeripheral!)
print(peripheral)
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)
//todo handle this error
print(error ?? "problem")
// if(error != nil)
// self.isKeyConnected = false
//
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
// toast(message: "Connected")
// self.isKeyConnected = true
lumnKeyPeripheral?.discoverServices([BLE_UUID_NUS_SERVICE])
扩展 AppDelegate:CBPeripheralDelegate
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)
// toast(message: "In peripherals")
guard let services=peripheral.services else return
for service in services
peripheral.discoverCharacteristics([BLE_UUID_NUS_RX_CHARACTERISTIC,
BLE_UUID_NUS_TX_CHARACTERISTIC], for: service)
// peripheral.discoverCharacteristics(nil, for: service)
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service:
CBService, error: Error?)
guard let characteristics = service.characteristics else return
for characteristic in characteristics
print(characteristic)
// check if it contains write characteristic
if characteristic.properties.contains(.read)
print("\(characteristic.uuid): properties contains .read")
// this does not contain any read charateristic
peripheral.readValue(for: characteristic)
if characteristic.properties.contains(.notify)
print("\(characteristic.uuid): properties contains .notify")
// this also does not notify so this is un used
// peripheral.setNotifyValue(true, for: characteristic)
if characteristic.properties.contains(.write)
Rx_Write_Characteristic = characteristic
BleCommandUtil.sendColorCommadToKey(color: UIColor.hexStringToUIColor(hex:AppUserDefaults.getselectedColorHex()) ,
lumnKeyPeripheral: lumnKeyPeripheral,
Rx_Write_Characteristic: self.Rx_Write_Characteristic!,
isRandomColor: AppUserDefaults.getRandomColorToggle(),
isPowerSave: AppUserDefaults.getPowerSaveToggle())
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?)
switch characteristic.uuid
case BLE_UUID_NUS_TX_CHARACTERISTIC:
print(characteristic.value ?? "no value")
default:
print("AppDelegate Unhandled Characteristic UUID: \(characteristic.uuid)")
开始监控功能
func startMonitoring(geotification: Geotification)
// 1
if !CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self)
self.toast(message: "Geofencing is not supported on this device!")
return
// 2
if CLLocationManager.authorizationStatus() != .authorizedAlways
let message = "Your geotification is saved but will only be activated once you grant Geotify permission to access the device location."
self.toast(message: message)
// 3
let fenceRegion = region(with: geotification)
// 4
loacationManager.startMonitoring(for: fenceRegion)
我无法识别问题。我注意到如果我运行 Geofencing with core location 的 Finished 示例代码并单击 iPhone 上的主页按钮,则 AppDelegate 的 func applicationWillTerminate(_ application: UIApplication) 不会被调用,但是当我运行时我的应用程序调用它。我做错了什么?如何解决这个问题
【问题讨论】:
【参考方案1】:您是否已在项目设置的“功能”选项卡上启用“后台模式”并选中“位置更新”复选框?如果没有,那么你可以在后台模式下获取更新位置。
【讨论】:
我检查了位置更新,但同样无法正常工作【参考方案2】:我已经解决了这个问题,问题是 info.list 有 uiapplicationexitsonsuspend = yes 。我删除了它,现在它工作正常
【讨论】:
以上是关于应用程序在后台 ios 中时地理围栏不起作用的主要内容,如果未能解决你的问题,请参考以下文章