mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-31 20:57:41 +00:00
Some checks are pending
Keyman Build Summary / Summarize build status checks (push) Waiting to run
added suite for Settings Container and stubs to test it without accessing disk or user defaults
138 lines
4.7 KiB
Swift
138 lines
4.7 KiB
Swift
/*
|
|
* Keyman is copyright (C) SIL Global. MIT License.
|
|
*
|
|
* Created by Shawn Schantz on 2025-12-10
|
|
*
|
|
* DefaultsRepository is responsible for reading, writing and removing
|
|
* values stored in the UserDefaults
|
|
*
|
|
*/
|
|
|
|
import Foundation
|
|
|
|
public enum UserDefaultsError: Error {
|
|
case unknownSuite
|
|
}
|
|
|
|
public class DefaultsRepository: DefaultsRepo {
|
|
fileprivate let pathUtil: KeymanPaths
|
|
let defaultsSuiteName: String
|
|
let defaults: UserDefaults
|
|
|
|
let kEnabledKeyboardsKey = "KMEnabledKeyboardsKey"
|
|
let kSelectedKeyboardKey = "KMSelectedKeyboardKey"
|
|
let kPersistedOptionsKey = "KMPersistedOptionsKey"
|
|
let kDataModelVersionKey = "KMDataModelVersion"
|
|
let kShowOskOnActivateKey = "KMShowOskOnActivate"
|
|
let kForceSentryErrorKey = "KMForceSentryError"
|
|
|
|
public init(suiteName: String) throws(Error) {
|
|
self.pathUtil = KeymanPaths()
|
|
self.defaultsSuiteName = suiteName
|
|
|
|
// the UserDefaults used are for the app group
|
|
guard let userDefaults = UserDefaults(suiteName: suiteName) else {
|
|
throw(UserDefaultsError.unknownSuite)
|
|
}
|
|
|
|
self.defaults = userDefaults
|
|
}
|
|
|
|
/**
|
|
* get the list of enabled keyboards from the UserDefaults
|
|
* The enabled keyboards are those that are shown in the Keyman menu
|
|
* when it is selected from the System Input Source menu.
|
|
*/
|
|
public func readEnabledKeyboards() -> Set<String> {
|
|
let enabledKeyboardsArray = self.defaults.stringArray(forKey: kEnabledKeyboardsKey) ?? []
|
|
let enabledKeyboardsSet = Set(enabledKeyboardsArray)
|
|
|
|
return enabledKeyboardsSet
|
|
}
|
|
|
|
/**
|
|
* update the list of enabled keyboards in the UserDefaults
|
|
* each String in the array must be formatted `/[packageName]/[keyboardName].kmx`
|
|
*/
|
|
public func writeEnabledKeyboards(enabledKeyboardsArray: [String]) {
|
|
self.defaults.set(enabledKeyboardsArray, forKey: kEnabledKeyboardsKey)
|
|
}
|
|
|
|
/**
|
|
* return the selected keyboard from the UserDefaults
|
|
* The selected keyboard is the one that Keyman is applying for each keydown event.
|
|
*/
|
|
public func readSelectedKeyboard() -> String {
|
|
return self.defaults.string(forKey: kSelectedKeyboardKey) ?? ""
|
|
}
|
|
|
|
/**
|
|
* update the selected keyboard keyboards in the UserDefaults
|
|
* `keyboardName` must be formatted `/[packageName]/[keyboardName].kmx`
|
|
*/
|
|
public func writeSelectedKeyboard(keyboardName: String) {
|
|
self.defaults.set(keyboardName, forKey: kSelectedKeyboardKey)
|
|
}
|
|
|
|
/**
|
|
* read the boolean value that allows a Sentry error to be generated for testing
|
|
* This value is set in the **standard** application UserDefaults -- not the shared app group defaults.
|
|
* This is necessary because it must be set to true from the command line.
|
|
*/
|
|
public func readForceSentryError() -> Bool {
|
|
return UserDefaults.standard.bool(forKey: kShowOskOnActivateKey)
|
|
}
|
|
|
|
/**
|
|
* read the data model version to know what values and format to expect
|
|
*/
|
|
public func readDataModelVersion() -> Int {
|
|
// note that zero is returned if key is not found in UserDefaults,
|
|
return self.defaults.integer(forKey: kDataModelVersionKey)
|
|
}
|
|
|
|
/**
|
|
* read the boolean value that indicates whether the OSK is opened when the input method is activated
|
|
* There may be no need to read this from with the config app.
|
|
*/
|
|
public func readShowOskOnActivate() -> Bool {
|
|
return self.defaults.bool(forKey: kShowOskOnActivateKey)
|
|
}
|
|
|
|
/**
|
|
* read the list of persisted options that are recorded dynamically from the input method
|
|
* There may be no need to read this from with the config app.
|
|
*/
|
|
public func readPersistedOptions() -> Dictionary<String, Any> {
|
|
if let options: Dictionary<String, Any> = self.defaults.dictionary(forKey: kPersistedOptionsKey) {
|
|
return options
|
|
} else {
|
|
return [:]
|
|
}
|
|
}
|
|
|
|
/**
|
|
* for debugging: prints UserDefaults values to the console
|
|
* with app group UserDefaults, there is no way to view from the command line
|
|
* (unlike standard application-level UserDefaults)
|
|
*/
|
|
public func logDefaults() {
|
|
print("UserDefaults:")
|
|
print("\(kSelectedKeyboardKey): \(self.readSelectedKeyboard())")
|
|
print("\(kDataModelVersionKey): \(self.readDataModelVersion())")
|
|
print("\(kForceSentryErrorKey): \(self.readForceSentryError())")
|
|
print("\(kShowOskOnActivateKey): \(self.readShowOskOnActivate())")
|
|
print("\(kEnabledKeyboardsKey): \(self.readEnabledKeyboards())")
|
|
print("\(kPersistedOptionsKey): \(self.readPersistedOptions())")
|
|
}
|
|
|
|
/**
|
|
* for debugging: clear all the entries for the app group UserDefaults
|
|
* unlike standard application-level UserDefaults, there is no way to view from the command line
|
|
*/
|
|
public func clearDefaults() {
|
|
self.defaults.dictionaryRepresentation().keys.forEach { key in
|
|
self.defaults.removeObject(forKey: key)
|
|
}
|
|
}
|
|
}
|