Skip to content

Instantly share code, notes, and snippets.

@thanhluand
Last active June 8, 2022 18:04
Show Gist options
  • Save thanhluand/bcd74285a82a820c30bce3fced634b50 to your computer and use it in GitHub Desktop.
Save thanhluand/bcd74285a82a820c30bce3fced634b50 to your computer and use it in GitHub Desktop.
Beacon, request location always on IOS > 14
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