Giám sát trạng thái thiết bị trên iOS

Trong Home API cho iOS, bạn có thể theo dõi các thay đổi về trạng thái trong nhà thông qua việc sử dụng khung Combine trong Swift. Bạn có thể theo dõi các thay đổi về cấu trúc, phòng, siêu dữ liệu thiết bị và trạng thái thiết bị trong Home API bằng bất kỳ API nào sử dụng HomeDevice. Việc này được thực hiện bằng cách đăng ký với nhà xuất bản hiển thị các giá trị từ các sự kiện không đồng bộ.

Khi bất kỳ mục nào trong một bộ sưu tập được thêm, xoá hoặc sửa đổi, ảnh chụp nhanh mới nhất của bộ sưu tập sẽ được trả về.

Nhà phát triển có trách nhiệm suy luận các thay đổi cụ thể bằng cách so sánh ảnh chụp nhanh này với một bản sao cũ hơn. Bạn có thể sử dụng trường id được cung cấp cho mỗi loại đối tượng mẹ trong Home API cho mục đích này.

Cách mở gói các đối tượng không bắt buộc

Khi một đối tượng là không bắt buộc, hãy dùng if let hoặc guard để giải gói đối tượng một cách an toàn. Đừng dùng ! vì bạn không bao giờ nên dùng ! trừ phi nhà phát triển chắc chắn rằng đối tượng không thể là nil.

Tham số đầu vào structureID trong ví dụ được xác định là String?, tức là một chuỗi không bắt buộc và có thể có giá trị rỗng. Hàm này tìm thấy đối tượng Structure dựa trên dữ liệu đầu vào trong structureID.

Sau đây là cách bạn nên xử lý các đối tượng không bắt buộc:

func structure(structureID: String?) -> Structure? {
    guard let structureID else { return nil }
    return structures.first { $0.id == structureID }
  }

Cách sử dụng nhà xuất bản

Sau đây là một số ví dụ cơ bản về cách làm việc với các nhà xuất bản trong Home API. Đối với các ví dụ sau, bạn phải tạo một phiên bản của Home.

var home: Home?

Trước khi truy cập vào các tập hợp, hãy nhớ mở gói chúng vì đây là các tập hợp không bắt buộc:

guard let home else { return nil }

Theo dõi các thay đổi đối với cấu trúc

Những thay đổi sau đây đối với một cấu trúc sẽ kích hoạt bộ sưu tập này:

home.structures().batched()
  .compactMap { $0.first(where: { $0.id = myStructureID} }
  .removeDuplicates()
  .sink { structure in
    if let structure = structure {
      print("Structure \(structure.id) updated to \(structure.name)")
    }
  }

Theo dõi các thay đổi đối với một thiết bị cụ thể

Những thay đổi sau đây đối với một thiết bị sẽ kích hoạt bộ sưu tập này:

home.devices().batched()
  .compactMap { deviceList -> HomeDevice? in
    deviceList.filter { $0.name == "Bedroom Lamp"}.first
  }
  .removeDuplicates()
  .sink { lampDevice in
    if lampDevice != nil {
      print("The bedroom lamp has changed!")
    }
  }

Theo dõi các thay đổi đối với một đặc điểm cụ thể trên thiết bị

Sử dụng mọi đặc điểm mà thiết bị và Home API hỗ trợ. Để xem danh sách đầy đủ, hãy xem Trait.

device.types.subscribe(OnOffLightDeviceType.self)
  .compactMap { $0.matterTraits.onOffTrait }
  .removeDuplicates()
  .sink { onOffState in
    if let onOffState = onOffState {
      print("Got new state update: \(onOffState.onOff)")
    }
  }

Theo dõi các thay đổi đối với một loại cụ thể trên thiết bị

Những thay đổi sau đây đối với một loại thiết bị sẽ kích hoạt bộ sưu tập này:

Sử dụng mọi loại thiết bị Matter mà Home API hỗ trợ. Để xem danh sách đầy đủ, hãy xem DeviceType.

device.types.subscribe(DimmableLightDeviceType.self)
  .compactMap { $0.matterTraits.levelControlTrait }
  .removeDuplicates()
  .sink { dimmableLightDevice in
    if let dimmableLightDevice = dimmableLightDevice
      print("Got new state update! \(levelControlTrait.currentLevel)")
    }
  }

Theo dõi các thay đổi đối với một phòng trong ngôi nhà

Những thay đổi sau đây đối với một phòng sẽ kích hoạt bộ sưu tập này:

Để theo dõi thời điểm thiết bị được thêm hoặc xoá khỏi một phòng, hãy sử dụng devices()truy vấn.

home.rooms().batched()
  .sink { rooms in
    print("Got a new updated set of rooms!")
    for room in rooms {
      print("Got room #\(room.name)")
    }
  }

Đăng ký nhận thông báo về sự kiện

Trong Home API, các sự kiện được dùng để phát hiện những thay đổi về trạng thái của thiết bị.

self.cancellable = self.device.types.subscribe(FanDeviceType.self)
  .receive(on: DispatchQueue.main)
  .catch { error in
    Logger.error("Error getting FanDeviceType: \(error)")
    return Empty<FanDeviceType, Never>().eraseToAnyPublisher()
  }
  .sink { [weak self] fanDeviceType in
    self?.fanDeviceType = fanDeviceType
    self?.updateTileInfo()
  }
}