Розробникам-початківцям: маленька хитрість для публікації в App Store

У коментарях до минулої статті, присвяченій міфам і реаліям роботи з App Store, висловилося досить багато читачів, додатки яких з тих чи інших причин відхилялися. Це навело мене на думку розповісти про один спосіб, який допомагає обійти суворих перевіряючих AppStore. Нижче я коротко опишу суть цього «лайфхака» з поясненнями і прикладами коду.


Популярна причина відмови в публікації - використання непублічного API (пункт 2.5 Apple Review Guidelines). Перевірити, чи використовує ваша програма приватні функції, можна, наприклад, за допомогою такої утиліти: http://www.chimpstudios.com/appscanner/


Проект, на жаль, нещодавно перестав підтримуватися, але місцями ще актуальний. Перевіритися варто всім, навіть якщо ви добропорядний розробник і жодного разу не чули імені Erica Sadun. Проблема може бути у ваших самостійно реалізованих методах: якщо назва будь-якого з них збігається з непублічним системним методом, додаток буде відхилено за тим же пунктом 2.5 ARG.

На мій погляд, можна виділити два великих класи завдань, для вирішення яких використовується непублічне API:

  1. додавання в iOS неіснуючої функціональності (робота на пряму з файловою системою, захоплення екрану тощо)
  2. кастомізація стандартних елементів управління (Apple до iOS 5 надавала дуже обмежені можливості налаштування стандартних елементів управління)

Додаткам з пункту 1 не бачити публікації в App Store, навіть якщо перевірка на приватні функції буде пройдена, оскільки з опису програми очевидно, що заборонені технології все ж використовуються. Другий випадок більш цікавий, адже можна реалізувати власні елементи управління, схожі на системні, але «з блекджеком і»..., тобто кастомізовані. Це завдання досить складне і трудовитратне, особливо якщо елемент управління активно використовує анімацію.

Припустимо, що наше завдання - написати додаток з підтримкою iOS 4 і вище, і реалізувати в ньому перемикач помаранчевого кольору, як в iOS Settings - Airplane Mode Switch:

Наступний код дозволить зробити, що потрібно:

Але setAlternceColors - непублічний метод, він не оголошений в офіційному описі UISwitch. Використання цього методу виявляється звичайним strings і тягне за собою відмову в публікації в App Store. Для маскування використання непублічного методу можна скористатися можливостями Objective-C Runtime, тобто не надсилати повідомлення об'єкту, а викликати відповідну функцію, знайдену по селектору. Тепер про це детальніше:


  1. Оголошуємо ім'я повідомлення setAlternceColors як складене з частин слів:
  2. Перебираємо методи класу UISwitch, поки не знайдемо покажчик на метод, який на ім'я збігається з setAlternceColors:
  3. Викликаємо функцію у відповідного об'єкта (у нашому випадку це археолог Switch), використовуючи селектор з п.2 і параметри, які потрібно використовувати. У нашому випадку це YES, як і в самому першому прикладі коду:

Тим самим отримуємо, що приватний метод не зустрічається цілим словом в ASCII рядках бінарного файлу (якраз те, що показує strings) і не може бути виявлений системами пошуку непублічних API-викликів.

На закінчення хочу нагадати, що перед використанням даного методу - і завжди перед використанням хитрощів і обхідних шляхів - потрібно спробувати зрозуміти, навіщо обмеження були встановлені і чи варто взагалі їх обходити? Не виключено, що поточні обмеження мають цілком зрозумілі причини.

COM_SPPAGEBUILDER_NO_ITEMS_FOUND