我有一个自定义类
public class Balance: NSObject {
var details: String
var date: Date
var amount: Double
}
我尝试过作为结构而且作为一个类都失败
我有一系列余额list: [Balance]
现在我需要将此数组转换为JSON字符串
之类的东西[ {details = "text"; date = "2016-11-20"; amount = 0;} ,
{details = "text2"; date = "2016-11-25"; amount= 10;} ]
我还需要能够将String转换回数组。 但我甚至无法让数组到JSON字符串工作
var resStr = ""
var list: [Balance]
do {
let data = try JSONSerialization.data(withJSONObject: list, options: .prettyPrinted)
resStr = String.init(data: data, encoding: .utf8) ?? ""
} catch { fatalError("Error BALANCE HISTORY ") }
失败了 'JSON写入无效类型(余额)'
请指教 提前致谢
答案 0 :(得分:1)
如何定义你的课程:
public class Balance: NSObject {
var details: String
var date: Date
var amount: Double
func toJSONString() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return "{details = \(self.details); date = \(dateFormatter.string(from: self.date)); amount = \(self.amount);}"
}
}
然后你可以像这样创建完整的JSON字符串:
var fullJSONArray = [String]()
for balance in list {
fullJSONArray.append(balance.toJSONString)
}
let fullJSONString = fullJSONArray.description
我希望这会帮助你!祝你好运,如果你有任何进一步的问题或问题,请告诉我!
答案 1 :(得分:1)
您只能将非常小的数据类型列表存储到JSON。
@CoolPenguin提供了一种解决方案 - 一种将对象转换为JSON字符串的自定义方法。
我建议不要自己构建JSON字符串。
相反,我建议为您的类创建toDictionary()
方法,并使用init(dictionary:)
方法从字典中创建Balance
对象。
您可以将日期转换为自1970年以来的TimeInterval
(UNIX"纪元日期"。)这似乎比将它们转换为日期字符串更容易。
然后,您可以将Balance
个对象数组映射到字典数组,并使用普通JSONSerialization
将那个转换为JSON。
let mappedArray = balanceArray.map{$0.toDictionary()}
然后轻松将您的词典数组转换为JSON。
答案 2 :(得分:1)
既然其他人指出首先将对象转换为 Dictionary 就可以达到预期的效果,那么我将提供一种方法来使用 JSONEncoder
来实现所需的效果。
如果您维护需要在 JSON 编码字符串中表示的值(例如 date
作为格式化的 String
),唯一需要的位是,
Codable
CodingKeys
枚举,代表您的类型属性的 JSON 键。请参阅以下适用于您的对象的示例。
public class Balance: NSObject, Codable {
var details: String
// Used to represent formatted date.
var dateString: String
var date: Date = Date(){
didSet{
updateDateString()
}
}
var amount: Double
enum CodingKeys: String, CodingKey{
case details, dateString, amount
}
init(_ d: String, amt: Double){
details = d
dateString = ""
date = Date()
amount = amt
super.init()
updateDateString()
}
private func updateDateString(){
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POSIX")
df.dateFormat = "yyyy-MM-dd"
dateString = df.string(from: date)
}
}
var arr: [Balance] = [
Balance("Shared Balance", amt: 100),
Balance("Coupon Balance", amt: 120),
Balance("Account Balance", amt: 150)
]
do{
let data = try JSONEncoder().encode(arr)
// Convert to JSON Encoded String
let str = String(data: data, encoding: .utf8)!
print(str)
// Convert back from JSON Encoded String
let raw = try JSONDecoder().decode([Balance].self, from: str.data(using: .utf8)!)
print(raw)
}
catch(let err){
print(err)
}
额外的 updateDateString()
样板代码用于生成日期格式为 "yyyy-MM-dd"
的字符串。
上述代码可以生成 Balance
数组的 JSON 编码版本,如下所示。
[{"details":"Shared Balance","amount":100,"dateString":"2021-01-14"},
{"details":"Coupon Balance","amount":120,"dateString":"2021-01-14"},
{"details":"Account Balance","amount":150,"dateString":"2021-01-14"}]
关键是使用 JSONEncoder
而不是 JSONSerialization
。
希望我有所帮助!
答案 3 :(得分:0)
嗯,我相信你首先需要将你的对象转换成某种形式的字典。
让我举个例子:
class Balance: NSObject {
var details: String
var date: Date
var amount: Double
func asDictionary() -> [String: AnyObject] {
return ["details": details as AnyObject, "date": "\(date)" as AnyObject, "amount": amount as AnyObject]
}
}
使用方法asDictionary
将对象转换为字典,以便将其序列化为JSON。
假设您有一个Balance对象列表。
您需要首先使用上述方法将每个对象转换为字典,然后尝试将对象序列化为JSON。请注意,该列表现在是[String:AnyObject]词典的列表,而不是Balance对象列表。
var resStr = ""
var list: [[String: AnyObject]] = [balance1.asDictionary(), balance2.asDictionary()]
do {
let data = try JSONSerialization.data(withJSONObject: list, options: .prettyPrinted)
resStr = String.init(data: data, encoding: .utf8) ?? ""
} catch { fatalError("Error BALANCE HISTORY ") }
对于某些类型,比如日期字段,您需要找到一些方法将其转换为String,因为JSONSerializer非常挑剔。在这种情况下,我只使用字符串插值,但格式可能不是您想要的样式。
如果要从JSON转换回Balance对象,首先需要将JSON转换为字典,然后检查每个字段是否存在,如果存在,则构造您的Balance对象。
假设您已将JSON数据转换为名为dict
的变量中的字典,您可以执行以下操作:
// supposing you have a single object in dict
var balance: Balance
balance.details = dict["details"]
balance.amount = dict["amount"]
balance.date = parseDate(dict["date"])
假设您有一个函数parseDate,用于将String中的日期解析为Date对象。
您可以在此处查看将字符串日期转换为对象:Use SwiftyJSON to deserialize NSDate