1#!/usr/bin/swift
2import Cocoa
3
4// Compilation: swiftc macos_notify.swift -o macos_notify
5// Usage: ./macos_notify <title> <body> <logoPath> [subtitle] [identifier] [soundName] [contentImagePath]
6// Or: ./macos_notify --remove [identifier]
7
8let args = ProcessInfo.processInfo.arguments
9
10if args.contains("--remove") {
11 let center = NSUserNotificationCenter.default
12 if args.count > 2 {
13 let identifier = args[2]
14 center.removeDeliveredNotification(withIdentifier: identifier)
15 } else {
16 center.removeAllDeliveredNotifications()
17 }
18 exit(0)
19}
20
21guard args.count >= 4 else {
22 print("Usage: \(args[0]) <title> <body> <logoPath> [subtitle] [identifier] [soundName] [contentImagePath]")
23 print(" \(args[0]) --remove [identifier]")
24 exit(1)
25}
26
27let title = args[1]
28let body = args[2]
29let logoPath = args[3]
30let subtitle = args.count > 4 ? args[4] : ""
31let identifier = args.count > 5 ? args[5] : nil
32let soundName = args.count > 6 ? args[6] : NSUserNotificationDefaultSoundName
33let contentImagePath = args.count > 7 ? args[7] : ""
34
35class NotificationDelegate: NSObject, NSUserNotificationCenterDelegate {
36 func userNotificationCenter(_ center: NSUserNotificationCenter, shouldPresent notification: NSUserNotification) -> Bool {
37 return true
38 }
39}
40
41let notification = NSUserNotification()
42notification.title = title
43notification.informativeText = body
44notification.subtitle = subtitle
45notification.soundName = soundName
46
47if let identifier = identifier {
48 notification.identifier = identifier
49}
50
51func loadImage(from path: String) -> NSImage? {
52 if path.isEmpty { return nil }
53 let expandedPath = (path as NSString).expandingTildeInPath
54 return NSImage(contentsOfFile: expandedPath)
55}
56
57if let img = loadImage(from: logoPath) {
58 // _identityImage is a private key that allows showing an image on the left of the notification.
59 notification.setValue(img, forKey: "_identityImage")
60}
61
62if let contentImg = loadImage(from: contentImagePath) {
63 notification.contentImage = contentImg
64}
65
66let delegate = NotificationDelegate()
67NSUserNotificationCenter.default.delegate = delegate
68NSUserNotificationCenter.default.deliver(notification)
69
70// Wait for the notification to be delivered to the system.
71RunLoop.main.run(until: Date(timeIntervalSinceNow: 0.1))