从最小的独立 Objective-C 程序中抛出 MacOS 通知?
Throwing a MacOS notification from a minimal standalone Objective-C program?
我正在尝试在 C 代码库中实现 MacOS 上的推送通知。理想情况下,只有一个 Objective-C 文件包含 (1) 我可以调用的 public C 函数和 (2) 我可以用来发出通知的一些 Objective-C 代码。这样,可以在构建过程中无缝地编译和 linked 源文件。
为此,我一直在尝试创建一个最小的示例,它可以只用一个 .m
文件(而不是整个 XCode 项目)抛出通知,就像讨论的那样在 NSUserNotificationCenter not showing notifications。但是,有两个问题:
- 尽管尝试了上述 link 中的解决方案,但我仍然无法使代码正常工作。它编译并运行但不抛出通知。
- 如果可能,我们想切换到 new user notifications API。不过,如果暂时无法做到这一点,也没什么大不了的。
这是我到目前为止尝试过的方法:
#import <Foundation/Foundation.h>
#import <Foundation/NSUserNotification.h>
@interface AppDelegate : NSObject <NSUserNotificationCenterDelegate>
@end
@implementation AppDelegate
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
shouldPresentNotification:(NSUserNotification *)notification {
return YES;
}
- (void)throwNotification {
NSUserNotification *userNotification = [[NSUserNotification alloc] init];
userNotification.title = @"Some title";
userNotification.informativeText = @"Some text";
printf("trying to throw {%s %s}\n", [[userNotification title] UTF8String], [[userNotification informativeText] UTF8String]);
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
}
@end
int main (int argc, const char * argv[]) {
AppDelegate *app = [[AppDelegate alloc] init];
[app throwNotification];
return 0;
}
这是用cc -framework Foundation -o app main.m
编译的。
如有任何见解,我们将不胜感激!
问题是为了显示通知,您需要 a proper bundle identifier。
我们将在 bit of the code from here 中等待通知显示。我们可以将一个 Info.plist 文件嵌入到编译后的二进制文件中,这将完成与名为 notify.m
:
的文件中的调配代码相同的事情
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject<NSUserNotificationCenterDelegate>
@property (nonatomic, assign) BOOL keepRunning;
@end
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSApplication *app = [NSApplication sharedApplication];
AppDelegate *appdel = [[AppDelegate alloc] init];
app.delegate = appdel;
NSUserNotificationCenter *nc = [NSUserNotificationCenter defaultUserNotificationCenter];
nc.delegate = appdel;
appdel.keepRunning = TRUE;
NSUserNotification *userNotification = [[NSUserNotification alloc] init];
userNotification.title = @"Some title";
userNotification.informativeText = @"Some text";
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
while (appdel.keepRunning) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
return 0;
}
@implementation AppDelegate
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
shouldPresentNotification:(NSUserNotification *)notification {
return YES;
}
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
self.keepRunning = NO;
}
@end
我构建了一个包含以下内容的 Info.plist
文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.finder</string>
</dict>
</plist>
Please use an appropriate bundle identifier, as com.apple.finder
will cause all these notifications to appear to come from macOS Finder, which might be confusing to users.
I then compile it using:
clang -o notify -framework Cocoa notify.m -Wl,-sectcreate,_\_TEXT,__info_plist,Info.plist
there's a \
in that build line to avoid the markdown parsing of the underscores, but it's not needed for the actual build command line.
我正在尝试在 C 代码库中实现 MacOS 上的推送通知。理想情况下,只有一个 Objective-C 文件包含 (1) 我可以调用的 public C 函数和 (2) 我可以用来发出通知的一些 Objective-C 代码。这样,可以在构建过程中无缝地编译和 linked 源文件。
为此,我一直在尝试创建一个最小的示例,它可以只用一个 .m
文件(而不是整个 XCode 项目)抛出通知,就像讨论的那样在 NSUserNotificationCenter not showing notifications。但是,有两个问题:
- 尽管尝试了上述 link 中的解决方案,但我仍然无法使代码正常工作。它编译并运行但不抛出通知。
- 如果可能,我们想切换到 new user notifications API。不过,如果暂时无法做到这一点,也没什么大不了的。
这是我到目前为止尝试过的方法:
#import <Foundation/Foundation.h>
#import <Foundation/NSUserNotification.h>
@interface AppDelegate : NSObject <NSUserNotificationCenterDelegate>
@end
@implementation AppDelegate
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
shouldPresentNotification:(NSUserNotification *)notification {
return YES;
}
- (void)throwNotification {
NSUserNotification *userNotification = [[NSUserNotification alloc] init];
userNotification.title = @"Some title";
userNotification.informativeText = @"Some text";
printf("trying to throw {%s %s}\n", [[userNotification title] UTF8String], [[userNotification informativeText] UTF8String]);
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
}
@end
int main (int argc, const char * argv[]) {
AppDelegate *app = [[AppDelegate alloc] init];
[app throwNotification];
return 0;
}
这是用cc -framework Foundation -o app main.m
编译的。
如有任何见解,我们将不胜感激!
问题是为了显示通知,您需要 a proper bundle identifier。
我们将在 bit of the code from here 中等待通知显示。我们可以将一个 Info.plist 文件嵌入到编译后的二进制文件中,这将完成与名为 notify.m
:
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject<NSUserNotificationCenterDelegate>
@property (nonatomic, assign) BOOL keepRunning;
@end
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSApplication *app = [NSApplication sharedApplication];
AppDelegate *appdel = [[AppDelegate alloc] init];
app.delegate = appdel;
NSUserNotificationCenter *nc = [NSUserNotificationCenter defaultUserNotificationCenter];
nc.delegate = appdel;
appdel.keepRunning = TRUE;
NSUserNotification *userNotification = [[NSUserNotification alloc] init];
userNotification.title = @"Some title";
userNotification.informativeText = @"Some text";
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
while (appdel.keepRunning) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
return 0;
}
@implementation AppDelegate
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
shouldPresentNotification:(NSUserNotification *)notification {
return YES;
}
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
self.keepRunning = NO;
}
@end
我构建了一个包含以下内容的 Info.plist
文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.finder</string>
</dict>
</plist>
Please use an appropriate bundle identifier, as
com.apple.finder
will cause all these notifications to appear to come from macOS Finder, which might be confusing to users. I then compile it using:
clang -o notify -framework Cocoa notify.m -Wl,-sectcreate,_\_TEXT,__info_plist,Info.plist
there's a
\
in that build line to avoid the markdown parsing of the underscores, but it's not needed for the actual build command line.