I'm just wondering is it possible?
Let's say I wrote an app and I want to use a button to open (from the app I wrote) another app (sing its directory) on my Mac
Any idea where to start off? I've been thinking about NSFileManager but it seems like a wrong way.
You should use the methods of NSWorkspace. Which method exactly depends a bit on exactly what you want to do. For example, if you have the URL for a document file and you want to open it in the appropriate app, you would use -openURL:.
If you just want to open a specific app (and not any particular document), then you should use -launchAppWithBundleIdentifier:options:additionalEventParamDescriptor:launchIdentifier:. Using a bundle identifier is the most reliable way to identify the app, rather than using its name or its URL, either of which can be changed.
Related
I have the following need to implement on Windows: file with files.
Originally I was thinking to use directory with extension. Something like "folderA.myappext", so when user clicks on it in Explorer, my app is launched instead of folder being opened. Unfortunately, I was unable to find a way to do that. Then I tried to use Alternate Data Streams. This works just fine, but several problems with it:
It works only in NTFS, so no way to send it via email or FTP as is;
Only WinRAR can properly archive it, and you still have to do extra clicks in the UI for that;
The real file size (with all streams in it) is not shown in Explorer and does not participate in showing free/used space, which can very quickly lead to big problems for the user.
No, I can't use zip or any other way to combine files into one - this is high-performance app that also requires write streaming (i.e. it changes data all the time).
Any idea how else to achieve my need on Windows? I know on MacOS you can use 'package', but there is nothing like that on Windows. Any idea?
Something like "folderA.myappext", so when user clicks on it in Explorer, my app is launched instead of folder being opened.
You can't do it based on the extension because folders don't have extensions but you can do it with desktop.ini. Windows 7 and later supports custom verbs on folders.
A working example can be found here.
I have an App Store app in which the free version is not scriptable, but the premium version is. AppleScript support is one of the key differences. I know the App Store reviewers are pushing more and more towards free + in-app-purchase, which will help declutter the App Store. Fine, I'll play ball.
Now I need to do something programmatically that I've always just worked into the build.
Is there a way to disable AppleScript if my OSAScriptingDefinition and NSAppleScriptEnabled are set in my Info.plist? This would still allow people to open the dictionary, and maybe they'd like what they see and consider activating the upgrade. Or,
Is there a way to enable AppleScript after the fact? Obviously with code-signing, I can't do things like modify Info.plist, or add my SDEF to the bundle later. But maybe if the SDEF were in a non-standard location, I could load it from the bundle and tell the system about it manually.
Does the SDEF have to live in my bundle? If not, I'm not sure how to point to the user's Application Support directory in the sandbox. I've also considered xinclude an SDEF I can install after the fact, but again, the SDEF and plist require actual directory paths and not functions.
I've tried a couple of things such as attempting to set NSScriptSuiteRegistry's singleton to nil, to no effect.
Because OSAScriptingDefinition and NSAppleScriptEnabled enable "automatic" support, surely there must be a manual way to make them to effect if not in the plist, and hopefully with a public API.
Any ideas here? Thanks!
A few points, for orientation:
All AppleScript commands are subclasses of NSScriptCommand
All AppleScript objects are represented by subclasses of
NSScriptObjectSpecifier
The scriptability of an app is controlled by its shared instance of NSScriptSuiteRegistry
This gives you a few options. You could try, for instance, overriding NSScriptSuiteRegistry setSharedScriptSuiteRegistry: and setting it to nil for the free version. You could also write a category on NSScriptCommand and/or NSScriptObjectSpecifier that does a version check. That would give you fine-grained control: you could call it from any methods that handle a script command or returns a script object, and decide on the fly which you want to allow and which you want to block; maybe even pop up a 'Pay for Full AppleScript Access' dialog.
CocoaScripting is a black box and not very adaptable. Simplest (kludgy) solution would be to wait until CS has installed its Apple event handlers then call -[NSAppleEventManager setEventHandler:andSelector:forEventClass:andEventID:] to replace those with a dummy handler that always sends back a "requires in-app purchase" error. (Don’t replace the standard open, quit, etc. handlers obviously.)
The idea is that I have a template of a file that needs to be opened but it should behave as if only the contents of the file were opened instead of the file itself.
The difference for the user should be, that he needs to select a place to save the file to instead of just overwriting the file that was opened.
Similar behaviour can be seen in the Preview app. When duplicating a function Preview will open the same file in a new window. Upon saving the file the user needs to specify where to save it to.
As far as I can see NSWorkspace does not support such behaviour out of the box. Does anybody know a workaround for that? I'd appreciate it!
EDIT
In my case I don't know where the user wants to save the file to when he or she is done with it. Currently I am only copying the file to a hidden folder in the user's home directory and then I open the copy so that the original file can not be overwritten.
The resulting behaviour is:
- the user does not see where the file is located
- upon saving and closing the application that the file was edited in the user will not find the file ever again.
Workaround: I guess for now I will ask the user where she wants to save it before opening it, which seems kind of redundant to me as it could very well be, that she will not want to save it. Hopefully I will find a better solution soon.
You may be able to achieve this by sending an "open contents" ('ocon'/kAEOpenContents) Apple Event to the target app. The easiest way is probably to use the Scripting Bridge.
The normal way to use the Scripting Bridge requires that you know in advance which app you want to target and generate an Objective-C header from its scripting interface definition. However, you should be able to use it "raw". For example, something like this:
SBApplication *app = [SBApplication applicationWith...:...]; // there are method to take a PID, a bundle ID, or a URL
[app activate];
NSAppleEventDescriptor *desc = [NSAppleEventDescriptor descriptorWithString:#"foobar"];
[app sendEvent:kCoreEventClass id:kAEOpenContents parameters:keyDirectObject, desc, nil];
The NSAppleEventDescriptor object is the contents payload, in this case the string "foobar". You can use other methods to create different types of payloads. If you use the generic one and need a descriptor type, you can look in the headers in /System/Library/Frameworks/CoreServices.framework/Frameworks/AE.framework/Headers (e.g. AEDataModel.h or AERegistry.h).
I am working on a Mac app. I ultimately want to use default app icons within my app. From the Info.plist and the Resource folder of an app I can get the .icns file and convert that to the image format I need. But I need to know the default application associated with the particular file extension, if any.
So how to get the default application that the system currently associates with a given file extension?
Don't go digging in other apps' bundles. It's always best to work at the level of abstraction that suits the question you want to ask. If you want to get the icon that the Finder (or a Mail attachment, etc) would display for a file of a particular type, use the NSWorkspace iconForFileType: method.
I think what you're looking for is part of the OSX Launch Services: LSCopyDefaultApplicationURLForContentType API. This returns the info on apps that can open specific Uniform Type Identifiers. There's also a similar API called LSCopyDefaultApplicationURLForURL to check which app opens a specific known file.
I want to create an application on a Mac to convert multiple files (txt, pdf, doc, html, etc) to a single pdf file that can be printed. The real point is that if you have 50 texts you don't have to open every single file and click command-p.
I'm not quite sure whether the best way to do this is by creating a full-fledged app or an automator plugin (or something else). If I remember correctly there's a filter in mac os's terminal that can convert files to pdf (but I forgot what it's called).
So would an automator plugin do this well, or shall I make an app for this? Can you provide me advantages for each answer?
I've done cocoa touch programming before so I can write objective-c quite well.
Use appscript, either as an action in an automator script or standalone. The advantage is that it is very simple and will take you a fraction of the time to write an app.
Here is something very close to what you want. It sets up a drop-folder and each file dragged onto it is printed (you can use multiple-select to get what you want). It uses Apple Works 6 which doesn't support the file-types that you want.
To modify it to use the Preview application instead you need to change the tell command in the script and then google the dictionary for Preview to check which verb to use for printing.