Comments 25
Реализовывать роутинг в UIView, это как минимум не логично, появится у вас новый переход и вот вы уже изменяете UIView!? Работать должно это приблизительно так: у UIViewController есть метод convenienceInit, который на вход принимает UiViewControllerParams. Затем, когда вам нужно отрисовать экран вы вызываете метод showAnimated куда передаете тип анимации для этого контроллера.
Я не iOS разработчик. Так что с терминологией могу немного путаться. Но в остальном, вопрос остается прежним, почему роутинг перекочевал во ViewController? ViewController не должен содержать такую логику. Он должен содержать логику для получения данных. А саму анимацию контроллера так же лучше вынести в отдельные сущности.
А мне идея сама понравилась — она достаточно красивая для внешнего использования.
Но проблема идеи — она не универсальна и плохо сочетаема с ограничением доступа — по факту теперь можно вызвать переход с любого экрана на любой.
Если идею расширить чтобы можно было: передавать параметры и ограничить доступ по переходам — то сталобы хорошо.
На самом деле то что описано в статье, это почти эквивалент того что я называю Навигатором.
Навигатор: Некий класс содержащий набор методов с переходами между экранами. Он наследуеться от десятка протоколов, в которых кокраз таки и содержаться эти методы.
После чего этот класс, но по протоколам, мы подсовываем во все ViewController-ы.
Такой подход не решает одной проблемы — не видно карты всех переходов целиком, что на мой взгляд кокраз таки и отличает Роутер от Навигатора — по первому видны все "маршруты" которые есть.
Сторибоард на картинке, показательный пример — в нем отображены только переходы, и именно это обязанность роутинга — давать подробную информацию обо всех переходах. Если можно былобы легко передавать параметры с помощью сторибоарда и его представление былобы поудачнее, думаю не у кого не возникло желания делать свой роутер.
1. Карта переходов. Если перейти в публикации к словам: "Введя новый параметр type у UIViewController можно детализировать функцию routing, в которой будут собраны все вызовы переходов между экранами приложения и разбиты по типу вызывающего UIViewController", то код приведенный под ними является той самой картой всех переходов в приложении. Ну и вроде как это достаточно наглядно.
2. Ограничение доступа. Вызвать переход с любого экрана на любой можно (но только вызвать). Если в карте переходов не будет прописано для конкретного типа контролера конкретного действия, то просто ничего не произойдет. Поэтому просто так перейти куда угодно не получится. В публикации, если вы вызовете для контролера с type = .navigation переход с параметром selectedCityTransport, то ничего не произойдет, т.к. этого нет в карте.
3. Передача параметров. Проблемы с передачей параметров и так нет. Внутри enum Routing можно передавать что угодно
Да пожалуй, первый пункт на самом деле проглядел. Ну и по второму и третьему пункту соглашусь.
Так что да, идея на самом деле отличная. Возможно попробую у себя как-нибудь в проекте, но сходу больше проблем не вижу.
Есть правда одна — сочетание со storyboard, так как у нас в компании принято разрабатывать через него.
Покрайней менее, это в разы проще моего сложного VCRouter который решает туже задачу.
Еще раз перечитал статью.
А почему не использовать в качестве type реальный тип класса?
тогда switch будет похож на:
switch type(of: self) {
case ViewController1.self:
...
case ViewController2.self:
...
}
Правда именно так не разрешено сделать, но всегда есть String(describing:) который можно красиво обернуть через расширение в какой-нибудь статический метод/свойство.
В этом случае не нужно добавлять enum и инициализировать его во всех ViewController + интеллисенс будет позволять легко переходить на каждый из них.
Но на самом деле, как и было сказано в публикации: Можно добиться адекватного сопоставления UIViewController и перехода разными способами. Предложенный вами один из таких. И, если для ваших задач его будет достаточно, то можно пользоваться и им. Тут любой подход будет оправдан если вписывается в рамки поставленной задачи
Ваш Storyboard стал настолько большим, что добавляя каждый новый экран вы испытываете различные сложности.
Маломощные машины просто не в силах открыть Storyboard проекта.
Именно для этого Apple еще в iOS 9 ввели Storyboard Reference. Который позволит создавать segue между ViewController'ами которые находятся в разных сторибоардах. Т.е. теперь для того чтобы манеджить весь уровень навигации не обязательно писать код, и не обязательно хранить все VC в одном сторибоарде.
В последних проектах только их и используем. Segue позволяет отлично инкапсулировать зависимости отдельных VC, а метод prepareForSegue для каждого VC позволяет без труда быстро понять кто и что вызывает.
Ваш Storyboard стал настолько большим, что добавляя каждый новый экран вы испытываете различные сложности.
Маломощные машины просто не в силах открыть Storyboard проекта.
Т.е. эти пункты подразумевают наличие и использование Storyboard в проекте изначально. И соответственно подразумевают отсутствие AsyncDisplayKit. И именно к этим пунктам я привел комментарий, о возможном использовании нативных Storyboard Reference, вместо написания лишнего кода.
Публикация решают одну конкретную задачу
Публикация приводит так же и комментарии, которые я справедливо подвергнул критике.
Думаю вам следует смириться с тем, что не все используют Storyboard
Думаю, что вы понятия не имеете о том с чем я смирился, а с чем нет, но переходить на личности в любом споре — это низко.
И, наверное, вам следует радоваться тому факту, что люди пишут интерфейс кодом
Вы не поверите, но я и сам пишу интерфейс кодом, когда этого требует проект, а вот чему радоваться мне или нет — решать далеко не вам.
Вы используете более современный подход и будете более востребованы как специалист и сможете зарабатывать больше $
Вы мало зарабатываете и поэтому у вас пассивная агрессия на этой почве? Если нет, то к чему этот комментарий? Он абсолютно не вносит конструктива в дискуссию.
Ну я бы точно этому радовался
Чему радоваться лично вам, я указывать естественно не буду, практически в каждой конституции — это закреплено как основная свобода человека.
После этого комментария сложилось впечатление, что вы один из людей который считает свой подход единственно верным в любой ситуации, но к справедливости всего сказанного выше, Storyboard и
программирования кодомприменяются в разных ситуациях и по разным причинам.
В данной ветке дискуссии вы прыгаете от аргумента к аргументу, от позиции к позиции при этом не пытаясь вести диалог, а просто пытаясь доказать свою правоту, например в предыдущем комментарии вы писали:
Это может точно так же подразумевать наличие Storyboard, который был создан до появления Storyboard Reference.
Т.е. вы все таки признаете наличие в проектах Storyboard как таковых, зачем же вы дальше пишите:
Думаю вам следует смириться с тем, что не все используют Storyboard. И, наверное, вам следует радоваться тому факту, что люди пишут интерфейс кодом, тратят на это больше времени и пишут подобные статьи завлекая других в этот омут программирования кодом.
В общем я не вижу смысла далее продолжать с вами дискуссию, вы изначально не поняли смысла моего комментария и вступили в демагогию, поводом для которой насколько я могу судить было упоминание Storyboard и IB.
1. Может вы что-то другое имели ввиду под словом решения?
2. Может вы думали, что я ваши комментарии назвал неактуальными?
Storyboards are a useful prototyping tool, but they're bad for performance — especially when paired with Auto Layout — and they add substantial long-term debugging and development costs. AsyncDisplayKit intentionally doesn't support them. (You could make ASTableView work with Interface Builder by implementing -initWithCoder:, but you'd still have to create and configure its cell nodes in code.)
И для самого Facebook, а так же других проектов, которые рассчитаны жить и поддерживаться более 2-3х лет это абсолютно справедливо, но если же вы пишите проект на релиз + 1-2 версии баг фикса, то я думаю отказ от Storyboard в пользу AsyncDisplayKit не слишком обоснованное решение.
extension UIViewController {
enum ViewType {
case undefined
case navigation
case transport
...
}
private struct Keys {
static var key = "\(#file)+\(#line)"
}
var type: ViewType {
get {
return objc_getAssociatedObject(self, &Keys.key) as? ViewType ?? .undefined
}
set {
objc_setAssociatedObject(self, &Keys.key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
Routing слой в iOS-приложениях