As a workaround, I have found that closing the popover on scene change stops the crash:
@Environment(\.scenePhase) var scenePhase
HStack {
...
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .background {
showPopover = false
}
}
Post
Replies
Boosts
Views
Activity
Doh! That's fixed it - Thanks Ed
I have found a workaround for my own app (which uses my own lightweight framework around the SQLite c/c++ api).
The package referenced below complies the latest version of SQLite into my code. It was very easy to implement and so far seems to have fixed the issue.
https://github.com/sbooth/CSQLite.git
Thank you Stephen Booth.
Bill Aylward
I also have this issue with an enhancement to my app which requires a large file of INSERT statements on initial running and for annual updates. Timings for this on various simulators and devices are shown below.
The following timings are for reading a string containing about 150,000 INSERT statements using Swift's sqlite3_exec call:
MacBook Pro M3: 0.44s
iPhoneSE (3rd generation) Simulator 15.5: 0.52s
iPhoneSE (3rd generation) Simulator 16.4: 7.49s
iPhoneSE (3rd generation) Simulator 17.4: 323.10s
iPad Pro (10.5-inch) 17.5.1 Device 1165.31s
iPhone SE 18.0 (beta) Device 0.69s
The issue does seem to have been fixed for iOS 18, but it remains a deal-breaker for iOS 17. Can anyone suggest a workaround?
Bill Aylward
Thanks Quinn, that's very helpful.
My application does a one-off search for SignalK servers at the start of a session. The user then selects one of them and sticks with it. If there are NO servers on the network, then I wanted to present that information to the user.
In practice, if the code has not discovered any after a few seconds, then I think its safe to say the search has finished (even if the browser is still running)
Thank you Quinn, that's a helpful way forward
Bill
Interesting - this sounds just like the problem I posted just now ("A user is unable to download content in app")
I've read much more about Combine now, and I think it's not possible to put this functionality into the struct itself. However, it CAN be put into a view model like this:
class MarineDatumViewModel: ObservableObject {
@Published var marineDatum: MarineDatum = MarineDatum(value: 0.0) {
didSet {
if marineDatum.isNew {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.marineDatum.makeOld() }
}
}
}
}
I experience the same issue with the .fileExporter, though it does not seem to affect the function of the modifier. The code is more than 12 months old, but the error message is new suggesting some change in iOS or Xcode over the last year has introduced this.
Understood, that's a clever use of a dictionary. Thanks - that solves my issue
Thanks for your reply. The structs are read from a file, so the array can't be populated statically.
I could use classes instead, but wouldn't I still need a switch to choose the appropriate subclass?
A workaround is to add an additional State variable to hold the selected item, like this:
let items = ["One", "Two", "Three"]
@State private var showAlert: Bool = false
@State private var selectedItem: String = ""
var body: some View {
List {
ForEach(items, id: \.self) { item in
Text(item)
.onTapGesture() {
selectedItem = item
showAlert = true
}
.alert(isPresented: $showAlert, content: {
Alert(title: Text(selectedItem), message: Text(selectedItem), dismissButton: .default(Text("OK")))
})
}
}
}
I have similar issue, illustrated with this cut-down code and an alert in place of a sheet which always shows the first item, irrespective of the user selection. Its the same in iOS14 and 15.
let items = ["One", "Two", "Three"]
@State private var showAlert: Bool = false
var body: some View {
List {
ForEach(items, id: \.self) { item in
Text(item)
.onTapGesture() {
showAlert = true
}
.alert(isPresented: $showAlert, content: {
Alert(title: Text(item), message: Text(item), dismissButton: .default(Text("OK")))
})
}
}
}
Thanks Quinn, it was coming out of the cache, and adding your suggested cachePolicy fixes the issue.
Incidentally, when I set up a delegate to handle an authentication challenge like this:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("didReceive challenge \(challenge.protectionSpace.authenticationMethod), failure count: \(challenge.previousFailureCount)") completionHandler(.useCredential, nil)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("Task: \(task.taskIdentifier) didReceive challenge \(challenge.protectionSpace.authenticationMethod)") completionHandler(.useCredential, nil)
}
The output is:
didReceive challenge NSURLAuthenticationMethodServerTrust, failure count: 0
didReceive challenge NSURLAuthenticationMethodServerTrust, failure count: 0
I'm not sure why I am not getting a NSURLAuthenticationMethodHTTPBasic challenge?
Bill Aylward