Missing Network Crate
NSNetService in Foundation has all been deprecated:
- See official documentation here: https://developer.apple.com/documentation/foundation/nsnetservice
- See https://forums.developer.apple.com/forums/thread/682744
It's been succeeded by the Network Framework: https://developer.apple.com/documentation/network?language=objc
I can only see a NetworkExtension autogenerated crate; which is completely different than Network
Question:
- How can I generate the
Networkcrate/feature since it's missing - Alternatively, can I call these methods without the Network crate on version 0.5.2?
Yeah, see https://github.com/madsmtm/objc2/issues/556, more work is needed to figure out how memory management should work.
can I call these methods without the Network crate on version 0.5.2?
You should be able to, you'll have to write the extern "C" definitions yourself, but it's a lot of work. For an API like nw_browser_create, to take a random example, the C header contains:
NW_RETURNS_RETAINED nw_browser_t
nw_browser_create(nw_browse_descriptor_t descriptor,
_Nullable nw_parameters_t parameters);
So in Rust you'd write something like:
// --- Declare protocols that is used in Network
extern_protocol!(
unsafe trait OS_nw_browser: NSObjectProtocol {}
unsafe impl ProtocolType for dyn OS_nw_browser {}
);
type nw_browser_t = ProtocolObject<dyn OS_nw_browser>;
extern_protocol!(
unsafe trait OS_nw_parameters: NSObjectProtocol {}
unsafe impl ProtocolType for dyn OS_nw_parameters {}
);
type nw_parameters_t = ProtocolObject<dyn OS_nw_parameters>;
extern_protocol!(
unsafe trait OS_nw_browse_descriptor: NSObjectProtocol {}
unsafe impl ProtocolType for dyn OS_nw_browse_descriptor {}
);
type nw_browse_descriptor_t = ProtocolObject<dyn OS_nw_browse_descriptor>;
// --- Declare the actual function prototype
extern "C" {
fn nw_browser_create(
descriptor: &nw_browse_descriptor_t,
parameters: Option<&nw_parameters_t>,
) -> *mut nw_browser_t;
}
// --- Usage
// SAFETY: Uses `Retained::from_raw` because of `NW_RETURNS_RETAINED`.
let browser = unsafe { Retained::from_raw(nw_browser_create(descriptor, parameters)) };
I think, at least, I doubt I'm familiar enough with the Network framework to help you out further, though feel free to ask!
With #556 closed, could a Network framework crate now be generated?
Possibly, though I found out that Network uses "OS objects" under the hood. So it will probably need a wrapper like DispatchRetained, but which calls nw_retain/nw_release:
https://github.com/madsmtm/objc2/blob/c589b66f7fe5e7705138758f3612105d39eb1f42/crates/dispatch2/src/retained.rs
I would very much like to have Network Framework in Rust, because it seems that without it you can't implement sending traffic from TUN to a local proxy server.
Yes nw_retain and nw_release need to be used.
With addition of Network framework, it should be possible to finally expose the virtualInterface from NEPacketTunnelProvider. This property is available since iOS 18.
I wonder how availability is being handled by objc2? Is there anything stopping the consumer of objc2 framework from calling functions that aren't available on the deployment target?
I wonder how availability is being handled by objc2? Is there anything stopping the consumer of objc2 framework from calling functions that aren't available on the deployment target?
Nope. You have to check for such things dynamically, with one of:
use objc2::{available, msg_send, rc::Retained, sel, runtime::NSObjectProtocol};
// Check OS version
if available!(ios = 18.0, macos = 15.0, tvos = 18.0, visionos = 2.0) {
let interface: Retained<AnyObject> = unsafe { msg_send![tunnel_provider, virtualInterface] };
}
// Check method exists
if tunnel_provider.respondsToSelector(sel!(virtualInterface)) {
let interface: Retained<AnyObject> = unsafe { msg_send![tunnel_provider, virtualInterface] };
}
See also https://github.com/madsmtm/objc2/issues/266.
This is becoming important for us because we use NetworkExtension that deprecated NWEndpoint and all its sub-classes since macOS 15 ending at mac0S 15 as well in favor of nw_endpoint_t, so in turn deprecates a whole bunch of other types and methods in the framework, while there is currently no easy pure-objc2 way to handle this transition as the Network types nor the nw_endpoint_t-based methods are made available here.
I have started working on it in https://github.com/madsmtm/objc2/pull/786. Please help me shape it into something workable.