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

関連記事

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

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

記事を読む

Xamarin.Forms出力バイナリのメモ

iOS -> .ipa, Android -> .apk ipaファイル作成方法 ソリュー

記事を読む

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

RECEIVE_BOOT_COMPLETEDの権限必要 ActionBootCompleted を

記事を読む

Xcode標準テンプレート

Xcodeで新規Projectを作成した時にテンプレートを選ぶことが出来る。 「Choose a

記事を読む

Minnow Board Turbot + Windows 10 IoT Core をSSD上で動作させる

MinnowBoard は SATAが搭載されているので、SSDなどが利用できる。 通常はSDカード

記事を読む

【iPhoneアプリ】リリース手順〜審査完了後〜

前回からの続き。 中身が無いアプリだったのでリジェクトされると思いきや 審査に通ってしま

記事を読む

Visual Studio 2015 Express の Language Pack

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

記事を読む

no image

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

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

記事を読む

拡張温度に対応した Windows 10 IoT Core ボード

Windows 10 IoT Core 対応ボード その2 こっちは拡張温度対応している。 Ban

記事を読む

Visual Studio Team Services ダッシュボードを自動更新する

Visual Studio Team Services のダッシュボードでプロジェクトや運用状況のサ

記事を読む

Message

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

PAGE TOP ↑