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

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

#ios #mobile #swift
加入频道
Пара слов про Ad hoc

Если не все, то каждый второй разработчик использовал Ad hoc профили для распространения приложений.
*Разработчики iOS, участвующие в стандартной программе, могут распространять приложение за пределами App Store на 100 различных устройствах в целях тестирования c помощью этих профилей.

Но знаете ли вы, что именно означает Ad hoc?

📖 Ad hoc — латинская фраза, означающая «к этому», «специально для этого», «по особому случаю».

Чаще всего её используют для способа решения специфической задачи. Например, закон ad hoc — закон, принятый в связи с каким-то конкретным инцидентом и не вписывающийся в обычную практику.

Также ad hoc — это подразделение в организации, созданное для решения какой-то специальной, узкой задачи.

Этот термин используется в политологии, науке, философии, даже в армии.

А наши коллеги, занимающиеся администрированием, вполне могут использовать термин для обозначения беспроводных ad-hoc-сетей, не имеющих постоянной структуры, в которых клиентские устройства соединяются «на лету».

@iOS Dev — неизвестное об известном, как говорится, по особому случаю✈️.
Please open Telegram to view this post
VIEW IN TELEGRAM
Каждый, кто работал со временем в iOS (и не только) может попасть в ловушку заблуждений

Вот некоторые из них:

🔘 В сутках всегда 24 часа.
🔘 Системные часы всегда будут установлены на правильное местное время.
🔘 Если системные часы неверны, они, по крайней мере, всегда будут отставать на постоянное количество секунд.
🔘 Часы сервера и часы клиента всегда будут установлены на одно и то же время.
🔘 Ну, или часы сервера и часы клиента всегда будут установлены примерно на одно и то же время.
🔘 Хорошо, но время на часах сервера и время на часах клиента никогда не будут отличаться на несколько десятков лет.
🔘 Если часы сервера и часы клиента не синхронизированы, они, по крайней мере, всегда будут рассинхронизированы на постоянное количество секунд.
🔘 Время не имеет начала и конца.
🔘 Наименьшая единица времени — одна секунда.
🔘 Хорошо, одна миллисекунда.
🔘 Ок, тестирование может потребовать установки системного времени в значение, отличное от правильного местного времени, но в производстве это никогда не потребуется. 😎
🔘 В месяцах 28, 29, 30 или 31 день.
🔘 В одном и том же месяце везде одинаковое количество дней!
🔘 Смещение местного времени (от UTC) не изменяется в рабочее время.
🔘 Thread.sleep(1000) спит в течение 1000 миллисекунд.
🔘 Ладно. Если нет, то Thread.sleep(1000) спит в течение >= 1000 миллисекунд.
🔘 В каждой минуте 60 секунд.
🔘 Время всегда идет вперед.
🔘 Разница между текущим временем и одной неделей от текущего времени всегда составляет 7 * 86400 секунд.
🔘 Если вы отображаете дату, то отображаемое время имеет ту же вторую часть, что и хранимое время.
🔘 Или тот же год.
🔘 Ну, по крайней мере, числовая разница между отображаемым и хранимым годом будет меньше 2.
🔘 Существует только 24 часовых пояса.
🔘 Я могу легко поддерживать список часовых поясов самостоятельно.
🔘 Годы состоят из 365 или 366 дней.
🔘 Вы можете определить часовой пояс по городу/селу.
🔘 Время идет с одинаковой скоростью на вершине горы и на дне долины.
🔘 Один час длится столько же, сколько и следующий во всех системах времени.
🔘 Вы можете рассчитать, когда будут добавлены високосные секунды.
🔘 Программа никогда не будет работать на космическом корабле, вращающемся вокруг черной дыры. (Вы помните, что это всё заблуждения?)

Список основан на двух статьях: вот на этой и вот этой.

📖 Ах да, крутой материал про работу с датами в iOS специально для тех, кто дочитал пост.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Swift Concurrency — вещи, о которых вам не говорят

⭐️ Делюсь с вами материалом-жемчужиной за авторством Wojciech Kulik. Автор рассматривает многие аспекты, которые обычно предлагается использовать из коробки, не задумываясь о том, как именно это работает внутри.

Swift Concurrency предоставляет действительно хороший способ написания асинхронного кода.

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

К сожалению, вокруг параллелизма много ловушек, и нет… компилятор не все проверяет.

Даже после проведения тестов, чтения документации и просмотра WWDC автор статьи всё еще не полностью уверен в Swift Concurrency и приводит свои мысли и исследования в следующих разделах:

🔘 Async-Await — основные проблемы.

🔘 Async — что это в целом значит для приложения?

🔘 Actor — тихий убийца вашего кода.

🔘 Tasks — скрытое бутылочное горлышко.

🔘 Swift Concurrency + Симулятор = Нет параллелизма.

📖 В этом материале говорится, почему Swift Concurrency — это не только добавить async-await и проверить, компилируется ли код.

Есть много скрытых проблем, которые требуют глубокого понимания, несмотря на то, что документация и туториалы предполагают, что это «дополнительные» знания, а не то, что необходимо знать перед использованием Swift Concurrency.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Невозможная отрисовка элементов в сетках на SwiftUI: код и примеры
Пусть в канале я практически всегда рассказываю о приёмах в UIKit, но в редких случаях хочется показать и то, что можно делать на SwiftUI.

📖 В этой статье рассматриваются основы, а затем автор выходит за рамки обычных сеток с однородными строками и столбцами.

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

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

@iOS Dev
Я всё-таки принял участие в конкурсе Telegram, но к сожалению, остался за чертой призёров. Ниже мои мысли по поводу конкурса.

Часть первая или что сделано


Реализовал расчёт контрольных точек в фоновом режиме для плавных скруглений и собственно расчёта скорости (ширины линии).

Собственный colorpicker (с цветами, кастомными слайдерами и так далее). Плюс магнифаер (когда увеличиваем объект под пальцем, условно, и выбираем оттуда цвет).

Карандаш сделан с помощью текстуры и cashapelayer, по факту это маска, которой происходит отрисовка.

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

Реализовал текстовый редактор с помощью catextlayer и кучи сложных моментов (как мне показалось). Типа отрисовка переходов между строками и скруглений (layoutmanager и кто с ним работал, поймёт о чём речь).

Адски страдал над анимацией карандашей и таймингов (ну чтобы они все нормально скрывались и увеличивался выбранный). Ах да, там же ещё ширина выбранного инструмента (толщина)... Это дополнительный элемент на объекте карандаша, ну и очень много всяких мелочей чисто по анимациям.

Undo manager можно было пилить с помощью системного, но я бы по времени не уложился. Поэтому по факту добавляется/удаляется последний слой (и всё на слоях).

Запилил сохранение изменений и с видео тоже. Думаю, жюри даже не посмотрело (но кто знает).

Ну и множество всего, кроме этого.

Часть вторая, что сказали жюри

Конкурсное задание не выполнено, работа над приложением не окончена.

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

Текущая реализация приложения не обеспечивает пользователю возможность отрисовки высококачественной, плавной, четкой линии – при отрисовке линия появляется с задержкой, рывком.

Часть третья, что думаю я

Работ было очень много, срезали, если линия не рисуется мгновенно.

Финал.

Конечно, я немного разочарован таким итогом. Но в целом опыта у меня прибавилось, и когда-нибудь, надеюсь, мне всё это пригодится.
А поскольку канал у нас образовательный (я очень хочу верить в это, и делаю всё необходимое), то после того, как я порефлексировал, собрался, в итоге оформил свои мысли в виде отдельного поста на хабре.

📖 Очень много кода, несколько необычных решений и примеров уже доступны вот тут:

⌨️ Большой пост на хабре.

❤️‍🔥Спасибо всем за вашу поддержку, коллеги.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Холодный и тёплый запуск приложения — о чём речь?

Для начала пара слов о том, что такое «активация приложения». Она происходит, когда пользователь нажимает на иконку или иным образом возвращается в ваше приложение.

ℹ️ В iOS активация может быть либо запуском (launch), либо возобновлением (resume).

Launch — начало процесса, а resume — это когда в вашем приложении уже есть активный процесс, даже если он приостановлен.

Resume, как правило, намного быстрее, и работа по оптимизации запуска и возобновления отличается. В macOS система, например, не завершает ваш процесс в рамках обычного использования.

Что же такое холодный и тёплый запуски?

Активация вашего приложения значительно зависит от предыдущих действий на устройстве.

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

Когда система определяет, что нужен запуск, это обычно называют «теплым запуском».

В iOS ваше приложение обычно вытесняется из памяти, чтобы предоставить foreground-приложению больше ресурсов.

Фреймворки также могут потребовать повторного запуска. Этот сценарий или запуск сразу после загрузки часто называют «холодным запуском».

Более корректно размышлять о тёплом и холодном запусках как о спектре.

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

📺 Для большего погружения рекомендую это видео с WWDC.

@iOS Dev
This media is not supported in your browser
VIEW IN TELEGRAM
Простой способ проверить тип в Swift

ℹ️ Кроме as? можно использовать оператор проверки типа is, чтобы проверить, относится ли экземпляр к определенному типу подкласса.

Оператор проверки типа вернёт true, если экземпляр относится к этому типу подкласса, и false, если нет.

В приведённом примере magicBool может быть либо Int, либо String.

Кстати, я изучаю возможности инструментов Apple и, как видите, гифки выходят на новый уровень!

@iOS Dev
This media is not supported in your browser
VIEW IN TELEGRAM
iOS Clean architecture на примере реализации фичи с использованием MVVM, Repository, URLSession

📖 В этом материале автор расскажет про:

1️⃣ Реализацию шаблона проектирования MVVM очень простым способом без дополнительных фреймворков.

2️⃣ Полностью несвязанную систему загрузки для любого источника данных с подходом Repository.

3️⃣ Создание клиента на базе URLSession.

4️⃣ Корректное использование API.

И, что еще более важно, про создание функции, которую можно изолировать, смоделировать и протестировать на каждом уровне.

🛠 Бонус! Репозиторий с проектом, где вы сразу можете посмотреть на решение.

@iOS Dev
Как добавить поддержку файлов с любым расширением в вашем приложении?

🔆 Представьте ситуацию, что вы делаете кастомный видеоредактор или архиватор и нужно поддерживать не только стандартные, но и свои файлы в приложении.

Если необходимо заставить систему распознавать файл, вы можете использовать Document Types и Exported Type Identifiers.

В документации Apple четко указано, что новый тип должен соответствовать хотя бы одному из public-типов.

public.data— базовый тип для byte streams.

public.content — базовый тип для смешанного контента. Например, файл PDF содержит как текст, так и специальные данные форматирования.

📖 Автор этой статьи доступно объясняет не только, как поддерживать кастомные типы данных и шарить их, но и как открывать эти файлы в вашем приложении.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Подборка необычных эффектов в IOS с конференции Tokyo iOS Meetup
Stack Overflow говорил, что это будет просто (спойлер: это оказалось отнюдь не просто)

Тим Оливер, в прошлом разработчик Realm и pixiv, делится своим опытом реализации сразу нескольких необычных вещей в iOS, кажущихся на первый взгляд тривиальными, но на самом деле содержащими непростую реализацию.

📺 Видео с конференции доступно здесь.

@iOS Dev
Рекурсия в Swift: определение, примеры, код
Примером рекурсии в реальном мире может быть размещение двух параллельных зеркал друг против друга. Любой объект между ними будет отражаться рекурсивно.

Среди плюсов их использования:

🔘 Это делает наш код короче и чище.
🔘 Рекурсия требуется в задачах, касающихся структур данных и продвинутых алгоритмов, таких как обход графа и дерева.

Минусы, впрочем, тоже есть:

🔘 Это занимает больше места в стеке по сравнению с итеративной программой.
🔘 Реализация использует больше процессорного времени.
🔘 Отладка может быть более сложной по сравнению с эквивалентной итеративной программой.

📖 В этой статье наглядно объясняется, что такое рекурсивные функции в Swift и объясняется работа таких функций на примерах

@iOS Devрекурсия в Swift с примерами в этом посте
Please open Telegram to view this post
VIEW IN TELEGRAM
Async/await в Swift c примером использования на базе существующего проекта

Async await является частью новых изменений структурированного параллелизма, которые появились в Swift 5.5 во время WWDC 2021.

ℹ️ Параллелизм в Swift означает возможность одновременного запуска нескольких фрагментов кода.

Пусть это и очень упрощенное описание, но оно должно дать вам представление о том, насколько важен параллелизм в Swift для производительности ваших приложений.

📖 Этот материал раскрывает следующие понятия:

🔘 Определение async.

🔘 Определение await.

🔘 Для чего нужен структурированный параллелизм (structured concurrency).

🔘 Добавление async-await в существующий проект.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Техники перехода между разными экранами: от простых к интерактивным

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

1️⃣ Создание кастомных переиспользуемых переходов.

2️⃣ Переходы между экранами: добавляем естественности.

3️⃣ Переходы между экранами: задание произвольного размера.

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

🛠 Репозиторий с примерами кода из статьи.

@iOS Dev
This media is not supported in your browser
VIEW IN TELEGRAM
Реализация плавного перехода между цветами в Swift

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

📖 Этот пример был создан с использованием изображений из Unsplash для создания желаемого эффекта.

🛠 Посмотреть на решение в коде можно на Github.

@iOS Dev