Opening FileDocument with URL → should only be called in the main thread

Its document says openDocument can open a document at a specific URL. So I've saved a model as a JSON object with its URL and a bookmark as Data. With its security-scoped bookmark data resolved, I am able to open a document except that the app will crash right after opening a document. Console says

should only be called in the main thread

struct ContentView: View {
    @EnvironmentObject var bookmarkViewModel: BookmarkViewModel
    
    var body: some View {
		VStack {
		
		}
		.onAppear {
			loadBookmarks()
		}
}

extension ContentView {
    func loadBookmarks() {        
        print("1 \(Thread.current)") // NSMainThread
        
        Task {
            for bookmarkItem in bookmarkViewModel.bookmarkItems { // resolving a security-scoped bookmark
                print("2 \(Thread.current)") // NSMainThread
                if let _ = resolveBookmark(bookmarkData: bookmarkItem.bookmarkData) {
                    print("3 \(Thread.current)") // NSMainThread                    
                    do {
                        print("4 \(Thread.current)") // NSMainThread                        
                        try await openDocument(at: bookmarkItem.bookmarkURL)                        
                        print("5 \(Thread.current)") // NSMainThread                        
                    } catch {
                        print("\(error.localizedDescription)")
                    }
                }
            }
        }
    }
}

Well, the application is on the main thread. I've checked every line before and after opening a document with its URL. Call what on the main thread? This is confusing. Thanks.

class BookmarkViewModel: ObservableObject {
    @Published var bookmarkItems: [BookmarkItem] = []
    
    var defaultFileManager: FileManager {
        return FileManager.default
    }
    
    var documentURL: URL? {
        ...
    }
    
    init() {
        fetchBookmarkItems()
    }
    
    func fetchBookmarkItems() {
        bookmarkItems.removeAll()
        
        if let documentURL {
            let bookmarkFolderURL = documentURL.appending(path: "MyApp").appending(path: "Bookmarks")
            do {
                let contents = try defaultFileManager.contentsOfDirectory(atPath: bookmarkFolderURL.path)
                for content in contents {
                    ...
                	let fileURL = bookmarkFolderURL.appending(path: content)
                    let data = try Data(contentsOf: fileURL)
                    let bookmarkItem = try JSONDecoder().decode(BookmarkItem.self, from: data)
                    bookmarkItems.append(bookmarkItem)
                }
            } catch {
                print("Error fetching folder content: \(error.localizedDescription)")
            }
        }
    }
}
struct BookmarkItem: Codable, Hashable {
    let bookmarkURL: URL
    let date: Date
    let bookmarkData: Data
    let open: Bool
}

Try using the .task view modifier and removing the Task {} from the function instead.

Okay. I get it. If I look at openDocument, it's labeled

@Environment @MainActor

That's where the main thread issue comes to surface, I guess.

Try using the .task view modifier and removing the Task {} from the function instead.

Thanks. But that's not really the main issue here.

Accepted Answer

I've upgraded my system to macOS 15.5. The bug has been system.

Opening FileDocument with URL → should only be called in the main thread
 
 
Q