-
-
Save Clustmart/707fe005fecc1efcb7fe51b3ff8d1e42 to your computer and use it in GitHub Desktop.
| import Foundation | |
| // Define the file path to save the CSV | |
| let filePath = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent("bookmarks.csv") | |
| // Create the CSV file if it doesn't exist | |
| if !FileManager.default.fileExists(atPath: filePath.path) { | |
| FileManager.default.createFile(atPath: filePath.path, contents: nil, attributes: nil) | |
| } | |
| // Open the file handle for writing | |
| guard let fileHandle = try? FileHandle(forWritingTo: filePath) else { | |
| print("Failed to open file for writing.") | |
| exit(1) | |
| } | |
| defer { | |
| fileHandle.closeFile() | |
| } | |
| // Write the CSV headers | |
| let headers = "Website name,URL,Bookmark path\n" | |
| fileHandle.write(headers.data(using: .utf8)!) | |
| // Get all bookmarks | |
| let bookmarksPlistPath = "\(NSHomeDirectory())/Library/Safari/Bookmarks.plist" | |
| let bookmarksData = try! Data(contentsOf: URL(fileURLWithPath: bookmarksPlistPath)) | |
| let plist = try! PropertyListSerialization.propertyList(from: bookmarksData, options: [], format: nil) | |
| // Recursive function to get all bookmarks with their parent folders | |
| func getAllBookmarks(bookmarks: [[String: Any]], parentFolders: [String]) -> [[String]] { | |
| var results: [[String]] = [] | |
| for bookmark in bookmarks { | |
| if let url = bookmark["URLString"] as? String, | |
| let uriDictionary = bookmark["URIDictionary"] as? [String: Any], | |
| let name = uriDictionary["title"] as? String { | |
| let bookmarkPath = parentFolders.joined(separator: " > ") | |
| results.append([name, url, bookmarkPath]) | |
| } | |
| if let children = bookmark["Children"] as? [[String: Any]] { | |
| let newParentFolders = parentFolders + [bookmark["Title"] as! String] | |
| results += getAllBookmarks(bookmarks: children, parentFolders: newParentFolders) | |
| } | |
| } | |
| return results | |
| } | |
| // Call the recursive function to get all bookmarks with their parent folders | |
| let allBookmarks = getAllBookmarks(bookmarks: (plist as! NSDictionary)["Children"] as! [[String: Any]], parentFolders: []) | |
| // Write the bookmarks to the CSV | |
| for bookmark in allBookmarks { | |
| let line = "\(bookmark[0]),\(bookmark[1]),\(bookmark[2])\n" | |
| fileHandle.write(line.data(using: .utf8)!) | |
| } | |
| print("Bookmarks exported to: \(filePath)") |
Thank you for taking the time to try out the code. It appears that the program required an existing bookmarks.csv file, which might have caused some confusion. I have addressed this issue and updated the code to create the file automatically if it doesn't exist. This modification should eliminate the need for a pre-existing bookmarks.csv file.
Thank you for the response! I have tried the new code, but ran into similar issues
./export-safari-bookmarks-new.swift
./export-safari-bookmarks-new.swift: line 1: import: command not found
./export-safari-bookmarks-new.swift: line 3: //: is a directory
./export-safari-bookmarks-new.swift: line 4: syntax error near unexpected token `('
./export-safari-bookmarks-new.swift: line 4: `let filePath = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent("bookmarks.csv")'
I actually had the import command not found issue, before as well.
I realized that maybe this script was not meant as an executable file, so I tried running it with
swift export-safari-bookmarks-new.swift
which got me permission error, so I tried with sudo but that messed with NSHomeDirectory().
I don't have any prior experience with Swift, can you please share some instructions for your workflow?
I couldn't replicate your issue. The error import: command not found indicates that the import statement is being interpreted as a shell command rather than a valid Swift language construct. This typically happens when you try to execute a Swift script using a shell interpreter.
You should make sure that swift is installed (execute swift --version). Executing swift export-safari-bookmarks-new.swift is correct, it works on my system.
I gave this a try but I am not sure what went wrong: