iOS Dev
7.6K subscribers
970 photos
78 videos
1 file
1.12K links
🍏Канал об iOS-разработке, необычных подходах и решениях.
👨‍💻Автор: Виктор Грушевский (@Viktorianec)
Темы:
⭐️ Подготовка к собеседованиям.
⭐️ Архитектуры и алгоритмы.
⭐️ Код. Много кода.

⚒️База знаний: https://boosty.to/ios_dev

#ios #mobile #swift
加入频道
This media is not supported in your browser
VIEW IN TELEGRAM
Create ML в Xcode: создание, обучение и настройка моделей

Create ML — встроенный инструмент Apple для создания и обучения моделей. Create ML фактически позволяет нам обучать наши модели без использования кода, и входит в состав инструментов IDE.

Доступно несколько шаблонов моделей для работы с различными ресурсами: изображениями, видео, звуком, текстом, движениями, позами и таблицами.

Create ML использует инфраструктуру машинного обучения, встроенную, например, в такие продукты Apple, как Photos и Siri. Это означает, что ваша классификация изображений и модели естественного языка компактнее и требует гораздо меньше времени для обучения.

Наш читатель Максим Скорынин — iOS Engineer в Evil Martians. Делюсь двумя крутейшими статьями за авторством Максима на эту тему.

📖 Обнаружение объектов с помощью Create ML: изображения и датасет.
В этой статье пошагово описывается процесс подготовки демо для iOS. Это приложение поможет идентифицировать и отмечать расположение номерных знаков автомобилей из видеопотока в реальном времени.

📖Анализ текста в реальном времени с помощью Word Tagger.
В этом материале автор делится опытом подготовки данных и создания ML-модели для распознавания кулинарных рецептов.

Тема Create ML обладает невероятным потенциалом, прочтите, и, возможно вы придумаете идею своего следующего приложения, которое ворвётся в топ аппстора.

@iOS Dev — расширяем базу знаний 😉
Управление памятью — важная тема в Swift и iOS-разработке. Cуществует множество руководств, объясняющих, когда следует использовать weak self в замыканиях.

📖 Это короткая история, когда утечка памяти все же может произойти.

Для целей этой статьи предполагается, что у нас есть класс с двумя функциями. Каждая функция выполняет что-то с помощью замыкания. В примерах из этого материала автор рассмотрел случаи увеличения счетчика ссылок и случаев, когда это может привести к утечке памяти.

💡 Совет от автора: если у нас слишком много замыканий, лучшим вариантом будет рефакторинг в виде отдельной функции.

————————————
Кстати! Если вы хотели бы поделиться своим опытом разработки с сообществом, то есть хорошая новость.

😎 Mobius начинает сбор докладов на свою осеннюю конференцию, и это отличный повод стать спикером. Посмотрите список тем и выберите ту, которая близка именно вам.
Рефакторинг UICollectionView с использованием дженериков в компании Etsy

Распространенный опыт работы с долгоживущими проектами заключается в том, что производительность может стать проблемой по следующим причинам:

1️⃣ Более старый код может не быть спроектирован так, чтобы использовать все преимущества оптимизации платформы и новых возможностей.

2️⃣ Производительность разработчиков также может пострадать.

3️⃣ Сложнее привлекать разработчиков к работе с кодом, который неоднократно изменялся и расширялся в течение многих лет, а также сложнее проверять и тестировать изменения.

Когда приложение Etsy только создавалось, экраны были относительно простыми вещами с ограниченной ответственностью. Имело смысл программировать их более или менее монолитно. Но когда в компании посмотрели на производительность и подумали о болевых точках инженеров, пришло решение, что пора обратить внимание на легаси-код.

В старой реализации, чем больше и сложнее становился экран, тем больше страдала его производительность: сборка одного огромного view заставляла приложение выполнять множество вычислений лэйаута заранее, включая те, которые лучше отложить. Гораздо менее затратный и более гибкий подход предполагает переосмысление экрана как набора независимых views.

📖 В этом материале идет речь о том, что предприняли в компании Etsy для улучшения ситуации. С примерами кода, конечно же.

@iOS Dev
Пример реализации модульной архитектуры в компании Just Eat

Модульная архитектура — это техника проектирования программного обеспечения, которая подчеркивает разделение функциональности программы на независимые, взаимозаменяемые модули, так что каждый из них содержит все необходимое для выполнения только одного аспекта желаемой функциональности.

Это скорее принцип, чем конкретная технология. Его можно достичь различными способами и с помощью различных инструментов. Вот несколько ключевых моментов и примеров, которые должны послужить основой для принятия решения о том, если и как внедрять модульную архитектуру:

Бизнес-причины. Например, переиспользование кода между крупными проектами компании.

Технические причины. Сложно поддерживать код, замедляется разработка.

Несколько команд. Распределение модулей между командами позволит повысить скорость итераций.

Существующая база знаний. Возможно, члены команды уже знакомы с конкретными решениями (Carthage, CocoaPods, Swift Package Manager, ручная настройка фреймворков в Xcode). В случае конкретного знакомства с какой-либо системой рекомендуется начать с неё.

📖 На примере этой статьи можно познакомиться с опытом компании, понять, через что они прошли. А также посмотреть на структуру модулей и общую архитектуру в целом.

🛠 Кстати, опенсорнсные модули доступны на Github.

@iOS Dev
Ускоряем запуск приложения: 7 советов для увеличения производительности

Важно, чтобы запуск приложения был плавным и максимально быстрым. Длительное время запуска может означать потерю большого количества пользователей.

Несмотря на то, что современные устройства быстры, мы все равно должны следить за тем, чтобы время запуска было как можно меньше. Хорошей новостью является то, что с помощью нескольких лучших практик вы сможете поддерживать время запуска вашего приложения на достаточно высоком уровне.

📖 Вот эти советы:

1️⃣ Установите целевую продолжительность запуска. На #WWDC 2019 в Apple рекомендовали не превышать 400 мс.

2️⃣ Напишите тесты, чтобы создать последовательный мониторинг и предотвратить регрессию.

3️⃣ Используйте органайзер Xcode для сбора статистики производительности времени запуска приложения.

4️⃣ Управляйте фреймворками с помощью статистики DYLD.

5️⃣ Замените или удалите зависимости, где это возможно.

6️⃣ Отложите логику приложения до рендера первого фрейма.

7️⃣ Оптимизируйте производительность логики запуска. Не всегда шестой пункт достижим, поэтому по возможности посмотрите на важные методы и способы их улучшения.

Производительность запуска приложения зависит от многих факторов. Все начинается с измерений и установки целевой продолжительности запуска. Xcode Instruments и статистика DYLD дают нам правильное направление, чтобы начать улучшать время запуска нашего приложения.

@iOS Dev
Использование кортежей в Swift на примере switch/case

Вы можете использовать кортежи и для проверки нескольких значений в одном операторе switch.

Каждый элемент кортежа может проверяться на разное значение или интервал значений.

В качестве альтернативы можно использовать символ подчеркивания (_) для поиска любого возможного значения.

В приведенном ниже примере берется точка (x, y), выраженная как простой кортеж типа (Int, Int), и классифицируется на графике, который следует за примером.

let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("\(somePoint) в начале координат")
case (_, 0):
print("\(somePoint) на оси x")
case (0, _):
print("\(somePoint) на оси y")
case (-2...2, -2...2):
print("\(somePoint) внутри рамки")
default:
print("\(somePoint) за пределами рамки")
}
// Выведется "(1, 1) внутри рамки"

Оператор switch определит, находится ли точка в начале координат (0, 0), на красной оси x, на зеленой оси y, внутри синей рамки 4 на 4 с центром в начале координат или за ее пределами.

😉 В отличие от языка C, Swift позволяет в switch/case рассматривать одно и то же значение или интервал значений.

Фактически, точка (0, 0) может соответствовать всем четырем вариантам в этом примере.

Однако, если возможно несколько совпадений, всегда используется первый подходящий вариант. Точка (0, 0) попадает под условие первого кейса (0, 0), поэтому все остальные случаи совпадения будут проигнорированы.

@iOS Dev
Продвинутые координаторы в iOS

📖 В этой статье рассматривается решение для шести распространенных проблем, с которыми мы можем столкнуться при использовании паттерна координатора в приложениях для iOS:

Как и когда использовать дочерние координаторы?

Как быть с навигацией «Назад»?

Как передавать данные между контроллерами?

Как работать с координаторами при наличии таббара?

Как работать с segues?

Как вместо этого использовать протоколы или замыкания?

Кроме этого, в материале много практического кода для реальных примеров решения этих проблем.

@iOS Dev
🎉 В iOS 16 появилось API для обновления текущей ориентации интерфейса!

Если вы вдруг используете решение со скриншота ниже, то вы с лёгкостью сможете выпилить старое решение в новой оси.

Для этого достаточно будет использовать новый метод:

requestGeometryUpdate(.iOS(interfaceOrientations: .portrait))

👨‍💻 Обратил внимание на это Simon B. Støvring.

@iOS Dev
Что нового в MapKit в iOS 16?

MapKit — это фреймворк для отображения Apple Maps в вашем приложении. Это помогает разработчикам обеспечить поддержку навигации и многое другое.

Что же поменялось?

Новый UI — это совершенно точно изменит пользовательский опыт с 3D: не только зданиями, но и картой в целом.

Конфигурация карты. Теперь нужно использовать MKStandardMapConfiguration, MKHybridMapConfiguration или MKImageryMapConfiguration.

Улучшили оверлэй. В iOS 16 оверлеи теперь также будут отображать 3D-здания, при этом они будут скрыты при просмотре в 2D.

Режимы наложения. Вы можете затемнить остальную часть карты, чтобы сфокусироваться на нужном участке.

Look Around. Наконец-то Apple предоставила свой Look Around API для использования в наших приложениях. С ним доступен MKLookAroundSceneRequest, который принимает координаты для поиска участка LookAround. Когда он будет создан, вы можете инициализировать MKLookAroundViewController с указанием местоположения.

Что можно прочесть на эту тему?

📖 Описание фреймворка на сайте Apple.
📖 Статья с разбором фич.

🛠 Пример демо-приложения.

@iOS Dev
This media is not supported in your browser
VIEW IN TELEGRAM
😲 Посмотрите, какую красоту можно сделать с помощью эффекта увеличения в SwiftUI!

@iOS Dev
This media is not supported in your browser
VIEW IN TELEGRAM
Как добавить фото или видео на симулятор?

Есть два способа добавить мультимедиа в системное приложение Photos.

1️⃣ Если вам просто нужно быстро добавить медиафайлы в симулятор, вы можете просто перетащить медиафайл из любого места на вашем Mac в симулятор.

2️⃣ Воспользуйтесь командой xcrun simctl addmedia SIMULATOR_UUID|booted ~/path/to/file/test.jpg

Здесь path это путь к вашему файлу, а test.jpg это его название.

@iOS Dev
Простой способ понять код ошибки от сервера при выполнении запроса

😎 Для этого можно воспользоваться HTTPURLResponse.

Это подкласс URLResponse, который предоставляет методы для доступа к информации, относящейся к ответам протокола HTTP.

Всякий раз, когда вы отправляете HTTP-запросы, любые объекты ответа, которые вы возвращаете из URLSession, NSURLConnection или NSURLDownload, будут экземплярами класса HTTPURLResponse.

В свою очередь, у него есть нужный нам метод.

localizedString(forStatusCode:)

Текст кода ошибки будет соответствовать стандарту RFC 2616.

@iOS Dev
Более короткий синтаксис для работы с опциональными строками

Опциональные строки очень часто встречаются в коде Swift, например, многие объекты из UIKit отображают текст как «String?»

Во многих случаях вам нужно будет работать с этими данными, причем для случаев nil значение по умолчанию будет установлено в пустую строку.

Хотя оператор nil-coalescing (например, ??) является отличным способом достижения этой цели, определение переменной типа orEmpty может значительно помочь в том, чтобы сделать наш код чище.
Какой алгоритм использует Swift для sort()?

💡 Этот вопрос из тех, которые вряд ли вы себе могли бы задать в пятницу, но если вам интересно, то внутри реализации алгоритма используется следующее:

1️⃣ Если менее, чем 20 элементов, то применяется сортировка вставками (insertion sort). В комментариях в коде уточняется, что именно этот тип лучше подходит для небольших областей.

2️⃣ Интроспективная сортировка (Introsort), включающая в себя быструю сортировку до определённой глубины рекурсии 2*floor(log(N)).

3️⃣ И переключается на пирамидальную сортировку (она же heapsort или сортировка кучей), когда глубина рекурсии превысит заранее установленный уровень.

Больше деталей в коде swift.

@iOS Dev — теперь вы, возможно, знаете больше😅
Упрощение внедрения зависимостей с помощью паттерна «Фасад» в iOS

Если мы работаем с приложением со слишком большим количеством модулей и слишком большим количеством зависимостей в каждом из них, может быть сложно подсчитать их все, чтобы внедрить в каждый класс, на который они полагаются.

Представьте, например, что в вашем приложении есть слой, который работает с сетевыми вызовами. Для этого вам, конечно, нужен JSONDecoder, несколько объектов DispatchQueue для работы с потоками и параллелизмом, возможно, объект менеджера флагов функций и так далее.

Представьте себе, насколько сложным может стать инициализатор для этого класса, поскольку вам нужно передать все эти экземпляры, и более того, чтобы сделать его тестируемым, все они должны быть мокабельны.

📖 Эта статья предлагает отличную комбинацию двух паттернов проектирования (Facade и Dependency Injection).

Используя возможности протоколов, рассказывается, как разделить Facade, позволяя каждому классу нашего приложения иметь внутри только те инструменты, которые ему необходимы для выполнения задач.

@iOS Dev
Chisel — набор команд LLDB для помощи в отладке iOS-приложений

Недавно исследовал возможности дебаггера, и пока разбирал материалы, наткнулся на интереснейший проект. Возможно, некоторые о нём слышали, а некоторые даже используют. Вкратце напишу, что же это за инструмент.

Для LLDB есть возможность импортировать подключаемые модули, что может значительно расширить возможности отладки. Chisel, инструмент, который содержит множество плагинов lldb — например, команду border, которая добавляет яркую рамку к UIView, чтобы вы могли быстро найти его на экране, и все эти плагины работают благодаря умному использованию команд e/po.

Несколько примеров команд, кроме border:

🟢 pviews — рекурсивно просматривает и выводит описание для key window.

🟢 visualize — можно открыть UIImage, CGImageRef, UIView, CALayer, NSData (для картинки), UIColor, CIColor, или CGColorRef в Preview.app на вашем маке.

🟢 fv — ищет вьюху в иерархии, чьё имя класса соответствует заданной регулярке.

🟢 presponder — выводит всю responder chain, начиная с данного объекта.

🟢 и много чего ещё.

Кстати, ещё с помощью Chisel можно пилить собственные команды и использовать их для отладки.

🛠 Ссылка на #opensource проект: Github.

Делюсь также и двумя крутейшими статьями про LLDB, благодаря одной из которых я и узнал об этом инструменте:

📖 Расширенные приемы lldb для Swift — внедрение и изменение кода на лету.

📖 Танец в отладчике - вальс с LLDB. Пусть материал вышел и давно, но всё ещё может быть нам полезен.

👍 Рекомендую прочесть и сохранить себе в избранное.

@iOS Dev
Посетитель или же Visitor — это один из паттернов, описанных в учебнике «Банды четырех», под названием «Design Patterns: Elements of Reusable Object-Oriented Software».

Одним словом, шаблон может быть полезен, когда необходимо иметь возможность выполнять какие-либо однотипные действия над группой несвязанных объектов разных типов.

Или, другими словами, расширить функциональность за счет какой-либо операции, однотипной или имеющей единый источник. При этом структура и реализация расширяемых типов не должны пострадать.

📖 Данный материал предназначен для знакомства с этим приемом. Автор подчёркивает, что знает о недостатках кода и возможностях его улучшения.

В любом случае, практически у любого паттерна есть свои преимущества и недостатки, и перед его использованием всегда следует подумать и принять решение осознанно.

Паттерны — это, с одной стороны, способ обобщения методов программирования для облегчения чтения и обсуждения кода. С другой стороны, есть способ решения проблемы (иногда искусственно вводимый). И, конечно, ни в коем случае не стоит фанатично доводить код до всех известных паттернов только ради самого факта их использования.

@iOS Dev
Создание переиспользуемой системы для сложных URL-запросов с помощью Swift

📖 В статье описывается, как обрабатывать элементы запроса, HTTP-заголовки, тело запроса и многое другое простым декларативным способом.

Большинство разработчиков просто пытаются работать с запросом напрямую, но построение отдельных элементов запроса может быть непростой задачей.

Foundation имеет встроенный механизм для этого — URLComponents с его свойством queryItems, но может оказаться довольно хлопотно каждый раз настраивать это для каждого запроса.

Поэтому в этой статье автор рассказывает, как построить многоразовую, гибкую систему, которая может пригодиться для сложных запросов.

@iOS Dev
iOS Dev
Photo
Каким будет результат выполнения со скриншота выше?
Anonymous Quiz
1%
3
54%
2
18%
1
1%
0
2%
nil
13%
Код не скомпилируется
10%
Будет ошибка Index out of bounds