{"id":6147,"library":"pyobjc-framework-network","title":"PyObjC Network Framework","description":"PyObjC-framework-network provides Python wrappers for Apple's Network.framework on macOS, enabling Python applications to interact with low-level networking APIs. The current version is 12.1, and PyObjC generally releases new versions to align with macOS SDK updates and Python version support changes.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macos","cocoa","bindings","network","objective-c"],"install":[{"cmd":"pip install pyobjc-framework-network","lang":"bash","label":"Install only Network framework bindings"},{"cmd":"pip install pyobjc","lang":"bash","label":"Install all PyObjC frameworks (includes Network)"}],"dependencies":[{"reason":"Provides the core bridge between Python and Objective-C, required for all PyObjC framework bindings.","package":"pyobjc-core","optional":false},{"reason":"A meta-package that installs pyobjc-core and all available framework wrappers, including pyobjc-framework-network. Convenient for general macOS development.","package":"pyobjc","optional":true}],"imports":[{"note":"Framework-specific classes and functions are typically imported directly from the module named after the framework.","symbol":"NWPathMonitor","correct":"from Network import NWPathMonitor"},{"note":"Core Cocoa classes like NSObject and NSRunLoop are part of the Foundation framework, not Network.","symbol":"NSObject","correct":"from Foundation import NSObject"}],"quickstart":{"code":"import objc\nfrom Foundation import NSObject, NSRunLoop, NSDefaultRunLoopMode, NSDate\nfrom Network import NWPathMonitor, NWPathStatus, NWInterfaceType\n\nclass MyPathMonitorDelegate(NSObject):\n    def init(self):\n        self = super().init()\n        if self:\n            self.monitor = NWPathMonitor.alloc().init()\n            # Define the path update handler as a Python method\n            # PyObjC automatically bridges this to an Objective-C block.\n            self.monitor.setPathUpdateHandler_(self.pathUpdateHandler_)\n            # Start the monitor on a default dispatch queue (None)\n            self.monitor.start_(None)\n        return self\n\n    def pathUpdateHandler_(self, path):\n        \"\"\"Called when the network path changes.\"\"\"\n        print(f\"[Path Update] {path}\")\n        if path.status() == NWPathStatus.satisfied:\n            print(\"  Network path is satisfied (connected).\")\n            if path.usesInterfaceType_(NWInterfaceType.wifi):\n                print(\"  Using Wi-Fi interface.\")\n            elif path.usesInterfaceType_(NWInterfaceType.cellular):\n                print(\"  Using Cellular interface.\")\n            else:\n                print(\"  Using another interface type.\")\n        else:\n            print(\"  Network path is not satisfied (disconnected).\")\n\n    def stopMonitor(self):\n        \"\"\"Cancels the path monitor.\"\"\"\n        self.monitor.cancel()\n        print(\"NWPathMonitor stopped.\")\n\nif __name__ == \"__main__\":\n    print(\"Starting NWPathMonitor example...\")\n    delegate = MyPathMonitorDelegate.alloc().init()\n\n    print(\"Monitoring network path for 10 seconds. Press Ctrl+C to stop earlier.\")\n    try:\n        for _ in range(10):\n            # Run the current thread's run loop for 1 second intervals\n            # This is crucial for receiving asynchronous updates from NWPathMonitor\n            NSRunLoop.currentRunLoop().runMode_beforeDate_(NSDefaultRunLoopMode, NSDate.dateWithTimeIntervalSinceNow_(1.0))\n    except KeyboardInterrupt:\n        print(\"Monitoring interrupted by user.\")\n    finally:\n        delegate.stopMonitor()\n    print(\"Exiting.\")","lang":"python","description":"This quickstart demonstrates how to use `NWPathMonitor` from Apple's Network.framework to observe network path changes. It defines a Python class acting as a delegate and sets a path update handler. A basic `NSRunLoop` is used to keep the script alive and process asynchronous network events. For full macOS applications, `PyObjCTools.AppHelper.runEventLoop()` is typically used."},"warnings":[{"fix":"Ensure your Python environment meets the `requires_python` specification for the desired PyObjC version. Upgrade Python if necessary.","message":"PyObjC drops support for older Python versions with major releases. Version 12.0 dropped Python 3.9 support, and version 11.0 dropped Python 3.8 support. Always check `requires_python` on PyPI or the release notes before upgrading PyObjC.","severity":"breaking","affected_versions":">=11.0"},{"fix":"Code that custom-manages reference counts for `init` methods might need review. Most users relying on PyObjC's automatic bridging should see more correct behavior, but complex manual memory management scenarios could be affected.","message":"PyObjC 11.1 changed how initializer methods (those in the 'init' family) behave, aligning with `clang`'s Automatic Reference Counting (ARC) documentation. Specifically, `init` methods now correctly model stealing a reference to `self` and returning a new one.","severity":"breaking","affected_versions":">=11.1"},{"fix":"If encountering issues with class instantiation or `__init__` not being called, review PyObjC's release notes for v10.3/10.3.1. Consider refactoring instantiation logic if it conflicts with PyObjC's `__new__` behavior.","message":"There were changes regarding the interaction of `__init__` and `__new__` in PyObjC versions 10.3 and 10.3.1. While user-implemented `__new__` methods can now correctly use `__init__`, classes relying on `__new__` provided by PyObjC still cannot use `__init__`.","severity":"gotcha","affected_versions":"10.3, 10.3.1"},{"fix":"Always check PyObjC release notes for removed framework bindings, especially when upgrading to new macOS versions or major PyObjC versions. Adapt code to use alternative Apple APIs if a framework binding has been removed.","message":"Specific framework bindings can be removed if Apple deprecates or removes the underlying macOS framework. For example, `IMServicePlugIn` bindings were removed in PyObjC 10.0 because the framework was deprecated in macOS 10.13 and removed in macOS 14.","severity":"breaking","affected_versions":">=10.0 (for IMServicePlugIn, similar issues may occur with other frameworks)"},{"fix":"If targeting Python 3.13 with experimental free-threading, ensure you are using PyObjC 11.0 or later. Be aware that free-threading support is still experimental.","message":"PyObjC 11.0 introduced experimental support for Python 3.13's free-threading (PEP 703). However, PyObjC 10.3, despite having Python 3.13 wheels, did *not* support experimental free-threading, which required significant core changes in v11.0.","severity":"gotcha","affected_versions":"10.3, 11.0"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}