【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して返却させた

関連記事

no image

BOT向け自然言語処理サービスまとめ

自然言語処理 自然言語処理(しぜんげんごしょり、英語: natural language p

記事を読む

Visual Studio 2015 Express の Language Pack

探してみたけど見当たらなかったのでメモ残し。 Visual Studio 2015 には言語パック

記事を読む

no image

Developers Festa Sapporo 2016 メモ

ブログ書くまでが、Developers Festa Sapporo 2016 社内とかに展開するよ

記事を読む

シマンテックインストール時に「指定されたパスが空です。」

Windows10 64bit, Symantec Endpoint Protection はおそら

記事を読む

no image

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

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

記事を読む

【.NET Framework 4.6.1】MultiLineなTextBoxでCtrl+Aが使えない問題が解決(今更)

WinForms.NETなアプリケーションの標準TextBoxで、Multiline=Trueに設定

記事を読む

Flowで毎月の定期タスク設定

Flow を使い始めてみた。 Requrrenceで時間をトリガーにすることが出来るがSecond

記事を読む

【Cocos2d-x】iPhone実機でプロジェクトを動かすまで

Macを購入してCocos2d-xデビューしたが、 iPhone実機で動かすまでをメモ

記事を読む

no image

【.NET】イベントのサブスクライブとサブスクライブ解除

.NETでイベントをハンドルする方法 サブスクライブ void CustomEven

記事を読む

no image

SmallBasicで拡張ライブラリを使用する

こんにちは。 teratailにて以下の質問に遭遇しまして。 small basic の 拡

記事を読む

Message

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

PAGE TOP ↑