|
4 | 4 |
|
5 | 5 | void SetDarwinAppIcon(const void *data, int len) { |
6 | 6 | @autoreleasepool { |
7 | | - NSData *imgData = [NSData dataWithBytes:data length:len]; |
8 | | - NSImage *icon = [[NSImage alloc] initWithData:imgData]; |
9 | | - if (icon) { |
10 | | - [NSApp setApplicationIconImage:icon]; |
| 7 | + @try { |
| 8 | + NSData *imgData = [NSData dataWithBytes:data length:len]; |
| 9 | + NSImage *icon = [[NSImage alloc] initWithData:imgData]; |
| 10 | + if (icon) { |
| 11 | + [NSApp setApplicationIconImage:icon]; |
| 12 | + } |
| 13 | + } @catch (NSException *exception) { |
| 14 | + NSLog(@"Watchfire: set app icon failed: %@", exception.reason); |
11 | 15 | } |
12 | 16 | } |
13 | 17 | } |
14 | 18 |
|
| 19 | +// Returns YES if the process has a valid app bundle (required for UNUserNotificationCenter). |
| 20 | +static BOOL hasAppBundle(void) { |
| 21 | + NSBundle *bundle = [NSBundle mainBundle]; |
| 22 | + return bundle != nil && [bundle bundleIdentifier] != nil; |
| 23 | +} |
| 24 | + |
15 | 25 | void SendDarwinNotification(const char *title, const char *message) { |
16 | 26 | @autoreleasepool { |
17 | | - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; |
18 | | - |
19 | | - // Request authorization (no-op after first grant). |
20 | | - [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound) |
21 | | - completionHandler:^(BOOL granted, NSError *error) {}]; |
22 | | - |
23 | | - UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; |
24 | | - content.title = [NSString stringWithUTF8String:title]; |
25 | | - content.body = [NSString stringWithUTF8String:message]; |
26 | | - content.sound = [UNNotificationSound defaultSound]; |
27 | | - |
28 | | - NSString *identifier = [[NSUUID UUID] UUIDString]; |
29 | | - UNNotificationRequest *request = |
30 | | - [UNNotificationRequest requestWithIdentifier:identifier |
31 | | - content:content |
32 | | - trigger:nil]; |
33 | | - |
34 | | - [center addNotificationRequest:request withCompletionHandler:^(NSError *error) { |
35 | | - if (error) { |
36 | | - NSLog(@"Watchfire notification error: %@", error); |
| 27 | + @try { |
| 28 | + if (!hasAppBundle()) { |
| 29 | + NSLog(@"Watchfire: skipping notification (no app bundle)"); |
| 30 | + return; |
37 | 31 | } |
38 | | - }]; |
| 32 | + |
| 33 | + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; |
| 34 | + |
| 35 | + // Request authorization (no-op after first grant). |
| 36 | + [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound) |
| 37 | + completionHandler:^(BOOL granted, NSError *error) {}]; |
| 38 | + |
| 39 | + UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; |
| 40 | + content.title = [NSString stringWithUTF8String:title]; |
| 41 | + content.body = [NSString stringWithUTF8String:message]; |
| 42 | + content.sound = [UNNotificationSound defaultSound]; |
| 43 | + |
| 44 | + NSString *identifier = [[NSUUID UUID] UUIDString]; |
| 45 | + UNNotificationRequest *request = |
| 46 | + [UNNotificationRequest requestWithIdentifier:identifier |
| 47 | + content:content |
| 48 | + trigger:nil]; |
| 49 | + |
| 50 | + [center addNotificationRequest:request withCompletionHandler:^(NSError *error) { |
| 51 | + if (error) { |
| 52 | + NSLog(@"Watchfire notification error: %@", error); |
| 53 | + } |
| 54 | + }]; |
| 55 | + } @catch (NSException *exception) { |
| 56 | + NSLog(@"Watchfire: notification failed: %@", exception.reason); |
| 57 | + } |
39 | 58 | } |
40 | 59 | } |
0 commit comments