即使应用程序终止,是否也可以定期执行功能?

问题描述 投票:0回答:1

我正在构建一个国家追踪应用程序。用户安装应用程序,通过多个API应用程序获取用户所在国家/地区并将其保存在核心数据中。问题是 BGTask 不可靠。在过去的三天里,我没有看到它执行一次。是否可以采取不同的做法?

我想添加第三个解决方案到我的

BGTaskScheduler.shared.register(forTaskWithIdentifier: "///", using: nil) { task in
            self.handleLocationFetch(task: task as! BGAppRefreshTask) }


private func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "///")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 1800) // 30 minutes
        do {
            try BGTaskScheduler.shared.submit(request)
        } catch {
            print("Could not schedule app refresh: \(error)")
        }
    }

init() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.pinborg.countryTracker.locationfetch", using: nil) { task in
            self.handleLocationFetch(task: task as! BGAppRefreshTask) }
}

,无论如何,永远有效的一个。预先感谢您。

编辑:

    private func handleLocationFetch(task: BGAppRefreshTask) {
        scheduleAppRefresh()
        let locationManager = LocationManager()
        let entryStore = EntryStore()
        let openCageVM = OpenCageVM()
        
        task.expirationHandler = {
            locationManager.locationManager.stopMonitoringSignificantLocationChanges()
        }
        
        locationManager.locationManager.startMonitoringSignificantLocationChanges()
        
        // Fetch the "app storage" toggle setting from UserDefaults (or another storage)
        let allowTrackingDuringFlight = UserDefaults.standard.bool(forKey: "allowTrackingDuringFlight")
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
            guard let location = locationManager.locationManager.location else {
                print("Failed to fetch location.")
                task.setTaskCompleted(success: false)
                return
            }
            
            let altitude = location.altitude
            
            // If app storage is enabled, check the altitude; otherwise, ignore altitude
            if !allowTrackingDuringFlight && altitude > 5000 {
                print("Location altitude is too high. Task aborted.")
                task.setTaskCompleted(success: false)
                return
            }
            
            let lat = location.coordinate.latitude
            let lng = location.coordinate.longitude
            
            // Call the API to fetch location information
            openCageVM.fetchLocationInfo(lat: lat, lng: lng) {
                print("Location info fetched")
                
                self.sendLocationNotification(location: location)
                
                // Use fetched data to add an entry to the store
                entryStore.addNewEntryHistory(
                    date: Date(),
                    iso2: openCageVM.info?.results?.first?.components?.iso31661Alpha2 ?? "",
                    iso3: openCageVM.info?.results?.first?.components?.iso31661Alpha3 ?? "",
                    name: openCageVM.info?.results?.first?.components?.country ?? ""
                )
                
                task.setTaskCompleted(success: true)
            }
        })
        
        task.setTaskCompleted(success: true)
    }
swift background background-process bgtaskscheduler
1个回答
0
投票

对你的问题的简短回答是否。 正如 Rob Napier 所提到的,苹果明确禁止应用程序在后台无限期运行,只有少数例外。

鉴于您的用例是跟踪用户在国家/地区之间的旅行,您应该使用 Core Location 的

startMonitoringSignificantLocationChanges
,再次按照 Rob Napier 在评论中的建议。

GPS 非常耗电,保持它“亮着”会很快耗尽用户的电池。重要的位置更改 API 允许系统仅偶尔打开 GPS,并且仅在检测到用户移动了有意义的距离时才调用应用程序的代码,从而限制电量使用。 (文档说,当用户从之前的位置移动 500 米时,您会收到通知,并且您不应该期望比每 5 分钟更频繁地接到电话。我不知道如何将这两件事平方,因为有人乘坐汽车/公共汽车/火车肯定会在 5 分钟内行驶超过 500 米。)

© www.soinside.com 2019 - 2024. All rights reserved.