Meshtastic-Apple/Meshtastic/Extensions/UserDefaults.swift
Garth Vander Houwen 40b28b7523
Alternate App icons (#1359)
* Add AppIcon_Dev

Adds a blue developer icon to help tell the dev app apart from the release app.

* Add AppIconPicker and a couple icons

Added a developer icon and an icon representing MSP Mesh

* Dismiss icon picker when icon changes

* Add icon to icon picker menu item

* Replace local mesh icons with Chirpy and add Testflight icon

* AppIconButton shows dark icon when in dark mode

* Update plist to match main

* Only show revelvant icons

* Remove testflight images

* Debug app icon in blue

---------

Co-authored-by: Chase Lau <chase9@mac.com>
2025-08-28 22:54:17 -07:00

187 lines
5.1 KiB
Swift

//
// UserDefaults.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 4/24/23.
//
import Foundation
@propertyWrapper
struct UserDefault<T: Decodable> {
let key: UserDefaults.Keys
let defaultValue: T
init(_ key: UserDefaults.Keys, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
if defaultValue is any RawRepresentable {
let storedValue = UserDefaults.standard.object(forKey: key.rawValue)
guard let storedValue,
let jsonString = (storedValue is String) ? "\"\(storedValue)\"" : "\(storedValue)",
let data = jsonString.data(using: .utf8),
let value = (try? JSONDecoder().decode(T.self, from: data)) else { return defaultValue }
return value
}
return UserDefaults.standard.object(forKey: key.rawValue) as? T ?? defaultValue
}
set {
UserDefaults.standard.set((newValue as? any RawRepresentable)?.rawValue ?? newValue, forKey: key.rawValue)
}
}
}
extension UserDefaults {
enum Keys: String, CaseIterable {
case preferredPeripheralId
case preferredPeripheralNum
case provideLocation
case provideLocationInterval
case mapLayer
case meshMapDistance
case enableMapWaypoints
case meshMapRecentering
case meshMapShowNodeHistory
case meshMapShowRouteLines
case enableMapConvexHull
case enableMapRecentering
case enableMapNodeHistoryPins
case enableMapRouteLines
case enableMapTraffic
case enableMapPointsOfInterest
case enableOfflineMaps
case enableMapShowFavorites
case mapTileServer
case enableOverlayServer
case mapOverlayServer
case mapTilesAboveLabels
case mapUseLegacy
case enableDetectionNotifications
case detectionSensorRole
case enableSmartPosition
case newNodeNotifications
case lowBatteryNotifications
case channelMessageNotifications
case modemPreset
case firmwareVersion
case hardwareModel
case environmentEnableWeatherKit
case enableAdministration
case mapReportingOptIn
case firstLaunch
case showDeviceOnboarding
case usageDataAndCrashReporting
case autoconnectOnDiscovery
case testIntEnum
}
func reset() {
Keys.allCases.forEach { removeObject(forKey: $0.rawValue) }
}
@UserDefault(.preferredPeripheralId, defaultValue: "")
static var preferredPeripheralId: String
@UserDefault(.preferredPeripheralNum, defaultValue: 0)
static var preferredPeripheralNum: Int
@UserDefault(.provideLocation, defaultValue: false)
static var provideLocation: Bool
@UserDefault(.provideLocationInterval, defaultValue: 30)
static var provideLocationInterval: Int
@UserDefault(.mapLayer, defaultValue: .standard)
static var mapLayer: MapLayer
@UserDefault(.meshMapDistance, defaultValue: 800000)
static var meshMapDistance: Double
@UserDefault(.enableMapWaypoints, defaultValue: true)
static var enableMapWaypoints: Bool
@UserDefault(.enableMapRecentering, defaultValue: false)
static var enableMapRecentering: Bool
@UserDefault(.enableMapNodeHistoryPins, defaultValue: false)
static var enableMapNodeHistoryPins: Bool
@UserDefault(.enableMapRouteLines, defaultValue: false)
static var enableMapRouteLines: Bool
@UserDefault(.enableMapConvexHull, defaultValue: false)
static var enableMapConvexHull: Bool
@UserDefault(.enableMapTraffic, defaultValue: false)
static var enableMapTraffic: Bool
@UserDefault(.enableMapPointsOfInterest, defaultValue: false)
static var enableMapPointsOfInterest: Bool
@UserDefault(.enableMapShowFavorites, defaultValue: false)
static var enableMapShowFavorites: Bool
@UserDefault(.enableDetectionNotifications, defaultValue: false)
static var enableDetectionNotifications: Bool
@UserDefault(.detectionSensorRole, defaultValue: .sensor)
static var detectionSensorRole: DetectionSensorRole
@UserDefault(.enableSmartPosition, defaultValue: false)
static var enableSmartPosition: Bool
@UserDefault(.channelMessageNotifications, defaultValue: true)
static var channelMessageNotifications: Bool
@UserDefault(.newNodeNotifications, defaultValue: true)
static var newNodeNotifications: Bool
@UserDefault(.lowBatteryNotifications, defaultValue: true)
static var lowBatteryNotifications: Bool
@UserDefault(.modemPreset, defaultValue: 0)
static var modemPreset: Int
@UserDefault(.firmwareVersion, defaultValue: "0.0.0")
static var firmwareVersion: String
@UserDefault(.hardwareModel, defaultValue: "Unset")
static var hardwareModel: String
@UserDefault(.environmentEnableWeatherKit, defaultValue: true)
static var environmentEnableWeatherKit: Bool
@UserDefault(.enableAdministration, defaultValue: false)
static var enableAdministration: Bool
@UserDefault(.mapReportingOptIn, defaultValue: false)
static var mapReportingOptIn: Bool
@UserDefault(.usageDataAndCrashReporting, defaultValue: true)
static var usageDataAndCrashReporting: Bool
@UserDefault(.firstLaunch, defaultValue: true)
static var firstLaunch: Bool
@UserDefault(.showDeviceOnboarding, defaultValue: false)
static var showDeviceOnboarding: Bool
@UserDefault(.autoconnectOnDiscovery, defaultValue: true)
static var autoconnectOnDiscovery: Bool
@UserDefault(.testIntEnum, defaultValue: .one)
static var testIntEnum: TestIntEnum
}
enum TestIntEnum: Int, Decodable {
case one = 1
case two
case three
}