1 contributor
//
// CBManagerState.swift
// USB Meter
//
// Created by Bogdan Timofte on 02/03/2020.
// Copyright © 2020 Bogdan Timofte. All rights reserved.
//
//import Foundation
import CoreBluetooth
import SwiftUI
//Manager States
//.poweredOff A state that indicates Bluetooth is currently powered off.
//.poweredOn A state that indicates Bluetooth is currently powered on and available to use.
//.resetting A state that indicates the connection with the system service was momentarily lost.
//.unauthorized A state that indicates the application isn’t authorized to use the Bluetooth low energy role.
//.unknown The manager’s state is unknown.
//.unsupported A state that indicates this device doesn’t support the Bluetooth low energy central or client role.
extension CBManagerState {
var description: String {
switch self {
case .poweredOff:
return "CBManagerState.poweredOff"
case .poweredOn:
return "CBManagerState.poweredOn"
case .resetting:
return "CBManagerState.resetting"
case .unauthorized:
return "CBManagerState.unauthorized"
case .unknown:
return "CBManagerState.unknown"
case .unsupported:
return "CBManagerState.unsupported"
default:
return "CBManagerState.other"
}
}
var color: Color {
switch self {
case .poweredOff:
return Color.red
case .poweredOn:
return Color.blue
case .resetting:
return Color.green
case .unauthorized:
return Color.orange
case .unknown:
return Color.secondary
case .unsupported:
return Color.gray
default:
return Color.yellow
}
}
var helpView: AnyView {
switch self {
case .poweredOff:
return AnyView(poweredOffHelperView())
case .poweredOn:
return AnyView(poweredOnHelperView())
case .resetting:
return AnyView(resettingHelperView())
case .unauthorized:
return AnyView(unauthorizedHelperView())
case .unknown:
return AnyView(unknownHelperView())
case .unsupported:
return AnyView(unsupportedHelperView())
default:
return AnyView(defaultHelperView())
}
}
private struct poweredOffHelperView: View {
var body: some View {
BluetoothHelpCard(
title: "Bluetooth Off",
detail: "Bluetooth is turned off on this device. You can enable it in Settings > Bluetooth.",
tint: .red
)
}
}
private struct poweredOnHelperView: View {
var body: some View {
BluetoothHelpCard(
title: "Bluetooth Ready",
detail: "Bluetooth is powered on and ready for scanning.",
tint: .blue
)
}
}
private struct resettingHelperView: View {
var body: some View {
BluetoothHelpCard(
title: "Bluetooth Resetting",
detail: "The Bluetooth stack is temporarily resetting. Wait a moment and try again.",
tint: .green
)
}
}
private struct unauthorizedHelperView: View {
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Bluetooth Access Needed")
.font(.headline)
Text("This application does not have permission to access Bluetooth. You can enable it in Settings.")
.font(.footnote)
.foregroundColor(.secondary)
Button(action: { UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil) }) {
Text("Settings")
}
.padding(.horizontal, 14)
.padding(.vertical, 10)
.meterCard(tint: .orange, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
.buttonStyle(.plain)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(20)
.meterCard(tint: .orange, fillOpacity: 0.18, strokeOpacity: 0.24)
.padding()
}
}
private struct unknownHelperView: View {
var body: some View {
BluetoothHelpCard(
title: "Unknown Bluetooth State",
detail: "Bluetooth is reporting an unknown state. Wait a moment and check again.",
tint: .secondary
)
}
}
private struct unsupportedHelperView: View {
var body: some View {
BluetoothHelpCard(
title: "Bluetooth Unsupported",
detail: "This device does not support the Bluetooth capabilities required by these USB meters.",
tint: .gray
)
}
}
private struct defaultHelperView: View {
var body: some View {
BluetoothHelpCard(
title: "Other Bluetooth State",
detail: "Bluetooth is in an unexpected state. Try again, then contact the developer if it persists.",
tint: .yellow
)
}
}
private struct BluetoothHelpCard: View {
let title: String
let detail: String
let tint: Color
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 10) {
Text(title)
.font(.system(.title3, design: .rounded).weight(.bold))
Text(detail)
.font(.footnote)
.foregroundColor(.secondary)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(20)
.meterCard(tint: tint, fillOpacity: 0.18, strokeOpacity: 0.24)
.padding()
}
.background(
LinearGradient(
colors: [tint.opacity(0.14), Color.clear],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
.ignoresSafeArea()
)
}
}
}