LoginSignup
0
0

More than 1 year has passed since last update.

Finderの「サーバへ接続」の「よく使うサーバ」リストに一括追加する

Last updated at Posted at 2022-01-08

Finderの「サーバへ接続」画面において,+ ボタンを押すと,「よく使うサーバ」にサーバのURLを追加できます。

image.png

ここに登録したいサーバがたくさんあるとき,コマンドで一括追加したくなります。

かつては,

$ /usr/bin/sfltool add-item -n "hoge" com.apple.LSSharedFileList.FavoriteServers "smb://hoge@192.168.0.100"

のようなコマンドで「よく使うサーバ」リストに追加ができました。これにより,~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.FavoriteServers.sfl2 にサーバのエントリが追記されたのです。

これをシェルスクリプトにしておけば,よく使うサーバを大量に一括登録できたのですが,なんと,macOS 10.13 以降,sfltool コマンドに add-item というサブコマンドは廃止され,復活の予定はないそうです。

そこで,com.apple.LSSharedFileList.FavoriteServers.sfl2 にエントリを追加するには,結構面倒なプログラミングが必要になりました。Swiftコードで書くとこのようになります(エラー処理はテキトーです)。

import Foundation

let error = NSError(domain: "error", code: -1, userInfo: nil)
let sflURL = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("Library").appendingPathComponent("Application Support").appendingPathComponent("com.apple.sharedfilelist").appendingPathComponent("com.apple.LSSharedFileList.FavoriteServers.sfl2")

func readFavoriteServers() throws -> (items: NSArray, properties: NSDictionary, existingURLs: [URL]) {
    guard let dict = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(Data(contentsOf: sflURL)) as? NSDictionary,
          let items = dict["items"] as? NSArray,
          let properties = dict["properties"] as? NSDictionary else { throw error }

    // 型情報
    // dict: NSDictionary<NSString*,id>*
    // items: NSArray<NSDictionary<NSString*,id>*>*
    // properties: NSDictionary<NSString*,id>*

    let existingURLs: [URL] = items.compactMap { item in
        var stale: Bool = false
        guard let item = item as? NSDictionary,
              let data = item["Bookmark"] as? Data,
              let url = try? URL(resolvingBookmarkData: data, bookmarkDataIsStale: &stale) else { return nil }
        return url
    }

    return (items: items, properties: properties, existingURLs: existingURLs)
}

func addFavoriteServer(_ paths: String...) throws {
    guard let (oldItems, properties, existingURLs) = try? readFavoriteServers() else { throw error }
    let uniqueURLs = Set(existingURLs)

    print("Existing items: " + existingURLs.description)

    let newItems = NSMutableArray(array: oldItems)

    paths.forEach { path in
        guard let encodedPath = path.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
              let url = URL(string: encodedPath),
              let bookmark = try? url.bookmarkData(options: [], includingResourceValuesForKeys: nil, relativeTo: nil) else { return }

        let entry: [String:Any] = [
            "Name": path,
            "Bookmark": bookmark,
            "uuid": UUID().uuidString,
            "visibility": 0,
            "CustomItemProperties": NSDictionary()
        ]

        if uniqueURLs.contains(url) {
            print("Skip: " + path)
        } else {
            newItems.add(entry)
            print("Add: " + path)
        }
    }

    let newDict: [String:Any] = [
        "items": newItems,
        "properties": properties
    ]

    do {
        try NSKeyedArchiver.archivedData(withRootObject: newDict, requiringSecureCoding: true).write(to: sflURL)
    } catch let e {
        throw e
    }
}

// main routine
do {
    try addFavoriteServer("smb://192.168.100.1","smb://192.168.100.2","smb://192.168.100.3","smb://192.168.100.4")
    let (_, _, existingURLs) = try readFavoriteServers()
    print("New items: " + existingURLs.description)
    print("Restart your Mac for the changes to take effect!")
} catch let e {
    print(e.localizedDescription)
}

このコードでは,最後のメインルーチンのところで

addFavoriteServer("smb://192.168.100.1","smb://192.168.100.2","smb://192.168.100.3","smb://192.168.100.4")

とすることで,サーバのURLを一括追加しています。addFavoriteServer は,引数に与えられたURLたちを,既存のサーバURLと照合して,既存のURLはスキップして,新しいURLのみだけを順に追加していきます。

この変更をFinderのUI上に反映させるためには,macOSの再起動が必要でした。(Finderの再起動だけで済むという話もありましたが,自分の環境ではOS全体を再起動しないと変更が反映されませんでした。)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0