Provide an OSX Service Without Launching the App?

2019-04-13 09:02发布

I have successfully implemented a "faceless service" (background-only app with .service extension) and get it to work (see this question), based on Apple's documentation and other tutorials on the web.

Now, I want to advertise a service from an existing, single-window GUI app that I have.

I have setup the Info.plist file of my app to advertise the service, and it gets installed when I build the app.

But when I invoke the service from the context menu in (say) TextEdit.app (my service colours the selected text based on a certain criterion), my app gets launched, main window and everything. To make things worse, I am right-clicking on a TextEdit window that is in a secondary monitor, so my app's main window appears for an instant in the secondary monitor, then quickly repositions into the main monitor (this might have something to do with my window-centering logic, but nevermind...).

I would like to provide the service (i.e., have the class that provides the service in my app instantiated and execute its method in response to the request), without my app appearing on the Dock or showing its window and main menu.

Is this possible? Safari advertises "Search With Google", so it should be possible...

EDIT: Now that I think about it, "Search With Google" must launch Safari every time in order to work, so this remark does not apply.

Perhaps I can put some logic in -applicationWillFinishLaunching/-applicationDidFinishLaunching to determine if the app is being launched in response to a service, and skip creating the window(notice the lack of withOptions: in OSX)?

But still, that doesn't feel right.

1条回答
Evening l夕情丶
2楼-- · 2019-04-13 09:45

It does have a lame version of withOptions: -- NSApplicationLaunchIsDefaultLaunchKey tells you if your application was launched to either:

open or print a file, to perform a Service action, if the app had saved state that will be restored, or if the app launch was in some other sense not a default launch

So in your applicationDidFinishLaunching you can see if that key is in the notification and set to NO. Unfortunately, the main way to tell that it is one of the possibilities other than the Service, you have to detect and record whether or not you also got an application:openFile:, etc.

查看更多
登录 后发表回答