Chapter 03

iOS 11でのアップデートまとめ

tokorom
tokorom
2020.10.12に更新

新しいイベントの追加

iOS 11ではイベントトリガ(HMEventTrigger)に設定可能なイベント(HMEvent)がいくつか追加されました。

HMCalendarEvent

HMCalendarEventの追加により日時指定での繰り返しのオートメーションが簡単に実現できるようになります[1]
たとえば、午前8:30に発火するイベントトリガを作成するには、ソースコード. HMCalendarEventの利用のようにします。

HMCalendarEventの利用
let comp = DateComponents(hour: 8, minute: 30)
let event = HMCalendarEvent(fire: comp)
let trigger = HMEventTrigger(name: "午前8:30", events: [event], predicate: nil)

HMSignificantTimeEvent

日の出、日の入りを発火条件とするためのHMSignificantTimeEventも加わりました。
たとえば、日の入り30分前に発火するイベントトリガを作成するには、ソースコード. HMSignificantTimeEventの利用のようにします。

HMSignificantTimeEventの利用
let offset = DateComponents(minute: -30)
let event = HMSignificantTimeEvent(significantEvent: .sunset, offset: offset)
let trigger = HMEventTrigger(
    name: "日の入り30分前",
    events: [event],
    predicate: nil
)

HMSignificantTimeEventのイニシャライザのsignificantEventに指定するHMSignificantEventには、表. HMSignificantEventの2種があります。

表. HMSignificantEvent

HMSignificantEvent 説明
sunrise 日の出
sunset 日の入り

HMCharacteristicThresholdRangeEvent

特定キャラクタ(HMCharacteristic)のvalueプロパティの数値の範囲を発火条件とするHMCharacteristicThresholdRangeEventも加わりました。
たとえば、リビングの現在の温度が29度以上になった時に発火するイベントトリガを作成するには、ソースコード. HMCharacteristicThresholdRangeEventの利用のようにします。

HMCharacteristicThresholdRangeEventの利用
let temperature = //< 現在の温度のcharacteristic

let range = HMNumberRange(minValue: 29.0)
let event = HMCharacteristicThresholdRangeEvent(
    characteristic: temperature,
    thresholdRange: range
)
let trigger = HMEventTrigger(
    name: "気温29度以上",
    events: [event],
    predicate: nil
)

数値の範囲を指定するHMNumberRangeには、表. HMNumberRangeの例に示す3種の使いかたがあります。

表. HMNumberRangeの例

説明
HMNumberRange(minValue: 29) 29以上
HMNumberRange(maxValue: 19) 19以下
HMNumberRange(minValue: 20, maxValue: 28) 20以上28以下

HMPresenceEvent

HMPresenceEventが追加され、ホームに誰もいなくなった時や、誰か一人が帰ってきた時など、ユーザの存在状態を発火条件とすることもできるようになりました。
たとえば、ホームに誰もいなくなった時に発火するイベントトリガを作成するには、ソースコード. HMPresenceEventの利用のようにします。

HMPresenceEventの利用
let event = HMPresenceEvent(
    presenceEventType: .lastExit,
    presenceUserType: .homeUsers
)
let trigger = HMEventTrigger(
    name: "全員が出発",
    events: [event],
    predicate: nil
)

HMPresenceEventのイニシャライザのpresenceEventTypeに指定できる値には、表. HMPresenceEventType一覧の6種があります。

表. HMPresenceEventType一覧

HMPresenceEventType 説明
everyEntry 対象のユーザいずれかが到着
everyExit 対象のユーザいずれかが出発
firstEntry 最初のユーザが到着
lastExit 最後のユーザが出発(全員が出発)
atHome firstEntryと同じ
notAtHome lastExitと同じ

firstEntryatHomelastExitnotAtHomeは、それぞれどちらを指定しても全く同じ挙動になりますが、文脈によって使い分けるのが良さそうです。たとえば「家に誰もいない時」という文脈ならnotAtHomeを利用するのが直感的でしょう。

また、presenceUserTypeに指定できる値には、表. HMPresenceEventUserType一覧の3種があります。

表. HMPresenceEventUserType一覧

HMPresenceEventUserType 説明
currentUser 自分
homeUsers ホームを利用するユーザ全員
customUsers 指定したユーザ

(customUsersについてですが、iOS 11ではプログラムからこのユーザを指定する方法はありません)

HMDurationEvent

HMDurationEventはイベントトリガに直接設定できない特殊なイベントです。
HMDurationEventについてはendEventsプロパティで紹介します。

HMEventTriggerのアップデート

HMEventTrigger自体にも、多くの機能追加と変更があります。

recurrencesプロパティ

HMEventTriggerrecurrencesプロパティを利用することで、イベントトリガを特定の曜日にだけ発火させることが簡単になりました。
たとえば、平日(月曜〜金曜)の日の出に発火するイベントトリガを作成するには、ソースコード. recurrencesの利用のようにします。

recurrencesの利用
let event = HMSignificantTimeEvent(significantEvent: .sunrise, offset: nil)

// 月曜日から金曜日までを示す5つのDateComponentsを作成
let weekday = Array(2...6).map { DateComponents(weekday: $0) }

// recurrencesを指定してHMEventTriggerを作成
let trigger = HMEventTrigger(
    name: "Weekday",
    events: [event],
    end: nil,
    recurrences: weekday,
    predicate: nil
)

recurrencesプロパティにはDateComponentsの配列を指定しますが、iOS 11時点で対応しているDateComponentsのプロパティは曜日(weekday)のみです。

executeOnceプロパティ

HMEventTriggerに追加されたexecuteOnceプロパティにより、そのイベントトリガが一度のみ発火されるものなのか繰り返し発火されるものなのかを、明示できるようになりました。
具体的にはexecuteOnceプロパティがtrueの場合、そのイベントトリガが発火した際、isEnabledプロパティが自動的にfalseに変更されます。
executeOnceを更新するコードをソースコード. executeOnceを更新に示します。

executeOnceを更新
trigger.updateExecuteOnce(true) { error in
}

endEventsプロパティ

HMEventTriggerが発火してシーンが実行された後に、特定の条件によって発火前の状態に戻すためのendEventsプロパティも追加されました。
具体的には、HMEventTriggerの発火により電球を点灯させた5分後に、自動的に電球の状態を元に戻す(つまり消灯する)といったことができます(ソースコード. endEventsを設定)。

endEventsを設定
let trigger = //< 電球を点灯させるHMEventTrigger

// 5分後
let endEvent = HMDurationEvent(duration: 300)

// endEventsを設定
trigger.updateEndEvents([endEvent]) { error in
}

HMDurationEventは、iOS 11で追加されたendEventsプロパティ専用のイベントです。
endEventsプロパティには、HMDurationEventの他、HMCharacteristicEventHMCharacteristicThresholdRangeEventsを設定できます。

predicate用メソッドのアップデート

predicateプロパティに指定するNSPredicateを作るためのメソッドもいくつか追加されました。

これまであったString指定で日の出・日の入りを条件として指定するメソッドがDeprecated(非推奨)となり、代わりにHMSignificantTimeEventで指定できるメソッドが追加されました。

class func predicateForEvaluatingTriggerOccurring(
                              afterSignificantEvent: HMSignificantTimeEvent)

class func predicateForEvaluatingTriggerOccurring(
                                beforeSignificantEvent: HMSignificantTimeEvent)

class func predicate(
  forEvaluatingTriggerOccurringBetweenSignificantEvent: HMSignificantTimeEvent,
                                secondSignificantEvent: HMSignificantTimeEvent)

たとえば、日中のみ(日の出から日の入りまで)という条件でpredicateプロパティを指定するには、ソースコード. HMSignificantTimeEvent指定でpredicate指定のようにします。

HMSignificantTimeEvent指定でpredicate指定
let sunrise = HMSignificantTimeEvent(significantEvent: .sunrise, offset: nil)
let sunset = HMSignificantTimeEvent(significantEvent: .sunset, offset: nil)

// 日の出から日の入りまでという条件
let predicate = HMEventTrigger.predicate(
    forEvaluatingTriggerOccurringBetweenSignificantEvent: sunrise,
    secondSignificantEvent: sunset
)

// 作成したpredicateを指定してトリガ作成
let trigger = HMEventTrigger(
    name: "日の出から日の入り",
    events: [event],
    predicate: predicate
)

HMPresenceEventを指定するメソッドも追加されました。

class func predicateForEvaluatingTrigger(withPresence: HMPresenceEvent)

これにより、たとえば、防犯のために誰も家にいないときだけ日の入りとともに自動でライトを点ける、といった条件指定ができます(ソースコード. HMPresenceEvent指定でpredicate指定)。

HMPresenceEvent指定でpredicate指定
// 誰も家にいないときだけという条件
let presence = HMPresenceEvent(
    presenceEventType: .notAtHome,
    presenceUserType: .homeUsers
)
let predicate = HMEventTrigger.predicateForEvaluatingTrigger(
    withPresence: presence
)

// 作成したpredicateを指定してトリガ作成
let trigger = HMEventTrigger(
    name: "誰も家にいない",
    events: [event],
    predicate: predicate
)

最後にもう1つ、時刻を条件として指定するメソッドに、時刻の範囲を一度に指定できるものが追加されました。

class func predicateForEvaluatingTriggerOccurringBetweenDate(with: DateComponents,
                                                   secondDateWith: DateComponents)

たとえば、10:00から18:30という条件でpredicateプロパティを指定するには、ソースコード. 開始時刻と終了時刻指定でpredicate指定のようにします。

開始時刻と終了時刻指定でpredicate指定
// 10:00から18:30という条件
let start = DateComponents(hour: 10, minute: 0)
let end = DateComponents(hour: 18, minute: 30)
let predicate = HMEventTrigger.predicateForEvaluatingTriggerOccurringBetweenDate(
    with: start,
    secondDateWith: end
)

// 作成したpredicateを指定してトリガ作成
let trigger = HMEventTrigger(
    name: "日中",
    events: [event],
    predicate: predicate
)

triggerActivationStateプロパティ

HMEventTriggerに新しく追加されたtriggerActivationStateプロパティにより、HMEventTriggerの利用可否状態を参照できるようになりました。
iOS 10まではisEnabledプロパティを参照し、単純にトリガ自体が有効か無効かを知ることしかできませんでした。しかしtriggerActivationStateプロパティでは表. HMEventTriggerActivationState一覧のように、利用できない理由を含め知ることができます。

表. HMEventTriggerActivationState一覧

説明
disabled トリガ自体が無効になっている
disabledNoHomeHub ホームハブがないため利用不可
disabledNoCompatibleHomeHub 互換性のあるホームハブがないため利用不可
disabledNoLocationServicesAuthorization 位置情報の利用が許可されていないため利用不可
enabled 利用可能

HMHomeのアップデート

HMHomeにはhomeHubStateプロパティが追加されました。
これによりホームハブの状態を参照できるようになりました。homeHubStateプロパティに入るHMHomeHubStateの値の一覧を表. HMHomeHubStateにまとめます。

表. HMHomeHubState

説明
notAvailable ホームハブが設定されていない
connected ホームハブに接続されている
disconnected ホームハブに接続されていない

HMAccessoryとHMCharacteristicのアップデート

characteristicTypeHMCharacteristicTypeColorTemperatureが追加されました(表. HMCharacteristicTypeColorTemperature)。

表. HMCharacteristicTypeColorTemperature

HMCharacteristicType 説明 フォーマット
ColorTemperature 色温度 int

一方で表. DeprecatedになったcharacteristicType一覧の4つがDeprecatedになっています。

表. DeprecatedになったcharacteristicType一覧

HMCharacteristicType 説明 フォーマット
Manufacturer 製造元 string
Model モデル string
SerialNumber シリアル番号 string
FirmwareVersion ファームウェアのバージョン string

これらのcharacteristicTypeがDeprecatedになったのはHMAccessory

  • manufacturerプロパティ
  • modelプロパティ
  • profilesプロパティ
  • firmwareVersionプロパティ

が追加されたためです。
iOS 11以降はアクセサリ > サービス > キャラクタと辿らなくともHMAccessoryのインスタンスから直接これらの情報を参照できるようになりました。

HMHomeDelegateのアップデート

HMHomeDelegateには以下2つのメソッドが追加されました。

// homeHubStateの更新を監視
optional func home(_ home: HMHome, didUpdate homeHubState: HMHomeHubState)

// currentUserの権限の更新を監視
optional func homeDidUpdateAccessControl(forCurrentUser home: HMHome)

HMAccessoryDelegateのアップデート

HMAccessoryDelegateには以下3つのメソッドが追加されました。

// アクセサリにprofileが追加されたことを検知
optional func accessory(_ accessory: HMAccessory, didAdd profile: HMAccessoryProfile)

// アクセサリからprofileが削除されたことを検知
optional func accessory(_ accessory: HMAccessory, didRemove profile: HMAccessoryProfile)

// アクセサリのファームウェアバージョンが更新されたことを検知
optional func accessory(_ accessory: HMAccessory,
            didUpdateFirmwareVersion firmwareVersion: String)
脚注
  1. これまでもHMTimerTriggerを利用することで可能でしたがHMCalendarEventにはHMTimerTriggerにない付加機能がいくつかあります ↩︎