Using ObservableDefaults library for settings
This commit is contained in:
parent
6b003990b8
commit
0a6426b7f1
@ -46,7 +46,6 @@
|
||||
7A2E11292CCE395300E5CA17 /* OptionalDatePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2E11282CCE395300E5CA17 /* OptionalDatePicker.swift */; };
|
||||
7A2E6FA72C42B3AD00C40DA7 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */; };
|
||||
7A3399AB299063370087DF98 /* SearchControllerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3399AA299063370087DF98 /* SearchControllerExt.swift */; };
|
||||
7A3E12D72C7B42B700EE710D /* UserDefaults+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3E12D62C7B42B700EE710D /* UserDefaults+Settings.swift */; };
|
||||
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AA24360DC800E59687 /* Dated.swift */; };
|
||||
7A4322912CB2CC8A00085CF6 /* FiltersScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4322902CB2CC8A00085CF6 /* FiltersScreen.swift */; };
|
||||
7A4322932CB2CCAA00085CF6 /* FiltersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4322922CB2CCAA00085CF6 /* FiltersViewModel.swift */; };
|
||||
@ -115,7 +114,9 @@
|
||||
7A761C0B267E8FF90005F28F /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A761C0A267E8FF90005F28F /* Error.swift */; };
|
||||
7A7AA2C42DA2A3CB00276D83 /* LocationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7AA2C32DA2A3CB00276D83 /* LocationError.swift */; };
|
||||
7A7AA2C72DA2A45600276D83 /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 7A7AA2C62DA2A45600276D83 /* RealmSwift */; };
|
||||
7A7AA2C82DA2A45600276D83 /* RealmSwift in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 7A7AA2C62DA2A45600276D83 /* RealmSwift */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
7A7AA2CA2DA2C85100276D83 /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 7A7AA2C92DA2C85100276D83 /* RealmSwift */; };
|
||||
7A7AA2CB2DA2C85100276D83 /* RealmSwift in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 7A7AA2C92DA2C85100276D83 /* RealmSwift */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
7A7AA2CE2DA3120500276D83 /* ObservableDefaults in Frameworks */ = {isa = PBXBuildFile; productRef = 7A7AA2CD2DA3120500276D83 /* ObservableDefaults */; };
|
||||
7A7DADAC2D99738300F52F6C /* AudioRecordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7DADAB2D99738300F52F6C /* AudioRecordView.swift */; };
|
||||
7A809F392D66755B00CF1B3C /* Error+Canceled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A809F382D66755B00CF1B3C /* Error+Canceled.swift */; };
|
||||
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; };
|
||||
@ -254,7 +255,6 @@
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
7A7AA2C82DA2A45600276D83 /* RealmSwift in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -265,6 +265,7 @@
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
7A7AA2CB2DA2C85100276D83 /* RealmSwift in Embed Frameworks */,
|
||||
7AF6D2052677C03B0086EA64 /* AutoCatCore.framework in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
@ -325,7 +326,6 @@
|
||||
7A2E6FA32C42B3AD00C40DA7 /* AutoCatCoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AutoCatCoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7A333813249A532400D878F1 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = "<group>"; };
|
||||
7A3399AA299063370087DF98 /* SearchControllerExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchControllerExt.swift; sourceTree = "<group>"; };
|
||||
7A3E12D62C7B42B700EE710D /* UserDefaults+Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+Settings.swift"; sourceTree = "<group>"; };
|
||||
7A3F07AA24360DC800E59687 /* Dated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dated.swift; sourceTree = "<group>"; };
|
||||
7A4322902CB2CC8A00085CF6 /* FiltersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiltersScreen.swift; sourceTree = "<group>"; };
|
||||
7A4322922CB2CCAA00085CF6 /* FiltersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiltersViewModel.swift; sourceTree = "<group>"; };
|
||||
@ -516,6 +516,7 @@
|
||||
files = (
|
||||
7AA7BC3525A5DFB80053A5D5 /* ExceptionCatcher in Frameworks */,
|
||||
7AA7BC3625A5DFB80053A5D5 /* PKHUD in Frameworks */,
|
||||
7A7AA2CA2DA2C85100276D83 /* RealmSwift in Frameworks */,
|
||||
7AC3554A2969652F00889457 /* SwiftEntryKit in Frameworks */,
|
||||
7ACBB91E2CB9B155005A5168 /* Mockable in Frameworks */,
|
||||
7AF6D2042677C03B0086EA64 /* AutoCatCore.framework in Frameworks */,
|
||||
@ -547,6 +548,7 @@
|
||||
files = (
|
||||
7A7AA2C72DA2A45600276D83 /* RealmSwift in Frameworks */,
|
||||
7AABB1F2267E9CC800D7AB32 /* SwiftDate in Frameworks */,
|
||||
7A7AA2CE2DA3120500276D83 /* ObservableDefaults in Frameworks */,
|
||||
7AF8606E2CB9B86300954D2F /* Mockable in Frameworks */,
|
||||
7A6C4D9E2C56BCA600982597 /* SwiftLocation in Frameworks */,
|
||||
);
|
||||
@ -570,7 +572,6 @@
|
||||
children = (
|
||||
7A06E0B22C707E13005731AC /* SettingsServiceProtocol.swift */,
|
||||
7A06E0B42C707E2B005731AC /* SettingsService.swift */,
|
||||
7A3E12D62C7B42B700EE710D /* UserDefaults+Settings.swift */,
|
||||
);
|
||||
path = SettingsService;
|
||||
sourceTree = "<group>";
|
||||
@ -1238,6 +1239,7 @@
|
||||
7AABDE1C2532F3EB0041AFC6 /* PKHUD */,
|
||||
7AC355492969652F00889457 /* SwiftEntryKit */,
|
||||
7ACBB91D2CB9B155005A5168 /* Mockable */,
|
||||
7A7AA2C92DA2C85100276D83 /* RealmSwift */,
|
||||
);
|
||||
productName = AutoCat;
|
||||
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
|
||||
@ -1312,6 +1314,7 @@
|
||||
7A6C4D9D2C56BCA600982597 /* SwiftLocation */,
|
||||
7AF8606D2CB9B86300954D2F /* Mockable */,
|
||||
7A7AA2C62DA2A45600276D83 /* RealmSwift */,
|
||||
7A7AA2CD2DA3120500276D83 /* ObservableDefaults */,
|
||||
);
|
||||
productName = AutoCatCore;
|
||||
productReference = 7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */;
|
||||
@ -1360,6 +1363,7 @@
|
||||
7A1CF7FD29A41C2F007962DA /* XCRemoteSwiftPackageReference "realm-swift" */,
|
||||
7A6C4D9C2C56BCA600982597 /* XCRemoteSwiftPackageReference "SwiftLocation" */,
|
||||
7ACBB91C2CB9B155005A5168 /* XCRemoteSwiftPackageReference "Mockable" */,
|
||||
7A7AA2CC2DA3120500276D83 /* XCRemoteSwiftPackageReference "ObservableDefaults" */,
|
||||
);
|
||||
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
|
||||
projectDirPath = "";
|
||||
@ -1597,7 +1601,6 @@
|
||||
7AB4E4332D3C21C00006D052 /* FileManagerExt.swift in Sources */,
|
||||
7A9519792D80B3E800E69883 /* AudioRecordService.swift in Sources */,
|
||||
7AB587322C42D38E00FA7B66 /* StorageServiceProtocol.swift in Sources */,
|
||||
7A3E12D72C7B42B700EE710D /* UserDefaults+Settings.swift in Sources */,
|
||||
7AB4E43B2D3D3F4F0006D052 /* VehicleServiceProtocol.swift in Sources */,
|
||||
7AA514E02D0B75B3001CAC50 /* StorageService+Events.swift in Sources */,
|
||||
7A64A2222C19E99E00284124 /* DebugInfoDto.swift in Sources */,
|
||||
@ -2115,6 +2118,14 @@
|
||||
minimumVersion = 6.0.0;
|
||||
};
|
||||
};
|
||||
7A7AA2CC2DA3120500276D83 /* XCRemoteSwiftPackageReference "ObservableDefaults" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/fatbobman/ObservableDefaults";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 0.6.2;
|
||||
};
|
||||
};
|
||||
7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/sindresorhus/ExceptionCatcher";
|
||||
@ -2160,6 +2171,16 @@
|
||||
package = 7A1CF7FD29A41C2F007962DA /* XCRemoteSwiftPackageReference "realm-swift" */;
|
||||
productName = RealmSwift;
|
||||
};
|
||||
7A7AA2C92DA2C85100276D83 /* RealmSwift */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 7A1CF7FD29A41C2F007962DA /* XCRemoteSwiftPackageReference "realm-swift" */;
|
||||
productName = RealmSwift;
|
||||
};
|
||||
7A7AA2CD2DA3120500276D83 /* ObservableDefaults */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 7A7AA2CC2DA3120500276D83 /* XCRemoteSwiftPackageReference "ObservableDefaults" */;
|
||||
productName = ObservableDefaults;
|
||||
};
|
||||
7A813DC02508C4D900CC93B9 /* ExceptionCatcher */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "6fccb9fdc0d29647d4f0b927aef60f375302d72b5b724992eab52ac0d8ec71c3",
|
||||
"originHash" : "3cc3aec63412867029bf57f8fff11744df284387a47994473d82e7aab44a4293",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "exceptioncatcher",
|
||||
@ -19,6 +19,15 @@
|
||||
"version" : "0.3.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "observabledefaults",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/fatbobman/ObservableDefaults",
|
||||
"state" : {
|
||||
"revision" : "4740e2c39043b7daff946aa3bbec22e6a68850d3",
|
||||
"version" : "0.6.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "pkhud",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
||||
@ -38,7 +38,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
let container = ServiceContainer.shared
|
||||
|
||||
let settingsService = SettingsService(defaults: .standard)
|
||||
let settingsService = SettingsService()
|
||||
|
||||
container.register(SettingsServiceProtocol.self, instance: settingsService)
|
||||
|
||||
|
||||
@ -6,21 +6,20 @@
|
||||
// Copyright © 2024 Selim Mustafaev. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
import ObservableDefaults
|
||||
|
||||
@Observable
|
||||
@ObservableDefaults
|
||||
public final class SettingsService: SettingsServiceProtocol {
|
||||
|
||||
let defaults: UserDefaults
|
||||
var observations: [NSKeyValueObservation] = []
|
||||
|
||||
let jsonEncoder = JSONEncoder()
|
||||
let jsonDecoder = JSONDecoder()
|
||||
@Ignore let jsonEncoder = JSONEncoder()
|
||||
@Ignore let jsonDecoder = JSONDecoder()
|
||||
|
||||
@ObservableOnly
|
||||
public var user: User {
|
||||
get {
|
||||
if let data = userData {
|
||||
let result = try? jsonDecoder.decode(User.self, from: data)
|
||||
if userData.count > 0 {
|
||||
let result = try? jsonDecoder.decode(User.self, from: userData)
|
||||
return result ?? User()
|
||||
} else {
|
||||
return User()
|
||||
@ -34,92 +33,20 @@ public final class SettingsService: SettingsServiceProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
public var userData: Data? = nil {
|
||||
didSet {
|
||||
defaults.user = userData
|
||||
}
|
||||
}
|
||||
@DefaultsKey(userDefaultsKey: "user")
|
||||
public var userData: Data = .init()
|
||||
|
||||
public var recognizeAlternativeOrder: Bool = false {
|
||||
didSet {
|
||||
defaults.recognizeAlternativeOrder = recognizeAlternativeOrder
|
||||
}
|
||||
}
|
||||
|
||||
public var recognizeShortenedNumbers: Bool = false {
|
||||
didSet {
|
||||
defaults.recognizeShortenedNumbers = recognizeShortenedNumbers
|
||||
}
|
||||
}
|
||||
|
||||
public var defaultRegion: String = "161" {
|
||||
didSet {
|
||||
defaults.defaultRegion = defaultRegion
|
||||
}
|
||||
}
|
||||
|
||||
public var recordBeep: Bool = false {
|
||||
didSet {
|
||||
defaults.recordBeep = recordBeep
|
||||
}
|
||||
}
|
||||
|
||||
public var showDebugInfo: Bool = false {
|
||||
didSet {
|
||||
defaults.showDebugInfo = showDebugInfo
|
||||
}
|
||||
}
|
||||
public var recognizeAlternativeOrder: Bool = false
|
||||
public var recognizeShortenedNumbers: Bool = false
|
||||
public var defaultRegion: String = "161"
|
||||
public var recordBeep: Bool = false
|
||||
public var showDebugInfo: Bool = false
|
||||
|
||||
@ObservableOnly
|
||||
public var backend: Constants.Backend {
|
||||
get { Constants.Backend(rawValue: backendString) ?? .de }
|
||||
set { backendString = newValue.rawValue }
|
||||
}
|
||||
|
||||
public var backendString: String = Constants.Backend.de.rawValue {
|
||||
didSet {
|
||||
defaults.backendString = backendString
|
||||
}
|
||||
}
|
||||
|
||||
public init(defaults: UserDefaults) {
|
||||
self.defaults = defaults
|
||||
|
||||
observe(key: \.recognizeAlternativeOrder, for: \.recognizeAlternativeOrder)
|
||||
observe(key: \.recognizeShortenedNumbers, for: \.recognizeShortenedNumbers)
|
||||
observe(key: \.defaultRegion, for: \.defaultRegion)
|
||||
observe(key: \.recordBeep, for: \.recordBeep)
|
||||
observe(key: \.showDebugInfo, for: \.showDebugInfo)
|
||||
observe(key: \.backendString, for: \.backendString)
|
||||
observe(key: \.user, for: \.userData)
|
||||
|
||||
register(defaultValues: [
|
||||
.recognizeAlternativeOrder: false,
|
||||
.recognizeShortenedNumbers: false,
|
||||
.defaultRegion: "761",
|
||||
.recordBeep: false,
|
||||
.showDebugInfo: false,
|
||||
.backendString: Constants.Backend.de.rawValue
|
||||
])
|
||||
}
|
||||
|
||||
deinit {
|
||||
observations.forEach { $0.invalidate() }
|
||||
}
|
||||
|
||||
func observe<T>(key userDefaultsKey: KeyPath<UserDefaults,T>, for settingsKey: ReferenceWritableKeyPath<SettingsService,T>) where T: Equatable {
|
||||
let observation = defaults.observe(userDefaultsKey, options: [.initial, .new]) { [weak self] _, change in
|
||||
guard let self else { return }
|
||||
|
||||
if let new = change.newValue, self[keyPath: settingsKey] != new {
|
||||
self[keyPath: settingsKey] = new
|
||||
}
|
||||
}
|
||||
observations.append(observation)
|
||||
}
|
||||
|
||||
func register(defaultValues: [SettingsKey: Any]) {
|
||||
defaults.register(defaults: defaultValues.reduce(into: [:], { (partialResult: inout [String: Any], tuple) in
|
||||
partialResult[tuple.key.rawValue] = tuple.value
|
||||
}))
|
||||
}
|
||||
public var backendString: String = Constants.Backend.de.rawValue
|
||||
}
|
||||
|
||||
@ -1,74 +0,0 @@
|
||||
//
|
||||
// UserDefaults+Settings.swift
|
||||
// AutoCatCore
|
||||
//
|
||||
// Created by Selim Mustafaev on 25.08.2024.
|
||||
// Copyright © 2024 Selim Mustafaev. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SettingsKey: String {
|
||||
|
||||
case user
|
||||
case recognizeAlternativeOrder
|
||||
case recognizeShortenedNumbers
|
||||
case defaultRegion
|
||||
case recordBeep
|
||||
case showDebugInfo
|
||||
case backendString
|
||||
}
|
||||
|
||||
extension UserDefaults {
|
||||
|
||||
func bool(for key: SettingsKey) -> Bool {
|
||||
bool(forKey: key.rawValue)
|
||||
}
|
||||
|
||||
func string(for key: SettingsKey, defaultValue: String = "") -> String {
|
||||
string(forKey: key.rawValue) ?? defaultValue
|
||||
}
|
||||
|
||||
func data(for key: SettingsKey) -> Data? {
|
||||
data(forKey: key.rawValue)
|
||||
}
|
||||
|
||||
func set<T>(value: T, for key: SettingsKey) {
|
||||
setValue(value, forKey: key.rawValue)
|
||||
}
|
||||
|
||||
@objc dynamic var recognizeAlternativeOrder: Bool {
|
||||
get { bool(for: .recognizeAlternativeOrder) }
|
||||
set { set(value: newValue, for: .recognizeAlternativeOrder) }
|
||||
}
|
||||
|
||||
@objc dynamic var recognizeShortenedNumbers: Bool {
|
||||
get { bool(for: .recognizeShortenedNumbers) }
|
||||
set { set(value: newValue, for: .recognizeShortenedNumbers) }
|
||||
}
|
||||
|
||||
@objc dynamic var defaultRegion: String {
|
||||
get { string(for: .defaultRegion) }
|
||||
set { set(value: newValue, for: .defaultRegion) }
|
||||
}
|
||||
|
||||
@objc dynamic var recordBeep: Bool {
|
||||
get { bool(for: .recordBeep) }
|
||||
set { set(value: newValue, for: .recordBeep) }
|
||||
}
|
||||
|
||||
@objc dynamic var showDebugInfo: Bool {
|
||||
get { bool(for: .showDebugInfo) }
|
||||
set { set(value: newValue, for: .showDebugInfo) }
|
||||
}
|
||||
|
||||
@objc dynamic var backendString: String {
|
||||
get { string(for: .backendString, defaultValue: Constants.Backend.de.rawValue) }
|
||||
set { set(value: newValue, for: .backendString) }
|
||||
}
|
||||
|
||||
@objc dynamic var user: Data? {
|
||||
get { data(for: .user) }
|
||||
set { set(value: newValue, for: .user) }
|
||||
}
|
||||
}
|
||||
@ -34,7 +34,7 @@ struct SettingsServiceTests {
|
||||
self.testUser = User(email: testEmail, token: testToken)
|
||||
self.defaults = UserDefaults(suiteName: dbName)!
|
||||
self.defaults.removePersistentDomain(forName: dbName)
|
||||
self.settingsService = SettingsService(defaults: defaults)
|
||||
self.settingsService = SettingsService(userDefaults: self.defaults)
|
||||
}
|
||||
|
||||
@Test("Creating default user")
|
||||
@ -50,7 +50,7 @@ struct SettingsServiceTests {
|
||||
let data = try #require(testUser.data)
|
||||
|
||||
defaults.setPersistentDomain(["user": data], forName: dbName)
|
||||
let service = SettingsService(defaults: defaults)
|
||||
let service = SettingsService(userDefaults: defaults)
|
||||
|
||||
#expect(service.user.email == testEmail)
|
||||
#expect(service.user.token == testToken)
|
||||
@ -73,7 +73,7 @@ struct SettingsServiceTests {
|
||||
|
||||
settingsService.backend = value
|
||||
|
||||
#expect(defaults.string(forKey: SettingsKey.backendString.rawValue) == value.rawValue)
|
||||
#expect(defaults.string(forKey: "backendString") == value.rawValue)
|
||||
}
|
||||
|
||||
@Test("Save settings", .serialized, arguments: [true, false])
|
||||
@ -85,10 +85,10 @@ struct SettingsServiceTests {
|
||||
settingsService.recordBeep = value
|
||||
settingsService.showDebugInfo = value
|
||||
|
||||
#expect(defaults.bool(forKey: SettingsKey.recognizeAlternativeOrder.rawValue) == value)
|
||||
#expect(defaults.bool(forKey: SettingsKey.recognizeShortenedNumbers.rawValue) == value)
|
||||
#expect(defaults.string(forKey: SettingsKey.defaultRegion.rawValue) == testRegion)
|
||||
#expect(defaults.bool(forKey: SettingsKey.recordBeep.rawValue) == value)
|
||||
#expect(defaults.bool(forKey: SettingsKey.showDebugInfo.rawValue) == value)
|
||||
#expect(defaults.bool(forKey: "recognizeAlternativeOrder") == value)
|
||||
#expect(defaults.bool(forKey: "recognizeShortenedNumbers") == value)
|
||||
#expect(defaults.string(forKey: "defaultRegion") == testRegion)
|
||||
#expect(defaults.bool(forKey: "recordBeep") == value)
|
||||
#expect(defaults.bool(forKey: "showDebugInfo") == value)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user