【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

【UWP】CS1061 : ‘XXX’に’InitializeComponent’の定義が含まれておらず

いろいろなことに起因しており、引き起こされた問題であって、 根本的な原因ではない可能性はあるが、凡ミ

記事を読む

【iPhoneアプリ】リリース手順〜プロビジョニングプロファイルを作成する〜

リリース前にDistribution Provisioning Profileを作成する 手順

記事を読む

no image

Xamarin.FormsのAndroidでスプラッシュ画面

Xamarin.Formsでアプリを作成した時、iOSは起動時にLauncher.storyboar

記事を読む

SIPSorceryにて、「型 ‘log4net.ILog’ が参照されていないアセンブリで定義されています。」

ある時、SIPクライアントの開発を行っていた。 SIPクライアントライブラリの選定にあたって S

記事を読む

Xamarin Studio から Visual Studio for Mac へ変更してから、”The “XamlCTask” task failed unexpectedly.” が発生。

Visual Studio for Mac がGAしたので、インストールしてみた。 それまで開発して

記事を読む

no image

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

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

記事を読む

no image

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

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

記事を読む

no image

【ストアアプリ】基本的な印刷手順

Windowsストアアプリにて印刷を行う方法を紹介します。 印刷を行うには印刷コントラ

記事を読む

【ストアアプリ】画面遷移の基本①

こんにちは。 Windowsストアアプリをぼちぼち触り始めています。 WindowsRuntim

記事を読む

初心者でも手順どおりに従うだけでロゴ画像が作れる

Webサイトを作ったので、ここを参考に ロゴ制作の練習をしました。  

記事を読む

Message

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

PAGE TOP ↑