Каков ваш опыт разработки приложений для Apple Watch с WatchKit?

«Каков ваш опыт разработки приложений для Apple Watch с WatchKit?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

WatchKit — фреймворк для разработки приложений и осложнений (complications) для watchOS. Имеет существенные отличия от UIKit из-за ограничений устройства.

Архитектура приложения:

  1. WatchKit App — интерфейс (storyboard или код)
  2. WatchKit Extension — логика приложения (запускается на iPhone)
  3. Complications — виджеты на циферблате

Основные компоненты:

import WatchKit

// 1. Контроллеры
class InterfaceController: WKInterfaceController {
    @IBOutlet weak var label: WKInterfaceLabel!
    @IBOutlet weak var button: WKInterfaceButton!

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        label.setText("Hello Watch!")
        button.setTitle("Нажми")
    }

    @IBAction func buttonTapped() {
        pushController(withName: "DetailController", context: nil)
    }
}

// 2. Таблицы
class TableController: WKInterfaceController {
    @IBOutlet weak var table: WKInterfaceTable!

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        let items = ["Item 1", "Item 2", "Item 3"]

        table.setNumberOfRows(items.count, withRowType: "RowController")

        for (index, item) in items.enumerated() {
            if let row = table.rowController(at: index) as? RowController {
                row.label.setText(item)
            }
        }
    }
}

Обмен данными с iPhone:

import WatchConnectivity

class ConnectivityManager: NSObject, WCSessionDelegate {
    static let shared = ConnectivityManager()
    private let session = WCSession.default

    func setup() {
        if WCSession.isSupported() {
            session.delegate = self
            session.activate()
        }
    }

    // Отправка сообщения
    func sendMessage(_ message: [String: Any]) {
        if session.isReachable {
            session.sendMessage(message, replyHandler: nil, errorHandler: { error in
                print("Ошибка отправки: (error.localizedDescription)")
            })
        } else {
            // Использовать transferUserInfo для фоновой передачи
            session.transferUserInfo(message)
        }
    }
}

Особенности и ограничения watchOS:

  • Нет UIKit — только WatchKit компоненты
  • Ограниченная память — ~50-100MB в зависимости от модели
  • Энергоэффективность — короткое время работы (15-70 секунд)
  • Нет многозадачности — одно активное приложение

Фоновые задачи:

// 1. Background App Refresh
WKApplication.shared().scheduleBackgroundRefresh(
    withPreferredDate: Date().addingTimeInterval(3600),
    userInfo: nil
) { error in
    if let error = error {
        print("Ошибка планирования: (error)")
    }
}

// 2. Обработка в ExtensionDelegate
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
    for task in backgroundTasks {
        if let refreshTask = task as? WKApplicationRefreshBackgroundTask {
            // Выполнить обновление данных
            scheduleNextRefresh()
            refreshTask.setTaskCompletedWithSnapshot(false)
        }
    }
}

Лучшие практики:

  • Минимизируйте использование памяти
  • Оптимизируйте загрузку данных (пагинация, кэширование)
  • Используйте Complications для быстрого доступа
  • Тестируйте на реальных устройствах (симулятор не отражает все ограничения)