Ответ 1
Хорошая практика состоит в том, чтобы разделить ваше приложение на две части:
Домен. Содержит все классы обслуживания для удаленной связи (то есть, если вам нужно ударить отдаленный сервер) и всех классов и моделей, связанных с вашей бизнес-логикой. Эта часть является той, которая использует j2objc, и вы хотите, чтобы она не была привязана к вашему пользовательскому интерфейсу.
Пользовательский интерфейс. Здесь присутствуют все ViewControllers и Views.
Почему они отличаются друг от друга?
Как только вы настроите свою бизнес-логику, вы должны хорошо сгенерировать свой код с помощью j2objc и оставить его практически нетронутым. Ваш пользовательский интерфейс, с другой стороны, может сильно измениться в течение срока действия вашего приложения (помните, как iOS 7 заставил каждого разработчика обновлять визуальное представление своих приложений). Вы хотите, чтобы обновления в домене или пользовательском интерфейсе влияли на другую часть.
Как они работают вместе?
После действия (например, нажатия на кнопку) вы можете спросить домен, выполняются ли какие-либо предварительные условия (т.е. это новый пользователь?), а затем вы создаете экземпляр ViewController для отображения. Пользовательский интерфейс может предоставлять данные в домене или запрашивать некоторые, но его обязанность заключается в создании экземпляров Views/ViewControllers.
Сложная маршрутизация
В приложениях, где мне нужно ориентироваться где-нибудь на основе удаленного push-уведомления или на основе некоторой сложной логики, я стараюсь, чтобы объект (называемый "маршрутизатор" ) обрабатывал все это. Он все еще находится в части пользовательского интерфейса, и вы передаете ему объекты домена, необходимые для принятия решений. Затем он возвращает объект навигации с изображением стека навигации (это может быть объект, обрабатывающий строку, похожую на URL-адрес), которую вы можете дать рекурсивно для просмотра viewControllers.
Скажем, ваш объект "router" возвращает навигационный объект "firstVC/secondVC/thirdVC" в AppDelegate. AppDelegate может вызвать метод dequeue
, который возвращает "firstVC", и на основе этого экземпляра объекта "firstViewController" добавляется в стек UINavigationController. Затем он передает объект "router" этому недавно созданному ViewController, который также вызывает метод dequeue
для получения "secondVC". Исходя из этого, "firstViewController" будет создавать экземпляр объекта "secondViewController" для добавления в стек UINavigationController. Затем он передал бы тот же объект "router" этому объекту "secondViewController" , и он снова вызовет метод dequeue
для получения "третьего VC" и создаст экземпляр соответствующего ViewController.
Таким образом, вы создаете свой навигационный стек, позволяя каждому ViewController создавать экземпляр другого ViewController, о котором он знает (в моем предыдущем примере "firstViewController" знает о "secondViewController" , потому что в его представлении есть кнопка, позволяющая пользователю достичь представления "secondViewController" , но не знает о "thirdViewController" ).
Вы также можете создать свой AppDelegate весь стек навигации, но поскольку ваш "firstViewController" уже имеет заголовок "secondViewController" , импортированный для работы кнопки, лучше разрешить ему выполнять работу, связанную с этим ViewController, и т.д.
Рабочий образец
Вот демонстрационный проект, который я сделал, чтобы проиллюстрировать, что я только что показал.
Классы, содержащиеся в папке "Домен", могут быть вашими классами, сгенерированными с помощью j2objc. Метод buildNavigationStack
в AppDelegate создает функциональный навигационный стек с объектом "Router". Я сделал этот скелет проекта простым, демонстрируя несколько шаблонов, таких как фабрики для централизованных и организованных экземпляров классов, и viewData, которые инкапсулируют объект модели и выводят данные, готовые для отображения. Его можно было бы улучшить с помощью нескольких протоколов, чтобы сделать вещи более абстрактными, но я старался держать их простыми с самого начала.