Anleitung für Türklingelgeräte für iOS

Der Gerätetyp „Türklingel“ wird mit zwei Traits implementiert: PushAvStreamTransportTrait, das den Transport von Audio- und Videostreams über Push-basierte Protokolle übernimmt, und WebRtcLiveViewTrait, das die Möglichkeit bietet, Livestreams und die Gegensprechfunktion zu steuern.

Prüfen Sie immer, ob ein Gerät Attribute und Befehle unterstützt, bevor Sie Funktionen verwenden oder versuchen, Attribute zu aktualisieren. Weitere Informationen finden Sie unter Geräte aufiOS steuern.

Gerätetyp für Home-APIs Merkmale Swift-Beispiel-App Anwendungsfall

Türklingel

GoogleDoorbellDeviceType

home.matter.6006.types.0113

Ein Gerät, das durch einen Knopf außerhalb einer Tür betätigt wird und ein akustisches und/oder visuelles Signal erzeugt. Dadurch soll die Aufmerksamkeit einer Person erregt werden, die sich auf der anderen Seite der Tür befindet. Türklingeln können zugängliche Livestreams, Zweiwege-Audio oder Erkennungsereignisse bieten.

Erforderliche Attribute
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

Türklingel

Grundlegende Informationen zu einem Gerät abrufen

Das Merkmal BasicInformation enthält Informationen wie den Namen des Anbieters, die Anbieter-ID, die Produkt-ID, den Produktnamen (einschließlich Modellinformationen), die Softwareversion und die Seriennummer eines Geräts:

// [START get_device_information]
let vendorName = basicInfoTrait.attributes.vendorName!
let vendorID = basicInfoTrait.attributes.vendorID!
let productID = basicInfoTrait.attributes.productID!
let productName = basicInfoTrait.attributes.productName!
let softwareVersion = basicInfoTrait.attributes.softwareVersion!
let serialNumber = basicInfoTrait.attributes.serialNumber!
// [END get_device_information]

Verbindung für ein Gerät prüfen

Die Verbindung für ein Gerät wird tatsächlich auf der Ebene des Gerätetyps geprüft, da einige Geräte mehrere Gerätetypen unterstützen. Der zurückgegebene Status ist eine Kombination der Verbindungsstatus für alle Merkmale auf diesem Gerät.

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

Der Status partiallyOnline kann bei gemischten Gerätetypen auftreten, wenn keine Internetverbindung besteht. Matter-Standardmerkmale sind aufgrund des lokalen Routings möglicherweise weiterhin online, cloudbasierte Merkmale jedoch nicht.

Livestream starten

Wenn Sie einen Livestream starten möchten, senden Sie den SDP-String (Session Description Protocol) an die Methode startLiveView(offerSdp:) des Traits WebRtcLiveViewTrait. Diese gibt drei Werte zurück:

  • Das SDP für die Sitzung.
  • Die Sitzungsdauer in Sekunden.
  • Die Sitzungs-ID, die zum Verlängern oder Beenden der Sitzung verwendet werden kann.
public func sendOffer(offerSdp: String) async throws
-> (answerSdp: String, mediaSessionId: String, liveViewDuration: TimeInterval)
{
  do {
    // Sending StartLiveView command
    let response = try await liveViewTrait.startLiveView(
      offerSdp: offerSdp
    )
    // Received StartLiveView response
    return (
      answerSdp: response.answerSdp,
      mediaSessionId: response.mediaSessionId,
      liveViewDuration: TimeInterval(response.liveSessionDurationSeconds)
    )
  } catch {
    // Failed to send StartLiveView command
    throw error
  }
}

Livestream verlängern

Livestreams haben eine voreingestellte Dauer, nach der sie ablaufen. Wenn Sie die Dauer eines aktiven Streams verlängern möchten, senden Sie eine Verlängerungsanfrage mit der Methode extendLiveView(mediaSessionId:optionalArgsProvider:):

public func extendLiveView(mediaSessionId: String) async throws {
  do {
    // Extending live view
    let extendedDuration = try await liveViewTrait.extendLiveView(mediaSessionId: mediaSessionId)
  } catch {
    // Failed to extend live view
    throw error
  }
}

TalkBack starten und beenden

Rufen Sie die Methode startTalkback(mediaSessionId:optionalArgsProvider:) des Traits WebRtcLiveViewTrait auf, um TalkBack zu starten. Verwenden Sie stopTalkback(mediaSessionId:), um die Aufnahme zu beenden.

public func toggleTwoWayTalk(isOn: Bool, mediaSessionId: String) async throws {
  do {
    if isOn {
      try await liveViewTrait.startTalkback(mediaSessionId: mediaSessionId)
    } else {
      try await liveViewTrait.stopTalkback(mediaSessionId: mediaSessionId)
    }
  } catch {
    throw HomeError.commandFailed("Failed to toggle twoWayTalk: \(error)")
  }
}

Aufzeichnungsfunktion aktivieren und deaktivieren

Um die Aufnahmefunktion der Kamera zu aktivieren, übergeben Sie TransportStatusEnum.Active an die Methode setTransportStatus(transportStatus:optionalArgsProvider:) des Traits PushAvStreamTransportTrait. Wenn Sie die Aufnahmefunktion deaktivieren möchten, übergeben Sie sie TransportStatusEnum.Inactive. Im folgenden Beispiel fassen wir diese Aufrufe in einem einzigen Aufruf zusammen, der ein Boolean verwendet, um die Aufnahmefunktion zu aktivieren oder zu deaktivieren:

public func toggleIsRecording(isOn: Bool) {
  self.uiState = .loading

  guard let pushAvStreamTransportTrait else {
    // PushAvStreamTransportTrait not found.
    return
  }
  Task {
    do {
      try await pushAvStreamTransportTrait.setTransportStatus(
        transportStatus: isOn ? .active : .inactive)
      if isOn {
        do {
          self.player = try self.createWebRtcPlayer()
        } catch {
          // Failed to initialize WebRtcPlayer
          self.uiState = .disconnected
          return
        }
        await self.player?.initialize()
        self.uiState = .live
      } else {
        self.player = nil
        self.uiState = .off
      }
    } catch {
      // Failed to toggle onOff
    }
  }
}

Das Aktivieren oder Deaktivieren der Aufnahmefunktion der Kamera entspricht dem Ein- oder Ausschalten des Kameravideos. Wenn das Video einer Kamera aktiviert ist, wird es aufgezeichnet (für Ereignisse und zugehörige Clips).

Wenn die Aufzeichnungsfunktion deaktiviert ist (das Kameravideo ist deaktiviert):

  • Die Kamera kann gemäß der connectivityState des Gerätetyps weiterhin als online angezeigt werden.
  • Auf den Livestream kann nicht zugegriffen werden und die Kamera erkennt keine Cloud-Ereignisse.

Prüfen, ob die Aufnahmefunktion aktiviert ist

Wenn Sie prüfen möchten, ob die Aufnahmefunktion einer Kamera aktiviert ist, sehen Sie nach, ob Verbindungen aktiv sind. Im folgenden Beispiel werden zwei Funktionen definiert, um dies zu tun:

public func isDeviceRecording() -> Bool {
  guard let pushAvStreamTransportTrait else {
    // PushAvStreamTransportTrait not found.
    return false
  }
  guard
    let hasActiveConnection =
      pushAvStreamTransportTrait
      .attributes
      .currentConnections?
      .contains(where: { $0.transportStatus == .active })
  else {
    return false
  }
  return hasActiveConnection
}

Akkueinstellungen

Über die Home-APIs können verschiedene Akku-Einstellungen gesteuert werden.

Einstellung für die Akkunutzung festlegen

Mit der Einstellung für die Energiebilanz können Sie den Kompromiss zwischen Akkulaufzeit und Leistung für ein Gerät konfigurieren. Sie können verschiedene Akkuprofile wie „Erweitert“, „Ausgewogen“ und „Leistung“ erstellen und zwischen ihnen wechseln.

Diese Funktion wird durch Aktualisieren des Attributs currentEnergyBalance des Traits EnergyPreference implementiert. Das Attribut akzeptiert einen Ganzzahlindex, der einem bestimmten Profil in der Liste energyBalances des Geräts entspricht (z. B. 0 für EXTENDED, 1 für BALANCED und 2 für PERFORMANCE).

Ein null-Wert für currentEnergyBalance gibt an, dass das Gerät ein benutzerdefiniertes Profil verwendet. Dies ist ein schreibgeschützter Status.

Im Folgenden sehen Sie ein Beispiel für eine Struktur, die vom Attribut currentEnergyBalance verwendet wird, gefolgt vom tatsächlichen Code-Snippet, in dem das Attribut verwendet wird.

// Example energyBalances list
{
  "energy_balances": [
    {
      "step": 0,
      "label": "EXTENDED"
    },
    {
      "step": 50,
      "label": "BALANCED"
    },
    {
      "step": 100,
      "label": "PERFORMANCE"
    }
  ]
}
private func setBatteryUsage(to option: UInt8) async throws {
  _ = try await energyPreferenceTrait.update {
    $0.setCurrentEnergyBalance(option)
  }
}

Automatischen Energiesparmodus aktivieren

Aktualisieren Sie das Attribut currentLowPowerModeSensitivity des Traits EnergyPreference, um diese Funktion zu konfigurieren. Für dieses Attribut wird ein Index verwendet, um eine Vertraulichkeitsstufe auszuwählen. Dabei steht 0 in der Regel für Disabled und 1 für Enabled oder Automatic.

private func setAutoBatterySaver(to value: Bool) async throws {
  _ = try await energyPreferenceTrait.update {
    $0.setCurrentLowPowerModeSensitivity(value ? 1 : 0)
  }
}

Akkuladestatus abrufen

Verwende das Attribut batChargeState des Trait PowerSource, um den aktuellen Ladestatus des Geräts abzurufen (wird geladen, vollständig geladen oder wird nicht geladen).

self.chargingState = powerSourceTrait.attributes.batChargeState

var description: String
switch self.chargingState {
case .isCharging:
  description = "Charging"
case .isAtFullCharge:
  description = "Full"
case .isNotCharging:
  description = "Not Charging"
default:
  description = "Unknown"
}

Akkustand abrufen

Verwende das Attribut batChargeLevel des Traits PowerSource, um den aktuellen Akkuladestand abzurufen. Der Wert ist entweder OK, Warning (niedrig) oder Critical.

self.batteryLevel = powerSourceTrait.attributes.batChargeLevel

var description: String
switch self.batteryLevel {
case .ok:
  description = "OK"
case .warning:
  description = "Warning"
case .critical:
  description = "Critical"
default:
  description = "Unknown"
}

Stromquelle

Verwende die Attribute BatPresent und wiredPresent des Traits PowerSource, um die Stromquelle des Geräts zu ermitteln.

if powerSourceTrait.attributes.wiredPresent ?? false {
  self.powerSourceType = .wired
} else if powerSourceTrait.attributes.batPresent ?? false {
  self.powerSourceType = .battery
} else {
  self.powerSourceType = nil
}

Audioeinstellungen

Über die Home-APIs lassen sich verschiedene Audioeinstellungen steuern.

Mikrofon ein- und ausschalten

Aktualisieren Sie das Attribut microphoneMuted des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setMicrophoneMuted, um das Mikrofon des Geräts zu aktivieren oder zu deaktivieren:

// Turn the device's microphone on or off
func setMicrophone(on: Bool) async {
  do {
    _ = try await self.cameraAvStreamManagementTrait?.update {
      $0.setMicrophoneMuted(!on)
    }
  } catch {
    // Error
  }
}

Audioaufnahme ein- oder ausschalten

Wenn Sie die Audioaufnahme für das Gerät aktivieren oder deaktivieren möchten, aktualisieren Sie das Attribut recordingMicrophoneMuted des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setRecordingMicrophoneMuted:

// Turn audio recording on or off for the device
func setAudioRecording(on: Bool) async {
  do {
    _ = try await self.cameraAvStreamManagementTrait?.update {
      $0.setRecordingMicrophoneMuted(!on)
    }
  } catch {
    // Error
  }
}

Lautsprecherlautstärke anpassen

Wenn Sie die Lautsprecherlautstärke für das Gerät anpassen möchten, aktualisieren Sie das Attribut speakerVolumeLevel des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setSpeakerVolumeLevel:

// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setSpeakerVolumeLevel(value)
    }
  } catch {
    // Error
  }
}

Weitere Einstellungen

Über die Home-APIs lassen sich verschiedene andere Einstellungen steuern.

Nachtsichtmodus aktivieren oder deaktivieren

Wenn Sie die Nachtsicht für die Kamera aktivieren oder deaktivieren möchten, verwenden Sie TriStateAutoEnum, um das Attribut nightVision des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setNightVision zu aktualisieren:

// Turn night vision on or off
func setNightVision(
  to value: Google.CameraAvStreamManagementTrait.TriStateAutoEnum
) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setNightVision(value)
    }
  } catch {
    // Error
  }
}

Helligkeit der Status-LED ändern

Wenn Sie die Helligkeit der Status-LED ändern möchten, verwenden Sie ThreeLevelAutoEnum, um das Attribut statusLightBrightness des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setStatusLightBrightness zu aktualisieren:

// Set the LED brightness
func setStatusLightBrightness(
  to value: Google.CameraAvStreamManagementTrait.ThreeLevelAutoEnum
) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setStatusLightBrightness(value)
    }
  } catch {
    // Error
  }
}

Kamera-Darstellungsbereich ändern

Der Kamera-Viewport entspricht der Funktion „Zoomen und zuschneiden“, die im Hilfeartikel zum Zoomen und Optimieren von Nest-Kameravideos beschrieben wird.

Der Viewport wird in einem ViewportStruct definiert, das vier Werte enthält, die als Koordinaten des Viewports verwendet werden. Die Koordinaten sind so definiert:

(x1,y1) -- (x2,y1)
   |          |
(x1,y2) -- (x2,y2)

Die Werte für ViewportStruct hängen von der Benutzeroberfläche und der Kameraimplementierung einer App ab. Um den Viewport des Kameravideos festzulegen, müssen Sie das Attribut viewport des Traits CameraAvStreamManagementTrait mit einem ViewportStruct aktualisieren. Verwenden Sie dazu die integrierte Funktion setViewport.

func setCrop(x1: UInt16, y1: UInt16, x2: UInt16, y2: UInt16) {

  let viewport = Google.CameraAvStreamManagementTrait.ViewportStruct(
    x1: x1,
    y1: y1,
    x2: x2,
    y2: y2
  )

  Task {
    do {
      try await cameraAvStreamManagementTrait.update {
        $0.setViewport(viewport)
      }
    } catch {
      // Error
    }
  }

}

TransportOptionsStruct generieren

Für einige Einstellungen sind Änderungen an Eigenschaften in einem TransportOptionsStruct erforderlich, das dann an die Transportoptionen einer Streamingverbindung übergeben wird. In Swift muss diese Struktur generiert werden, bevor Eigenschaften aktualisiert werden.

Mit dieser Hilfsfunktion können Sie die Struktur für die Verwendung mit den folgenden Einstellungsänderungen generieren:

func getTransportOptions(
  transportOptions: Google.PushAvStreamTransportTrait.TransportOptionsStruct,
  wakeUpSensitivity: UInt8?,
  maxEventLength: UInt32?
) async throws
  -> Google.PushAvStreamTransportTrait.TransportOptionsStruct
{

  var newMotionTimeControl:
    Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct? = nil
  if let maxEventLength {
    guard let motionTimeControl = transportOptions.triggerOptions.motionTimeControl else {
      throw HomeError.failedPrecondition(
        // Error - cannot update max event length without motion time control
    }
    newMotionTimeControl =
      Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct(
        initialDuration: motionTimeControl.initialDuration,
        augmentationDuration: motionTimeControl.augmentationDuration,
        maxDuration: maxEventLength,
        blindDuration: motionTimeControl.blindDuration
      )
  }

  return Google.PushAvStreamTransportTrait.TransportOptionsStruct(
    streamUsage: .recording,
    videoStreamID: nil,
    audioStreamID: nil,
    tlsEndpointID: transportOptions.tlsEndpointID,
    url: transportOptions.url,
    triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct(
      triggerType: .motion,
      motionZones: nil,
      motionSensitivity: wakeUpSensitivity,
      motionTimeControl: newMotionTimeControl,
      maxPreRollLen: nil
    ),
    ingestMethod: .cmafIngest,
    containerOptions: Google.PushAvStreamTransportTrait.ContainerOptionsStruct(
      containerType: .cmaf,
      cmafContainerOptions: nil
    ),
    expiryTime: nil
  )
}

private func getRecordingConnection() async throws
  -> Google.PushAvStreamTransportTrait.TransportConfigurationStruct?
{
  guard let pushAvStreamTransportTrait else {
    // Error - PushAvStreamTransport trait not available
    return nil
  }

  let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations

  for connection in connections {
    guard let transportOptions = connection.transportOptions,
      transportOptions.streamUsage == .recording
    else {
      continue
    }

    return connection
  }

  return nil
}

Empfindlichkeit für die Beendigung des Ruhemodus anpassen

Die Aufwachsensibilität des Geräts wird verwendet, um den Akku zu schonen. Dazu wird der Bereich verkleinert, in dem das Gerät Aktivitäten erkennen kann, und die Zeit bis zum Aufwachen nach Erkennen einer Aktivität verlängert.

In den Home APIs kann dies mit dem Attribut motionSensitivity des triggerOptions im transportOptions des Geräts festgelegt werden. Diese Optionen werden für jedes Gerät im PushAvStreamTransportTrait-Trait definiert.

Die Weckempfindlichkeit kann nur auf die folgenden Werte eingestellt werden:

  • 1 = Niedrig
  • 5 = Mittel
  • 10 = Hoch

Suchen Sie zuerst mit dem Befehl findTransport nach der Transportkonfiguration für aktive Aufzeichnungsstreams und ändern Sie dann die Konfiguration mit dem neuen Empfindlichkeitswert mit dem Befehl modifyPushTransport.

Für den Befehl modifyPushTransport muss der vollständige TransportOptionsStruct übergeben werden. Sie müssen also zuerst vorhandene Werte aus der aktuellen Konfiguration kopieren. Verwenden Sie dazu die TransportOptionsStruct-Funktion für eine Hilfsfunktion.

func setWakeUpSensitivity(to value: UInt8) async {
  do {
    let connection = try await getRecordingConnection()
    guard let connection,
      let transportOptions = connection.transportOptions
    else {
      // Error - Transport options not available
      return
    }

    guard transportOptions.triggerOptions.motionSensitivity != nil else {
      // Error - Motion sensitivity not available to be updated for this device
      return
    }

    try await pushAvStreamTransportTrait.modifyPushTransport(
      connectionID: connection.connectionID,
      transportOptions: self.getTransportOptions(
        transportOptions: transportOptions,
        wakeUpSensitivity: value,
        maxEventLength: nil
      )
    )

  } catch {
    // Error
  }
}

Maximale Ereignisdauer anpassen

Die maximale Ereignisdauer gibt an, wie lange die Kamera einen Clip für ein Ereignis aufzeichnet. Über die Home APIs kann dies pro Gerät auf die gleiche Länge wie über die Google Home app (GHA) konfiguriert werden, in Intervallen von Sekunden:

  • 10 Sekunden
  • 15 Sekunden
  • 30 Sekunden
  • 60 Sekunden (1 Minute)
  • 120 Sekunden (2 Minuten)
  • 180 Sekunden (3 Minuten)

In den Home APIs kann dies mit dem Attribut motionTimeControl des triggerOptions im transportOptions des Geräts festgelegt werden. Diese Optionen werden für jedes Gerät im PushAvStreamTransportTrait-Trait definiert.

Suchen Sie zuerst mit dem Befehl findTransport nach der Transportkonfiguration für aktive Aufzeichnungsstreams. Ändern Sie dann die Konfiguration mit dem neuen Wert für die Ereignislänge mit dem Befehl modifyPushTransport.

Für den Befehl modifyPushTransport muss der vollständige TransportOptionsStruct übergeben werden. Sie müssen also zuerst vorhandene Werte aus der aktuellen Konfiguration kopieren. Verwenden Sie dazu die TransportOptionsStruct-Funktion für eine Hilfsfunktion.

func setMaxEventLength(to value: UInt32) async {
  do {
    let connection = try await getRecordingConnection()
    guard let connection,
      let transportOptions = connection.transportOptions
    else {
      // Error - Transport options not available
      return
    }

    guard transportOptions.triggerOptions.motionTimeControl != nil else {
      // Error - Motion time control not available to be updated for this device
      return
    }

    try await pushAvStreamTransportTrait.modifyPushTransport(
      connectionID: connection.connectionID,
      transportOptions: self.getTransportOptions(
        transportOptions: transportOptions,
        wakeUpSensitivity: nil,
        maxEventLength: value
      )
    )

  } catch {
    // Error
  }
}

Glockeneinstellungen

Über die Home-APIs lassen sich verschiedene Einstellungen für den Glockenton der Türklingel steuern.

Glockenton ändern

Wenn Sie den Klingelton der Türklingel ändern möchten, rufen Sie zuerst die Liste der Klingeltöne ab, die auf dem Gerät installiert sind. Verwenden Sie dazu das Attribut installedChimeSounds des Traits ChimeTrait:

doorbellChimeTrait.attributes.installedChimeSounds?.compactMap { chimeSound in
  return chimeSound.chimeID, chimeSound.name
}

Aktualisieren Sie dann das Attribut selectedChime des Traits ChimeTrait mit der integrierten Funktion setSelectedChime:

func setDoorbellChime(chimeID: UInt8) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setSelectedChime(chimeID)
    }
  } catch {
    // Error
  }
}

Externe Glocke verwenden

Die Türklingel kann so konfiguriert werden, dass sie eine externe Glocke verwendet, z. B. eine mechanische Glocke im Haus. Dies sollte bei der Installation der Türklingel konfiguriert werden, um potenzielle Schäden an der externen Glocke zu vermeiden.

Um anzugeben, welcher Typ von externem Gong installiert ist, verwenden Sie ExternalChimeType, um das Attribut externalChime des ChimeTrait-Traits mit der integrierten Funktion setExternalChime zu aktualisieren:

// Indicate the external chime is mechanical
func setExternalChime(to value: Google.ChimeTrait.ExternalChimeType) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setExternalChime(value)
    }
  } catch {
    // Error
  }
}

Dauer des externen Glockentons ändern

Die Dauer, in Sekunden, die ein externer Gong klingelt, kann über die Home-APIs konfiguriert werden. Wenn die externe Glocke eine Dauer für den Glockenton unterstützt, kann der Nutzer diese konfigurieren.

Der hier festgelegte Wert hängt von den Spezifikationen des externen Gongs und der empfohlenen Gongdauer ab.

Wenn Sie die Dauer des externen Glockentons ändern möchten, aktualisieren Sie das Attribut externalChimeDurationSeconds des Traits ChimeTrait mit der integrierten Funktion setExternalChimeDurationSeconds:

// Change the external chime duration
func setExternalChimeDuration(to value: UInt16) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setExternalChimeDuration(value)
    }
  } catch {
    // Error
  }
}

Klingelton-Design aktivieren

Einige Türklingeln haben möglicherweise Klingeltöne, die Nutzern nur für begrenzte Zeit zur Verfügung stehen. Das können beispielsweise Glockenspiele für Feiertage sein. Diese werden als Glockenspiel-Themen bezeichnet.

Wenn Sie sehen möchten, welche Chime-Designs für einen Nutzer verfügbar sind, erstellen Sie einen Timebox-Filter und verwenden Sie ihn, um die Ergebnisse des Befehls getAvailableThemes aus dem Trait ChimeThemes zu filtern. Daraufhin wird eine Liste der verfügbaren Designs mit den jeweiligen Namen zurückgegeben.

Im folgenden Beispiel wird gezeigt, wie die Liste gefiltert wird. Ein Theme gilt als aktiv, wenn die aktuelle Zeit innerhalb des Start- und Endzeitpunkts liegt (die Werte startTimeSeconds bzw. endTimeSeconds). Wenn keine Startzeit festgelegt ist, gilt sie als von Anfang an aktiv. Wenn keine Endzeit festgelegt ist, bleibt sie auf unbestimmte Zeit aktiv. Wenn beide fehlen, ist das Design immer aktiv.

let chimeThemes = try await chimeThemeTrait.getAvailableThemes().themes

if !chimeThemes.isEmpty {
  var chimeThemeSettings = []
  for chimeTheme in chimeThemes {
    let currentDateTime = UInt64(Date().timeIntervalSince1970)

    // Only show chime themes that are active.
    if chimeTheme.startTimeSeconds ?? 0 <= currentDateTime
      && chimeTheme.endTimeSeconds ?? UInt64.max >= currentDateTime
    {
      self.chimeThemeSettings.append(chimeTheme.name)
    }
  }
}

Sobald Sie den Namen des gewünschten Designs haben, z. B. Christmas, können Sie es mit der Funktion setSelectedTimeboxedThemeName() für das Attribut ChimeThemes ChimeThemes auswählen.

private func setChimeTheme(to value: String) async throws {
  _ = try await chimeThemeTrait.update {
    $0.setSelectedTimeboxedThemeName(value)
  }
}```