PyObjC Network Framework

12.1 · active · verified Tue Apr 14

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.

Warnings

Install

Imports

Quickstart

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.")

view raw JSON →