SDBeaconScanner is a Swift library for scanning Bluetooth beacons using CoreLocation's beacon ranging API. It simplifies scanning for beacons by providing an easy-to-use API with support for UUID, major, and minor identifiers. Additionally, the scanner allows you to specify a timeout for the scan and handles beacon detection results through completion handlers.
- Beacon Scanning: Scan for nearby Bluetooth beacons by UUID, with optional major and minor values.
- Customizable Timeout: Specify a custom timeout for the scan to avoid indefinite scanning.
- Completion Handlers: Results are returned via completion handlers, making it easy to integrate with your existing app logic.
- Error Handling: Provides detailed errors, including invalid UUID, unavailable ranging, and generic errors via NSError.
- iOS 13.0+
- Swift 5.0+
CoreLocation
framework
Add SDBeaconScanner to your project using Swift Package Manager:
- Open your Xcode project.
- Select File > Add Packages.
- Paste the repository URL in the search field:
https://github.com/SagarSDagdu/SDBeaconScanner.git
- Choose the package and add it to your project.
You can manually copy the files under Sources/SDBeaconScanner
to your project.
Ensure that your app includes the necessary permissions in Info.plist
to use location services:
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to scan for beacons.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>We need your location to scan for beacons even when the app is in the background.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need your location to scan for beacons.</string>
To enable scanning for beacons while your app is in the background, ensure that your app has the correct background modes enabled in Info.plist:
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
import SDBeaconScanner
SDBeaconScanner is designed as a singleton, so you can directly access the shared instance:
let beaconScanner = SDBeaconScanner.shared
To start scanning for beacons, you can use either of the following methods depending on whether you want to scan by UUID only or include major and minor values.
beaconScanner.getNearbyBeacons(uuid: "your-uuid") { scanResult in
switch scanResult {
case let .success(beacons):
print("Got \(beacons.count) beacons")
case let .failure(scanError):
print("Error: \(scanError)")
}
}
beaconScanner.getNearbyBeacons(uuid: "your-uuid", major: 123, minor: 456) { scanResult in
switch scanResult {
case let .success(beacons):
print("Got \(beacons.count) beacons")
case let .failure(scanError):
print("Error: \(scanError)")
}
}
You can specify a custom timeout duration (in seconds) for the scan. The scan will automatically stop once the timeout is reached or once beacons are found.
beaconScanner.getNearbyBeacons(uuid: "your-uuid", timeout: 10.0) { scanResult in
switch scanResult {
case let .success(beacons):
print("Got \(beacons.count) beacons")
case let .failure(scanError):
print("Error: \(scanError)")
}
}
The BeaconScanningCompletion
typealias is used for handling the results of a scan. You can check for errors and handle the returned beacons in the completion handler.
SDBeaconScanner provides detailed error handling through the BeaconScannerError
enum. The following errors are reported:
invalidUUID
: Indicates that the provided UUID is not valid.rangingUnavailable
: Indicates that the device does not support ranging.rangingFailed(NSError)
: A generic error that reports anNSError
object, typically triggered by internal location manager issues.
Example usage:
switch error {
case .invalidUUID:
print("The UUID provided is invalid.")
case .rangingUnavailable:
print("Ranging is unavailable on this device.")
case .rangingFailed(let nsError):
print("Ranging failed with error: \(nsError.localizedDescription)")
}
You can find a simple example project in the Example directory. The example demonstrates how to scan for beacons using SDBeaconScanner
.
SDBeaconScanner is licensed under the MIT License. See the LICENSE file for more details.