Macintosh C Creating a navigation window to choose an app - macos

I'm writing a C program for mac, and I need to allow the user to choose an application to send an apple event to. I can create a navigation window, using NavCreateChooseFileDialog(), but I can't get it to enable any .app files. If I restrict the types using NavDialogSetFilterTypeIdentifiers, it will only allow me to select applications like MS Office, that don't have .app in the folder name. Everything else is greyed out.
Any ideas?

Make sure to set the flag kNavSupportPackages in inOptions.optionFlags for NavCreateChooseFileDialog, and put 'APPL' in the types list (might as well still use that param instead of NavDialogSetFilterTypeIdentifiers(), that way you'll run on 10.3-) and you should be good to go, I just tried.
Alternatively, if you don't mind using Cocoa, you can use -[NSOpenPanel runModalForTypes:[NSArray arrayWithObjects:#"app", nil]] (which also lists non-.app applications), and then you're only one FSPathMakeRef((UInt8*)[path fileSystemRepresentation], &fsRef, NULL); away from an FSRef.
Do remember that, in either case, the file you get may be an alias so you will have to try and resolve aliases.

Remember that .app bundles are directories, so you may need to enable some sort of allow-directories (or, more likely, enable-bundles) option.
I'm sorry that I can't offer more specific help. I started with Carbon, but never did touch Navigation Services.

This works for me:
NSOpenPanel * panel = [ NSOpenPanel openPanel ] ;
panel.allowedFileTypes = #[ (__bridge id)kUTTypeApplication ] ;
[ panel runModal ] ;

Related

QLPreviewView can not show the quicklook preview in sandbox

I use QLPreviewView to show the quicklook preview in the app. Without sandbox, this works well, but once change the app to sandbox, the preview can not show up.
I found the error in Console: QuickLookUIHelpe(20786) deny file-read-data XXX.
I have used the security-scoped bookmarks & com.apple.security.files.user-selected.read-write to grant access the user home dir, then:
[allowedURL startAccessingSecurityScopedResource];
self.myPreiviewItem.myURL = fileURL;
self.myQLPreviewView.previewItem = self.myPreiviewItem;
[self.myQLPreviewView refreshPreviewItem];
[allowedURL stopAccessingSecurityScopedResource];
with these, I can delete files of user home dir, but the QLPreviewView can not work.
I do not know what is the difference between these 2 scenes, does QLPreviewView need more for sandbox?
If I add com.apple.security.files.downloads.read-only into the entitlement, the files in "Downloads" can be previewed, but other files of user home dir can not be previewed.
Finally I have found the solution!
refreshPreviewItem is an async call, so before Mac finishes loading the preview, the following api stopAccessingSecurityScopedResource immediately shutdown the access, as a result, Mac failed to load the preview successfully.
so the solution is: do NOT call stopAccessingSecurityScopedResource here, keep the allowedURL's access right until you do not need the QL preview function, and then call stopAccessingSecurityScopedResource there, such as when closing the window.
I encountered this, or at least a similar, issue a while back (in Mavericks).
This is why I started asking users for access to parent folders of files they wish to Quick Look. Feel free to look at how I do it in this app of mine, version 1.1 at the time of this writing. Just go into Chikoo → Preferences… → Folder Access. Here are two screenshots:
I confess that this is not a great solution. It’s a compromise that I came up with to work around the problem.

How to implment drag and drop feature on Rubymotion for a OSX app

Trying to whip up something quick and dirty that mass renames and converts files, and having a rubymotion license I thought why not use it to make a simple app that you can drag and drop instead of some batch file.
However I am having trouble detecting the drag event, can't seem to find information about how to do this in rubymotion, I've only used rubymotion to do iOS apps, and find myself lost.
Any help would be appreciated.
Have you started on any Cocoa tutorials? Anything written in Objective-C can be ported easily. I would start here: Drag and Drop Programming (developer.apple.com)
If you want to support dragging onto the dock icon, you'll need to modify the project's supported document types, and I'm not sure how to do this (check rake config, it might give a clue). You'll eventually need to implement this method, too:
def application(sender, openFile: path)
# sender is an NSApplication, path is NSString
true # or false
end
You need to add something like :
app.info_plist['CFBundleDocumentTypes'] = [
{'CFBundleTypeRole': 'Viewer', 'CFBundleTypeExtensions': ['mp4','m4v','avi','*'] } ,
{'CFBundleTypeRole': 'Editor', 'CFBundleTypeExtensions': ['txt'] }
]
to the setup block in the Rakefile
And add the following method to the AppDelegate class in app_delegate.rb
def application(sender, openFile: path)
true
end
Do a rake clean before you do rake build and you should be good to go.
Note that the application method gets called for each file that you drop onto the Application icon. path contains a string of the dropped files path.

How do I disable automatic text replacement in my NSTextViews?

Our app has some non-rich-text NSTextViews that users can enter text into. When a user enters "..." into the text view, OS X automatically replaces it with an ellipsis character, which we don't want to happen. This needs to be something we disable for all users of our app, rather than relying on them to disable it themselves.
I expected this to be an NSUserDefaults setting, like the "ApplePressAndHoldEnabled" one, but I was unable to find anything in the docs about it. I found some information about the "WebAutomaticTextReplacementEnabled" preference that sounds like it does what we need, but setting it to "NO" doesn't seem to do anything for our app.
I've also looked at NSSpellChecker, which appears to provide the "isAutomaticTextReplacementEnabled" method to check whether text replacement happens, but no way to stop it happening for an application.
How can I disable this text replacement for our app?
There are settings in the nib file for this (select the NSTextView). Unfortunately as of the latest version of OS X / Xcode, some of them seem to be broken so you may find that you have to send messages to your view from e.g. -awakeFromNib instead, e.g.
- (void)awakeFromNib
{
[myTextView setAutomaticQuoteSubstitutionEnabled:NO];
[myTextView setAutomaticTextReplacementEnabled:NO];
}
See the documentation for NSTextView for the full set of methods.

Using OSX Security-Scoped Bookmarks in a Firemonkey app

I have been developing an OSX app with Delphi XE3 and running into various problems. The latest one is with the sanboxed version built for the Apple Appstore.
The user has to select an arbitrary folder and the app needs to get access to it. Since there is a problem with the OpenDialog, I had to turn to drag-drop functionality instead.
The user drags a folder to the app, the sandbox gives the app temporary access to it and all works properly.
To preserve the access to this folder when the app is restarted I have to use the so-called "security-scoped bookmarks"
I am having two issues with them:
1) How to add the "com.apple.security.files.bookmarks.app-scope" entitlement to an XE3 firemonkey app? It is not available in the Project Options->Entitlements. If I add it manually in the ".entitlements" file it gets overwritten when the app is built.
So is there a way to add a custom entitlement that is not in the list in the project options?
2) To create the bookmark I should use the NSURL.bookmarkDataWithOptions method. I think it should be used like this, but I am not sure of the exact syntax:
var
URL: NSURL;
Err: NSError;
Data: NSData;
...
URL := TNSURL.Create;
Data := URL.bookmarkDataWithOptions(NSURLBookmarkCreationWithSecurityScope, nil, #Err);
...
Maybe there should be a call to Wrap(...) instead of Create.
I have not yet experimented with it, because it is pointless without the answer to issue 1).
It seems no one has written anything about these problems for Delphi, but I hope someone here has experience with that.
Thanks in advance.
Edit:
For problem 1) I tried to add edit manually the ".entitlements" file in the OSX32 folder and set it to read-only to prevent it from being overwritten. It was too easy to be true of course, because the linker complained that the file can not be modified...
OK, I finally found the way to manually add entitlements that are not available in the Project Options > Entitlements.
Instead of selecting the "App Store" build in the Project Manager you have to select a Normal release build and deploy the application as usual.
The application gets deployed in the PAServer scratch-dir as APP package. Inside this package there is an "Entitlements.plist" file, which is in XML format and can be edited with a text editor. It is quite obvious how to add new entitlements once you open the file.
After it is edited, the app has to be code-signed manually and a package has to be prepared. It is slightly more complicated than using the Delphi IDE, but there are instructions about it on the Embarcadero and Apple websites and it actually went without problems.
Still haven't tried the bookmarkDataWithOptions functions.
An alternative could be to deactivate the checkbox for the entitlements-file in the deployment page.
But attention: Evry time you change between Build/Release or App Store/Normal, delphi activates the checkbox. That means you have to deactivate it again in the deplayment-page, to avoid the transfer of this file to the mac PC.
By the way: Do you have tryed meanwhile the StartAccessingSecurityScopedResource function?
In the MacApi.Foundation unit the function is not declared in the NSURL interface.
Do you have found a way to use this function?

How to register a custom non-document UTI / file type for OSX to recognize it?

I've read all the tickets about this issue, but I still don't get it right. I have a non-document OSX app (for OSX Lion and MountainLion). I want this app to export and import custom data, associated with a custom file extension ".iobs". Internally, these files are just data archived with [NSKeyedArchiver archivedDataWithRootObject:], and saved onto the disk with the "iobs" extension.
So, my check list is this:
1) Export mechanism: checked. My app create correctly .iobs files. If I run "file <filename.iobs>" in the Terminal, I get "iObserve_exportedItems.iobs: Apple binary property list"
2) Declaration of an exported UTI, checked. As shown in the image below. I did NOT declared a custom Document type, since it I never use NSDocument inside my app, and there is no point. Anyway, I already tried and failed. I've tried also different combinations of "Conforms To" entries, but with no success.
3) Is there any 3rd point??? Do I need to start my app once to let the system know? I just ran it in Debug from Xcode so far, and this has no effect. So I guess my Info.plist is wrong, but I filled it from within Xcode4 interface, so???
Thanks for any help, hint, question, suggestion.
Ok, so apparently, I do have to declare a document type even if I don't specify a document class. See the attached screenshot. Note that leaving only the Document UTI doesn't work. I do need the two (exported UTI and document type). Note also that if I say it conforms to com.apple.binary-property-list, I don't have the right icon.
And for those who wonder, there is nothing to do to "register" a type (and its subsequent changes) apart from launching the app once.

Resources