Post

Replies

Boosts

Views

Activity

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.2k
Dec ’22
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.7k
Dec ’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.6k
Jan ’23
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
1k
Jan ’25
Can corrupt Xcode project explain broken intellisense?
We have a very large project that consists of 1000+ source files that builds 20+ targets (libraries and different versions of our app). Most is C++. We recently started having problems with intenseness. The strange thing is that compiling and navigation works but simple code completion is suddenly very broken. I manage to narrow it down to a simple use-case by deleting all the targets but one, and all the source files but two. I have a simple main.cpp that includes one header file test.h. If test.h is in the same folder as main.cpp, then intellisense works, but placing it in any other folder (all part of my project), intellisense stops working. I've re-created this simple project from scratch, reproducing the file structure. Intellisense would work in this case. I could open the two projects side by side and went through all project and target settings and they were all identical, but the one from our original project does not work. Can it be that the project contains something corrupt that was built up over the years? I really do not want to create the entire project and targets again from scratch. I've done all the tricks I could find on the forums (Removing Derived folder; opening and closing Xcode; etc.). Nothing works, except apparently creating the project from scratch. The problem is also present in latest Xcode 15 Beta. Any ideas on how to fix this?
1
0
653
Jun ’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.7k
Aug ’23
How to get SwiftUI views to move, not fade when animating change
I am trying to get SwiftUI views to move from one position to another using animation. I know that when the identity of the views change this often result in a fade instead of an animation but I do not believe this is happening in my case. Below is a simple example program with four views from a 2D array (the 2D array is important). There is a button to rotate the views clockwise. I tried using two ForEach blocks but I cannot use it on the outer one because the row arrays does not conform to Identifiable. I also changed my code to write out the views explicitly without the ForEach blocks but I get the same result: The column changes animate as movement but the row changes animate as fades. How do I get it to animate all four views moving clockwise? import SwiftUI struct Block: Identifiable { var id : Int = 0 } struct Board { let numRows = 2 let numCols = 2 var blocks: [[Block]] init() { blocks = Array(repeating: Array(repeating: Block(), count: numCols), count: numRows) for row in 0..<numRows { for col in 0..<numCols { blocks[row][col].id = row * numCols + col } } } mutating func rotate() { let temp = blocks[0][0] blocks[0][0] = blocks[1][0] blocks[1][0] = blocks[1][1] blocks[1][1] = blocks[0][1] blocks[0][1] = temp } } struct BlockView: View { var block: Block var body: some View { ZStack { Rectangle() .fill(Color.secondary) Text("\(block.id)") .font(.largeTitle) } .aspectRatio(1.0, contentMode: .fit) } } struct ContentView: View { @State var board = Board() var body: some View { VStack { Button("Rotate") { withAnimation(.easeInOut(duration: 1.0)) { board.rotate() } } VStack { ForEach(0..<2) { row in HStack { ForEach(board.blocks[row]) { block in BlockView(block: block) } } } } } .padding() } } #Preview { ContentView() }```
0
0
508
Mar ’24
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
180
Sep ’25
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() } }
Replies
3
Boosts
0
Views
1.2k
Activity
Dec ’22
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.
Replies
6
Boosts
0
Views
3.7k
Activity
Dec ’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?
Replies
2
Boosts
0
Views
1.6k
Activity
Jan ’23
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) } } }
Replies
4
Boosts
0
Views
1k
Activity
Jan ’25
Can corrupt Xcode project explain broken intellisense?
We have a very large project that consists of 1000+ source files that builds 20+ targets (libraries and different versions of our app). Most is C++. We recently started having problems with intenseness. The strange thing is that compiling and navigation works but simple code completion is suddenly very broken. I manage to narrow it down to a simple use-case by deleting all the targets but one, and all the source files but two. I have a simple main.cpp that includes one header file test.h. If test.h is in the same folder as main.cpp, then intellisense works, but placing it in any other folder (all part of my project), intellisense stops working. I've re-created this simple project from scratch, reproducing the file structure. Intellisense would work in this case. I could open the two projects side by side and went through all project and target settings and they were all identical, but the one from our original project does not work. Can it be that the project contains something corrupt that was built up over the years? I really do not want to create the entire project and targets again from scratch. I've done all the tricks I could find on the forums (Removing Derived folder; opening and closing Xcode; etc.). Nothing works, except apparently creating the project from scratch. The problem is also present in latest Xcode 15 Beta. Any ideas on how to fix this?
Replies
1
Boosts
0
Views
653
Activity
Jun ’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.
Replies
2
Boosts
0
Views
1.7k
Activity
Aug ’23
How to get SwiftUI views to move, not fade when animating change
I am trying to get SwiftUI views to move from one position to another using animation. I know that when the identity of the views change this often result in a fade instead of an animation but I do not believe this is happening in my case. Below is a simple example program with four views from a 2D array (the 2D array is important). There is a button to rotate the views clockwise. I tried using two ForEach blocks but I cannot use it on the outer one because the row arrays does not conform to Identifiable. I also changed my code to write out the views explicitly without the ForEach blocks but I get the same result: The column changes animate as movement but the row changes animate as fades. How do I get it to animate all four views moving clockwise? import SwiftUI struct Block: Identifiable { var id : Int = 0 } struct Board { let numRows = 2 let numCols = 2 var blocks: [[Block]] init() { blocks = Array(repeating: Array(repeating: Block(), count: numCols), count: numRows) for row in 0..<numRows { for col in 0..<numCols { blocks[row][col].id = row * numCols + col } } } mutating func rotate() { let temp = blocks[0][0] blocks[0][0] = blocks[1][0] blocks[1][0] = blocks[1][1] blocks[1][1] = blocks[0][1] blocks[0][1] = temp } } struct BlockView: View { var block: Block var body: some View { ZStack { Rectangle() .fill(Color.secondary) Text("\(block.id)") .font(.largeTitle) } .aspectRatio(1.0, contentMode: .fit) } } struct ContentView: View { @State var board = Board() var body: some View { VStack { Button("Rotate") { withAnimation(.easeInOut(duration: 1.0)) { board.rotate() } } VStack { ForEach(0..<2) { row in HStack { ForEach(board.blocks[row]) { block in BlockView(block: block) } } } } } .padding() } } #Preview { ContentView() }```
Replies
0
Boosts
0
Views
508
Activity
Mar ’24
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
Replies
7
Boosts
0
Views
180
Activity
Sep ’25