【问题标题】:Create JSON in swift快速创建 JSON
【发布时间】:2015-06-13 07:18:07
【问题描述】:

我需要像这样创建 JSON:

Order = {   type_id:'1',model_id:'1',

   transfer:{
     startDate:'10/04/2015 12:45',
     endDate:'10/04/2015 16:00',
     startPoint:'Ул. Момышулы, 45',
     endPoint:'Аэропорт Астаны'
   },
   hourly:{
     startDate:'10/04/2015',
     endDate:'11/04/2015',
     startPoint:'ЖД Вокзал',
     endPoint:'',
     undefined_time:'1'
   },
   custom:{
     startDate:'12/04/2015',
     endDate:'12/04/2015',
     startPoint:'Астана',
     endPoint:'Павлодар',
     customPrice:'50 000'
   },
    commentText:'',
    device_type:'ios'
};

问题是我无法创建有效的 JSON。 以下是我创建对象的方式:

let jsonObject: [AnyObject]  = [
        ["type_id": singleStructDataOfCar.typeID, "model_id": singleStructDataOfCar.modelID, "transfer": savedDataTransfer, "hourly": savedDataHourly, "custom": savedDataReis, "device_type":"ios"]
    ]

savedData 是字典:

let savedData: NSDictionary = ["ServiceDataStartDate": singleStructdata.startofWork, 
"ServiceDataAddressOfReq": singleStructdata.addressOfRequest, 
"ServiceDataAddressOfDel": singleStructdata.addressOfDelivery, 
"ServiceDataDetailedText": singleStructdata.detailedText, "ServiceDataPrice": singleStructdata.priceProposed]

当我只使用字符串创建我的 JSON 对象时,一切正常。但是,当我包含字典 @​​987654326@ 时,返回 false。如何创建有效的字典?

【问题讨论】:

  • 是的,红色那篇文章。那篇文章 nsdictionary 只有字符串值。在我的情况下 var transfer, hourly, custom 有很多值。它不是字符串......所以我应该如何包含它们?
  • 让 jsonObject: [AnyObject] = [ ["type_id": singleStructDataOfCar.typeID, "model_id": singleStructDataOfCar.modelID, "transfer":[ "startDate":savedDataTransfer["ServiceDataStartDate"] as String , "EndPoint": savedDataTransfer["ServiceDataAddressOfDel"] as String, "CommentText": savedDataTransfer["ServiceDataDetailedText"] as String, "StartPoint":savedDataTransfer["ServiceDataAddressOfReq"] as String ] ]//, "hourly": savedDataHourly, "custom": savedDataReis, "device_type":"ios"] ]
  • 我知道这是乱码。但它也不起作用
  • 我想singleStructdata.* 项目之一确实不是 json 可转换的。使用NSJSONSerialization.isValidJSONObject 分别尝试这些方法,您就会找到罪魁祸首。

标签: json swift object


【解决方案1】:

斯威夫特 5 - 21 年 6 月 30 日

采用 Codable 协议(类似于其他编程语言中的接口)

struct ConfigRequestBody: Codable {
var systemid: String
var password: String
var request: String = "getconfig"

init(systemID: String, password: String){
    self.systemid = systemID
    self.password = password
}

}

创建要转换为 JSON 的结构/类的实例:

let requestBody = ConfigRequestBody(systemID: systemID, password: password)

使用JSONEncoder 将对象编码为 JSON。这里我打印字符串表示,以便您查看结果:

    let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted
    do {
        let result = try encoder.encode(requestBody)
        // RESULT IS NOW JSON-LIKE DATA OBJECT
        if let jsonString = String(data: result, encoding: .utf8){
            // JSON STRING
            print("JSON \(jsonString)")
        }
    } catch {
        print("Your parsing sucks \(error)")
        return nil
    }
}

【讨论】:

    【解决方案2】:

    对于 Swift 3.0,截至 2016 年 12 月,这对我来说是这样的:

    let jsonObject: NSMutableDictionary = NSMutableDictionary()
    
    jsonObject.setValue(value1, forKey: "b")
    jsonObject.setValue(value2, forKey: "p")
    jsonObject.setValue(value3, forKey: "o")
    jsonObject.setValue(value4, forKey: "s")
    jsonObject.setValue(value5, forKey: "r")
    
    let jsonData: NSData
    
    do {
        jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: JSONSerialization.WritingOptions()) as NSData
        let jsonString = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue) as! String
        print("json string = \(jsonString)")                                    
    
    } catch _ {
        print ("JSON Failure")
    }
    

    EDIT 2018:我现在使用 SwiftyJSON 库来节省时间,让我的开发生活更轻松、更好。在 Swift 中原生处理 JSON 是一种不必要的头痛和痛苦,而且浪费太多时间,并且创建的代码难以读写,因此容易出错。

    【讨论】:

      【解决方案3】:

      • Swift 4.1,2018 年 4 月

      这是一种更通用的方法,可用于通过使用字典中的值来创建 JSON 字符串:

      struct JSONStringEncoder {
          /**
           Encodes a dictionary into a JSON string.
           - parameter dictionary: Dictionary to use to encode JSON string.
           - returns: A JSON string. `nil`, when encoding failed.
           */
          func encode(_ dictionary: [String: Any]) -> String? {
              guard JSONSerialization.isValidJSONObject(dictionary) else {
                  assertionFailure("Invalid json object received.")
                  return nil
              }
      
              let jsonObject: NSMutableDictionary = NSMutableDictionary()
              let jsonData: Data
      
              dictionary.forEach { (arg) in
                  jsonObject.setValue(arg.value, forKey: arg.key)
              }
      
              do {
                  jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
              } catch {
                  assertionFailure("JSON data creation failed with error: \(error).")
                  return nil
              }
      
              guard let jsonString = String.init(data: jsonData, encoding: String.Encoding.utf8) else {
                  assertionFailure("JSON string creation failed.")
                  return nil
              }
      
              print("JSON string: \(jsonString)")
              return jsonString
          }
      }
      

      如何使用:

      let exampleDict: [String: Any] = [
              "Key1" : "stringValue",         // type: String
              "Key2" : boolValue,             // type: Bool
              "Key3" : intValue,              // type: Int
              "Key4" : customTypeInstance,    // type: e.g. struct Person: Codable {...}
              "Key5" : customClassInstance,   // type: e.g. class Human: NSObject, NSCoding {...}
              // ... 
          ]
      
          if let jsonString = JSONStringEncoder().encode(exampleDict) {
              // Successfully created JSON string.
              // ... 
          } else {
              // Failed creating JSON string.
              // ...
          }
      

      注意:如果您将自定义类型(结构)的实例添加到字典中,请确保您的类型符合 Codable 协议,如果您将自定义类的对象添加到字典中,请确保您的类继承自NSObject 并符合NSCoding 协议。

      【讨论】:

      • 另外,如果你描述如何使用,看到的用户会很容易理解。
      • @HardikThakkar 这很简单。我已经用如何使用 sn-p 编辑了答案。
      • @Baran Emre 您如何将 deocde jsonString 解码为 [String:Any] 字典?
      • @BaranEmre 只是为了添加到最后一个问题,我正在编码的 json 具有任意值的字符串类型的键。想想某些服务生成的 userId。
      • @chibro2 您想从 JSON 字符串创建字典,对吗?如果是,则执行以下操作:let data: Data! = yourString.data(using: .utf8),然后是 let dictionary = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]。
      【解决方案4】:

      一个问题是这段代码不是Dictionary类型的。

      let jsonObject: [Any]  = [
          [
               "type_id": singleStructDataOfCar.typeID,
               "model_id": singleStructDataOfCar.modelID, 
               "transfer": savedDataTransfer, 
               "hourly": savedDataHourly, 
               "custom": savedDataReis, 
               "device_type":"iOS"
          ]
      ]
      

      上面是AnyObject 的Array,其中包含[String: AnyObject] 类型的Dictionary。

      尝试这样的方式来匹配您在上面提供的 JSON:

      let savedData = ["Something": 1]
      
      let jsonObject: [String: Any] = [ 
          "type_id": 1,
          "model_id": 1,
          "transfer": [
              "startDate": "10/04/2015 12:45",
              "endDate": "10/04/2015 16:00"
          ],
          "custom": savedData
      ]
      
      let valid = JSONSerialization.isValidJSONObject(jsonObject) // true
      

      【讨论】:

      • 这是正确的,但我想为下一个出现的人向 SwiftyJSON pod 大声疾呼。它可能很有用。
      • SwiftyJSON 对此有很好的实现。此当前答案无效,但是,安装 SwiftyJSON 后,只需将 [String: AnyObject 更改为 JSON 即可。稍后当您尝试将值作为字典获取时,只需输入 jsonData.dictionaryObject 就可以了!
      • 我已将[String: AnyObject] 更改为[String: Any],以便编译示例代码。我最初在上面使用了AnyObject,以便jsonObject 可以在其中包含类实例。
      • 为什么 jsonObject["transfer"]["startDate"] 给我错误?
      • 这里是错误:error: type 'Any?' has no subscript members jsonObject["transfer"]["startDate"] 键“转移”给你一个Any?(可选Any);这是给jsonObject 的类型,即[String: Any](String 类型的键,Any 类型的值)。
      【解决方案5】:

      创建 JSON 字符串:

      let para:NSMutableDictionary = NSMutableDictionary()
      para.setValue("bidder", forKey: "username")
      para.setValue("day303", forKey: "password")
      para.setValue("authetication", forKey: "action")
      let jsonData = try! NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions.allZeros)
      let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
      print(jsonString)
      

      【讨论】:

      • 这对我真的很有帮助。谢谢
      【解决方案6】:

      查看https://github.com/peheje/JsonSerializerSwift

      用例:

      //Arrange your model classes
      class Object {
        var id: Int = 182371823
        }
      class Animal: Object {
        var weight: Double = 2.5
        var age: Int = 2
        var name: String? = "An animal"
        }
      class Cat: Animal {
        var fur: Bool = true
      }
      
      let m = Cat()
      
      //Act
      let json = JSONSerializer.toJson(m)
      
      //Assert
      let expected = "{\"fur\": true, \"weight\": 2.5, \"age\": 2, \"name\": \"An animal\", \"id\": 182371823}"
      stringCompareHelper(json, expected) //returns true
      

      目前支持标准类型、可选标准类型、数组、可空标准类型数组、自定义类数组、继承、自定义对象组合。

      【讨论】:

      • 我有一个 json,它有一个属性,它本身就是一个自定义对象的数组。通过 JsonSerialization.toJson 运行时,这会丢失值,我得到类似:“key”:[{},{}] 关于如何解决这个问题的任何想法?
      • 它适用于自定义对象数组,请检查 GitHub 测试文件以获取有关如何执行此操作的示例。测试用例名为 test_arrayOfCustomClass_included
      • 我将我的结构切换到一个类并且它起作用了。是否支持将结构作为自定义对象?
      【解决方案7】:

      这对我有用... Swift 2

      static func checkUsernameAndPassword(username: String, password: String) -> String?{
          let para:NSMutableDictionary = NSMutableDictionary()
              para.setValue("demo", forKey: "username")
              para.setValue("demo", forKey: "password")
             // let jsonError: NSError?
          let jsonData: NSData
          do{
              jsonData = try NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions())
              let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
              print("json string = \(jsonString)")
              return jsonString
      
          } catch _ {
              print ("UH OOO")
              return nil
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-13
        • 1970-01-01
        • 2019-08-20
        • 2015-10-13
        • 1970-01-01
        • 1970-01-01
        • 2021-05-19
        • 2016-02-29
        相关资源
        最近更新 更多