iOS에서 기기 상태 모니터링

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

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

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

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

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

예의 입력 매개변수 structureIDString?로 정의됩니다. 즉, 선택사항이며 nil일 수 있는 문자열입니다. 이 함수는 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()
  }
}