diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b7f288a..37657e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,23 +1,16 @@ name: CI on: [push, pull_request] -env: - BUILD_NUMBER: ${{ github.run_number }} jobs: macos: name: Build on macOS runs-on: macos-latest steps: - name: Checkout - uses: actions/checkout@v2 - with: - submodules: 'true' + uses: actions/checkout@v4 - name: Build - run: | - xcodebuild -project EstEIDTokenApp.xcodeproj -target package CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO DSTROOT=$PWD/tmp install - mkdir upload - mv *pkg upload + run: xcodebuild -project EstEIDTokenApp.xcodeproj -target package CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO DSTROOT=$PWD/tmp CURRENT_PROJECT_VERSION=${{ github.run_number }} install - name: Archive artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: pkg - path: upload \ No newline at end of file + path: ./*.pkg diff --git a/EstEIDToken/Info.plist b/EstEIDToken/Info.plist index 2feef93..ea3ff78 100644 --- a/EstEIDToken/Info.plist +++ b/EstEIDToken/Info.plist @@ -2,36 +2,12 @@ - CFBundleDevelopmentRegion - en - CFBundleDisplayName - EstEIDToken - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) NSExtension NSExtensionAttributes com.apple.ctk.aid - F04573744549442076657220312E - D23300000045737445494420763335 A000000077010800070000FE00000100 com.apple.ctk.class-id diff --git a/EstEIDToken/Localizable.xcstrings b/EstEIDToken/Localizable.xcstrings new file mode 100644 index 0000000..6c8feba --- /dev/null +++ b/EstEIDToken/Localizable.xcstrings @@ -0,0 +1,241 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "AUTH_CERT" : { + "comment" : "Localizable.strings\n CryptoTokenKit", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificate For Card Authentication" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificate For Card Authentication" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificate For Card Authentication" + } + } + } + }, + "AUTH_KEY" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Key For Card Authentication" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Key For Card Authentication" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Key For Card Authentication" + } + } + } + }, + "ENTER_PINPAD" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Please enter PIN code on PinPAD" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Palun sisestada PIN kaardilugeja sõrmistikult" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Please enter PIN code on PinPAD" + } + } + } + }, + "INVALID_PIN" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invalid PIN entered" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sisestati ebakorrektne PIN" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invalid PIN entered" + } + } + } + }, + "SIGN_CERT" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificate For Digital Signature" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificate For Digital Signature" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Certificate For Digital Signature" + } + } + } + }, + "SIGN_KEY" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Key For Digital Signature" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Key For Digital Signature" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Key For Digital Signature" + } + } + } + }, + "VERIFY_TRY_LEFT" : { + "localizations" : { + "en" : { + "variations" : { + "plural" : { + "one" : { + "stringUnit" : { + "state" : "translated", + "value" : "PIN Incorrect.\nPIN will be locked next failed attempt." + } + }, + "other" : { + "stringUnit" : { + "state" : "translated", + "value" : "PIN Incorrect.\n%d tries left" + } + }, + "zero" : { + "stringUnit" : { + "state" : "translated", + "value" : "PIN locked.\nUnblock to reuse PIN." + } + } + } + } + }, + "et" : { + "variations" : { + "plural" : { + "one" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vale PIN.\nJärgmise vale koodi sisestamisel PIN lukustub." + } + }, + "other" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vale PIN.\n%d katset jäänud" + } + }, + "zero" : { + "stringUnit" : { + "state" : "translated", + "value" : "PIN on lukus.\nTühista blokeering, et PIN-i taas kasutada." + } + } + } + } + }, + "ru" : { + "variations" : { + "plural" : { + "one" : { + "stringUnit" : { + "state" : "translated", + "value" : "Неверный PIN.\nPIN будет заблокирован при следующей неудачной попытке" + } + }, + "other" : { + "stringUnit" : { + "state" : "translated", + "value" : "Неправильный PIN.\nОсталось %d попыток" + } + }, + "zero" : { + "stringUnit" : { + "state" : "translated", + "value" : "PIN заблокирован.\nРазблокируйте его для повторного использования PIN." + } + } + } + } + } + } + }, + "WRONG_CONSTR" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unexpected constraint" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unexpected constraint" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unexpected constraint" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/EstEIDToken/Token.h b/EstEIDToken/Token.h index 1f41b52..ddf72c7 100644 --- a/EstEIDToken/Token.h +++ b/EstEIDToken/Token.h @@ -35,18 +35,12 @@ static const TKTokenOperationConstraint EstEIDConstraintPIN = @"PIN"; @interface Token : TKSmartCardToken @end -@interface EstEIDToken : Token -@end - @interface IDEMIAToken : Token @end @interface TokenSession : TKSmartCardTokenSession @end -@interface EstEIDTokenSession : TokenSession -@end - @interface IDEMIATokenSession : TokenSession @end diff --git a/EstEIDToken/Token.m b/EstEIDToken/Token.m index 755d010..7eadd04 100644 --- a/EstEIDToken/Token.m +++ b/EstEIDToken/Token.m @@ -77,19 +77,6 @@ - (nullable NSData*)readCert:(NSData*)file error:(NSError **) error { return fileData; } -- (nullable NSString*)readRecord:(UInt8)record error:(NSError **) error { - UInt16 sw = 0; - NSData *data = [self sendIns:0xB2 p1:record p2:0x04 data:nil le:@0 sw:&sw error:error]; - if (sw == 0x9000) { - return [[NSString alloc] initWithData:data encoding:NSWindowsCP1252StringEncoding]; - } - NSLog(@"EstEIDToken readRecord failed to read record %@", @(record)); - if (error != nil) { - *error = [NSError errorWithDomain:TKErrorDomain code:TKErrorCodeObjectNotFound userInfo:nil]; - } - return nil; -} - @end @implementation TKTokenKeychainItem(EstEIDDataFormat) @@ -148,11 +135,10 @@ - (BOOL)populateIdentity:(NSData*)certificateData certificateID:(NSData*)certifi } [keyItem setName:NSLocalizedString(auth ? @"AUTH_KEY" : @"SIGN_KEY", nil)]; keyItem.canSign = YES; - keyItem.canDecrypt = NO; //auth; FIXME: implement decryption + keyItem.canDecrypt = NO; keyItem.suitableForLogin = NO; //auth; FIXME: implement login keyItem.canPerformKeyExchange = NO; //auth; FIXME: implement derive keyItem.constraints = @{ @(TKTokenOperationSignData): EstEIDConstraintPIN }; - // keyItem.constraints = constraints[@(TKTokenOperationDecryptData)] = EstEIDConstraintPIN; //auth; FIXME: implement decryption // keyItem.constraints = constraints[@(TKTokenOperationPerformKeyExchange)] = EstEIDConstraintPIN; //auth; FIXME: implement derive // Populate keychain state with keys. [self.keychainContents fillWithItems:@[certificateItem, keyItem]]; @@ -161,36 +147,6 @@ - (BOOL)populateIdentity:(NSData*)certificateData certificateID:(NSData*)certifi @end -@implementation EstEIDToken - -- (nullable instancetype)initWithSmartCard:(TKSmartCard *)smartCard AID:(nullable NSData *)AID tokenDriver:(TKSmartCardTokenDriver *)tokenDriver error:(NSError **)error { - NSLog(@"EstEIDToken initWithSmartCard AID %@", AID); - NSString *instanceID; - if ([smartCard selectFile:0x00 p2:0x0C file:nil error:error] == nil || - [smartCard selectFile:0x01 p2:0x0C file:NSDATA(2, 0xEE, 0xEE) error:error] == nil || - [smartCard selectFile:0x02 p2:0x0C file:NSDATA(2, 0x50, 0x44) error:error] == nil || - (instanceID = [smartCard readRecord:0x08 error:error]) == nil) { - NSLog(@"EstEIDToken initWithSmartCard failed to read card"); - return nil; - } - NSLog(@"EstEIDToken initWithSmartCard %@", instanceID); - if (self = [super initWithSmartCard:smartCard AID:AID instanceID:instanceID tokenDriver:tokenDriver]) { - NSData *certificateID = NSDATA(2, 0xAA, 0xCE); - NSData *keyID = NSDATA(2, 0x11, 0x00); - if (![super populateIdentity:[smartCard readCert:certificateID error:error] certificateID:certificateID keyID:keyID auth:YES error:error]) { - return nil; - } - } - return self; -} - -- (TKTokenSession *)token:(TKToken *)token createSessionWithError:(NSError **)error { - NSLog(@"EstEIDToken createSessionWithError %@", self.AID); - return [[EstEIDTokenSession alloc] initWithToken:self]; -} - -@end - @implementation IDEMIAToken - (nullable instancetype)initWithSmartCard:(TKSmartCard *)smartCard AID:(nullable NSData *)AID tokenDriver:(TKSmartCardTokenDriver *)tokenDriver error:(NSError **)error { @@ -229,10 +185,7 @@ - (TKSmartCardToken *)tokenDriver:(TKSmartCardTokenDriver *)driver createTokenFo NSBundle *bundle = [NSBundle bundleForClass:EstEIDTokenDriver.class]; NSLog(@"EstEIDTokenDriver createTokenForSmartCard AID %@ version %@.%@", AID, bundle.infoDictionary[@"CFBundleShortVersionString"], bundle.infoDictionary[@"CFBundleVersion"]); [EstEIDTokenDriver showNotification:nil]; - if ([AID isEqualToData:NSDATA(16, 0xA0, 0x00, 0x00, 0x00, 0x77, 0x01, 0x08, 0x00, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x01, 0x00)]) { - return [[IDEMIAToken alloc] initWithSmartCard:smartCard AID:AID tokenDriver:self error:error]; - } - return [[EstEIDToken alloc] initWithSmartCard:smartCard AID:AID tokenDriver:self error:error]; + return [[IDEMIAToken alloc] initWithSmartCard:smartCard AID:AID tokenDriver:self error:error]; } + (void)showNotification:(NSString*__nullable)msg { @@ -248,8 +201,9 @@ + (void)showNotification:(NSString*__nullable)msg { NSBundle *bundle = [NSBundle bundleForClass:EstEIDTokenDriver.class]; NSString *path = [bundle.bundlePath.stringByDeletingLastPathComponent.stringByDeletingLastPathComponent stringByAppendingString:@"/Resources/EstEIDTokenNotify.app"]; NSLog(@"EstEIDTokenDriver showNotification path: %@", path); - BOOL isLaunched = [NSWorkspace.sharedWorkspace launchApplication:path]; - NSLog(@"EstEIDTokenDriver showNotification launchApplication: %d", isLaunched); + [NSWorkspace.sharedWorkspace openApplicationAtURL:[NSURL fileURLWithPath:path isDirectory:YES] configuration:NSWorkspaceOpenConfiguration.configuration completionHandler:^(NSRunningApplication *app, NSError *error) { + NSLog(@"EstEIDTokenDriver showNotification openApplicationAtURL: %@", error); + }]; } [NSDistributedNotificationCenter.defaultCenter postNotificationName:@"EstEIDTokenNotify" object:msg userInfo:nil deliverImmediately:YES]; } diff --git a/EstEIDToken/TokenSession.m b/EstEIDToken/TokenSession.m index 75c4040..c60f021 100644 --- a/EstEIDToken/TokenSession.m +++ b/EstEIDToken/TokenSession.m @@ -352,54 +352,6 @@ - (NSData *)tokenSession:(TKTokenSession *)session signData:(NSData *)dataToSign @end -@implementation EstEIDTokenSession - -- (BOOL)initSignEnv:(NSError **)error { - NSLog(@"EstEIDTokenSession initSignEnv"); - UInt16 sw; - [self.smartCard sendIns:0x22 p1:0xF3 p2:0x01 data:nil le:@0 sw:&sw error:error]; - if (sw != 0x9000) { - NSLog(@"EstEIDTokenSession signData failed to set sec env"); - if (error != nil) { - *error = [NSError errorWithDomain:TKErrorDomain code:TKErrorCodeCorruptedData userInfo:nil]; - } - [self closeSession]; - return NO; - } - - [self.smartCard sendIns:0x22 p1:0x41 p2:0xB8 data:NSDATA(2, 0x83, 0x00) le:nil sw:&sw error:error]; //Key reference, 8303801100 - if (sw != 0x9000) { - NSLog(@"EstEIDTokenSession signData failed to select default key"); - if (error != nil) { - *error = [NSError errorWithDomain:TKErrorDomain code:TKErrorCodeCorruptedData userInfo:nil]; - } - [self closeSession]; - return NO; - } - return YES; -} - -- (UInt8)triesLeft:(NSError **)error { - NSLog(@"EstEIDTokenSession triesLeft"); - UInt16 sw; - NSData *pinStatus; - if ([self.smartCard sendIns:0xA4 p1:0x00 p2:0x0C data:nil le:@0 sw:&sw error:error] == nil || - [self.smartCard sendIns:0xA4 p1:0x02 p2:0x0C data:NSDATA(2, 0x00, 0x16) le:@0 sw:&sw error:error] == nil || - (pinStatus = [self.smartCard sendIns:0xB2 p1:0x01 p2:0x04 data:nil le:@0 sw:&sw error:error]) == nil) { - NSLog(@"EstEIDTokenSession triesLeft %d %@", sw, pinStatus); - [self closeSession]; - if (error != nil) { - *error = [NSError errorWithDomain:TKErrorDomain code:TKErrorCodeAuthenticationFailed userInfo:@{NSLocalizedDescriptionKey:NSLocalizedString(@"WRONG_CONSTR", nil)}]; - } - return 0; - } - UInt8 triesLeft = 0; - [pinStatus getBytes:&triesLeft range:NSMakeRange(5, sizeof(triesLeft))]; - return triesLeft; -} - -@end - @implementation IDEMIATokenSession - (BOOL)initSignEnv:(NSError **)error { diff --git a/EstEIDToken/en.lproj/Localizable.strings b/EstEIDToken/en.lproj/Localizable.strings deleted file mode 100644 index ced769d..0000000 --- a/EstEIDToken/en.lproj/Localizable.strings +++ /dev/null @@ -1,12 +0,0 @@ -/* - Localizable.strings - CryptoTokenKit - */ - -"AUTH_CERT" = "Certificate For Card Authentication"; -"SIGN_CERT" = "Certificate For Digital Signature"; -"AUTH_KEY" = "Key For Card Authentication"; -"SIGN_KEY" = "Key For Digital Signature"; -"WRONG_CONSTR" = "Unexpected constraint"; -"ENTER_PINPAD" = "Please enter PIN code on PinPAD"; -"INVALID_PIN" = "Invalid PIN entered"; diff --git a/EstEIDToken/en.lproj/Localizable.stringsdict b/EstEIDToken/en.lproj/Localizable.stringsdict deleted file mode 100644 index c6f7536..0000000 --- a/EstEIDToken/en.lproj/Localizable.stringsdict +++ /dev/null @@ -1,27 +0,0 @@ - - - - - VERIFY_TRY_LEFT - - NSStringLocalizedFormatKey - %1$#@tries@ - tries - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - d - zero - PIN locked. -Unblock to reuse PIN. - one - PIN Incorrect. -PIN will be locked next failed attempt. - other - PIN Incorrect. -%d tries left - - - - diff --git a/EstEIDToken/et.lproj/Localizable.strings b/EstEIDToken/et.lproj/Localizable.strings deleted file mode 100644 index c28e969..0000000 --- a/EstEIDToken/et.lproj/Localizable.strings +++ /dev/null @@ -1,12 +0,0 @@ -/* - Localizable.strings - CryptoTokenKit - */ - -"AUTH_CERT" = "Certificate For Card Authentication"; -"SIGN_CERT" = "Certificate For Digital Signature"; -"AUTH_KEY" = "Key For Card Authentication"; -"SIGN_KEY" = "Key For Digital Signature"; -"WRONG_CONSTR" = "Unexpected constraint"; -"ENTER_PINPAD" = "Palun sisestada PIN kaardilugeja sõrmistikult"; -"INVALID_PIN" = "Sisestati ebakorrektne PIN"; diff --git a/EstEIDToken/et.lproj/Localizable.stringsdict b/EstEIDToken/et.lproj/Localizable.stringsdict deleted file mode 100644 index 4d534a7..0000000 --- a/EstEIDToken/et.lproj/Localizable.stringsdict +++ /dev/null @@ -1,27 +0,0 @@ - - - - - VERIFY_TRY_LEFT - - NSStringLocalizedFormatKey - %1$#@tries@ - tries - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - d - zero - PIN on lukus. -Tühista blokeering, et PIN-i taas kasutada. - one - Vale PIN. -Järgmise vale koodi sisestamisel PIN lukustub. - other - Vale PIN. -%d katset jäänud - - - - diff --git a/EstEIDToken/ru.lproj/Localizable.strings b/EstEIDToken/ru.lproj/Localizable.strings deleted file mode 100644 index ced769d..0000000 --- a/EstEIDToken/ru.lproj/Localizable.strings +++ /dev/null @@ -1,12 +0,0 @@ -/* - Localizable.strings - CryptoTokenKit - */ - -"AUTH_CERT" = "Certificate For Card Authentication"; -"SIGN_CERT" = "Certificate For Digital Signature"; -"AUTH_KEY" = "Key For Card Authentication"; -"SIGN_KEY" = "Key For Digital Signature"; -"WRONG_CONSTR" = "Unexpected constraint"; -"ENTER_PINPAD" = "Please enter PIN code on PinPAD"; -"INVALID_PIN" = "Invalid PIN entered"; diff --git a/EstEIDToken/ru.lproj/Localizable.stringsdict b/EstEIDToken/ru.lproj/Localizable.stringsdict deleted file mode 100644 index f278df5..0000000 --- a/EstEIDToken/ru.lproj/Localizable.stringsdict +++ /dev/null @@ -1,27 +0,0 @@ - - - - - VERIFY_TRY_LEFT - - NSStringLocalizedFormatKey - %1$#@tries@ - tries - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - d - zero - PIN заблокирован. -Разблокируйте его для повторного использования PIN. - one - Неверный PIN. -PIN будет заблокирован при следующей неудачной попытке - other - Неправильный PIN. -Осталось %d попыток - - - - diff --git a/EstEIDTokenApp.xcodeproj/project.pbxproj b/EstEIDTokenApp.xcodeproj/project.pbxproj index 8adddbf..16df6d5 100644 --- a/EstEIDTokenApp.xcodeproj/project.pbxproj +++ b/EstEIDTokenApp.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 60; objects = { /* Begin PBXAggregateTarget section */ @@ -27,10 +27,9 @@ 2F3883A21CF46C6E00F114A7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2F3883A11CF46C6E00F114A7 /* Assets.xcassets */; }; 2F3883A51CF46C6F00F114A7 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2F3883A31CF46C6F00F114A7 /* MainMenu.xib */; }; 2F3883B91CF46C9D00F114A7 /* Token.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F3883B81CF46C9D00F114A7 /* Token.m */; }; - 2F3883BF1CF46C9D00F114A7 /* EstEIDToken.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2F3883B01CF46C9D00F114A7 /* EstEIDToken.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 2F3883BF1CF46C9D00F114A7 /* EstEIDToken.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2F3883B01CF46C9D00F114A7 /* EstEIDToken.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 2F3883C51CF46D6F00F114A7 /* TokenSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F3883C41CF46D6F00F114A7 /* TokenSession.m */; }; - 2F7767771CF5E0A00062B0A8 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2F7767731CF5E0A00062B0A8 /* Localizable.strings */; }; - 2F7767781CF5E0A00062B0A8 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2F7767751CF5E0A00062B0A8 /* Localizable.stringsdict */; }; + 4E77CCA42B5E85AB00518F62 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 4E77CCA32B5E85AB00518F62 /* Localizable.xcstrings */; }; 4EF3231120AC183E00809D13 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF3231020AC183E00809D13 /* AppDelegate.m */; }; 4EF3231920AC184000809D13 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4EF3231720AC184000809D13 /* Main.storyboard */; }; 4EF3231C20AC184000809D13 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EF3231B20AC184000809D13 /* main.m */; }; @@ -63,15 +62,15 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 2F3883C31CF46C9D00F114A7 /* Embed App Extensions */ = { + 2F3883C31CF46C9D00F114A7 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 13; files = ( - 2F3883BF1CF46C9D00F114A7 /* EstEIDToken.appex in Embed App Extensions */, + 2F3883BF1CF46C9D00F114A7 /* EstEIDToken.appex in Embed Foundation Extensions */, ); - name = "Embed App Extensions"; + name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ @@ -82,27 +81,18 @@ 2F38839F1CF46C6E00F114A7 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 2F3883A11CF46C6E00F114A7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2F3883A41CF46C6F00F114A7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 2F3883A61CF46C6F00F114A7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2F3883B01CF46C9D00F114A7 /* EstEIDToken.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = EstEIDToken.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 2F3883B61CF46C9D00F114A7 /* EstEIDToken.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EstEIDToken.entitlements; sourceTree = ""; }; 2F3883B71CF46C9D00F114A7 /* Token.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = ""; }; 2F3883B81CF46C9D00F114A7 /* Token.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Token.m; sourceTree = ""; }; 2F3883BC1CF46C9D00F114A7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2F3883C41CF46D6F00F114A7 /* TokenSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TokenSession.m; sourceTree = ""; }; - 2F7767741CF5E0A00062B0A8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - 2F7767761CF5E0A00062B0A8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; - 4EAFE859212C20BE00DD6D87 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MainMenu.strings; sourceTree = ""; }; - 4EAFE85B212C20BE00DD6D87 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; - 4EAFE85C212C20BE00DD6D87 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; - 4EAFE85D212C20F200DD6D87 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/MainMenu.strings; sourceTree = ""; }; - 4EAFE85F212C20F200DD6D87 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Localizable.strings; sourceTree = ""; }; - 4EAFE860212C20F200DD6D87 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = et; path = et.lproj/Localizable.stringsdict; sourceTree = ""; }; - 4EAFE864212C21E900DD6D87 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Main.strings; sourceTree = ""; }; - 4EAFE866212C21E900DD6D87 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Main.strings; sourceTree = ""; }; + 4E77CCA12B5E85AB00518F62 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/MainMenu.xcstrings; sourceTree = ""; }; + 4E77CCA22B5E85AB00518F62 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Main.xcstrings; sourceTree = ""; }; + 4E77CCA32B5E85AB00518F62 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 4EF3230D20AC183E00809D13 /* EstEIDTokenNotify.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EstEIDTokenNotify.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4EF3231020AC183E00809D13 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 4EF3231820AC184000809D13 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 4EF3231A20AC184000809D13 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4EF3231B20AC184000809D13 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 4EF3232720AC304C00809D13 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = EstEIDTokenApp/Assets.xcassets; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ @@ -158,7 +148,6 @@ 2F38839C1CF46C6E00F114A7 /* AppDelegate.m */, 2F3883A11CF46C6E00F114A7 /* Assets.xcassets */, 2F3883A31CF46C6F00F114A7 /* MainMenu.xib */, - 2F3883A61CF46C6F00F114A7 /* Info.plist */, 2F38839F1CF46C6E00F114A7 /* main.m */, ); path = EstEIDTokenApp; @@ -180,8 +169,7 @@ 2F7767721CF5E08E0062B0A8 /* en.lproj */ = { isa = PBXGroup; children = ( - 2F7767731CF5E0A00062B0A8 /* Localizable.strings */, - 2F7767751CF5E0A00062B0A8 /* Localizable.stringsdict */, + 4E77CCA32B5E85AB00518F62 /* Localizable.xcstrings */, ); name = en.lproj; sourceTree = ""; @@ -192,7 +180,6 @@ 4EF3232720AC304C00809D13 /* Assets.xcassets */, 4EF3231020AC183E00809D13 /* AppDelegate.m */, 4EF3231720AC184000809D13 /* Main.storyboard */, - 4EF3231A20AC184000809D13 /* Info.plist */, 4EF3231B20AC184000809D13 /* main.m */, ); path = EstEIDTokenNotify; @@ -208,7 +195,7 @@ 2F3883941CF46C6E00F114A7 /* Sources */, 2F3883951CF46C6E00F114A7 /* Frameworks */, 2F3883961CF46C6E00F114A7 /* Resources */, - 2F3883C31CF46C9D00F114A7 /* Embed App Extensions */, + 2F3883C31CF46C9D00F114A7 /* Embed Foundation Extensions */, ); buildRules = ( ); @@ -261,7 +248,8 @@ 2F3883901CF46C6E00F114A7 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1230; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1520; ORGANIZATIONNAME = ""; TargetAttributes = { 2F3883971CF46C6E00F114A7 = { @@ -286,7 +274,7 @@ }; }; buildConfigurationList = 2F3883931CF46C6E00F114A7 /* Build configuration list for PBXProject "EstEIDTokenApp" */; - compatibilityVersion = "Xcode 10.0"; + compatibilityVersion = "Xcode 13.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -323,8 +311,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2F7767771CF5E0A00062B0A8 /* Localizable.strings in Resources */, - 2F7767781CF5E0A00062B0A8 /* Localizable.stringsdict in Resources */, + 4E77CCA42B5E85AB00518F62 /* Localizable.xcstrings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -410,38 +397,16 @@ isa = PBXVariantGroup; children = ( 2F3883A41CF46C6F00F114A7 /* Base */, - 4EAFE859212C20BE00DD6D87 /* ru */, - 4EAFE85D212C20F200DD6D87 /* et */, + 4E77CCA12B5E85AB00518F62 /* mul */, ); name = MainMenu.xib; sourceTree = ""; }; - 2F7767731CF5E0A00062B0A8 /* Localizable.strings */ = { - isa = PBXVariantGroup; - children = ( - 2F7767741CF5E0A00062B0A8 /* en */, - 4EAFE85B212C20BE00DD6D87 /* ru */, - 4EAFE85F212C20F200DD6D87 /* et */, - ); - name = Localizable.strings; - sourceTree = ""; - }; - 2F7767751CF5E0A00062B0A8 /* Localizable.stringsdict */ = { - isa = PBXVariantGroup; - children = ( - 2F7767761CF5E0A00062B0A8 /* en */, - 4EAFE85C212C20BE00DD6D87 /* ru */, - 4EAFE860212C20F200DD6D87 /* et */, - ); - name = Localizable.stringsdict; - sourceTree = ""; - }; 4EF3231720AC184000809D13 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 4EF3231820AC184000809D13 /* Base */, - 4EAFE864212C21E900DD6D87 /* ru */, - 4EAFE866212C21E900DD6D87 /* et */, + 4E77CCA22B5E85AB00518F62 /* mul */, ); name = Main.storyboard; sourceTree = ""; @@ -453,10 +418,11 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -486,10 +452,12 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 0; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 4F425HHPH8; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -504,10 +472,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.3.3; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + MARKETING_VERSION = 1.4.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; }; name = Debug; }; @@ -515,10 +485,11 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -549,10 +520,12 @@ CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 0; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 4F425HHPH8; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -561,10 +534,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 1.3.3; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 11.0; + MARKETING_VERSION = 1.4.0; OTHER_CODE_SIGN_FLAGS = "--timestamp --options=runtime"; SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; }; name = Release; }; @@ -573,7 +548,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = EstEIDTokenApp/Info.plist; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + INFOPLIST_KEY_NSMainNibFile = MainMenu; INSTALL_PATH = "$(LOCAL_APPS_DIR)/Utilities"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -589,7 +566,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = EstEIDTokenApp/Info.plist; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + INFOPLIST_KEY_NSMainNibFile = MainMenu; INSTALL_PATH = "$(LOCAL_APPS_DIR)/Utilities"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -605,6 +584,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = EstEIDToken/EstEIDToken.entitlements; COMBINE_HIDPI_IMAGES = YES; + GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = EstEIDToken/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -622,6 +602,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = EstEIDToken/EstEIDToken.entitlements; COMBINE_HIDPI_IMAGES = YES; + GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = EstEIDToken/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -637,6 +618,7 @@ 4E5814FB20225F53008493DC /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ENABLE_USER_SCRIPT_SANDBOXING = NO; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -644,6 +626,7 @@ 4E5814FC20225F53008493DC /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ENABLE_USER_SCRIPT_SANDBOXING = NO; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -653,7 +636,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = EstEIDTokenNotify/Info.plist; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSBackgroundOnly = YES; + INFOPLIST_KEY_NSMainStoryboardFile = Main; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", @@ -669,7 +654,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = EstEIDTokenNotify/Info.plist; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSBackgroundOnly = YES; + INFOPLIST_KEY_NSMainStoryboardFile = Main; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", diff --git a/EstEIDTokenApp/Info.plist b/EstEIDTokenApp/Info.plist deleted file mode 100644 index 895a223..0000000 --- a/EstEIDTokenApp/Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - LSApplicationCategoryType - public.app-category.utilities - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSRequiresAquaSystemAppearance - - - diff --git a/EstEIDTokenApp/et.lproj/MainMenu.strings b/EstEIDTokenApp/et.lproj/MainMenu.strings deleted file mode 100644 index 8b4e4ce..0000000 --- a/EstEIDTokenApp/et.lproj/MainMenu.strings +++ /dev/null @@ -1,42 +0,0 @@ - -/* Class = "NSMenuItem"; title = "EstEIDTokenApp"; ObjectID = "1Xt-HY-uBw"; */ -"1Xt-HY-uBw.title" = "EstEIDTokenApp"; - -/* Class = "NSMenuItem"; title = "Quit EstEIDTokenApp"; ObjectID = "4sb-4s-VLi"; */ -"4sb-4s-VLi.title" = "Quit EstEIDTokenApp"; - -/* Class = "NSMenuItem"; title = "About EstEIDTokenApp"; ObjectID = "5kV-Vb-QxS"; */ -"5kV-Vb-QxS.title" = "About EstEIDTokenApp"; - -/* Class = "NSTextFieldCell"; title = "Version: 1.0.0"; ObjectID = "9Pp-ko-iP0"; */ -"9Pp-ko-iP0.title" = "Version: 1.0.0"; - -/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ -"AYu-sK-qS6.title" = "Main Menu"; - -/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ -"BOF-NM-1cW.title" = "Preferences…"; - -/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ -"Kd2-mp-pUS.title" = "Show All"; - -/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ -"NMo-om-nkz.title" = "Services"; - -/* Class = "NSMenuItem"; title = "Hide EstEIDTokenApp"; ObjectID = "Olw-nP-bQN"; */ -"Olw-nP-bQN.title" = "Hide EstEIDTokenApp"; - -/* Class = "NSWindow"; title = "EstEIDToken"; ObjectID = "QvC-M9-y7g"; */ -"QvC-M9-y7g.title" = "EstEIDToken"; - -/* Class = "NSTextFieldCell"; title = "In case of questions please contact our support via id.ee"; ObjectID = "VD0-B1-6pa"; */ -"VD0-B1-6pa.title" = "Küsimuste korral pöörduge id.ee"; - -/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ -"Vdr-fp-XzO.title" = "Hide Others"; - -/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ -"hz9-B4-Xy5.title" = "Services"; - -/* Class = "NSMenu"; title = "EstEIDTokenApp"; ObjectID = "uQy-DD-JDr"; */ -"uQy-DD-JDr.title" = "EstEIDTokenApp"; diff --git a/EstEIDTokenApp/mul.lproj/MainMenu.xcstrings b/EstEIDTokenApp/mul.lproj/MainMenu.xcstrings new file mode 100644 index 0000000..9896f94 --- /dev/null +++ b/EstEIDTokenApp/mul.lproj/MainMenu.xcstrings @@ -0,0 +1,342 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "1Xt-HY-uBw.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"EstEIDTokenApp\"; ObjectID = \"1Xt-HY-uBw\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "EstEIDTokenApp" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "EstEIDTokenApp" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "EstEIDTokenApp" + } + } + } + }, + "4sb-4s-VLi.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Quit EstEIDTokenApp\"; ObjectID = \"4sb-4s-VLi\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Quit EstEIDTokenApp" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quit EstEIDTokenApp" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quit EstEIDTokenApp" + } + } + } + }, + "5kV-Vb-QxS.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"About EstEIDTokenApp\"; ObjectID = \"5kV-Vb-QxS\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "About EstEIDTokenApp" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "About EstEIDTokenApp" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "About EstEIDTokenApp" + } + } + } + }, + "9Pp-ko-iP0.title" : { + "comment" : "Class = \"NSTextFieldCell\"; title = \"Version: 1.0.0\"; ObjectID = \"9Pp-ko-iP0\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Version: 1.0.0" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Versioon: 1.0.0" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version: 1.0.0" + } + } + } + }, + "AYu-sK-qS6.title" : { + "comment" : "Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Main Menu" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Main Menu" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Main Menu" + } + } + } + }, + "BOF-NM-1cW.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Preferences…" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferences…" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferences…" + } + } + } + }, + "hz9-B4-Xy5.title" : { + "comment" : "Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Services" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + } + } + }, + "Kd2-mp-pUS.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Show All" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show All" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show All" + } + } + } + }, + "NMo-om-nkz.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Services" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + } + } + }, + "Olw-nP-bQN.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Hide EstEIDTokenApp\"; ObjectID = \"Olw-nP-bQN\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hide EstEIDTokenApp" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide EstEIDTokenApp" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide EstEIDTokenApp" + } + } + } + }, + "QvC-M9-y7g.title" : { + "comment" : "Class = \"NSWindow\"; title = \"EstEIDToken\"; ObjectID = \"QvC-M9-y7g\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "EstEIDToken" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "EstEIDToken" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "EstEIDToken" + } + } + } + }, + "uQy-DD-JDr.title" : { + "comment" : "Class = \"NSMenu\"; title = \"EstEIDTokenApp\"; ObjectID = \"uQy-DD-JDr\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "EstEIDTokenApp" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "EstEIDTokenApp" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "EstEIDTokenApp" + } + } + } + }, + "VD0-B1-6pa.title" : { + "comment" : "Class = \"NSTextFieldCell\"; title = \"In case of questions please contact our support via id.ee\"; ObjectID = \"VD0-B1-6pa\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "In case of questions please contact our support via id.ee" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Küsimuste korral pöörduge id.ee" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Если у вас возникнут вопросы, пожалуйста, обратитесь на id.ee" + } + } + } + }, + "Vdr-fp-XzO.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hide Others" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide Others" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide Others" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/EstEIDTokenApp/ru.lproj/MainMenu.strings b/EstEIDTokenApp/ru.lproj/MainMenu.strings deleted file mode 100644 index 1d5fa42..0000000 --- a/EstEIDTokenApp/ru.lproj/MainMenu.strings +++ /dev/null @@ -1,42 +0,0 @@ - -/* Class = "NSMenuItem"; title = "EstEIDTokenApp"; ObjectID = "1Xt-HY-uBw"; */ -"1Xt-HY-uBw.title" = "EstEIDTokenApp"; - -/* Class = "NSMenuItem"; title = "Quit EstEIDTokenApp"; ObjectID = "4sb-4s-VLi"; */ -"4sb-4s-VLi.title" = "Quit EstEIDTokenApp"; - -/* Class = "NSMenuItem"; title = "About EstEIDTokenApp"; ObjectID = "5kV-Vb-QxS"; */ -"5kV-Vb-QxS.title" = "About EstEIDTokenApp"; - -/* Class = "NSTextFieldCell"; title = "Version: 1.0.0"; ObjectID = "9Pp-ko-iP0"; */ -"9Pp-ko-iP0.title" = "Version: 1.0.0"; - -/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ -"AYu-sK-qS6.title" = "Main Menu"; - -/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ -"BOF-NM-1cW.title" = "Preferences…"; - -/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ -"Kd2-mp-pUS.title" = "Show All"; - -/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ -"NMo-om-nkz.title" = "Services"; - -/* Class = "NSMenuItem"; title = "Hide EstEIDTokenApp"; ObjectID = "Olw-nP-bQN"; */ -"Olw-nP-bQN.title" = "Hide EstEIDTokenApp"; - -/* Class = "NSWindow"; title = "EstEIDToken"; ObjectID = "QvC-M9-y7g"; */ -"QvC-M9-y7g.title" = "EstEIDToken"; - -/* Class = "NSTextFieldCell"; title = "In case of questions please contact our support via id.ee"; ObjectID = "VD0-B1-6pa"; */ -"VD0-B1-6pa.title" = "Если у вас возникнут вопросы, пожалуйста, обратитесь на id.ee"; - -/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ -"Vdr-fp-XzO.title" = "Hide Others"; - -/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ -"hz9-B4-Xy5.title" = "Services"; - -/* Class = "NSMenu"; title = "EstEIDTokenApp"; ObjectID = "uQy-DD-JDr"; */ -"uQy-DD-JDr.title" = "EstEIDTokenApp"; diff --git a/EstEIDTokenNotify/AppDelegate.m b/EstEIDTokenNotify/AppDelegate.m index 923f1f2..9bcab25 100644 --- a/EstEIDTokenNotify/AppDelegate.m +++ b/EstEIDTokenNotify/AppDelegate.m @@ -18,51 +18,45 @@ */ #import +#import -@interface AppDelegate : NSObject +@interface AppDelegate : NSObject @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)notification { + UNUserNotificationCenter *center = UNUserNotificationCenter.currentNotificationCenter; + UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; + [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError *error) { + if (granted) { + NSLog(@"EstEIDTokenNotify: requestAuthorizationWithOptions %i %@", granted, error); + } + }]; [NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(notificationEvent:) name:@"EstEIDTokenNotify" object:nil]; } -(void)notificationEvent:(NSNotification *)notification { - NSLog(@"EstEIDTokenNotify: notificationEvent %@", notification.object); - NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter; + UNUserNotificationCenter *center = UNUserNotificationCenter.currentNotificationCenter; if (notification.object != nil) { NSArray *list = [(NSString*)notification.object componentsSeparatedByString:@"\n"]; - NSUserNotification *ui = [NSUserNotification new]; + UNMutableNotificationContent *ui = [UNMutableNotificationContent new]; ui.title = list[0]; if (list.count > 1) { ui.subtitle = list[1]; } - ui.hasActionButton = NO; - ui.soundName = NSUserNotificationDefaultSoundName; - center.delegate = self; - [center deliverNotification:ui]; + //ui.hasActionButton = NO; + ui.sound = UNNotificationSound.defaultSound; + NSString *uuidString = NSUUID.UUID.UUIDString; + UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:uuidString content:ui trigger:nil]; + [center addNotificationRequest:request withCompletionHandler:^(NSError *error) { + NSLog(@"EstEIDTokenNotify: addNotificationRequest %@", error); + }]; } else { [center removeAllDeliveredNotifications]; } } -- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification -{ - NSLog(@"EstEIDTokenNotify: didDeliverNotification %d", notification.isPresented); -} - -- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification -{ - NSLog(@"EstEIDTokenNotify: didActivateNotification"); -} - -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification -{ - NSLog(@"EstEIDTokenNotify: shouldPresentNotification"); - return YES; -} - @end diff --git a/EstEIDTokenNotify/Info.plist b/EstEIDTokenNotify/Info.plist deleted file mode 100644 index a5f5e0d..0000000 --- a/EstEIDTokenNotify/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - LSBackgroundOnly - - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSMainStoryboardFile - Main - NSPrincipalClass - NSApplication - - diff --git a/EstEIDTokenNotify/et.lproj/Main.strings b/EstEIDTokenNotify/et.lproj/Main.strings deleted file mode 100644 index 0334e57..0000000 --- a/EstEIDTokenNotify/et.lproj/Main.strings +++ /dev/null @@ -1,33 +0,0 @@ - -/* Class = "NSMenuItem"; title = "Notify"; ObjectID = "1Xt-HY-uBw"; */ -"1Xt-HY-uBw.title" = "Notify"; - -/* Class = "NSMenuItem"; title = "Quit Notify"; ObjectID = "4sb-4s-VLi"; */ -"4sb-4s-VLi.title" = "Quit Notify"; - -/* Class = "NSMenuItem"; title = "About Notify"; ObjectID = "5kV-Vb-QxS"; */ -"5kV-Vb-QxS.title" = "About Notify"; - -/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ -"AYu-sK-qS6.title" = "Main Menu"; - -/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ -"BOF-NM-1cW.title" = "Preferences…"; - -/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ -"Kd2-mp-pUS.title" = "Show All"; - -/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ -"NMo-om-nkz.title" = "Services"; - -/* Class = "NSMenuItem"; title = "Hide Notify"; ObjectID = "Olw-nP-bQN"; */ -"Olw-nP-bQN.title" = "Hide Notify"; - -/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ -"Vdr-fp-XzO.title" = "Hide Others"; - -/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ -"hz9-B4-Xy5.title" = "Services"; - -/* Class = "NSMenu"; title = "Notify"; ObjectID = "uQy-DD-JDr"; */ -"uQy-DD-JDr.title" = "Notify"; diff --git a/EstEIDTokenNotify/mul.lproj/Main.xcstrings b/EstEIDTokenNotify/mul.lproj/Main.xcstrings new file mode 100644 index 0000000..c3479e8 --- /dev/null +++ b/EstEIDTokenNotify/mul.lproj/Main.xcstrings @@ -0,0 +1,270 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "1Xt-HY-uBw.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Notify\"; ObjectID = \"1Xt-HY-uBw\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Notify" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notify" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notify" + } + } + } + }, + "4sb-4s-VLi.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Quit Notify\"; ObjectID = \"4sb-4s-VLi\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Quit Notify" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quit Notify" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quit Notify" + } + } + } + }, + "5kV-Vb-QxS.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"About Notify\"; ObjectID = \"5kV-Vb-QxS\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "About Notify" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "About Notify" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "About Notify" + } + } + } + }, + "AYu-sK-qS6.title" : { + "comment" : "Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Main Menu" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Main Menu" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Main Menu" + } + } + } + }, + "BOF-NM-1cW.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"BOF-NM-1cW\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Preferences…" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferences…" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Preferences…" + } + } + } + }, + "hz9-B4-Xy5.title" : { + "comment" : "Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"hz9-B4-Xy5\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Services" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + } + } + }, + "Kd2-mp-pUS.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"Kd2-mp-pUS\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Show All" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show All" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Show All" + } + } + } + }, + "NMo-om-nkz.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"NMo-om-nkz\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Services" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Services" + } + } + } + }, + "Olw-nP-bQN.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Hide Notify\"; ObjectID = \"Olw-nP-bQN\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hide Notify" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide Notify" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide Notify" + } + } + } + }, + "uQy-DD-JDr.title" : { + "comment" : "Class = \"NSMenu\"; title = \"Notify\"; ObjectID = \"uQy-DD-JDr\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Notify" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notify" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Notify" + } + } + } + }, + "Vdr-fp-XzO.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"Vdr-fp-XzO\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hide Others" + } + }, + "et" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide Others" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hide Others" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/EstEIDTokenNotify/ru.lproj/Main.strings b/EstEIDTokenNotify/ru.lproj/Main.strings deleted file mode 100644 index 0334e57..0000000 --- a/EstEIDTokenNotify/ru.lproj/Main.strings +++ /dev/null @@ -1,33 +0,0 @@ - -/* Class = "NSMenuItem"; title = "Notify"; ObjectID = "1Xt-HY-uBw"; */ -"1Xt-HY-uBw.title" = "Notify"; - -/* Class = "NSMenuItem"; title = "Quit Notify"; ObjectID = "4sb-4s-VLi"; */ -"4sb-4s-VLi.title" = "Quit Notify"; - -/* Class = "NSMenuItem"; title = "About Notify"; ObjectID = "5kV-Vb-QxS"; */ -"5kV-Vb-QxS.title" = "About Notify"; - -/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ -"AYu-sK-qS6.title" = "Main Menu"; - -/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ -"BOF-NM-1cW.title" = "Preferences…"; - -/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ -"Kd2-mp-pUS.title" = "Show All"; - -/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ -"NMo-om-nkz.title" = "Services"; - -/* Class = "NSMenuItem"; title = "Hide Notify"; ObjectID = "Olw-nP-bQN"; */ -"Olw-nP-bQN.title" = "Hide Notify"; - -/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ -"Vdr-fp-XzO.title" = "Hide Others"; - -/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ -"hz9-B4-Xy5.title" = "Services"; - -/* Class = "NSMenu"; title = "Notify"; ObjectID = "uQy-DD-JDr"; */ -"uQy-DD-JDr.title" = "Notify";