😺

Swift: 全てのユーザー名を取得する

2021/05/21に公開

はじめに

全てのログインアカウント名を取得する必要が出てきた。
現在ログインしているユーザーアカウント名、フルネームは以下で取得できる。
NSUserName()
NSFullUserName()

つまり、私の推理が正しければNSUserNames()でアカウント名の配列が返却されるでしょう。
しかし、NSUserNames()は存在しないのです。

環境

OS : macOS Catalina(10.15.7)
XCode : 12.4
Swift : 5.3.2

調査結果

なかなか取得方法が見つからなかったが、一件だけ情報が見つかった。
https://stackoverflow.com/questions/3681895/get-all-users-on-os-x/3682039

コード

回答者のコードを丸パクリです(問題があれば記事ごと削除します)。
ただバージョンの問題で上記リンクのコードそのままではコンパイルが通らないため、IDEの警告からFixをポチポチした結果が以下。

注意: iOS関連は触ったことがないためiOS開発時にコードが動くかどうかわからないです(未検証)。

import Collaboration

func getSystemUsers() -> [CBIdentity] {
    // 以下を利用することでActive Directoryのユーザー名も取得できた(接続時)
    // let defaultAuthority = CSGetDefaultIdentityAuthority().takeUnretainedValue()
    let defaultAuthority = CSGetLocalIdentityAuthority().takeUnretainedValue()
    let identityClass = kCSIdentityClassUser
    let query = CSIdentityQueryCreate(nil, identityClass, defaultAuthority).takeRetainedValue()
    var error: Unmanaged<CFError>? = nil
    CSIdentityQueryExecute(query, 0, &error)
    let results = CSIdentityQueryCopyResults(query).takeRetainedValue()
    let resultsCount = CFArrayGetCount(results)
    var allUsersArray = [CBIdentity]()
    
    for idx in 0...resultsCount-1 {
        
        let identity = unsafeBitCast(CFArrayGetValueAtIndex(results,idx),to: CSIdentity.self)
        let uuidString = CFUUIDCreateString(nil, CSIdentityGetUUID(identity).takeUnretainedValue())
        if let uuidNS = NSUUID(uuidString: uuidString! as String),
           let identityObject = CBIdentity(uniqueIdentifier: uuidNS as UUID,
                                           authority: CBIdentityAuthority.default()) {
            allUsersArray.append(identityObject)
        }
    }

    return allUsersArray
}

上記の関数を呼ぶとCBIdentity型の配列が返却され、
アカウント名はposixName, フルネームはfullNameからそれぞれ取得できる。

getSystemUsers().forEach { u in
    // 「アカウント名 フルネーム」が出力される
    print(u.posixName, u.fullName)
}

おわりに

コードの内容はあまり把握していないです。
気力があれば調べる予定です。

Discussion