mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-26 09:37:40 +00:00
feat(mac): check settings state and version
This commit is contained in:
parent
6a69097e1d
commit
85adbea99e
4 changed files with 102 additions and 60 deletions
|
|
@ -788,18 +788,27 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
|
|||
* namely, the keyboard data on disk and the settings in UserDefaults
|
||||
*/
|
||||
- (void)prepareStorage {
|
||||
os_log_debug([KMLogs dataLog], "*** prepareStorage ***");
|
||||
SettingsState state = [KMSettingsRepository.shared determineSettingsState];
|
||||
|
||||
// if necessary, migrate settings and keyboard data for compatibility with Keyman 19
|
||||
if ([KMSettingsRepository.shared keyman19SettingsMigrationNeeded]) {
|
||||
[KMDataRepository.shared migrateDataForKeyman19];
|
||||
[KMSettingsRepository.shared migrateSettingsForKeyman19];
|
||||
switch (state) {
|
||||
case KeymanSettingsVersion17:
|
||||
os_log_info([KMLogs dataLog], "prepareStorage, migration needed for Keyman 17 to current");
|
||||
break;
|
||||
case KeymanSettingsVersion18:
|
||||
os_log_info([KMLogs dataLog], "prepareStorage, migration needed for Keyman 18 to current");
|
||||
[KMDataRepository.shared migrateDataForKeyman19];
|
||||
[KMSettingsRepository.shared migrateSettingsForKeyman19];
|
||||
break;
|
||||
case KeymanSettingsNotFound:
|
||||
os_log_info([KMLogs dataLog], "prepareStorage, settings not found, create them");
|
||||
[KMDataRepository.shared createKeyman19SharedDirectoriesIfNecessary];
|
||||
[KMSettingsRepository.shared createKeyman19SharedSettingsIfNecessary];
|
||||
// MAC-CONFIG-TODO: are settings created for fresh install?
|
||||
break;
|
||||
case KeymanSettingsVersionCurrent:
|
||||
os_log_info([KMLogs dataLog], "prepareStorage: settings are current, no migration needed");
|
||||
break;
|
||||
}
|
||||
|
||||
// if this is a fresh install, then create the shared directories
|
||||
[KMDataRepository.shared createKeyman19SharedDirectoriesIfNecessary];
|
||||
|
||||
// MAC-CONFIG-TODO: are settings created for fresh install?
|
||||
}
|
||||
|
||||
- (void)setDefaultKeymanMenuItems {
|
||||
|
|
|
|||
|
|
@ -12,13 +12,22 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// for classifying the state of the settings (UserDefaults) and data
|
||||
// used for determining whether migration is needed of the UserDefaults and Keyman packages
|
||||
// to a new format and/or location
|
||||
typedef NS_ENUM(NSInteger, SettingsState) {
|
||||
KeymanSettingsNotFound = 0,
|
||||
KeymanSettingsVersion17 = 17,
|
||||
KeymanSettingsVersion18 = 18,
|
||||
KeymanSettingsVersionCurrent = 19
|
||||
};
|
||||
|
||||
@interface KMSettingsRepository : NSObject
|
||||
+ (KMSettingsRepository *)shared;
|
||||
- (instancetype)init;
|
||||
- (BOOL)keyman18DataMigrationNeeded;
|
||||
- (BOOL)keyman19SettingsMigrationNeeded;
|
||||
- (SettingsState)determineSettingsState;
|
||||
- (void)createKeyman19SharedSettingsIfNecessary;
|
||||
- (void)migrateSettingsForKeyman18;
|
||||
- (void)setDataModelVersionIfNecessary;
|
||||
- (void)migrateSettingsForKeyman19;
|
||||
- (BOOL)migrateInputMethodSettingsToAppGroup;
|
||||
- (NSString *)readSelectedKeyboard;
|
||||
|
|
|
|||
|
|
@ -89,53 +89,53 @@ NSInteger const kCurrentDataModelVersionNumber = kVersionStoreDataInGroupContain
|
|||
return self;
|
||||
}
|
||||
|
||||
// MAC-CONFIG-TODO: add support for migration from Keyman 18 and earlier to Keyman 19
|
||||
|
||||
/**
|
||||
* Determines whether the keyboard data needs to be moved from pre-Keyman-18 location to the Keyman 18 location
|
||||
* This is true if
|
||||
* 1) the UserDefaults exist (indicating that this is not a new installation of Keyman) and
|
||||
* 2) the value for kVersionStoreDataInLibraryDirectory is < 1,
|
||||
* Determines the current state of the Keyman settings (UserDefaults), indicating
|
||||
* whether migration is needed to a new format and/or location or whether this is
|
||||
* a first-time install and settings must be created.
|
||||
*/
|
||||
- (BOOL)keyman18DataMigrationNeeded {
|
||||
BOOL keymanSettingsExist = [self settingsExist];
|
||||
os_log([KMLogs dataLog], "keyman settings exist: %{public}@", keymanSettingsExist ? @"YES" : @"NO" );
|
||||
- (SettingsState)determineSettingsState {
|
||||
SettingsState state = KeymanSettingsVersionCurrent;
|
||||
|
||||
BOOL keyboardsStoredInLibrary = [self dataModelWithKeyboardsInLibrary];
|
||||
os_log([KMLogs dataLog], "settings indicate that keyboards are stored in ~/Library: %{public}@", keyboardsStoredInLibrary ? @"YES" : @"NO" );
|
||||
// settings were moved to share app group beginning in Keyman 19
|
||||
if ([self settingsExistForAppGroup]) {
|
||||
os_log([KMLogs dataLog], "keyman shared settings exist, version is current");
|
||||
SettingsState state = KeymanSettingsVersionCurrent;
|
||||
} else if ([self settingsExistForInputMethod]) {
|
||||
// In Keyman 18, KMDataModelVersion was added to settings and set to value of 1
|
||||
if ([self version18SettingsExistForInputMethod]) {
|
||||
os_log([KMLogs dataLog], "keyman app (unshared) settings version indicates Keyman 18, packages stored in ~/Library");
|
||||
state = KeymanSettingsVersion18;
|
||||
} else {
|
||||
// no KMDataModelVersion key is found in the app UserDefaults
|
||||
os_log([KMLogs dataLog], "lack of keyman settings version indicates Keyman 17 or earlier, packages stored in ~/Documents");
|
||||
state = KeymanSettingsVersion17;
|
||||
}
|
||||
} else {
|
||||
// settings do not exist, must be a new install
|
||||
os_log([KMLogs dataLog], "keyman settings do not exist, must be created for new install");
|
||||
state = KeymanSettingsNotFound;
|
||||
}
|
||||
|
||||
BOOL migrationNeeded = keymanSettingsExist && !keyboardsStoredInLibrary;
|
||||
os_log([KMLogs dataLog], "keyman18DataMigrationNeeded: %{public}@", migrationNeeded ? @"YES" : @"NO" );
|
||||
|
||||
return migrationNeeded;
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the keyboard data needs to be moved from the Keyman 18 location to the Keyman 19 location
|
||||
* This is true if the UserDefaults exist in the old location for the input method
|
||||
*/
|
||||
- (BOOL)keyman19SettingsMigrationNeeded {
|
||||
BOOL keymanSettingsExistForInputMethod = [self inputMethodUserDefaultsExist];
|
||||
os_log([KMLogs dataLog], "keyman input method settings exist (for 18 and earlier): %{public}@", keymanSettingsExistForInputMethod ? @"YES" : @"NO" );
|
||||
|
||||
BOOL keyboardsStoredInLibrary = [self dataModelWithKeyboardsInLibrary];
|
||||
os_log([KMLogs dataLog], "settings indicate that keyboards are stored in ~/Library: %{public}@", keyboardsStoredInLibrary ? @"YES" : @"NO" );
|
||||
|
||||
BOOL migrationNeeded = keymanSettingsExistForInputMethod;
|
||||
os_log([KMLogs dataLog], "keyman19SettingsMigrationNeeded: %{public}@", migrationNeeded ? @"YES" : @"NO" );
|
||||
|
||||
return migrationNeeded;
|
||||
}
|
||||
// MAC-CONFIG-TODO: add support for migration from Keyman 17 and earlier to Keyman 19
|
||||
|
||||
- (void)migrateSettingsForKeyman19 {
|
||||
[self migrateInputMethodSettingsToAppGroup];
|
||||
|
||||
// set kDataModelVersion to indicate that we are using the group container
|
||||
[self.groupDefaults setInteger:kVersionStoreDataInGroupContainer forKey:kDataModelVersion];
|
||||
|
||||
// set kDataModelVersion for the current format
|
||||
[self.setDataModelVersionIfNecessary];
|
||||
|
||||
[self removeMigratedInputMethodSettings];
|
||||
}
|
||||
|
||||
- (void)createKeyman19SharedSettingsIfNecessary {
|
||||
// set kDataModelVersion for the current format
|
||||
[self.setDataModelVersionIfNecessary];
|
||||
}
|
||||
|
||||
/**
|
||||
* Move userdefaults from app to app group
|
||||
* Read the settings in the input method's user defaults
|
||||
|
|
@ -194,28 +194,37 @@ NSInteger const kCurrentDataModelVersionNumber = kVersionStoreDataInGroupContain
|
|||
|
||||
- (void)setDataModelVersionIfNecessary {
|
||||
if (![self dataModelWithKeyboardsInLibrary]) {
|
||||
[self.groupDefaults setInteger:kVersionStoreDataInLibraryDirectory forKey:kDataModelVersion];
|
||||
[self.groupDefaults setInteger:kVersionStoreDataInGroupContainer forKey:kDataModelVersion];
|
||||
}
|
||||
}
|
||||
|
||||
// MAC-CONFIG-TODO: remove if obsolete
|
||||
/**
|
||||
* If the selectedKeyboard has not been set, then the settings have not been saved in the UserDefaults.
|
||||
* The dataModelVersion field will always exists for Keyman 18 and later, and starting
|
||||
* with Keyman 19, it will be located in the UserDefaults for the app group.
|
||||
* If this method is called after applicationDidFinishLaunching, then it will always return true.
|
||||
* If called from awakeFromNib, then it will return false when running for the first time.
|
||||
*/
|
||||
- (BOOL)settingsExist
|
||||
- (BOOL)settingsExistForAppGroup
|
||||
{
|
||||
return ([self.groupDefaults objectForKey:kDataModelVersion] != nil);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the selectedKeyboard has not been set, then the settings have not been saved in the UserDefaults.
|
||||
* For old versions of Keyman, 17 and earlier, there was no`KMDataModelVersion` to check.
|
||||
*/
|
||||
- (BOOL)settingsExistForInputMethod
|
||||
{
|
||||
return ([self.appDefaults objectForKey:kSelectedKeyboardKey] != nil);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true for Keyman 18 and earlier when settings were stored exclusively for the input method rather than for the app group.
|
||||
* If the selectedKeyboard has not been set, then the settings are not saved in the input method's UserDefaults.
|
||||
* The dataModelVersion field will always exists for Keyman 18 and later, but it will be located
|
||||
* in the app UserDefaults -- for the input method only -- instead of the app group UserDefaults
|
||||
*/
|
||||
- (BOOL)inputMethodUserDefaultsExist
|
||||
- (BOOL)version18SettingsExistForInputMethod
|
||||
{
|
||||
return ([self.appDefaults objectForKey:kSelectedKeyboardKey] != nil);
|
||||
return ([self.appDefaults objectForKey:kDataModelVersion] != nil);
|
||||
}
|
||||
|
||||
- (void)writeOptionForSelectedKeyboard:(NSString *)key withValue:(NSString*)value {
|
||||
|
|
@ -263,7 +272,7 @@ NSInteger const kCurrentDataModelVersionNumber = kVersionStoreDataInGroupContain
|
|||
// [NSUserDefaults integerForKey] returns zero if the key does not exist
|
||||
NSInteger dataModelVersion = [self.groupDefaults integerForKey:kDataModelVersion];
|
||||
|
||||
return dataModelVersion >= kVersionStoreDataInLibraryDirectory;
|
||||
return dataModelVersion == kVersionStoreDataInLibraryDirectory;
|
||||
}
|
||||
|
||||
- (NSString *)readSelectedKeyboard {
|
||||
|
|
|
|||
|
|
@ -43,11 +43,26 @@ void runAsInputMethod(void) {
|
|||
*/
|
||||
int doMigration(void) {
|
||||
os_log_info([KMLogs startupLog], "doMigration executed");
|
||||
// if necessary, migrate settings and keyboard data for compatibility with Keyman 19
|
||||
if ([KMSettingsRepository.shared keyman19SettingsMigrationNeeded]) {
|
||||
[KMDataRepository.shared migrateDataForKeyman19];
|
||||
[KMSettingsRepository.shared migrateSettingsForKeyman19];
|
||||
|
||||
SettingsState state = [KMSettingsRepository.shared determineSettingsState];
|
||||
|
||||
switch (state) {
|
||||
case KeymanSettingsVersion17:
|
||||
os_log_info([KMLogs startupLog], "doMigration executed for Keyman 17 to current");
|
||||
break;
|
||||
case KeymanSettingsVersion18:
|
||||
os_log_info([KMLogs startupLog], "doMigration executed for Keyman 18 to current");
|
||||
[KMDataRepository.shared migrateDataForKeyman19];
|
||||
[KMSettingsRepository.shared migrateSettingsForKeyman19];
|
||||
break;
|
||||
case KeymanSettingsNotFound:
|
||||
os_log_info([KMLogs startupLog], "doMigration: no migration needed, settings not found");
|
||||
break;
|
||||
case KeymanSettingsVersionCurrent:
|
||||
os_log_info([KMLogs startupLog], "doMigration: no migration needed, settings are current");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue