在 Finder 上下文中建立服务
Establish a service in Finder context
我正在尝试使用此 class:
向 Finder 的上下文菜单添加服务
public class Service {
public func handleServices(pboard:NSPasteboard, userData:String, error:UnsafeMutableBufferPointer<String>) { // not sure about the correct parameters
if (pboard.types?.contains(NSFilenamesPboardType) != nil) {
let fileArray = pboard.propertyListForType(NSFilenamesPboardType)
print(fileArray)
}
}
init () {
NSApp.servicesProvider = self
NSUpdateDynamicServices()
}
}
服务于info.plist公布如下:
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Service Handling Demo</string>
</dict>
<key>NSMessage</key>
<string>handleServices</string>
<key>NSPortName</key>
<string>services</string>
<key>NSSendTypes</key>
<array>
<string>NSFilenamesPboardType</string>
</array>
</dict>
</array>
终于在系统Preferences/Keyboard/Shortcuts中开启了服务。所以我看到了服务并可以调用它。但是我调用它时得到的只是
Cannot find service provider for selector handleServices:userData:error: or handleServices:: for service handleServices
尝试像这样在您的方法中为变量创建别名。
public func handleServices(pboard:NSPasteboard, userData userData:String, error error:UnsafeMutableBufferPointer<String>)
你的代码有两个问题:
Objective-C 消息 被发送到服务提供商,因此 Swift
方法必须是 "Objective-C compatible"。这可以通过子类化来实现
NSObject
,或通过使用 @objc
属性标记方法。
服务处理程序方法具有签名
- (void)handleServices:(NSPasteboard *)pboard
userData:(NSString *)userData
error:(NSString **)error
映射到 Swift 为
func handleServices(pboard: NSPasteboard!,
userData: String!,
error: AutoreleasingUnsafeMutablePointer<NSString?>)
所以这将是一个正确的版本(在我的测试中有效):
public class Service {
@objc public func handleServices(pboard: NSPasteboard!,
userData: String!, error: AutoreleasingUnsafeMutablePointer<NSString?>) {
// ...
}
init() {
NSApp.servicesProvider = self
NSUpdateDynamicServices()
}
}
一些补充说明:
if (pboard.types?.contains(NSFilenamesPboardType) != nil) { ... }
是 "optional chaining" 并检查是否可以在 pboard.types
上调用 contains()
方法,
换句话说,它只检查 pboard.types != nil
。你可能想要什么
是检查 pboard.types != nil
和 contains()
方法 returns true
。
这可以通过 "nil-coalescing operator" ??
:
来实现
if (pboard.types?.contains(NSFilenamesPboardType) ?? false) { ... }
接下来,
pboard.propertyListForType(NSFilenamesPboardType)
被记录为 return 一个可选的 NSString
数组,因此您可以解包
并将其转换为 String
数组
if let fileArray = pboard.propertyListForType(NSFilenamesPboardType) as? [String] { ... }
最后,分配一个错误字符串(给
来电者)将完成
if (error != nil) {
error.memory = "My error description"
}
收到相同的错误 (Swift 3.1)。在本主题中尝试了所有方法,但没有任何帮助。找到解决方案 here
从这里更改代码
@objc public func handleServices(pboard: NSPasteboard!,
userData: String!, error: AutoreleasingUnsafeMutablePointer<NSString?>)
到这个
@objc public func handleServices(_ pboard: NSPasteboard,
userData: String, error:AutoreleasingUnsafeMutablePointer<NSString>)
而且有效。
我正在尝试使用此 class:
向 Finder 的上下文菜单添加服务public class Service {
public func handleServices(pboard:NSPasteboard, userData:String, error:UnsafeMutableBufferPointer<String>) { // not sure about the correct parameters
if (pboard.types?.contains(NSFilenamesPboardType) != nil) {
let fileArray = pboard.propertyListForType(NSFilenamesPboardType)
print(fileArray)
}
}
init () {
NSApp.servicesProvider = self
NSUpdateDynamicServices()
}
}
服务于info.plist公布如下:
<key>NSServices</key>
<array>
<dict>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Service Handling Demo</string>
</dict>
<key>NSMessage</key>
<string>handleServices</string>
<key>NSPortName</key>
<string>services</string>
<key>NSSendTypes</key>
<array>
<string>NSFilenamesPboardType</string>
</array>
</dict>
</array>
终于在系统Preferences/Keyboard/Shortcuts中开启了服务。所以我看到了服务并可以调用它。但是我调用它时得到的只是
Cannot find service provider for selector handleServices:userData:error: or handleServices:: for service handleServices
尝试像这样在您的方法中为变量创建别名。
public func handleServices(pboard:NSPasteboard, userData userData:String, error error:UnsafeMutableBufferPointer<String>)
你的代码有两个问题:
Objective-C 消息 被发送到服务提供商,因此 Swift 方法必须是 "Objective-C compatible"。这可以通过子类化来实现
NSObject
,或通过使用@objc
属性标记方法。服务处理程序方法具有签名
- (void)handleServices:(NSPasteboard *)pboard userData:(NSString *)userData error:(NSString **)error
映射到 Swift 为
func handleServices(pboard: NSPasteboard!, userData: String!, error: AutoreleasingUnsafeMutablePointer<NSString?>)
所以这将是一个正确的版本(在我的测试中有效):
public class Service {
@objc public func handleServices(pboard: NSPasteboard!,
userData: String!, error: AutoreleasingUnsafeMutablePointer<NSString?>) {
// ...
}
init() {
NSApp.servicesProvider = self
NSUpdateDynamicServices()
}
}
一些补充说明:
if (pboard.types?.contains(NSFilenamesPboardType) != nil) { ... }
是 "optional chaining" 并检查是否可以在 pboard.types
上调用 contains()
方法,
换句话说,它只检查 pboard.types != nil
。你可能想要什么
是检查 pboard.types != nil
和 contains()
方法 returns true
。
这可以通过 "nil-coalescing operator" ??
:
if (pboard.types?.contains(NSFilenamesPboardType) ?? false) { ... }
接下来,
pboard.propertyListForType(NSFilenamesPboardType)
被记录为 return 一个可选的 NSString
数组,因此您可以解包
并将其转换为 String
数组
if let fileArray = pboard.propertyListForType(NSFilenamesPboardType) as? [String] { ... }
最后,分配一个错误字符串(给 来电者)将完成
if (error != nil) {
error.memory = "My error description"
}
收到相同的错误 (Swift 3.1)。在本主题中尝试了所有方法,但没有任何帮助。找到解决方案 here
从这里更改代码
@objc public func handleServices(pboard: NSPasteboard!,
userData: String!, error: AutoreleasingUnsafeMutablePointer<NSString?>)
到这个
@objc public func handleServices(_ pboard: NSPasteboard,
userData: String, error:AutoreleasingUnsafeMutablePointer<NSString>)
而且有效。