我的应用程序提供全球服务。我想用command-alt-key组合安装服务。我现在做的事情不是很容易出错,而且很难调试,因为我们没有看到发生了什么:
inside Info.plist:
<key>NSServices</key>
<array>
<dict>
<key>NSSendTypes</key>
<array>
<string></string>
</array>
<key>NSReturnTypes</key>
<array>
<string></string>
</array>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Go To Window in ${PRODUCT_NAME}</string>
</dict>
<key>NSMessage</key>
<string>bringZFToForegroundZoomOut</string>
<key>NSPortName</key>
<string>com.raskinformac.${PRODUCT_NAME:identifier}</string>
</dict>
</array>
并在代码中:
CFStringRef serviceStatusName = (CFStringRef)[NSString stringWithFormat:@"%@ - %@ - %@", appIdentifier, appName, methodNameForService];
CFStringRef serviceStatusRoot = CFSTR("NSServicesStatus");
CFPropertyListRef pbsAllServices = (CFPropertyListRef) CFMakeCollectable ( CFPreferencesCopyAppValue(serviceStatusRoot, CFSTR("pbs")) );
// the user did not configure any custom services
BOOL otherServicesDefined = pbsAllServices != NULL;
BOOL ourServiceDefined = NO;
if ( otherServicesDefined ) {
ourServiceDefined = NULL != CFDictionaryGetValue((CFDictionaryRef)pbsAllServices, serviceStatusName);
}
NSUpdateDynamicServices();
NSMutableDictionary *pbsAllServicesNew = nil;
if (otherServicesDefined) {
pbsAllServicesNew = [NSMutableDictionary dictionaryWithDictionary:(NSDictionary*)pbsAllServices];
} else {
pbsAllServicesNew = [NSMutableDictionary dictionaryWithCapacity:1];
}
NSDictionary *serviceStatus = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, @"enabled_context_menu",
(id)kCFBooleanTrue, @"enabled_services_menu",
@"@~r", @"key_equivalent", nil];
[pbsAllServicesNew setObject:serviceStatus forKey:(NSString*)serviceStatusName];
CFPreferencesSetAppValue (
serviceStatusRoot,
(CFPropertyListRef) pbsAllServicesNew,
CFSTR("pbs"));
Boolean result = CFPreferencesAppSynchronize(CFSTR("pbs"));
if (result) {
NSUpdateDynamicServices();
JLog(@"successfully installed our alt-command-R service");
} else {
ALog(@"couldn't install our alt-command-R service");
}
并更改服务:
// once installed, its's a bit tricky to set new ones (works only in RELEASE somehow?)
// quit finder
// open "~/Library/Preferences/pbs.plist" and remove ch.ana.Zoom - Reveal Window in Zoom - bringZFToForegroundZoomOut inside NSServicesStatus and save
// start app
// /System/Library/CoreServices/pbs -dump_pboard (to see if it hat actually done what we wanted, might be empty)
// /System/Library/CoreServices/pbs (to add the new services)
// /System/Library/CoreServices/pbs -dump_pboard (see new linking)
// and then /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder -NSDebugServices MY.APP.IDENTIFIER to restart finder
所以我的问题是:是否有更简单的方法来使用cmd-option-key启用服务?如果是的话,我很乐意在我的软件中实现它。
答案 0 :(得分:1)
您可以尝试使用'〜'设置密钥等效字符串作为服务字典中NSKeyEquivalent
的值。 Services Implementation Guide声称它必须是单个字符,但我认为值得尝试完整的密钥等效字符串。
请记住,与NSMenuItem一样,它必须包含在字典中:
<key>NSKeyEquivalent</key>
<dict>
<key>default</key>
<string>~r</string>
</dict>
(我省略了'@';如果没有它就行不通,你可以试试吧。)
如果确实有效,我建议filing a bug反对文档。
Apple可能希望所有服务都使用⌘-something或⇧⌘-something等效键,为菜单项和全局热键保留其他修饰符。所以,虽然我尝试了上述内容,但如果不起作用,我也不会感到惊讶。
答案 1 :(得分:1)
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Go To Window in ${PRODUCT_NAME}</string>
</dict>
并且serviceStatusName的中间组件必须完全相同。我改变了问题中的代码。
NSString *appServiceName = @"Go To Window in ${PRODUCT_NAME}"
CFStringRef serviceStatusName = (CFStringRef)[NSString stringWithFormat:@"%@ - %@ - %@", appIdentifier, appServiceName, methodNameForService];