【发布时间】:2018-06-28 22:44:36
【问题描述】:
我从 firebase 获得以下 JSON:
{"listings":{"-cecececee-oha-":{"listing_id":"-xsxsxsxsxs-oha-","location":"Edinburgh"},"-xsxssxxsxs":{"listing_id":"-xsxsxsxs","location":"Edinburgh","messages":{"xsxsxsxs":{"-xsxssxxs":{"senderId":"wdwdwwd","senderName":"wddwdw","text":"Hey there"},"-L19r0osoet4f9SjBGE7":{"senderId":"cddccdcd","senderName":"dccd","text":"Hi"}}}},"-cdcdcdcd":{"listing_id":"-cdcdcdcd","location":"Edinburgh","messages":{"879dUqGuiXSd95QHzfhbSs05IZn2":{"-L1i6c7sGf3BcF2cCSCu":{"senderId":"879dUqGuiXSd95QHzfhbSs05IZn2","senderName":"cddcdcdcd","text":"cdcddccdcd"}},"cddcdccdcd":{"-L19FGCMuQACjYKCFEwV":{"senderId":"Rp7ytJdEvZeMFgpLqeCSzkSeTyf1","senderName":"dccdcdcd","text":"Hey"},"-cdcdcdcdcd-":{"senderId":"cdcdcdcd","senderName":"dcdccdcd","text":"cdcddccd"},"-cdcdcdcd":{"senderId":"cdcdcdcdcd","senderName":"cdcdcdcdcd","text":"How are you"}}}},"-cdcdcdcd-dccd":{"listing_id":"-cdcdcdcd-JCbiAnN","location":"Edinburgh"},"-dccdcdcdcd-EKCq2":{"listing_id":"-cdcdcdcd-EKCq2","location":"Edinburgh"},"-cddccdcdcd":{"listing_id":"-cdcdcddcdc","location":"Edinburgh"}}}
我目前正在使用 Firebase API 在 Swift 中进行如下解析:
_ = Database.database().reference().child("users").child(UserDefaults.standard.object(forKey: "uid") as! String).observeSingleEvent(of : .value, with: { (snapshot) in
var matches_list = [ChatMatch]()
if let matches = snapshot.childSnapshot(forPath: "listings").value as? [String:AnyObject] {
for (str,_) in matches {
if let dictionary = snapshot.childSnapshot(forPath: "listings").childSnapshot(forPath: str).value as? [String:AnyObject] {
let location = dictionary["location"] as! String
let a = ChatMatch()
a.id = str
a.location = location
if let pairs = snapshot.childSnapshot(forPath: "listings").childSnapshot(forPath: str).childSnapshot(forPath:"messages").value as? [String:AnyObject] {
for (str1,_) in pairs {
if let dic = snapshot.childSnapshot(forPath: "listings").childSnapshot(forPath: str).childSnapshot(forPath:"messages").childSnapshot(forPath: str1).value as? [String:AnyObject] {
for (str2, _) in dic {
if let dic2 = snapshot.childSnapshot(forPath: "listings").childSnapshot(forPath: str).childSnapshot(forPath:"messages").childSnapshot(forPath: str1).childSnapshot(forPath: str2).value as? [String:AnyObject] {
if let senderid = dic2["senderId"] as? String {
if (senderid != UserDefaults.standard.object(forKey: "uid") as! String) {
a.matchid = senderid
}
}
if let senderName = dic2["senderName"] as? String {
if (senderName != UserDefaults.standard.object(forKey: "name") as! String) {
a.matchName = senderName
matches_list.append(a)
break
}
}
}
}
}
}
}
}
}
}
for match in matches_list {
Database.database().reference().child("listings").child(match.location!).child(match.id!).observeSingleEvent(of: .value, with: { (snapshot2) in
if let dict = snapshot2.value as? [String : Any] {
let new_listing = Listing()
let fromString = dict["from"] as! String
let toString = dict["to"] as! String
let landlordId = dict["landlord_id"] as! String
let landlordName = dict["name"] as! String
let listingId = dict["listing_id"] as! String
let pic1url = dict["pic_1_url"] as! String
let pic2url = dict["pic_2_url"] as! String
let pic3url = dict["pic_3_url"] as! String
let pic4url = dict["pic_4_url"] as! String
let pic5url = dict["pic_5_url"] as! String
let pricepernight = dict["price_per_night"] as! String
let postcode = dict["postcode"] as! String
let location = dict["location"] as! String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/mm/yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+0:00")
let fromdate = dateFormatter.date(from: fromString)
new_listing.from = fromdate
let todate = dateFormatter.date(from: toString)
new_listing.to = todate
new_listing.landlordId = landlordId
new_listing.landlordName = landlordName
new_listing.listingId = listingId
new_listing.pricePerNight = Int(String(pricepernight.suffix(pricepernight.count - 1)))!
if (pic1url != "none") {
new_listing.pic1url = URL(string: pic1url)
}
if (pic2url != "none") {
new_listing.pic2url = URL(string: pic2url)
}
if (pic3url != "none") {
new_listing.pic3url = URL(string: pic3url)
}
if (pic4url != "none") {
new_listing.pic4url = URL(string: pic4url)
}
if (pic5url != "none") {
new_listing.pic5url = URL(string: pic5url)
}
new_listing.postcode = postcode
new_listing.location = location
new_listing.partnername = match.matchName
new_listing.partnerid = match.matchid
listings.append(new_listing)
if (matches_list.index(of: match) == matches_list.count - 1) {
completionHandler(true, listings)
return
}
}
})
}
if (matches_list.count == 0) {
completionHandler(false, listings)
}
})
}
如您所见,我通过转换成字典并循环遍历 JSON 来完成我的工作。
我现在需要在F# 中做同样的事情。我设法使用REST API 获取 JSON,因为 F# 中没有适用于 Firebase 的本机 API。但是,在解析这个 JSON 时,我完全迷失了。我设法想出了以下代码:
let myCallbackGetChats (reader:IO.StreamReader) url =
let html = reader.ReadToEnd()
let reader : JsonTextReader = new JsonTextReader(new StringReader(html))
while (reader.Read()) do
if reader.Value <> null then
let value = reader.Value :?> String
这允许我遍历 JSON 并读取所有值,但是我认为这不适合这里,因为某些值可能不存在(由 Swift 中的 if let 处理)。另外,我认为这不能正确维护 JSON 的嵌套或层次结构,它只是依次访问所有值。
我正在阅读本教程:http://www.hoonzis.com/fsharp-json-serializaton/ 但是我不知道如何使用:
JsonConvert.SerializeObject(data)
我是否应该简单地创建一个模仿 JSON 结构的对象?那么日期将如何处理,它们会自动转换吗?存储为字符串等的双打怎么样?我自己编写这段代码会更舒服,就像我在 Swift 中所做的那样,因为这将确保所有内容都被正确解析,但是我不知道真正从哪里开始以及如何处理代码 sn-p 中 JSON 的嵌套假如。
【问题讨论】:
-
我不知道 F#,但是你用谷歌搜索过这个吗? fsharp.github.io/FSharp.Data/library/JsonProvider.html 似乎演示了如何解析 JSON
-
谢谢!
-
我忘了说,JSONSerialization,iOS SDK 提供了一种在 Swift 中使用几乎单线解析 JSON 的方法。 developer.apple.com/documentation/foundation/jsonserialization
标签: ios json swift firebase-realtime-database f#