- PVSM.RU - https://www.pvsm.ru -

Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября)

В новом выпуске разбираемся со скруглением иконок (два раза!), с UI-тестами и MVI, мультиплатформенными приложениями и CI/CD, проектированием интерфейсов, самыми зарабатывающими приложениями и многим другим.

Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 1

История с долгими поисками девайсов и/или проводов стала касаться меня ежедневно. Такая пустяковая задача, как найти Xiaomi Mi A1, занимала кучу времени и приносила душевные страдания. Спустя некоторое время, я пришёл к мысли, что меня это бесит и на поиск девайса столько времени уходить не должно. Я нашёл узкое горлышко в рабочих процессах и решил его ликвидировать.

Этот дайджест доступен в виде еженедельной рассылки [2]. А ежедневно новости мы рассылаем в Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 3Telegram-канале [3].

Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 4 iOS

(+66) Секрет формы иконок iOS: это сквиркл? Разбор [4]
(+3) Формулы переводов: хитрая локализация для iOS и не только [5]
(+3) Swift Best Practices которые не стыдно знать [6]
Apple откладывает защиту конфиденциальности в iOS 14 до следующего года [7]
Особенности реализации календаря с горизонтальным скролом [8]
В App Store запускаются промо-коды для подписок [9]
10 советов по разработке виджетов для iOS 14 [10]
Apple не будет задерживать исправление ошибок в App Store [11]
Apple делает свой поисковый сервис? [12]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 5 Мои любимые приложения для iOS-разработки в 2020 году [13]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 6 Как создать интерактивный Bottom Sheet в Swift 5 [14]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 7 Встроенные покупки и StoreKit в iOS 14 [15]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 8 Привязка к прокрутке элемента [16]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 9 Как создать навигатор для перехода на любую страницу в Swift [17]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 10 Ваш первый UITest на Swift [18]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 11 Что нового в Xcode 12.0? [19]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 12 Обработка видео в SwiftUI в реальном времени с использованием Core Image [20]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 13 Не делайте этого с помощью Swift Optionals [21]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 14 Ассемблер в iOS [22]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 15 Apple Silicon для разработчиков приложений [23]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 16 Swifty Guitar Chords: гитарные аккорды на Swift [24]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 17 MultiplatformApp: мультиплатформенное приложение на SwiftUI [25]

Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 18 Android

(+10) На чем писать Android UI-тесты [26]
(+4) Быть или не быть: дискуссии о тестировании в мобильной разработке [27]
(+3) Загрузка и сборка AOSP [28]
(+2) Так для чего же нам все таки нужен MVI в мобильной разработке [29]
(+2) Как встроить голосового помощника в любое мобильное приложение. Разбираем на примере Habitica [30]
(+1) Анализ сервисов приема SMS для Android против сайтов-сервисов и опыт разработки нового функционала под Android [31]
Android Broadcast: Dagger Hilt: Deep Dive / No more Koin [32]
Android Broadcast: Kotlin 1.4: быстрее и лучше [33]
Вышла альфа Kotlin Multiplatform Mobile [34]
Thermal в Android [35]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 19 Приватные библиотеки в Android – почему вы должны рассмотреть это [36]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 20 Извлекаем взаимодействий из ViewModel [37]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 21 Распознавание касания, двойного касания, панорамирования и щипка в Android [38]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 22 Заставьте ваш (Kotlin) код выражать самого себя [39]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 23 Распространенные ошибки разработчиков при создании RecyclerViews и способы их устранения с помощью класса ViewRepresentation [40]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 24 Отформатируйте код Kotlin с помощью Ktlint [41]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 25 Shape Drawables — самый мощный инструмент для Android UI [42]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 26 Исследуем Kotlin Multiplatform [43]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 27 Настраиваем Logcat в Android Studio [44]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 28 20 инструментов Android-разработки о которых вы, вероятно, никогда не слышали [45]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 29 Добавляем ленту на иконку приложения в Android (снова) [46])
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 30 Предпочитаемое хранение данных в Jetpack DataStore [47]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 31 Jetpack Release Tracker: отслеживание обновлений AndroidX [48]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 32 TrackerControl: отслеживание сбора данных на Android [49]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 33 Jetpack Compose Samples: примеры работы с Compose [50]

Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 34 Разработка

(+43) Ваши квадрокруги — неправильные [51]
(+18) Создаем разрушаемые объекты в Unreal Engine 4 и Blender [52]
(+17) «Ну, покати!» или CI/CD мобильных приложений на основе контракта [53]
(+9) Как прошел открытый Demo Day в Райффайзенбанке [54]
(+7) Тестирование Flutter-приложений: инструменты, преимущества, проблемы [55]
(+7) Как работают мобильные кошельки на примере приложения «Mir Pay» [56]
(+4) Улучшаем работу со сценами с помощью ScriptableObject [57]
(+4) Продвинутое велосипедостроение или клиент-серверное приложение на базе C# .Net framework [58]
(+3) Совет инженерам по тестированию №1: Докеризируйте ваш Selenium Grid [59]
(+2) Победитель Apple Design Awards: статистически усреднённый портрет [60]
Podlodka #179: рациональность [61]
Как создать свой игровой бизнес [62]
Дизайн приложений: примеры для вдохновения #15 [63]
Google и Apple разработали упрощенную систему предупреждения о COVID-19 [64]
Pokemon GO прекращает поддержку старых смартфонов [65]
Unity Distribution Portal позволит работать сразу со многими магазинами приложений [66]
Проектирование игры в Sketch: интервью с создателем King Rabbit [67]
Не проектируйте для мобильных устройств (Mobile-first) [68]
С чего начать проектирование мобильного приложения. Основы UI дизайна [69]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 35 Что такое Actions Builder? Actions Builder и Actions SDK для Google Assistant [70]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 36 Реверс-инжиниринг: разработка эмулятора сервера для Marvel’s Avengers [71]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 37 10 лучших и самых популярных пакетов Flutter [72]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 38 5 советов для лучшего дизайна кнопок [73]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 39 Улучшаем Flutter-приложения с помощью автозаполнения [74]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 40 Чистый код для ведущих разработчиков [75]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 41 Автоматизация жизненного цикла Flutter-проекта с помощью GitHub Actions [76]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 42 Да, TDD вас замедляет [77]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 43 Разработка дневника настроения на Flutter за 2 часа [78]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 44 6 шагов в поиске подходящей среды автоматизации тестирования (с примером из практики) [79]

Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 45 Аналитика, маркетинг и монетизация

Avo: аналитика нового поколения [80]
Самые зарабатывающие приложения в августе 2020 [81]
Индия забанила PUBG и еще сотню приложений [82]
Google запустил Growth Academy для Украины и Беларуси [83]
App Annie представляет отчет по геймингу за первое полугодие [84]
myTracker анализирует доходы от рекламы в приложениях [85]
Локализация: как выйти на международный рынок и увеличить количество установок? [86]
Модель монетизации: меняем и дешево тестируем новую [87]
Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 46 Почему удержание — лучший способ роста [88]

Дайджест интересных материалов для мобильного разработчика #360 (31 августа — 6 сентября) - 47 AI, Устройства, IoT

(+20) Малиновый киноцентр или как сделать неубиваемый смарт-ТВ [89]
(+18) Как игры стали движущей силой двух школ исследований ИИ [90]
(+1) Микроволновка, знающая о тебе всё: что такое Интернет вещей (IoT)? [91]
Apple iPhone 11 стал самым продаваемым смартфоном в первой половине 2020 [92]

Предыдущий дайджест [93]. Если у вас есть другие интересные материалы или вы нашли ошибку — пришлите, пожалуйста, в почту [94].

Автор: DigitalEcosystems

Источник [95]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/razrabotka-pod-ios/356702

Ссылки в тексте:

[1] Устрой дестрой, порядок НЕ отстой: как я приводил в чувство шкаф для хранения девайсов: https://habr.com/ru/post/517740/

[2] рассылки: http://apptractor.us3.list-manage2.com/subscribe?u=fbdb52f18301080a3cc983f4b&id=bb7bc0a9c0

[3] Telegram-канале: https://t.me/apptractor

[4] Секрет формы иконок iOS: это сквиркл? Разбор: https://habr.com/ru/company/droider/blog/517298/

[5] Формулы переводов: хитрая локализация для iOS и не только: https://habr.com/ru/post/517818/

[6] Swift Best Practices которые не стыдно знать: https://habr.com/ru/post/517220/

[7] Apple откладывает защиту конфиденциальности в iOS 14 до следующего года: https://apptractor.ru/info/news/apple-delay-ios-14-privacy.html

[8] Особенности реализации календаря с горизонтальным скролом: https://apptractor.ru/info/media/calendar-uicollectionviewlayout.html

[9] В App Store запускаются промо-коды для подписок: https://apptractor.ru/info/news/ios-subscription-offer-codes.html

[10] 10 советов по разработке виджетов для iOS 14: https://apptractor.ru/info/articles/developing-ios-14-widgets.html

[11] Apple не будет задерживать исправление ошибок в App Store: https://apptractor.ru/deploy/app-stores/app-review-process-updates.html

[12] Apple делает свой поисковый сервис?: https://apptractor.ru/info/news/apple-search.html

[13] Мои любимые приложения для iOS-разработки в 2020 году: https://ebelinski.com/apps-for-ios-development-2020/

[14] Как создать интерактивный Bottom Sheet в Swift 5: https://medium.com/better-programming/how-to-create-an-interactive-bottom-sheet-in-swift-5-adadaad79e72

[15] Встроенные покупки и StoreKit в iOS 14: https://medium.com/better-programming/in-app-purchases-and-storekit-in-ios-14-aed2c3e58966

[16] Привязка к прокрутке элемента: https://levelup.gitconnected.com/snap-to-item-scrolling-debccdcbb22f

[17] Как создать навигатор для перехода на любую страницу в Swift: https://medium.com/better-programming/how-to-build-a-navigator-to-go-to-any-page-you-want-in-swift-ae14ef6ba4ee

[18] Ваш первый UITest на Swift: https://uxdesign.cc/your-first-uitest-in-swift-847bc5595c26

[19] Что нового в Xcode 12.0?: https://medium.com/better-programming/whats-new-in-xcode-12-0-6202528b8f9b

[20] Обработка видео в SwiftUI в реальном времени с использованием Core Image: https://medium.com/better-programming/swiftui-video-player-real-time-processing-with-core-image-ef0688745c57

[21] Не делайте этого с помощью Swift Optionals: https://medium.com/better-programming/dont-do-these-with-swift-optionals-285e2d99b0ea

[22] Ассемблер в iOS: https://suelan.github.io/2020/08/18/20200817-ios-main-in-assembly/

[23] Apple Silicon для разработчиков приложений: https://medium.com/better-programming/apple-silicon-app-developer-9d725f10bee8

[24] Swifty Guitar Chords: гитарные аккорды на Swift: https://apptractor.ru/info/github/swifty-guitar-chords.html

[25] MultiplatformApp: мультиплатформенное приложение на SwiftUI: https://apptractor.ru/info/github/multiplatformapp.html

[26] На чем писать Android UI-тесты: https://habr.com/ru/company/avito/blog/516650/

[27] Быть или не быть: дискуссии о тестировании в мобильной разработке: https://habr.com/ru/company/yamoney/blog/513722/

[28] Загрузка и сборка AOSP: https://habr.com/ru/post/517922/

[29] Так для чего же нам все таки нужен MVI в мобильной разработке: https://habr.com/ru/post/517962/

[30] Как встроить голосового помощника в любое мобильное приложение. Разбираем на примере Habitica: https://habr.com/ru/company/just_ai/blog/514290/

[31] Анализ сервисов приема SMS для Android против сайтов-сервисов и опыт разработки нового функционала под Android: https://habr.com/ru/post/517484/

[32] Android Broadcast: Dagger Hilt: Deep Dive / No more Koin: https://apptractor.ru/info/media/dagger-hilt.html

[33] Android Broadcast: Kotlin 1.4: быстрее и лучше: https://apptractor.ru/info/media/kotlin-1-4.html

[34] Вышла альфа Kotlin Multiplatform Mobile: https://apptractor.ru/info/news/kotlin-multiplatform-mobile-alpha.html

[35] Thermal в Android: https://proandroiddev.com/thermal-in-android-26cc202e9d3b

[36] Приватные библиотеки в Android – почему вы должны рассмотреть это: https://deezer.io/private-libraries-in-android-why-you-should-consider-it-91dcc1af3d7b

[37] Извлекаем взаимодействий из ViewModel: https://proandroiddev.com/extract-interactions-from-viewmodel-7760451f5c16

[38] Распознавание касания, двойного касания, панорамирования и щипка в Android: https://proandroiddev.com/android-tap-double-tap-pan-and-pinch-gestures-recognising-part-1-129235e4dc67

[39] Заставьте ваш (Kotlin) код выражать самого себя: https://proandroiddev.com/make-your-kotlin-code-express-itself-9a36b37c5f93

[40] Распространенные ошибки разработчиков при создании RecyclerViews и способы их устранения с помощью класса ViewRepresentation: https://medium.com/swlh/common-mistake-developers-make-when-building-recyclerviews-and-how-to-fix-it-using-3b642a2ba0f4

[41] Отформатируйте код Kotlin с помощью Ktlint: https://medium.com/better-programming/format-your-kotlin-code-with-ktlint-6fd1321504d0

[42] Shape Drawables — самый мощный инструмент для Android UI: https://medium.com/better-programming/shape-drawables-the-most-powerful-tool-for-your-android-ui-e5c2b1ab9eef

[43] Исследуем Kotlin Multiplatform: https://medium.com/better-programming/exploring-kotlin-multiplatform-part-1-b73f59d61135

[44] Настраиваем Logcat в Android Studio: https://medium.com/better-programming/customize-the-logcat-in-android-studio-8f58d39222ef

[45] 20 инструментов Android-разработки о которых вы, вероятно, никогда не слышали: https://medium.com/better-programming/20-android-dev-tools-youve-probably-never-heard-of-c6cc08b4e543

[46] Добавляем ленту на иконку приложения в Android (снова): https://medium.com/@cycki/ribbonize-your-android-application-laucher-icon-again-c52e08d58172

[47] Предпочитаемое хранение данных в Jetpack DataStore: https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html?linkId=98693079

[48] Jetpack Release Tracker: отслеживание обновлений AndroidX: https://apptractor.ru/info/github/jetpack-release-tracker.html

[49] TrackerControl: отслеживание сбора данных на Android: https://apptractor.ru/info/github/trackercontrol.html

[50] Jetpack Compose Samples: примеры работы с Compose: https://apptractor.ru/info/github/jetpack-compose-samples.html

[51] Ваши квадрокруги — неправильные: https://habr.com/ru/post/517620/

[52] Создаем разрушаемые объекты в Unreal Engine 4 и Blender: https://habr.com/ru/company/pixonic/blog/517684/

[53] «Ну, покати!» или CI/CD мобильных приложений на основе контракта: https://habr.com/ru/company/avito/blog/516812/

[54] Как прошел открытый Demo Day в Райффайзенбанке: https://habr.com/ru/company/raiffeisenbank/blog/517328/

[55] Тестирование Flutter-приложений: инструменты, преимущества, проблемы: https://habr.com/ru/company/surfstudio/blog/517574/

[56] Как работают мобильные кошельки на примере приложения «Mir Pay»: https://habr.com/ru/company/nspk/blog/517258/

[57] Улучшаем работу со сценами с помощью ScriptableObject: https://habr.com/ru/company/otus/blog/517686/

[58] Продвинутое велосипедостроение или клиент-серверное приложение на базе C# .Net framework: https://habr.com/ru/post/517670/

[59] Совет инженерам по тестированию №1: Докеризируйте ваш Selenium Grid: https://habr.com/ru/company/otus/blog/517710/

[60] Победитель Apple Design Awards: статистически усреднённый портрет: https://habr.com/ru/company/digital-ecosystems/blog/516962/

[61] Podlodka #179: рациональность: https://apptractor.ru/info/media/podlodka-179.html

[62] Как создать свой игровой бизнес: https://apptractor.ru/info/media/how-to-games.html

[63] Дизайн приложений: примеры для вдохновения #15: https://apptractor.ru/develop/design/app-design-15.html

[64] Google и Apple разработали упрощенную систему предупреждения о COVID-19: https://apptractor.ru/info/news/exposure-notifications-express.html

[65] Pokemon GO прекращает поддержку старых смартфонов: https://apptractor.ru/info/news/pokemon-go-old.html

[66] Unity Distribution Portal позволит работать сразу со многими магазинами приложений: https://apptractor.ru/info/news/unity-distribution-portal.html

[67] Проектирование игры в Sketch: интервью с создателем King Rabbit: https://ux.pub/proektirovanie-igry-v-sketch-intervyu-s-sozdatelem-king-rabbit/

[68] Не проектируйте для мобильных устройств (Mobile-first): https://ux.pub/ne-proektiruyte-dlya-mobilnyh-ustroystv-mobile-first/

[69] С чего начать проектирование мобильного приложения. Основы UI дизайна: https://ux.pub/s-chego-nachat-proektirovanie-mobilnogo-prilozheniya-osnovy-ui-dizayna/

[70] Что такое Actions Builder? Actions Builder и Actions SDK для Google Assistant: https://techhype.io/?story=what-is-actions-builder-actions-builder-and-actions-sdk-google-assistant

[71] Реверс-инжиниринг: разработка эмулятора сервера для Marvel’s Avengers: https://krystalgamer.github.io/avengers-emulator/

[72] 10 лучших и самых популярных пакетов Flutter: https://medium.com/better-programming/the-10-best-and-most-liked-flutter-packages-f5813822e118

[73] 5 советов для лучшего дизайна кнопок: https://uxdesign.cc/5-tips-for-better-button-design-8d68f0418f0e

[74] Улучшаем Flutter-приложения с помощью автозаполнения: https://medium.com/flutter-community/level-up-your-flutter-apps-with-autofill-1418a02db2e0

[75] Чистый код для ведущих разработчиков: https://medium.com/huawei-developers/clean-code-for-top-developers-2c78828ad4d1

[76] Автоматизация жизненного цикла Flutter-проекта с помощью GitHub Actions: https://medium.com/better-programming/lifecycle-automation-of-a-flutter-project-with-github-actions-e26b8f106467

[77] Да, TDD вас замедляет: https://medium.com/better-programming/yes-tdd-slows-you-down-c7ee154ec322

[78] Разработка дневника настроения на Flutter за 2 часа: https://medium.com/flutter-community/develop-a-mood-diary-flutter-app-in-2-hours-ca54f8bf6703

[79] 6 шагов в поиске подходящей среды автоматизации тестирования (с примером из практики): https://www.mindk.com/blog/test-automation-framework/

[80] Avo: аналитика нового поколения: https://apptractor.ru/measure/user-analytics/avo.html

[81] Самые зарабатывающие приложения в августе 2020: https://apptractor.ru/info/analytics/top-grossing-apps-august-2020.html

[82] Индия забанила PUBG и еще сотню приложений: https://apptractor.ru/info/news/india-pubg.html

[83] Google запустил Growth Academy для Украины и Беларуси: https://apptractor.ru/info/conferences/google-for-startups-growth-academy.html

[84] App Annie представляет отчет по геймингу за первое полугодие: https://apptractor.ru/measure/app-store-analytics/app-annie-gaming-1h2020.html

[85] myTracker анализирует доходы от рекламы в приложениях: https://apptractor.ru/measure/user-analytics/mytracker-monetization.html

[86] Локализация: как выйти на международный рынок и увеличить количество установок?: https://vc.ru/marketing/153162-lokalizaciya-kak-vyyti-na-mezhdunarodnyy-rynok-i-uvelichit-kolichestvo-ustanovok

[87] Модель монетизации: меняем и дешево тестируем новую: https://sense23.com/post/model-monetizatsii-menyaem-i-deshevo-testiruem-novuyu

[88] Почему удержание — лучший способ роста: https://medium.com/@nikolasvogt/why-retention-is-the-ultimate-growth-hack-7a4d6a26c52e

[89] Малиновый киноцентр или как сделать неубиваемый смарт-ТВ: https://habr.com/ru/post/517304/

[90] Как игры стали движущей силой двух школ исследований ИИ: https://habr.com/ru/company/vdsina/blog/517428/

[91] Микроволновка, знающая о тебе всё: что такое Интернет вещей (IoT)?: https://habr.com/ru/post/517850/

[92] Apple iPhone 11 стал самым продаваемым смартфоном в первой половине 2020: https://apptractor.ru/info/news/best-selling-phones-2020.html

[93] Предыдущий дайджест: https://habr.com/ru/company/digital-ecosystems/blog/517100/

[94] почту: mailto:lbogolubov@gmail.com

[95] Источник: https://habr.com/ru/post/518000/?utm_source=habrahabr&utm_medium=rss&utm_campaign=518000