Подтвердить что ты не робот

Mac Mountain Lion отправляет уведомление из приложения CLI

Как отправить уведомление в центр уведомлений из приложения командной строки? Мои попытки пока компилируются и выполняются, но мне не удается уведомить меня.

Пример

#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[]) {
    NSLog(@"Running notifications");

    NSUserNotification *note = [[NSUserNotification alloc] init];
    [note setTitle:@"Test"];
    [note setInformativeText:@"Woot"];

    NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
    [center scheduleNotification: note];

    return 0;
}

Затем я компилирую как:

clang -framework cocoa /tmp/Notes.m

и я получаю

 2012-07-29 16:08:35.642 a.out[2430:707] Running notifications

в качестве вывода, но без уведомления: (

Является ли кодовое выражение для этого фактора?

4b9b3361

Ответ 1

Я обнаружил, что NSUserNotificationCenter работает, когда [[NSBundle mainBundle] bundleIdentifier] возвращает правильный идентификатор. Итак, я написал несколько swizzling код, который вы можете найти в https://github.com/norio-nomura/usernotification

Он может отправить NSUserNotification без пакета приложений.

Ответ 2

Пока я не нашел какой-либо конкретной документации по этому вопросу, я предполагаю, что вам нужно быть приложением (пакетом) для доставки уведомлений. Обратите внимание, что пользовательский интерфейс Центра уведомлений всегда показывает имя и значок приложения, из которого было получено уведомление. Это невозможно с помощью средства командной строки.

Подписание кода, похоже, не требуется.

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

Ответ 3

Я не знаю точно, но, возможно, расписаниеNotification вызывает асинхронность, и ваше приложение выходит, прежде чем что-нибудь получит шанс. Попробуйте добавить:

[[NSRunLoop currentRunLoop] run];

до конца основного.

Ответ 4

уже есть терминальный уведомитель на github: https://github.com/alloy/terminal-notifier

и README говорит:

В настоящее время он упакован как пакет приложений, поскольку NSUserNotification не работать с помощью инструмента "Фонд". радар://11956694

Ответ 5

Это то, что я должен был сделать. Обратите внимание на то, что у runloop есть очень маленькая задержка. Это необходимо, чтобы увидеть это уведомление.

NSUserNotification *n = [[NSUserNotification alloc] init];
n.title = @"My Title";
n.subtitle = @"my subtitle";
n.informativeText = @"some informative text";
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:n];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];

Однако вы можете заметить, что на нем отображается значок терминала, а не значок. Чтобы исправить это, существует плохо документированная техника. К сожалению, с помощью этой техники я не знаю, как связать ее со своим собственным значком - только с установленным значком приложения.

  • Добавьте в проект файл Info.plist. Если ваш проект называется acme, обычно XCode создает желтую папку в вашем проекте под названием acme и помещает туда ваши файлы. Итак, добавьте Info.plist и не забывайте использовать эту информацию в Info. BTW, не беспокойтесь о распространении этого файла Info.plist с вашим приложением CLI - он автоматически включается в сам двоичный файл.

  • Затем откройте Info.plist и добавьте новый элемент. Он предложит вам некоторые элементы по умолчанию. Выберите Bundle Identifier. Теперь, в части значения этого ключа, установите его для действительного идентификатора пакета для установленного приложения в папке "Приложения". Итак, для меня мой LaunchDaemon был приложением командной строки, которому необходимо было отправлять уведомления, и у меня было приложение GUI, которое было связано с ним в папке /Applications, называемой (здесь ради) как /Applications/Acme.app. Итак, внутри файла Acme.app Info.plist у меня был мой существующий идентификатор пакета com.acme.myapp. Кроме того, на этом графическом приложении уже есть значок. Итак, я установил свою ценность в свой идентификатор пакета Info.plist приложения CLI для com.acme.myapp, чтобы он использовал этот значок. Теперь вы также можете установить это в com.apple.finder, если хотите, и он захватит значок Finder. (Кстати, если вы знаете, как связать значок с самим приложением CLI, а не заимствовать его из другого установленного приложения, то, пожалуйста, дайте мне знать.)

  • Теперь перейдите в свои настройки сборки и используйте поле поиска и введите "infoplist". Вы увидите элемент под названием "Info.plist File". Установите его в относительный путь к папке вашего файла. Итак, помните, когда я упоминал, что у моего проекта была желтая папка "acme", и мой файл Info.plist был внутри этого? Итак, все, что мне нужно было сделать, это напечатать "acme/Info.plist" под вторым столбцом (слева - "Разрешено" ) и третьим столбцом.

  • Теперь, находясь в настройках сборки, выполните поиск в разделе "создать информацию". Вы увидите запись "Создать секцию Info.plist в двоичном формате". Во втором и третьем столбцах установите значение Да.

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