{"id":6186,"library":"pyobjc-framework-usernotifications","title":"PyObjC UserNotifications Framework","description":"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.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","osx","notifications","cocoa","pyobjc","gui"],"install":[{"cmd":"pip install pyobjc-framework-usernotifications","lang":"bash","label":"Install pyobjc-framework-usernotifications"}],"dependencies":[{"reason":"Provides the core Python to Objective-C bridge functionality, which all PyObjC framework wrappers depend on. Installing `pyobjc-framework-usernotifications` will typically pull `pyobjc` as a dependency.","package":"pyobjc","optional":false}],"imports":[{"note":"PyObjC frameworks are typically imported directly from their top-level module name.","symbol":"UserNotifications","correct":"from UserNotifications import *"},{"note":"Often needed for basic Objective-C types and runtime functions when working with Cocoa frameworks.","symbol":"Foundation","correct":"from Foundation import *"}],"quickstart":{"code":"import objc\nfrom Foundation import *\nfrom UserNotifications import *\n\ndef send_test_notification():\n    center = UNUserNotificationCenter.currentNotificationCenter()\n\n    # Request authorization for alerts, sounds, and badges\n    options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge\n    # The completionHandler can be None for simple cases if no Python callback is needed.\n    granted, error = center.requestAuthorizationWithOptions_completionHandler_(options, None)\n    \n    if error:\n        print(f\"Error requesting authorization: {error.localizedDescription()}\") # cite: 11\n        return\n    \n    if not granted:\n        print(\"Notification authorization denied. Please enable in System Settings -> Notifications -> Python.\") # cite: 11\n        return\n\n    # Create notification content\n    content = UNMutableNotificationContent.alloc().init()\n    content.setTitle_(\"PyObjC Notification\")\n    content.setBody_(\"This is a test notification from your Python script!\")\n    content.setSound_(UNNotificationSound.defaultSound())\n    content.setUserInfo_({\"source\": \"PyObjC\"}) # Optional: Add custom data\n\n    # Create a trigger for immediate delivery (1 second from now, no repeat)\n    trigger = UNTimeIntervalNotificationTrigger.triggerWithTimeInterval_repeats_(1, False)\n\n    # Create the request with a unique identifier, content, and trigger\n    request = UNNotificationRequest.requestWithIdentifier_content_trigger_(\"pyobjcTestNotification\", content, trigger)\n\n    # Add the request to the notification center\n    center.addNotificationRequest_withCompletionHandler_(request, None)\n    print(\"Notification request added. Check your macOS Notification Center.\")\n\n    # Keep the Python process alive briefly to allow the notification to be processed by macOS.\n    # In a full macOS application, you would typically run an NSApplication main loop.\n    NSRunLoop.currentRunLoop().runUntilDate_(NSDate.dateWithTimeIntervalSinceNow_(3.0))\n    print(\"Script finished. Notification should appear shortly if authorized.\")\n\nif __name__ == \"__main__\":\n    send_test_notification()\n","lang":"python","description":"This quickstart demonstrates how to send a simple user notification using `pyobjc-framework-usernotifications`. It requests notification authorization, creates notification content and a trigger, and then schedules the notification. The script uses `NSRunLoop` to keep the Python process alive briefly, allowing macOS to process and display the notification. For persistent applications, a full `NSApplication` run loop would be required."},"warnings":[{"fix":"Upgrade your Python environment to 3.10 or later, or pin `pyobjc-framework-usernotifications<12.0`.","message":"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.","severity":"breaking","affected_versions":">=12.0"},{"fix":"Upgrade your Python environment to 3.9 or later, or pin `pyobjc-framework-usernotifications<11.0`.","message":"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.","severity":"breaking","affected_versions":">=11.0"},{"fix":"Review custom `init` methods in your PyObjC code to ensure they adhere to ARC best practices for reference handling. Consult the PyObjC documentation on 'What's new' for version 11.1 and clang's ARC documentation.","message":"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.","severity":"breaking","affected_versions":">=11.1"},{"fix":"If your classes implement custom `__new__`, ensure `__init__` is explicitly called or that initialization logic is handled within `__new__`. Refer to PyObjC's documentation regarding object instantiation for detailed guidance.","message":"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.","severity":"gotcha","affected_versions":">=10.3, <10.3.1 (full breakage), >=10.3.1 (partial fix)"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z","problems":[]}