ObjecTips

Swift & Objective-C で iOS とか macOS とか

NSUserDefaults に時・分のみ記録する(日付は不要なケース)

日付は不要で時・分のみを NSUserDefaults に保存したい場合、パッと以下の様な方法が思い付く

  • 時・分を2つに分けて2つの NSNumber で保存する
  • 時・分を分換算して1つの NSNumber で保存する
  • NSDate で保存して時・分のみを利用する

他には以下も考えられる

  • 時・分を設定した NSDateComponents を Archive して NSData にして保存する

Apple はどう実装しているのか実例を探してみる。


「システム環境設定>省エネルギー>ディスプレイをオフにするまで」の時間を1時間5分に設定
System Preferences>Energy Saver>Turn display off after

f:id:Koze:20180706001624p:plain

defaults read /Library/Preferences/com.apple.PowerManagement.plist
{
    "AC Power" =     {
        "Automatic Restart On Power Loss" = 0;
        DarkWakeBackgroundTasks = 1;
        "Disk Sleep Timer" = 10;
        "Display Sleep Timer" = 65;
        "Display Sleep Uses Dim" = 1;
        GPUSwitch = 2;
        "System Sleep Timer" = 65;
        "Wake On LAN" = 1;
    };
    SystemPowerSettings =     {
        "Update DarkWakeBG Setting" = 1;
    };
}

分に換算


「システム環境設定>省エネルギー>スケジュール...」で「起動またはスリープ解除」を毎日1:23「スリープ」を毎日4:56に設定
System Preferences>Energy Saver>Schedule...>Start up or wake, sleep

f:id:Koze:20180706001629p:plain

defaults read /Library/Preferences/SystemConfiguration/com.apple.AutoWake.plist
{
    RepeatingPowerOff =     {
        eventtype = sleep;
        time = 296;
        weekdays = 127;
    };
    RepeatingPowerOn =     {
        eventtype = wakepoweron;
        time = 83;
        weekdays = 127;
    };
}

分に換算


「システム環境設定>通知>おやすみモード>おやすみモードをオンにする設定」で開始を23:45、終了を1:23に設定
System Preferences>Notifications>Do Not Disturb>Turn on Do Not Disturb

f:id:Koze:20180706002503p:plain

sudo defaults read ~/Library/Preferences/ByHost/com.apple.notificationcenterui.*

(なぜか sudo しないと読めない、且つ設定変更直後3秒間ぐらいも読めない)

{
    dndEnd = 83;
    dndMirroring = 0;
    dndStart = 1425;
    doNotDisturb = 0;
}

分に換算


「システム環境設定>ディスプレイ>Night Shift>スケジュール」をカスタムにして開始を23:45、終了を1:23に設定
System Preferences>Displays>Night Shift>Schedule

f:id:Koze:20180706013113p:plain

sudo defaults read /private/var/root/Library/Preferences/com.apple.CoreBrightness.plist

又は

sudo defaults read com.apple.CoreBrightness.plist

抜粋

        CBBlueReductionStatus =         {
            AutoBlueReductionEnabled = 1;
            BlueLightReductionAlgoOverride = 4;
            BlueLightReductionAlgoOverrideTimestamp = "2018-07-05 16:51:14 +0000";
            BlueLightReductionDisableScheduleAlertCounter = 3;
            BlueLightReductionSchedule =             {
                DayStartHour = 1;
                DayStartMinute = 23;
                NightStartHour = 23;
                NightStartMinute = 45;
            };
            BlueReductionEnabled = 1;
            BlueReductionMode = 2;
            BlueReductionSunScheduleAllowed = 1;
            Version = 1;
        };

時・分を分ける

まとめ

NSUserDefaultssetObject:forKey: をすると plist のルートに値が保存されるけど、Apple の実装としては(全体的に保存される設定が複雑な事もあってか、保存パラメータから簡潔にモデルのインスタンスを作るためか)ルートには値を保存せずに辞書でラップして分換算で時・分を保存するのがメジャーなのかなという感じ。
分換算するか時・分を分けて保存するかはどちらでも良い様な気がするけど、とりあえず NSDateNSDateComponents で時・分のみを管理するなんてのは冗長で、管理の面からも human-readble で分かりやすい形で保存するのがベターだと思った。

メモ

plist の内容表示は以下

defaults read foo.plist
plutil -p foo.plist
/usr/libexec/PlistBuddy -c print foo.plist

設定ファイルの捜索場所は以下のあたり
対象の plist ファイルが色々なところに散らばっていて探すのは結構大変だった、、

~/Library/Preferences/
~/Library/Preferences/ByHost/
/Library/Preferences/
/private/var/root/Library/Preferences/