【Swift】SecItemCopyMatchingで複数件を処理

公開日: : 最終更新日:2014/11/04 Blog ,

SecItemCopyMatchingを使ってKeyChainからデータを取得する時に
全件取得したかったのだが、取得したデータをどう加工すれば良いかわからなかった。

.NET Frameworkの感覚で、
Objective-cとSwiftを理解せず進めたのがまずいなと感じはじめた。
言語がなんだろうと問題ないべと思っていたのは慢心であった。

    class func GetAllKey() -> [SaveRecord]?
    {
        var query = NSMutableDictionary(
            objects: [
                kSecClassGenericPassword,
                kCFBooleanTrue,
                kCFBooleanTrue,
                kSecMatchLimitAll
            ], forKeys: [
                kSecClass,
                kSecReturnAttributes,
                kSecReturnData,
                kSecMatchLimit
            ])
        var result: Unmanaged<AnyObject>?
        let status: OSStatus = SecItemCopyMatching(query, &result)
        if status == errSecItemNotFound
        {
            return nil
        }
        let retrievedData: NSArray = result!.takeRetainedValue() as NSArray
        var returnList: [SaveRecord] = []
        for current in retrievedData {
            var currentDic: NSDictionary = current as NSDictionary
            //キーの取得
            var key: String = currentDic.objectForKey(kSecAttrAccount) as String
            //値の取得(ここではNSData)
            var value: NSData = currentDic.objectForKey(kSecValueData) as NSData
            var ro: RecordObject =  NSKeyedUnarchiver.unarchiveObjectWithData(value) as RecordObject
            var sr: SaveRecord = SaveRecord(asKey: key, aoData: ro)
            returnList.append(sr)
        }
        return returnList
    }

手探りで実装したので不要な変数など冗長な部分が多いが
ここでは無視。

処理の前後関係をメモしておくと、
SaveRecordはRecordObjectを保持する
RecordObjectはNSData型との変換を行ってキーチェーンに保存したいので
NSCodingインタフェース(プロトコル?)を実装している。

public class RecordObject: NSObject, NSCoding{
    var psTitle: String
    var psId: String
    var psPassword: String
    init (asTitle: String, asId: String, asPassword: String)
    {
        psTitle = asTitle
        psId = asId
        psPassword = asPassword
    }
    public required init(coder aDecoder: NSCoder) {
        self.psTitle = aDecoder.decodeObjectForKey("title") as String
        self.psId = aDecoder.decodeObjectForKey("id") as String
        self.psPassword = aDecoder.decodeObjectForKey("pass") as String
    }
    public func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(self.psTitle, forKey: "title")
        aCoder.encodeObject(self.psId, forKey: "id")
        aCoder.encodeObject(self.psPassword, forKey: "pass")
    }
}

SecItemCopyMatchingの第二引数はUnmanaged
queryのkSecMatchLimitがLimitOneの時はNSDictionary
LimitAllの時はNSDictionaryなNSArrayが取得される

3件キーチェーンに登録されていればNSArrayのCountは3
1件づつ独自データオブジェクトクラスに変換し可変DictionaryにAppendして返却させた

関連記事

Docker for Windows で ドライブ共有が出来ない

Shared Drives タブで Cドライブにチェックをして Apply を押す。 認証ダイ

記事を読む

no image

【Xcode】Capabilities全項目【v6.1時点】

Capabilitiesの各項目が何を示しているのか よくわからなかった、かつ日本語のサイトが少な

記事を読む

Xamarin.Androidで起動時にアプリケーションを起動

RECEIVE_BOOT_COMPLETEDの権限必要 ActionBootCompleted を

記事を読む

no image

【Cocos2d-x】Cocos2d-xセットアップ

メモ。Xcodeはインストール済、OSはMac10.9.5 必要なものをダウンロード&解凍

記事を読む

NetworkOperatorTetheringManager を使って、モバイルホットスポットをアプリケーションから構成する

UWPアプリケーションからテザリングアクセスポイントの構成を行ったメモ テザリングの Networ

記事を読む

Visual Studio Team Services で 新規プロジェクトを作成するときの自分用初期設定メモ

新規プロジェクト作成 Version control -> Git Work item proc

記事を読む

VisualStudio2015でiOSアプリケーション開発

こんにちは。 Windows10にアップグレードしました。 VisualStudioも201

記事を読む

no image

UWP+IoT Coreのシリアル通信メモ

Windows10 IoT + Raspberry Pi を始めようとしているのだが、どうもセンサー

記事を読む

no image

Raspberry Pi 3 Model B 各OS、動画プレイヤーでの再生比較

ベンチマークではなく、ただ感想をメモしただけ。 Windows 10 IoT Core C#

記事を読む

no image

YomiganaWPFTextBox

こんにちは。 WPFでテキストボックスに入力した内容をカナ変換する方法について今日は掲載します

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

PAGE TOP ↑