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

Trong API Nhà thông minh dành 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 API Nhà thông minh bằng bất kỳ API nào sử dụng HomeDevice. Bạn có thể thực hiện việc này bằng cách đăng ký nhà xuất bản hiển thị các giá trị từ sự kiện không đồng bộ.

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

Nhà phát triển có trách nhiệm suy ra 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 từng loại đối tượng mẹ trong API Nhà thông minh cho mục đích này.

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

Khi một đối tượng là không bắt buộc, hãy sử dụng if let hoặc guard để mở gói đối tượng một cách an toàn. Đừng sử dụng !! không bao giờ được sử dụng trừ phi nhà phát triển biết 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à đây là một chuỗi không bắt buộc và có thể là nil. Hàm này tìm đố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 nhà xuất bản trong API Nhà thông minh. Đối với các ví dụ sau đây, bạn phải tạo một thực thể 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 các tập hợp đó vì chúng là không bắt buộc:

guard let home else { return nil }

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

Các thay đổi sau đây đối với một cấu trúc sẽ kích hoạt tập hợp này:

  • Tên cấu trúc
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ể

Các thay đổi sau đây đối với một thiết bị sẽ kích hoạt tập hợ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 trait cụ thể trên một thiết bị

Sử dụng mọi trait được thiết bị và API Nhà thông minh 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 một thiết bị

Các thay đổi sau đây đối với một loại thiết bị sẽ kích hoạt tập hợp này:

Sử dụng mọi loại thiết bị Matter được API Nhà thông minh 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 một cấu trúc

Các thay đổi sau đây đối với một phòng sẽ kích hoạt tập hợp này:

Để theo dõi thời điểm thiết bị được thêm vào 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ý sự kiện

Trong API Nhà thông minh, các sự kiện được dùng để phát hiện các thay đổi về trạng thái của một thiết bị.

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