Structure API には、iOS 向け Home API を介してアクセスできます。
Structure API を使用するには、まず GoogleHomeSDK
パッケージをアプリにインポートします。
import GoogleHomeSDK
エラー処理
Home API の一部のメソッドは HomeError
をスローするため、do-catch
ブロックを使用してこれらの呼び出しで HomeError
をキャッチすることをおすすめします。
HomeError
を処理するときは、code
フィールドと message
フィールドを確認して、何が問題だったかを把握します。
処理されていないエラーがあると、アプリがクラッシュします。
詳細については、エラー処理をご覧ください。
Structure API
Home
は Home Graph を表し、Structure API のエントリ ポイントです。ストラクチャ、部屋、デバイスへの参照を提供します。
Structure
は、ホームグラフ内の構造を表します。id
や name
などの構造メタデータへのアクセスを提供します。
structures()
を使用して、アカウント内のすべての構造を取得します。構造は Query
の形式で返されます。これにより、データの使用方法を選択できます。
API | 説明 |
---|---|
stream() |
変更が発生するたびに各オブジェクトを個別に発行する Publisher を返します。 |
batched() |
現在の結果をオブジェクトの Set として出力する Publisher を返します。出力された各 Set は、オブジェクト グラフの現在の状態を表します。 |
list() |
現在の結果をオブジェクトの Set として返します。 |
structures().list()
呼び出しでは、有効な構造体のセットがすぐに返されないことがあります。アプリがリアクティブで、stream()
を呼び出してすべての構造変更をサブスクライブし、UI を駆動する場合、最終的に有効な構造のリストが返されます。空の構造リストが返される可能性のある状況は他にもあります。たとえば、ユーザーのスマートフォンの接続が切れた場合や、ユーザーがアプリの権限を取り消した場合などです。アプリでこれらのケースを処理するようにしてください。
@Published public private(set) var structures: [Structure] = []
private var structuresCancellable: AnyCancellable?
self.structuresCancellable = home
.structures()
.batched()
.receive(on: DispatchQueue.main)
.map { Array($0) }
.catch {
Logger.error("Failed to load structures: \($0)")
return Just([Structure]())
}
.assign(to: \.structures, on: self)
Sample Structure 呼び出し
構造体のセットを取得する
Query<Structure>
で list()
を呼び出すと、最新の要素のセットが返されます。
// Get a stream of all structures accessible to the user let allStructuresChanges = try await self.home.structures() let allStructures = try? await allStructuresChanges.list()
リアクティブ アプリを設計する場合は、list()
ではなく batched()
と stream()
の呼び出しを使用します。これらの呼び出しは、ホームグラフが変更されたときにデータを自動的に生成するためです。
構造プロパティを取得する
構造のリストを取得したら、そのプロパティにアクセスできます。
// Get a stream of changes taking place on a structure. let structureChanges = try await home.structures().list().filter { $0.id == structureID } // Get a snapshot of the structure. let structure = try await structureChanges.first! // Get structure properties print("id \(structure.id) ") print("name \(structure.name) ")
名前でストラクチャを検索する
構造体の名前がわかっている場合は、name
プロパティを使用してアクセスすることもできます。
do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let error as HomeError { // Code for handling the exception }
そこから、各構造のプロパティ、部屋、デバイスにアクセスできます。
複数のストラクチャを扱う
複数の構造体を使用するには、各構造体への個別の参照を取得します。
var structure1: Structure! var structure2: Structure! do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let error as HomeError { // Code for handling the exception } do { structure2 = try await home.structures().list().first(where: { $0.name == "Guest Cottage" }) } catch let error as HomeError { // Code for handling the exception }
Rooms
部屋にはデバイスのグループが含まれます。部屋は常にストラクチャの一部であり、ストラクチャには複数の部屋を含めることができます。ストラクチャから部屋を削除しても、その部屋のデバイスはストラクチャから削除されません。ただし、部屋が削除されると、その部屋のデバイスは割り当て解除されます。
Home.rooms()
を使用してアカウント内のすべての部屋を取得し、roomID = device.roomID
を使用して各部屋の対応するデバイスを表示します。
self.home.rooms().batched()
.combineLatest(self.home.devices().batched())
.receive(on: DispatchQueue.main)
.catch { error in
Logger.error("Failed to load rooms and devices: \(error)")
return Just((Set<Room>(), Set<HomeDevice>()))
}
.map { rooms, devices in
var devicesByRoom = [Room: [HomeDevice]]()
for room in rooms where room.structureID == currentStructureID {
devicesByRoom[room] = devices.filter { $0.roomID == room.id }
}
return devicesByRoom
}.assign(to: &self.$devicesByRoom)
Room 呼び出しのサンプル
チャットルームのリストを取得する
Home
クラスを使用すると、会議室のリストを取得して、そのプロパティにアクセスできます。
let allRoomsChanges = self.home.rooms() let allRooms = try await allRoomsChanges.list() let room = allRooms.first! XCTAssertTrue(allRooms.contains(room)) print("id \(room.id) ") print("name \(room.name) ")
チャットルームを作成する
Structure
で新しい部屋を作成するには:
let testName = "Test Room Name" var newRoom: Room! do { newRoom = try await structure.createRoom(name: testName) XCTAssertNotNil(newRoom) } catch let error as HomeError { // Code for handling the exception }
部屋を削除する
または、チャットルームを削除することもできます。
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
ID を使用してルームを削除することもできます。
let roomToDelete = allRooms.first(where: { $0.id == room.id }) if let roomToDelete1 = roomToDelete { do { try await structure.deleteRoom(roomToDelete1) } catch let error as HomeError { // Code for handling the exception } }
デバイスが設置されている部屋を削除すると、デバイスは構造内に残りますが、部屋に割り当てられなくなります。
デバイスを別の部屋に移動する
Structure
では、デバイスを別の部屋に移動することもできます。
do { try await structure.move(device: light, to: room) } catch let error as HomeError { // Code for handling the exception }
部屋の名前を変更する
setName(_:)
メソッドを呼び出して、部屋の名前を変更します。
let updatedRoom = try await theRoom.setName("new room name")
ルームの名前を変更すると、元の Room
構造体はそのまま残り、変更は返される更新された Room
オブジェクトに反映されます。
名前が 60 Unicode コードポイント(文字)の上限を超えている場合、名前は切り捨てられます。エラーは発生しません。長い名前の処理はデベロッパーの責任で行われます。たとえば、名前が切り捨てられることをユーザーに通知するかどうかをデベロッパーが決定できます。
API リスト
Home
のインスタンスが作成されると、次の Structure API にアクセスできるようになります。
API | 説明 |
---|---|
devices() |
このアカウントに表示されるすべてのデバイスを取得します。 |
device(id:) |
指定されたデバイスの Publisher を取得します。これは、現在の状態と、今後の状態更新のたびに状態を出力します。 |
structures() |
Google アカウントのすべての構造を取得します。取得とフィルタリングのオプションを提供する Query<Structure> を返します。 |
structure(id:) |
一致する ID を持つ構造を取得します。 |
rooms() |
Google アカウントのすべてのルームを取得します。取得とフィルタリングのオプションを提供する Query<strRoom> を返します。 |
room(id:) |
指定されたルームの Publisher を取得します。これは、現在の状態を出力し、今後の状態更新でも出力します。 |
Structure
には次の API があります。
API | 説明 |
---|---|
deleteRoom(id:) |
ルーム ID を指定してルームを削除します。 |
id |
構造の一意のシステム ID。 |
move(device:, to:) |
デバイスをストラクチャ内の別の部屋に移動する。 |
move(device:, to:) |
指定された ID のデバイスを指定された ID の部屋に移動します。 |
move(devices:, to:) |
指定されたデバイスを指定された部屋に移動します。 |
move(devices:, to:) |
指定された ID のデバイスを指定された ID の部屋に移動します。 |
name |
ユーザーが指定した構造体の名前。 |
Room
には次の API があります。
API | 説明 |
---|---|
id |
客室の一意のシステム ID。 |
name |
ユーザーが指定したチャットルームの名前。 |
structureID |
客室が属する構造の一意のシステム ID。 |