iOS'te Home API'lerini kullanarak mobil uygulama oluşturma

1. Giriş

f154e30306882c74.png

Home API'ler nedir?

Google Home API'leri, geliştiricilerin Google Home ekosistemine erişebilmesi için bir dizi kitaplık sağlar. Home API'leri sayesinde geliştiriciler, akıllı ev cihazlarını sorunsuz bir şekilde devreye alan ve kontrol eden uygulamalar oluşturabilir.

3e11583c779a2cec.png

Home API'lerinin bileşenleri

Home API'leri şunlardan oluşur:

  • Device ve Structure API'leri: Kullanıcının evi ile etkileşimde bulunun. Uygulamalar, cihazlar, odalar ve yapılarla ilgili bilgileri okumak (ör. mevcut termostat sıcaklığını görmek) ve cihazları kontrol etmek (ör. termostat istenen sıcaklığını değiştirmek) için bu API'leri kullanabilir.
  • Devreye Alma API'si: Minimum düzeyde çabayla yeni Matter cihazlarını kumaşta etkinleştirin (kurabilirsiniz).
  • Automation API: Kullanıcının evinde çalışan otomasyonları oluşturun, silin ve sorgulayın.

Ön koşullar

Neler öğreneceksiniz?

  • Home API'lerini en iyi uygulamalarla kullanarak iOS uygulaması oluşturma.
  • Akıllı evi temsil etmek ve kontrol etmek için Device ve Structure API'lerini kullanma.
  • Google Home ekosistemine cihaz eklemek için Commissioning API'yi kullanma.
  • Temel bir otomasyon oluşturmak için Otomasyon API'yi kullanma.

2. Evinizi ayarlama

Cihazları hazırlama

Google Home Playground, önceden oluşturulmuş çeşitli emülasyonlu akıllı ev cihazları sunar. Özellikle evinizde sınırlı sayıda cihaz varsa Home API'lerin tüm potansiyelini keşfetmek için bu platformu kullanmanız önerilir.

Google Home Playground'ta oturum açma ve Google Home uygulamasında hesap bağlama işlemini tamamlama talimatlarını uygulayın. Bu işlemi tamamladıktan sonra cihazları Google Home uygulamasındaki "Cihazlar" sekmesinde görebilirsiniz.

c892afce113abe8f.png

3. Hazırlanma

Örnek uygulamanın kodunu alma

GitHub'dan kaynak kodunu kopyalayarak başlayın:

git clone https://github.com/google-home/google-home-api-sample-app-ios.git

Örnek dizin, bu kod laboratuvarının start ve finished olmak üzere iki dalını içerir.

  • start: Codelab'i tamamlamak için değişiklikler yapacağınız bu projenin başlangıç kodu.
  • finished: Bu codelab'in tamamlanmış kodu. Çalışmanızı kontrol etmek için kullanılır.

"start" kodunu keşfetme

Klonlanan deponuzun start dalına geçerek bu codelab'e başlayın:

git checkout start

Bu dal, projenin başlangıç kodunu içerir. Tüm işlevleri uygulamak için codelab boyunca bu kodu değiştireceksiniz. Codelab örnek uygulaması, Home APIs iOS SDK'sı ile etkileşim kurmak için Swift'te oluşturulmuş temel bir yapı sağlar. start projesindeki temel bileşenlere hızlıca göz atalım:

  • Main Entry (GoogleHomeAPISampleIOSApp): GoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift adresinde bulunan bu adres, uygulamanın ana giriş noktasıdır. SDK'yı yapılandırır ve başlatır, birincil kullanıcı arayüzünü kurar.
  • Core Views (View/):
    • MainView.swift: Ana NavigationView'ı içeren, lansmandan sonraki kök görünüm. Etkin Google Home yapısını seçer ve ilgili StructureView değerini gösterir.
    • StructureView.swift: Sekmeleri kullanarak Cihazlar ızgarası ile Otomasyonlar listesi arasında geçiş yaparak, seçili yapının içeriğini gösterir. Ayrıca oda veya cihaz ekleme menüleri de sağlar.
    • DeviceView.swift: StructureView ızgarasındaki tek bir cihazın etkileşimli karosunu temsil eder.
    • AutomationsView.swift: Yapı için mevcut otomasyonların listesini gösterir ve otomasyon ayrıntılarını oluşturmak veya görüntülemek için gezinme sağlar.
  • ViewModels (ViewModel/): Bu sınıflar, görünümlerin durumunu ve mantığını yönetir.
    • AccountViewModel.swift: Home nesnesine bağlantıyı yönetir ve kimlik doğrulama durumunu yönetir.
    • MainViewModel.swift: Mevcut Structure nesnelerinin listesini yönetir ve seçili yapıyı izler.
    • StructureViewModel.swift: Seçilen yapıdaki odaların ve DeviceControl nesnelerinin görüntülenmesini yönetir.
    • AutomationList.swift, AutomationViewModel.swift vb.: Otomasyonları getirme, görüntüleme, oluşturma ve yönetme işlemlerini yönetir.
  • Device Controls (ViewModel/Device/):
    • DeviceControl.swift: Kullanıcı arayüzünde kontrol edilebilir cihazları temsil eden bir temel sınıf.
    • Belirli alt sınıflar (LightControl.swift, FanControl.swift, OnOffPlugInUnitControl.swift vb.): Farklı cihaz türleri için kullanıcı arayüzü mantığını, cihaz kontrolünü ve durum eşlemesini özelliklerine göre uygulayın.
    • DeviceControlFactory.swift: Belirli bir HomeDevice için uygun DeviceControl alt sınıfını oluşturmaktan sorumludur.
  • Commissioning (Commissioning/):
    • CommissioningManager.swift: Matter cihazı devreye alma akışını yönetme mantığını içerir.
  • Utilities & UX (Utils/, UX/, Storage/): Kullanıcı arayüzü öğeleri (renkler, boyutlar), hata işleme, veri depolama (SelectedStructureStorage.swift) ve diğer yardımcı programlar için yardımcı kod içerir.

Bu codelab'de, start projesinde TODO gibi yorumlar veya yorumlanmış kod blokları ve uyarılar göreceksiniz. Bu işaretler, sağlanan adımları uygulayarak gerekli işlevi uygulamak için kod ekleyeceğiniz veya kod yorumunu kaldıracağınız bölümleri gösterir.

Apple dağıtım yapılandırma dosyaları oluşturma

App Attest'i yapılandırmak için Apple dağıtım yapılandırma dosyaları oluşturma talimatlarını uygulayın. Uygulamanın, kurulumdan sonra yalnızca gerçek bir cihaza dağıtılabileceğini unutmayın. Uygulamayı simülatöre dağıtamazsınız.

Kimlik doğrulamayı ayarlama

OAuth istemci kimliğini almak ve Home API'leri etkinleştirmek için önce Google Cloud'da oturum açın ve yeni bir proje oluşturun veya mevcut bir projeyi seçin. Ardından, OAuth istemci kimliğini oluşturmak ve Home API'leri etkinleştirmek için verilen adımları uygulayın ve hesabınızı izin verilenler listesine ekleyin.

SDK'yı ayarlama

Home APIs iOS SDK'sını edinin ve SDK'yı kurma bölümünde verilen kurulum talimatlarına başvurarak yapılandırın. HOME_API_TODO_ADD_APP_GROUP değerini kendi uygulama grubunuzla değiştirmeyi unutmayın.

Projeyi derleyip çalıştırma

Projeyi start dalıyla derleyip çalıştırdıktan sonra bir TODO iletişim kutusu ve "Oturum Açılması Gerekiyor" yazan bir ekran gösterilir. Home API'leri etkileşimi aşağıdaki bölümlerde uygulanacaktır.

bd56b7080037e38a.png 9c0f08a3f4197a77.png

Not: Projede iletişim kutusunda gösterilen metni arayarak değiştirilmesi gereken kodu bulun. Örneğin, "TODO: Ana ekranı başlat" ifadesini arayın.

4. Başlatma

Evi ilk kullanıma hazırlama

iOS için Home API'lerinden herhangi birini kullanmadan önce uygulamanızda Home öğesini başlatmanız gerekir. Home, SDK'ya üst düzey giriştir ve kullanıcının yapısındaki tüm öğelere erişim sağlar. API, belirli bir türdeki tüm öğeleri istediğinde sonuçları nasıl alacağınızı seçmenize olanak tanıyan bir Query nesnesi döndürür. Ev başlatma işlemini uygulamak için GoogleHomeAPISampleIOS/Accounts/AccountViewModel.swift'te yorumu ve connect()'te uyarıyı kaldırın.

  /// TODO: initialize Home
  /// Remove comments to initialize Home and handling permission.
  private func connect() {
    Task {
      do {
        self.home = try await Home.connect()
      } catch {
        Logger().error("Auth error: \(error).")
      }
    }
  }

Home API'lerini kullanma izni

Uygulamayı çalıştırdığınızda izin ekranı gösterilir. Google Home yapısını ve Google Cloud projenizin izin verilenler listesinde bulunan hesabı seçin.

47310f458c0094d9.png 4a571dbd9979a88c.png e29c75891a3a67af.png

5. Cihazlar ve Yapılar

Odalar ve cihazlar

Seçili yapıdaki odaları ve cihazları sırasıyla home.rooms() ve home.devices() ile almak için GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift'te getRoomsAndDevices()'teki yorumu ve uyarıyı kaldırın.

  /// TODO: get rooms and devices
  /// Remove comments to get the rooms and devices from home entry
  private func getRoomsAndDevices(){
    self.home.rooms().batched()
      .combineLatest(self.home.devices().batched())
      .receive(on: DispatchQueue.main)
      .catch { error in
        Logger().error("Failed to load rooms and devices: \(error)")
        return Just((Set<Room>(), Set<HomeDevice>()))
      }
      .map { [weak self] rooms, devices in
        guard let self = self else { return [] }
        self.hasLoaded = true
        return self.process(rooms: rooms, devices: devices)
      }
      /// receive from .map and .assign() to publisher entries
      .assign(to: &self.$entries)
  }

process() işlevi, DeviceControl ve DeviceControlFactory'i kullanarak cihazların HomeDevices olarak etkileşime geçmesini sağlamadan önce cihazların aynı odada olduğundan emin olur.

4c677c4c294e67ca.png

Not: Cihazınız DeviceControlFactory listesinde yoksa "Desteklenmiyor" olarak gösterilir. Desteklenen cihazlar hakkında daha fazla bilgi edinmek için iOS'te Desteklenen Cihaz Türleri sayfasına bakın.

Bir cihazla etkileşimde bulunma

Cihazlara dokunulduğunda veya kaydırıldığında outlet1 fişi başlangıçta etkin değildir. Bu öğeyle etkileşimi etkinleştirmek için GoogleHomeAPISampleIOS/ViewModel/Device/OnOffPlugInUnitControl.swift öğesini bulun ve primaryAction() işlevindeki yorumu ve uyarıyı kaldırın.

  /// TODO: primary action of OnOffPlug
  /// Toggles the plug; usually provided as the `action` callback on a Button.
  public override func primaryAction() {
    self.updateTileInfo(isBusy: true)
    Task { @MainActor [weak self] in
      guard
        let self = self,
        let onOffPluginUnitDeviceType = self.onOffPluginUnitDeviceType,
        let onOffTrait = onOffPluginUnitDeviceType.matterTraits.onOffTrait
      else { return }

      do {
        try await onOffTrait.toggle()
      } catch {
        Logger().error("Failed to to toggle OnOffPluginUnit on/off trait: \(error)")
        self.updateTileInfo(isBusy: false)
      }
    }
  }

OnOffPlugInUnitControl sınıfında bulunan primaryAction() işlevi, akıllı bir prizin veya OnOffPluginUnitDeviceType ile temsil edilen herhangi bir cihazın açık/kapalı durumunu değiştirir.

GoogleHomeAPISampleIOS/ViewModel/Device bölümünde ek cihaz denetimi örnekleri bulunmaktadır.

Yeni oda oluşturma

Structure API, oda oluşturma ve silme işlemlerinin yanı sıra cihazların odalar arasında aktarılmasını sağlar.

GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift'te yorumu ve addRoom()'teki uyarıyı kaldırın.

  /// TODO: add room
  /// Add a new room in a given structure.
  func addRoom(name: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.createRoom(name: name)
      } catch {
        Logger().error("Failed to create room: \(error)")
      }
    }
  }

structure.createRoom() ile yeni bir oda oluşturmak için sol üst köşeye gidin ve "+" simgesini > Oda Ekle'yi seçin. Yeni oda adınızı girin ve "Oda Oluştur"u tıklayın. Yeni oda birkaç saniye sonra görünür.

b122ae6642b7da1c.png a45f785e1d51938e.png 7753b56cbdcff8d6.png

Cihazı farklı bir odaya taşıma

GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift'te yorumu ve moveDevice()'teki uyarıyı kaldırın.

  /// TODO: move device
  /// Move a device into a different room.
  func moveDevice(device deviceID: String, to roomID: String, structure: Structure) {
    Task {
      do {
        _ = try await structure.move(device: deviceID, to: roomID)
      } catch {
        Logger().error("Failed to move to room: \(error)")
      }
    }
  }

Cihazı structure.move() ile taşımak için cihaza uzun basın, "Başka bir odaya taşı"yı seçin ve yeni odayı belirleyin.

f9627592af44163d.png fd126fabb454f2bf.png 813e1e23e50cd9f6.png

Boş bir odayı silme

GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift'te yorumu ve removeRoom()'teki uyarıyı kaldırın.

  /// TODO: delete room
  /// Delete an empty room in a given structure.
  func removeRoom(id: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.deleteRoom(id: id)
      } catch {
        Logger().error("Failed to remove room: \(error)")
      }
    }
  }

structure.deleteRoom() ile boş bir odayı silmek için oda adının sağındaki çöp kutusunu tıklayın ve işlemi onaylayın. Yalnızca boş olan odaların silinebileceğini unutmayın.

4f129262ad67f564.png

Not: Boş bir oda oluşturmak için cihazı geri taşıyın.

6. Devreye alma

Not: Bu bölüm için bir Google hub ve Matter cihazı gerekir. Yapınızdaki Google Hub'ın internete bağlı ve erişilebilir olduğundan emin olun. Matter cihazınız yoksa bunun yerine Matter Virtual Device uygulamasını kullanmayı deneyin.

Matter cihazı ekleme

Commissioning API, uygulamanızın kullanıcının evine ve Google Hesabı'na yeni Matter cihazları eklemesine olanak tanır. Bu sayede, doğrudan uygulamanızda sorunsuz bir kurulum deneyimi sunabilirsiniz.

GoogleHomeAPISampleIOS/Commissioning/CommissioningManager.swift'te yorumu ve addMatterDevice()'teki uyarıyı kaldırın.

  /// TODO: add Matter Device
  /// Starts the Matter device commissioning flow to add the device to the user's home.
  /// - Parameters:
  ///   - structure: The structure to add the device to.
  ///   - add3PFabricFirst: Whether to add the device to a third party fabric first.
  public func addMatterDevice(to structure: Structure, add3PFabricFirst: Bool) {
    self.isCommissioning = true

    /// pass if it's 1p or 3p commissioning
    let userDefaults = UserDefaults(
      suiteName: CommissioningManager.appGroup)
    userDefaults?.set(
    add3PFabricFirst, forKey: CommissioningUserDefaultsKeys.shouldPerform3PFabricCommissioning)

    Task {
      do {
        try await structure.prepareForMatterCommissioning()
      } catch {
        Logger().error("Failed to prepare for Matter Commissioning: \(error).")
        self.isCommissioning = false
        return
      }

      // Prepare the Matter request by providing the ecosystem name and home to be added to.
      let topology = MatterAddDeviceRequest.Topology(
        ecosystemName: "Google Home",
        homes: [MatterAddDeviceRequest.Home(displayName: structure.name)]
      )
      let request = MatterAddDeviceRequest(topology: topology)

      do {
        Logger().info("Starting MatterAddDeviceRequest.")
        try await request.perform()
        Logger().info("Completed MatterAddDeviceRequest.")
        let commissionedDeviceIDs = try structure.completeMatterCommissioning()
        Logger().info("Commissioned device IDs: \(commissionedDeviceIDs).")
      } catch let error {
        structure.cancelMatterCommissioning()
        Logger().error("Failed to complete MatterAddDeviceRequest: \(error).")
      }

      self.isCommissioning = false
    }
  }

structure.prepareForMatterCommissioning() ile yeni bir oda oluşturmak için sol üst köşeye gidin ve "+" simgesini > Google Fabric'e Cihaz Ekle'yi seçin. Matter cihazını odanıza eklemek için MatterAddDeviceRequest kullanır. Oda ve cihaz adı seçildikten sonra cihaz "Cihazlar" ekranında gösterilir.

adf6cbb531787aaf.png f002bd6320bc480d.png

7. Otomasyon

Yapıdaki tüm otomasyonları görüntüleme

Alttaki gezinme çubuğunda Otomasyonlar'a dokunun. Bu komut, yapınızdaki tüm otomasyonları structure.listAutomations() ile listeler.

cc6d50f72f812c24.png

Not: Ev otomasyonu ayarlamadıysanız "Başlamak için otomasyon ekleyin" mesajını görürsünüz.

Otomasyon oluşturma

Cihaz ve Yapı API'leri hakkında bilgi sahibi olduğunuza ve yeni bir cihaz eklediğinize göre Otomasyon API'sini kullanarak yeni bir otomasyon oluşturmanın zamanı geldi.

GoogleHomeAPISampleIOS/ViewModel/Automation/AutomationsRepository.swift'te yorumu, uyarıyı ve lightAutomation()'teki boş otomasyonu kaldırın.

  /// TODO: create automation
  /// - Parameter devices: devices in current selected structure
  /// - Returns: the automation object to be created
  /// This automation will turn off the light after 5 seconds.
  public func lightAutomation(devices: Set<HomeDevice>) async throws -> any DraftAutomation {
    let light = devices.first { $0.name == "light2" }
    
    guard let light else {
      Logger().error("Unable to find light device with name light2")
      throw HomeError.notFound("No devices support OnOffLightDeviceType")
    }
    
    return automation(
      name: "Turn off light after 5 seconds",
      description:
        """
        Turns off light2 after it has been on for 5 seconds.
        """
    ) {
      let onOffStarter = starter(light, OnOffLightDeviceType.self, OnOffTrait.self)
      onOffStarter
      condition {
        onOffStarter.onOff.equals(true)
      }
      delay(for: Duration.seconds(5))
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.off()
      }
    }
  }

Işığı açtıktan beş saniye sonra kapatacak bir otomasyon oluşturmak için otomasyon görünümüne gidin ve "+ Ekle" düğmesini tıklayın. Ardından "Işığı 5 saniye sonra kapat"ı seçin. starter, condition ve action dahil olmak üzere otomasyon ayrıntıları gösterilir. structure.createAutomation() tarafından otomasyonu oluşturmak için "Kaydet"i tıklayın.

21c1f8ea2a29134b.png 4bd36f6ed9c5f6e9.png

Not: Kullanılabilen otomasyonlar, evinizdeki cihazlara bağlıdır. Kullanılabilir otomasyon görmüyorsanız ışık cihazınızı "ışık2" olarak yeniden adlandırmayı deneyin.

"Cihazlar" sekmesine dönüp "light2" adlı ışığı açın. Beş saniye sonra otomatik olarak kapanır.

Otomasyonun bileşenleri şunlardır:

  • Başlatıcı: Bu, otomasyonu başlatan bir etkinliktir. Bu örnekte, otomasyon OnOffTrait'te bir değişiklik olduğunda başlar.
  • Durum: Bu, başlatıcı cihazın belirli koşulları karşılayıp karşılamadığını kontrol eder. Bu durumda, ışık açıksa otomasyon yürütülür.
  • İşlem: Bu, yalnızca başlatıcı koşulları karşılıyorsa gerçekleştirmek istediğiniz otomasyondur. Koşullar karşılanırsa ışık söner.

Daha fazla örnek için Örnek otomasyonlar sayfasına göz atın.

Otomasyonu silme

Mevcut bir otomasyonu soldan kaydırarak ve çöp kutusu simgesine dokunarak yapınızdan kaldırdığınızda structure.deleteAutomation() yöntemi çağrılır.

dc678cd9e16f89a5.png

8. Tebrikler

Tebrikler! iOS için Home API'lerini kullanarak temel bir akıllı ev uygulaması oluşturdunuz.

Başardığınız İşlemler:

  • Başlatma: Home.connect() kullanarak uygulamanızı Google Home ekosistemine bağladınız.
  • İzinler: Ev verilerine erişmek için kullanıcı kimlik doğrulaması ve yetkilendirme işlemleri gerçekleştirilir.
  • Cihazlar ve Yapılar: home.rooms() ve home.devices() kullanılarak getirilen ve görüntülenen odalar ve cihazlar.
  • Cihaz Kontrolü: Özelliklerinde komutlar çağırarak bir OnOffPluginUnitDeviceType öğesinin durumunu değiştirme gibi uygulanmış cihaz etkileşimi.
  • Yapı Yönetimi: Yeni odalar (structure.createRoom()) oluşturma, cihazları odalar arasında taşıma (structure.move()) ve boş odaları silme (structure.deleteRoom()) işlevleri eklendi.
  • Devreye alma: Yeni Matter cihazları (MatterAddDeviceRequest) eklemek için SDK'nın devreye alma akışı entegre edildi.
  • Otomasyon: Bir yapı içinde otomasyonların nasıl listeleneceğini, oluşturulacağını (structure.createAutomation()) ve silineceğini (structure.deleteAutomation()) keşfetti.

Artık iOS'te zengin akıllı ev kontrol deneyimleri oluşturmak için Home API'lerinden nasıl yararlanacağınızı temel düzeyde anlamışsınızdır.

Sonraki Adımlar:

  • Örnek uygulamada sağlanan diğer cihaz türlerini (ışıklar, vantilatörler, panjurlar vb.) kontrol etmeyi keşfedin.
  • Çeşitli cihazlarda kullanılabilen farklı özellikler ve komutlar hakkında daha fazla bilgi edinin.
  • Farklı başlatıcılar, koşullar ve işlemler kullanarak daha karmaşık otomasyonlar oluşturmayı deneyin.
  • Daha gelişmiş özellikler ve ayrıntılar için Home API'leri belgelerine göz atın.

Tebrikler!