Я активно занимался внедрением 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 неоднократно повторяют об использовании именно свойств через приватную категорию вместо приватных переменных.