Last active
June 8, 2022 18:04
-
-
Save thanhluand/bcd74285a82a820c30bce3fced634b50 to your computer and use it in GitHub Desktop.
Beacon, request location always on IOS > 14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import CoreLocation | |
import os | |
class BeaconService: NSObject { | |
static let shared = BeaconService() | |
private var locationManager: CLLocationManager = CLLocationManager() | |
var callback: ((_ beacons: [CLBeacon])->())? | |
private var requestLocationAuthorizationCallback: ((CLAuthorizationStatus) -> Void)? | |
override init() { | |
super.init() | |
} | |
func registerIbeacon(uuidString: String, callBack: @escaping ([CLBeacon]) -> ()) { | |
locationManager = CLLocationManager() | |
locationManager.delegate = self | |
let _ = isLocationEnabled() | |
// requestLocationAuthorization() | |
guard let uuid = UUID.init(uuidString: uuidString) else { return } | |
let beaconRegion = CLBeaconRegion(proximityUUID: uuid, identifier: uuidString) | |
beaconRegion.notifyOnEntry = true | |
beaconRegion.notifyOnExit = true | |
startMonitoringIbeacon(beaconRegion: beaconRegion) | |
self.callback = callBack | |
} | |
/// check request of permission has approved | |
/// | |
/// - Returns: result of request of permission has approved if not approved will show alert | |
public func isLocationEnabled()-> Bool { | |
// | |
if CLLocationManager.locationServicesEnabled() { | |
switch(CLLocationManager.authorizationStatus()) { | |
case .notDetermined: | |
locationManager.requestAlwaysAuthorization() | |
return true | |
case .restricted, .denied: | |
locationManager.requestAlwaysAuthorization() | |
return false | |
case .authorizedAlways: // Recomment user choose | |
locationManager.requestAlwaysAuthorization() | |
return true | |
case .authorizedWhenInUse: | |
locationManager.requestAlwaysAuthorization() | |
return true | |
@unknown default: | |
fatalError() | |
} | |
} | |
return false | |
} | |
// request always on ios > 13.4 | |
public func requestLocationAuthorization() { | |
self.locationManager.delegate = self | |
let currentStatus = CLLocationManager.authorizationStatus() | |
// Only ask authorization if it was never asked before | |
guard currentStatus == .notDetermined else { return } | |
// Starting on iOS 13.4.0, to get .authorizedAlways permission, you need to | |
// first ask for WhenInUse permission, then ask for Always permission to | |
// get to a second system alert | |
if #available(iOS 13.4, *) { | |
self.requestLocationAuthorizationCallback = { status in | |
if status == .authorizedWhenInUse { | |
self.locationManager.requestAlwaysAuthorization() | |
} | |
} | |
self.locationManager.requestWhenInUseAuthorization() | |
} else { | |
self.locationManager.requestAlwaysAuthorization() | |
} | |
} | |
func startMonitoringIbeacon(beaconRegion: CLBeaconRegion) { | |
// Logger.log(prefixLog + "startMonitoringIbeacon: \(beaconRegion.proximityUUID)") | |
// locationManager.requestAlwaysAuthorization() | |
beaconRegion.notifyEntryStateOnDisplay = true | |
locationManager.allowsBackgroundLocationUpdates = true | |
locationManager.pausesLocationUpdatesAutomatically = false | |
locationManager.startMonitoring(for: beaconRegion) | |
locationManager.startRangingBeacons(in: beaconRegion) | |
locationManager.startUpdatingLocation() | |
// locationManager | |
} | |
} | |
// MARK: - Location manager | |
extension BeaconService: CLLocationManagerDelegate { | |
func locationManager(_ manager: CLLocationManager, didStartMonitoringFor region: CLRegion) { | |
// Logger.log(prefixLog + "didStartMonitoringFor: \(region)") | |
locationManager.requestState(for: region) | |
} | |
/// Detect BLE when user provide permission authorizedAlways | |
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) { | |
os_log("didDetermineState Beacon") | |
} | |
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { | |
self.requestLocationAuthorizationCallback?(status) | |
// Logger.log("Location did change Authorization status: \(status)") | |
} | |
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { | |
// Logger.log("Location did Enter Region: \(region)") | |
} | |
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) { | |
// Logger.log("Location did Exit Region: \(region)") | |
} | |
/// Detect BLE when user provide permission authorizedWhenInUse | |
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) { | |
self.callback?(beacons) | |
os_log("didRangeBeacons Beacon") | |
} | |
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { | |
// Logger.log(level: .error, "Location Manager Error: didFailWithError \(error)") | |
} | |
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) { | |
// Logger.log(level: .error, "Location Manager Error: monitoringDidFailFor \(error)") | |
} | |
func locationManager(_ manager: CLLocationManager, rangingBeaconsDidFailFor region: CLBeaconRegion, withError error: Error) { | |
// Logger.log(level: .error, "Location Manager error: rangingBeaconsDidFailFor \(error)") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment