Telegram Web Link
Grand Central Dispatch: от определения к низкоуровневым примитивам

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

В серии статей ниже Alex Shchukin рассматривает основные понятия, как, например, очереди, как с ними работать, иссследует dispatch source и затрагивает DispatchIO (который не является супер популярным инструментом).

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

А для самых любопытных Алекс расскажет, как реализовать примитивы GCD самостоятельно.

Материалы доступны здесь:

1️⃣ GCD: Очереди и методы.

2️⃣ DispatchWorkItem и Quality of Service (тот самый QoS).

3️⃣ DispatchGroup и concurrentPerform.

4️⃣ Синхронизация: семафоры, барьеры (и не только).

5️⃣ DispatchSource и Target Queue Hierarchy.

👨‍💻 Примитивы GCD в деталях — в этой статье автор использует низкоуровневые примитивы, чтобы разобраться, как на самом деле работает GCD.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Протоколы ошибок, о которых вы могли не знать: Localized​Error, Recoverable​Error, Custom​NSError

Несмотря на то, насколько мы все знакомы с Error, на удивление немногие из нас могут быть знакомы с другими протоколами ошибок, появившимися в SE-0112. Например, когда вы в последний раз сталкивались с LocalizedError в дикой природе? А что насчет RecoverableError?

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

🔘 LocalizedError. Специализированная ошибка, предоставляющая локализованные сообщения с описанием ошибки и причиной ее возникновения.

🔘 RecoverableError. Специальная ошибка, которую можно исправить, предоставив пользователю несколько возможных вариантов восстановления.

🔘 CustomNSError. Специализированная ошибка, предоставляющая домен, код ошибки и user-info dictionary.

📖 В этом объёмном материале автор разбирает на примерах, что и когда лучше использовать.

@iOS Dev
This media is not supported in your browser
VIEW IN TELEGRAM
⌨️ А у нас интересный факт, посмотрите, как устроен эпловский календарь изнутри!

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

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

Полезно посмотреть на то, как решают типовые проблемы инженеры яблочной компании, и как они, например:

1️⃣ В системном калькуляторе, сетку с кнопками расставили с помощью фреймов.

2️⃣ А вот тут можно прочесть про то, как устроено приложение App Store.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Рефакторинг вашего кода на Swift: лучшие практики и советы для достижения успеха

ℹ️ Рефакторинг кода — это часть пути к созданию надежных приложений.

Неважно, опытный вы или нет: каждый разработчик рефакторит свой код, чтобы улучшить его качество или читабельность.

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

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

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

В этом процессе он выделил несколько основных этапов:

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

🔘 Создание уверенности в рефакторинге. Наши товарищи здесь это, по возможности, модульные тесты и конечно же, GIT.

🔘 Маленькие шаги к финальной цели.

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

Не стоит пренебрегать помощью Xcode в рефакторинге.

Конечно, вы не всегда можете предотвратить повторный рефакторинг, но вы можете вырасти как профессионал, постаравшись предотвратить свои прошлые ошибки.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Заполнение столбцов градиентом с использованием Swift Charts

🆕 С новыми Swift Charts очень легко создавать простые диаграммы для визуализации данных в наших приложениях.

Фреймворк также предоставляет множество вариантов настройки, чтобы наши диаграммы по-настоящему выделялись.

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

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

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

@iOS Dev
⌨️ Как можно передавать данные между приложениями iOS?
Полегче, посложнее и для хакермэнов.

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

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

🔘 App Groups, пожалуй, самое очевидное из списка, и содержащее свой принцип в названии.

🔘 UIActivityViewController — возможно и не первое, что приходит на ум, но существующее решение. Поддерживается с iOS 6.0+ и реализуется с помощью application:openURL:sourceApplication:annotation:.

🔘 Custom URL Schemes.

Чтобы включить схему URL-адресов в нашем приложении, мы должны добавить пользовательскую схему URL-адресов на вкладку информации. Откройте, например, Safari и введите [URL_scheme]://параметр, чтобы открыть ваше приложение.

🔘 Share Extension. iOS 8.0+. Это тип расширений, как, например Today, Action, Custom Keyboard и так далее.

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

🔘 Shared Keychain Access. iOS 3.0+.

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

🔘 Custom Pasteboards. iOS 3.0+. Другой объект в том же или другом приложении считывает данные из pasteboard и представляет их пользователю в новом месте; обычно это происходит, когда пользователь запрашивает операцию вставки.
В этом твиттер-треде разработчик делится своим опытом использования этого решения.

🔘 Darwin Notification Center (в этой статье есть и пример использования, и даже код).

🟡 iOS Photos! Что? Да! Посмотрите, как в этом репозитории нашли изысканное решение, хотя и может возникнуть два вопроса.

@iOS Dev — шарим данные (и пост 😎).
Please open Telegram to view this post
VIEW IN TELEGRAM
Архитектура приложения и композиция объектов в Swift

Композиция объектов — это основная концепция объектно-ориентированного программирования.

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

📖 В этой статье автор рассказывает, как спроектировать такую ​​архитектуру.

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

@iOS Dev
Apple Security Bounty Program: поиск уязвимостей за вознаграждение

⌨️ Apple обновила раздел, посвященный поиску проблем в системе.

Выплаты вознаграждения Apple Security Bounty производятся по собственному усмотрению Apple и зависят от типа проблемы, достигнутого уровня доступа или выполнения, а также качества отчета.

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

🔘 Например, сетевая атака может принести от $ 5 000 до $ 150 000.
Пример: щелкнув ссылку в сообщении iOS Mail, вы можете загрузить удаленный контент, когда этот параметр отключен.

🔘 А в случае, если вы знаете способ, как обойти режим блокировки и определённых уровней защиты, вы сможете получить вплоть до $ 2 000 000.

📖 Подробнее о категориях написано здесь (любопытно узнать, чего Apple боится больше всего).

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Разбор различных политик кэширования при работе с URLRequest в Swift

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

В зависимости от выбранной политики поведение может и правила управления контентом изменяются.

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

@iOS Dev
Практический опыт работы с UICollectionView: создание приложения для просмотра фотографий с помощью Flickr API

UICollectionView упрощает добавление кастомных лэйаутов и переходов между ними, такими, как в Photos.

Вы не ограничены только стэком или гридом, поскольку UICollectionView настраиваемы. Вы можете использовать их для создания круговых макетов, макетов в стиле cover-flow, макетов в стиле новостей и почти всего, что только можно придумать!

📖 В этом материале вы получите практический опыт работы с UICollectionView, создав приложение для просмотра фотографий на основе сетки. Попутно вы узнаете, как:

😂 Добавлять свои хэдеры к UICollectionView.

😂 Легко перемещать ячейки путем их перетаскивания.

😂 Реализовывать выделение одной ячейки для показа вьюхи с деталями.

😂 Реализовывать выделение нескольких ячеек.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Как добавить маску для изображения в виде многоугольника?

Мы все часто используем свойство cornerRadius в CALayer, чтобы сделать наш UIImageView закруглённым в соответствии с дизайном.

⭐️Но что делать, если дизайнер хочет чего-то большего, например, звезду или многоугольник?

📖 Этот пример подскажет, как использовать UIBezierPath для создания динамического многоугольника, который будет маской для UIImageView, как в примере на картинке.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Как изменить стиль отступов простым способом?

Для этого можно воспользоваться комбинацией Ctrl+Shift+«Клик мышкой» для создания мультикурсора.

😎 А затем если нужно, уже настраивайте отступы или же используйте Enter по вашему вкусу.

#xcode #shortcuts

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Apple Wallet: поддерживаемые типы штрих-кодов и обходные пути

К сожалению, Apple Wallet поддерживает только ограниченный набор типов штрих-кодов.

Конечно, поддержка более современных 2D-штрих-кодов лучше, но ограничения Apple ведут к сложностям.

📖 В этом материале автор делится найденной информацией об Apple Wallet и о том, почему программы членства/лояльности могут не предлагать добавить цифровую карту в Apple Wallet.

@iOS Dev
Бесконечный скролл в iOS приложении: UITableView + REST API

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

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

📖 В этом руководстве вы узнаете, как добавить бесконечную прокрутку в приложение iOS, которое извлекает данные из REST API.

Кстати, ещё вы познакомитесь с Prefetching API. Это адаптивная технология, которая выполняет оптимизацию, направленную на улучшение производительности прокрутки.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
👩‍💻 Xсode, pbxproj, IBoutlet и IBAction

Те, кто давно читают это канал, в курсе, что иногда я пишу о повседневных вещах, названия и предназначение которых не всегда очевидны. Привет камню из Хаблингбо в Швеции!

Сегодня пятница, и поэтому позволю себе в двух предложениях рассказать, почему наша среда разработки называется Xcode, а не iCode или iBuilder (хотя последнее не так далеко от правды).

🕔 Xcode начинал свою жизнь как связка двух приложений: Project Builder и Interface Builder.

Эти инструменты были написаны для NeXT Computer, Inc. Стива Джобса для их операционной системы NeXTSTEP.

После покупки Apple NeXT, компания начала превращать NeXTSTEP в OS X, они также начали адаптировать Project Builder и Interface Builder к своей новой операционной системе.

Первоначально эти два инструмента сохранили свои старые названия, но в OS X Panther (10.3) Apple заменила Project Builder переработанной версией под названием Xcode.

В нескольких версиях Xcode продолжал поставляться вместе с Interface Builder, но связь между этими двумя инструментами всегда была сложной, поэтому в Xcode 4 (выпущенном между 10.6 и 10.7) они наконец объединили Interface Builder с Xcode.

Точно так же, как происхождение OS X как NeXTSTEP выдается префиксами «NS» во многих API, так и происхождение Xcode как Interface Builder и Project Builder выдается аббревиатурами в приложении. «IB» в «IBOutlet» и «IBAction» является аббревиатурой для «Interface Builder», а основной файл информации о проекте в пакете xcodeproj имеет расширение «pbxproj» для «Project Builder X Project».

⌨️ Поэтому X означал написание приложений для OS X. А в будущем, что ж, кто знает, может и появится iCode (когда-нибудь).

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Как синхронизировать код и отрисовку с помощью CADisplayLink?

Многие новички считают, что Timer — это отличный (и единственный) способ управлять запущенными приложениями или играми, чтобы код выполнялся каждый раз, когда экран перерисовывается.

Логика довольно очевидна: обновляйте приложение каждые 60 секунд, и отрисовка будет плавной. Вот только...

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

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

Обычно это 60 кадров в секунду, но на некоторых более новых устройствах это 120 кадров в секунду.

Кстати! CADisplayLink имеет два полезных свойства: preferredFramesPerSecond и isPaused.

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

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

📖 Больше инфы: в доке эпла, или вот в этих примерах — раз, два.

@iOS Dev
Please open Telegram to view this post
VIEW IN TELEGRAM
Пара слов про 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
2025/02/22 18:18:16
Back to Top
HTML Embed Code: