webentwicklung-frage-antwort-db.com.de

JSON-Analyse in Swift 3

Hat jemand einen Weg gefunden, JSON-Dateien in Swift 3 zu analysieren? Ich konnte die Daten zurückgeben, ist jedoch nicht erfolgreich, wenn es darum geht, die Daten in bestimmte Felder zu unterteilen. Ich würde Beispielcode posten, aber ich habe so viele verschiedene Methoden durchlaufen und habe keine gespeichert. Das grundlegende Format, das ich analysieren möchte, ist so etwas. Danke im Voraus.

{
  "Language": {

    "Field":[
          {
          "Number":"976",
          "Name":"Test"
          },
          {
          "Number":"977",
          "Name":"Test"
          }
       ]
   }
}
21
Nas5296

Haben Sie JSONSerialization.jsonObject(with:options:) ausprobiert?

var jsonString = "{" +
    "\"Language\": {" +
    "\"Field\":[" +
    "{" +
    "\"Number\":\"976\"," +
    "\"Name\":\"Test\"" +
    "}," +
    "{" +
    "\"Number\":\"977\"," +
    "\"Name\":\"Test\"" +
    "}" +
    "]" +
    "}" +
    "}"

var data = jsonString.data(using: .utf8)!

let json = try? JSONSerialization.jsonObject(with: data)

Swift erzeugt manchmal eine sehr seltsame Syntax.

if let number = json?["Language"]??["Field"]??[0]?["Number"] as? String {
    print(number)
}

Alles in der JSON-Objekthierarchie wird als optionales Element eingeschlossen (dh AnyObject?). Array<T> subscript gibt eine nicht optionale T zurück. Für diese JSON, die optional in einem Array eingeschlossen ist, gibt der Array-Index Optional<AnyObject> zurück. Dictionary<K, V>-Index gibt jedoch einen Optional<V> zurück. Für diese JSON gibt das Subskription das sehr ungerade aussehende Optional<Optional<AnyObject>> (dh AnyObject??) zurück.

  • json ist ein Optional<AnyObject>.
  • json?["Language"] gibt einen Optional<Optional<AnyObject>> zurück.
  • json?["Language"]??["Field"] gibt einen Optional<Optional<AnyObject>> zurück.
  • json?["Language"]??["Field"]??[0] gibt einen Optional<AnyObject> zurück.
  • json?["Language"]??["Field"]??[0]?["Number"] gibt einen Optional<Optional<AnyObject>> zurück.
  • json?["Language"]??["Field"]??[0]?["Number"] as? String gibt einen Optional<String> zurück.

Der Optional<String> wird dann von der if let-Syntax verwendet, um eine String zu erzeugen.


Schlussbemerkung: Das Durchlaufen des Feld-Arrays sieht folgendermaßen aus.

for field in json?["Language"]??["Field"] as? [AnyObject] ?? [] {
    if let number = field["Number"] as? String {
        print(number)
    }
}

Swift 4 Update

Mit Swift 4 ist das alles viel einfacher zu handhaben. Wieder beginnen wir mit Ihren Testdaten (""" macht das so viel schöner).

let data = """
{
  "Language": {

    "Field":[
          {
          "Number":"976",
          "Name":"Test"
          },
          {
          "Number":"977",
          "Name":"Test"
          }
       ]
   }
}
""".data(using: .utf8)!

Als Nächstes können wir Klassen um die in Ihrem JSON verwendeten Objekte definieren.

struct Object: Decodable {
    let language: Language
    enum CodingKeys: String, CodingKey { case language="Language" }
}

struct Language: Decodable {
    let fields: [Field]
    enum CodingKeys: String, CodingKey { case fields="Field" }
}

struct Field: Decodable {
    let number: String
    let name: String
    enum CodingKeys: String, CodingKey { case number="Number"; case name="Name" }
}

Die Aufzählung CodingKeys gibt an, wie Struktureigenschaften JSON-Objektelementstrings zugeordnet werden. Diese Zuordnung wird automatisch von Decodable durchgeführt.


Das Parsen des JSON ist jetzt einfach.

let object = try! JSONDecoder().decode(Object.self, from: data)

print(object.language.fields[0].name)

for field in object.language.fields {
    print(field.number)
}
27
Jeffery Thomas

In Xcode 8 und Swift 3id wird jetzt als Any anstelle von AnyObject importiert.

Dies bedeutet, dass JSONSerialization.jsonObject(with: data)Any zurückgibt. Sie müssen also die json data in einen bestimmten Typ wie [String:Any] umwandeln. Gleiches gilt für die nächsten Felder des Json.

var jsonString = "{" +
    "\"Language\": {" +
    "\"Field\":[" +
    "{" +
    "\"Number\":\"976\"," +
    "\"Name\":\"Test1\"" +
    "}," +
    "{" +
    "\"Number\":\"977\"," +
    "\"Name\":\"Test2\"" +
    "}" +
    "]" +
    "}" +
"}"

var data = jsonString.data(using: .utf8)!
if let parsedData = try? JSONSerialization.jsonObject(with: data) as! [String:Any] {
    let language = parsedData["Language"] as! [String:Any]
    print(language)
    let field = language["Field"] as! [[String:Any]]
    let name = field[0]["Name"]!
    print(name) // ==> Test1
}

In der Praxis würden Sie wahrscheinlich ein bestimmtes Feld im Json begraben wollen. Nehmen wir an, es ist das Feld Name des ersten Elements des Arrays Field. Sie können eine Kette von Unwraps wie folgt verwenden, um sicher auf das Feld zuzugreifen:

var data = jsonString.data(using: .utf8)!
if let json = try? JSONSerialization.jsonObject(with: data) as? [String:Any],
    let language = json?["Language"] as? [String:Any],
    let field = language["Field"] as? [[String:Any]],
    let name = field[0]["Name"] as? String, field.count > 0 {
    print(name) // ==> Test1
} else {
    print("bad json - do some recovery")
}

Vielleicht möchten Sie auch den Swift-Blog von Apple überprüfen Arbeiten mit JSON in Swift

13
serg_zhd

JSON manuell in einen String zu schieben ist eine Pita. Warum legst du nicht einfach die JSON in eine Datei und liest das ein?

Swift 3:

let bundle = Bundle(for: type(of: self))
    if let theURL = bundle.url(forResource: "response", withExtension: "json") {
        do {
            let data = try Data(contentsOf: theURL)
            if let parsedData = try? JSONSerialization.jsonObject(with: data) as! [String:Any] {
                grok(parsedData)
            }
        } catch {
            print(error)
        }
    }
3
Gene De Lisa

Verwenden Sie die Bibliothek swiftjson Ich denke, es ist eine sehr einfache Methode zum Analysieren 

let count: Int? = json["Field"].array?.count
            if let ct = count {

                for index in 0...ct-1{

                let number = json ["Field"][index]["number"].string
                let name = json ["Field"][index]["name"].string 

....

so was .

0
ismailtsn92

JSON-Analyse mit Swift 4 in Simple WAY

   let url = URL(string: "http://mobileappdevelop.co/TIPIT/webservice/get_my_groups?user_id=5")
    URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
        guard let data = data, error == nil else { return }

        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]

             print(json)

            let posts =  json["Field"] as? [[String: Any]] ?? []
            print(posts)
        } catch let error as NSError {
            print(error)
        }

    }).resume()

}
0
user8771317
 override func viewDidLoad() {
        super.viewDidLoad()
        let url=URL(string:"http://api.androidhive.info/contacts/")
        do {
            let allContactsData = try Data(contentsOf: url!)
            let allContacts = try JSONSerialization.jsonObject(with: allContactsData, options: JSONSerialization.ReadingOptions.allowFragments) as! [String : AnyObject]
            if let arrJSON = allContacts["contacts"] {
                for index in 0...arrJSON.count-1 {
                    let aObject = arrJSON[index] as! [String : AnyObject]
                    names.append(aObject["name"] as! String)
                    contacts.append(aObject["email"] as! String)
                }
            }
            print(names)
            print(contacts)
            self.tableView.reloadData()
        }
        catch {
        }
    }
0
BhuShan PaWar

JSON-Analyse in Swift 4 unter Verwendung des decodierbaren Protokolls:

Ich erstelle eine mocky Datei mit Ihrem Json-Objekt: 

http://www.mocky.io/v2/5a280c282f0000f92c0635e6

Hier ist der Code zum Parsen des JSON: 

Modellerstellung:

import UIKit

struct Item : Decodable { 
// Properties must be the same name as specified in JSON , else it will return nil
var Number : String
var Name : String
}

struct Language : Decodable {
 var Field : [Item]
}

struct Result : Decodable {
 var Language : Language
}

Sie können optional im Modell verwenden, wenn Sie sich nicht sicher sind, ob in der JSON-Datei etwas fehlt.

Dies ist die Parsing-Logik:

class ViewController: UIViewController {

let url = "http://www.mocky.io/v2/5a280c282f0000f92c0635e6"

private func parseJSON() {

    guard let url = URL(string: url) else { return }

    let session = URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let data = data else { return }
        guard let result = try? JSONDecoder().decode(Result.self, from: data) else { return }
        print("\n\nResult : \(result)")
    }
    session.resume()
}

override func viewDidLoad() {
    super.viewDidLoad()
    parseJSON()
}
}

Die Druckausgabe:

 Result : Result(Language: JSON_Parsing.Language(Field: [JSON_Parsing.Item(Number: "976", Name: "Test"), JSON_Parsing.Item(Number: "977", Name: "Test")]))

Dies ist der Github Project Link. Du kannst nachschauen.

0
Ashis Laha