Post

Replies

Boosts

Views

Activity

How to access parent in List View with children?
I have a simple List with nested children forming a tree. Each item can be checked. If all children are checked (or not) then the parent must reflect this state. It must also be possible to change the state of the children by selecting the parent. Below is a simple example that sort-of works. When you change the state of a parent, the state of all the children change as well. But how do I make it work the other way around so that the parent is notified when a child changes? When all the children are checked, the parent should be checked. I cannot get a reference to the parent. I tried adding handlers but that captures self (the parent) in an escaping closure that mutates it. I created a timer for each item that would periodically check the children but this just feels very wrong. I do not want to convert all the value-type coding to reference types but I cannot find an elegant way of solving this problem. Any suggestions will be greatly appreciated. import SwiftUI struct Item: Identifiable { var id = UUID() var name: String var isSelected: Bool = false { didSet { guard children != nil else { return } for i in 0..<children!.count { children![i].isSelected = isSelected } } } var children: [Item]? } struct ContentView: View { @Binding var itemsTree: [Item] var body: some View { List($itemsTree, children: \.children) { $item in Toggle(item.name, isOn: $item.isSelected) } } } @main struct ListQuestionApp: App { @State private var itemTree: [Item] = [ Item(name: "Level 1", children: [ Item(name: "Level 2", children: [ Item(name: "Item B"), Item(name: "Item A") ]) ]) ] var body: some Scene { WindowGroup { ContentView(itemsTree: $itemTree) } } }
2
0
1.8k
Nov ’22
Why does clean C++ sandbox app crash before reaching main?
Crash Report I have a sandboxed C++ console app that crashes before reaching main. I can reproduce the problem by starting a new, empty console application. It crashes without any changes after I select it to be a sandbox app. I have looked at this (Sandbox activated macOS application crashes immediately after execution) thread and this (Receiving this error 'EXC_BREAKPOINT') one but neither seem to be related, or give any clues. My crash log (attached) mentions "Unable to get bundle identifier for container id". I've added a Info.plist but it made no difference. What is causing this?
2
0
1.5k
Jan ’23
Issues using git in XCode
I feel a bit dumb asking for help because it is clear that git integration in XCode should just work, but it never worked for me and I hope someone can help. I can see some more work went into XCode 15 Beta but it is not working well their either. It always sort-of worked, but many features are just broken. I can do basic commits and push to a remote but almost everything else is broken. The following basic things does not work: Upstream changes are never shown. It shows that I am behind but there is nothing I can do about it. Pull does not work. When I select "Pull" it shows "Loading..." in the dropdown. Pressing the Pull button dismisses the dialog, but does nothing. I have top pull from the command line, or use external app. It does not show my current position in a repo correctly. Neither in my current branch, or when I look at the remotes (origin). Refresh and Fetch has no effect. I can switch to a different point in the branch, but the display does not show me that it happened. I can however confirm with command line or external tool that it worked (and obviously the code). I did a very simple test where I made a local repo on the file system. I then cloned two projects from it, and used it to test the above. It works perfectly from command line, or Sourcetree, but not from XCode. What am I doing wrong? I've read all the help from apple and various guides but clearly I am doing something wrong. It would have been nice if I did not have to switch my tools.
2
0
1.6k
Aug ’23
How to override Edit>Copy when first responder cannot copy
I have a program where I need to handle Edit>Copy when the first responder cannot. I've added the following to my AppDelegate: @IBAction @objc func copy(_ sender: Any?) {     // My code here...   } But Edit>Copy is greyed out on the menu unless a TextField has focus and it has text selected. How do I get my copy function called when the text field has focus but does not have text selected (or any other case where the current view with focus cannot handle copy)?
3
0
1.3k
Feb ’21
Cannot bind to local UDP socket - address already in use
I have some code that used to work but is failing to bind to a local UDP port saying it is already in use. lsof does not show that the port is being used. Below is my receive function that fails. bindResult is "-1" when calling bind, and the error printed out contains "Address already in use (48)". I am trying to bind to 127.0.0.1:6000. This has been working for a very long time, but I've not used it for one or two months, so not sure if a macOS upgrade or something else broke it. func receive(handleRxData: @escaping (UdpSocket, IpAddress, ArraySlice&lt;UInt8&gt;) -&gt; Void,                withError error: (_ msg: String) -&gt; Void) {          self.handleRxData = handleRxData          var cfSocketContext = CFSocketContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)     cfSocketContext.info = Unmanaged.passRetained(self).toOpaque()          cfSock = CFSocketCreate(kCFAllocatorDefault,                             PF_INET,                             SOCK_DGRAM,                             IPPROTO_UDP, CFSocketCallBackType.readCallBack.rawValue,                             { (socket: CFSocket?, callBackType: CFSocketCallBackType, address: CFData?, data: UnsafeRawPointer?, info: UnsafeMutableRawPointer?) -&gt; Void in                               let udpSocket = Unmanaged&lt;UdpSocket&gt;.fromOpaque(info!).takeUnretainedValue()                               udpSocket.receiveCallback()     },                             UnsafeMutablePointer&lt;CFSocketContext&gt;(&amp;cfSocketContext))     let sock = CFSocketGetNative(cfSock)          // Create ipv4 addr struct:     var sin = sockaddr_in()     if (local.type == .ipv4) {       sin.sin_len = __uint8_t(MemoryLayout.size(ofValue: sin))       sin.sin_family = sa_family_t(AF_INET)       sin.sin_addr.s_addr = local.ipv4.bigEndian       sin.sin_port = local.port.bigEndian     }          let bindResult = withUnsafeMutablePointer(to: &amp;sin) {       $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {         bind(sock, UnsafeMutablePointer&lt;sockaddr&gt;($0), socklen_t(MemoryLayout&lt;sockaddr_in&gt;.size))       }     }     if bindResult &lt; 0 {       error("Could not bind to socket \(sin) ( \(String(cString: strerror(errno)!)) (\(errno)).")       return     }          // Change socket to non-blocking:     let flags = fcntl(sock, F_GETFL);     let fcntlResult = fcntl(sock, F_SETFL, flags | O_NONBLOCK);     if (fcntlResult &lt; 0) {       print("Could not change socket to non-blocking ( \(String(cString: strerror(errno)!)) (\(errno)).")     }     // Add to run loop:     let rls = CFSocketCreateRunLoopSource(nil, cfSock, 0);     if (rls == nil) {       error("Could not get run loop source.")       return     }     CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, CFRunLoopMode.commonModes)// CFRunLoopMode.defaultMode);   }
3
0
2.9k
Feb ’22
How to preserve state in reference types in swiftUI
I have a SwiftUI app with a class that conforms to ObservableObject that contains state that I would like to preserve between application launches. How do I do this in swiftUI? I need something similar to @SceneStorage but for reference types. Below is an example showing what I am trying to accomplish. This app shows statistics for a specific network port. I would like to have the StreamStats parameters preserved. I can save the lastPort value using the @SceneStorage property wrapper but this is just to demonstrate the intent. Note: Although this example does not show it, the port member in StreamStats could be changed by code in the class itself. It must not only be reflected correctly the the GUI, but also be saved as part of the state. import SwiftUI @main struct SceneStorageTest: App { var body: some Scene { WindowGroup("Port Statistics", id: "statsView") { ContentView() } } } class StreamStats: ObservableObject { @Published public var port: Int = 60000 init() { startListening() } public func startListening() { print("Gathering stats for port \(port)") } } struct ContentView: View { @SceneStorage("lastPort") var lastPort: Int = 0 @StateObject var streamStats = StreamStats() @Environment(\.openWindow) private var openWindow var body: some View { VStack { Text("Last port: \(lastPort)") TextField("port", value: $streamStats.port, format: .number) Button("Open") { lastPort = streamStats.port streamStats.startListening() } Divider() Button("New Port Statistics Window") { openWindow(id: "statsView") } }.padding() } }
3
0
1.1k
Dec ’22
Can I bind to Int but edit with TextField
My question is slightly broader, but hopefully this simple use case states the point.I ofthen run in to the problem where my source of truth is a custom type (struct, array of bytes, int, etc.) that I want to edit. I would like to write a view that has a binding to this type so that all the editing logic lives inside this view without the views outside having to worry how it is edited.The simplest example of this is a view that takes a binding to an Int where the user edits it with a TextField. Up to now I've only been able to do this with a custom UI- or NSViewRepresentable implementation. I thought I had a solution today, but it too does not work. It is close enough, that I thought maybe someone can see a path going further.Below is my code. It has an IntView that takes a binding to an Int, and uses state for the strValue. When it first apears, it updates the local state. It then has a method that can be called to update the binding value (this because I cannot get updates as the text field is changing).My contentView creates this view and stores updateValue so that it can be called when the button is pressed. The problem is that view is a value (not a reference), so the intView created in body() is not the same one as that in the .async call (I double-checked this with the print that prints the pointer to each). When updateValue() is called, I get an exception, because I am using the wrong view. The reason for using an .async call is so that I do not change state when body is computed.Can this code somehow be made to work, or is there another solution to writing IntView that takes a binding to an Int?My problem is often more complicated for example when I want to bind to a struct. If I write a custom __ViewRepresentable solution, then I lose a lot of the ease-of-use of swift, and goes back to manual layout, etc.struct IntView: View { @Binding var value: Int @State private var strValue: String = "" var body: some View { return TextField("Type here", text: $strValue) .onAppear(perform: { self.strValue = "\(self.value)" }) } func updateValue() { value = Int(strValue)! } } struct ContentView: View { @State var intValue: Int = 12 @State var updateValue: (() -&gt; Void)? var body: some View { let intView = IntView(value: $intValue) withUnsafePointer(to: intView) { print("value at first @\($0)") } DispatchQueue.main.async { withUnsafePointer(to: intView) { print("value in async @\($0)") } self.updateValue = intView.updateValue } return VStack { Text("\(intValue)") intView Button(action: { self.updateValue!() }, label: { Text("Get Value") }) } .padding() .frame(maxWidth: .infinity, maxHeight: .infinity) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
6
0
6k
Apr ’22
Using TextField:text:selection crashes on macOS
I am trying out the new TextField selection ability on macOS but it crashes in various different ways with extremely large stack traces. Looks like it is getting into re-entrant function calls. A similar problem is described on the SwiftUI forums with no responses yet. Here is my simple example struct ContentView: View { @State private var text: String = "" @State private var selection: TextSelection? var body: some View { TextField("Message", text: $text, selection: $selection) .padding() } } Setting text to a value like "Hallo World" causes an instant crash as soon as you start typing in the TextField. Setting text empty (as in example above) lets you edit the text but as it crashes as soon as you commit it (press enter). Any workarounds or fixes?
4
1
531
Dec ’24
Why is AVAudioEngine input giving all zero samples?
I am trying to get access to raw audio samples from mic. I've written a simple example application that writes the values to a text file. Below is my sample application. All the input samples from the buffers connected to the input tap is zero. What am I doing wrong? I did add the Privacy - Microphone Usage Description key to my application target properties and I am allowing microphone access when the application launches. I do find it strange that I have to provide permission every time even though in Settings > Privacy, my application is listed as one of the applications allowed to access the microphone. class AudioRecorder { private let audioEngine = AVAudioEngine() private var fileHandle: FileHandle? func startRecording() { let inputNode = audioEngine.inputNode let audioFormat: AVAudioFormat #if os(iOS) let hardwareSampleRate = AVAudioSession.sharedInstance().sampleRate audioFormat = AVAudioFormat(standardFormatWithSampleRate: hardwareSampleRate, channels: 1)! #elseif os(macOS) audioFormat = inputNode.inputFormat(forBus: 0) // Use input node's current format #endif setupTextFile() inputNode.installTap(onBus: 0, bufferSize: 1024, format: audioFormat) { [weak self] buffer, _ in self!.processAudioBuffer(buffer: buffer) } do { try audioEngine.start() print("Recording started with format: \(audioFormat)") } catch { print("Failed to start audio engine: \(error.localizedDescription)") } } func stopRecording() { audioEngine.stop() audioEngine.inputNode.removeTap(onBus: 0) print("Recording stopped.") } private func setupTextFile() { let tempDir = FileManager.default.temporaryDirectory let textFileURL = tempDir.appendingPathComponent("audioData.txt") FileManager.default.createFile(atPath: textFileURL.path, contents: nil, attributes: nil) fileHandle = try? FileHandle(forWritingTo: textFileURL) } private func processAudioBuffer(buffer: AVAudioPCMBuffer) { guard let channelData = buffer.floatChannelData else { return } let channelSamples = channelData[0] let frameLength = Int(buffer.frameLength) var textData = "" var allZero = true for i in 0..<frameLength { let sample = channelSamples[i] if sample != 0 { allZero = false } textData += "\(sample)\n" } if allZero { print("Got \(frameLength) worth of audio data on \(buffer.stride) channels. All data is zero.") } else { print("Got \(frameLength) worth of audio data on \(buffer.stride) channels.") } // Write to file if let data = textData.data(using: .utf8) { fileHandle!.write(data) } } }
4
0
926
Jan ’25
Why does custom Binding not update UI
I have a class that I cannot change to ObservableObject with Published members. I tried getting around this by writing my own Binding. Although the value is updated correctly, the UI is not. Why is this. Below is a simple demo view. When it is run and the toggle is clicked, it will print out correctly that the value is changed, but the UI does not update. Why? import SwiftUI class BoolWrapper {   public var value = false {     didSet {       print("Value changed to \(value)")     }   } } let boolWrapper = BoolWrapper() struct ContentView: View {   var body: some View {     Toggle(isOn: Binding(get: {       return boolWrapper.value     }, set: { value in       boolWrapper.value = value     }), label: { Text("Toggle") })   } } struct ContentView_Previews: PreviewProvider {   static var previews: some View {     ContentView()   } }
5
0
4.8k
Mar ’24
Where is userDefaults saved for SwiftUI Sandbox app?
I have a SwiftUI sandbox app that uses userDefaults. I would like to verify that the data is correctly saved and also modify it during development to check that my app behaves correctly. I can see the data in ~/Library/Containers//Data/Library/Preferences/.plist. My problem is that when I delete this file to check that my app will behave correctly, then it is re-created with old data. It contains entries that I used for development testing, and not in use any longer. I am unable to get a clean file again. Where is the original data saved, and how do I access it? I've looked in: ~/Library/Preferences ~/Library/Preferences/By Host ~/Library/Caches ~/Library/Saved Application State It is not in one of those locations unless it is named differently. Even a search on my mac did not find it.
6
0
3.6k
Dec ’22
SwiftUI TextField corrupts selection when inserting utf16
The example code below shows what I am trying to achieve: When the user types a '*', it should be replaced with a '×'. It looks like it works, but the cursor position is corrupted, even though it looks OK, and the diagnostics that is printed below shows a valid index. If you type "12*34" you get "12×43" because the cursor is inserting before the shown cursor instead of after. How can I fix this? struct ContentView: View { @State private var input: String = "" @State private var selection: TextSelection? = nil var body: some View { VStack { TextField("Type 12*34", text: $input, selection: $selection) .onKeyPress(action: {keyPress in handleKeyPress(keyPress) }) Text("Selection: \(selectionAsString())") }.padding() } func handleKeyPress(_ keyPress: KeyPress) -> KeyPress.Result { if (keyPress.key.character == "*") { insertAtCursor(text: "×") moveCursor(offset: 1) return KeyPress.Result.handled } return KeyPress.Result.ignored } func moveCursor(offset: Int) { guard let selection else { return } if case let .selection(range) = selection.indices { print("Moving cursor from \(range.lowerBound)") let newIndex = input.index(range.lowerBound, offsetBy: offset, limitedBy: input.endIndex)! let newSelection : TextSelection.Indices = .selection(newIndex..<newIndex) if case let .selection(range) = newSelection { print("Moved to \(range.lowerBound)") } self.selection!.indices = newSelection } } func insertAtCursor(text: String) { guard let selection else { return } if case let .selection(range) = selection.indices { input.insert(contentsOf: text, at: range.lowerBound) } } func selectionAsString() -> String { guard let selection else { return "None" } switch selection.indices { case .selection(let range): if (range.lowerBound == range.upperBound) { return ("No selection, cursor at \(range.lowerBound)") } let lower = range.lowerBound.utf16Offset(in: input) let upper = range.upperBound.utf16Offset(in: input) return "\(lower) - \(upper)" case .multiSelection(let rangeSet): return "Multi selection \(rangeSet)" @unknown default: fatalError("Unknown selection") } } }
Topic: UI Frameworks SubTopic: SwiftUI
7
0
155
Sep ’25
How to use network sockets with async/await?
I have an application that communicates with custom external hardware on the network (using UDP). I have a thread that receives and process the UDP data and then signals a waiting thread by releasing a semaphore when data is available. A have a asyncSendAndReceive and asyncReceive function that just begs to use async/await. But I cannot simply switch because of the use of the semaphore. Various forums and discussions said that semaphores should no longer be used for signalling. If not semaphores, then what else? Note that my two async functions may not always block. If data was received before they were called, then it is queued (and the semaphore is signalled).
9
0
3.8k
Jul ’24