【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

Xamarin.Android フルスクリーン

自分用メモです。

記事を読む

no image

Xamarin.UITest, Xamarin Test Cloud にて iPhone 6 Plus, 6S Plus, 7 Plus などで app.Tap が効かない

動作しないというか、app.Tapがどうしても反応しない。 app.ScreenShotなどは動作す

記事を読む

no image

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

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

記事を読む

no image

【iPhoneアプリ】背景画像を設定する

ImageResourceにBg.pngという背景画像を登録しておく 背景を設定するタイミング

記事を読む

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

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

記事を読む

no image

Windows8.1 64bitにVB6.0開発環境を構築メモ

MSDNフォーラムの、この投稿はとても素晴らしいです。 windows 8 64bit

記事を読む

【VisualStudio2015】UWPアプリケーションのXAMLデザイナにて「パッケージを登録できませんでした。」

VisualStudio2015 / UWPアプリケーション / XAMLデザイナ / エラー のメ

記事を読む

【iPhoneアプリ】リリース手順〜審査申し込み〜

初めてiPhoneアプリを作成したがリリース手順が 手元の参考書と全然違って困ったのでメモ。

記事を読む

PHP executable not found. Install PHP 7 and add it to your PATH or set the php.executablePath setting

Visual Studio Code へ PHP IntelliSense 拡張をインストールし

記事を読む

Visual Studio から Android SDK Managerが起動できない

Android SDKやエミュレーターイメージのアップデートを行いたい場合にAndroid SDK

記事を読む

Message

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

PAGE TOP ↑