import Foundation final class Content: ObservableObject { @Published var posts: [Post] = [] @Published var pages: [Page] = [] @Published var tags: [Tag] = [] @Published var images: [ImageResource] = [] @Published var files: [FileResources] = [] func generateFeed(for language: ContentLanguage, bookmarkKey: String) { let posts = posts.map { $0.feedEntry(for: language) } DispatchQueue.global(qos: .userInitiated).async { let navigationItems: [FeedNavigationLink] = [ .init(text: .init(en: "Projects", de: "Projekte"), url: .init(en: "/projects", de: "/projekte")), .init(text: .init(en: "Adventures", de: "Abenteuer"), url: .init(en: "/adventures", de: "/abenteuer")), .init(text: .init(en: "Services", de: "Dienste"), url: .init(en: "/services", de: "/dienste")), .init(text: .init(en: "Tags", de: "Kategorien"), url: .init(en: "/tags", de: "/kategorien")), ] let feed = Feed( language: language, title: .init(en: "Blog | CH", de: "Blog | CH"), description: .init(en: "The latests posts, projects and adventures", de: "Die neusten Beiträge, Projekte und Abenteuer"), iconDescription: .init(en: "An icon consisting of the letters C and H in blue and orange", de: "Ein Logo aus den Buchstaben C und H in Blau und Orange"), navigationItems: navigationItems, posts: posts) let fileContent = feed.content Content.accessFolderFromBookmark(key: bookmarkKey) { folder in let outputFile = folder.appendingPathComponent("feed.html", isDirectory: false) do { try fileContent .data(using: .utf8)! .write(to: outputFile) } catch { print("Failed to save: \(error)") } } } } func importOldContent() { let importer = Importer() do { try importer.importOldContent() } catch { print(error) return } self.posts = importer.posts self.tags = importer.tags #warning("TODO: Copy page sources to data folder") self.pages = importer.pages self.images = importer.images #warning("TODO: Copy images to data folder") } static func accessFolderFromBookmark(key: String, operation: (URL) -> Void) { guard let bookmarkData = UserDefaults.standard.data(forKey: key) else { print("No bookmark data to access folder") return } var isStale = false let folderURL: URL do { // Resolve the bookmark to get the folder URL folderURL = try URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale) } catch { print("Failed to resolve bookmark: \(error)") return } if isStale { print("Bookmark is stale, consider saving a new bookmark.") } // Start accessing the security-scoped resource if folderURL.startAccessingSecurityScopedResource() { print("Accessing folder: \(folderURL.path)") operation(folderURL) folderURL.stopAccessingSecurityScopedResource() } else { print("Failed to access folder: \(folderURL.path)") } } }