I would like to show on the screen the distance (Unknown, far, near or right here) and the ID of the found beacon. This is my code
struct ContentView: View{
@ObservedObject var detector = BeaconDetector()
var body: some View {
if detector.lastDistance == .immediate {
return Text("RIGHT HERE")
// id here
.modifier(BigText())
.background(Color.green)
.edgesIgnoringSafeArea(.all)
} else if detector.lastDistance == .near {
return Text("NEAR")
.modifier(BigText())
.background(Color.orange)
.edgesIgnoringSafeArea(.all)
} else if detector.lastDistance == .far {
return Text("FAR")
.modifier(BigText())
.background(Color.red)
.edgesIgnoringSafeArea(.all)
} else {
return Text("UNKNOWN")
.modifier(BigText())
.background(Color.gray)
.edgesIgnoringSafeArea(.all)
}
}
}
import Combine
import CoreLocation
import SwiftUI
class BeaconDetector: NSObject, ObservableObject,
CLLocationManagerDelegate{
var didChange = PassthroughSubject<Void, Never>()
var locationManager: CLLocationManager?
var beaconID = UUID().self
@Published var lastDistance = CLProximity.unknown
override init() {
super.init()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
if CLLocationManager.isMonitoringAvailable(for:
CLBeaconRegion.self){
if CLLocationManager.isRangingAvailable(){
startScanning()
}
}
}
}
func startScanning() {
let uuid = UUID(uuidString: "D3D6736B-4C7C-412D-865B-EE61ACF88C61")!
let constraint = CLBeaconIdentityConstraint(uuid: uuid, major: 123,
minor: 456)
let beconRegion = CLBeaconRegion(beaconIdentityConstraint:
constraint, identifier: "MyBeacon")
locationManager?.startMonitoring(for: beconRegion)
locationManager?.startRangingBeacons(satisfying: constraint)
}
func locationManager(_ manager: CLLocationManager, didRange beacons:
[CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) {
if let beacon = beacons.first {
update(distance: beacon.proximity)
} else {
update(distance: .unknown)
}
}
func update(distance: CLProximity) {
lastDistance = distance
didChange.send(())
}
}
struct BigText: ViewModifier {
func body(content: Content) -> some View {
content
.font(Font.system(size: 72, design: .rounded))
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0,
maxHeight: .infinity)
}
}
CodePudding user response:
This is my code, I can see the distance on the screen but I want to add the ID of the beacon found as well. Every time that I add something on the ContentView I have en error: not in scope.
import Combine
import CoreLocation
import SwiftUI
class BeaconDetector: NSObject, ObservableObject,
CLLocationManagerDelegate{
var didChange = PassthroughSubject<Void, Never>()
var locationManager: CLLocationManager?
var beaconID = UUID().self
@Published var lastDistance = CLProximity.unknown
override init() {
super.init()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
if CLLocationManager.isMonitoringAvailable(for:
CLBeaconRegion.self){
if CLLocationManager.isRangingAvailable(){
startScanning()
}
}
}
}
func startScanning() {
let uuid = UUID(uuidString: "D3D6736B-4C7C-412D-865B-EE61ACF88C61")!
let constraint = CLBeaconIdentityConstraint(uuid: uuid, major: 123,
minor: 456)
let beconRegion = CLBeaconRegion(beaconIdentityConstraint:
constraint, identifier: "MyBeacon")
locationManager?.startMonitoring(for: beconRegion)
locationManager?.startRangingBeacons(satisfying: constraint)
}
func locationManager(_ manager: CLLocationManager, didRange beacons:
[CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) {
if let beacon = beacons.first {
update(distance: beacon.proximity)
} else {
update(distance: .unknown)
}
}
func update(distance: CLProximity) {
lastDistance = distance
didChange.send(())
}
}
struct BigText: ViewModifier {
func body(content: Content) -> some View {
content
.font(Font.system(size: 72, design: .rounded))
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0,
maxHeight: .infinity)
}
}
struct ContentView: View{
@ObservedObject var detector = BeaconDetector()
var body: some View {
if detector.lastDistance == .immediate {
return Text("RIGHT HERE")
// I’m trying to add here
.modifier(BigText())
.background(Color.green)
.edgesIgnoringSafeArea(.all)
} else if detector.lastDistance == .near {
return Text("NEAR")
// I’m trying to add here
.modifier(BigText())
.background(Color.orange)
.edgesIgnoringSafeArea(.all)
} else if detector.lastDistance == .far {
return Text("FAR")
// I’m trying to add here
.modifier(BigText())
.background(Color.red)
.edgesIgnoringSafeArea(.all)
} else {
return Text("UNKNOWN")
.modifier(BigText())
.background(Color.gray)
.edgesIgnoringSafeArea(.all)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
CodePudding user response:
Try something like this:
Text("Beacon with major: \(detector.lastMajor) minor: \(detector.lastMinor) is RIGHT HERE")
.modifier(BigText())
.background(Color.green)
.edgesIgnoringSafeArea(.all)
If the BeaconDetector
class has a field for lastMajor and lastMinor you can reference these inside your string to be shown on the screen by escaping the expression inside the string with \()
EDIT: Since the clarified code shows that the major and minor are not fields on BeaconDetector
you will need to add them like this:
@Published var lastMajor: NSNumber? = nil
@Published var lastMinor: NSNumber? = nil
And then you will need to update them when you update the proximity like this:
update(distance: beacon.proximity, major: beacon.major, minor: beacon.minor)
And add these to your update function like this:
func update(distance: CLProximity, major: NSNumber, minor: NSNumber) {
lastDistance = distance
lastMajor = major
lastMinor = minor
didChange.send(())
}