NSUserDefaults と NSKeyedArchiver と KeyChain の速度比較

ちょっと気になったので調べてみた。

使ったのはこんなデータ

NSDictionary *data = @{
    @"spam": @"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    @"egg" : @123456,
    @"ham" : [NSDate date],
};

このデータを実機(iPhone5)で1,000回読み書きした時の時間をそれぞれ計測した結果がこれ。まあ予想通りというか KeyChain が一番遅い。

KeyChain はセキュアなデータを保存するためのもので、永続化のためにカジュアルに利用するべきではない。NSUserDefaults の read が速いのは繰り返し読む場合にメモリに載ってるからかな。普通は繰り返し読み込むデータは何度もファイルから読み出したりはしないので、ArchiveToFileにキャッシュする機能を付ければその差は無視できそう。

読み書きする部分のコードはこちら。KeyChain に関しては、LUKeychainAccessというライブラリを利用した。NSUserDefaults のように簡単に使えてセキュアに保存できるのでとても便利。自分はこれを API Token の保存に利用している。

- (void)writeUserDefaults
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:self.data forKey:@"data"];
    [userDefaults synchronize];
}

- (void)readUserDefaults
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    self.data = [userDefaults objectForKey:@"data"];
}

- (void)writeArchiveToFile
{
    [NSKeyedArchiver archiveRootObject:self.data toFile:pathToArchive];
}

- (void)readArchiveToFile
{
    self.data = [NSKeyedUnarchiver unarchiveObjectWithFile:pathToArchive];
}

- (void)writeKeyChain
{
    [[LUKeychainAccess standardKeychainAccess] setObject:self.data forKey:@"data"];
}

- (void)readKeyChain
{
    self.data = [[LUKeychainAccess standardKeychainAccess] objectForKey:@"data"];
}

Xcode で Debug の時以外に自動で buildNumber をインクリメントする

以下を Build Phases の Run Script に書いてあげればOK

#!/bin/bash
if [ "$CONFIGURATION" == "Debug" ]; then
  exit
fi

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"