В этой статье мы расскажем как собирали свое первое WebRTC-приложение для iOS и размещали его в App Store, с чем пришлось при этом столкнуться и что из этого вышло.

Зачем

Мы занимаемся тем, что пилим WebRTC медиасервер и три SDK для работы с сервером: Web, Android, iOS.

С каждым SDK идет несколько примеров. Например для iOS SDK есть 11 примеров приложений, исходники которых доступны здесь.

Разработчик берет пример по ссылке, убеждается, что пример работает и уже после этого собирает пример из исходников и начинает его видоизменять / встраивать SDK в свое приложение для работы с потоковым видео.

Такой подход, как «посмотрел демку — собрал — внедрил» прекрасно работает практически везде, но не с Apple. Вы не можете сбросить ссылку любому желающему протестировать ваше приложение до тех пор, пока оно не будет опубликовано в App Store.

Возможно мы пишем здесь простые истины, которые уже давно пройдены всеми iOS разработчиками и издателями, но для нас это было небольшим сюрпризом.

Без публикации в App Store никто не сможет установить ваше приложение, пока UDID вашего устройства (iPhone) не будет внесен в список.

Т.е. Для того, чтобы дать потестировать приложение кому-то, вы должны сначала попросить этого кого-то дать вам UDID устройства, внести его в список на сайте developer.apple.com, пересобрать приложение в Xcode, выложить, и только после этого давать ссылку на скачивание этому конкретному человеку.

Такой метод распространения называется adhoc. В принципе это удобно, внутри команды — один раз вписать всех разработчиков и тестировщиков. Но это жутко неудобно, если вам нужно предоставить доступ к тестовому демо-приложению всем желающим.

В результате, было принято решение опубликовать наше демо-приложение в App Store, дабы дать всем желающим возможность его потестить и понять как оно работает, не затрачивая времени на сборку из сурсов.

Приложение

В качестве пилотного приложения взяли Two Way Streaming, которое выглядит так:

two-way-streaming

Это простое приложение позволяет делать всего три вещи:

  • Подключиться к серверу.
  • Захватить видеопоток с камеры и отправить на сервер.
  • Забрать видеопоток с сервера и проиграть на дисплее справа.

Приложение представляет собой фейковый видеочат, в котором вы можете отправить видеопоток со своего iPhone и тут же посмотреть видеопоток другого человека. Т.е. При желании, приложение достаточно легко переделывается в видеочат на подобие Chatroulette.

Исходный код приложения доступен по этой ссылке и требует WCS iOS SDK в качестве зависимости. Процесс сборки приложения и всех остальных примеров, с вытягиванием сурсов, описан на странице SDK. Поэтому на сборке мы заострять внимание не будем, а перейдем сразу к описанию публикации в App Store.

Публикация

1. Начнем с самого главного — с иконок. Делаем иконки с максимальным размером 1024×1024 и добавляем в Xcode.

publish

С иконками вышла незадача, т.к. самую крупную иконку решили сделать немного другой и по этой причине наше приложение было впервые отклонено, но об этом позже.

2. Создаем App Record — заполняем карточку приложения.

Заполнение формы процесс не сложный., поэтому предлагаем ознакомиться с ним на сайте Apple.

3. Добавляем скриншоты.

Так как, у нас демо-приложение, мы не стали долго раздумывать и просто подфотошопили скриншоты под требуемые размеры:

  • 5.5-Inch Display (1242 x 2208)
  • 12.9-Inch Display (2048 x 2732)

4. Загружаем сборку в iTunes Connect

Это можно сделать с использованием Application Loader для выгрузки приложения в iTunes Connect.

1) Открываем Xcode меню и кликаем Open Developer Tool / Application Loader
2) Логинимся со своим Apple ID
3) Нажимаем «Deliver Your App».
4) Выбираем приложение ipa, кликаем Send и ждем окончания загрузки.

5. Отправляем загруженное приложение на модерацию в iTunes Connect Здесь нужно будет ответить на три вопроса. Немного погуглив, мы вписали No во все три ответа:

Is your app designed to use cryptography or does it contain or incorporate cryptography? No
Does your app contain, display, or access third-party content? No
Does this app use the Advertising Identifier (IDFA)? No

На самом деле, наше приложение активно использует шифрование, а именно AES и HTTPS / Websocket. Но гугл дал ответ о том, что это про кастомное шифрование, выходящее за рамки стандартных технологий AES, HTTPS. Поэтому поставили No, как и для двух остальных вопросов.

В результате приложение ушло на модерацию, а мы занялись своими делами.

Траблы

После того, как приложение отправилось на модерацию, на почту может прийти нотификация об отклонении сборки — Binary Rejected.

1. Первый реджект не заставил себя долго ждать и буквально в этот же день пришло сообщение.

We have started the review of your app, but we are not able to continue because we need access to a video that demonstrates your app in use on an iOS device.

Пришлось записать короткое демонстрационное видео и выложить его на YouTube. Видеоролик записан с экрана мобильного устройства и показывает как функционирует данное мобильное приложение.

2. Второй трабл, как мы и писали, был связан с иконкой.

Мы установили в качестве крупной иконки такую:

2-way

А в качестве мелких иконок такую:

icon-2-way

Оказывается так делать нельзя, потому что вводит пользователей в заблуждение.

We noticed the app icon displayed on the device and the large icon displayed on the App Store do not sufficiently match, which makes it difficult for users to find the app they just downloaded.

3. Разобраться с иконками и записать видео для демонстрации приложения было делом недолгим, и в этот же день мы снова отправили приложение на модерацию.

Следующий реджект пришел через четыре дня и был, с первого взгляда, более непонятным:

Your app declares support for audio in the UIBackgroundModes key in your Info.plist but did not include features that require persistent audio.

The audio key is intended for use by apps that provide audible content to the user while in the background, such as music player or streaming audio apps. Please revise your app to provide audible content to the user while the app is in the background or remove the «audio» setting from the UIBackgroundModes key.

Здесь утверждается, что наше приложение декларирует поддержку аудио в UIBackgroundModes, но при этом не имеет фич, которые бы требовали воспроизведения аудио в бэкграунде. Имеется в виду, что если при работе приложения переключиться на другое приложение либо нажать кнопку Home, то аудио будет продолжать играть, и это называется audio in the UIBackgroundModes, т.е. функция, актуальная например для воспроизведения музыки.

Чтобы не спорить с модераторами Apple и не доказывать, что наше приложение Two Way Streaming тоже способно играть аудио / видеопотоки в бэкграунде, мы просто отключили декларацию этой фичи.

4. Аналогичное требование, касающиеся работы в UIBackgroundModes было по функции VoIP. Наше приложение декларировало поддержку VoIP в бэкграунде, а модераторы заподозрили наше приложение в отсутствие VoIP.

Your app declares support for VoIP in the UIBackgroundModes key in your Info.plist, but it does not include any Voice over IP services.

To resolve this issue, please revise your app to either add VoIP features or remove the «voip» setting from the UIBackgroundModes key.

Формулировка «revise your app to add VoIP features» нам не очень понравилась, т.к. пришлось бы доказывать и показывать модераторам, что у нас есть VoIP функции и им необходимо работать в UIBackgroundModes. Поэтому чтобы ускорить процесс, мы отключили VoIP in UIBackgroundModes, пересобрали приложение и снова отправили на модерацию.

Отключение UIBackgroundModes

Для отключения, мы проводили все манипуляции с файлом Info.plist, который для adhoc-раздачи выглядел так.





        method
        ad-hoc


После подготовки его для публикации в App Store, конфиг стал выглядеть так.





	CFBundleDevelopmentRegion
	en
	CFBundleExecutable
	$(EXECUTABLE_NAME)
	CFBundleIdentifier
	$(PRODUCT_BUNDLE_IDENTIFIER)
	CFBundleInfoDictionaryVersion
	6.0
	CFBundleName
	$(PRODUCT_NAME)
	CFBundlePackageType
	APPL
	CFBundleShortVersionString
	1.0
	CFBundleSignature
	????
	CFBundleVersion
	1
	LSRequiresIPhoneOS
	
	NSCameraUsageDescription
	Need camera access for publishing stream with video
	NSMicrophoneUsageDescription
	Need microphone for publishing stream with audio
	UIBackgroundModes
	
		audio
		voip
	
	UILaunchStoryboardName
	LaunchScreen
	UIMainStoryboardFile
	Main
	UIRequiredDeviceCapabilities
	
		armv7
	
	UISupportedInterfaceOrientations
	
		UIInterfaceOrientationPortrait
		UIInterfaceOrientationLandscapeLeft
		UIInterfaceOrientationLandscapeRight
	
	UISupportedInterfaceOrientations~ipad
	
		UIInterfaceOrientationPortrait
		UIInterfaceOrientationPortraitUpsideDown
		UIInterfaceOrientationLandscapeLeft
		UIInterfaceOrientationLandscapeRight
	


И сейчас, после удаления UIBackgroundModes, конфиг имеет такой вид:





	CFBundleDevelopmentRegion
	en
	CFBundleExecutable
	$(EXECUTABLE_NAME)
	CFBundleIdentifier
	$(PRODUCT_BUNDLE_IDENTIFIER)
	CFBundleInfoDictionaryVersion
	6.0
	CFBundleName
	$(PRODUCT_NAME)
	CFBundlePackageType
	APPL
	CFBundleShortVersionString
	1.0
	CFBundleSignature
	????
	CFBundleVersion
	1.1
	LSRequiresIPhoneOS
	
	NSCameraUsageDescription
	Need camera access for publishing stream with video
	NSMicrophoneUsageDescription
	Need microphone for publishing stream with audio
	UIBackgroundModes
	
	UILaunchStoryboardName
	LaunchScreen
	UIMainStoryboardFile
	Main
	UIRequiredDeviceCapabilities
	
		armv7
	
	UISupportedInterfaceOrientations
	
		UIInterfaceOrientationPortrait
		UIInterfaceOrientationLandscapeLeft
		UIInterfaceOrientationLandscapeRight
	
	UISupportedInterfaceOrientations~ipad
	
		UIInterfaceOrientationPortrait
		UIInterfaceOrientationPortraitUpsideDown
		UIInterfaceOrientationLandscapeLeft
		UIInterfaceOrientationLandscapeRight
	

Ура

Через пару дней пришло сообщение о том, что наше приложение заапрувили и теперь оно имеет статус Ready For Sale и скоро появится в App Store. The following app has been approved and the app status has changed to Ready for Sale: App Name: TwoWayStreaming App Version Number: 1.0 App Type: iOS В результате публикация приложения заняла 1 неделю и потребовала корректировки следующих проблем:

  • Крупная иконка не должна отличаться от мелких рисунком
  • Должно быть обязательно добавлено демонстрационное видео, по которому видно как работает приложение.
  • Приложение должно явно показывать, что для его работы требуется воспроизведение аудио в бэкграунде, либо эта функция audio in the UIBackgroundModes должна быть отключена.
  • Приложение должно явно показывать, что для его работы требуется использование микрофона бэкграунде, либо эта функция VoIP in the UIBackgroundModes должна быть отключена.

На данный момент приложение доступно в App Store по этой ссылке: https://appsto.re/ru/r1MEjb.i Теперь любой желающий сможет установить апп и провести тесты. Надеемся, что эта статья поможет при публикации вашего собственного приложения с аудио и видео функциями и ваше приложение попадет в App Store намного быстрее.

Ссылки

Two Way Streaming for iOS — демо приложение Live-стриминга для iOS
Source — исходный код

Two Way Streaming for Web — тоже самое приложение для Web
Source — исходный код

Two Way Streaming for Android — тоже самое приложение для Android
Source — исходный код

Web Call Server — WebRTC сервер, через который работает приложение Two Way Streaming
WCS iOS SDK — описание процесса сборки примеров в Xcode для iOS.

Подборка ссылок на iTunes Connect

Работа с иконками

iTunes Connect Properties App Distribution Guide, Adding App Icons

Создание карточки приложения (App Record)

iTunes Connect Developer Help, Add an app to your account
iTunesConnect_Guide, Creating iTunes Connect Record for an App
iTunes Connect Properties

Требования к скриншотам

Screenshot Properties

Загрузка билда приложения на iTunes Connect

App Distribution Guide, Uploading Your App to iTunes Connect
Xcode Help, Upload an app to iTunes Connect
Upload your application binary files with Application Loader