web-dev-qa-db-ja.com

Swift 3のJSON解析

Swift 3でJSONファイルを解析する方法を見つけた人はいますか?サンプルコードを投稿しますが、非常に多くの異なる方法を実行して失敗し、保存していません。解析したい基本的な形式はこのようなものです。

{
  "Language": {

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

JSONSerialization.jsonObject(with:options:)を試しましたか?

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は非常に奇妙な構文を生成することがあります。

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

JSONオブジェクト階層のすべては、オプションとしてラップされます(つまり、AnyObject?)。 Array<T>添え字は、オプションではないTを返します。このJSONはオプションでラップされており、配列添え字はOptional<AnyObject>を返します。ただし、Dictionary<K, V>添え字はOptional<V>を返します。このJSONの場合、添え字は非常に奇妙なOptional<Optional<AnyObject>>(つまりAnyObject??)を返します。

  • jsonOptional<AnyObject>です。
  • json?["Language"]Optional<Optional<AnyObject>>を返します。
  • json?["Language"]??["Field"]Optional<Optional<AnyObject>>を返します。
  • json?["Language"]??["Field"]??[0]Optional<AnyObject>を返します。
  • json?["Language"]??["Field"]??[0]?["Number"]Optional<Optional<AnyObject>>を返します。
  • json?["Language"]??["Field"]??[0]?["Number"] as? StringOptional<String>を返します。

Optional<String>は、if let構文でStringを生成するために使用されます。


最後の注意:フィールド配列の反復は次のようになります。

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

Swift 4 Update

Swift 4では、これらすべての処理がはるかに簡単になります。繰り返しますが、テストデータから始めます("""はこれを非常に良くします)。

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

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

次に、JSONで使用されるオブジェクトの周りにクラスを定義できます。

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" }
}

CodingKeys enumは、構造体プロパティがJSONオブジェクトメンバー文字列にマップされる方法です。このマッピングは、Decodableによって自動的に行われます。


JSONの解析が簡単になりました。

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

Xcode 8およびSwift 3idAnyではなくAnyObjectとしてインポートするようになりました

つまり、JSONSerialization.jsonObject(with: data)Anyを返します。そのため、json data[String:Any]のような特定の型にキャストする必要があります。 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
}

実際には、jsonに特定のフィールドを埋めておくとよいでしょう。 Name配列の最初の要素のFieldフィールドであると仮定しましょう。このようなアンラップのチェーンを使用して、フィールドに安全にアクセスできます。

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")
}

また、AppleのSwift Blog SwiftでJSONを操作する

13
serg_zhd

JSONを文字列に手動で入力するのはピタです。 JSONをファイルに入れてそれを読み取ってみませんか?

スウィフト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

Swiftjsonライブラリを使用する

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 

....

このような 。

0
ismailtsn92

Simple WayでSwift 4を使用したJSON解析

   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

Decodable Protocolを使用したSwift 4でのJSON解析:

あなたのjsonオブジェクトを使用してモックファイルを作成します:

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

JSONを解析するコードは次のとおりです。

モデル作成:

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
}

JSONファイルに何かが欠落している可能性がある場合に、モデルでオプションを使用できます。

これは解析ロジックです:

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()
}
}

印刷出力:

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

このgithubプロジェクトリンク。確認できます。

0
Ashis Laha