Статьи

Работа с JSON в Swift

Формат данных JSON широко используется в современной сети и является одним из наиболее распространенных способов передачи данных. Многие современные API, в частности веб-сервисы RESTful , поддерживают формат данных JSON.

В этом руководстве я покажу вам, как работать с форматом данных JSON на языке программирования Swift для iOS, tvOS, watchOS и OS X.

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

Как я уже упоминал, JSON — это широко используемый формат данных, который используется для связи, например, между клиентами и серверами. Он популярен благодаря удобству использования практически на любой мобильной платформе, такой как iOS, Android, Windows Phone и веб-браузеры.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
{
  «dataTitle»: «JSON Tutorial!»,
  «swiftVersion»: 2.1
   
  «users»: [
    {
      «name»: «John»,
      «age»: 25
    },
    {
      «name»: «Mark»,
      «age»: 29
    },
    {
      «name»: «Sarah»,
      «age»: 22
    }
  ],
}

Как видите, формат данных JSON прост для понимания. JSON структурирован с использованием двух типов коллекций, словарей и массивов. Словари содержат одну или несколько пар ключ-значение и заключены в фигурные скобки {} . Массивы содержат список упорядоченных элементов и заключены в квадратные скобки, [] . Почти каждый язык программирования определяет эти типы коллекций, поэтому JSON поддерживается почти каждым языком вокруг.

Ниже приведен список поддерживаемых типов данных в объекте JSON:

  • строка
  • Число (целое число, число с плавающей запятой, двойное число и т. Д.)
  • логический
  • массив
  • Словарь

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

Запустите Xcode и создайте новую игровую площадку. Дайте детской площадке имя и установите Платформу на iOS .

Откройте навигатор слева и разверните игровую площадку JSON . Щелкните правой кнопкой мыши папку « Ресурсы » и выберите « Новый файл» в меню.

Добавить данные JSON

Назовите файл data.json и заполните файл следующим JSON.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
{
  «users»: [
    {
      «name»: «John»,
      «age»: 25
    },
    {
      «name»: «Mark»,
      «age»: 29
    },
    {
      «name»: «Sarah»,
      «age»: 22
    }
  ],
  «dataTitle»: «JSON Tutorial!»,
  «swiftVersion»: 2.1
}

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

1
2
3
4
import UIKit
 
let url = NSBundle.mainBundle().URLForResource(«Data», withExtension: «json»)
let data = NSData(contentsOfURL: url!)

С помощью этого кода мы получаем ссылку на файл JSON, который мы добавили на площадку несколько минут назад, и получаем его содержимое в виде необработанных данных. Обратите внимание, что созданный здесь URL-адрес является локальным для файла на вашем компьютере. Это может быть URL-адрес веб-службы или любой другой URL-адрес, который может вам понадобиться.

Также важно понимать, что необработанные данные объекта JSON не должны собираться таким образом. Единственной важной частью является необработанный объект NSData , который может быть получен из URL-адреса, как показано в примере, ответа API или из ряда других источников.

Следующим шагом является анализ и сериализация этих данных в объект, который мы можем использовать. К счастью, в iOS и OS X класс Foundation NSJSONSerialization выполняет всю сложную работу по синтаксическому анализу и сериализации для вас. Добавьте следующий фрагмент кода на свою игровую площадку.

1
2
3
4
5
6
7
8
do {
    let object = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
    if let dictionary = object as?
        readJSONObject(dictionary)
    }
} catch {
    // Handle Error
}

Сначала мы включаем всю нашу логику в оператор do-catch , потому что сериализация из данных JSON потенциально может вызвать ошибку. Затем мы вызываем метод JSONObjectWithData(_:options:) класса NSJSONSerialization , передавая объект NSData и некоторые параметры. Параметры, которые могут быть переданы, определяются структурой NSJSONReadingOptions :

  • AllowFragments Это позволяет AllowFragments объекты в пределах первого или верхнего уровня данных JSON, которые не являются массивами или словарями. В данных JSON, используемых в этом руководстве, они включают значения как dataTitle и swiftVersion .
  • MutableLeaves Этот параметр позволяет автоматически создавать строки, считываемые из данных JSON, в качестве экземпляров NSMutableString . Эта опция больше подходит для разработки Objective-C. В Swift вы можете игнорировать эту опцию, поскольку строки представляют собой встроенный базовый тип данных и автоматически изменяются при определении с помощью ключевого слова var .
  • MutableContainers Это позволяет массивам и словарям, считываемым из данных JSON, также быть изменяемыми. Как и в MutableLeaves параметром MutableLeaves , в Swift использование ключевого слова var при назначении массива / словаря переменной автоматически делает его изменчивым.

Наконец, мы проверяем, имеет ли сериализованный объект ожидаемый тип [String: AnyObject] и, если это так, вызываем readJSONObject(_:) . Давайте посмотрим на метод readJSONObject(_:) .

После анализа и сериализации собранных вами данных JSON вы можете взаимодействовать с ними так же, как и с любым другим словарем. Добавьте следующую функцию на игровую площадку над оператором do-catch .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
func readJSONObject(object: [String: AnyObject]) {
    guard let title = object[«dataTitle»] as?
        let version = object[«swiftVersion»] as?
        let users = object[«users»] as?
    _ = «Swift \(version) » + title
     
    for user in users {
        guard let name = user[«name»] as?
            let age = user[«age»] as?
        switch age {
        case 22:
            _ = name + » is \(age) years old.»
        case 25:
            _ = name + » is \(age) years old.»
        case 29:
            _ = name + » is \(age) years old.»
        default:
            break
        }
    }
}

Как видите, с сериализованными данными JSON можно взаимодействовать точно так же, как с обычным словарем или массивом. Вышеупомянутая readJSONObject(_:) служит примером того, как вы можете извлечь информацию из сериализованного объекта JSON. Обратите внимание, что я включил в функцию оператор switch просто для разделения строк в выводе игровой площадки.

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

Выход на игровую площадку

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
let validDictionary = [
    «numericalValue»: 1,
    «stringValue»: «JSON»,
    «arrayValue»: [0, 1, 2, 3, 4, 5]
]
 
let invalidDictionary = [
    «date»: NSDate()
]
 
if NSJSONSerialization.isValidJSONObject(validDictionary) { // True
    do {
        let rawData = try NSJSONSerialization.dataWithJSONObject(validDictionary, options: .PrettyPrinted)
    } catch {
        // Handle Error
    }
}
 
if NSJSONSerialization.isValidJSONObject(invalidDictionary) { // False
    // NSJSONSerialization.dataWithJSONObject(validDictionary, options: .PrettyPrinted) will produce an error if called
}

При создании ваших собственных данных JSON из объекта лучше всего сначала использовать метод isValidJSONObject(_:) чтобы проверить, можно ли преобразовать объект в объект JSON.

После этой начальной проверки вы вызываете метод dataWithJSONObject(_:) , который возвращает объект NSData случае успеха. Поскольку мы уже проверили, является ли объект допустимым, блок catch ошибок здесь не так важен, как раньше, но все же может вызываться из-за внутренней ошибки API при создании необработанных данных.

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

1
2
3
4
5
6
7
8
// With PrettyPrinted Option:
{
    «name»: «John»,
    «age»: 25
}
 
// Without PrettyPrinted Option:
{«name»:»John»,»age»: 25}

NSData объект NSData можно затем использовать по NSData . Вы можете сохранить его в локальном файле или отправить в веб-службу.

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

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