How to use geofencing in iOS?

33 Views Asked by At

When developing an APP in Swift, I want to develop a function that allows users to set notifications when they enter or leave a certain range. Currently, I find that the function I develop must obtain "Always allow the use of positioning" before the APP exits. Notifications are triggered when entering the background, but I saw that another APP only obtained the "during use" permission and was able to send out notifications in a timely manner. Also, when the APP was completely exited, my APP was only able to do so very rarely and occasionally. Receive geofencing notifications. Is there some way that I don't know about that can be used to receive timely notifications like another APP, and does not require the "Always allow positioning" permission.

override init() {
    super.init()
    locationManager.delegate = self
    locationManager.requestWhenInUseAuthorization()
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.startMonitoringSignificantLocationChanges()
}

func newMonitor(latitude: CLLocationDegrees, longitude: CLLocationDegrees, identifier: String, notifyMode: Int, groupIdTodoId: [Int64]) {
    
    let gpsl = LocationTransform.gcj2wgs(gcjLat: latitude, gcjLng: longitude)
    
    if !CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
        let message = String(localized: LocalizedStringResource("info_start_monitoring_no_authorize", locale: Locale.init(identifier: SettingDataManager.shared.getSetingLanguage())))
        ToastUtil.showToast(message, duration: 5)
        return
    }
    
    let targetLocation = CLLocationCoordinate2D(latitude: gpsl.wgsLat, longitude: gpsl.wgsLng)
    let region = CLCircularRegion(center: targetLocation, radius: CLLocationDistance(SettingDataManager.shared.getRemindRange()), identifier: identifier)
 
    if (notifyMode == Constants.LOCATION_NOTIFY_ENTRY) {
        region.notifyOnEntry = true
        region.notifyOnExit = false
    } else if (notifyMode == Constants.LOCATION_NOTIFY_OUT) {
        region.notifyOnExit = true
        region.notifyOnEntry = false
    }
    
    UserDataManager.shared.setMonitoredGroupIdTodoId(identifier: identifier, groupIdTodoId: groupIdTodoId, type: notifyMode)
    monitoredIdentifiers.append(identifier)
    locationManager.startMonitoring(for: region)
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
    if let groupIdTodoId = UserDataManager.shared.getMonitoredGroupIdTodoId(identifier: region.identifier) {
        
        let groupName = ""//(GroupViewModel.shared.groupItems.first(where: {$0.id == groupIdTodoId[0]})?.name)!
        let todoTitle = (TodoListViewModel.shared.todoItems[groupIdTodoId[0]]?.first(where: { tdi in
            tdi.id == groupIdTodoId[1]
        })?.title) ?? ""
        // 根据groupIdTodoId 获取分组名和ToDo内容
        NotificationUtil.sendLocationNotification(notifyTitle: groupName,notifyContent: todoTitle, identifier: region.identifier, timeInterval: 1)
        removeConditionFromMonitoring(withIdentifier: region.identifier)
    }
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
    if let groupIdTodoId = UserDataManager.shared.getMonitoredGroupIdTodoId(identifier: region.identifier) {
        
        let groupName = ""//(GroupViewModel.shared.groupItems.first(where: {$0.id == groupIdTodoId[0]})?.name)!
        let todoTitle = (TodoListViewModel.shared.todoItems[groupIdTodoId[0]]?.first(where: { tdi in
            tdi.id == groupIdTodoId[1]
        })?.title)!
        // 根据groupIdTodoId 获取分组名和ToDo内容
        NotificationUtil.sendLocationNotification(notifyTitle: groupName,notifyContent: todoTitle, identifier: region.identifier, timeInterval: 1)
        removeConditionFromMonitoring(withIdentifier: region.identifier)
    }
}
0

There are 0 best solutions below