0
votes

I am trying to do geofencing for my App .When my app is running and i simulate location .it received geofence but when its is in background its does not receive any geofence . (I have followed this tutorial for geofencing Geofencing with core location

but I am using google Maps to display maps as per requirement)

There is code of my 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])
}

}

extension 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)")
    }
}

}

Function for Start Monitoring

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)
}

I am unable to identify problem .I have noticed if i run Finished sample code of Geofencing with core location and click home button on iPhone then func applicationWillTerminate(_ application: UIApplication) of AppDelegate does not called but when i run my app it does called .What i am doing wrong ? How to solve this

2

2 Answers

1
votes

Do you have enable “Background Modes” on the Capabilities tab of your project settings and select the “Location updates” checkbox? If not then do it then you can get update location in background mode.

-1
votes

I have resolved the issue , issue was info.list have uiapplicationexitsonsuspend = yes .I removed it and now its working fine