Objective c 如何自动激活OS X服务菜单中的项目

Objective c 如何自动激活OS X服务菜单中的项目,objective-c,cocoa,macos,Objective C,Cocoa,Macos,我需要在“服务”菜单中默认启用我创建的服务 我已经为我的OSX应用程序(在雪豹上运行)创建了一个服务。我对Info.plist进行了如下配置: <key>NSServices</key> <array> <dict> <key>NSSendTypes</key> <array> <string>NSStringPboardType<

我需要在“服务”菜单中默认启用我创建的服务

我已经为我的OSX应用程序(在雪豹上运行)创建了一个服务。我对Info.plist进行了如下配置:

<key>NSServices</key>
<array>
    <dict>
        <key>NSSendTypes</key>
        <array>
            <string>NSStringPboardType</string>
        </array>
        <key>NSMessage</key>
        <string>dropService</string>
        <key>NSMenuItem</key>
        <dict>
            <key>default</key>
            <string>Drop Service</string>
        </dict>
        <key>NSPortName</key>
        <string>MyApp</string>
    </dict>
</array>
现在我的服务显示在“系统首选项->键盘->键盘快捷键->服务”下。所以系统知道这一点。但除非我手动激活它,否则它不会显示在“服务”菜单中

当我尝试调试服务时,会收到以下消息:

/Applications/TextEdit.app/Contents/MacOS/TextEdit -NSDebugServices com.myapp.MyApp
Drop Service (com.myapp.MyApp) is disabled in the services menu and disabled in the context menu, by the standard Services policy.
我不知道“标准服务政策”是什么,在苹果开发者网站上也找不到任何关于这个错误的参考

我认为自动启用服务项是不可能的,但我已经确认某些应用程序可以做到这一点(比如来自培养代码的东西),所以我知道这是可以做到的


有什么想法吗?

我不知道有什么公共API可以做到这一点,但我找到了一种解决方法。所有激活服务的列表保存在

~/Library/Preferences/pbs.plist
您只需添加一个条目并重置
pbs
。我正在使用以下代码段:

NSString*pbsPlistPath=[@"~/Library/Preferences/pbs.plist" stringByExpandingTildeInPath];
NSMutableDictionary*dict=[NSPropertyListSerialization 
                                  propertyListFromData:[NSData dataWithContentsOfFile:pbsPlistPath]
                                    mutabilityOption:NSPropertyListMutableContainers
                                                format:NULL
                                      errorDescription:NULL];
NSMutableDictionary*status=[dict objectForKey:@"NSServicesStatus"];
if(!status){
    status=[NSMutableDictionary dictionary];
    [dict setObject:status forKey:@"NSServicesStatus"];
}
if(status){
    NSMutableDictionary*m=[NSMutableDictionary dictionary];
    [m setObject:[NSNumber numberWithBool:YES] forKey:@"enabled_context_menu"];
    [m setObject:[NSNumber numberWithBool:YES] forKey:@"enabled_services_menu"];
    [status setObject:m
               forKey:@"com.my.app - Drop Service - dropService"];
}
NSData* data=[NSPropertyListSerialization dataWithPropertyList:dict
                                                        format:NSPropertyListBinaryFormat_v1_0
                                                       options:0
                                                         error:NULL];
[data writeToFile:pbsPlistPath atomically:YES];
system("/System/Library/CoreServices/pbs -flush");
system("/System/Library/CoreServices/pbs -flush_userdefs");

让您的服务在默认情况下启用而不攻击任何系统plist的正确方法是编辑您自己的plist。具体而言,在每个服务字典中添加
NSRequiredContext
键。这个信息来源于


至于需要为该键提供的值,.

只需在Info.plist中添加一个NSRequiredContext键,并将一个空白字典作为其对象。下面是它的外观:

<key>NSRequiredContext</key>
<dict>
</dict>
NSRequiredContext

我尝试了这个方法,但仍然无法自动激活它们。可能我做错了什么。Levi Nunnink:请编辑您的问题,将更新的服务词典包括在内,并包括NSRequiredContext。好的,NSRequiredContext确实有效。pbs正在为我的计算机上的旧版本编制索引。如果您想指定所需的上下文,请使用非空白字典。我无法确定要添加什么(文档中的任何限制都没有真正应用)。一本空白字典会影响这种行为,这对我来说没有多大意义,但确实如此。感谢您的回答。需要注意的是,此条目需要添加到服务数组的字典中,而不是添加到Info.plist的根目录中(Peter Hosey更清楚地指出了这一点)。
<key>NSRequiredContext</key>
<dict>
</dict>