Приложения Mac не запускаются каждый раз, когда открывается соответствующий файл.Они могут быть запущены, но если они уже запущены, то их просто просят открыть другой файл.Таким образом, путь не приходит к приложению через командную строку.Оно отправляется как сообщение приложению, которому для его получения необходимо обработать цикл выполнения (NSRunLoop).
В обычной программе Cocoa вы реализуете NSApplicationDelegate и реализуете метод (в именовании ObjC):
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
Если вы поддерживаете только 10.13+, предпочтительный метод был изменен на:
- (void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls;
ОС будет вызывать это, когда вашему приложению потребуется открыть файл, если есть объект NSApplication.бежит, чтобы принять это.Обычно вы создаете объект NSApplication, вызывая NSApplicationMain()
, но при необходимости вы можете реализовать собственную версию NSApplicationMain()
(подробности см. В документах NSApplication ).
Этоможно ответить на эти открытые запросы без NSApplication или любого Objective-C, самостоятельно внедрив Apple Events и ответив на сообщение odoc
(открытый документ; { kCoreEventClass, kAEOpenDocuments }
).Чтобы атаковать это, см. Руководство по программированию событий Apple .
Вы должны ожидать написания некоторого фрагмента кода, который устанавливает обработчик событий, например:
err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
NewAEEventHandlerUPP(OpenDocumentsAE), 0, false);
require_noerr(err, CantInstallAppleEventHandler);
А затем вы фактически обработаете сообщение в OpenDocumentsAE
(взято из "Обработчика для«Открытые документы Apple Event»):
static pascal OSErr OpenDocumentsAE(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
AEDescList docList;
FSRef theFSRef;
long index;
long count = 0;
OSErr err = AEGetParamDesc(theAppleEvent,
keyDirectObject, typeAEList, &docList);// 1
require_noerr(err, CantGetDocList);// 2
err = AECountItems(&docList, &count);// 3
require_noerr(err, CantGetCount);
for(index = 1; index <= count; index++)// 4
{
err = AEGetNthPtr(&docList, index, typeFSRef,
NULL, NULL, &theFSRef, sizeof(FSRef), NULL);// 5
require_noerr(err, CantGetDocDescPtr);
err = OpenDocument(&theFSRef);// 6
}
AEDisposeDesc(&docList);// 7
CantGetDocList:
CantGetCount:
CantGetDocDescPtr:
if (err != noErr)// 8
{
// For handlers that expect a reply, add error information here.
}
return(err);// 9
}