How to resolve missing QuickLook preview in Mojave?

We are currently migrating our app to Mojave. As a productivity utility for information retrieval, if needs access to content in the user's Library dierectory.


Even if a user has security scoped bookkark for the user's home directory and has added the app to the security setting to grant full access to the local storage, QuickLook previews are not possible for emails and other content from the user's Library path.


The QuickLook preview did work in High Sierra and works in Mojave for documents in the user's document folder. It that a bug? dies someione know a solution? We use the QLPreviewView element the user interface of our app.


I found the following output in the Xcode log after I have selected a search result item. It's confusing, because the message doesn't relate to our app at all and even refers to another hard drive. It's not a log output of our app, that I have startet for debugging from Xcode.


[QL] file:///Volumes/Macintosh%20HD/Applications/OmniOutliner.localized/OmniOutliner.app/Contents/Library/QuickLook/OmniOutliner.qlgenerator/ has no identifier: ignoring
[QL] file:///Volumes/Macintosh%20HD/Applications/Xcode.app/Contents/Library/QuickLook/DVTProvisioningProfileQuicklookGenerator.qlgenerator/ has no identifier: ignoring

I have the system for my development on Mojave from an external harddrive. Macintosh HD is the internal harddrive of my Macbook Pro. I'm not sure, whether this output is related to the issie. The log message doeesn't appear for a second time, if I click on another result item, that represents an email.


We check successfully the read access right of the file, that represents the email.


[[NSFileManager defaultManager] isReadableFileAtPath:_resultItem.path]

Answers

This is probably related to the same "Full Disk Access" (or lack thereof) issues from your other thread.


That is your hard drive. All volumes are accessible from /Volumes.


QuickLook is special. It doesn't run in the context of your app. You could get messages from apps anywhere on the system.


Finally, I don't recommend external hard drives. There is a long list of subtle bugs and complications in recent versions of macOS that can cause problems if you have multiple boot partitions. I don't know the deep details of what you app does, so I can't say for certain if these issues would cause a problem for you. The safest thing to do is use a standalone test machine booted from an internal hard drive, with only one booting partition. VMs can sometimes work, but they seem unreliable with iTunes test users. Don't use Time Machine, clones, or copy any home directories. Set everything up from scratch.

Thanks for the answer.


To make it more clear: I have booted the test system for Mojave on an external drive. On this test system I run Xcode and the tested app, that shows content objects form the user's library folder on the same external drive. And the tested app was added to the security preferences. Hopefully you are not right, that this has no impact on Quicklook. But I assume, the the access rights of QuickLook depend on the process, that calls QuickLook. It works, if Finder shows email files from the Library folder, for example. Maybe a bug?


It's not a good news, that macOS is not reilable, that was booted form an external hard disk. We use many test systems for serveral versions and setup of macOS, to get reproducable and comparable results. It would be quite expensive to have as many hardware as system scenarios for test cases.


A developer computer is sometimes not the best scenario for consumer use cases. If lot's off additional stuff on my machine.

Quicklook is a system service. Usually, it is the Finder that triggers it. Your app can trigger it with an NSOpenPanel. But in all cases, the Quicklook plugin, although residing inside an app, is running in a system context.


I think your app may be doing something unusual. I can't say for sure. Are you manually calling quicklook somehow? For me, it seems to work in a predictable fashion when triggered from an NSOpenPanel. That is the only context where an app should be triggering quicklook.


As for the external hard drive issue, remember that I was referring to "subtle" bugs. I can't guarantee that you will notice any problems. But I know there are some there. At least I have encountered them. Maybe you will too. I also don't have the resources for a separate machine for each version. I use what I have. I do most testing on my development machine. Sometimes I used VMs. Before releases, I test on stand alone systems. In some cases, like when I need to test a fusion drive in either APFS or HFS, then I need real hardware.

We have opened a support ticket to clarify this issue. QuickLook works for files inside the home directory as a security scoped bookmak but not for content in the user's library folder although I have added the app in the security settings. I have written a small test app to isolate this problem.


The app calls QuickLook is the following way in a class, that has implemented the QLPreviewPanelDataSource protocol:


[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:self];


This is the part of the class, that enables QuickLook features:


-(BOOL)acceptsPreviewPanelControl:(QLPreviewPanel *)panel {
    return YES;
}

-(void)beginPreviewPanelControl:(QLPreviewPanel *)previewPanel {
    _qlPanel = previewPanel;
    _qlPanel.dataSource = self;
}

-(void)endPreviewPanelControl:(QLPreviewPanel *)panel {
    _qlPanel = nil;
}

-(NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel {
    return 1;
}

-(id )previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index {
    return _qlItem;
}


The QuickLook item impements the QLPreviewItem protocol:


-(NSURL *)previewItemURL {
    return [NSURL fileURLWithPath:self.path];
}

-(NSString *)previewItemTitle {
    return self.title;
}


So everything is very simple in the test project. It seems to be a bug for me. If the QuickLook preview would be a system process, it shouldn't be a problem, because it works fine for emails in Finder.


I could publish a link to the test project.


I have no idea, how NSOpenPanel could help in this case. The app shows a list of content as a result of a retrieval process. A workaround could be to copy the file into a temp folder in the app's container and show a QuickLook preview of the copied file.


Update: Ihave tested to copy the file into a temp directoy. This works:


NSString *newPath = [NSString stringWithFormat:@"%@/%@", NSTemporaryDirectory(), _qlItem.path.lastPathComponent];
NSURL *newURL = [NSURL fileURLWithPath:newPath];
NSLog(@"New URL: %@", newURL);
NSError *error;
[[NSFileManager defaultManager] copyItemAtURL:_qlItem.previewItemURL toURL:newURL error:&error];
if (error) {
     NSLog(@"%@", error);
}
_qlItem.path = newURL.path;
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:self];


It's the same approach as the recommended one for UWP apps for Windows to process files. Hopefilly Apple accepts this solution.

I didn't even know about the QLPreviewPanel class. Unfortunately, that class dates from Snow Leopard days. This class does run in the context of your app, not in a system context. As such, it will be limited by any other issues that would limit your app. My original hunch was correct. This is a sandbox/full disk access issue. You will have to wait for the user to give your app access to any restricted locations before this type of QuickLook operation will work.


That is the official, bottom-line on this issue.


In your other thread, I believe we've had some "discussions" regarding various ways to enable this functionality and guide the user to the appropriate controls. To be clear, the system is operating as designed. I'm pretty sure that DTS will tell you the same thing and probably refund your ticket.


I strongly suggest that you modify your code, screenshots, and metadata to reflect the app doing whatever it does without having access to the full drive or any restricted locations. Releasing a Developer ID version would be a Really Good Idea. For the App Store, you can have your app obtain access to those locations and guide the user to them. But that has to be strictly optional. It can't be "in your face" or required in any way for the app to function. The user MUST go looking for it. It can't be visible when you first start the app. You should definitely mention these changes in the App Review notes. Don't make Apple think you are trying to do something sneaky. They can just pull your app and kick you out of the Developer program entirely for that kind of stuff. Just be careful in your wording. If you even use words like "critical", "required", or "must" then the answer will always be Reject, Reject, Reject.


That is why I suggest you review the code, metadata, and screenshots first. The app has to work and do something useful without any extra access. If not, it shouldn't be in the store. I'm just relaying my own recent experience. It could be completely different for you. App Review is often just the luck of the draw.

The apple developer support confirmed the issue and motivaded me to file a bug. The bug ticket number is 45482397.


The suggested workaround is similar:


-(QuickLookItem *)anyEmail {
...    
   if (count > 0) {
       MDItemRef mdItem = (MDItemRef)MDQueryGetResultAtIndex(mdQuery, 0);

       NSString* foundPath = CFBridgingRelease(MDItemCopyAttribute(mdItem, kMDItemPath));

       QuickLookItem *qlItem = [[QuickLookItem alloc] init];
       qlItem.path = "/Users/XXXX/testPath.emlx";
       [[NSFileManager defaultManager] removeItemAtPath: qlItem.path error: NULL];
       [[NSFileManager defaultManager] linkItemAtPath: foundPath toPath: qlItem.path error: NULL];

       qlItem.title = CFBridgingRelease(MDItemCopyAttribute(mdItem, kMDItemDisplayName));
...

I'm trying to do the same, I've made sure I have a secure bookmark link to the URL in question and am trying to create a link into my sandboxed 'Application Support' folder, but it seems to fail with a 513 error. Any ideas?