iOS разработчик, который делится фишками, своим опытом и опытом других. В этом канале вы сможете найти истории из жизни, подходы к реализации а также новости и тренды из мира iOS-разработки Авторский канал, iOS разработка
CMD+C CMD+V).
🥷 Но есть и другой путь: выделите код, нажмите Refactor -> Extract to method и укажите название нужного метода.
Кстати, что такое #warning и зачем он нужен — можно прочитать вот тут.
@iOS Dev — о простых вещах понятными словами.UUID довольно просто:
let identifier = UUID()
print(identifier)
Результатом будут 128 случайно сгенерированных битов (если вы хотите вывести значение строки, то можно использовать identifier.uuidString).
Но так ли они случайны?
Для этого мы можем обратиться к стандарту RFC 4122, который содержит целых 5 различных подходов к созданию этих идентификаторов.
UUID — это просто 128-битные числа, используемые для уникальной идентификации элементов при разработке ПО. Их каноническое текстовое представление это пять групп шестнадцатеричных символов, разделённых дефисами: 8-4-4-4-12.
Что-то вроде: 3422b448-2460-4fd2-9183-8000de6f8343 (подозреваю, что вы где-то такое уже видели).
В эту, на первый взгляд, случайную серию шестнадцатеричных символов встроена информация о реализации UUID.
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
Значения на позициях M и N однозначно определяют версию и вариант UUID.
Версия
Номер версии идентифицируется путем просмотра старших 4 битов значения в позиции M
Вариант
Поле варианта определяет расположение информации, встроенной в UUID. Интерпретация всех остальных битов в UUID зависит от значения варианта.
😎 В iOS нас больше всего интересует RFC 2144 версии 4
Более ранние версии универсальных уникальных идентификаторов полагались на дату и время, MAC-адрес устройства и идентификаторы namespace (можно прочесть ниже).
Всякий раз, когда структура UUID генерирует новый идентификатор, она в основном делает 122 броска кубика (или костей 😅), чтобы получить 122 случайных бита. Остальные ведь нужны нам для идентификации версии и варианта, помните?
Немного математики говорит нам, что всего у нас 3 ундециллиона идентификаторов, или 5,3 триллионов триллионов триллионов (ладно, чтобы было проще 5.3 и 36 нулей). ЭТО МНОГО!
Количество идентификаторов, которые необходимо сгенерировать, чтобы иметь 50-процентную вероятность коллизии (т. е. два одинаковых идентификатора), составляет 2,71 квинтиллиона, или 2,71 в 1018 степени. А я говорил, что они не на 100% уникальны!
На это потребуется 85 лет, если вы будете генерировать 1 миллиард идентификаторов в секунду.
Внимание, спойлер финальной серии сериала «Лучше звоните Солу»!
📺 Почти столько же, сколько дали Солу, чёрт возьми!
Чтобы сохранить все эти идентификаторы, вы должны создать файл размером около 45 экзабайт или 45 миллионов терабайт, что намного больше, чем самые большие БД в мире.
UUID является универсально уникальным для всех устройств, баз данных, iPhone и т. д. в мире. Вероятность создания одного и того же UUID дважды ничтожно мала (но есть).
Остальные версии UUID
1️⃣ Версия 1. На основе времени + уникальный или случайный идентификатор хоста
2️⃣ Версия 2 (безопасность распределенной вычислительной среды) — менее распространена, чем первая, юзает некий специальный идентификатор, уникальный для системы.
3️⃣ Версия 3. На основе имени + хэш MD5.
4️⃣ Версия 4. PRNG (аббревиатура pseudo-random number generator). Использует большинство современных языков программирования.
5️⃣ На основе имени + хэш SHA-1.
По традиции для расширения кругозора можно прочесть следующее
📖 Документация Apple
📖 How To Generate a Random Unique Identifier
📖 Understanding How UUIDs Are Generated
📖 RFC 4122
@iOS Dev — вот этот канал точно уникален на 100% (но есть ничтожная вероятность, что посты отсюда вы ещё где-то увидите 😁)out of memory exception. Так в чём же дело?
Использование памяти нашим приложением резко возрастает, когда мы начинаем показывать HD-изображения на экране (даже одно уже может внести существенный импакт для увеличения используемой памяти).
Главное, что нужно запомнить, использование памяти ≠ размеру файла. И вот почему.
Использование памяти связано с размерами изображения, а не с размером файла (Session 416, WWDC 2018).
Всё дело в том, что для отображения изображения на экране, iOS сначала необходимо декодировать и распаковать изображение. Обычно 1 пиксель декодированного изображения занимает 4 байта памяти — 1 байт для красного, 1 байт для зеленого, 1 байт для синего и 1 байт для альфа-канала (да-да, тот самый SRGB). Например:
(3648 * 5472) * 4 bytes ≈ 80MB
И именно это значение и будет отображаться, когда мы будем чекать, что же происходит в приложении.
Что со всем этим делать?
Разработчики в этой статье пробовали менять масштаб и перерисовать изображение, но это не помогло. Это связано с тем, что операции для изменения размера для UIImage дороги. В процессе изменения размера iOS по-прежнему будет декодировать и распаковывать исходное изображение, вызывая нежелательный скачок памяти.
Одно из решений, которым делятся инженеры Apple — юзать даунсэмплинг.
Мы можем использовать ImageIO для изменения размера изображения перед его отображением на экране. По факту, для нас это выльется только в стоимости ресайзинга исходной картинки. Вот здесь можно чекнуть сниппет.
Флаги, которые можно использовать
1️⃣ kCGImageSourceShouldCache — когда для этого флага установлено значение false, мы сообщаем основному фреймворку, что нам нужно только создать ссылку на источник изображения и не хотим декодировать изображение сразу при создании объекта CGImageSource.
В ситуации, когда у вас нет доступа к пути к источнику изображения, вы можете создать объект CGImageSource, используя инициализатор CGImageSourceCreateWithData().
2️⃣ kCGImageSourceShouldCacheImmediately — этот флаг указывает, что декодировать изображение нужно именно в тот момент, когда мы запускаем процесс понижения дискретизации.
3️⃣ kCGImageSourceCreateThumbnailWithTransform — установка этого флага в значение true очень важно для сохранения исходной ориентации.
Подводные камни (а как же без них)
Имейте в виду, что даунсэмплинг — это процесс, который потребляет ресурсы процессора. Таким образом, по-прежнему предпочтительнее использовать правильно масштабированный источник изображения, а не понижать дискретизацию HD-изображения. Другими словами, вы должны использовать даунсэмплинг только тогда, когда вам нужно отобразить изображение, размер которого намного превышает требуемый размер на экране.
Важные моменты
⚪ Помните, что память — это конечный и общий ресурс.
⚪ Используйте встроенный в Xcode мониторинг.
⚪ Позвольте iOS выбрать ваши форматы изображений, когда это возможно.
⚪ Используйте ImageIO для понижения разрешения изображений (помните про подводные камни).
⚪ Выгружайте крупные ресурсы, которые находятся за пределами экрана.
⚪ Не игнорируйте графики памяти (memory graphs), чтобы лучше понять, что происходит.
Что почитать ещё?
📖 Deep Dive into iOS Memory.
📖 Reducing Memory Footprint When Using UIImage.
📺 Session 416, WWDC 2018.
🔗 developer.apple.com/documen…gesource.
@iOS Dev — отвечаем на вопросы.Natural Language эту задачу выполняет NLLanguageRecognizer.
С помощью NLLanguageRecognizer вы можете получить наиболее вероятный язык для фрагмента входного текста или набор возможных языков-кандидатов со связанными с ними вероятностями.
💡 Чтобы сгенерировать несколько возможных прогнозов, используйте метод languageHypotheses(withMaximum:).
One more thing
Хотя этот шаг не обязателен, вы можете предоставить информацию о тексте, который хотите идентифицировать, если вы уже что-то о нем знаете.
Например, если вы знаете, что язык должен входить в определенный набор языков, вы можете указать это ограничение.
recognizer.languageConstraints = [.french, .russian, .german, .italian]
recognizer.languageHints = [.french: 0.5, .russian: 0.9, .german: 0.8, .italian: 0.6]
let constrainedHypotheses = recognizer.languageHypotheses(withMaximum: 2)
print(constrainedHypotheses)
@iOS Dev — is it some reebok or some nike?ViewController, анимируя CollectionViewCell в ImageView. На гифке пример того, как это выглядит.
Это руководство рассчитано на то, что у читателя может не быть опыта работы с подобными переходами.
⏳ И, поскольку задача не слишком простая, то если вы обнаружите проблемы с реализацией в своем собственном проекте, наберитесь терпения и постарайтесь изо всех сил.
Если вы будете следовать инструкциям шаг за шагом, все должно быть довольно гладко.
После этого вы можете попробовать даже внедрить решение в свой собственный проект.
Автор материала признаётся, что вдохновлялся Airbnb для iOS и в основном пытался сделать ту же анимацию, что и при открытии экрана «Experience» (на вкладке «Explore»).
🛠 Проект с итоговым результатом находится на Github.
@iOS DevTimelineView, представленный в iOS 15, можно использовать для изменения объектов с течением времени.
📖 В статье для примера используется фигура звезды, определенная ранее, и показывается, как реализовать анимацию её поворота.
Вращение можно комбинировать вместе с изменением размера фигуры и вращением в 3D-пространстве для создания интересных эффектов.
@iOS DevUILabel уже немного сложнее, чем изменение цвета этого лейбла.
📖 С помощью этой статьи вы сможете создать расширение, которое управляет не только высотой строки, но и установкой межбуквенного интервала, подчеркивания и зачеркивания.
🚀 В материале затрагиваются неочевидные моменты при работе со строками и объясняется, как можно избежать некоторых сложностей.
🛠 Код на GitHub.
@iOS Dev