수색…


통사론

  • NSJSONSerialization.JSONObjectWithData (jsonData, options : NSJSONReadingOptions) // jsonData에서 객체를 반환합니다. 이 메서드는 실패시에 throw됩니다.
  • NSJSONSerialization.dataWithJSONObject (jsonObject, options : NSJSONWritingOptions) // JSON 객체에서 NSData를 반환합니다. NSJSONWritingOptions.PrettyPrinted에서 더 읽기 쉬운 출력 옵션을 전달하십시오.

Apple Foundation 및 Swift Standard 라이브러리를 사용한 JSON 직렬화, 인코딩 및 디코딩

JSONSerialization 클래스는 Apple의 Foundation 프레임 워크에 내장되어 있습니다.

2.2

JSON 읽기

JSONObjectWithData 함수는 NSData 를 사용하고 AnyObject 반환합니다. 당신은 as? 결과를 예상 유형으로 변환하십시오.

do {
    guard let jsonData = "[\"Hello\", \"JSON\"]".dataUsingEncoding(NSUTF8StringEncoding) else {
        fatalError("couldn't encode string as UTF-8")
    }

    // Convert JSON from NSData to AnyObject
    let jsonObject = try NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
    
    // Try to convert AnyObject to array of strings
    if let stringArray = jsonObject as? [String] {
        print("Got array of strings: \(stringArray.joinWithSeparator(", "))")
    }
} catch {
    print("error reading JSON: \(error)")
}

options: [] 대신 options: .AllowFragments 를 전달하면 최상위 오브젝트가 배열이나 사전이 아닌 경우 JSON을 읽을 수 있습니다.

JSON 작성

dataWithJSONObject 호출하면 JSON 호환 객체 (중첩 배열 또는 문자열, 숫자 및 NSNull 사전)가 UTF-8로 인코딩 된 원시 NSData 로 변환됩니다.

do {
    // Convert object to JSON as NSData
    let jsonData = try NSJSONSerialization.dataWithJSONObject(jsonObject, options: [])
    print("JSON data: \(jsonData)")
    
    // Convert NSData to String
    let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding)!
    print("JSON string: \(jsonString)")
} catch {
    print("error writing JSON: \(error)")
}

options: .PrettyPrinted 을 전달할 수 options: .PrettyPrinted 대신 options: .PrettyPrinted options: [] 예쁜 인쇄를 위해 options: []

3.0

스위프트 3에서도 같은 구문이지만 다른 구문을 사용합니다.

do {
    guard let jsonData = "[\"Hello\", \"JSON\"]".data(using: String.Encoding.utf8) else {
        fatalError("couldn't encode string as UTF-8")
    }
    
    // Convert JSON from NSData to AnyObject
    let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
    
    // Try to convert AnyObject to array of strings
    if let stringArray = jsonObject as? [String] {
        print("Got array of strings: \(stringArray.joined(separator: ", "))")
    }
} catch {
    print("error reading JSON: \(error)")
}

do {
    // Convert object to JSON as NSData
    let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
    print("JSON data: \(jsonData)")

    // Convert NSData to String
    let jsonString = String(data: jsonData, encoding: .utf8)!
    print("JSON string: \(jsonString)")
} catch {
    print("error writing JSON: \(error)")
}

참고 : 다음은 현재 Swift 4.0 이상 에서만 사용할 수 있습니다.

스위프트 4.0로, 스위프트 표준 라이브러리 프로토콜을 포함 EncodableDecodable 된 데이터의 부호화 및 복호화에 대한 표준 방식을 정의한다. 이러한 프로토콜을 채택하면 EncoderDecoder 프로토콜 구현시 데이터를 가져와 JSON과 같은 외부 표현에서 데이터를 인코딩하거나 디코딩 할 수 있습니다. Codable 프로토콜에 대한 적합성은 인 EncodableDecodable 프로토콜을 모두 결합합니다. 이제는 프로그램에서 JSON을 처리하기 위해 권장되는 방법입니다.

자동으로 인코딩 및 디코딩

유형 코드 가능을 작성하는 가장 쉬운 방법은 해당 특성을 이미 Codable 유형으로 선언하는 Codable 입니다. 이러한 유형에는 String , IntDouble 과 같은 표준 라이브러리 유형이 포함됩니다. Date , DataURL 과 같은 Foundation 유형이 있습니다. 타입의 프로퍼티가 코드 가능하다면, 타입 자체는 단순히 적합성을 선언함으로써 Codable 으로 자동적으로 적합 할 것이다.

Book 구조가 Codable 준수하는 다음 예제를 고려하십시오.

struct Book: Codable {
    let title: String
    let authors: [String]
    let publicationDate: Date
}

같은 표준 컬렉션을 참고 ArrayDictionary 에 부합 Codable 가 codable 유형을 포함합니다.

Codable 을 채택함으로써 Book 구조 자체가 JSON을 특별히 다루는 코드를 포함하지 않지만 Book 구조는 이제 Apple Foundation 클래스 인 JSONEncoderJSONDecoder 사용하여 JSON으로 인코딩되고 디코드 될 수 있습니다. 사용자 정의 인코더 및 디코더는 각각 EncoderDecoder 프로토콜을 준수하여 작성할 수 있습니다.

JSON 데이터로 인코딩

// Create an instance of Book called book
let encoder = JSONEncoder()
let data = try! encoder.encode(book) // Do not use try! in production code
print(data)

더 쉽게 읽을 수 있도록 encoder.outputFormatting = .prettyPrinted 를 설정하십시오. # JSON 데이터에서 디코딩

JSON 데이터에서 디코딩

// Retrieve JSON string from some source
let jsonData = jsonString.data(encoding: .utf8)!
let decoder = JSONDecoder()
let book = try! decoder.decode(Book.self, for: jsonData) // Do not use try! in production code
print(book)

위의 예에서 Book.self 는 JSON을 디코딩해야하는 유형을 디코더에 알립니다.

독점적으로 인코딩 또는 디코딩

때로는 API에서 JSON 데이터를 읽는 것만 필요하거나 API에서 JSON 데이터 만 제출하는 경우와 같이 데이터를 인코딩 및 디코딩 할 필요가없는 경우도 있습니다.

JSON 데이터를 작성하려는 경우 유형을 EncodableEncodable .

struct Book: Encodable {
    let title: String
    let authors: [String]
    let publicationDate: Date
}

JSON 데이터 만 읽으려면 유형을 Decodable .

struct Book: Decodable {
    let title: String
    let authors: [String]
    let publicationDate: Date
}

사용자 정의 키 이름 사용

API는 스 니크 케이스와 같이 Swift 표준 낙타 케이스 이외의 이름 지정 규칙을 자주 사용합니다. 기본적으로 JSON 키는 유형의 속성 이름과 정확히 일치해야하므로 JSON을 디코딩 할 때는 문제가 될 수 있습니다. 이러한 시나리오를 처리하기 위해 CodingKey 프로토콜을 사용하여 유형에 맞게 사용자 정의 키를 만들 수 있습니다.

struct Book: Codable {
    // ...
    enum CodingKeys: String, CodingKey { 
        case title
        case authors
        case publicationDate = "publication_date"
    }
}

CodingKeysCodable 프로토콜을 채택하는 유형에 대해 자동으로 생성되지만, 위의 예에서 자체 구현을 작성하면 Google Codable 가 현지 낙타 사례 인 publicationDate 를 API에서 제공 한대로 뱀 사례 publication_date 와 일치시킬 수 있습니다.

SwiftyJSON

SwiftyJSON은 일반 JSON 직렬화에서 선택적 체인의 필요성을 없애기 위해 만들어진 Swift 프레임 워크입니다.

여기에서 다운로드 할 수 있습니다. https://github.com/SwiftyJSON/SwiftyJSON

SwiftyJSON이 없으면 코드는 JSON 객체에서 첫 번째 책의 이름을 찾기 위해 다음과 같이 보입니다.

if let jsonObject = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [[String: AnyObject]],
let bookName = (jsonObject[0]["book"] as? [String: AnyObject])?["name"] as? String {
    //We can now use the book name
}

SwiftyJSON에서 이것은 매우 단순합니다.

let json = JSON(data: data)
if let bookName = json[0]["book"]["name"].string {
    //We can now use the book name
}

그 중 하나라도 유효하지 않으면 nil을 반환하므로 모든 필드를 검사 할 필요가 없습니다.

SwiftyJSON을 사용하려면 Git 저장소에서 올바른 버전을 다운로드하십시오. Swift 3에 대한 브랜치가 있습니다. "SwiftyJSON.swift"를 프로젝트로 끌어와 클래스로 가져 오기 만하면됩니다.

import SwiftyJSON

다음 두 이니셜 라이저를 사용하여 JSON 객체를 만들 수 있습니다.

let jsonObject = JSON(data: dataObject)

또는

let jsonObject = JSON(jsonObject) //This could be a string in a JSON format for example

데이터에 액세스하려면 아래 첨자를 사용하십시오.

let firstObjectInAnArray = jsonObject[0]
let nameOfFirstObject = jsonObject[0]["name"]

그런 다음 값을 특정 데이터 형식으로 구문 분석하면 선택적 값이 반환됩니다.

let nameOfFirstObject = jsonObject[0]["name"].string //This will return the name as a string

let nameOfFirstObject = jsonObject[0]["name"].double //This will return null

신속한 경로로 경로를 컴파일 할 수도 있습니다.

let convolutedPath = jsonObject[0]["name"][2]["lastName"]["firstLetter"].string

와 같다:

let convolutedPath = jsonObject[0, "name", 2, "lastName", "firstLetter"].string

SwiftyJSON은 자체 오류를 인쇄하는 기능도 있습니다.

if let name = json[1337].string {
    //You can use the value - it is valid
} else {
    print(json[1337].error) // "Array[1337] is out of bounds" - You cant use the value
}

JSON 객체에 작성해야하는 경우 아래 첨자를 다시 사용할 수 있습니다.

var originalJSON:JSON = ["name": "Jack", "age": 18]
originalJSON["age"] = 25 //This changes the age to 25
originalJSON["surname"] = "Smith" //This creates a new field called "surname" and adds the value to it

JSON 용 원본 문자열이 필요한 경우 (예 : 파일에 작성해야하는 경우) 원시 값을 가져올 수 있습니다.

if let string = json.rawString() { //This is a String object
    //Write the string to a file if you like
}

if let data = json.rawData() { //This is an NSData object
    //Send the data to your server if you like
}

프레디

FreddyBig Nerd Ranch가 관리하는 JSON 구문 분석 라이브러리입니다. 세 가지 주요 이점이 있습니다.

  1. 유형 안전 : 런타임 충돌을 방지하는 방식으로 JSON을주고받는 작업을 도와줍니다.

  2. 관용적 인 : 복잡한 문서 또는 마법의 사용자 지정 연산자없이 스위프트의 제네릭, 열거 및 기능을 활용합니다.

  3. 오류 처리 : 일반적으로 발생하는 JSON 오류에 대한 유익한 오류 정보를 제공합니다.

JSON 데이터의 예

이 예제에 사용할 JSON 데이터 예제를 정의 해 보겠습니다.

{
  "success": true,
  "people": [
    {
      "name": "Matt Mathias",
      "age": 32,
      "spouse": true
    },
    {
      "name": "Sergeant Pepper",
      "age": 25,
      "spouse": false
    }
  ],
  "jobs": [
    "teacher",
    "judge"
  ],
  "states": {
    "Georgia": [
      30301,
      30302,
      30303
    ],
    "Wisconsin": [
      53000,
      53001
    ]
  }
}
let jsonString = "{\"success\": true, \"people\": [{\"name\": \"Matt Mathias\",\"age\": 32,\"spouse\": true},{\"name\": \"Sergeant Pepper\",\"age\": 25,\"spouse\": false}],\"jobs\": [\"teacher\",\"judge\"],\"states\": {\"Georgia\": [30301,30302,30303],\"Wisconsin\": [53000,53001]}}"
let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)!

원시 데이터 직렬화 해제

데이터를 비 직렬화하려면 JSON 객체를 초기화 한 다음 특정 키에 액세스합니다.

do {
    let json = try JSON(data: jsonData)
    let success = try json.bool("success")
} catch {
    // do something with the error
}

"success" 대한 json 에 액세스 할 수 없으므로 여기에서 try 합니다. 존재하지 않을 수도 있고 값이 부울이 아닐 수도 있습니다.

또한 JSON 구조에 중첩 된 요소에 액세스하는 경로를 지정할 수 있습니다. 경로는 관심 값에 대한 경로를 설명하는 키와 색인의 쉼표로 구분 된 목록입니다.

do {
    let json = try JSON(data: jsonData)
    let georgiaZipCodes = try json.array("states", "Georgia")
    let firstPersonName = try json.string("people", 0, "name")
} catch {
    // do something with the error
}

직접 모델 역 직렬화

JSON은 JSONDecodable 프로토콜을 구현하는 모델 클래스로 직접 파싱 할 수 있습니다.

public struct Person {
    public let name: String
    public let age: Int
    public let spouse: Bool
}

extension Person: JSONDecodable {
    public init(json: JSON) throws {
        name = try json.string("name")
        age = try json.int("age")
        spouse = try json.bool("spouse")
    }
}

do {
    let json = try JSON(data: jsonData)
    let people = try json.arrayOf("people", type: Person.self)
} catch {
    // do something with the error
}

원시 데이터 직렬화

모든 JSON 값은 NSData 직접 직렬화 할 수 있습니다.

let success = JSON.Bool(false)
let data: NSData = try success.serialize()

직접 모델 직렬화

JSONEncodable 프로토콜을 구현하는 모든 모델 클래스는 NSData 직접 직렬화 할 수 있습니다.

extension Person: JSONEncodable {
    public func toJSON() -> JSON {
        return .Dictionary([
            "name": .String(name),
            "age": .Int(age),
            "spouse": .Bool(spouse)
        ])
    }
}

let newPerson = Person(name: "Glenn", age: 23, spouse: true)
let data: NSData = try newPerson.toJSON().serialize()

화살

Arrow 는 Swift의 우아한 JSON 파싱 라이브러리입니다.

JSON을 파싱하여 <-- 연산자를 사용하여 사용자 정의 모델 클래스에 매핑 할 수 있습니다.

identifier <-- json["id"]
name <-- json["name"]
stats <-- json["stats"]

예:

신속한 모델

struct Profile {
    var identifier = 0
    var name = ""
    var link: NSURL?
    var weekday: WeekDay = .Monday
    var stats = Stats()
    var phoneNumbers = [PhoneNumber]()
}

JSON 파일

{
    "id": 15678,
    "name": "John Doe",
    "link": "https://apple.com/steve",
    "weekdayInt" : 3,
    "stats": {
        "numberOfFriends": 163,
        "numberOfFans": 10987
    },
    "phoneNumbers": [{
                     "label": "house",
                     "number": "9809876545"
                     }, {
                     "label": "cell",
                     "number": "0908070656"
                     }, {
                     "label": "work",
                     "number": "0916570656"
    }]
}

매핑

extension Profile: ArrowParsable {
    mutating func deserialize(json: JSON) {
        identifier <-- json["id"]
        link <-- json["link"]
        name <-- json["name"]
        weekday <-- json["weekdayInt"]
        stats <- json["stats"]
        phoneNumbers <-- json["phoneNumbers"]
    }
}

용법

let profile = Profile()
profile.deserialize(json)

설치:

카르타고

github "s4cha/Arrow"

CocoaPods

pod 'Arrow'
use_frameworks!

수동으로

Xcode 프로젝트에서 Arrow.swift를 복사하여 붙여 넣기 만하면됩니다.

https://github.com/s4cha/Arrow

프레임 워크로서

GitHub 저장소 에서 Arrow를 다운로드하고 예제 프로젝트에서 Framework 타겟을 빌드하십시오. 그런 다음이 프레임 워크와 연결하십시오.

사용자 정의 객체로의 간단한 JSON 구문 분석

타사 라이브러리가 좋다하더라도, JSON을 구문 분석하는 간단한 방법은 객체 가지고 당신이 상상할 수있는 프로토콜에 의해 제공됩니다 Todo 등을

struct Todo {
    let comment: String
}

JSON을받을 때마다 NSJSONSerialization 객체를 사용하여 다른 예제와 같이 일반 NSData 를 처리 할 수 ​​있습니다.

그런 다음 간단한 프로토콜 JSONDecodable

typealias JSONDictionary = [String:AnyObject]
protocol JSONDecodable {
    associatedtype Element
    static func from(json json: JSONDictionary) -> Element?
}

JSONDecodable 준수하는 Todo 구조체를 JSONDecodable 것이 트릭입니다.

extension Todo: JSONDecodable {
    static func from(json json: JSONDictionary) -> Todo? {
        guard let comment = json["comment"] as? String else { return nil }
        return Todo(comment: comment)
    }
}

이 json 코드로 시도해 볼 수 있습니다.

{
    "todos": [
        {
            "comment" : "The todo comment"
        }
    ]
}

API에서 얻은 정보는 AnyObject 인스턴스에 표시된 이전 예제와 같이 직렬화 할 수 있습니다. 그런 다음 인스턴스가 JSONDictionary 인스턴스인지 확인할 수 있습니다.

guard let jsonDictionary = dictionary as? JSONDictionary else { return }

검사 할 다른 것은 JSON에 Todo 배열이 있기 때문에이 경우에 해당합니다. todos 사전입니다.

guard let todosDictionary = jsonDictionary["todos"] as? [JSONDictionary] else { return }

이제 사전의 배열을 얻었 flatMap 을 사용하여 Todo 객체에서 각 배열을 변환 할 수 있습니다 (배열에서 nil 값이 자동으로 삭제됩니다)

let todos: [Todo] = todosDictionary.flatMap { Todo.from(json: $0) }

JSON 파싱 스위프트 3

다음은 animals.json 이라는 JSON 파일입니다.

{
    "Sea Animals": [
    {
     "name": "Fish",
     "question": "How many species of fish are there?"    },
                {
                "name": "Sharks",
                "question": "How long do sharks live?"
                },
                {
                "name": "Squid",
                "question": "Do squids have brains?"
                },
                {
                "name": "Octopus",
                "question": "How big do octopus get?"
                },
                {
                "name": "Star Fish",
                "question": "How long do star fish live?"
                }
                ],
    "mammals": [
                {
      "name": "Dog",
      "question": "How long do dogs live?"
    },
    {
      "name": "Elephant",
      "question": "How much do baby elephants weigh?"
    },
    {
      "name": "Cats",
      "question": "Do cats really have 9 lives?"
    },
    {
      "name": "Tigers",
      "question": "Where do tigers live?"
    },
    {
      "name": "Pandas",
      "question": "WHat do pandas eat?"
    }   ] }

프로젝트에서 JSON 파일 가져 오기

이 간단한 함수를 수행하여 JSON 파일을 출력 할 수 있습니다.

   func jsonParsingMethod() {
        //get the file
        let filePath = Bundle.main.path(forResource: "animals", ofType: "json")
        let content = try! String(contentsOfFile: filePath!)
        
        let data: Data = content.data(using: String.Encoding.utf8)!
        let json: NSDictionary =  try! JSONSerialization.jsonObject(with: data as Data, options:.mutableContainers) as! NSDictionary
      
//Call which part of the file you'd like to pare
        if let results = json["mammals"] as? [[String: AnyObject]] {
            
            for res in results {
                //this will print out the names of the mammals from out file.
                if let rates = res["name"] as? String {
                    print(rates)
                }
           }
       }
    }

테이블 뷰에 넣으려면 먼저 NSObject로 사전을 작성해야합니다.

ParsingObject 라는 새로운 신속한 파일을 만들고 문자열 변수를 만듭니다.

변수 이름이 JSON 파일과 동일한 지 확인하십시오.

. 예를 들어, 우리 프로젝트에서 우리는 namequestion 을 가지고 있습니다. 그래서 새로운 신속한 파일에서 우리는

var name: String?
var question: String?

우리가 만든 NSObject를 ViewController.swift var array = ParsingObject로 초기화합니다. 그런 다음 사소한 수정을 가하여 이전과 동일한 방법을 수행합니다.

     func jsonParsingMethod() {
            //get the file
            let filePath = Bundle.main.path(forResource: "animals", ofType: "json")
            let content = try! String(contentsOfFile: filePath!)
            
            let data: Data = content.data(using: String.Encoding.utf8)!
            let json: NSDictionary =  try! JSONSerialization.jsonObject(with: data as Data, options:.mutableContainers) as! NSDictionary
            
//This time let's get Sea Animals
            let results = json["Sea Animals"] as? [[String: AnyObject]]
            
//Get all the stuff using a for-loop
            for i in 0 ..< results!.count {
                
//get the value
                let dict = results?[i]
                let resultsArray = ParsingObject()
                
//append the value to our NSObject file
                resultsArray.setValuesForKeys(dict!)
                array.append(resultsArray)
                
            }
          
        }

그런 다음이를 테이블 뷰에 표시합니다.

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return array.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
//This is where our values are stored
            let object = array[indexPath.row]
            cell.textLabel?.text = object.name
            cell.detailTextLabel?.text = object.question
            return cell
        }


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow