mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-02 05:37:41 +00:00
feat(mac): add group ID for Input Method
test to see whether the Input Method can access the group container without any warnings from the system.
This commit is contained in:
parent
72e35c2c9e
commit
e6797f5a58
7 changed files with 81 additions and 10 deletions
|
|
@ -2,6 +2,10 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>3YE4W86L3G.com.keyman</string>
|
||||
</array>
|
||||
<key>com.apple.security.automation.apple-events</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
|
|
|||
|
|
@ -1312,6 +1312,7 @@
|
|||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
REGISTER_APP_GROUPS = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -1359,6 +1360,7 @@
|
|||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
REGISTER_APP_GROUPS = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
|
|
@ -1404,6 +1406,7 @@
|
|||
PRODUCT_VERSION = 0.0.1;
|
||||
PROVISIONING_PROFILE = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
REGISTER_APP_GROUPS = NO;
|
||||
STRIP_INSTALLED_PRODUCT = YES;
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -1447,6 +1450,7 @@
|
|||
PRODUCT_VERSION = 0.0.1;
|
||||
PROVISIONING_PROFILE = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
REGISTER_APP_GROUPS = NO;
|
||||
STRIP_INSTALLED_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// keymanKeyboardsDirectory: '~/Library/Application Support/keyman.inputmethod.Keyman/Keyman-Keyboards'
|
||||
@property (readonly) NSURL *keymanKeyboardsDirectory;
|
||||
|
||||
@property (readonly) NSURL *keyman19ContainerDirectory;
|
||||
@property (readonly) NSURL *keyman19KeyboardsDirectory;
|
||||
|
||||
+ (KMDataRepository *)shared;
|
||||
- (void)createDataDirectoryIfNecessary;
|
||||
- (void)createKeyboardsDirectoryIfNecessary;
|
||||
- (void)createKeyman19SharedDirectoriesIfNecessary;
|
||||
- (BOOL)migrateData;
|
||||
- (NSString*)buildFullPath:(NSString *)fromPartialPath;
|
||||
- (NSString*)trimToPartialPath:(NSString *)fromFullPath;
|
||||
|
|
|
|||
|
|
@ -19,13 +19,15 @@
|
|||
|
||||
@implementation KMDataRepository
|
||||
/**
|
||||
* Two directory trees are represented by the following properties, one in active use
|
||||
* and one that is obsolete.
|
||||
* The actively used directories, begin with the parent
|
||||
* Three directory trees are represented by the following properties, one in active use
|
||||
* and two that are obsolete.
|
||||
* The actively used directories, introduced in Keyman 19, are shared via the app group 3YE4W86L3G.com.keyman:
|
||||
* 'Group Containers/3YE4W86L3G.com.keyman/Library/Application Support/Keyman-Keyboards/
|
||||
* The obsolete directories from Keyman 18 are:
|
||||
* applicationSupportSubDirectory: '~/Library/Application Support'
|
||||
* keymanDataDirectory: '~/Library/Application Support/keyman.inputmethod.Keyman'
|
||||
* keymanKeyboardsDirectory: '~/Library/Application Support/keyman.inputmethod.Keyman/Keyman-Keyboards'
|
||||
* The obsolete directories, begin with the parent
|
||||
* The obsolete directories from Keyman 17 and earlier are:
|
||||
* documentsSubDirectory: '~/Documents'
|
||||
* obsoleteKeymanKeyboardsDirectory: '~/Documents/Keyman-Keyboards'
|
||||
*/
|
||||
|
|
@ -35,6 +37,9 @@
|
|||
@synthesize documentsSubDirectory = _documentsSubDirectory;
|
||||
@synthesize obsoleteKeymanKeyboardsDirectory = _obsoleteKeymanKeyboardsDirectory;
|
||||
|
||||
@synthesize keyman19ContainerDirectory = _keyman19ContainerDirectory;
|
||||
@synthesize keyman19KeyboardsDirectory = _keyman19KeyboardsDirectory;
|
||||
|
||||
NSString *const kKeyboardsDirectoryName = @"Keyman-Keyboards";
|
||||
/**
|
||||
* The name of the subdirectory within '~/Library/Application Support'.
|
||||
|
|
@ -44,6 +49,11 @@ NSString *const kKeyboardsDirectoryName = @"Keyman-Keyboards";
|
|||
*/
|
||||
NSString *const kKeymanSubdirectoryName = @"keyman.inputmethod.Keyman";
|
||||
|
||||
//NSString *const kKeymanGroupId = @"3YE4W86L3G.com.keyman";
|
||||
NSString *const kKeymanGroupId = @"3YE4W86L3G.com.keyman";
|
||||
|
||||
NSString *const kContainerKeyboardsPartialPath = @"Library/Application Support/Keyman-Keyboards";
|
||||
|
||||
+ (KMDataRepository *)shared {
|
||||
static KMDataRepository *shared = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
|
|
@ -103,8 +113,49 @@ NSString *const kKeymanSubdirectoryName = @"keyman.inputmethod.Keyman";
|
|||
return _keymanKeyboardsDirectory;
|
||||
}
|
||||
|
||||
- (NSURL *)keyman19ContainerDirectory {
|
||||
if (_keyman19ContainerDirectory == nil) {
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *containerUrl = [fileManager containerURLForSecurityApplicationGroupIdentifier: kKeymanGroupId];
|
||||
|
||||
_keyman19ContainerDirectory = containerUrl;
|
||||
}
|
||||
return _keyman19ContainerDirectory;
|
||||
}
|
||||
|
||||
- (NSURL *)keyman19KeyboardsDirectory {
|
||||
if (_keymanKeyboardsDirectory == nil) {
|
||||
NSURL *keyboardsUrl = [self.keyman19ContainerDirectory URLByAppendingPathComponent:kContainerKeyboardsPartialPath isDirectory: TRUE];
|
||||
_keyman19KeyboardsDirectory = keyboardsUrl;
|
||||
}
|
||||
return _keyman19KeyboardsDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Keyman data directory if it do not exist yet. This is the main data subdirectory: keyman.inputmethod.Keyman
|
||||
* Creates Keyman 19 data directory if it does not exist yet. This is under 'Group Containers'.
|
||||
*/
|
||||
- (void)createKeyman19SharedDirectoriesIfNecessary {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
BOOL isDir;
|
||||
BOOL exists = [fileManager fileExistsAtPath:self.keyman19KeyboardsDirectory.path isDirectory:&isDir];
|
||||
|
||||
if (!exists) {
|
||||
NSError *createError = nil;
|
||||
os_log_info([KMLogs dataLog], "createKeyman19SharedDirectoriesIfNecessary, about to attempt createDirectoryAtPath for: '%{public}@'", self.keyman19KeyboardsDirectory.path);
|
||||
[fileManager createDirectoryAtPath:self.keyman19KeyboardsDirectory.path withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
if (createError) {
|
||||
os_log_error([KMLogs dataLog], "error creating Keyman data directory: '%{public}@'", createError.localizedDescription);
|
||||
} else {
|
||||
os_log_info([KMLogs dataLog], "created Keyman data directory: '%{public}@'", self.keyman19KeyboardsDirectory.path);
|
||||
}
|
||||
} else {
|
||||
os_log_info([KMLogs dataLog], "Keyman data directory already exists: '%{public}@'", self.keyman19KeyboardsDirectory.path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Keyman data directory if it does not exist yet. This is the main data subdirectory: keyman.inputmethod.Keyman
|
||||
*/
|
||||
- (void)createDataDirectoryIfNecessary {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
|
|
|
|||
|
|
@ -754,7 +754,12 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
|
|||
* namely, the keyboard data on disk and the settings in UserDefaults
|
||||
*/
|
||||
- (void)prepareStorage {
|
||||
[KMDataRepository.shared createDataDirectoryIfNecessary];
|
||||
os_log_debug([KMLogs dataLog], "*** prepareStorage ***");
|
||||
|
||||
[KMDataRepository.shared createKeyman19SharedDirectoriesIfNecessary];
|
||||
// [KMDataRepository.shared createDataDirectoryIfNecessary];
|
||||
|
||||
// TODO: MAC_CONFIG expand data migration for Keyman 19
|
||||
|
||||
if ([KMSettingsRepository.shared dataMigrationNeeded]) {
|
||||
[KMDataRepository.shared migrateData];
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public class KeymanSettings : ObservableObject {
|
|||
// }
|
||||
|
||||
// load keyboards from disk
|
||||
if (self.dataRepository.keyman19DataDirectoryExists()) {
|
||||
if (self.dataRepository.keyman19SharedDataDirectoryExists()) {
|
||||
let packageSourceArray = self.dataRepository.readKeymanPackagesForKeyman19()
|
||||
|
||||
// create a KeymanPackage object for each PackageSource object and insert it in the array
|
||||
|
|
@ -32,7 +32,7 @@ public class KeymanSettings : ObservableObject {
|
|||
self.keyboardPackages.append(package)
|
||||
}
|
||||
} else {
|
||||
self.dataRepository.createKeyman19DataDirectories()
|
||||
self.dataRepository.createKeyman19SharedDataDirectories()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public class PackageRepository {
|
|||
/**
|
||||
* Creates the directory tree where keyboards are stored under the standard 'Group Containers' directory
|
||||
*/
|
||||
func createKeyman19DataDirectories() {
|
||||
func createKeyman19SharedDataDirectories() {
|
||||
if let keyboardDirectory = pathUtil.keyman19KeyboardsDirectory {
|
||||
|
||||
do {
|
||||
|
|
@ -63,7 +63,10 @@ public class PackageRepository {
|
|||
}
|
||||
}
|
||||
|
||||
public func keyman19DataDirectoryExists() -> Bool {
|
||||
/**
|
||||
* Check to see whether the shared Keyman data directory exists under 'Library/Group Containers/'
|
||||
*/
|
||||
public func keyman19SharedDataDirectoryExists() -> Bool {
|
||||
guard let keyboardsUrl = self.pathUtil.keyman19KeyboardsDirectory else {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue