首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从最小的独立目标C程序抛出MacOS通知?

从最小的独立目标C程序抛出MacOS通知?
EN

Stack Overflow用户
提问于 2022-01-04 21:11:33
回答 1查看 185关注 0票数 1

我试图在C代码库中实现MacOS上的推送通知。理想情况下,只有一个目标C文件,包含(1)我可以调用的公共C函数和(2)一些目标C代码,我可以用来抛出通知。这样,源文件就可以在构建过程中无缝地编译和链接。

为此,我一直在尝试创建一个最小的示例,该示例只使用一个.m文件(不是整个XCode项目)就可以抛出通知,就像在NSUserNotificationCenter未显示通知中讨论的那样。然而,有两个问题:

  1. 尽管尝试了上述链接中的解决方案,我仍然无法让代码工作。它编译和运行,但不抛出通知。
  2. 如果可能的话,我们想切换到新用户通知API。不过,如果这暂时不可能的话,那也没什么大不了的。

到目前为止,我尝试过的是:

代码语言:javascript
运行
复制
#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编译的。

任何洞察力都将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-04 22:02:04

问题是,为了显示通知,需要有正确的捆绑标识符

我们将使用一个从这里开始的代码,在那里我们等待显示通知。我们可以将一个Info.plist文件嵌入到编译的二进制文件中,这将完成与名为notify.m的文件中的swizzling代码相同的任务。

代码语言:javascript
运行
复制
#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文件:

代码语言:javascript
运行
复制
<?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>

请使用适当的包标识符,因为com.apple.finder将导致所有这些通知似乎来自macOS查找器,这可能会使用户感到困惑。然后我使用以下方法编译它:

代码语言:javascript
运行
复制
clang -o notify -framework Cocoa notify.m -Wl,-sectcreate,_\_TEXT,__info_plist,Info.plist

在构建行中有一个\,以避免对下划线的标记解析,但实际构建命令行并不需要它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70585123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档