با استفاده از APIهای Home در iOS یک برنامه تلفن همراه بسازید

1. مقدمه

f154e30306882c74.png

API های Home چیست؟

API های Google Home مجموعه ای از کتابخانه ها را برای توسعه دهندگان فراهم می کند تا از اکوسیستم Google Home استفاده کنند. با API های Home، توسعه دهندگان می توانند برنامه هایی بسازند که به طور یکپارچه دستگاه های خانه هوشمند را راه اندازی و کنترل کنند.

3e11583c779a2cec.png

اجزای APIهای Home

API های Home از موارد زیر تشکیل شده اند:

  • Device & Structure APIs: تعامل با خانه کاربر. برنامه‌ها می‌توانند از این APIها برای خواندن اطلاعات مربوط به دستگاه‌ها، اتاق‌ها و سازه‌ها (به عنوان مثال، دمای فعلی ترموستات را ببینید) و دستگاه‌های کنترل (مثلاً تغییر نقطه تنظیم ترموستات) استفاده کنند.
  • راه اندازی API : دستگاه های جدید Matter را با حداقل تلاش وارد پارچه کنید.
  • Automation API : ایجاد، حذف، و پرس و جو خودکارهای در حال اجرا در خانه کاربر.

پیش نیازها

چیزی که یاد خواهید گرفت

  • نحوه ساخت یک برنامه iOS با استفاده از APIهای Home با بهترین شیوه ها.
  • نحوه استفاده از Device and Structure APIs برای نمایش و کنترل یک خانه هوشمند.
  • نحوه استفاده از Commissioning API برای افزودن دستگاه‌ها به اکوسیستم Google Home.
  • نحوه استفاده از Automation API برای ایجاد یک اتوماسیون اساسی.

2. خانه خود را راه اندازی کنید

دستگاه ها را آماده کنید

Google Home Playground انواع دستگاه‌های خانه هوشمند شبیه‌سازی شده را ارائه می‌دهد و برای کاوش در پتانسیل کامل APIهای Home توصیه می‌شود، به خصوص اگر تعداد محدودی دستگاه در خانه خود داشته باشید.

دستورالعمل‌ها را برای ورود به Google Home Playground و تکمیل پیوند حساب در برنامه Google Home دنبال کنید. پس از انجام این کار، باید بتوانید دستگاه‌ها را در تب «دستگاه‌ها» در برنامه Google Home مشاهده کنید.

c892afce113abe8f.png

3. راه اندازی

کد برنامه نمونه را دریافت کنید

با شبیه سازی کد منبع از GitHub شروع کنید:

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

دایرکتوری نمونه شامل دو شاخه start و finished برای این Codelab است.

  • start : کد شروع برای این پروژه که در آن تغییراتی را برای تکمیل Codelab ایجاد خواهید کرد.
  • finished : کد تکمیل شده برای این Codelab که برای بررسی کار شما استفاده می شود.

کد "شروع" را کاوش کنید

این نرم افزار کد را با جابجایی به شاخه start مخزن شبیه سازی شده خود شروع کنید:

git checkout start

این شاخه شامل کد شروع پروژه است. شما این کد را در سرتاسر Codelab تغییر خواهید داد تا عملکرد کامل را پیاده سازی کنید. برنامه نمونه Codelab ساختاری اساسی را ارائه می‌کند که در سوئیفت برای تعامل با Home APIs iOS SDK ساخته شده است. بیایید نگاهی گذرا به اجزای کلیدی در پروژه start بیندازیم:

  • Main Entry (GoogleHomeAPISampleIOSApp) : واقع در GoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift ، این نقطه ورود اصلی برنامه است. SDK را پیکربندی و مقداردهی اولیه می کند و رابط کاربری اصلی را تنظیم می کند.
  • Core Views (View/) :
    • MainView.swift : نمای اصلی پس از راه‌اندازی که شامل NavigationView اصلی است. انتخاب ساختار فعال Google Home را انجام می دهد و StructureView مربوطه را نمایش می دهد.
    • StructureView.swift : محتوای ساختار انتخاب شده فعلی را با استفاده از برگه ها برای جابجایی بین شبکه ای از دستگاه ها و لیست اتوماسیون ها نمایش می دهد. همچنین منوهایی را برای افزودن اتاق یا دستگاه فراهم می کند.
    • DeviceView.swift : نمایانگر کاشی تعاملی برای یک دستگاه واحد در شبکه StructureView است.
    • AutomationsView.swift : فهرستی از اتوماسیون های موجود را برای ساختار نشان می دهد و جهت ایجاد یا مشاهده جزئیات اتوماسیون را ارائه می دهد.
  • ViewModels (ViewModel/) : این کلاس ها حالت و منطق نماها را مدیریت می کنند.
    • AccountViewModel.swift : اتصال به شی Home را مدیریت می کند و وضعیت احراز هویت را مدیریت می کند.
    • MainViewModel.swift : فهرست اشیاء Structure موجود را مدیریت می کند و ساختار انتخاب شده را پیگیری می کند.
    • StructureViewModel.swift : نمایش اتاق ها و اشیاء DeviceControl را در ساختار انتخاب شده مدیریت می کند.
    • AutomationList.swift ، AutomationViewModel.swift ، و غیره: واکشی، نمایش، ایجاد و مدیریت اتوماسیون ها را کنترل می کند.
  • Device Controls (ViewModel/Device/) :
    • DeviceControl.swift : یک کلاس پایه برای نمایش دستگاه های قابل کنترل در رابط کاربری.
    • زیر کلاس‌های خاص ( LightControl.swift ، FanControl.swift ، OnOffPlugInUnitControl.swift و غیره): منطق UI، کنترل دستگاه و نقشه‌برداری حالت را برای انواع دستگاه‌های مختلف بر اساس ویژگی‌های آنها پیاده‌سازی کنید.
    • DeviceControlFactory.swift : مسئول ایجاد زیرکلاس DeviceControl مناسب برای یک HomeDevice معین است.
  • Commissioning (Commissioning/) :
    • CommissioningManager.swift : شامل منطق مدیریت جریان راه اندازی دستگاه Matter است.
  • Utilities & UX (Utils/, UX/, Storage/) : حاوی کد کمکی برای عناصر رابط کاربری (رنگ‌ها، ابعاد)، مدیریت خطا، ذخیره‌سازی داده‌ها ( SelectedStructureStorage.swift ) و سایر ابزارها.

در سرتاسر این نرم‌افزار، نظراتی مانند TODO یا بلوک‌های کد اظهارنظر شده و هشدارها را در پروژه start خواهید یافت. این بخش‌ها را علامت‌گذاری می‌کنند که در آن‌ها کد اضافه یا لغو نظر برای اجرای عملکرد مورد نیاز، با دنبال کردن مراحل ارائه‌شده، مشخص می‌شوند.

فایل های پیکربندی استقرار اپل را ایجاد کنید

برای پیکربندی App Attest، دستورالعمل‌های ایجاد فایل‌های پیکربندی استقرار Apple را دنبال کنید. توجه داشته باشید که پس از راه‌اندازی، برنامه فقط روی یک دستگاه واقعی قابل اجرا است، نه در شبیه‌ساز.

احراز هویت را تنظیم کنید

برای دریافت شناسه مشتری OAuth و فعال کردن APIهای Home، ابتدا وارد Google Cloud شوید و یک پروژه جدید ایجاد کنید یا یک پروژه موجود را انتخاب کنید. سپس، مراحل ارائه شده را برای تولید شناسه مشتری OAuth دنبال کنید و API های Home را فعال کنید و حساب خود را به لیست مجاز اضافه کنید.

SDK را تنظیم کنید

Home APIs iOS SDK را دریافت کنید و با مراجعه به دستورالعمل‌های راه‌اندازی ارائه شده در Set up the SDK، آن را پیکربندی کنید. به یاد داشته باشید که HOME_API_TODO_ADD_APP_GROUP با گروه برنامه خود جایگزین کنید.

پروژه را بسازید و اجرا کنید

پس از ساخت و اجرای پروژه با شاخه start ، یک گفتگوی TODO و یک صفحه نمایش "ورود به سیستم الزامی است" ظاهر می شود. تعامل Home APIs در بخش‌های بعدی پیاده‌سازی می‌شود.

bd56b7080037e38a.png9c0f08a3f4197a77.png

توجه : با جستجوی پروژه برای متن نمایش داده شده در گفتگو، کدی را که باید اصلاح شود پیدا کنید. به عنوان مثال، عبارت "TODO: Initialize Home" را جستجو کنید.

4. مقداردهی اولیه

خانه را راه اندازی کنید

قبل از استفاده از هر یک از API های Home برای iOS، باید Home در برنامه خود مقداردهی اولیه کنید. Home ورودی سطح بالای SDK است و دسترسی به تمام موجودات در ساختار کاربر را فراهم می کند. هنگام درخواست همه موجودیت‌ها از یک نوع خاص، API یک شی Query را برمی‌گرداند که به شما امکان می‌دهد نحوه دریافت نتایج را انتخاب کنید. در GoogleHomeAPISampleIOS/Accounts/AccountViewModel.swift ، نظر و هشدار را در connect() حذف کنید تا مقداردهی اولیه خانه را پیاده سازی کنید.

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

اجازه استفاده از APIهای Home

هنگامی که برنامه را اجرا می کنید صفحه رضایت ظاهر می شود. ساختار Google Home را انتخاب کنید و حسابی را انتخاب کنید که در لیست مجوزهای پروژه Google Cloud شما قرار دارد.

47310f458c0094d9.png4a571dbd9979a88c.pnge29c75891a3a67af.png

5. دستگاه ها و سازه ها

اتاق ها و دستگاه ها را دریافت کنید

در GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift ، نظر و هشدار را در getRoomsAndDevices() حذف کنید تا اتاق‌ها و دستگاه‌های موجود در ساختار انتخاب‌شده را به ترتیب با home.rooms() و home.devices() دریافت کنید.

  /// 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() ابتدا اطمینان حاصل می کند که دستگاه ها در یک اتاق هستند قبل از اینکه دستگاه ها با استفاده از DeviceControl و DeviceControlFactory به عنوان HomeDevices تعامل داشته باشند.

4c677c4c294e67ca.png

توجه : اگر دستگاه شما در DeviceControlFactory فهرست نشده باشد، به عنوان "Unsupported" نمایش داده می شود. برای کسب اطلاعات بیشتر در مورد دستگاه هایی که پشتیبانی می شوند، به صفحه انواع دستگاه های پشتیبانی شده در iOS مراجعه کنید.

تعامل با یک دستگاه

هنگام ضربه زدن یا سر خوردن روی دستگاه ها، پریز outlet1 در ابتدا غیر فعال است. برای فعال کردن تعامل با آن، GoogleHomeAPISampleIOS/ViewModel/Device/OnOffPlugInUnitControl.swift را پیدا کنید و نظر و هشدار را در تابع primaryAction() حذف کنید.

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

تابع primaryAction() که در کلاس OnOffPlugInUnitControl یافت می‌شود، وضعیت روشن/خاموش یک دوشاخه هوشمند یا هر دستگاهی را که توسط OnOffPluginUnitDeviceType نشان داده می‌شود تغییر می‌دهد.

نمونه‌های کنترل دستگاه اضافی در GoogleHomeAPISampleIOS/ViewModel/Device موجود است.

یک اتاق جدید ایجاد کنید

Structure API ایجاد و حذف اتاق ها و همچنین انتقال دستگاه ها بین اتاق ها را امکان پذیر می کند.

در GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift ، نظر و هشدار را در addRoom() حذف کنید.

  /// 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() ، به گوشه سمت چپ بالا بروید و نماد "+" > Add Room را انتخاب کنید. نام اتاق جدید خود را وارد کنید و روی «ایجاد اتاق» کلیک کنید. اتاق جدید پس از چند ثانیه ظاهر می شود.

b122ae6642b7da1c.pnga45f785e1d51938e.png7753b56cbdcff8d6.png

دستگاه را به اتاق دیگری منتقل کنید

در GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift ، نظر و هشدار را در moveDevice() حذف کنید.

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

برای جابجایی دستگاه با structure.move() آن را به مدت طولانی فشار دهید، «Move to Another Room» را انتخاب کنید و اتاق جدید را انتخاب کنید.

f9627592af44163d.pngfd126fabb454f2bf.png813e1e23e50cd9f6.png

یک اتاق خالی را حذف کنید

در GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift ، نظر و هشدار را در removeRoom() حذف کنید.

  /// 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() ، روی نماد سطل زباله در سمت راست نام اتاق کلیک کنید و عمل را تأیید کنید. توجه داشته باشید که فقط اتاق هایی که خالی هستند قابل حذف هستند.

4f129262ad67f564.png

توجه : برای ایجاد یک اتاق خالی، دستگاه را به عقب ببرید.

6. راه اندازی

توجه : این بخش به یک هاب Google و یک دستگاه Matter نیاز دارد. مطمئن شوید که هاب گوگل در ساختار شما آنلاین و قابل دسترسی است. اگر دستگاه Matter ندارید، به جای آن از برنامه Matter Virtual Device استفاده کنید.

یک دستگاه Matter اضافه کنید

Commissioning API به برنامه شما امکان می‌دهد دستگاه‌های جدید Matter را به خانه و حساب Google کاربر اضافه کند. این یک تجربه راه اندازی یکپارچه را مستقیماً در برنامه شما فراهم می کند.

در GoogleHomeAPISampleIOS/Commissioning/CommissioningManager.swift ، نظر و هشدار را در addMatterDevice() حذف کنید.

  /// 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() ، به گوشه سمت چپ بالا بروید و نماد «+» > Add Device to Google Fabric را انتخاب کنید. از MatterAddDeviceRequest برای اضافه کردن دستگاه Matter به اتاق شما استفاده می کند. پس از انتخاب نام اتاق و دستگاه، دستگاه در صفحه «دستگاه ها» نمایش داده می شود.

adf6cbb531787aaf.pngf002bd6320bc480d.png

7. اتوماسیون

مشاهده تمام اتوماسیون های موجود در ساختار

روی Automations در نوار ناوبری پایین ضربه بزنید. تمام اتوماسیون های ساختار شما را با structure.listAutomations() فهرست می کند.

cc6d50f72f812c24.png

توجه : اگر هیچ اتوماسیون خانگی را راه‌اندازی نکرده‌اید، پیام «افزودن یک اتوماسیون برای شروع کار» را مشاهده خواهید کرد.

یک اتوماسیون ایجاد کنید

اکنون که با Device and Structure API ها و افزودن یک دستگاه جدید آشنا شدید، وقت آن است که یک اتوماسیون جدید با استفاده از Automation API ایجاد کنید.

در GoogleHomeAPISampleIOS/ViewModel/Automation/AutomationsRepository.swift ، نظر، هشدار و اتوماسیون خالی را در lightAutomation() حذف کنید.

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

برای ایجاد اتوماسیونی که چراغ را پنج ثانیه پس از روشن شدن خاموش می کند، به نمای اتوماسیون بروید و روی دکمه " + افزودن " کلیک کنید. سپس گزینه Turn off light after 5 seconds را انتخاب کنید. جزئیات اتوماسیون، از جمله starter ، condition و action ظاهر می‌شوند. برای ایجاد اتوماسیون توسط structure.createAutomation() روی " ذخیره " کلیک کنید.

21c1f8ea2a29134b.png4bd36f6ed9c5f6e9.png

توجه : اتوماسیون های موجود به دستگاه های موجود در خانه شما بستگی دارد. اگر هیچ اتوماسیون موجودی نمی‌بینید، نام دستگاه نور خود را به "light2" تغییر دهید.

به تب «دستگاه ها» برگردید و چراغی به نام «light2» را روشن کنید. پس از پنج ثانیه به طور خودکار خاموش می شود.

اجزای یک اتوماسیون عبارتند از:

  • شروع کننده: این رویدادی است که اتوماسیون را آغاز می کند. در این مثال، زمانی که تغییری در OnOffTrait ایجاد شود، اتوماسیون شروع می‌شود.
  • شرایط: این بررسی می کند که آیا دستگاه استارت شرایط خاصی را برآورده می کند. در این حالت، اگر چراغ روشن باشد، اتوماسیون اجرا می شود.
  • اقدام: این اتوماسیونی است که می‌خواهید انجام دهید، اما تنها در صورتی که استارتر الزامات را برآورده کند. اگر شرایط فراهم باشد، چراغ خاموش می شود.

برای مثال‌های بیشتر، صفحه نمونه اتوماسیون‌ها را بررسی کنید.

یک اتوماسیون را حذف کنید

متد structure.deleteAutomation() زمانی فراخوانی می شود که روی یک اتوماسیون موجود به چپ بکشید و روی نماد سطل زباله ضربه بزنید تا آن را از ساختار خود حذف کنید.

dc678cd9e16f89a5.png

8. تبریک می گویم

تبریک می گویم! شما با موفقیت یک برنامه اصلی خانه هوشمند را با استفاده از Home API برای iOS ساخته اید.

آنچه شما انجام داده اید :

  • مقداردهی اولیه : برنامه خود را با استفاده از Home.connect() به اکوسیستم Google Home متصل کنید.
  • مجوزها : احراز هویت کاربر و مجوز برای دسترسی به داده های خانه.
  • Devices & Structures : اتاق‌ها و دستگاه‌هایی که با استفاده از home.rooms() و home.devices() واکشی و نمایش داده می‌شوند.
  • Device Control : تعامل دستگاه اجرا شده، مانند تغییر وضعیت OnOffPluginUnitDeviceType با فراخوانی دستورات روی ویژگی‌های آن.
  • مدیریت ساختار : قابلیت اضافه شده برای ایجاد اتاق های جدید ( structure.createRoom() )، انتقال دستگاه ها بین اتاق ها ( structure.move() ) و حذف اتاق های خالی ( structure.deleteRoom() ).
  • راه اندازی : جریان راه اندازی SDK را برای افزودن دستگاه های جدید Matter ( MatterAddDeviceRequest ) یکپارچه کرد.
  • Automation : نحوه فهرست کردن، ایجاد ( structure.createAutomation() ) و حذف ( structure.deleteAutomation() ) اتوماسیون ها در یک ساختار را بررسی کرد.

اکنون درک اساسی از نحوه استفاده از APIهای Home برای ایجاد تجربیات غنی کنترل خانه هوشمند در iOS دارید.

مراحل بعدی :

  • کنترل انواع دیگر دستگاه های ارائه شده در برنامه نمونه (چراغ ها، پنکه ها، پرده ها و غیره) را کاوش کنید.
  • در ویژگی ها و دستورات مختلف موجود برای دستگاه های مختلف عمیق تر شوید.
  • با استفاده از شروع، شرایط و اقدامات مختلف، اتوماسیون‌های پیچیده‌تری ایجاد کنید.
  • برای جزئیات و ویژگی‌های پیشرفته‌تر ، با اسناد Home APIs مشورت کنید.

آفرین!