Падение обещанных файлов на иконку приложения в Dock


Можно ли открыть обещанные файлы NSFilesPromisePboardType в изолированном приложении при переходе на значок приложения в Dock? Значок Dock принимает падение, но -application:openFile: никогда не вызывается.

Единственная ссылка, которую я нашел, - это pre sandbox: принятие iCal событий, упавших на значок моего приложения

1 5

1 ответ:

Давайте разберем это: NSApplication и NSDocumentController в приложениях на основе NSDocument дает вам -application:openFile: или -openDocumentWithContentsOfURL:display:completionHandler: бесплатно в случае NSFilenamesPboardType и NSURLPboardType капель.

Примечание: Я думаю, что под капотом это реализация с обработчиками событий NSAppleEventManager для kCoreEventClass/kAEOpenDocuments и еще kInternetEventClass/kAEGetURL.

К сожалению, они не справляются с NSFilesPromisePboardType.

Давайте освежим наши знания о картоне: картонная доска являетсяобщей среди всех приложений. Для задач существуют стандартные картонные панели например, копировать, находить и перетаскивать.

При запуске перетаскивания приложение записывает данные в общую папку перетаскивания. Так что все, что нам сейчас нужно, это уведомление о падении на значок Dock.

Вот где NSService вступает в игру:

<key>NSServices</key>
<array>
    <dict>
        <key>NSMessage</key>
        <string>openService</string>
        <key>NSSendTypes</key>
        <array>
            <string>public.data</string>
        </array>
        <key>NSMenuItem</key>
        <dict>
            <key>default</key>
            <string>Open</string>
        </dict>
    </dict>
</array>

И установить его в коде:

- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
    [NSApp setServicesProvider:self];
}

- (void)openService:(NSPasteboard *)serviceBoard
           userData:(NSString *)userData
              error:(NSString **)error
{
}
Одно предостережение состоит в том, что NSService не является NSDragPboard картоном. Но они все общие, так что мы можем просто получить доступ к тому, что мы хотим:
NSPasteboard *dragPboard = [NSPasteboard pasteboardWithName:NSDragPboard];

if ([[dragPboard types] containsObject:NSFilesPromisePboardType])
{
}

Следующая проблема заключается в том, что мы не надо -[NSDraggingInfo namesOfPromisedFilesDroppedAtDestination:].

#import <ApplicationServices/ApplicationServices.h>

Старого доброго угля есть.

    PasteboardRef pboardRef = NULL;
    PasteboardCreate((__bridge CFStringRef)NSDragPboard, &pboardRef);
    PasteboardSetPasteLocation(pboardRef, (__bridge CFURLRef)temporaryDirectory);

    NSString *urlString = [dragPboard stringForType:(NSString *)kPasteboardTypeFileURLPromise];

    CFRelease(pboardRef);

Обрабатывайте как любой другой файл обещаний с этого момента.