// // Constants.swift // KeymanEngine // // Created by Gabriel Wong on 2017-10-20. // Copyright © 2017 SIL International. All rights reserved. // import Foundation public enum Key { public static let keyboardInfo = "keyboardInfo" public static let lexicalModelInfo = "lexicalModelInfo" /// Array of user keyboards info list in UserDefaults static let userKeyboardsList = "UserKeyboardsList" /// Array of user lexical models info list in UserDefaults static let userLexicalModelsList = "UserLexicalModelsList" /// Dictionary of cached query results for a user's installed packages static let userPackageQueryCacheDict = "UserQueryDistributionStateCache" /// Currently/last selected keyboard info in UserDefaults static let userCurrentKeyboard = "UserCurrentKeyboard" /// Currently/last selected lexical model info in UserDefaults static let userCurrentLexicalModel = "UserCurrentLexicalModel" /// Dictionary of lexical model ids keyed by language id in UserDefaults static let userPreferredLexicalModels = "UserPreferredLexicalModels" /// Dictionary of prediction/correction toggle settings keyed by language id in UserDefaults static let userPredictSettings = "UserPredictionEnablementSettings" static let userCorrectSettings = "UserCorrectionEnablementSettings" // Internal user defaults keys static let engineVersion = "KeymanEngineVersion" static let keyboardPickerDisplayed = "KeyboardPickerDisplayed" static let synchronizeSWKeyboard = "KeymanSynchronizeSWKeyboard" static let synchronizeSWLexicalModel = "KeymanSynchronizeSWLexicalModel" static let migrationLevel = "KeymanEngineMigrationLevel" // JSON keys for language REST calls static let options = "options" static let language = "language" // TODO: Check if it matches with the key in Keyman Cloud API static let keyboardCopyright = "copyright" static let lexicalModelCopyright = "lexicalmodelcopyright" static let languages = "languages" // Other keys static let update = "update" // ResourceDownloadQueue keys static let downloadTask = "downloadTask" static let downloadBatch = "downloadBatch" static let downloadQueueFrame = "queueFrame" // Settings-related keys static let optShouldReportErrors = "ShouldReportErrors" static let optShouldShowBanner = "ShouldShowBanner" static let optSpacebarText = "SpacebarText" // This one SHOULD be app-only, but is needed by the currently // in-engine Settings menus. Alas. static let optShouldShowGetStarted = "ShouldShowGetStarted" } public enum Defaults { private static let font = Font(family: "LatinWeb", source: ["DejaVuSans.ttf"], size: nil) public static let keyboardID = FullKeyboardID(keyboardID: "sil_euro_latin", languageID: "en") public static let lexicalModelID = FullLexicalModelID(lexicalModelID: "nrc.en.mtnt", languageID: "en") public static var keyboardPackage: KeyboardKeymanPackage = { let bundledKMP = Resources.bundle.url(forResource: keyboardID.keyboardID, withExtension: ".kmp")! return try! ResourceFileManager.shared.prepareKMPInstall(from: bundledKMP) as! KeyboardKeymanPackage }() public static let lexicalModelPackage: LexicalModelKeymanPackage = { let bundledKMP = Resources.bundle.url(forResource: lexicalModelID.lexicalModelID, withExtension: ".model.kmp")! return try! ResourceFileManager.shared.prepareKMPInstall(from: bundledKMP) as! LexicalModelKeymanPackage }() // Must be retrieved from their packages! public static let keyboard: InstallableKeyboard = { return keyboardPackage.findResource(withID: keyboardID)! }() public static let lexicalModel: InstallableLexicalModel = { return lexicalModelPackage.findResource(withID: lexicalModelID)! }() } public enum Resources { /// Keyman Web resources public static let bundle: Bundle = { // If we're executing this code, KMEI's framework should already be loaded. Just use that. let frameworkBundle = Bundle(for: Manager.self) //Bundle(identifier: "org.sil.Keyman.ios.Engine")! return Bundle(path: frameworkBundle.path(forResource: "Keyman", ofType: "bundle")!)! }() public static let oskFontFilename = "keymanweb-osk.ttf" static let kmwFilename = "keyboard.html" } public enum Util { /// Is the process of a custom keyboard extension. Avoid using this /// in most situations as Manager.shared.isSystemKeyboard is more /// reliable in situations where in-app and system keyboard can /// be used in the same app, for example using the Web Browser in /// the Keyman app. However, in initialization scenarios this test /// makes sense. public static let isSystemKeyboard: Bool = { let infoDict = Bundle.main.infoDictionary let extensionInfo = infoDict?["NSExtension"] as? [AnyHashable: Any] let extensionID = extensionInfo?["NSExtensionPointIdentifier"] as? String return extensionID == "com.apple.keyboard-service" }() /// The version of the Keyman SDK public static let sdkVersion: String = { return Version.current.plainString }() } public enum FileExtensions { public static let javaScript = "js" public static let trueTypeFont = "ttf" public static let openTypeFont = "otf" public static let configurationProfile = "mobileconfig" } public enum KeymanError: Error, LocalizedError { case unknown // file that is missing, is the file critical? case missingFile(String, Bool) var localizedDescription: String { switch self { case .unknown: return engineBundle.localizedString(forKey: "error-unknown", value: nil, table: nil) case .missingFile(_, let isCritical): if isCritical { return engineBundle.localizedString(forKey: "error-missing-file-critical", value: nil, table: nil) } else { return engineBundle.localizedString(forKey: "error-missing-file", value: nil, table: nil) } } } }