Как я могу собрать несколько событий openFile: (NSString *) и затем что-то с ними сделать? - PullRequest
3 голосов
/ 19 января 2012

Я работаю над служебным приложением Cocoa / Objective C ++ и хочу обработать несколько (мгновенных) открытий файлов. Для обработки части открытия файла у меня есть эта функция в моем AppDelegate.mm файле:

- (BOOL)application:(NSApplication*)app openFile:(NSString *)filename
{
    NSLog(@"Opening file %@", filename);

    // more C++ code here

    return YES;
}

Файлы отправляются в Quicksilver, который, я думаю, будет отправлять файлы один за другим в приложение («Открыть с помощью» Finder, я думаю, отправляет все файлы одновременно - и, возможно, использование handleOpenApplicationEvent:(NSAppleEventDescriptor *)event может работать лучше для что) - но независимо от того, приложение получит несколько файлов один за другим - почти мгновенно - но не совсем вместе. Вот что показывает Console.app:

console-screenshot.png http://img109.imageshack.us/img109/1205/consolescreenshot.png

Поскольку файлы отправляются отдельно, но один за другим, у меня вопрос: как мне собрать все отправленные файлы и сделать с ними одну вещь? Например, я хотел бы собрать все отправленные пути к файлам и затем отобразить их вместе в диалоговом окне.

Я могу придумать одну концепцию, которая может сработать: сохранять каждый путь к файлу в массиве по мере его поступления. В то же время, когда первый получен, установите задержку в 1-2 секунды в фоновом режиме, а затем в диалоговом окне отобразите все, что является определенной переменной. Правильно ли это понятие или есть лучший способ сделать это? Я новичок в Cocoa / Objective C ++ - из таких языков, как PHP / Perl, bash и т. Д.

Я также хотел бы, чтобы это вспомогательное приложение завершалось, когда оно было завершено, но если я жду файлы, как я могу завершить приложение, когда последний из файлов получен?

Если я добавлю [NSApp terminate:nil]; к функции applicationDidFinishLaunching, приложение фактически завершит работу после получения только первого файла.

Обновление - больше заметок

Это консоль после использования функции openFiles (множественное число): Изображение 7.png http://img24.imageshack.us/img24/5715/picture7zc.png

И с помощью Quicksilver я беру некоторые файлы, например файлы из временного каталога, и выбираю «Открыть с помощью», а затем создаваемое приложение (с именем darn.app)

Снимок экрана 2012-01-18 в 7.02.45 PM.png http://img9.imageshack.us/img9/4171/screenshot20120118at702.png

Но с Finder все работает нормально:

Снимок экрана 2012-01-18 в 7.09.08 PM.png http://img832.imageshack.us/img832/8858/screenshot20120118at709.png

... приводит к consolea.app:

Изображение 8.png http://img24.imageshack.us/img24/2812/picture8fe.png

Я спрашивал разработчиков Quicksilver, и они подтвердили, что QS открывает файлы по одному с действием Open With, и они признают, что это отличается от того, как это делает Finder, но они видят это как задуманное. Так что, возможно, Даррен прав - лучше всего выбрать таймер ...

Ответы [ 3 ]

5 голосов
/ 19 января 2012

Попробуйте реализовать -application:openFiles: вместо -application:openFile:

- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
    NSLog(@"Opening multiple files %@", filenames);
}

Это обрабатывает получение нескольких файлов из Finder.

Если это не работает с вашей настройкой Quicksilver, то, вероятно, лучше всего использовать таймер.

Установите таймер в методе -init AppDelegate.

@implementation MyAppDelegate {
    NSMutableArray* _files;
}

- (id)init {
    if (self = [super init]) {
        _files = [[NSMutableArray alloc] initWithCapacity:10];

        [self performSelector:@selector(processFiles) 
                   withObject:nil 
                   afterDelay:1.0]; // one second delay
    }
    return self;
}

В -application: openFile: собрать файл в массив и сбросить таймер.

- (BOOL)application:(NSApplication*)app openFile:(NSString*)filename {
    NSAssert(_files != nil, @"Timer already fired");

    [_files addObject:filename];

    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(processFiles) 
               withObject:nil 
               afterDelay:1.0];
} 

Когда таймер срабатывает, обработайте собранные файлы и выйдите из приложения.

-(void)processFiles

    // Process the _files

    [_files release];
    _files = nil;
    [NSApp terminate:nil];
}
1 голос
/ 19 января 2012

В системе нет способа узнать, поступит ли больше запросов на открытие файла, поэтому не только нет предоставленного метода обозначения последнего запроса, но и нет никакого возможного метода.

В качестве альтернативы таймерудля первой проблемы вы можете сразу же начать обработку файлов и отображать их по мере их появления в диалоговом окне, чтобы пользователь мог видеть, что список увеличивается.Это не решает вторую проблему (завершение приложения после получения всех файлов).

Если вы используете таймер, обязательно сбрасывайте его после каждого application:openFile:.

0 голосов
/ 24 июня 2014

Я запускаю исполняемый файл приложения с несколькими аргументами командной строки.

MyApp.app/Contents/MacOS/MyApp file1 file2 file3

Каждый аргумент генерирует отдельное приложение: вызов openFile (s), как описано выше.Однако в этом случае applicationDidFinishLaunching не вызывается до ПОСЛЕ всех вызовов openFile, поэтому легко сделать что-то вроде этого:

NSMutableArray *_allFiles = nil;

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
  [self handleFiles:_allFiles];
}

- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
  [self application:theApplication openFiles:[NSArray arrayWithObject:filename]];
  return YES;
}

- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames {
  if(!_allFiles) _allFiles = [NSMutableArray arrayWithCapacity:8];
  [_allFiles addObjectsFromArray:filenames];
}

Этот метод также работает для открытия нескольких файлов с помощью команды «Открыть с помощью» изнаходчик.Я не удивлюсь, если Quicksilver будет обрабатывать несколько файлов одинаково, и поэтому этот простой метод может сработать для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...