iOS에서 기기 상태 모니터링

iOS용 Home API에서는 Swift에서 Combine 프레임워크를 사용하여 홈의 상태 변경사항을 관찰할 수 있습니다. Home API에서 구조, 방, 기기 메타데이터, 기기 상태의 변경사항을 관찰하는 작업은 HomeDevice를 사용하는 모든 API로 실행할 수 있습니다. 비동기 이벤트의 값을 노출하는 게시자구독하여 이를 실행합니다.

컬렉션의 항목이 추가, 삭제 또는 수정되면 컬렉션의 최신 스냅샷이 반환됩니다.

이 스냅샷을 이전 사본과 비교하여 구체적인 변경사항을 추론하는 것은 개발자에게 달려 있습니다. Home API의 각 상위 객체 유형에 제공된 id 필드를 이 용도로 사용할 수 있습니다.

선택적 객체를 래핑 해제하는 방법

객체가 선택사항인 경우 if let 또는 guard를 사용하여 객체를 안전하게 래핑 해제합니다. 개발자가 객체가 null이 될 수 없다고 확실히 알지 않는 한 !를 사용해서는 안 되므로 !를 사용하지 마세요.

예시의 입력 매개변수 structureIDString?로 정의됩니다. 즉, 선택사항이며 null일 수 있는 문자열입니다. 이 함수는 structureID의 입력을 기반으로 Structure 객체를 찾습니다.

선택적 객체를 처리하는 권장 방법은 다음과 같습니다.

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

게시자 사용 방법

다음은 Home API에서 게시자를 사용하는 몇 가지 기본 예입니다. 다음 예에서는 Home의 인스턴스를 만들어야 합니다.

var home: Home?

컬렉션은 선택사항이므로 컬렉션에 액세스하기 전에 래핑을 해제해야 합니다.

guard let home else { return nil }

구조 변경사항 추적

구조에 다음과 같은 변경사항이 있으면 이 컬렉션이 트리거됩니다.

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)")
    }
  }

특정 기기의 변경사항 추적

기기에 다음과 같은 변경사항이 있으면 이 컬렉션이 트리거됩니다.

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!")
    }
  }

기기에서 특정 트레잇의 변경사항 추적

기기 및 Home API에서 지원하는 모든 트레잇을 사용합니다. 전체 목록은 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)")
    }
  }

기기에서 특정 유형의 변경사항 추적

다음과 같은 기기 유형 변경사항이 이 수집을 트리거합니다.

Home API에서 지원하는 Matter 기기 유형을 사용합니다. 전체 목록은 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)")
    }
  }

구조물의 방 변경사항 추적

다음과 같은 채팅방 변경사항이 있으면 이 컬렉션이 트리거됩니다.

기기가 방에 추가되거나 삭제되는 시점을 추적하려면 devices() 쿼리를 사용하세요.

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

이벤트 구독

Home API에서 이벤트는 기기 상태의 변경사항을 감지하는 데 사용됩니다.

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()
  }
}