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

Swift 5 представил достойную версию строковой интерполяции с SE-228 и обновил старую версию протокола ExpressibleByStringInterpolation, который был объявлен устаревшим со времен Swift 3. Новая версия этого протокола позволяет нам писать мощные расширения для существующих типов, которые определяют, как объекты взаимодействуют при использовании в строковой интерполяции.

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

Что такое строковая интерполяция?

Название говорит само за себя - все дело в интерполяции значений в строки. Другими словами, добавление строки к другой строке.

Самый простой пример этого выглядит следующим образом:

let name = "Antoine van der Lee"
print("Hello, I'm \(name)")

В этом примере мы вставили имя в оператор печати. В результате получается напечатанное предложение: «Здравствуйте, я Антуан ван дер Ли». Ниже мы использовали структуру DefaultStringInterpolation, которая по умолчанию обрабатывает интерполирующие значения, и добавили имя к строковому значению "Hello, I'm".

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

Случай 1. Возможности печати

Печать опций в Swift может быть довольно болезненной. Вы можете выбрать несколько вариантов:

Последнее часто предлагается компилятором:

String interpolation produces a debug description for an optional value; did you mean to make this explicit?
- Use String(describing:) to silence this warning

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

Теперь это позволяет нам распечатывать опции, как мы могли раньше, но мы больше не получаем предложение компилятора:

print("The title is \(title)")
// Prints: The title is SwiftLee - A blog about Swift

Значение красиво распечатывается без ключевого слова Optional(..). Если значение не установлено, будет напечатано nil, в котором четко указано, что значение не установлено, и это поможет нам во время сеансов отладки.

Случай 2. Печать JSON

Другой распространенный вариант использования - распечатка ответов JSON на запросы данных. Это может быть полезно во время отладки, но код для распечатки JSON не всегда может быть под рукой. Я обнаружил, что несколько раз искал код в Stack Overflow, чтобы узнать, как можно красиво распечатать JSON из Data.

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

Этот метод интерполяции представляет новый способ работы с интерполяцией строк и требует от нас установки имени свойства внутри интерполяции. Поначалу это может быть необычно для вас, но может стать полезным, если вы поймете, какие возможности это открывает. В этом случае наш JSON распечатывается красиво!

Это также можно использовать непосредственно в URLSessionDataTask ответах:

Случай 3. Печать запросов URL

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

По умолчанию URLRequest распечатывается следующим образом:

Хотя это дает нам URL-адрес, он также может предоставить нам информацию о методе HTTP, включенных заголовках или другую полезную информацию, о которой вы можете подумать:

Строчная интерполяция против CustomStringConvertible

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

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

Например, в предыдущем примере URL-адрес будет распечатан без дополнительных свойств, если он используется следующим образом, даже если мы настроили расширение интерполяции строк:

print(request)
// Prints: https://www.avanderlee.com/feed?offset=10&limit=20

Причина в том, что запрос не используется внутри другой строки с использованием синтаксиса \(..). Вместо этого он распечатывается с использованием значения description, определенного в протоколе CustomStringConvertible.

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

Случай 4. Преобразование в HTML

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

По умолчанию ваш String может оказаться загроможденным тегами HTML, хотя вы хотите, чтобы он оставался читабельным:

"""
   The blog post can be found at <a href="www.avanderlee.com">www.avanderlee.com</a>
"""

Из-за тега HTML <a></a> мы добавили дополнительный синтаксис в наш String, что сделало его менее читаемым. Вместо этого мы могли бы добавить настраиваемое расширение интерполяции строк, которое обрабатывает добавление HTML-ссылок в String:

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

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

Заключение

Пользовательская интерполяция строк позволяет дополнительно оптимизировать работу со строками в Swift. Распространенные варианты использования, такие как печать JSON или дополнительных компонентов, могут сделать разработку на Swift еще более удобной. Однако полезно знать, когда использовать пользовательскую интерполяцию строк по сравнению с использованием CustomStringConvertible реализации протокола.

Спасибо за прочтение!