使用 Swifty JSON 解析数组

Posted

技术标签:

【中文标题】使用 Swifty JSON 解析数组【英文标题】:Use Swifty JSON to parse array 【发布时间】:2016-12-10 15:01:53 【问题描述】:

这是我要解析的 json(示例):

[
  
    "id": 1,
    "name": "Team name",
    "shower": 
      "id": 1,
      "status": 1,
      "startLocation": 
        "id": 1,
        "name": "abc 16"
      
    
  ,
  
    "id": 2,
    "name": "Team name",
    "shower": 
      "id": 2,
      "status": 1,
      "startLocation": 
        "id": 1,
        "name": "efg 16"
      
    
  
]
粘贴this json viewer即可轻松查看。

如您所见,它是一个(团队)数组。 我需要让每个团队都参与其中。

经过多次尝试,我尝试使用SwiftyJSON,因为我认为它会更容易。但是,它对我不起作用。

这是我尝试过的:

let array = JSON(response)  

// print each subJSON in array
for team in array.arrayValue                     
  print(team)                    

但循环不起作用。它根本不进入循环。 也许它不明白我的json是一个数组。

我可以在调试器中看到数组对象。它看起来像这样:

如何获取这些子 JSON?

谢谢。

【问题讨论】:

您的 JSON 无效。 "name": "abc 16" 之后的行和之后的行不应该有逗号。 使用jsoneditoronline.org 这个来验证你的json。它在您的 json 字符串中显示错误。 要求您的服务器团队在每个创建问题的值之前删除额外的斜杠,因为 json 是键值对,但它似乎是无法获取的字符串 谢谢大家,我编辑并修复了 json 示例。 修复json字符串后还是不行? 【参考方案1】:

我认为你应该使用

let array = JSON(parseJSON: response) 

而不是

let array = JSON(response)

【讨论】:

我试过你的建议@Arjuna,它没有奏效。仍然没有进入循环。谢谢,【参考方案2】:

SwiftyJSON 包含将 JSON 字符串解析为 JSON 对象的方法,请查看documentation

/**
 Parses the JSON string into a JSON object
 - parameter json: the JSON string
 - returns: the created JSON object
*/

 public init(parseJSON jsonString: String) 
   if let data = jsonString.data(using: .utf8) 
                self.init(data)
             else 
                self.init(NSNull())
                    
          


/**
 Creates a JSON from JSON string
 - parameter string: Normal json string like '"a":"b"'

 - returns: The created JSON
 */
@available(*, deprecated: 3.2, message: "Use instead `init(parseJSON: )`")
public static func parse(json: String) -> JSON 
    return json.data(using: String.Encoding.utf8)
        .flatMap JSON(data: $0)  ?? JSON(NSNull())

或者您也可以将子字符串转换为子对象,例如

斯威夫特 3:

let dataFromString = response.data(using: .utf8)
let jsonArray = JSON(data: dataFromString!)

【讨论】:

【参考方案3】:

在以下示例中,我将团队名称保存在一个数组中。我已经测试过了。

var names = [String]()
if let array = json.array 
    for i in 0..<array.count 
        let name = array[i]["name"]
        names.append(name.stringValue)
    


print(names) // ["Team name", "Team name"]

【讨论】:

【参考方案4】:

这是 Swift 5 的答案。在我的情况下,数据响应如下所示:

[
  
    "Name": "Some Type",
    "Data": [
      
        "ParentId": 111,
        "Code": "Personal",
        "SortOrder": 1,
        "Name": "Personal",
        "Id": 323
      ,
      
        "ParentId": null,
        "Code": "Work",
        "SortOrder": 2,
        "Name": "Work",
        "Id": 324
      
    ],
    "KeyType": "Integer"
  ,
  
    "Name": "Phone Type",
    "Data": [
      
        "ParentId": null,
        "Code": "Phone",
        "SortOrder": 1,
        "Name": "Phone",
        "Id": 785
      ,
      
        "ParentId": null,
        "Code": "Cell",
        "SortOrder": 2,
        "Name": "Cell",
        "Id": 786
      ,
      
        "ParentId": null,
        "Code": "Fax",
        "SortOrder": 3,
        "Name": "Fax",
        "Id": 787
      ,
      
        "ParentId": null,
        "Code": "Home",
        "SortOrder": 4,
        "Name": "Home",
        "Id": 788
      ,
      
        "ParentId": null,
        "Code": "Office",
        "SortOrder": 5,
        "Name": "Office",
        "Id": 789
      
    ],
    "KeyType": "Integer"
  
]

我是用下面的代码处理的。

struct responseObjectClass:BaseModel 
    var responsearray: [arrayData]? = nil

    init(json: JSON) 
        responsearray = json.arrayValue.map  arrayData(json: $0) 
    


struct arrayData:BaseModel 
    let Name: String?
       var DataValue: [DataLookup]? = nil
       let KeyType: String?
       
       init(json: JSON) 
           Name = json["Name"].stringValue
           DataValue = json["Data"].arrayValue.map  DataLookup(json: $0) 
           KeyType = json["KeyType"].stringValue
       


struct DataLookup:BaseModel 
    
    
    let ParentId: Any?
    let Code: String?
    let SortOrder: Int?
    let Name: String?
    let Id: Int?
    
    init(json: JSON) 
        ParentId = json["ParentId"]
        Code = json["Code"].stringValue
        SortOrder = json["SortOrder"].intValue
        Name = json["Name"].stringValue
        Id = json["Id"].intValue
    

BaseModel 是可选的,它只用于 init Json。

protocol BaseModel 
  init(json: JSON)

【讨论】:

【参考方案5】:

没有 SwiftyJSON

以下是有效的 JSON

data.json 文件

[
  "id": 1,
  "name": "Team name",
  "shower": 
        "id": 1,
        "status": 1,
        "startLocation": 
  "id": 1,
  "name": "abc 16"
        
  
  , 
  "id": 2,
  "name": "Team name",
  "shower": 
        "id": 2,
        "status": 1,
        "startLocation": 
  "id": 1,
  "name": "efg 16"
        
  
]

以下是读取 json 的代码。

if let path = Bundle.main.path(forResource: "data", ofType: "json") 
        let url = URL(fileURLWithPath: path)
        do 
            let data = try Data(contentsOf: url)
            if let jsonArray = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSArray 
                for (_, item) in jsonArray.enumerated() 
                    let itemDict = item as! NSDictionary
                    let id = itemDict["id"] as! Int
                    let name = itemDict["name"] as! String
                    let shower = itemDict["shower"] as! NSDictionary

                    let showerId = shower["id"] as! Int
                    let showerStatus = shower["status"] as! Int
                    let startLocation = shower["startLocation"] as! NSDictionary


                    let startLocationId = startLocation["id"] as! Int
                    let startLocationName = startLocation["name"] as! String

                
            
         catch 
            print("Error: \(error.localizedDescription)")
        

【讨论】:

【参考方案6】:

这对我有用:

   // Convert JSON to Array
    func JSONToArray(_ json: String) -> Array<Any>? 
        if let data = json.data(using: String.Encoding.utf8) 
            do 
                return try JSONSerialization.jsonObject(with: data, options: []) as? Array
             catch let error as NSError 
                print(error)
            
        
        return nil
    

使用此函数后,我可以循环遍历子 JSON。

谢谢。

【讨论】:

以上是关于使用 Swifty JSON 解析数组的主要内容,如果未能解决你的问题,请参考以下文章

Swifty JSON 响应解析

使用 Swifty JSON 解析

Swifty-JSON:无法解析下划线

如何使用 Swifty 动态创建具有多个键和值的 json 对象

swifty Json 解析数据显示我为零?

Swift 3 Alamofire Swifty json 解析问题