Падение обещанных файлов на иконку приложения в Dock
Можно ли открыть обещанные файлы NSFilesPromisePboardType
в изолированном приложении при переходе на значок приложения в Dock? Значок Dock принимает падение, но -application:openFile:
никогда не вызывается.
Единственная ссылка, которую я нашел, - это pre sandbox: принятие iCal событий, упавших на значок моего приложения
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);
Обрабатывайте как любой другой файл обещаний с этого момента.