Post

Replies

Boosts

Views

Activity

Why does my SwiftUI app crash when opened from an intent?
I'm encountering a crash in my SwiftUI app when it is opened via an AppIntent. The app runs perfectly when launched by tapping the app icon, but it crashes when opened from an intent. Here is a simplified version of my code: import AppIntents import SwiftData import SwiftUI @main struct GOGODemoApp: App { @State private var state: MyController = MyController() var body: some Scene { WindowGroup { MyView() //.environment(state) // ok } .environment(state) // failed to start app, crash with 'Dispatch queue: com.apple.main-thread' } } struct MyView: View { @Environment(MyController.self) var stateController var body: some View { Text("Hello") } } @Observable public class MyController { } struct OpenIntents: AppIntent { static var title: LocalizedStringResource = "OpenIntents" static var description = IntentDescription("Open App from intents.") static var openAppWhenRun: Bool = true @MainActor func perform() async throws -> some IntentResult { return .result() } } Observations: The app works fine when launched by tapping the app icon. The app crashes when opened via an AppIntent. The app works if I inject the environment in MyView instead of in WindowGroup. Question: Why does injecting the environment in WindowGroup cause the app to crash when opened from an intent, but works fine otherwise? What is the difference when injecting the environment directly in MyView?
1
0
410
Jul ’24
SwiftUI URLRequest Warning: "Connection has no local endpoint"
I have a simple SwiftUI application that sends a URLRequest as shown in the code snippet below: import SwiftUI @main struct GOGODemoApp: App { var body: some Scene { WindowGroup { MyView() } } } struct MyView: View { var body: some View { Button("Click") { sendHTTPRequest(to: "https://www.google.com") { code, err in print("Finished, code: \(code ?? -1), err: \(String(describing: err))") } } } } func sendHTTPRequest(to urlString: String, completion: @escaping (Int?, Error?) -> Void) { guard let url = URL(string: urlString) else { completion(nil, NSError(domain: "InvalidURL", code: 0, userInfo: nil)) return } let task = URLSession.shared.dataTask(with: url) { _, resp, error in if let httpResponse = resp as? HTTPURLResponse { completion(httpResponse.statusCode, error) } else { completion(-1, error) } } task.resume() } However, Xcode prints the following warning messages: nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint nw_connection_copy_connected_local_endpoint_block_invoke [C3] Connection has no local endpoint nw_connection_copy_connected_local_endpoint_block_invoke [C3] Connection has no local endpoint Finished, code: 200, err: nil What does the warning 'Connection has no local endpoint' mean? Thank you for your assistance!
1
0
846
Jul ’24
What is the affection of insert order in SwiftData
In SwiftData, what is the order of insertion for dependent and parent instances? In the snippet below, it works when the dependent instance is inserted before the parent. However, it fails when the order is reversed. Why is this the case? // // DebugView.swift // gogodict // // Created by djzhu on 2024/1/13. // import Foundation import SwiftData import SwiftUI struct DebugView: View { @Query var parent: [ParentClass] @Query var dept: [DependentClass] var body: some View { Text("parent cnt:\(parent.count), dept cnt:\(dept.count)") } } @Model class ParentClass { @Relationship(deleteRule: .cascade) var deps: DependentClass init(deps: DependentClass) { self.deps = deps } } @Model class DependentClass { var id: String init(id: String = UUID().uuidString) { self.id = id } } #Preview { do { let config = ModelConfiguration(isStoredInMemoryOnly: true) let container = try ModelContainer(for: ParentClass.self, configurations: config) let context = ModelContext(container) var dept = DependentClass() var parentClass = ParentClass(deps: dept) /* ok to insert dept before parent. View shows: "parent cnt:1, dept cnt:1" */ context.insert(dept) context.insert(parentClass) /* ok to insert only parent, swiftData will insert dept too. View shows: "parent cnt:1, dept cnt:1" */ // context.insert(parentClass) /* failed to insert dept after parent, error list below */ // context.insert(parentClass) // context.insert(dept) return DebugView() .modelContainer(container) } catch { return Text("Failed to create container: \(error.localizedDescription)") } } The error log insert dept after parent: Date/Time: 2024-01-13 14:10:10.3694 +0800 Launch Time: 2024-01-13 14:10:09.9932 +0800 OS Version: macOS 14.1.1 (23B81) Release Type: User Report Version: 104 Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x00000001929f3938 Termination Reason: SIGNAL 5 Trace/BPT trap: 5 Terminating Process: exc handler [51868] Triggered by Thread: 0 Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libswiftCore.dylib 0x1929f3938 _assertionFailure(_:_:file:line:flags:) + 248 1 SwiftData 0x1c42fc454 0x1c42d1000 + 177236 2 SwiftData 0x1c4315aac 0x1c42d1000 + 281260 3 SwiftData 0x1c42fd4e0 0x1c42d1000 + 181472 4 DebugView.1.preview-thunk.dylib 0x10161ae10 closure #1 in static $s39gogodict_PreviewReplacement_DebugView_133_20B25209EACDFA98A88DFB5B90B26E4CLl0B0fMf_15PreviewRegistryfMu_.makePreview() + 840 (@__swiftmacro_39gogodict_PreviewReplacement_DebugView_133_20B25209EACDFA98A88DFB5B90B26E4CLl0B0fMf_.swift:18) 5 PreviewsInjection 0x1d6aaa0ec 0x1d6a6f000 + 241900 6 PreviewsInjection 0x1d6aab060 0x1d6a6f000 + 245856 7 libswift_Concurrency.dylib 0x1e450b738 static MainActor.assumeIsolated<A>(_:file:line:) + 144 8 PreviewsInjection 0x1d6aa9e48 0x1d6a6f000 + 241224 9 PreviewsInjection 0x1d6aadfb8 0x1d6a6f000 + 257976 10 PreviewsInjection 0x1d6aaea88 0x1d6a6f000 + 260744 11 PreviewsInjection 0x1d6a9c89c 0x1d6a6f000 + 186524 12 PreviewsInjection 0x1d6a9f5c8 0x1d6a6f000 + 198088 13 PreviewsInjection 0x1d6a87c90 0x1d6a6f000 + 101520 14 PreviewsInjection 0x1d6a88128 0x1d6a6f000 + 102696 15 PreviewsInjection 0x1d6aa0fa0 0x1d6a6f000 + 204704 16 PreviewsInjection 0x1d6a777b8 0x1d6a6f000 + 34744 17 PreviewsInjection 0x1d6a77004 0x1d6a6f000 + 32772 18 PreviewsFoundation 0x1d69b4630 0x1d691c000 + 624176 19 libdispatch.dylib 0x18016b4f4 _dispatch_call_block_and_release + 24 20 libdispatch.dylib 0x18016cd3c _dispatch_client_callout + 16 21 libdispatch.dylib 0x18017bb24 _dispatch_main_queue_drain + 1272 22 libdispatch.dylib 0x18017b61c _dispatch_main_queue_callback_4CF + 40 23 CoreFoundation 0x1803f1a30 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 24 CoreFoundation 0x1803ec148 __CFRunLoopRun + 1936 25 CoreFoundation 0x1803eb5a4 CFRunLoopRunSpecific + 572 26 GraphicsServices 0x18e9fbae4 GSEventRunModal + 160 27 UIKitCore 0x1852f02e4 -[UIApplication _run] + 868 28 UIKitCore 0x1852f3f5c UIApplicationMain + 124 29 SwiftUI 0x1c51fc1b0 0x1c4371000 + 15249840 30 SwiftUI 0x1c51fc050 0x1c4371000 + 15249488 31 SwiftUI 0x1c4f02fa4 0x1c4371000 + 12132260 32 gogodict 0x1009f03b0 static GOGODictApp.$main() + 40 33 gogodict 0x1009f0474 main + 12 (GOGODictApp.swift:12) 34 dyld_sim 0x100bfd544 start_sim + 20 35 dyld 0x100ce60e0 start + 2360 It seems perplexing to someone new like me. Is there any documentation or article that explains the underlying logic of the engine?
0
0
354
Jan ’24
"Understanding Swift Closure Capture Mechanism and Type Inference in the Context of SwiftUI Query Filters"
In SwiftUI, I have a class Notebook that contains an id property. I am encountering a compilation error when I attempt to initialize a Query filter using notebook.id. However, when I assign notebook.id to a local constant id and use that in the filter, the code compiles successfully. Here is the code snippet: @Query var wordNotes: [WordNote] init(notebook: Notebook) { self.notebook = notebook let id = notebook.id _wordNotes = Query(filter: #Predicate<WordNote> { ** in **.notebookId == notebook.id // fails to compile **.notebookId == id // compiles successfully }, sort: \.createTime) } The compilation error I receive when using notebook.id directly is: Cannot convert value of type 'PredicateExpressions.Equal<PredicateExpressions.KeyPath<PredicateExpressions.Variable<WordNote>, String>, PredicateExpressions.KeyPath<PredicateExpressions.Value<Notebook>, String>>' to closure result type 'any StandardPredicateExpression<Bool>'. It appears that the failing code is being converted into a PredicateExpressions.Equal<> object, while the successful code is converted into a StandardPredicateExpression<Bool>. Github Copilot said: In Swift, closures capture and store references to any constants and variables from the context in which they are defined. This is known as closing over those constants and variables, hence the name "closures". In your case, when you're using notebook.id directly inside the closure, Swift tries to capture the notebook object itself. However, because notebook is a complex object, Swift has trouble determining the exact type of the comparison expression, leading to the error you're seeing. But, I have already define notebook: Notebook which means the notebook is a exact type of Notebook. Why the swift still can't determining the type? I have also expand the macro in XCode shows: Foundation.Predicate<WordNote>({ ** in // only <WordNote> PredicateExpressions.build_Equal( lhs: PredicateExpressions.build_KeyPath( root: PredicateExpressions.build_Arg(**), keyPath: \.notebookId ), rhs: PredicateExpressions.build_KeyPath( root: PredicateExpressions.build_Arg(notebook), // doesn't know what type is notebook keyPath: \.id ) ) }) Seems swift only declare that ** is type WordNote by <WordNote>, but why not declare notebook by another generic type? Is uncomplished work of swiftui? Or any obstacle that I don't know? Could you please explain the underlying reason for this behavior?
0
0
381
Jan ’24
SwiftData/ModelContainer.swift:144: Fatal error: failed to find a currently active container for Student
I am currently following the tutorial from Hacking with swift url: (https://www.hackingwithswift.com/books/ios-swiftui/introduction-to-swiftdata-and-swiftui) to integrate SwiftData into a SwiftUI project. The code generated based on the tutorial is provided below. However, an error occurs upon launching the app: SwiftData/ModelContainer.swift:144: Fatal error: failed to find a currently active container for Student. I am seeking assistance in resolving this issue. import SwiftUI import SwiftData @Model class Student { var id: UUID var name: String init(id: UUID, name: String) { self.id = id self.name = name } } @main struct project8App: App { var body: some Scene { WindowGroup { VStack { ContentView() } } .modelContainer(for: Student.self) } } struct ContentView: View { @Environment(\.modelContext) var modelContext @Query var students: [Student] let allStudents = [ Student(id: UUID(), name: "John"), Student(id: UUID(), name: "Paul"), Student(id: UUID(), name: "George"), Student(id: UUID(), name: "Ringo"), ] var body: some View { VStack { ForEach(students) { student in Text("\(student.name)") } Button(action: { // random student let student = allStudents.randomElement()! modelContext.insert(student) }) { Text("Add/Change name") } } } } P.S. It appears that the problem may be related to the container not being initialized by .modelContainer(for: Student.self). I have managed to resolve the error with the modified version below. However, I am still curious about the reasons behind the original version's malfunction and the differences between the two implementations. // version 2, which is ok to run @main struct project8App: App { let modelContainer: ModelContainer init() { do { modelContainer = try ModelContainer(for: Student.self) } catch { fatalError("Could not initialize ModelContainer") } } var body: some Scene { WindowGroup { VStack { ContentView() } } .modelContainer(modelContainer) } }
1
0
1.5k
Jan ’24