← назад к разделу

Если вы делаете приложение на основе веба и хотите выйти на iOS — вы столкнётесь с WKWebView, ограничениями Safari и правилами App Store. Эта статья объясняет с нуля, почему iOS устроена именно так и что это значит на практике.

Что такое WKWebView и зачем он нужен

Когда нативное iOS-приложение хочет показать веб-контент, оно использует встроенный компонент — WKWebView. Это «окно браузера» внутри приложения: он рендерит HTML, исполняет JavaScript и обрабатывает CSS.

Важная особенность iOS: все браузеры на платформе обязаны использовать один и тот же движок — WebKit. Safari, Chrome, Firefox на iPhone — внутри все работают на WebKit. Это означает, что поведение вашего веб-приложения внутри нативной обёртки будет таким же, как в Safari той же версии iOS. Никаких сюрпризов от «другого движка».

(С iOS 17.4 Apple разрешила альтернативные движки в Евросоюзе, но это касается только браузеров, не нативных обёрток.)

Capacitor на iOS работает именно поверх WKWebView. Собранная веб-сборка кладётся в нативный проект и загружается в WKWebView с локального origin. Мост между JavaScript и нативным кодом даёт доступ к нативным API через плагины.

Что iOS ограничивает для веба

iOS ограничивает веб строже, чем Android. Это главная причина, почему чистый PWA на iPhone — не лучшая ставка, если нужны расширенные возможности.

Хранилище. localStorage и sessionStorage ограничены примерно 5 МБ на origin. Общая квота для хранилища встроенного контента — порядка 15% дискового пространства. При нехватке места WebKit может вытеснить данные приложения без предупреждения.

Фоновый режим. Service Worker и фоновое выполнение в standalone-режиме работают ограниченно. Медиа и геолокация приостанавливаются, когда приложение уходит в фон.

Нативные возможности. Значительная часть push-уведомлений, фоновых задач и системных интеграций недоступна вебу напрямую.

Обёртка через WKWebView эти лимиты движка не снимает — движок тот же. Но поверх неё можно подключить нативный слой и добрать недостающее через плагины.

Сборка под iOS

Сборка под iOS требует аккаунта Apple Developer: подпись (signing) и provisioning profile обязательны даже для запуска на физическом устройстве.

С Capacitor поток выглядит так:

npm run build
npm install @capacitor/ios
npx cap add ios
npx cap sync
npx cap open ios

npx cap sync копирует собранную веб-сборку в нативный проект и обновляет зависимости. npx cap open ios открывает .xcworkspace в Xcode, где задаются bundle identifier, команда подписи и target устройства.

Базовое требование Capacitor — iOS 15+ и актуальная версия Xcode.

Отладка в Safari Web Inspector. В релизных сборках отладка по умолчанию отключена. Чтобы подключить Safari Web Inspector к релизной сборке во время тестирования:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'ru.example.app',
  appName: 'Example',
  webDir: 'dist',
  ios: {
    webContentsDebuggingEnabled: true,
  },
};

export default config;

В отладочных сборках инспекция включена автоматически. В финальном релизе флаг оставлять не нужно.

App Store и гайдлайн 4.2

Здесь кроется главная сложность для web-first-приложений. App Store Review Guideline 4.2 (minimum functionality) требует, чтобы приложение давало пользователю нативную ценность — а не было просто оболочкой вокруг сайта.

Ревьюер отклонит приложение с формулировкой «не отличается от веб-сёрфинга», если оно целиком сводится к WKWebView с тем же содержимым, что и мобильный браузер. Это не теоретический риск — это самая частая причина отказа для web-first-обёрток.

Чтобы пройти проверку, приложение должно давать что-то, чего браузер не даёт:

  • push-уведомления;
  • доступ к нативным функциям — камера, биометрия, файлы, системный обмен;
  • офлайн-режим с кешем данных;
  • нативная навигация и поведение на уровне системы.

Если ни одного из этих отличий нет — честнее остаться PWA и не идти в App Store.

TestFlight

До публичного релиза сборку раздают через TestFlight — систему бета-тестирования Apple. Процесс такой:

  1. Загружаете сборку в App Store Connect.
  2. Внутренним тестировщикам (до 100 человек из команды) она доступна почти сразу.
  3. Внешним тестировщикам (до 10 000 человек, по приглашению или публичной ссылке) — после прохождения beta-ревью.

Первая сборка версии требует полного ревью; последующие — нет. TestFlight позволяет проверить web-first-обёртку на реальных устройствах и разных версиях iOS до встречи с ревьюером App Store.

Коротко

  • WKWebView — единственный движок для веб-контента на iOS; все браузеры в системе используют WebKit.
  • Веб на iOS ограничен сильнее Android: лимиты хранилища, слабый фоновый режим, меньше нативных API.
  • Обёртка через Capacitor даёт нативный слой поверх тех же ограничений WKWebView, но открывает доступ к платформе через плагины.
  • Сборка требует Xcode и аккаунта Apple Developer; базовый поток: cap sync → Xcode → подпись → архив.
  • Гайдлайн 4.2 отклоняет приложения, которые ничем не отличаются от открытия сайта в браузере.
  • Нативная ценность для прохождения ревью: push, камера, биометрия, офлайн, нативная навигация.
  • TestFlight — обязательный шаг перед публичным релизом: бета-тест на реальных устройствах.

Что почитать дальше

  • Мобильная стратегия: PWA, обёртка или нативное — с чего начать выбор подхода.
  • Capacitor: мост между вебом и нативом — как работает обёртка изнутри.
  • Android и TWA — как устроена та же задача на Android.
  • Когда нужен нативный код — граница, за которой обёртки уже не хватает.