Статьи

Что нового в Swift 4

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

Снимок Swift 4 уже был доступен за несколько недель до объявления Xcode 9 на WWDC 2017. В этом посте вы узнаете все о новых функциях, представленных в Swift 4 — от совершенно новых API до улучшений синтаксиса языка.

Давайте сначала посмотрим, как вы можете установить новый компилятор на вашу машину.

Существует два способа запуска Swift 4. Вы можете установить бета-версию Xcode 9, если у вас есть учетная запись разработчика с доступом к ней, или вы можете настроить Xcode 8 для запуска со снимком Swift 4. В первом случае загрузите бета-версию со страницы загрузки учетной записи разработчика.

Если вы предпочитаете использовать Xcode 8, просто зайдите на Swift.org, чтобы загрузить последний снимок разработки Swift 4.0. После завершения загрузки дважды щелкните файл .pkg, который устанавливает моментальный снимок.

Переключитесь на Xcode сейчас и перейдите к Xcode> Toolchains> Manage Toolchains . Оттуда выберите только что установленный снимок Swift 4.0. Перезапустите Xcode, и теперь Swift 4 будет использоваться при компиляции вашего проекта или игровой площадки. Обратите внимание, что весь код, представленный в этом руководстве, также доступен в репозитории GitHub .

Настройка снимка Swift 40 в Xcode 83

Давайте посмотрим на новые функции, добавленные в Swift 4. Одно предостережение: язык все еще находится в бета-версии, и мы, скорее всего, увидим больше изменений и исправлений ошибок до выпуска официальной версии. Более того, некоторые из недавно одобренных предложений могут быть еще не реализованы в настоящее время, поэтому следите за примечаниями к будущему выпуску, чтобы увидеть, что будет реализовано и исправлено.

Разбор JSON — одна из самых обсуждаемых тем в сообществе Swift. Приятно видеть, что кто-то наконец-то позаботился о написании предложений SE-0166 и SE-0167 и выдвинул идею обновить API архивации и сериализации в среде Foundation. В Swift 4 больше нет необходимости анализировать или кодировать ваш класс, структуру или перечисление вручную.

Encodable Decodable протоколы Encodable и Decodable , и вы можете привести свои классы в соответствие с ними, просто добавив Codable (который является псевдонимом Decodable & Encodable ) в список наследования класса. Затем вы можете использовать JSONEncoder для кодирования экземпляра класса:

1
2
3
4
let wwdc = Conference(name: «WWDC», city: «San Jose», date: Date(timeIntervalSince1970: 0))
let jsonEncoder = JSONEncoder()
let jsonEncoded = try jsonEncoder.encode(wwdc)
let jsonString = String(data: jsonEncoded, encoding: .utf8) // {«name»:»WWDC»,»city»:»San Jose»,»date»:-978307200}

Как видите, вы создаете экземпляр объекта JSONEncoder для преобразования структуры в строковое представление JSON. Есть несколько настроек, которые вы можете настроить, чтобы получить именно тот формат JSON, который вам нужен. Например, чтобы установить пользовательский формат даты, вы можете указать dateEncodingStrategy следующим образом:

1
2
3
4
5
6
7
let jsonEncoder = JSONEncoder()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .long
jsonEncoder.dateEncodingStrategy = JSONEncoder.DateEncodingStrategy.formatted(dateFormatter)
let jsonEncoded = try jsonEncoder.encode(wwdc)
let jsonString = String(data: jsonEncoded, encoding: .utf8) // {«name»:»WWDC»,»city»:»San Jose»,»date»:»January 1, 1970 at 1:00:00 AM GMT+1″}

Обратный процесс декодирования строки работает очень похоже благодаря классу JSONDecoder .

1
2
let jsonDecoder = JSONDecoder()
let decodedWWDC = try jsonDecoder.decode(Conference.self, from: jsonEncoded) // `decodedWWDC` is already of type Conference!

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

Это даже не вся мощь и модульность нового API. Вместо использования JSONEncoder вы можете использовать новые PropertyListEncoder и PropertyListDecoder в случае, если вам нужно сохранить данные в файле plist. Вы также можете создать свой собственный кодер и декодер. Вам нужно только настроить декодер в соответствии с Decoder а кодер — с протоколом Encoder .

Как часть String Manifesto , тип String также получил довольно большое обновление. Теперь он снова соответствует (после удаления в Swift 2) протоколу Collection благодаря предложению SE-0163 . Так что теперь вы можете просто перечислить строку, чтобы получить все символы.

1
2
3
4
let text: String = «Hello from Tutsplus!»
for character in text.reversed() {
    print(character)
}

Substring — это новый тип, который соответствует тому же StringProtocol которому соответствует String . Вы можете создать новую Substring , просто подписав String . Следующая строка создает Substring , пропуская первый и последний символ.

1
let substring = text[text.index(after: text.startIndex)..<text.index(before: text.endIndex)]

Хорошим дополнением, облегчающим работу с большими фрагментами текста, являются многострочные строки. Если вам нужно создать блок текста, который состоит из нескольких строк, ранее вам приходилось вручную вставлять \n повсюду. Это было очень не элегантно и трудно управлять. Теперь существует лучший способ написания многострочных строк, как вы можете видеть из следующего примера:

1
2
3
4
5
6
let welcomeMessage = «»»
 Hey there,
  
 Welcome to Envato Tuts+.
 We hope you enjoy learning with us!
 «»»

Есть несколько правил, которые согласуются с этим новым синтаксисом. Каждая строка начинается с тройной кавычки ( """ ). Затем, если вся строка имеет отступ, интервал закрывающих символов определяет интервал, который нужно убрать из каждой строки в строке. Например, если закрывающий символ с отступом в две вкладки, одинаковое количество будет удалено из каждой строки.Если строка содержит строку, у которой нет такого интервала, компилятор выдаст ошибку.

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

Ключевые пути были хорошим дополнением к Swift 3, но их использование было ограничено NSObject и они не очень хорошо играли со структурами. Это были основные мотивы предложения SE-0161 обновить API.

Сообщество согласовало новый синтаксис для указания ключевого пути: путь записывается, начиная с \ . Это выглядит следующим образом:

1
2
3
4
5
6
7
8
struct Conference {
    var name = «»
    let city: String
}
 
let nameKeyPath = \Conference.name
let wwdc = Conference(name: «WWDC», city: «San Jose»)
wwdc[keyPath: nameKeyPath] // «WWDC»

Объект nameKeyPath описывает ссылку на свойство name . Затем его можно использовать в качестве нижнего индекса этого объекта.

Если вы измените переменную с let на var из wwdc , вы также можете изменить определенное свойство с помощью синтаксиса wwdc ключа.

1
2
wwdc[keyPath: nameKeyPath] = «AltConf»
let name = wwdc[keyPath: nameKeyPath] // «AltConf»

SE-0172 предложил добавить новые префиксные и постфиксные операторы, чтобы избежать ненужного повторения начального или конечного индекса, когда он может быть выведен. Например, если вы хотите подписать массив от второго индекса до последнего, вы можете написать его следующим образом:

1
2
let numbers = [-2, -1, 0, 1, 2]
let positive = numbers[2..<numbers.endIndex]

Ранее endIndex должен был быть указан. Теперь существует более короткий синтаксис:

1
let positive = numbers[2…]

Или, если вы хотите начать со стартового индекса:

1
let negative = numbers[…1]

Тот же синтаксис также можно использовать для сопоставления с образцом в операторе switch .

До Swift 4 подписчики должны были определять конкретный тип возвращаемого значения. В SE-0148 предложена возможность определения единого общего индекса, который будет выводить тип возвращаемого значения на основе определенного значения результата. Помимо аннотации типа, она работает почти так же, как и раньше.

01
02
03
04
05
06
07
08
09
10
struct Conferences {
    let conferences: [String: Any]
 
    // Returns the conference models given its key.
    subscript<T>(key: String) -> T?
        return conferences[key] as?
  }
}
// Define the return type of the variable and access the object via subscript.
let thing: Conference?

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

На сегодняшний день одной из недостающих возможностей системы типов Swift была возможность ограничить класс конкретным протоколом. Это было исправлено в Swift 4 — теперь вы можете указать тип объекта и протоколы, которым он должен соответствовать, благодаря SE-0156 . Например, вы можете написать метод, который принимает UIView , соответствующий протоколу Reloadable , со следующим синтаксисом:

1
2
func reload(view: UIView & Reloadable) {
}

Dictionary и Set также получили хорошее обновление в Swift 4. Их гораздо приятнее использовать благодаря нескольким добавленным утилитам.

В словаре теперь есть метод mapValues для изменения всех значений, избегая использования универсального метода map который требует работы с кортежами key, value.

1
2
3
4
5
let conferences = [«WWDC»: «Very Good», «AltConf»: «Good», «Firebase Party»: «Very Fun»]
// Map over all values in the dictionary.
let newConferences = conferences.mapValues { value in
    return value + » 👍»
}

Метод filter теперь возвращает объект того же типа, с которым вы фильтруете.

1
2
// The type of this variable is [String: String]
let wwdc = conferences.filter { $0.key == «WWDC» }

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

1
2
// Default value if key is not found.
let talkShow = conferences[«The Talk Show», default: «🤷‍♂️»]

Наконец, был введен инициализатор Dictionary(grouping:) для облегчения создания нового словаря путем группировки элементов существующей коллекции в соответствии с некоторыми критериями.

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

1
let dictionary = Dictionary(grouping: conferences.values) { $0.uppercased().first!

Если вы хотите углубиться в новые возможности Swift 4, вот еще несколько ресурсов:

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

Мы создали полное руководство, которое поможет вам изучить Swift , независимо от того, начинаете ли вы с основ или начинаете изучать более сложные темы.

Вы также можете проверить другие наши посты о разработке приложений для iOS!

  • IOS
    Swift Основы анимации
    Маркус Мюльбергер
  • Мобильная разработка
    WWDC 2017 Последствия: самые важные объявления
    Барт Джейкобс
  • iOS SDK
    Realm Мобильная база данных для iOS
    Дорон Кац
  • IOS
    Что нового в iOS 10
    Маркус Мюльбергер