Python conf in Kharkiv, Nov 16 with Intel, Elastic engineering leaders. Prices go up 21.10

WWDC 2019: обзор и практическое применение Custom Instruments и SF Symbols

Пожалуй, WWDC 2019 стала самой значимой конференцией для iOS девелоперов за последние несколько лет — так утверждали большинство участников ивента. Я поехал вместе с коллегой, таким образом среди 6 тысяч счастливых участников этого события оказались еще и два разработчика из NIX. Мы посетили самые важные закрытые сессии и воркшопы конференции, на которых как раз и разбирались особенности работы с новыми инструментами. В этой статье я расскажу, что осталось за кадром онлайн-трансляции и с чем предстоит работать iOS девелоперам уже в ближайшем будущем.

Да, я знаю, что после WWDC 2019 прошло уже три месяца, и о событиях конференции успели написать многие. И все же для меня эта пауза была не напрасной по двум причинам. Во-первых, если бы я сел за статью раньше, вы увидели бы примерно такое начало: «А-а-а, я пожал руку Крэйгу Федериги!» :) Во-вторых, все лето мы с командой осваивали презентованные фичи, разбирались в особенностях их работы и даже успели обсудить нюансы их применения на открытой конференции iThink #3, благодаря чему я смог четко сформулировать для себя, чем стоит поделиться с вами в этой статье.

Custom Instruments

Это фича от Apple, которая была презентована ещё в прошлом году. На WWDC 2019 ей было посвящено несколько сессий. На них докладчики рассказали, как работают кастомные инструменты, в каких случаях их применять и чем они могут быть полезны девелоперу. Основа — os_signpost. Это трассировщик, который Apple представила в прошлом году. Оs_signpost может делать простые ивенты и интервалы.

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

Архитектура самого инструмента в самом начале встречает нас Data stream — потоком данных. И теперь их мы получаем как раз благодаря os_signpost. Эти данные записываются в input таблицу. Схема этой и output таблицы описана с помощью специальной XML структуры. Шаги считывания данных и записи в таблицу являются трассировкой.

Далее следует modeller. Здесь данные, которые попали в input таблицу, начинают обрабатываться modeller’ом. Сам моделлер пишется на специальном языке CLIPS, который имеет декларативную и императивную часть для обработки новых событий и преобразования данных. Тут может производиться кастомный подсчёт или преобразование данных в нужный нам формат.

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

CloudKit + CoreData

Фича от Apple, презентованная в этом году, позволяет включить автоматическую синхронизацию Core Data с Cloud Kit. Для этого достаточно поставить две галочки при старте проекта. Тем самым мы получаем:

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

И всё, основную работу за вас сделал Xcode. Автоматически был сгенерирован вот такой контейнер, который агрегирует в себе работу с базой данных и CloudKit. Если же у вас уже есть проект и вы хотите воспользоваться этой новой фичей от Apple, вы можете сами создать Container и применить его вместо уже существующего. Таким образом даже уже в готовых старых проектах можно добиться простой синхронизации с CloudKit.

    lazy var persistentContainer: NSPersistentCloudKitContainer = {
        let container = NSPersistentCloudKitContainer(name: "_2312")
        guard
            let description = container.persistentStoreDescriptions.first
        else {
            fatalError("No description found in NSPersistentCloudKitContainer” )
        }
        
        let id = "iCloud.testnixsolutions.dontBeBored"
        let options = NSPersistentCloudKitContainerOptions(containerIdentifier: id)
        description.cloudKitContainerOptions = options
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

На практике это выглядит следующим образом. Для использования иконок в своих проектах ничего не потребуется, потому что они интегрированы в системный San Francisco шрифт. Для создания символа потребуются новые инициализаторы от UIImage.

SF Symbols

В этом году на сессиях Apple этой теме было уделено слишком мало внимания. Сама сессия оказалась максимально насыщенной, но подача информации носила, скорее, поверхностный характер: описывалось всего несколько use cases, что только провоцировало участников на дополнительные вопросы. Создавалось ощущение, что на тебя высыпали кучу брендовой одежды, а вот в шкаф тебе придется складывать ее самостоятельно.

Я задался вопросом, зачем Apple создала новые символы, если девелоперы уже много лет спокойно использовали .png/.jpg/.pdf картинки. Возможно, этот способ не всегда был удачным, имел свои особенности и нюансы, но все уже привыкли многократно конфигурировать свою UI.

Как все мы знаем, разработчики мобильных приложений всегда стараются сделать user friendly ui для своих пользователей. Иначе приложением никто не будет пользоваться, так как оно окажется неудобным и непонятным. Одним из распространенных способов создания нативно понятного приложения является использование иконок. Девелоперы должны понимать их значение и функции в зависимости от местоположения, когда будут вставлять иконки в интерфейс своего приложения.

Иконки разделяют контексты:

Иконки объединяют контексты:

Иконки должны визуально соответствовать тексту:

Таким образом, Apple создали SF Symbols для легкого решения этих проблем. Так как Apple уделяет много внимания своим продуктам, они создали отдельное приложение, которое позволяет ознакомиться со всеми символами (их сейчас более 1500), воспользоваться поиском, изменить некоторые параметры и посмотреть, что же произойдет с нужным тебе символом.

Если тебе окажется недостаточно 1500 символов, тогда читаем инфу по ссылке выше. Там подробно рассказывается, как можно сделать свои кастомные символы. Как утверждает создатель — это векторная картинка с метаданными текста. Поэтому одной из центральных идей сессии было заставить разработчиков концептуально переосмыслить подход к работе с символами: для них уже неприменимы решения, которые мы долгое время использовали в работе с обычными картинками. Проще говоря, при работе с символами думайте о них как о UIFont.

На практике это выглядит следующим образом. Для использования иконок в своих проектах ничего не потребуется, потому что они интегрированы в системный San Francisco шрифт. Для создания символа потребуются новые инициализаторы от UIImage.

// UIKit
let image = UIImage(systemName: "circle")
let image = UIImage(systemName: "circle", withConfiguration: UIImage.Configuration?)

// SwiftUI
let image = Image(systemName: "circle")

Как мы видим, в одном из инициализаторов появился новый параметр UIImage.Configuration. Сюда мы можем передать UIImage.SymbolConfiguration, что является наследником UIImage.Configuration. Стоит отметить, что конфигурации являются иммутабельными, и для применения новых параметров придется использовать applying (_:).

Конфигурация позволяет изменить:

  • PointSize;
  • UIImage.SymbolScale;
  • UIFont.TextStyle;
  • UIImage.SymbolWeight;
  • UIFont.

А теперь обо всем по порядку

Point size — параметр, который позволяет задавать размер символа. Это та самая первая концепция, которая должна дать понять, что символ не является той самой png-картинкой. Важно понимать, что Point size (CGFloat) != CGSize. Таким образом, о размерах SF Symbols думаем в point size, особенно когда работаем в связке символа и текста.

let topFont = topLabel.font
let topConfiguration = UIImage.SymbolConfiguration(pointSize: topFont!.pointSize)
        topImageView.image = UIImage(systemName: "bell", withConfiguration: topConfiguration)

Используя UIImage.SymbolWeight, мы можем придать толщину линии (жирность) символу, как и у UIFont.

Со следующим параметром SymbolConfiguration.init (font: UIFont) все довольно просто. Достаточно закинуть параметром нужный UIFont, и система все делает за тебя.

Самым неоднозначным из всех параметров будет UIImage.SymbolScale. Его тоже используют для изменения размеров символа. Поэтому в итоге мы получаем сразу два параметра, которые меняют размер символа. Но не стоит паниковать. Эти параметры, скорее, взаимодополняющие, чем взаимоисключающие.

Давайте представим ситуацию: вы задали идентичный point size вашему UIFont в лайбе, но при этом ваш символ визуально больше/меньше текста. Чтобы не создавать новую конфигурацию с новым значением point size, нам и пригодится SymbolScale. Он поможет изменить размер изображения, не меняя при этом его point size.

Что же касается параметра UIFont.TextStyle, то здесь также не предвидится ничего сложного. Его нам рекомендуют использовать в случае имплементации dynamic font type.

В итоге

Мы имеем новый подход к работе с символами (картинками) и текстом. Фактически Apple заставила iOS-девелоперов пересмотреть свои взгляды на этот счет. Плюс ко всему, мы получили более широкие возможности добавления своих инструментов, что позволяет нам снизить порог вхождения в проект. Также мы теперь имеем возможность настроить CoreData с CloudKit всего в пару кликов. iOS-разработчикам предстоит попробовать и узнать еще много нового. Начинайте работать с этими инструментами уже сегодня, двигайтесь вперёд и делитесь опытом в статьях и на митапах и, конечно, в комментариях к этому материалу.

LinkedIn

2 комментария

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

Сам использую SF Symbols, но пока только как хранилище иконок, придется подождать как обычно, пока они войдут в моду :) А еще в статье немного сдвинулись или смешались картинки и исходный код

Подписаться на комментарии