-
-
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: