Перетаскивание обещанных файлов на значок приложения в Dock

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

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

rdar: // 47917787


person catlan    schedule 19.11.2015    source источник


Ответы (1)


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

Примечание. Я думаю, что под капотом это реализовано с помощью обработчиков событий NSAppleEventManager для _8 _ / _ 9_ и _10 _ / _ 11_.

К сожалению, они не обрабатывают 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>

Старый добрый Carbon нас прикрыл.

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

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

    CFRelease(pboardRef);

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

person catlan    schedule 26.11.2015
comment
Я хочу перетащить электронное письмо из Mail на значок Dock моего приложения. Я использовал приведенный выше код (добавил ключ NSService в свой файл Info.plist, установил поставщика услуг и добавил метод openService). Но метод openService не вызывается. Что я могу сделать? - person vomako; 21.12.2016