// // UpdateUserLocationTask.swift // Earthquake Network // // Created by Andrea Busi on 16/08/23. // Copyright © 2023 Earthquake Network. All rights reserved. // import Foundation import BackgroundTasks import CoreLocation final class UpdateUserLocationTask: NSObject, BackgroundTaskIdentifiable { static var identifier: String { "com.finazzi.distquake.update_server_position" } static var interval: TimeInterval { 5 * 60 } static let shared = UpdateUserLocationTask() private let debugHelper = EQNBackgroundPositionDebugHelper() // MARK: - Internal private lazy var locationManager: CLLocationManager = { let manager = CLLocationManager() manager.delegate = self manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters manager.allowsBackgroundLocationUpdates = true manager.pausesLocationUpdatesAutomatically = false return manager }() var appTaskCompletion: BackgroundTaskIdentifiable.TaskCompletion? func handle(_ task: BGTask, completion: @escaping (_ success: Bool) -> Void) { self.appTaskCompletion = completion // ricaviamo la posizione corrente dell'utente if let location = locationManager.location { complete(with: location) } else { locationManager.requestLocation() } } func exipration() { locationManager.stopUpdatingLocation() failed() } // MARK: - Private private func complete(with location: CLLocation) { // send position to cloud let url = EQNGeneratoreURLServer.urlPosizione(withLocation: location.coordinate) ServerRequest.default().inviaInformazioniAlServer(with: url, richiesta: .posizione) { result in if self.debugHelper.isEnabled { self.debugHelper.savePosition(coordinate: location.coordinate, requestSuccess: true) } self.appTaskCompletion?(true) } failure: { error in if self.debugHelper.isEnabled { self.debugHelper.savePosition(coordinate: location.coordinate, requestSuccess: false) } self.appTaskCompletion?(false) } } private func failed() { appTaskCompletion?(false) } } extension UpdateUserLocationTask: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.first { complete(with: location) } else { failed() } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("[UpdateUserLocationTask] Location manager failed. Error: \(error.localizedDescription)") // nope, but mandatory failed() } }