PyObjC UserNotifications Framework
PyObjC is a bridge between Python and Objective-C, allowing full-featured macOS applications and scripts to be written in Python. The `pyobjc-framework-usernotifications` package provides Python wrappers for the macOS UserNotifications framework, enabling developers to send and manage user notifications on macOS. The current version is 12.1, and PyObjC generally follows a release cadence tied to macOS SDK updates and Python version support.
Warnings
- breaking Python 3.9 support was dropped in PyObjC 12.0. If you are using Python 3.9, you must use an older version of PyObjC.
- breaking Python 3.8 support was dropped in PyObjC 11.0. If you are using Python 3.8, you must use an older version of PyObjC.
- breaking PyObjC 11.1 introduced changes to align initializer method (e.g., `init*`) behavior with `clang`'s Automatic Reference Counting (ARC) documentation. This means `init` methods now correctly 'steal' a reference to `self` and return a new one, which might alter reference counting and lead to memory management issues or crashes in existing code that relies on older reference semantics.
- gotcha In PyObjC 10.3, behavior around user-defined `__new__` and `__init__` methods changed, preventing `__init__` from being called in some cases. While partially reverted in 10.3.1 to reintroduce `__init__` calls for user-defined `__new__` methods, `__init__` is still not called when relying on PyObjC's default `__new__` implementation. This can lead to unexpected initialization behavior.
Install
-
pip install pyobjc-framework-usernotifications
Imports
- UserNotifications
from UserNotifications import *
- Foundation
from Foundation import *
Quickstart
import objc
from Foundation import *
from UserNotifications import *
def send_test_notification():
center = UNUserNotificationCenter.currentNotificationCenter()
# Request authorization for alerts, sounds, and badges
options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge
# The completionHandler can be None for simple cases if no Python callback is needed.
granted, error = center.requestAuthorizationWithOptions_completionHandler_(options, None)
if error:
print(f"Error requesting authorization: {error.localizedDescription()}") # cite: 11
return
if not granted:
print("Notification authorization denied. Please enable in System Settings -> Notifications -> Python.") # cite: 11
return
# Create notification content
content = UNMutableNotificationContent.alloc().init()
content.setTitle_("PyObjC Notification")
content.setBody_("This is a test notification from your Python script!")
content.setSound_(UNNotificationSound.defaultSound())
content.setUserInfo_({"source": "PyObjC"}) # Optional: Add custom data
# Create a trigger for immediate delivery (1 second from now, no repeat)
trigger = UNTimeIntervalNotificationTrigger.triggerWithTimeInterval_repeats_(1, False)
# Create the request with a unique identifier, content, and trigger
request = UNNotificationRequest.requestWithIdentifier_content_trigger_("pyobjcTestNotification", content, trigger)
# Add the request to the notification center
center.addNotificationRequest_withCompletionHandler_(request, None)
print("Notification request added. Check your macOS Notification Center.")
# Keep the Python process alive briefly to allow the notification to be processed by macOS.
# In a full macOS application, you would typically run an NSApplication main loop.
NSRunLoop.currentRunLoop().runUntilDate_(NSDate.dateWithTimeIntervalSinceNow_(3.0))
print("Script finished. Notification should appear shortly if authorized.")
if __name__ == "__main__":
send_test_notification()