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
в качестве вывода, но без уведомления: (
Является ли кодовое выражение для этого фактора?
Ответы
Ответ 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, которое вы можете загрузить.