I'm trying to create an OS X Service. I found Providing System Services in Apple's documentation, however I'm finding it less than clear on what exactly I need to do. I'm currently using an application to register my service (thinking that would be more straight forward - eventually I'd like to create a .service), however even after a logout/login my service still doesn't appear in the list of services in the menu.
Is there some step missing from the linked document that I'm missing? I feel like there is some registration step so that the OS knows about my service (in addition to what is listed in that doc), but I'm not able to find anything.
Thanks in advance. :)
Edit: Here is my NSServices dictionary from my Info.plist file:
<key>NSServices</key>
<array>
<dict>
<key>NSPortName</key>
<string>POPrlTest</string>
<key>NSMessage</key>
<string>shortenUrlService</string>
<key>NSSendTypes</key>
<string>NSStringPboardType</string>
<key>NSReturnTypes</key>
<string>NSStringPboardType</string>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Shorten URL</string>
</dict>
</dict>
</array>
Make sure your NSServices dictionary has everything it needs. If you're not sure, please post it so we can tell you.
Make sure you are launching your app first to get the system to see the Service.
Make sure you are registering the services handler in your app using
- setServicesProvider:
Also, check the Console log as that might give you some useful error info.
You might want to look at some commercial products to help you with this. See this posting on Fun Script.
Related
For my KEXT I set the property “Protocol Characteristics” in Info.plist file
<key>Protocol Characteristics</key>
<dict>
<key>Physical Interconnect</key>
<string>SAS</string>
<key>Physical Interconnect Location</key>
<string>External</string>
</dict>
For DEXT this method does not work - still my SCSI device has “Internal/External” property instead of “External”
Protocol Characteristics
<dict>
<key>Physical Interconnect</key>
<string>SCSI Parallel Interface</string>
<key>Physical Interconnect Location</key>
<string>Internal/External</string>
</dict>
I also tried to set these properties by the second parameter for UserCreateTargetForId(). It also did not work.
Does anybody know how to set the property?
I assume this is for a dext implementing IOUserSCSIParallelInterfaceController?
I've not tested it myself, but have you tried calling UserSetTargetProperties() in your controller?
Update OS to current state and setup properties by using 'Info.plist' has worked correct for me.
I am developing a Mac app that makes use of App Scripting. The is Sandboxed and thus needs the proper entitlements in order to get permissions to send AppleScript events to other apps. I have gotten this working properly for apps (like Mail and spotify) which specify access-group identifiers like this:
<access-group identifier="com.apple.mail.compose" access="rw"/>
<access-group identifier="com.spotify.playback"/>
However, a few other of the Apple made apps (like Xcode) specify their identifiers like this:
<access-group identifier="*"/>
I have tried to configure my entitlement file like this:
<key>com.apple.security.scripting-targets</key>
<dict>
<key>com.apple.dt.Xcode</key>
<array>
<string>*</string>
</array>
</dict>
, but when doing this it does not work and I get this error message in the console:
AppleEvents/sandbox: Returning errAEPrivilegeError/-10004 and denying dispatch of event xcod/buld from process '-------'/0x0-0x1a05a04, pid=82514, because it is not entitled to send an AppleEvent to this process.
Does anyone know how to properly configure this?
Actually I found the answer myself. In the sdef Man pages it states:
An identifier of "*" means the element is usable by any application,
without an explicit entitlement.
This means that you do not have to add the identifiers in your entitlements file and it should work regardless. The reason why I got the error was because I accidentally used commands that were not included in those particular access-groups.
I am trying to watch a directory for changes via launchd. My plist
file looks like this:
<key>ProgramArguments</key>
<array>
<string>/Users/myname/bin/boink</string>
<string>path modified</string>
</array>
All this works OK, but I would like to pass the name of the file that
was changed as an argument to the script /Users/myname/bin/boink
Is that possible? the man page isn't very helpful, nor did googling help a lot.
Thanks.
The short answer is: no. launchd(8) uses Kqueue (http://en.wikipedia.org/wiki/Kqueue) to receive this kind of notification. Unfortunately kqueue(2) does not return which item has triggered the event.
You may want to use the launchd(8) key QueueDirectories instead. It works essentially the same way WatchPaths works, but it assumes that the processing agent/daemon is moving the processed items from the directory being monitored to another one. So whenever an event is triggered your job can process every file in the monitored directory. Just make sure you move them after processing.
Should be relatively straightforward, but I can't seem to find anything on this - I'm trying to add a URL handler to a Cocoa-Applescript application, as described here:
http://www.macosxautomation.com/applescript/linktrigger/index.html
Except that example doesn't seem to work in an Xcode/Cocoa-Applescript application.
In my AppDelegate.applescript, after applicationDidFinishLaunching_ I've got:
on open location this_URL
tell me to log "this_URL: " & this_URL
end open location
And I've added all the CFBundleURLTypes/CFBundleURLschemes stuff in info.plist.
The latter seems to be working, as my app activates when I click a myAppScheme:// link.
But the log statement doesn't fire.
I also tried stuff like on handleGetURLEvent_(this_URL) but I'm kind of just guessing at this point :)
Any help much appreciated..
Solved! (The 'magic number' below is due to a bug in ASObjc stuff).
on applicationDidFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
-- Register the URL Handler stuff
tell current application's NSAppleEventManager's sharedAppleEventManager() to setEventHandler_andSelector_forEventClass_andEventID_(me, "handleGetURLEvent:", current application's kInternetEventClass, current application's kAEGetURL)
-- all your other application startup stuff..
end applicationDidFinishLaunching_
-- handler that runs when the URL is clicked
on handleGetURLEvent_(ev)
set urlString to (ev's paramDescriptorForKeyword_(7.57935405E+8)) as string
tell me to log "urlString: " & urlString
-- do stuff with 'Set AppleScript's text item delimiters to "foo="', and then "&" etc, to parse your parameters out of the URL String
end handleGetURLEvent_
And your info.plist needs to be in the form:
<key>CFBundleIdentifier</key>
<string>com.myappname</string>
...
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>My App Name Helper</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myappscheme</string>
</array>
</dict>
</array>
Which allows your app to take input from URLs in the form:
myappscheme://com.myappname/?foo=stuff&bar=otherstuff
The whole URL is passed in and and ends up in your 'urlString' variable, so you can parse it however you like. Which means you don't even necessarily have to follow the standard URL conventions like I have above, but you might find it convenient to do so, so that potentially you can support parsing let's say Facebook or Google Maps URLs in your app with a simple change of http:// to myappscheme://
Enjoy/Hope that helps.. :)
I don't use ApplescriptObjC, however in a normal cocoa application see this post which explains how to do it. I'd assume you need to do it like that.
I may be running into something similar. I have an Applescript URL handler that launches but doesn't process the passed URL (just as you've described).
What I found was when another program sends a link, everything functions properly.
When I try to manually send a link via the terminal "open" command, the "on run" handler triggers rather than "on open location" - which unfortunately means I can't get the passed URL.
I am sandboxing an existing application, and for some reasons the migration does not seem to work, although I am following exactly what is specified in the documentation. In summary, here is what I am doing:
I have removed the existing container (in ~/Library/Containers/com.mycompany.myapp);
I have created the container-migration.plist in the Resources group;
I want to migrate a single file, in ~/Application Support: I have tried to specify the file, and the enclosing folder, neither worked. Here is the migration plist that I am using (I have just changed the application name), with the folder:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Move</key>
<array>
<string>${ApplicationSupport}/myapp</string>
</array>
</dict>
</plist>
When I start the application, the new container is created, and a blank file is created but no migration is performed.
The file that I am trying to migrate is a CoreData SQLite store. The data model has not changed so there is no data migration involved, I am simply trying to move the CoreData store to the sandboxed container.
I guess I am missing something very obvious, as I can't find anything useful around, any help will be much appreciated.
Just after posting the question I noticed this error in the system log:
13/11/2012 4:59:59.026 PM sandboxd[55845]: ([55835]) myapp(55835) deny file-read-data /Volumes/Mac_HD/Users/me/Library/Developer/Xcode/DerivedData/myapp-hfgnivbvxutfvcxjmyntrenofdsh/Build/Products/Debug no receipt verif
I tried to copy the application to my Desktop before running it, and from there it works correctly. I do not understand why from the build folder the migration does not work, but this is sufficient to solve my problem.
Hopefully this will avoid somebody else to waste their time.