mcpField
H
homekit

homekit

github.com/dpearson2699開発1.2k3.1k 回インストール13 週間前に更新
リポジトリ

homekit について

Appleプラットフォーム開発者向けのHomeKitスキルです。ホーム、部屋、アクセサリの管理や特性値、アクションセット、トリガーを扱い、MatterSupportでMatterデバイスをアプリのエコシステムに追加する方法も説明します。

主な機能

  1. 01ホーム・部屋・アクセサリの管理
  2. 02特性値の読み書きと監視
  3. 03アクションセットの作成と実行
  4. 04タイマー・イベントトリガーの設定
  5. 05MatterSupportによるデバイスのコミッショニング

活用シーン

  1. 01スマートホーム制御アプリの開発
  2. 02アクセサリ状態の確認や変更
  3. 03照明などの自動化の作成
  4. 04Matterデバイスのアプリ連携

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dpearson2699/swift-ios-skills --skill homekit

インストール後、Claude Code で/homekitを入力して読み込まれたか確認します。

同梱ファイルevals/evals.jsonreferences/matter-commissioning.md

詳細

HomeKit

ホームオートメーションアクセサリを制御し、Matter デバイスをコミッショニングします。HomeKit は、ホーム/部屋/アクセサリのモデル、アクションセット、トリガーを管理します。MatterSupport は、デバイスをエコシステムにコミッショニングします。

目次

セットアップ

HomeKit の設定
  1. Xcode(Signing & Capabilities)で HomeKit 機能を有効にします
  2. Info.plist に NSHomeKitUsageDescription を追加します:
<key>NSHomeKitUsageDescription</key>
<string>This app controls your smart home accessories.</string>
MatterSupport の設定

独自のエコシステムに Matter デバイスをコミッショニングする場合:

  1. MatterSupport Extension ターゲットを追加し、プリンシパルクラスを MatterAddDeviceExtensionRequestHandler のサブクラスに設定します
  2. _matter._tcp、_matterc._udp、および _matterd._udp のエントリーを NSBonjourServices に追加します
  3. 呼び出し元が Matter のセットアップペイロードをプログラムから 提供する場合に限り、com.apple.developer.matter.allow-setup-payload を追加します
フレームワークの境界
必要な処理フレームワーク
ホーム、部屋、アクセサリ、特性、アクション、トリガーHomeKit
アプリのエコシステムへの Matter のコミッショニングMatterSupport
近くの Bluetooth または Wi-Fi アクセサリの選択と認証AccessorySetupKit
選択後の Bluetooth GATT データの交換CoreBluetooth
選択後のアクセサリの Wi-Fi ネットワークへの接続または設定NetworkExtension

HomeKit データモデル

HomeKit は、ホームオートメーションを階層構造で整理します:

HMHomeManager
  -> HMHome (one or more)
       -> HMRoom (rooms in the home)
            -> HMAccessory (devices in a room)
                 -> HMService (functions: light, thermostat, etc.)
                      -> HMCharacteristic (readable/writable values)
       -> HMZone (groups of rooms)
       -> HMActionSet (grouped actions)
       -> HMTrigger (time or event-based triggers)
ホームマネージャーの初期化

単一の HMHomeManager を作成し、データの読み込み完了を確認できるように デリゲートを実装します。HomeKit の読み込みは非同期です。デリゲートが呼び出されるまで homes にアクセスしないでください。

import HomeKit

final class HomeStore: NSObject, HMHomeManagerDelegate {
    let homeManager = HMHomeManager()

    override init() {
        super.init()
        homeManager.delegate = self
    }

    func homeManagerDidUpdateHomes(_ manager: HMHomeManager) {
        // Safe to access manager.homes now
        let homes = manager.homes
        let primaryHome = manager.primaryHome
        print("Loaded \(homes.count) homes")
    }

    func homeManager(
        _ manager: HMHomeManager,
        didUpdate status: HMHomeManagerAuthorizationStatus
    ) {
        if status.contains(.authorized) {
            print("HomeKit access granted")
        }
    }
}
部屋へのアクセス
guard let home = homeManager.primaryHome else { return }

let rooms = home.rooms
let kitchen = rooms.first { $0.name == "Kitchen" }

// Room for accessories not assigned to a specific room
let defaultRoom = home.roomForEntireHome()

アクセサリの管理

アクセサリの検出と追加

アクセサリを追加する前に、フレームワークの境界の表を 確認してください。このスキルで扱うのは HomeKit/MatterSupport の処理のみです。

// System UI for accessory discovery
home.addAndSetupAccessories { error in
    if let error {
        print("Setup failed: \(error)")
    }
}
アクセサリとサービスの一覧表示
for accessory in home.accessories {
    print("\(accessory.name) in \(accessory.room?.name ?? "unassigned")")

    for service in accessory.services {
        print("  Service: \(service.serviceType)")

        for characteristic in service.characteristics {
            print("    \(characteristic.characteristicType): \(characteristic.value ?? "nil")")
        }
    }
}
アクセサリを部屋に移動する
guard let accessory = home.accessories.first,
      let bedroom = home.rooms.first(where: { $0.name == "Bedroom" }) else { return }

home.assignAccessory(accessory, to: bedroom) { error in
    if let error {
        print("Failed to move accessory: \(error)")
    }
}

特性の読み取りと書き込み

値の読み取り
let characteristic: HMCharacteristic = // obtained from a service

characteristic.readValue { error in
    guard error == nil else { return }
    if let value = characteristic.value as? Bool {
        print("Power state: \(value)")
    }
}
値の書き込み
// Turn on a light
characteristic.writeValue(true) { error in
    if let error {
        print("Write failed: \(error)")
    }
}
変更の監視

リアルタイム更新を有効にします:

characteristic.enableNotification(true) { error in
    guard error == nil else { return }
}

// In HMAccessoryDelegate:
func accessory(
    _ accessory: HMAccessory,
    service: HMService,
    didUpdateValueFor characteristic: HMCharacteristic
) {
    print("Updated: \(characteristic.value ?? "nil")")
}

アクションセットとトリガー

アクションセットの作成

HMActionSet は、まとめて実行される特性への書き込みをグループ化します:

home.addActionSet(withName: "Good Night") { actionSet, error in
    guard let actionSet, error == nil else { return }

    // Turn off living room light
    let lightChar = livingRoomLight.powerCharacteristic
    let action = HMCharacteristicWriteAction(
        characteristic: lightChar,
        targetValue: false as NSCopying
    )
    actionSet.addAction(action) { error in
        guard error == nil else { return }
        print("Action added to Good Night scene")
    }
}
アクションセットの実行
home.executeActionSet(actionSet) { error in
    if let error {
        print("Execution failed: \(error)")
    }
}
タイマートリガーの作成
var timeOfDay = DateComponents()
timeOfDay.hour = 22
timeOfDay.minute = 30

let firstFireDate = Calendar.current.nextDate(
    after: Date(),
    matching: timeOfDay,
    matchingPolicy: .nextTime
)!

let trigger = HMTimerTrigger(
    name: "Nightly",
    fireDate: firstFireDate,
    recurrence: DateComponents(day: 1)  // Repeat every day after firstFireDate
)

home.addTrigger(trigger) { error in
    guard error == nil else { return }

    // Attach the action set to the trigger
    trigger.addActionSet(goodNightActionSet) { error in
        guard error == nil else { return }

        trigger.enable(true) { error in
            print("Trigger enabled: \(error == nil)")
        }
    }
}
イベントトリガーの作成
let motionDetected = HMCharacteristicEvent(
    characteristic: motionSensorCharacteristic,
    triggerValue: true as NSCopying
)

let eventTrigger = HMEventTrigger(
    name: "Motion Lights",
    events: [motionDetected],
    predicate: nil
)

home.addTrigger(eventTrigger) { error in
    // Add action sets as above
}

Matter のコミッショニング

MatterAddDeviceRequest を使用して、Matter デバイスをエコシステムに コミッショニングします。これは HMHome のホームオートメーションモデルとは別のもので、 Matter のセットアップフローを処理し、MatterSupport エクステンションを呼び出します。

基本的なコミッショニング
import MatterSupport

func addMatterDevice() async throws {
    guard MatterAddDeviceRequest.isSupported else {
        print("Matter not supported on this device")
        return
    }

    let topology = MatterAddDeviceRequest.Topology(
        ecosystemName: "My Smart Home",
        homes: [
            MatterAddDeviceRequest.Home(displayName: "Main House")
        ]
    )

    let request = MatterAddDeviceRequest(
        topology: topology,
        setupPayload: nil,
        showing: .allDevices
    )

    // Presents system UI for device pairing
    try await request.perform()
}

セットアップコードを直接渡す場合は、Matter をインポートし、 MTRSetupPayload を setupPayload として渡します。この場合は セットアップペイロードのエンタイトルメントが必要です。

デバイスのフィルタリング
// Only show devices from a specific vendor
let criteria = MatterAddDeviceRequest.DeviceCriteria.vendorID(0x1234)

let request = MatterAddDeviceRequest(
    topology: topology,
    setupPayload: nil,
    showing: criteria
)

条件を .all([.vendorID(...), .not(.productID(...))]) で組み合わせるか、 いずれか1つの条件で十分な場合は .any(...) を使用します。

MatterAddDeviceExtensionRequestHandler

エコシステムを完全にサポートするには、MatterSupport Extension を作成します。 このエクステンションはコミッショニングのコールバックを処理します。必要なメソッドを オーバーライドしますが、オーバーライド内から super を呼び出さないでください。 認証情報の検証、部屋の選択、設定、コミッショニング、ネットワーク関連付けの オーバーライドについては、Matter Extension Handler の詳細 を参照してください。

よくある間違い

間違い修正方法
デリゲートの更新前にホームを読み取るマネージャーを1つ作成してデリゲートを設定し、homeManagerDidUpdateHomesを待ちます。
MatterエコシステムのコミッショニングにHomeKitの設定を使用するMatterAddDeviceRequestと、設定済みのMatterSupport拡張機能を使用します。
Matterの設定が不完全であるプリンシパルハンドラー、Bonjourサービス、セットアップペイロードのエンタイトルメントを、該当する場合にのみ確認します。
複数のHMHomeManagerインスタンスがデータベースを読み込む保持するマネージャー/ストアを1つ共有します。
特性の書き込み時にメタデータを無視する書き込む前に、権限、フォーマット、最小値/最大値/ステップ、許可される値を確認します。

レビューチェックリスト

  • XcodeでHomeKit機能が有効になっている
  • Info.plistにNSHomeKitUsageDescriptionがある
  • アプリ全体で単一のHMHomeManagerインスタンスを共有している
  • HMHomeManagerDelegateを実装している。homeManagerDidUpdateHomesより前にホームへアクセスしていない
  • アクセサリと部屋の変更を受け取るため、ホームにHMHomeDelegateを設定している
  • 特性の更新を受け取るため、アクセサリにHMAccessoryDelegateを設定している
  • 値を書き込む前に特性のメタデータを確認している
  • すべての完了ハンドラーでエラーを処理している
  • MatterSupport拡張機能のターゲットとプリンシパルハンドラーを設定している
  • Matterの検出に必要なNSBonjourServicesエントリーを追加している
  • セットアップコードを提供する場合にのみcom.apple.developer.matter.allow-setup-payloadを使用している
  • リクエストを実行する前にMatterAddDeviceRequest.isSupportedを確認している
  • Matter拡張機能のハンドラーにcommissionDevice(in:onboardingPayload:commissioningID:)を実装している
  • リリース前にHomeKit Accessory Simulatorでアクションセットをテストしている
  • 作成後にトリガーを有効にしている(trigger.enable(true))

参考資料

コメント