SWIFTER | Блог про Swift
268 subscribers
4 photos
30 links
Swift для каждого на простом и понятном языке. Уроки программирования с интересными кейсами из реальных проектов, без воды и сложных терминов.
Download Telegram
Опциональное декодирование элементов массива с помощью Decodable

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

Для этого нам понадобится создать дженерик класс FailableDecodable с типом, который нужно будет десериализовать. Далее, используя singleValueContainer, получаем контейнер с декодера и пробуем получить нужную нам модель с помощью try? container.decode(Base.self).

Чтобы выполнить само декодирование элементов массива, вместо обычного типа данных, указываем тип в обертке с FailableDecodable и проходимся по нему с помощью compactMap, получая переменную base.

Таким образом, сначала мы получили массив с опциональными элементами, где могут встречаться nil, а дальше профильтровали этот массив, оставив только non-nil значения.

Source
#tips #decodable #intermediate
Как использовать tableHeaderView вместе с auto-layout?

Казалось бы, задача тривиальная, но на деле все немного сложнее. Для ее решения нам понадобится создать два метода: setTableHeaderView (1), updateTableHeaderViewIfNeeded (2). Логика следующая:

1. Мы создаем width constraint, где ширина tableHeaderView равна ширине самой tableView. Это позволит таблице получить нужный размер, когда мы будем вызывать layoutIfNeeded. Дополнительно мы центрируем наш хедер и крепим его вверху таблицы.

2. Реагируем на изменения размера в случаях вроде поворота девайса. Для этого позволяем tableView управлять frame самостоятельно, точно так же, как для ячеек. Достигается это с помощью beginUpdates/endUpdates.

Метод setTableHeaderView вызываем, когда делаем layout для нашего UI - viewDidLoad, а updateTableHeaderViewIfNeeded в viewDidLayoutSubviews.

Source
#tips #tableView #basic
Асинхронные скрипты на Swift

Да, на Swift можно писать скрипты и, используя некоторые хитрости, делать это достаточно эффективно. А с добавлением executableTarget в SPM задача стала еще проще.

Проблема возникает тогда, когда вы пытаетесь сделать скрипт асинхронным (например, получить или обновить какие-то данные в сети). В таком случае нужно заставить скрипт ждать выполнения асинхронной задачи и только после этого завершать работу. В этом нам поможет RunLoop. Обычно, когда мы пишем приложения под iOS или macOS, система сама контролирует процесс создания RunLoop, но для скриптов мы должны сделать это самостоятельно.

Сегодня я хотел бы поделиться небольшой, но полезной библиотекой SwiftScriptRunner, которая реализует своего рода мьютекс, предотвращая завершение программы. Механизм достаточно простой: счетчик, на основе которого мы стартуем бесконечный цикл while, в котором запускаем RunLoop.current на 0.1 секунды. Как только счетчик становится равен 0, скрипт завершает работу.

Source / SwiftScriptRunner
#shareLibrary #scripts #advanced