progrium/darwinkit

Notification example doesn’t work.

Opened this issue · 1 comments

hood commented

The notification example (code pasted below for convenience) doesn’t produce any notification under OSX 14.

OS details (uname -a):

Darwin MyMac 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 arm6

Code:

package main

import (
	"runtime"
	"time"

	"github.com/progrium/macdriver/macos/foundation"
	"github.com/progrium/macdriver/objc"
)

func main() {
	runtime.LockOSThread()

	// notifications need a unique bundleIdentifier which we can define by
	// replacing the bundleIdentifier method on the default main bundle
	nsbundle := foundation.Bundle_MainBundle().Class()
	objc.ReplaceMethod(nsbundle, objc.Sel("bundleIdentifier"), func(_ objc.IObject) string {
		return "com.example.fake2" // change this if you miss the allow notification
	})

	objc.WithAutoreleasePool(func() {
		// this API is deprecated and we currently don't generate bindings for deprecated APIs,
		// so this is what using an API without bindings looks like.
		notif := objc.Call[objc.Object](objc.GetClass("NSUserNotification"), objc.Sel("new"))
		notif.Autorelease()
		objc.Call[objc.Void](notif, objc.Sel("setTitle:"), "Hello, world!")
		objc.Call[objc.Void](notif, objc.Sel("setInformativeText:"), "More text")

		center := objc.Call[objc.Object](objc.GetClass("NSUserNotificationCenter"), objc.Sel("defaultUserNotificationCenter"))
		objc.Call[objc.Void](center, objc.Sel("deliverNotification:"), notif)
	})

	// give notification center a moment
	<-time.After(1 * time.Second)
}

NSUserNotification is an old depreciated api. (see: https://developer.apple.com/documentation/foundation/nsusernotification?language=objc)
The newer API for Notifications is called, UNUserNotificationCenter, (https://developer.apple.com/documentation/usernotifications/asking-permission-to-use-notifications?language=objc)

The newer API has a more complicated handshake, you need to request permissions to present the notification, then you can start sending messages to the Notification center.

What is happening with the code in the example is it causing a prompt to ask permission and if you don't click on that first notification and grant permission it doesn't present ANY further notifications.

To get the example to run on your machine, change the "bundle identifier" in line 18. "com.example.fake2" with a different identifier and you will trigger the notification permission prompt.