Is there a way to prevent a Swift Package Manager package from exposing its own dependencies to the applications that use the package?
Here's current observed behavior:
PackageA, a Swift static library (no framework, just source files) This contains an SPM dependency declared in its Package.swift manifest: PackageB, a static library (no framework, just source files)
In Xcode, in a Application .xcproject, PackageA gets added as a dependency through the Swift Package Manager via its GitHub repo URL *.swift source files do not see any of LibraryA or LibraryB contents until they are imported (which is normal) As soon as you import PackageA in a *.swift file, both PackageA and PackageB are exposed in that scope (this is undesirable)
My expectation would be that only PackageA's methods and objects be exposed to the Application by default and not also expose all of its dependencies. I would expect the methods in PackageB would only be exposed if the Application also imports PackageB explicitly in a *.swift file's scope.
Is there a way to prevent LibraryB from being imported when only import LibraryA is used?
(What makes this additionally confounding is that if you open the LibraryA package itself in Xcode, LibraryB is only available when import LibraryB is denoted, which makes sense. However, when an application imports LibraryA, then unconditionally LibraryB is exposed to the application every time. This seems incorrect behavior.)
I'm at a bit of a dead-end here and hope someone can shed some light.Recently refactored a macOS app that sends and receives data on a wired LAN to use Network Framework, and through some stumbling around I've gotten UDP receive (NWListener) working great.Here's my issue: NWConnection acting as a UDP client (send-only) is working great seemingly -- but once the network connection is lost and returns (ie: unplug the Ethernet cable and plug it back in, or any other condition that would cause connectivity to be lost), the NWConnection simply stops sending messages altogether until I quit and restart my app.As soon as connectivity is lost and my app tries to send a UDP message, I see these errors in the console:[] nw_socket_service_writes_block_invoke [C1:1] sendmsg(fd 7, 28 bytes) [49: Can't assign requested address][] nw_endpoint_flow_prepare_output_frames Failing the write requests [49: Can't assign requested address]And apparently it is not able to recover after that.I've checked the documentation, Googled and tried everything I can think of trial-and-error wise and I'm coming up dry.Through all of it, the state never leaves "ready," but the viability does come and go as the network link goes down and up again as you'd epect.From what I've read, this sort of connectivity issue should remedy/resolve itself within Network Framework and I shouldn't have to manually deal with it. But if I do, how would I go about it?I've checked all the connection parameters, context meta data, etc. Really not sure what I'm doing wrong.Thanks!public class UDPClient {
public final let name: String
internal final var gcdThread: DispatchQueue = DispatchQueue.main // placeholder; custom thread will be created at class init
internal final func makegcdThread() {
gcdThread = DispatchQueue(label: specifics.app.bundleID + ".udpclient." + name)
}
private var connection: NWConnection?
private var parameters: NWParameters!
private var context: NWConnection.ContentContext?
public internal(set) var host: NWEndpoint.Host
public internal(set) var port: NWEndpoint.Port
public init(name: String, host: NWEndpoint.Host, port: NWEndpoint.Port = 0, parameters: NWParameters? = nil, context: NWConnection.ContentContext? = nil) {
self.name = name
// cache address & port
self.host = host
self.port = port
self.context = context
makegcdThread()
// port params
let params: NWParameters
if parameters != nil {
// user parameers used
params = parameters!
} else {
// default parameters used
params = NWParameters.udp
params.allowLocalEndpointReuse = true
params.includePeerToPeer = true
}
self.parameters = params
// set up connection
connect()
}
internal final func connect() {
// new connection
connection = NWConnection(host: host, port: port, using: self.parameters)
// update handler
connection?.stateUpdateHandler = { [weak self] state in
// state seems to never change and is always in "ready" state for a UDP client...?
self?.stateDidChange(to: state)
}
connection?.viabilityUpdateHandler = { [weak self] isViable in
self?.viabilityDidChange(to: isViable)
}
// start connection
connection?.start(queue: gcdThread)
}
}