Я активно занимался внедрением Finite-State Machine у себя на работе и безусловно это одно из самых лучших паттернов в мобильной разработке. Большая часть работы приложения это реакция на события, это может быть состояние об Интернет соединении, запуск приложения, аутентификация пользователя и т.п. В результате бизнес логика может распределена по зоне ответственности более детально. В тоже самое время состояния очень легко тестировать, потому как они отвечают только за переход от текущего состояние в некое следующее по заданным правилам.
В целом состояние можно описать следующим образом:
Определение состояния по своей сути
Тип состояния содержит список состояний, список событий и функцию редуктера (reducer), которая мутирует состояние.
Сама по себе машина состояния это просто менеджер или тот кто владеет состоянием и может его изменить через редуктор. Здесь важно понимать что извне состояние нельзя изменить в обход машины состояния. Можно только прочитать текущее значение или подписаться не его изменение.
Изменение состояния через машину состоянияЗапрет на изменение состояния в обход владельца состояния
Для реализации данного подхода вам необходимо определить протокол состояния который может выглядеть следующий образом:
protocol StateType: Equatable {
associatedtype Event
associatedtype Command = Void
/// The initial state.
static var initial: Self { get }
/// Updates the current state to a new state caused by a given event.
@discardableResult
mutating func reduce(with event: Event) -> Command
}
Command по умолчанию может никак не использовать машиной состояния, но может быть очень полезен для дополнительных действий со стороны машины состояния. В некоторых случаешь состояние может перейти в такой случай где менеджеру (машине состояния) необходимо подсказка как интерпретировать одно и тоже состояние для разных возможных действий со стороны менеджера.
В реальном приложении состояние аутентификации имеет больше событий и состояний переходов, но главное, что при переходи на "чистую" машину состояний целостность, изоляция бизнес логики и отказоустойчивость повысилась значительно.
Походу это когнитивный диссонанс российских скреп, вроде белый медведь это наше, но вот мужик невеста, это точно запрещено :)))
Как ещё радужный флаг сработал, это вопрос
И понятно что это только для iOS 13. У меня вопрос, кто-нибудь пробовал использовать комбинацию Starscream подключаемую как динамическую библиотеку для iOS 12- и встроенный для iOS13+. Есть какая-то выгода? По идеи памяти должно меньше кушать, ведь «все» системные либы динамические и скорее всего уже в памяти (случай для iOS13). Сама реализация думаю всем понятна, что надо написать обёртку для вебсокетов и менеджер который выбирает необходимую реализацию в зависимости от версии iOS.
Неадаптированная версия для незрячего выглядит так:
Насколько я понимаю, вы сами нарисовали эту версию для незрячего? Это выглядит очень интересно. Помогает легче намного быстрее понять что надо поправить. Спасибо за идею.
Выше я написал ответ, к которому добавлю, что Apple Beta-Testing это скорее для тестирования Beta и больше Release Candidate версий. Всё же быстрое ревью неприятно замедяет тестирование приложения, которое находится на стадии разработки. В Apple Beta-Testing ещё многого не хватает по сравнению с другими сервисами, но уникальность тестирования продакшн версии, я считаю очень полезной и важной.
Я не исключаю AdHoc провижен и он безусловно полезен в процессе разработки и тестирования. Конечно, создаются дополнительные схемы с соответствующими ключами, чтобы управлять теми же ссылками на сервер, но несмотря на все предосторожности ошибки случаются. До запуска Apple Beta-Testing, продакшн версию никак нельзя было проверить, пока она не появится в AppStore. Например, могут забыть новый ключ для продакшн схемы или условие в коде, которое отвечает за миграцию базы данных, а при обновлении выяснится, что апп крашится. Apple TestFlight на данный момент не достаточен для того, чтобы перестать пользоваться другими сервисами на подобии HockeyApp и Crashlytics.
Для распространения тестовых версий необходимо создать AppStore Distribution provisioning profile и настроить профиль приложения в iTunes Connect.
Это одно из самых важных преимуществ Apple TestFlight от остальных, а совсем не недостаток. Здесь мы получаем рабочую протестированную версию с нужным provisioning profile для того чтобы легко и без лишних сборок отправить билд в AppStore.
Люди прекратите делать «пробу пера», да ещё и «раскручивать» и писать статьи о своём «великом» опыте «разработки» под iOS. Хватит уже захламлять АппСтор подобным Г. Что вы хотите сказать этим продуктом пользователям? Я понимаю, если вам интересно изучить новый язык программирования, готовую платформу распространения продуктов, это одно, тогда и распространяйте это среди друзей или просто бесплатно, потому что идея нулевая и ваши затраты минимальны, а ожидания слишком завышены. Получили опыт разработки отлично, надо двигаться дальше, очень много и усердно работать и тогда возможно через год сможете создать что-то разумное в плане реализации. Но главное это всё же это идея, попробуйте создать что-то что действительно будет кому-либо интересно и в первую очередь это должно быть интересно вам лично. Честно ответьте себе, что вам это интересно и вы будете этим пользоваться не раз. Изучите конкурентов, это поможет определиться с уникальностью вашего продукта или функций. Оцените насколько лучше вы сможете реализовать чем конкуренты и сколько им потребуется времени, чтобы скопировать вашу хорошую идею. Подобных вопросов множество и всё это складывается из огромного труда и усилий чтобы сделать действительно интересный проект, затраты на который будут куда больше чем $5000, но не обязательно в денежном эквиваленте.
1. k префикс и константа — я не настолько категоричен к префиксу k сколько к именованию константы. Например kShouldShowBeautifulProgressBar: не хорошо называть константы, которые начинаются как ShouldShow… Во первых это похоже больше на булеву переменную. Во вторых это внешняя константа, а в этом пространстве имён огромное количество других констант и в objective-c так называемый namespacing строится от 2-х, 3-х и т.д. буквенного префикса соответствующего проекта/модуля для соответствующих классов, протоколов, констант и т.д. Константы от класса соответственно строятся от имени класса и смысловой нагрузки константы. Поэтому и получаем такую длинную константу примерно такую: BSBeautifulProgressBarManagerShowProgressBarNotification.
Правило для именования констант, енумов и блоков простое: чем больше область видимости, тем больше контекстной/родительской состовляющей, т.е. если константа в области видимости всего класса или даже внешняя, то добавляем имя класса как префикс. Константы внутри метода достаточно просто по имени. Почти тоже самое для имён переменных и методов. Обратный пример, если переменная живёт в области видимости 2-3-х строк, тогда её можно назвать очень кратко: i, frame, view, hidden и т.д.
Про k префикс это всё же рекомендация, будет проще и удобнее, поверьте. Но это по большей части рекомендация именно для objective-c.
2. Приватные переменные. Здесь мнительность совсем лишняя, что вообще-то можно всех обмануть и получить доступ к свойству. А важно это работа с ARC, KVO и многопоточностью. На WWDC неоднократно повторяют об использовании именно свойств через приватную категорию вместо приватных переменных.
Год-два назад сам также именовал и всё ещё с ними работаю. Я всё понимаю, исторически сложилось. Но всё же это не в стиле Objective-C. В новых фрейворках iOS и в популярных open-source проектах видно что всё больше уходят от k префикса. А в итоге по работе скажу, что стало намного удобнее, когда сразу по имени класса начинаешь ввод и поиск константы. Если часто используете Open Quickly… (⇧⌘+O) то быстро можно привыкнуть к поиску констант без k.
Я активно занимался внедрением Finite-State Machine у себя на работе и безусловно это одно из самых лучших паттернов в мобильной разработке. Большая часть работы приложения это реакция на события, это может быть состояние об Интернет соединении, запуск приложения, аутентификация пользователя и т.п. В результате бизнес логика может распределена по зоне ответственности более детально. В тоже самое время состояния очень легко тестировать, потому как они отвечают только за переход от текущего состояние в некое следующее по заданным правилам.
В целом состояние можно описать следующим образом:
Тип состояния содержит список состояний, список событий и функцию редуктера (reducer), которая мутирует состояние.
Сама по себе машина состояния это просто менеджер или тот кто владеет состоянием и может его изменить через редуктор. Здесь важно понимать что извне состояние нельзя изменить в обход машины состояния. Можно только прочитать текущее значение или подписаться не его изменение.
Для реализации данного подхода вам необходимо определить протокол состояния который может выглядеть следующий образом:
Commandпо умолчанию может никак не использовать машиной состояния, но может быть очень полезен для дополнительных действий со стороны машины состояния. В некоторых случаешь состояние может перейти в такой случай где менеджеру (машине состояния) необходимо подсказка как интерпретировать одно и тоже состояние для разных возможных действий со стороны менеджера.Ну и последнее приведу более менее близкий к реальности пример состояния: https://gist.github.com/buh/63e1dd41b267bb65baacf03b8557786a
В реальном приложении состояние аутентификации имеет больше событий и состояний переходов, но главное, что при переходи на "чистую" машину состояний целостность, изоляция бизнес логики и отказоустойчивость повысилась значительно.
Как ещё радужный флаг сработал, это вопрос
receiveData(), но это надо делать только on.success.Я оставлю здесь пару ссылок где более развёрнуто описано как работать с новыми веб-сокетами:
1. appspector.com/blog/websockets-in-ios-using-urlsessionwebsockettask
2. kristaps.me/websockets-ios-13-swift
И понятно что это только для iOS 13. У меня вопрос, кто-нибудь пробовал использовать комбинацию
Starscreamподключаемую как динамическую библиотеку для iOS 12- и встроенный для iOS13+. Есть какая-то выгода? По идеи памяти должно меньше кушать, ведь «все» системные либы динамические и скорее всего уже в памяти (случай для iOS13). Сама реализация думаю всем понятна, что надо написать обёртку для вебсокетов и менеджер который выбирает необходимую реализацию в зависимости от версии iOS.Насколько я понимаю, вы сами нарисовали эту версию для незрячего? Это выглядит очень интересно. Помогает легче намного быстрее понять что надо поправить. Спасибо за идею.
UUID— это хороший пример дляid, только без NS.Result(SE0235), что тоже очень удобно. Вот тут хороший туториал.Это одно из самых важных преимуществ Apple TestFlight от остальных, а совсем не недостаток. Здесь мы получаем рабочую протестированную версию с нужным provisioning profile для того чтобы легко и без лишних сборок отправить билд в AppStore.
BSBeautifulProgressBarManagerShowProgressBarNotification.Правило для именования констант, енумов и блоков простое: чем больше область видимости, тем больше контекстной/родительской состовляющей, т.е. если константа в области видимости всего класса или даже внешняя, то добавляем имя класса как префикс. Константы внутри метода достаточно просто по имени. Почти тоже самое для имён переменных и методов. Обратный пример, если переменная живёт в области видимости 2-3-х строк, тогда её можно назвать очень кратко:
i, frame, view, hiddenи т.д.Про k префикс это всё же рекомендация, будет проще и удобнее, поверьте. Но это по большей части рекомендация именно для objective-c.
2. Приватные переменные. Здесь мнительность совсем лишняя, что вообще-то можно всех обмануть и получить доступ к свойству. А важно это работа с ARC, KVO и многопоточностью. На WWDC неоднократно повторяют об использовании именно свойств через приватную категорию вместо приватных переменных.