Cleaned up onboarding flow

This commit is contained in:
Garth Vander Houwen 2025-07-11 14:13:43 -07:00
parent 536975eff5
commit 964948fb7e
6 changed files with 49 additions and 140 deletions

View file

@ -8108,6 +8108,9 @@
}
}
}
},
"Configure Location Permissions" : {
},
"Configure notification permissions" : {
@ -8611,9 +8614,6 @@
}
}
}
},
"Continue to next step" : {
},
"Control Type" : {
"localizations" : {
@ -12450,9 +12450,6 @@
}
}
}
},
"Enable MQTT" : {
},
"Enable Notifications" : {
"localizations" : {
@ -25664,6 +25661,9 @@
}
}
}
},
"Phone Location" : {
},
"Pin %lld" : {
"localizations" : {
@ -31638,6 +31638,9 @@
}
}
}
},
"Send Notifications" : {
},
"Send Reboot OTA" : {
"localizations" : {
@ -41578,4 +41581,4 @@
}
},
"version" : "1.0"
}
}

View file

@ -201,7 +201,6 @@
DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */; };
DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */; };
DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */; };
DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */; };
DDC4C9FF2A8D982900CE201C /* DetectionSensorConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC4C9FE2A8D982900CE201C /* DetectionSensorConfig.swift */; };
DDC4D568275499A500A4208E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC4D567275499A500A4208E /* Persistence.swift */; };
DDC94FC129CE063B0082EA6E /* BatteryLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC94FC029CE063B0082EA6E /* BatteryLevel.swift */; };
@ -516,7 +515,6 @@
DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
DDC2E16526CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationHelper.swift; sourceTree = "<group>"; };
DDC4C9FE2A8D982900CE201C /* DetectionSensorConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectionSensorConfig.swift; sourceTree = "<group>"; };
DDC4CA012A8DAA3800CE201C /* MeshtasticDataModelV16.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV16.xcdatamodel; sourceTree = "<group>"; };
DDC4D567275499A500A4208E /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
@ -1101,7 +1099,6 @@
DDD43FE12A78C86B0083A3E9 /* Mqtt */,
DDAF8C5226EB1DF10058C060 /* BLEManager.swift */,
DD1BEF492E0292220090CE24 /* KeychainHelper.swift */,
DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */,
DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */,
DDA6B2E828419CF2003E8C16 /* MeshPackets.swift */,
DD964FBC296E6B01007C176F /* EmojiOnlyTextField.swift */,
@ -1430,7 +1427,6 @@
6DEDA55A2A957B8E00321D2E /* DetectionSensorLog.swift in Sources */,
DD798B072915928D005217CD /* ChannelMessageList.swift in Sources */,
231B3F272D0885240069A07D /* MetricsColumnDetail.swift in Sources */,
DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */,
DD77093D2AA1AFA3007A8BF0 /* ChannelTips.swift in Sources */,
6D825E622C34786C008DBEE4 /* CommonRegex.swift in Sources */,
DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */,

View file

@ -1,5 +1,5 @@
{
"originHash" : "a3033aea781828906c453276e3723177901ce64df5757de7ada28c854c9662eb",
"originHash" : "fd71b247ba909b0eb360db5530e1068363839c5e169dea6f6a9974b2d98276f4",
"pins" : [
{
"identity" : "cocoamqtt",
@ -10,6 +10,15 @@
"version" : "2.1.8"
}
},
{
"identity" : "dd-sdk-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/DataDog/dd-sdk-ios.git",
"state" : {
"revision" : "d0a42d8067665cb6ee86af51251ccc071f62bd54",
"version" : "2.29.0"
}
},
{
"identity" : "mqttcocoaasyncsocket",
"kind" : "remoteSourceControl",
@ -19,6 +28,24 @@
"version" : "1.0.8"
}
},
{
"identity" : "opentelemetry-swift-packages",
"kind" : "remoteSourceControl",
"location" : "https://github.com/DataDog/opentelemetry-swift-packages.git",
"state" : {
"revision" : "4a7295600d4ebb9525a23c11586c5fdb74ae8b7e",
"version" : "1.13.1"
}
},
{
"identity" : "plcrashreporter",
"kind" : "remoteSourceControl",
"location" : "https://github.com/microsoft/plcrashreporter.git",
"state" : {
"revision" : "8c61e5e38e9f737dd68512ed1ea5ab081244ad65",
"version" : "1.12.0"
}
},
{
"identity" : "starscream",
"kind" : "remoteSourceControl",

View file

@ -1,76 +0,0 @@
import Foundation
import CoreLocation
import MapKit
import OSLog
class LocationHelper: NSObject, ObservableObject, CLLocationManagerDelegate {
static let shared = LocationHelper()
var locationManager = CLLocationManager()
// @Published var region = MKCoordinateRegion()
@Published var authorizationStatus: CLAuthorizationStatus?
override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.pausesLocationUpdatesAutomatically = true
locationManager.allowsBackgroundLocationUpdates = true
locationManager.activityType = .other
}
// Apple Park
static let DefaultLocation = CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090)
static var currentLocation: CLLocationCoordinate2D {
guard let location = shared.locationManager.location else {
return DefaultLocation
}
return location.coordinate
}
static var satsInView: Int {
// If we have a position we have a sat
var sats = 1
if shared.locationManager.location?.verticalAccuracy ?? 0 > 0 {
sats = 4
if 0...5 ~= shared.locationManager.location?.horizontalAccuracy ?? 0 {
sats = 12
} else if 6...15 ~= shared.locationManager.location?.horizontalAccuracy ?? 0 {
sats = 10
} else if 16...30 ~= shared.locationManager.location?.horizontalAccuracy ?? 0 {
sats = 9
} else if 31...45 ~= shared.locationManager.location?.horizontalAccuracy ?? 0 {
sats = 7
} else if 46...60 ~= shared.locationManager.location?.horizontalAccuracy ?? 0 {
sats = 5
}
} else if shared.locationManager.location?.verticalAccuracy ?? 0 < 0 && 60...300 ~= shared.locationManager.location?.horizontalAccuracy ?? 0 {
sats = 3
} else if shared.locationManager.location?.verticalAccuracy ?? 0 < 0 && shared.locationManager.location?.horizontalAccuracy ?? 0 > 300 {
sats = 2
}
return sats
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedAlways:
authorizationStatus = .authorizedAlways
case .authorizedWhenInUse:
authorizationStatus = .authorizedWhenInUse
locationManager.requestLocation()
case .restricted:
authorizationStatus = .restricted
case .denied:
authorizationStatus = .denied
case .notDetermined:
authorizationStatus = .notDetermined
locationManager.requestAlwaysAuthorization()
default:
break
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
Logger.services.error("Location manager error: \(error.localizedDescription, privacy: .public)")
}
}

View file

@ -57,7 +57,7 @@ import OSLog
func startLocationUpdates() {
if self.manager.authorizationStatus == .notDetermined {
self.manager.requestWhenInUseAuthorization()
// self.manager.requestWhenInUseAuthorization()
}
let status = self.manager.authorizationStatus
guard status == .authorizedAlways || status == .authorizedWhenInUse else {

View file

@ -8,7 +8,6 @@ struct DeviceOnboarding: View {
enum SetupGuide: Hashable {
case notifications
case location
case mqtt
}
@State var navigationPath: [SetupGuide] = []
@ -170,54 +169,22 @@ struct DeviceOnboarding: View {
}
.padding()
Spacer()
if LocationHelper.shared.locationManager.authorizationStatus != .notDetermined {
Button {
Task {
await goToNextStep(after: .location)
}
} label: {
Text("Continue to next step")
.frame(maxWidth: .infinity)
}
.padding()
.buttonBorderShape(.capsule)
.controlSize(.large)
.padding()
.buttonStyle(.borderedProminent)
}
}
}
var mqttView: some View {
VStack {
VStack {
Text("MQTT")
.font(.largeTitle.bold())
.multilineTextAlignment(.center)
.fixedSize(horizontal: false, vertical: true)
}
Spacer()
Button {
Task {
let status = await LocationsHandler.shared.requestLocationAlwaysPermissions()
if status != .notDetermined {
dismiss()
}
}
} label: {
Text("Enable MQTT")
Text("Configure Location Permissions")
.frame(maxWidth: .infinity)
}
.padding()
.padding()
.buttonBorderShape(.capsule)
.controlSize(.large)
.padding()
.buttonStyle(.borderedProminent)
Button {
dismiss()
} label: {
Text("Set up later")
.frame(maxWidth: .infinity)
}
}
}
@ -230,8 +197,6 @@ struct DeviceOnboarding: View {
notificationView
case .location:
locationView
case .mqtt:
mqttView
}
}
}
@ -279,27 +244,21 @@ struct DeviceOnboarding: View {
fallthrough
}
case .notifications:
let status = LocationHelper.shared.locationManager.authorizationStatus
if status == .notDetermined {
let status = LocationsHandler.shared.manager.authorizationStatus
if status == .notDetermined || status == .restricted || status == .denied {
navigationPath.append(.location)
let newStatus = await LocationsHandler.shared.manager.requestAlwaysAuthorization()
} else {
fallthrough
}
case .location:
if true {
navigationPath.append(.mqtt)
} else {
fallthrough
let status = LocationsHandler.shared.manager.authorizationStatus
if status != .notDetermined && status != .restricted && status != .denied {
dismiss()
}
case .mqtt:
dismiss()
}
}
// MARK: Permission Checks
func requestNotificationsPermissions() async {
let center = UNUserNotificationCenter.current()
do {