Posts

Post marked as solved
1 Replies
1.9k Views
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.)
Posted
by orchetect.
Last updated
.
Post marked as solved
4 Replies
2.2k Views
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) } }
Posted
by orchetect.
Last updated
.