Падение обещанных файлов на иконку приложения в 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);Обрабатывайте как любой другой файл обещаний с этого момента.