i am trying this but getting error . whats other way to sort this list of items .
getting error Value of tuple type
'(String, JSON)' has no member 'subscript'
let jsonData = try JSONSerialization.data(withJSONObject: bizSnapshot.value as Any, options: .prettyPrinted)
var bizOfferingsJson = try JSON(data: jsonData)
bizOfferingsJson items contains itemIndex as key as Int , i want to sort based on that itemIndex
bizOfferingsJson = bizOfferingsJson.sorted(by: { $0.["itemIndex"] > $1.["itemIndex"] })
print("bizOfferingsJson===",bizOfferingsJson)
sample bizOfferingsJson data
[
{
"isVisible" : true,
"itemRetailInfo" : {
"units" : "GRAMS",
"quantityPrice" : [
{
"discountPrice" : 0,
"regularPrice" : 25,
"quantity" : 1000,
"quantitySelected" : 1000,
"isEditable" : false
}
]
},
"imageStoragePathList" : [
"ONION_RED.png"
],
"bizOfferingsID" : "Vegetables_0",
"masterImage" : 0,
"vegNonVegInfoEnum" : "NONE",
"description" : "",
"itemQunatitySelected" : 0,
"bizOfferingsHeaderTypeThree" : {
"indexOrder" : 0,
"headerText" : "Vegetables",
"isVisible" : true
},
"itemIndex" : 0,
"totalCountQunatity" : 0,
"primaryText" : "Onion Red"
},
{
"isVisible" : true,
"itemRetailInfo" : {
"units" : "GRAMS",
"quantityPrice" : [
{
"discountPrice" : 0,
"regularPrice" : 25,
"quantity" : 1000,
"quantitySelected" : 1000,
"isEditable" : false
}
]
},
"imageStoragePathList" : [
"POTATO.png"
],
"bizOfferingsID" : "Vegetables_1",
"masterImage" : 0,
"vegNonVegInfoEnum" : "NONE",
"description" : "",
"itemQunatitySelected" : 0,
"bizOfferingsHeaderTypeThree" : {
"indexOrder" : 0,
"headerText" : "Vegetables",
"isVisible" : true
},
"itemIndex" : 1,
"totalCountQunatity" : 0,
"primaryText" : "Potato"
},
{
"isVisible" : true,
"itemRetailInfo" : {
"units" : "PIECES",
"quantityPrice" : [
{
"discountPrice" : 0,
"regularPrice" : 3,
"quantity" : 1,
"quantitySelected" : 0.10000000000000001,
"isEditable" : false
}
]
},
"imageStoragePathList" : [
"CORIANDER_LEAVES_BUNCH.png"
],
"bizOfferingsID" : "Vegetables_2",
"masterImage" : 0,
"vegNonVegInfoEnum" : "NONE",
"description" : "",
"itemQunatitySelected" : 0,
"bizOfferingsHeaderTypeThree" : {
"indexOrder" : 0,
"headerText" : "Vegetables",
"isVisible" : true
},
"itemIndex" : 2,
"totalCountQunatity" : 0,
"primaryText" : "Coriander Leaves Bunch"
},
{
"isVisible" : true,
"itemRetailInfo" : {
"units" : "GRAMS",
"quantityPrice" : [
{
"discountPrice" : 0,
"regularPrice" : 8,
"quantity" : 500,
"quantitySelected" : 500,
"isEditable" : false
}
]
},
"imageStoragePathList" : [
"TOMATO_STANDARD.png"
],
"bizOfferingsID" : "Vegetables_3",
"masterImage" : 0,
"vegNonVegInfoEnum" : "NONE",
"description" : "",
"itemQunatitySelected" : 0,
"bizOfferingsHeaderTypeThree" : {
"indexOrder" : 0,
"headerText" : "Vegetables",
"isVisible" : true
},
"itemIndex" : 3,
"totalCountQunatity" : 0,
"primaryText" : "Tomato Standard"
}
]
You need to clarify which type you sort assuming an array
var bizOfferingsJson = try JSON(data: jsonData).array!
bizOfferingsJson = bizOfferingsJson.sorted(by: { $0["itemIndex"] > $1["itemIndex"] })
or using mutating sort
bizOfferingsJson.sort{ $0["itemIndex"] > $1["itemIndex"] }
using Codable is much better given your json
struct Root: Codable {
let isVisible: Bool
let itemRetailInfo: ItemRetailInfo
let imageStoragePathList: [String]
let bizOfferingsID: String
let masterImage: Int
let vegNonVegInfoEnum, purpleDescription: String
let itemQunatitySelected: Int
let bizOfferingsHeaderTypeThree: BizOfferingsHeaderTypeThree
let itemIndex, totalCountQunatity: Int
let primaryText: String
enum CodingKeys: String, CodingKey {
case isVisible, itemRetailInfo, imageStoragePathList, bizOfferingsID, masterImage, vegNonVegInfoEnum
case purpleDescription = "description"
case itemQunatitySelected, bizOfferingsHeaderTypeThree, itemIndex, totalCountQunatity, primaryText
}
}
// MARK: - BizOfferingsHeaderTypeThree
struct BizOfferingsHeaderTypeThree: Codable {
let indexOrder: Int
let headerText: String
let isVisible: Bool
}
// MARK: - ItemRetailInfo
struct ItemRetailInfo: Codable {
let units: String
let quantityPrice: [QuantityPrice]
}
// MARK: - QuantityPrice
struct QuantityPrice: Codable {
let discountPrice, regularPrice, quantity: Int
let quantitySelected: Double
let isEditable: Bool
}
var res = try! JSONDecoder().decode([Root].self, from: jsonData)
res.sort { $0.itemIndex > $1.itemIndex }
Related
I am working on a timeslot system that will give available time slots and unavailable but I am filtering available slots and loading the array. Sometimes many days don't have available timeslots. I wanted to find the next available slots on recently available days through the loop from the "available" Bool Parameter from the response below (I pasted only part of the response.
{
"timeslots" : [
{
"slots" : [
{
"day" : "tuesday",
"selected" : false,
"pk" : 160,
"available" : false,
"timeframe" : "10:00 - 12:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 161,
"available" : true,
"timeframe" : "12:00 - 14:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 162,
"available" : true,
"timeframe" : "15:00 - 17:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 163,
"available" : true,
"timeframe" : "17:00 - 19:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 164,
"available" : false,
"timeframe" : "19:00 - 21:00"
}
],
"day_name" : "tuesday",
"date" : "2022-04-26",
"available" : 3,
"day_abbr" : "26 Apr"
},
{
"slots" : [
{
"pk" : 160,
"day" : "wednesday",
"timeframe" : "10:00 - 12:00",
"selected" : false,
"available" : true
},
{
"pk" : 161,
"day" : "wednesday",
"timeframe" : "12:00 - 14:00",
"selected" : false,
"available" : true
},
{
"pk" : 162,
"day" : "wednesday",
"timeframe" : "15:00 - 17:00",
"selected" : false,
"available" : true
},
{
"pk" : 163,
"day" : "wednesday",
"timeframe" : "17:00 - 19:00",
"selected" : false,
"available" : true
},
{
"pk" : 164,
"day" : "wednesday",
"timeframe" : "19:00 - 21:00",
"selected" : false,
"available" : false
}
],
"day_name" : "wednesday",
"date" : "2022-04-27",
"available" : 4,
"day_abbr" : "27 Apr"
},
I did an iteration like this so far.
switch response.result {
case let .success(value):
let json = JSON(value)
print("Time slot response: \(json)")
self.slots.removeAll()
self.daySlots.removeAll()
self.typeOfSlot = slotType
if let slotArray = json[slotType][self.dayIndex ?? 0]["slots"].array{
if !slotArray.isEmpty || slotArray != [] {
for slotJSON in slotArray {
let slot = Slots.parseSlots(slotJSON: slotJSON)
self.slots.append(slot)
}
self.slots = self.slots.filter({ $0.available ?? false })
//
if self.slots.count != 0{
switch self.typeOfSlot{
case "seasonal_timeslots":
self.seasonalTimeSlotPK = self.slots.first?.pk
print("time slot pk \(self.seasonalTimeSlotPK ?? 0)")
UserDefaults.standard.set(self.seasonalTimeSlotPK, forKey:uds.kSeasonalTimeslotPK)
self.selectedSeasonalTimeRange = self.slots.first?.timeFrame
UserDefaults.standard.set(self.selectedSeasonalTimeRange, forKey:uds.kSeasonalTimeRange)
case "timeslots":
self.timeSlotPK = self.slots.first?.pk
print("time slot pk \(self.timeSlotPK ?? 0)")
UserDefaults.standard.set(self.timeSlotPK ?? 0, forKey:uds.kTimeslotPK)
self.selectedTimeRange = self.slots.first?.timeFrame
UserDefaults.standard.set(self.selectedTimeRange ?? "", forKey:uds.kTimeRange)
default:
break
}
}
// timeframe
}
else {
// self.tableView.setEmptyView(title: "No available slots found for current date!", message: "Please tap on other days for next available slots.")
self.view.makeToast("No Slots Found!", duration: 3.0, position: .bottom)
}
Please give me code example for me to search for available slots and stops until it's found.
instead of using the json raw data,
you could re-structure your code and use specific models to do what you ask. Here is some example test code to show
how to get the slots.
struct Response: Identifiable, Codable {
let id = UUID()
var timeslots: [Timeslot]
}
struct Timeslot: Codable {
let slots: [Slot]
let dayName: String
let date: String
let available: Int
let dayAbbr: String
enum CodingKeys: String, CodingKey {
case slots
case dayName = "day_name"
case date, available
case dayAbbr = "day_abbr"
}
}
struct Slot: Identifiable, Codable {
let id = UUID()
let day: String
let selected: Bool
let pk: Int
let available: Bool
let timeframe: String
}
struct ContentView: View {
var body: some View {
Text("testing")
.onAppear {
let json = """
{
"timeslots" : [
{
"slots" : [
{
"day" : "tuesday",
"selected" : false,
"pk" : 160,
"available" : false,
"timeframe" : "10:00 - 12:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 161,
"available" : true,
"timeframe" : "12:00 - 14:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 162,
"available" : true,
"timeframe" : "15:00 - 17:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 163,
"available" : true,
"timeframe" : "17:00 - 19:00"
},
{
"day" : "tuesday",
"selected" : false,
"pk" : 164,
"available" : false,
"timeframe" : "19:00 - 21:00"
}
],
"day_name" : "tuesday",
"date" : "2022-04-26",
"available" : 3,
"day_abbr" : "26 Apr"
},
{
"slots" : [
{
"pk" : 160,
"day" : "wednesday",
"timeframe" : "10:00 - 12:00",
"selected" : false,
"available" : true
},
{
"pk" : 161,
"day" : "wednesday",
"timeframe" : "12:00 - 14:00",
"selected" : false,
"available" : true
},
{
"pk" : 162,
"day" : "wednesday",
"timeframe" : "15:00 - 17:00",
"selected" : false,
"available" : true
},
{
"pk" : 163,
"day" : "wednesday",
"timeframe" : "17:00 - 19:00",
"selected" : false,
"available" : true
},
{
"pk" : 164,
"day" : "wednesday",
"timeframe" : "19:00 - 21:00",
"selected" : false,
"available" : false
}
],
"day_name" : "wednesday",
"date" : "2022-04-27",
"available" : 4,
"day_abbr" : "27 Apr"
}
]
}
"""
let data = json.data(using: .utf8)!
do {
let response = try JSONDecoder().decode(Response.self, from: data)
// print("\n--> response: \(response) \n")
// here loop over the timeslots
for tmslot in response.timeslots {
// here loop over the slots
for slot in tmslot.slots {
if slot.available {
print("slot available: \(slot.day) \(slot.timeframe)")
}
}
}
} catch {
print("error: \(error)")
}
}
}
}
I'm not really sure what goes om in your code. But you are asking to find the first available slot in your array of slots?
i made some structs to keep track of the data and used Swift 4's Decodable to easier represent the data:
struct Timeslots: Decodable {
let slots: [Slot]
var firstFreeTime: Slot? {
slots.first(where: { $0.available })
}
}
struct Slot: Decodable {
let day: String
let selected: Bool
let pk: Int
let available: Bool
let timeFrame: String
}
I am trying to parse JSON data from a post request and I am struggling with the outcome. I would like to parse the JSON data in the Swift 5 programming language.
I have spent hours trying to figure this out. I am very confused on how to deal with multiple levels of hiarchy like this.
I dont need all the data i just need time and total_amount_sent.
Swift
struct Response: Codable {
var txs: [ResponseData]
enum CodingKeys: String, CodingKey {
case txs
}
}
struct ResponseData: Codable {
var time: String?
var total_amount_sent: String?
var recipient: String?
var txid: String?
var amount: String?
}
let url = URL(string: paramURL)!
let json: [String: Any] = [
"key": "value"
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: json)
let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
do {
let json = try JSONDecoder().decode(Response.self, from: data!)
print(json)
json.txs.forEach { charge in
let transaction_time = charge.time
let transaction_txid = charge.txid
let transaction_total_amount_sent = charge.total_amount_sent
print(transaction_time)
print(transaction_txid)
print(transaction_total_amount_sent)
}
} catch {
print("Error! \(error)")
}
})
task.resume()
Error:
Error! keyNotFound(CodingKeys(stringValue: "txs", intValue: nil),
Swift.DecodingError.Context(codingPath: [], debugDescription: "No
value associated with key CodingKeys(stringValue: "txs", intValue:
nil) ("txs").", underlyingError: nil))
JSON:
{
"status" : "success",
"data" : {
"network" : "DOGETEST",
"txs" : [
{
"txid" : "df4ac3ecfc356d9e10325cd4043a4103602599b71a91ea96cb3fa3204c61264c",
"from_green_address" : false,
"time" : 1620076250,
"confirmations" : 5,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "2.00000000"
}
],
"senders" : [
"2MtSgfBmXzZv6raD7yyuGzFamzBzQD7G6Rf"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
},
{
"txid" : "d983739751a6170d336016ffa1b7d7f2849a4a81cb0021e03a2cc6d76c55379d",
"from_green_address" : false,
"time" : 1620076071,
"confirmations" : 6,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "2.00000000"
}
],
"senders" : [
"2MtSgfBmXzZv6raD7yyuGzFamzBzQD7G6Rf"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
},
{
"txid" : "1dce7dd99f6a655ca82a94c8e088576c78e4ece94995f2f90891b8f5f31a54db",
"from_green_address" : false,
"time" : 1620076021,
"confirmations" : 6,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "8.00000000"
}
],
"senders" : [
"2MtSgfBmXzZv6raD7yyuGzFamzBzQD7G6Rf"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
},
{
"txid" : "27719e8fae3bb64f1ecec8ac64a2135d1ccc5d9219040dceaec9d24e4b17a466",
"from_green_address" : false,
"time" : 1620075780,
"confirmations" : 6,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "4.00000000"
}
],
"senders" : [
"2MtSgfBmXzZv6raD7yyuGzFamzBzQD7G6Rf"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
},
{
"txid" : "2a6547411b15442b78b118981cf5632e3faedec8941aea22453d8837807d37be",
"from_green_address" : false,
"time" : 1620075743,
"confirmations" : 7,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "2.00000000"
}
],
"senders" : [
"2MtSgfBmXzZv6raD7yyuGzFamzBzQD7G6Rf"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
},
{
"txid" : "63a145cbdc48c1e644fa52a30ed26d66c58b685698104a549001d0fe539816ba",
"from_green_address" : false,
"time" : 1620075697,
"confirmations" : 7,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "4.00000000"
}
],
"senders" : [
"2MtSgfBmXzZv6raD7yyuGzFamzBzQD7G6Rf"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
},
{
"txid" : "ff350583e0cb1396a3d5cc09350697daf111626ec5a3b893f8e936276f1c6715",
"from_green_address" : false,
"time" : 1620075677,
"confirmations" : 7,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "2.00000000"
}
],
"senders" : [
"2MtSgfBmXzZv6raD7yyuGzFamzBzQD7G6Rf"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
},
{
"txid" : "5a0115a9f608f3d01caee03587253fc58e0ad0c602f4e95e6c0db1e11703af84",
"from_green_address" : false,
"time" : 1619998414,
"confirmations" : 227,
"amounts_received" : [
{
"recipient" : "2N3ZbAaJqtxD5jfbLDZichV6SSHZ6PBYPmi",
"amount" : "1000.00000000"
}
],
"senders" : [
"2MytwDpHWpdoVYQ7JzYwBPxQ5XsEdiV7udZ"
],
"confidence" : 1.0,
"propagated_by_nodes" : null
}
]
}
}
Your model was not properly structured.
struct Response: Decodable {
var txs: [ResponseData]
enum CodingKeys: CodingKey {
case data
}
enum ValueCodingKeys: CodingKey {
case txs
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let nestedContainer = try container.nestedContainer(keyedBy: ValueCodingKeys.self, forKey: .data)
txs = try nestedContainer.decode([ResponseData].self, forKey: .txs)
}
}
struct ResponseData: Decodable {
var time: Int?
var txid: String?
var amountsReceived: [AmoutReceived]
}
struct AmoutReceived: Decodable {
var recipient: String?
var amount: String?
}
Use .convertFromSnakeCase.
Hope you are handling error cases properly. Here is the code
func fetch(urlString: String, callback: #escaping (Result<Response, Error>) -> Void) {
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else {
if let error = error {
callback(.failure(error))
}
return
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Response.self, from: data)
callback(.success(result))
} catch {
callback(.failure(error))
}
}.resume()
}
You can use tools such as Quicktype.io to create a model from a JSON. This is an example model from your provided JSON. You can play around with this tool, and also there is an option "Renders output in a Swift 5 compatible mode" since you are asking about parsing in Swift 5 programming language.
import Foundation
struct User: Codable {
let status: String
let data: DataClass
}
struct DataClass: Codable {
let network: String
let txs: [Tx]
}
struct Tx: Codable {
let txid: String
let fromGreenAddress: Bool
let time, confirmations: Int
let amountsReceived: [AmountsReceived]
let senders: [String]
let confidence: Int
let propagatedByNodes: JSONNull?
enum CodingKeys: String, CodingKey {
case txid
case fromGreenAddress = "from_green_address"
case time, confirmations
case amountsReceived = "amounts_received"
case senders, confidence
case propagatedByNodes = "propagated_by_nodes"
}
}
struct AmountsReceived: Codable {
let recipient, amount: String
}
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
I watch WWDC session 102 and I try to use JSONDecoder to model,but I have a question,this is my struct
public struct DataListResult:Codable{
let _id : String
let createdAt : String
let desc : String
let images : Array<String>
let publishedAt : String
let source : String
let type : String
let url : String
let used : Int
let who : String
}
public struct DataListModel:Codable{
let results : [DataListResult]
let error: Bool
}
JSON:
{
"results" : [
{
"_id" : "59266a79421aa92c73b6475c",
"images" : [
"http:\/\/img.gank.io\/875a9508-3a1e-4d4b-8b91-c111ea62871a"
],
"source" : "chrome",
"who" : "S",
"publishedAt" : "2017-05-25T13:32:48.92Z",
"used" : true,
"createdAt" : "2017-05-25T13:24:09.35Z",
"type" : "iOS",
"desc" : "iOS ",
"url" : "https:\/\/github.com\/adamzjk\/iOS-ObjectDetection"
},
{
"_id" : "592502d6421aa92c769a8bac",
"images" : [
"http:\/\/img.gank.io\/44e8aa0a-b66f-4a5b-9cb0-74c3ae9fc156"
],
"source" : "chrome",
"who" : "S",
"publishedAt" : "2017-05-24T12:09:25.526Z",
"used" : true,
"createdAt" : "2017-05-24T11:49:42.14Z",
"type" : "iOS",
"desc" : "Whatʼs new in Swift 4",
"url" : "https:\/\/github.com\/ole\/whats-new-in-swift-4"
},
{
"_id" : "5923a438421aa92c73b64743",
"images" : [
"http:\/\/img.gank.io\/25762b53-b2ba-4c1c-9666-1683cd72bb82"
],
"source" : "chrome",
"who" : "who",
"publishedAt" : "2017-05-23T11:14:05.141Z",
"used" : true,
"createdAt" : "2017-05-23T10:53:44.853Z",
"type" : "iOS",
"desc" : "music",
"url" : "https:\/\/github.com\/HarshilShah\/DeckTransition"
}
],
"error" : false
}
The property images can't decoded,because I remove this it can be success,but I don't know how to fix,please tell me, thank you
do
{
let model = try JSONDecoder().decode(DataListModel.self, from: response.data!)
}catch let error as NSError {
print("\(error)") //Error Domain=Swift.DecodingError Code=2 "(null)"
}
--------- last update 2017.6.17 ----------
let images : Array<String> -> let images : Array<String>?
images need opotional property when it empty,thank you for your help
The property used is supposed to be Bool but the structure is decoded correctly with
do {
let decoded = try JSONDecoder().decode(DataListModel.self, from: data)
print(decoded)
} catch {
print(error)
}
assuming data is the JSON Data object.
I have a JSON response that I store as an NSMutableDictionary that looks like this:
{
"list": { "ID1", "ID2", "ID3" },
"items": {
"ID1" : { "name" : "shoe" },
"ID2" : { "name" : "pants" },
"ID3" : { "name" : "hat" }
}
}
i need to have the NSMutableDictionary add entries from any additional JSON responses, so if i receive a new response as follows:
{
"list": { "ID4", "ID5", "ID6" },
"items": {
"ID4" : { "name" : "shirt" },
"ID5" : { "name" : "tie" },
"ID6" : { "name" : "glasses" }
}
}
the updated NSMutableDictionary needs to appear as follows:
{
"list": { "ID1", "ID2", "ID3", "ID4", "ID5", "ID6" },
"items": {
"ID1" : { "name" : "shoe" },
"ID2" : { "name" : "pants" },
"ID3" : { "name" : "hat" },
"ID4" : { "name" : "shirt" },
"ID5" : { "name" : "tie" },
"ID6" : { "name" : "glasses" }
}
}
Unfortunately, when i call addEntriesFromDictionary with the additions, i get this:
{
"list": { "ID1", "ID2", "ID3" },
"items": {
"ID1" : { "name" : "shoe" },
"ID2" : { "name" : "pants" },
"ID3" : { "name" : "hat" }
}
}
"list": { "ID4", "ID5", "ID6" },
"items": {
"ID4" : { "name" : "shirt" },
"ID5" : { "name" : "tie" },
"ID6" : { "name" : "glasses" }
}
}
Assuming we have the same dictionaries as in your example:
let key1 = "list"
let key2 = "items"
var rec = [key1:["ID1","ID2","ID3"],
key2:["ID1":["name":"shoe"],"ID2":["name":"pants"],"ID3":["name":"hat"]]] as [String : Any]
let inc = [key1:["ID4","ID5","ID6"],
key2:["ID4":["name":"shirt"],"ID5":["name":"tie"],"ID6":["name":"glasses"]]] as [String : Any]
I used the following rationale to find a solution:
... implemented this code snippet hereafter:
func merge(_ inc:[String:Any], into rec: inout [String:Any]) -> [String:Any] {
for (_, vals) in inc {
if var recKeys = rec[key1] as? [String],
var recItems = rec[key2] as? [String:[String:String]],
let incItems = inc[key2] as? [String:[String:String]] {
if let incValIds = vals as? [String] {
for id in incValIds {
if let newVal = incItems[id] {
if recKeys.contains(id) {
for (newValId, newValObj) in newVal {
guard var tab = recItems[id] else { continue }
tab[newValId] = newValObj
recItems[id] = tab
}
} else {
recKeys.append(id)
recItems[id] = newVal
}
}
}
}
rec[key1] = recKeys
rec[key2] = recItems
}
}
return rec
}
... and used this function as described hereunder to get the result defined below:
let updatedInfo = merge(inc, into: &rec)
print(updatedInfo)
You can now properly merge the two provided dictionaries as desired.
I'm trying to retrieve all the values that I have in each post (post_text, timestamp, username) to be used in a Table View using Swift. I have tried this code but wasn't sure where to go from here to get each value from posts.
ref.observeEventType(.Value, withBlock: { snapshot in
self.posts = snapshot.value.objectForKey("posts") as! [String: String]
print(self.posts)
self.tableView.reloadData()
})
The JSON Firebase file:
{
"posts" : {
"-KAqlyZ71SNZfZ4Zbs27" : {
"post_text" : "Hello",
"timestamp" : 1455839242909,
"username" : "hello"
},
"-KAqmD6HPbhAVkjT54-k" : {
"post_text" : "Hi",
"timestamp" : 1455839306600,
"username" : "user7"
},
"-KAr9ATmAjObiTsn4yUC" : {
"post_text" : "Hi",
"timestamp" : 1455845587135,
"username" : "user7"
},
"-KArIBlnKSJWGhD9Me6T" : {
"post_text" : "Dddd",
"timestamp" : 1455847983983
}
},
"users" : {
"5476cde6-b343-476d-abb7-8131d3766ba7" : {
"email" : "ad#ad.com",
"posts" : {
"-KAm_8ShLSKrKKMhNjpm" : {
"post_text" : "Hello :)",
"timestamp" : 1455768771004
}
},
"provider" : "password",
"username" : "ad"
},
"b7b7de04-e180-4cac-abd3-57c016640e32" : {
"email" : "user#user.com",
"posts" : {
"-KAqmD6HPbhAVkjT54-l" : {
"post_text" : "Hi",
"timestamp" : 1455839306869
},
"-KAr9ATq-MEkYmAr2SB_" : {
"post_text" : "Hi",
"timestamp" : 1455845587513
},
"-KArIBlxY-FvbsmgF5bI" : {
"post_text" : "Dddd",
"timestamp" : 1455847985342
}
},
"provider" : "password",
"username" : "user7"
},
"fb67da22-e0dd-4ced-873b-53a588d78feb" : {
"email" : "hello#hi.com",
"posts" : {
"-KAqlyZAah6bclwqWi5M" : {
"post_text" : "Hello",
"timestamp" : 1455839243184
}
},
"provider" : "password",
"username" : "hello"
}
}
}
How could I do this?
You can just create an object Post that can be initialized by a Dictionary. Then, just fetch the single key with his value.
var posts : [Post] = []()
json.forEach { (key, dictionary) -> in
let post = Post(
key: key,
dictionary: dictionary
)
posts.append(post)
}