i need ur help! i do an app and i need said that the "minorBeacon" do a global variable, because in other ViewController i will called. but i can't and the other problem is convert this data to "Int"
func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
if let beacon = beacons.first {
var minorBeacon : Int = beacon.minor
print(minorBeacon)
}
the problem says
"cannot convert value type "NSNumber" to specified type "Int" " help me please!!
Thanks Guys ! :)
You can user intValue to get the NSNumber's value as a Swift Int:
func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
if let beacon = beacons.first {
var minorBeacon = beacon.minor.intValue
print(minorBeacon)
}
Related
It's pretty frustrating to not being able to retrieve identifier from CLBeaconRegion. Here's a simplified example:
let beaconRegion = CLBeaconRegion(uuid: UUID(uuidString: "E2C56DB5-DFFB-48D2-B060-D0F5A71096E0")!, major: 111, minor: 222, identifier: "NewBeacon")
locationManager?.startMonitoring(for: beaconRegion)
locationManager?.startRangingBeacons(in: beaconRegion)
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
if let beacon = beacons.first {
print(beacon.identifier) //that
}
}
Is there a way to get "NewBeacon" identifier?
The identifier is associated with the region, you can simply access region.identifier
is it possible to use GPS with iBeacon when app is in background?
I need to start update gps location when iPhone detect iBeacon only through 180s, I do something like this but it doesn't work :/
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
if !isInForeground {
extendBackgroundTime()
}
print(wasBeaconDetected)
for beacon in beacons {
if beacon.rssi < -10 {
wasBeaconDetected = true
nearbyBeacons.append(beacon)
}
}
print(beacons)
currentLocation = manager.location!.coordinate
if firstRegionDetected == "" {
firstRegionDetected = region.identifier
} else if firstRegionDetected == region.identifier {
analyzeScan(nearbyBeacons, currentLocation)
}
}
of course I start monitoring when determine State
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
if isInBackground {
extendBackgroundTime()
}
}
My question is very simple. I would like to display an error message i.e. "Cannot find iBeacon" if iBeacon monitoring fails, after calling startSearchingForSessions via a button press after being called in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
if self.locationManager.responds(to: #selector(CLLocationManager.requestWhenInUseAuthorization)) {
self.locationManager.requestWhenInUseAuthorization()
}
self.locationManager.delegate = self
self.locationManager.pausesLocationUpdatesAutomatically = false
let uuid = UUID(uuidString: "869A6E2E-AE14-4CF5-8313-8D6976058A7A")
self.beaconRegion = CLBeaconRegion(proximityUUID: uuid!, identifier: "com.dejordan.myapp"
startSearchingForSessions()
}
func startSearchingForSessions() {
// Start looking for the beacons with that UUID and Identifier.
self.locationManager.startMonitoring(for: self.beaconRegion)
self.locationManager.startRangingBeacons(in: self.beaconRegion)
self.locationManager.startUpdatingLocation()
}
And handling the found beacons thusly:
// Required by the Location Manager.
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
self.locationManager.startRangingBeacons(in: self.beaconRegion)
}
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
if state == CLRegionState.outside {
print("Cannot Find Beacon")
}
}
// Required by the Location Manager.
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
self.locationManager.stopRangingBeacons(in: self.beaconRegion)
}
// This is called if any beacons are found.
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
var result = Array<CLBeacon>()
for beacon in beacons {
result.append(beacon)
}
foundBeacons = result
// If we found any, we need to see
// what class they belong to based on information
// from Parse.
self.identifyFoundBeacons()
// We can stop looking for beacons now.
self.locationManager.stopMonitoring(for: self.beaconRegion)
self.locationManager.stopRangingBeacons(in: self.beaconRegion)
self.locationManager.stopUpdatingLocation()
}
I have implemented the delegate error methods in an attempt to find where this occurs but thus far in navigating the mounds of documentation on iBeacon I have come up fruitless.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location manager failed: \(error.localizedDescription)")
}
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
print("Failed monitoring region: \(error.localizedDescription)")
}
Thank you!
If you simply want to know when beacons are not detected (vs. when there was a low-level failure to look for beacons), then simply use the following delegate method:
public func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
if state == CLRegionState.outside {
print("Cannot find beacon")
}
}
Interestingly enough, didRangeBeacons in the delegate method
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)
gets called with an empty array of [CLBeacon]s, wherein I can use the beacons array size to determine whether or not any beacons were found.
Not what I expected, but this has solved my problem!
I range beacons and display them in my TableView. I need to detect when my app detects a new beacon. I try to do it in this way, but something goes wrong
var oldBeacons: [CLBeacon] = []
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
for beacon in beacons {
for oldBeacon in oldBeacons {
if beacon.minor != oldBeacon.minor, beacon.major != oldBeacon.major {
print("New Beacon")
} else {
print("Old Beacon")
}
}
}
oldBeacons = beacons
}
Iterating through two arrays won't easily work because if you ever see two beacons at the same time, you'll incorrectly think they are "new" because one is not the same as the other.
I typically use a Set to do this:
var detectedBeacons: Set<String>
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
for beacon in beacons {
let key = "\(beacon.proximityUUID) \(beacon.major) \(beacon.minor)"
if detectedBeacons.contains(key) {
print("Old Beacon")
}
else {
print("New Beacon")
detectedBeacons.insert(key)
}
}
}
I had did beacon searching code as per Kontakt SDK Sample code as below. But I am getting beacon count always 0, while I am having 11 beacons near by my iPhone. Can any body help me over this?
I have initialise KTKBeaconManager in viewDidLoad method and then create region object and stopped any previous ranging service and then started new monitoring and ranging services.
And all time it calls didRangeBeacons with beacons count = 0. Not sure what exactly the issue. Its same code from their example code.
import UIKit
import KontaktSDK
class ViewController: UIViewController {
var beaconManager: KTKBeaconManager!
#IBOutlet var statusLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Initiate Beacon Manager
beaconManager = KTKBeaconManager(delegate: self)
beaconManager.requestLocationAlwaysAuthorization()
// Region
let proximityUUID = NSUUID(uuidString: "f7826da6-4fa2-4e98-8024-bc5b71e0893e")
let region = KTKBeaconRegion(proximityUUID: proximityUUID! as UUID, identifier: "com.weenggs.KontaktDemo")
// Region Properties
region.notifyEntryStateOnDisplay = true
beaconManager.stopMonitoringForAllRegions()
// Start Ranging
beaconManager.startMonitoring(for: region)
beaconManager.startRangingBeacons(in: region)
beaconManager.requestState(for: region)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController: KTKBeaconManagerDelegate {
func beaconManager(_ manager: KTKBeaconManager, didDetermineState state: CLRegionState, for region: KTKBeaconRegion) {
print("Did determine state \"\(state.rawValue)\" for region: \(region)")
statusLabel.text = "Did determine state \"\(state.rawValue)\" for region: \(region)"
}
func beaconManager(_ manager: KTKBeaconManager, didChangeLocationAuthorizationStatus status: CLAuthorizationStatus) {
print("Did change location authorization status to: \(status.rawValue)")
statusLabel.text = "Did change location authorization status to: \(status.rawValue)"
if status == .authorizedAlways{
// Region
let proximityUUID = NSUUID(uuidString: "f7826da6-4fa2-4e98-8024-bc5b71e0893e")
let region = KTKBeaconRegion(proximityUUID: proximityUUID! as UUID, identifier: "com.weenggs.KontaktDemo")
// Region Properties
region.notifyEntryStateOnDisplay = true
beaconManager.startMonitoring(for: region)
beaconManager.startRangingBeacons(in: region)
beaconManager.requestState(for: region)
}
}
func beaconManager(_ manager: KTKBeaconManager, monitoringDidFailFor region: KTKBeaconRegion?, withError error: Error?) {
print("Monitoring did fail for region: \(region)")
print("Error: \(error)")
statusLabel.text = "Monitoring did fail for region: \(region)"
}
func beaconManager(_ manager: KTKBeaconManager, didStartMonitoringFor region: KTKBeaconRegion) {
print("Did start monitoring for region: \(region)")
statusLabel.text = "Did start monitoring for region: \(region)"
}
func beaconManager(_ manager: KTKBeaconManager, didEnter region: KTKBeaconRegion) {
print("Did enter region: \(region)")
statusLabel.text = "Did enter region: \(region)"
}
func beaconManager(_ manager: KTKBeaconManager, didExitRegion region: KTKBeaconRegion) {
print("Did exit region \(region)")
statusLabel.text = "Did exit region \(region)"
}
func beaconManager(_ manager: KTKBeaconManager, didRangeBeacons beacons: [CLBeacon], in region: KTKBeaconRegion) {
print("Did ranged \"\(beacons.count)\" beacons inside region: \(region)")
statusLabel.text = "Did ranged \"\(beacons.count)\" beacons inside region: \(region)"
if let closestBeacon = beacons.sorted(by: { $0.0.accuracy < $0.1.accuracy }).first , closestBeacon.accuracy > 0 {
print("Closest Beacon is M: \(closestBeacon.major), m: \(closestBeacon.minor) ~ \(closestBeacon.accuracy) meters away.")
statusLabel.text = "\(statusLabel.text) Closest Beacon is M: \(closestBeacon.major), m: \(closestBeacon.minor) ~ \(closestBeacon.accuracy) meters away."
}
}
}
I reckon the common issue is that you forgot to set
Kontakt.setAPIKey("yourSuperSecretAPIKey")
and either one of those two permissions
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
If it's not the case then your beacons' batteries could be drained out.
Finally I was able to detect beacons using CBPeripheral class and identify uniquely based on received UUID with instance id( last 12 characters are instance id which are unique)