Registry /
http-networking / pyobjc-framework-network
Install & Compatibility
Where this runs
tested against v? · pip install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.940 runs
build_error
glibcpy 3.10–3.940 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
NWPathMonitor
✓ from Network import NWPathMonitor
Framework-specific classes and functions are typically imported directly from the module named after the framework.
NSObject
✓ from Foundation import NSObject
Core Cocoa classes like NSObject and NSRunLoop are part of the Foundation framework, not Network.
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.
import objc
from Foundation import NSObject, NSRunLoop, NSDefaultRunLoopMode, NSDate
from Network import NWPathMonitor, NWPathStatus, NWInterfaceType
class MyPathMonitorDelegate(NSObject):
def init(self):
self = super().init()
if self:
self.monitor = NWPathMonitor.alloc().init()
# Define the path update handler as a Python method
# PyObjC automatically bridges this to an Objective-C block.
self.monitor.setPathUpdateHandler_(self.pathUpdateHandler_)
# Start the monitor on a default dispatch queue (None)
self.monitor.start_(None)
return self
def pathUpdateHandler_(self, path):
"""Called when the network path changes."""
print(f"[Path Update] {path}")
if path.status() == NWPathStatus.satisfied:
print(" Network path is satisfied (connected).")
if path.usesInterfaceType_(NWInterfaceType.wifi):
print(" Using Wi-Fi interface.")
elif path.usesInterfaceType_(NWInterfaceType.cellular):
print(" Using Cellular interface.")
else:
print(" Using another interface type.")
else:
print(" Network path is not satisfied (disconnected).")
def stopMonitor(self):
"""Cancels the path monitor."""
self.monitor.cancel()
print("NWPathMonitor stopped.")
if __name__ == "__main__":
print("Starting NWPathMonitor example...")
delegate = MyPathMonitorDelegate.alloc().init()
print("Monitoring network path for 10 seconds. Press Ctrl+C to stop earlier.")
try:
for _ in range(10):
# Run the current thread's run loop for 1 second intervals
# This is crucial for receiving asynchronous updates from NWPathMonitor
NSRunLoop.currentRunLoop().runMode_beforeDate_(NSDefaultRunLoopMode, NSDate.dateWithTimeIntervalSinceNow_(1.0))
except KeyboardInterrupt:
print("Monitoring interrupted by user.")
finally:
delegate.stopMonitor()
print("Exiting.")
Debug
Known issues
breakingPyObjC 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.fixEnsure your Python environment meets the `requires_python` specification for the desired PyObjC version. Upgrade Python if necessary.
affects: >=11.0
breakingPyObjC 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.fixCode 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.
affects: >=11.1
gotchaThere 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__`.fixIf 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.
affects: 10.3, 10.3.1
breakingSpecific 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.fixAlways 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.
affects: >=10.0 (for IMServicePlugIn, similar issues may occur with other frameworks)
gotchaPyObjC 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.fixIf 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.
affects: 10.3, 11.0
Upgrade
Version history
12.2latest on PyPI · released May 30, 2026
Audit
Dependencies
pyobjc-corerequiredProvides the core bridge between Python and Objective-C, required for all PyObjC framework bindings.
pyobjcoptionalA meta-package that installs pyobjc-core and all available framework wrappers, including pyobjc-framework-network. Convenient for general macOS development.