Post

Replies

Boosts

Views

Activity

SwiftUI and vars outside the SwiftUI world
We inherited some code that has a variable that begins in the "SwiftUI world", so to speak, and is copied over to a global variable in the "Swift world" for use in non-SwiftUI classes (POSOs? Plain Ol' Swift Objects?). Here's a contrived example showing the basic gist of it. Note how there's an AppViewModel that maintains the state, and an .onChange that copies the value to a global var, which is used in the plain class DoNetworkStuff. I would like to weed out the redundant global var, but I kind of see why it was done this way--how DO you bridge between the 2 worlds? I don't think you can add a ref to AppViewModel inside DoNetworkStuff. I was thinking you could add a function to the AppViewModel that returns devid, and stash a ref to the function in a var for use whenever devid is needed., so at least you're eliminating the var value being stored in 2 places, but that might be confusing a year from now. I'm trying to think of a way to rewrite this without ripping out too much code (it could be that maybe it's better to leave it). var gblDevID = "" //global var class AppViewModel: ObservableObject { @Published var devid = "" ... } struct ContentView: View { @StateObject var appViewModel = AppViewModel() var body: some View { TextField("Enter device id", text: $appViewModel.devid) .onChange(of: appViewModel.devid) { newVal in gblDevID = newVal } ... } } class DoNetworkStuff { func networkingTask() { doSomeTask(gblDevID) } }
5
0
2.7k
Dec ’23
Jetsam memory crash during Network framework usage
I'm using Network Framework to transfer files between 2 devices. The "secondary" device sends file requests to the "primary" device, and the primary sends the files back. When the primary gets the request, it responds like this: do { let data = try Data(contentsOf: filePath) let priSecDataFilePacket = PriSecDataFilePacket(fileName: filename, dataBlob: data) let jsonData = try JSONEncoder().encode(priSecDataFilePacket) let message = NWProtocolFramer.Message(priSecMessageType: PriSecMessageType.priToSecDataFile) let context = NWConnection.ContentContext(identifier: "TransferUtility", metadata: [message]) connection.send(content: encodedJsonToSend, contentContext: context, isComplete: true, completion: .idempotent) } catch { print("\(error)") } It works great, even for hundreds of file requests. The problem arises if some files being requested are extremely large, like 600MB. You can see the memory speedometer on the primary quickly ramp up to the yellow zone, at which point iOS kills the app for high memory use, and you see the Jetsam log. I changed the code to skip JSON encoding the binary file as a test, and that helped a bit, but it still goes too high; the real offender is the step where it loads the 600MB file into the data var: let data = try Data(contentsOf: filePath) If I remark out everything else and just leave that one line, I can still see the memory use spike. As a fix, I'm rewriting this so the secondary requests the file in 5MB chunks by telling the primary a byte range such as "0-5242880" or "5242881-10485760", and then reassembling the chunks on the secondary once they all come in. So far this seems promising, but it's a fair amount of work. My question: Does Network Framework have a built-in way to stream those bytes straight from disk as it sends them? So that I could send all the data in one single request without having to load the bytes into memory?
5
0
422
Mar ’25
Network.Framework vs URLSession in Background Task (BGTask)
As noted here, https://developer.apple.com/forums/thread/116799 the Network framework probably won't have a connection available when running in the background. We've been using the BGTask for a couple years now to start a URLSession and pull data from a web server. It works very nicely and reliably. Do we have any options if we want to connect to another iPad, though? I ran a test and even if I have a "server" iPad running a Network framework listener (NWListener), and the app is in the foreground and the screen on, a "client" iPad (NWBrowser) cannot connect to the NWListener when trying to connect from the BGTask; it gives a DefunctConnection error. Why does the Network framework not have the network available to it, but a URLSession does? Is this a limitation of the iPad, or the Network framework? If I had an iPad running as a web server like this project, https://github.com/swisspol/GCDWebServer and an iPad client tries to connect a URLSession to it, would that work? If this is an iPad limitation, could I use a MacBook on the network as a web server and connect to that instead?
6
0
1.4k
Nov ’23