モバイル端末管理ツールの一種であるMicrosoft Intuneから、iPhoneにアプリ専用の設定値を配信することがありました。備忘録として、Intune側での設定方法とiOSアプリでの読み出し方を記載します。
Intune側設定
アプリ構成ポリシーを追加します。手順の流れは以下の通りです。
- アプリ構成ポリシー: "マネージドデバイスの追加"を選ぶ
- ポリシーの概要を設定する
- iOS端末に書き込む値を設定する
- どのグループに端末を配信するかを設定する
- ポリシーの内容を確認し、OKであれば確定する
- ポリシーが端末に反映されているか確認する
1. アプリ構成ポリシー: "マネージドデバイス"の追加を選ぶ
Microsoft Endpoint Manager admin centerを開き、アプリ > アプリ構成ポリシー > 追加 > マネージドデバイスを選択します。
2. ポリシーの概要を設定する
"基本"にて、以下の項目を入力します。
- ポリシー名*: 必須。配信する設定に応じて命名する
- 説明: 任意。ポリシーの配信目的、概要などを記載する
- プラットフォーム名: "iOS/iPadOS"
- 対象アプリ: Intuneで配信しているiOS/iPadOSアプリのうち、設定を配信したいアプリを選ぶ
3. iOS端末に書き込む値を設定する
本項目はiOSでのMDM管理設定(mcx_preference_settings)に相当します。そのため、アプリからはUserDefaultsを介して取得できます。
構成設定は、XMLデータか構成デザイナーで指定できます。以下は、
- ManagedDevice = true
- ManagedDeviceId = IntuneでのデバイスID
を書き込む例です。
構成デザイナーの場合
構成キー | 値の型 | 構成値 |
---|---|---|
ManagedDevice | ブール値 | true |
ManagedDeviceId | 文字列 | {{deviceid}} |
xmlの場合
<dict>
<key>ManagedDevice</key>
<true/>
<key>ManagedDeviceId</key>
<string>{{deviceid}}</string>
</dict>
値には、Intuneで定義されている変数を指定できます。これらの変数は{{変数名}}
と書くと参照できます。なお、Intune上では変数名について記載ミスがあっても警告やエラーは表示されません(型の不整合については表示されます)。
なお、複数のアプリ構成ポリシー間もしくはコンプライアンスポリシー間で競合値があった場合、どれが反映されるかはランダムになる1のでご注意ください。
4. どのグループに端末を配信するかを設定する
- ポリシーを配信したいグループを"組み込まれたグループ"
- 配信しないグループを"除外されたグループ"
で指定します。
除外は組み込まれたグループよりも優先されるので、除外されたグループに指定されたiOS端末にはポリシーは適用されません。
5. ポリシーの内容を確認し、OKであれば確定する
ポリシーの内容が表示されるので、問題がなければ確定します。
6. ポリシーが端末に反映されているか確認する
作成されたアプリ構成ポリシーにて、"管理しているデバイス"で状態が"成功"であれば設定が反映されています。まだ反映されていない場合は最大で数時間待機するか、または同期を行ってポリシーを反映します。
iOS端末側の実装
以下の2手順でポリシーに設定した値を取得することができます。ポリシーの適用状態によっては設定値を取得できない場合があるので、その場合のデフォルト値を考慮しておく必要があります。
1. ManagedPreferenceを取得する
MDMから配信されたManagedPreferenceは、UserDefaultsから取得できます。ManagedPreferenceは"com.apple.configuration.managed"キー以下に格納されています。なお、以下のケースでは返り値はnilになります。
- MDM管理でない端末で当該アプリを実行している場合
- ポリシーが当該端末に反映されていない場合
func getManagedPreference() -> [String: Any]? {
return UserDefaults.standard.object(forKey: "com.apple.configuration.managed") as? [String: Any]
}
2. ManagedPreferenceから、特定の設定値を読み出す
以下の処理より、ManagedPreference中の設定値を取得できます。値が設定されていない場合にクラッシュすることがないよう、 as? 当該パラメータの型
でキャストした上で値を取得します。
func deviceId() -> String? {
guard let managedProfile = getManagedProfile() else { return nil }
let deviceId = managedProfile["ManagedDeviceId"] as? String
return deviceId
}