私はそれが動作していないと思うように導くいくつかの小さな間違いを作ったようです。しかし、結局私はそれを機能させることができました。ですから、ここでは、同じタスクに直面している場合スウィフト3におけるソリューションです:
(1)あなたは、サービスメソッドを実装する必要があります。私は前に知りませんでした
import Cocoa
class ServiceProvider: NSObject {
let errorMessage = NSString(string: "Could not find the text for parsing.")
func service(_ pasteboard: NSPasteboard, userData: String?, error: AutoreleasingUnsafeMutablePointer<NSString>) {
guard let str = pasteboard.string(forType: NSStringPboardType) else {
error.pointee = errorMessage
return
}
let alert = NSAlert()
alert.messageText = "Hello \(str)"
alert.informativeText = "Welcome in the service"
alert.addButton(withTitle: "OK")
alert.runModal()
}
}
ここで重要なことは、ということでしたサービスを提供するオブジェクトはNSObjectをサブクラス化する必要があります(ViewControllerまたは他のNSObjectサブクラスでもあります)。サービスAPIはセレクタを使用してそれを呼び出し、セレクタテクノロジはNSObjectのみで動作します。ラベル付けされていない、それは(あなたがPasteboard
を使用することができますが、それはstring
方法を提供していない)NSPasteboard
である第一、3つの引数を取り、第二第三、userData
ラベルオプションString
です:
また、service
方法は、この宣言を持たなければなりませんerror
とラベルされたAutoreleasingUnsafeMutablePointer<NSString>
。これを続けて、最良の型安全性を得るには、それを動作させます。それ以外の場合、サービスAPIはそれを見つけて呼び出すことができません。すべての引数にUnsafeRawPointers
を使用できますが、それでも何も得られません。
(2)アプリデリゲートで(またはドキュメントあなたはどこにでもそれを行うことができますことを言いますが、私はここでそれをやっている)を使用すると、サービス・プロバイダーを登録します。
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
NSApplication.shared().servicesProvider = ServiceProvider()
NSUpdateDynamicServices()
}
}
それはNSUpdateDynamicServices
なしにも動作しているようです申し訳ありませんが、あなたが現在のサービスバージョンを取得するためにログオフしてログインする必要がないように、システム内のサービスを更新する必要があります。
(3)最後に、あなたのサービスメソッドを宣伝するためにInfo.plistファイルを設定する必要があります。
<key>NSServices</key>
<array>
<dict>
<key>NSMessage</key>
<string>service</string>
<key>NSPortName</key>
<string>serviceTest</string>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Test hello world</string>
</dict>
<key>NSRestricted</key>
<false/>
<key>NSRequiredContext</key>
<dict/>
<key>NSSendTypes</key>
<array>
<string>NSStringPboardType</string>
</array>
</dict>
</array>
これは、Info.plistファイルのXMLソースである - Appleがで、彼らのエディタを使用することを推奨していますが、 Xcode 8.2エディタでNSRequiredContext
キーを追加できませんでした。ファイルをソースコードとして開いて手動で追加する必要がありました。 XMLソースを直接編集することをお勧めします。
各キーの意味に関するドキュメントはServices Propertiesにありますが、いくつかの重要な点についてお伝えしたいと思います。まず、NSRequiredContext
キーが必要です。ドキュメントに記述されていますが、エディタではサポートされていません。XMLを直接編集し、空のままで追加します(私のように)。第二に、NSSendTypes
またはNSReturnTypes
を使用していて、文字列を扱いたい場合、documentationには推奨されておらず、NSPasteboardTypeString
で置き換える必要がありますが、NSStringPboardType
を使用してください。後者は機能しません。最後に、service
値のNSMessage
キーがサービスメソッドの名前です。私はNSMessage
でservice
値を使用しています
func service(_ pasteboard: NSPasteboard, userData: String?, error: AutoreleasingUnsafeMutablePointer<NSString>)
:だから、私のサービスプロバイダオブジェクトは、メソッドを次のように宣言します。これを変更したい場合(たとえば、いくつかのサービスメソッドが必要な場合)、これら2つが一致していることを忘れないでください(Info.plist設定の値とサービスメソッドの名前)。
(4)この状態で動作しているはずです。デバッグに役立つと言いたいことが1つあります。実行することによって、最後にdocumentationに記載の方法を使用して、それをテストします。
/Applications/TextEdit.app/Contents/MacOS/TextEdit -NSDebugServices com.mycompany.myapp
ターミナルからこれを実行すると、提供するバンドルを使用して任意のサービスが登録されているかどうか、また、それが提示されるかどうかを報告しなければならない - 例えば、私の場合には問題は私が義務的なNSRequiredContext
を提供していないということでした。このアプローチを使用してテストしたところ、サービスがインストールされたことを認識することができました。問題は、サービスAPIがフィルタリングする必要があると判断されたことでした。いくつかの実験とグーグル・グーグルの後、私は空を追加して解決したNSRequiredContext
。
サービスを変更するたびに、TextEditを終了してもう一度実行することをお勧めします。古いサービスプロバイダオブジェクトへの参照を保持しているようです(再起動しなければTextEditによって変更が登録されませんでしたそれ)。