Post

Replies

Boosts

Views

Activity

Reply to @State variable returns empty despite being set in .onAppear function
Did you change datum to a simple var and not a State var ? Could you show the complete code, to see how Binding is used. Logically, @Binding var index: Int should be in the ContentView and the @State var index = 0 in the other view But I would need to check. PS: don't forget to close the thread, eventually starting a new one where you reference this one.
Topic: Design SubTopic: General Tags:
Aug ’25
Reply to @State variable returns empty despite being set in .onAppear function
Another point. In DataView, index should not be a State variable. Add a button in ContentView VStack { if showView && (index >= 0) && (index < data.count) { DataView(datum: data[index]) } Spacer() HStack { Text("Index: \(index) -> ") Button("Next") { index += 1 if index >= data.count { index = 0 } } } } You will see that text in DataView does not change Text("DataView \(datum.str)") always says DataView String 1 Now change DataView as follows to get it updated on index change by button press: struct DataView: View { /*@State*/ var datum: Data2 var body: some View { Text("DataView \(datum.str)") } } Note: I renamed data to datum for an array item, to differentiate from the array. Now, I have to update my initial answer. In fact, no need for showView and Dispatch (even though that made it work). Just test index: if (index < data.count) { DataView(datum: data[index]) Without the index test, it crashes… Swift/ContiguousArrayBuffer.swift:691: Fatal error: Index out of range Reason is that DataView is not called immediately but only when State var data is populated by getData (then count changes) and has all its elements. So the test has a similar effect as Dispatch to wait for data to be fetched.
Topic: Design SubTopic: General Tags:
Aug ’25
Reply to @State variable returns empty despite being set in .onAppear function
It is a question of timing. When onAppear returns, and DataView is called, the array is not yet populated, even though its count is already OK. You have to wait for a short time in onAppear (0.01 s should be OK). Here is the solution. I had to rename Data to avoid the error above (Data is a Foundation type). I renamed to Data2 struct Data2: Decodable, Hashable { let index: Int let str: String } struct DataView: View { @State var data: Data2 var body: some View { Text("DataView \(data.str)") } } struct ContentView: View { @State var showView = false // To wait for array to be populated before we display the view @State var data: [Data2] @State var index: Int = 0 var body: some View { VStack { if showView { DataView(data: data[index]) // Text("Hello \(data.count)") // To test if needed ; without async, data.count is 2. Seems OK, but… // Text("Hello \(data.count) index \(index) \(data[0].str)") // but without async, it will crash, as data is not populated yet, even if count is already 2 } } .onAppear { let filePath = Bundle.main.path(forResource: "data", ofType: "json") let url = URL(fileURLWithPath: filePath!) data = getData(url: url) DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // <<-- THE KEY POINT 0.1 sec delay self.showView = true } } } func getData(url: URL) -> [Data2] { do { let data = try Data(contentsOf: url) let jsonDecoded = try JSONDecoder().decode([Data2].self, from: data) return jsonDecoded } catch let error as NSError { print("Fail: \(error.localizedDescription)") } catch { print("Fail: \(error)") } return [] } } Credit: https://stackoverflow.com/questions/62355428/how-do-i-show-a-new-view-after-some-delay-amount-of-time-swiftui A simpler option is to use an init: struct ContentView: View { @State var data: [Data2] @State var index: Int = 0 init() { let filePath = Bundle.main.path(forResource: "data", ofType: "json") let url = URL(fileURLWithPath: filePath!) // data = getData(url: url) // We cannot call getData in init do { let dataRead = try Data(contentsOf: url) let jsonDecoded = try JSONDecoder().decode([Data2].self, from: dataRead) data = jsonDecoded return } catch let error as NSError { print("Fail: \(error.localizedDescription)") } catch { print("Fail: \(error)") } data = [] return } var body: some View { VStack { DataView(data: data[index]) } } }
Topic: Design SubTopic: General Tags:
Aug ’25
Reply to Tab bar controller drag and drop order of items not working
I succeeded moving Xcode 16.4, MacMini, MacOS 15.6 (24G84): Here is the initial tabbar I click on the tabor in the TabBarController it turns blue I click on icon of item 1 and start dragging (I had to take care to hold the mouse pressed). A position caret appears (I cannot screenshot the caret) and icon starts to move and the other to rearrange I move the caret (and the icon) to the desired position) and drop it The icons are reordered If that's OK, don't forget to close the thread on this answer ; otherwise please explain where it fails. As you noticed, there is another way to do it, by creating the segues in desired order.
Aug ’25
Reply to @State variable returns empty despite being set in .onAppear function
Could you provide complete code as well as the json file ? Is Data a structure you have defined ? If it is an empty set, it should crash at: DataView(data: data[index]) Do you get Fail messages ? Problem is not in onAppear. I tested by replacing getData by a dummy call .onAppear { // let filePath = Bundle.main.path(forResource: "data", ofType: "json") // let url = URL(fileURLWithPath: filePath!) // // data = getData(url: url) data = [Data()] } And data DataView is not empty, as I could check with the following struct DataView: View { @State var data: Data var body: some View { Text("DataView \(data)") } } So, it looks like you return from getData by line 29 and not 22. So, could you change line 29, to return a custom single data to check ?
Topic: Design SubTopic: General Tags:
Aug ’25
Reply to Swift 6 conversion for IBOutlet
@eskimo that was when testing with Swift6 and Xcode 16.4. But after encapsulating the code using IBOutlet in MainActor.assumeIsolated({ // using textField.text }) I could remove the nonIsolated declaration for IBOutlet and get it working. Unfortunately, I've not kept a version to reproduce the error. In any case, I will not switch to Swift6 before using Xcode 26.
Topic: Programming Languages SubTopic: Swift Tags:
Aug ’25
Reply to Crash in Swift 6 when using UNUserNotification
@Engineer Thanks for reply. Some more crash info. On simulator (did not test on device at this stage). Here is crash report: Error occurs in #4 notifyMe IBAction @IBAction func notifyMe(_ sender: UIButton) { let center = UNUserNotificationCenter.current() center.delegate = self center.getNotificationSettings(completionHandler: { (settings) in if settings.authorizationStatus == .notDetermined { center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in DispatchQueue.main.async { if !granted { // Alert user } } } } else if settings.authorizationStatus == .denied { DispatchQueue.main.async { // Alert user } } else if settings.authorizationStatus == .authorized { DispatchQueue.main.async { self.alarmButton.isHidden = self.duree <= 120 } } }) var alertStyle = UIAlertController.Style.alert let alertController = UIAlertController( title: NSLocalizedString("M'avertir", comment: ""), message: NSLocalizedString("Attention", comment: ""), preferredStyle: alertStyle) var title = NSLocalizedString("5'", comment: "") let ok = UIAlertAction(title: title, style: .default, handler: {(action) -> Void in self.sendInitialNotification(beforeEnd: 5) DispatchQueue.main.async { sender.isHidden = true } }) alertController.addAction(ok) let cancelAction = UIAlertAction(title: NSLocalizedString("Non", comment: ""), style: .default, handler: { (action) -> Void in alertController.addAction(cancelAction) present(alertController, animated: true, completion: nil) } Crash apparently occurs on calling userNotificationCenter: nonisolated func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { if notification.request.identifier == requestIdentifier { completionHandler( [.alert,.sound,.badge]) } }
Aug ’25
Reply to Swift 6 conversion for IBOutlet
Thanks Quinn. I removed the nonisolated for IBOutlet. But, as shown in your example, I had to mark all func în a class that uses UNUserNotificationCenterDelegate as nonIsolated, such as nonisolated func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) I also note in your example that you marked response for didReceive as async. I tried to, but got the error: Instance method 'userNotificationCenter(_:didReceive:withCompletionHandler:)' nearly matches optional requirement 'userNotificationCenter(_:didReceive:withCompletionHandler:)' of protocol 'UNUserNotificationCenterDelegate' with the advice to Make 'userNotificationCenter_:didReceive:withCompletionHandler:)' private to silence this warning Converting to Swift 6 is definitely not an easy ride… I'll do extensive testing.
Topic: Programming Languages SubTopic: Swift Tags:
Aug ’25
Reply to Crash in Swift 6 when using UNUserNotification
Thanks for the answer. didReceive was already non isolated. So problem likely does not come from here. For willPresent, if I don't make it nonIsolated, I get an Xcode 16.4 compiler error: Main actor-isolated instance method 'userNotificationCenter(_:willPresent:withCompletionHandler:)' cannot be used to satisfy nonisolated requirement from protocol 'UNUserNotificationCenterDelegate' n Xcode 26, no error in func declaration if I remove nonIsolated. But error at UIViewController class definition level Conformance of 'CalcViewController' to protocol 'UNUserNotificationCenterDelegate' crosses into main actor-isolated code and can cause data races
Aug ’25
Reply to @State variable returns empty despite being set in .onAppear function
Did you change datum to a simple var and not a State var ? Could you show the complete code, to see how Binding is used. Logically, @Binding var index: Int should be in the ContentView and the @State var index = 0 in the other view But I would need to check. PS: don't forget to close the thread, eventually starting a new one where you reference this one.
Topic: Design SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to @State variable returns empty despite being set in .onAppear function
Another point. In DataView, index should not be a State variable. Add a button in ContentView VStack { if showView && (index >= 0) && (index < data.count) { DataView(datum: data[index]) } Spacer() HStack { Text("Index: \(index) -> ") Button("Next") { index += 1 if index >= data.count { index = 0 } } } } You will see that text in DataView does not change Text("DataView \(datum.str)") always says DataView String 1 Now change DataView as follows to get it updated on index change by button press: struct DataView: View { /*@State*/ var datum: Data2 var body: some View { Text("DataView \(datum.str)") } } Note: I renamed data to datum for an array item, to differentiate from the array. Now, I have to update my initial answer. In fact, no need for showView and Dispatch (even though that made it work). Just test index: if (index < data.count) { DataView(datum: data[index]) Without the index test, it crashes… Swift/ContiguousArrayBuffer.swift:691: Fatal error: Index out of range Reason is that DataView is not called immediately but only when State var data is populated by getData (then count changes) and has all its elements. So the test has a similar effect as Dispatch to wait for data to be fetched.
Topic: Design SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to @State variable returns empty despite being set in .onAppear function
It is a question of timing. When onAppear returns, and DataView is called, the array is not yet populated, even though its count is already OK. You have to wait for a short time in onAppear (0.01 s should be OK). Here is the solution. I had to rename Data to avoid the error above (Data is a Foundation type). I renamed to Data2 struct Data2: Decodable, Hashable { let index: Int let str: String } struct DataView: View { @State var data: Data2 var body: some View { Text("DataView \(data.str)") } } struct ContentView: View { @State var showView = false // To wait for array to be populated before we display the view @State var data: [Data2] @State var index: Int = 0 var body: some View { VStack { if showView { DataView(data: data[index]) // Text("Hello \(data.count)") // To test if needed ; without async, data.count is 2. Seems OK, but… // Text("Hello \(data.count) index \(index) \(data[0].str)") // but without async, it will crash, as data is not populated yet, even if count is already 2 } } .onAppear { let filePath = Bundle.main.path(forResource: "data", ofType: "json") let url = URL(fileURLWithPath: filePath!) data = getData(url: url) DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // <<-- THE KEY POINT 0.1 sec delay self.showView = true } } } func getData(url: URL) -> [Data2] { do { let data = try Data(contentsOf: url) let jsonDecoded = try JSONDecoder().decode([Data2].self, from: data) return jsonDecoded } catch let error as NSError { print("Fail: \(error.localizedDescription)") } catch { print("Fail: \(error)") } return [] } } Credit: https://stackoverflow.com/questions/62355428/how-do-i-show-a-new-view-after-some-delay-amount-of-time-swiftui A simpler option is to use an init: struct ContentView: View { @State var data: [Data2] @State var index: Int = 0 init() { let filePath = Bundle.main.path(forResource: "data", ofType: "json") let url = URL(fileURLWithPath: filePath!) // data = getData(url: url) // We cannot call getData in init do { let dataRead = try Data(contentsOf: url) let jsonDecoded = try JSONDecoder().decode([Data2].self, from: dataRead) data = jsonDecoded return } catch let error as NSError { print("Fail: \(error.localizedDescription)") } catch { print("Fail: \(error)") } data = [] return } var body: some View { VStack { DataView(data: data[index]) } } }
Topic: Design SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to Tab bar controller drag and drop order of items not working
I succeeded moving Xcode 16.4, MacMini, MacOS 15.6 (24G84): Here is the initial tabbar I click on the tabor in the TabBarController it turns blue I click on icon of item 1 and start dragging (I had to take care to hold the mouse pressed). A position caret appears (I cannot screenshot the caret) and icon starts to move and the other to rearrange I move the caret (and the icon) to the desired position) and drop it The icons are reordered If that's OK, don't forget to close the thread on this answer ; otherwise please explain where it fails. As you noticed, there is another way to do it, by creating the segues in desired order.
Replies
Boosts
Views
Activity
Aug ’25
Reply to @State variable returns empty despite being set in .onAppear function
Could you provide complete code as well as the json file ? Is Data a structure you have defined ? If it is an empty set, it should crash at: DataView(data: data[index]) Do you get Fail messages ? Problem is not in onAppear. I tested by replacing getData by a dummy call .onAppear { // let filePath = Bundle.main.path(forResource: "data", ofType: "json") // let url = URL(fileURLWithPath: filePath!) // // data = getData(url: url) data = [Data()] } And data DataView is not empty, as I could check with the following struct DataView: View { @State var data: Data var body: some View { Text("DataView \(data)") } } So, it looks like you return from getData by line 29 and not 22. So, could you change line 29, to return a custom single data to check ?
Topic: Design SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to Swift 6 conversion for IBOutlet
@eskimo that was when testing with Swift6 and Xcode 16.4. But after encapsulating the code using IBOutlet in MainActor.assumeIsolated({ // using textField.text }) I could remove the nonIsolated declaration for IBOutlet and get it working. Unfortunately, I've not kept a version to reproduce the error. In any case, I will not switch to Swift6 before using Xcode 26.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to Crash in Swift 6 when using UNUserNotification
@Engineer Thanks for reply. Some more crash info. On simulator (did not test on device at this stage). Here is crash report: Error occurs in #4 notifyMe IBAction @IBAction func notifyMe(_ sender: UIButton) { let center = UNUserNotificationCenter.current() center.delegate = self center.getNotificationSettings(completionHandler: { (settings) in if settings.authorizationStatus == .notDetermined { center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in DispatchQueue.main.async { if !granted { // Alert user } } } } else if settings.authorizationStatus == .denied { DispatchQueue.main.async { // Alert user } } else if settings.authorizationStatus == .authorized { DispatchQueue.main.async { self.alarmButton.isHidden = self.duree <= 120 } } }) var alertStyle = UIAlertController.Style.alert let alertController = UIAlertController( title: NSLocalizedString("M'avertir", comment: ""), message: NSLocalizedString("Attention", comment: ""), preferredStyle: alertStyle) var title = NSLocalizedString("5'", comment: "") let ok = UIAlertAction(title: title, style: .default, handler: {(action) -> Void in self.sendInitialNotification(beforeEnd: 5) DispatchQueue.main.async { sender.isHidden = true } }) alertController.addAction(ok) let cancelAction = UIAlertAction(title: NSLocalizedString("Non", comment: ""), style: .default, handler: { (action) -> Void in alertController.addAction(cancelAction) present(alertController, animated: true, completion: nil) } Crash apparently occurs on calling userNotificationCenter: nonisolated func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { if notification.request.identifier == requestIdentifier { completionHandler( [.alert,.sound,.badge]) } }
Replies
Boosts
Views
Activity
Aug ’25
Reply to Swift 6 conversion for IBOutlet
Thanks Quinn. I removed the nonisolated for IBOutlet. But, as shown in your example, I had to mark all func în a class that uses UNUserNotificationCenterDelegate as nonIsolated, such as nonisolated func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) I also note in your example that you marked response for didReceive as async. I tried to, but got the error: Instance method 'userNotificationCenter(_:didReceive:withCompletionHandler:)' nearly matches optional requirement 'userNotificationCenter(_:didReceive:withCompletionHandler:)' of protocol 'UNUserNotificationCenterDelegate' with the advice to Make 'userNotificationCenter_:didReceive:withCompletionHandler:)' private to silence this warning Converting to Swift 6 is definitely not an easy ride… I'll do extensive testing.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to Crash in Swift 6 when using UNUserNotification
Thanks for the answer. didReceive was already non isolated. So problem likely does not come from here. For willPresent, if I don't make it nonIsolated, I get an Xcode 16.4 compiler error: Main actor-isolated instance method 'userNotificationCenter(_:willPresent:withCompletionHandler:)' cannot be used to satisfy nonisolated requirement from protocol 'UNUserNotificationCenterDelegate' n Xcode 26, no error in func declaration if I remove nonIsolated. But error at UIViewController class definition level Conformance of 'CalcViewController' to protocol 'UNUserNotificationCenterDelegate' crosses into main actor-isolated code and can cause data races
Replies
Boosts
Views
Activity
Aug ’25