В комментариях к прошлой статье, посвященной мифам и реалиям работы с App Store, высказалось достаточно много читателей, приложения которых по тем или иным причинам отклонялись. Это навело меня на мысль рассказать об одном способе, который помогает обойти строгих проверяющих AppStore. Ниже я вкратце опишу суть этого «лайфхака» с пояснениями и примерами кода.
Популярная причина отказа в публикации – использование непубличного API (пункт 2.5 Apple Review Guidelines). Проверить, использует ли ваше приложение приватные функции, можно, например, с помощью такой утилиты: http://www.chimpstudios.com/appscanner/
Проект, к сожалению, недавно перестал поддерживаться, но местами еще актуален. Провериться стоит всем, даже если вы добропорядочный разработчик и ни разу не слышали имени Erica Sadun. Проблема может быть в ваших самостоятельно реализованных методах: если название какого-либо из них совпадет с непубличным системным методом, приложение будет отклонено по тому же пункту 2.5 ARG.
На мой взгляд, можно выделить два больших класса задач, для решения которых используется непубличное API:
Приложениям из пункта 1 не видать публикации в App Store, даже если проверка на приватные функции будет пройдена, так как из описания приложения очевидно, что запрещенные технологии все же используются. Второй случай более интересен, ведь можно реализовать собственные элементы управления, похожие на системные, но «с блэкджеком и …», то есть кастомизируемые. Эта задача достаточно сложная и трудозатратная, особенно если элемент управления активно использует анимацию.
Предположим, что наша задача — написать приложение с поддержкой iOS 4 и выше, и реализовать в нем переключатель оранжевого цвета, как в iOS Settings – Airplane Mode Switch:
Следующий код позволит сделать, что требуется:
Но setAlternateColors — непубличный метод, он не объявлен в официальном описании UISwitch. Использование этого метода обнаруживается обычным strings и влечет за собой отказ в публикации в App Store. Для маскировки использования непубличного метода можно воспользоваться возможностями Objective-C Runtime, то есть не посылать сообщение объекту, а вызвать соответствующую функцию, найденную по селектору. Теперь об этом подробнее:
Тем самым получаем, что приватный метод не встречается целым словом в ASCII строках бинарного файла (как раз то, что показывает strings) и не может быть обнаружен системами поиска непубличных API-вызовов.
В заключение хочу напомнить, что перед использованием данного метода — и всегда перед использованием хитростей и обходных путей — нужно попытаться понять, зачем ограничения были установлены и стоит ли вообще их обходить? Не исключено, что текущие ограничения имеют вполне объяснимые причины.
COM_SPPAGEBUILDER_NO_ITEMS_FOUND