How to retrieve data from each child in Firebase? - ios

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)
}

Related

Swift 5 Json Parse from post Request

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()
}
}

how to json list after converting into json

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 }

swift JSONDecoder is not working

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.

NSMutableDictionary addEntriesFromDictionary not merging dictionaries properly

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.

Parse JSON Swift 3

I have been searching for an answer to this all day and I'm about to break down and cry but can anyone show me or point me in the direction of how I would parse this JSON file so that I could access the first array of 'members' and print out the first name of all of them? All of the info I looked at now doesn't work in Swift 3(!!!).
JSON file:
[
{
"id" : "001",
"firstName" : "Mark",
"lastName" : "Mason",
"role" : "CEO",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"teamName" : "iOS",
"members" : [
{
"id" : "002",
"firstName" : "Olly",
"lastName" : "Berry",
"role" : "iOS Team Lead",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png",
"teamLead" : true
},
{
"id" : "003",
"firstName" : "James",
"lastName" : "Frost",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "004",
"firstName" : "Liam",
"lastName" : "Nichols",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "005",
"firstName" : "Chris",
"lastName" : "Watson",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "006",
"firstName" : "Richard",
"lastName" : "Turton",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "007",
"firstName" : "Matt",
"lastName" : "Colliss",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "008",
"firstName" : "David",
"lastName" : "Gibson",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "009",
"firstName" : "Tom",
"lastName" : "Guy",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "010",
"firstName" : "Rich",
"lastName" : "Hodgkins",
"role" : "iOS Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
}
]
},
{
"teamName" : "Android",
"members" : [{
"id" : "011",
"firstName" : "David",
"lastName" : "Branton",
"role" : "Android Team Lead",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png",
"teamLead" : true
},
{
"id" : "012",
"firstName" : "Dre",
"lastName" : "Pilipczuk",
"role" : "Android Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "013",
"firstName" : "Ray",
"lastName" : "Britton",
"role" : "Android Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "014",
"firstName" : "Charly",
"lastName" : "Murillo",
"role" : "Android Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
}
]
},
{
"teamName" : "Web",
"members" : [{
"id" : "015",
"firstName" : "Ryan",
"lastName" : "French",
"role" : "Web Team Lead",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png",
"teamLead" : true
},
{
"id" : "016",
"firstName" : "James",
"lastName" : "Ward",
"role" : "Web Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "018",
"firstName" : "Adam",
"lastName" : "Smith",
"role" : "Web Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "019",
"firstName" : "Leonard",
"lastName" : "Da Costa",
"role" : "Web Developer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
}
]
},
{
"teamName" : "Design",
"members" : [{
"id" : "020",
"firstName" : "Hannah",
"lastName" : "Tempest",
"role" : "Design Team Lead",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png",
"teamLead" : true
},
{
"id" : "021",
"firstName" : "Ellis",
"lastName" : "Reed",
"role" : "Designer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "022",
"firstName" : "Pete",
"lastName" : "Horsham",
"role" : "Designer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "023",
"firstName" : "Hemel",
"lastName" : "Dave",
"role" : "Designer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
},
{
"id" : "024",
"firstName" : "Hannah",
"lastName" : "Corke",
"role" : "Designer",
"profileImageURL" : "http://developers.mub.lu/resources/profilePlaceholder.png"
}
]
}
]
I keep getting the error 'Type 'Any' has no subscript members' and I just don't know what to do anymore. I parsed the data like this:
let urlString = "url of the json file"
let url = URL(string: urlString)
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
if error != nil {
print(error)
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSMutableArray
} catch let error as NSError {
print(error)
}
}
}).resume()
but then I have no idea how to access the individual arrays and dictionaries.
Thank you!!
Because your array contain items not in same format. The first item contain CEO info, an rest items contain teams info.
You can parse them by check current items is CEO or teams
here's your parse code in Swift3
do {
if let parsedData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [[String: AnyObject]] {
// parse data here
for item in parsedData {
if let ceoFirstName = item["firstName"] as? String { // first item is CEO info. You can get more info like id, lastName, role, profileImageURL here
print("CEO firstName is \(ceoFirstName)")
}
if let teamName = item["teamName"], members = item["members"] as? [[String: AnyObject]] { // rest items are teams
print("all members firstName from team \(teamName):")
for member in members { // loop for all members
if let firstName = member["firstName"] as? String {
print("firstName = \(firstName)")
}
// you can get other member info like id, lastName, role, profileImageURL, teamLead here
}
}
}
}
} catch {
print(exception)
}
result:
CEO firstName is Mark
all members firstName from team iOS:
firstName = Olly
firstName = James
firstName = Liam
firstName = Chris
firstName = Richard
firstName = Matt
firstName = David
firstName = Tom
firstName = Rich
all members firstName from team Android:
firstName = David
firstName = Dre
firstName = Ray
firstName = Charly
all members firstName from team Web:
firstName = Ryan
firstName = James
firstName = Adam
firstName = Leonard
all members firstName from team Design:
firstName = Hannah
firstName = Ellis
firstName = Pete
firstName = Hemel
firstName = Hannah
let urlpath : String = "http://..."
let url = URL(string: urlpath)
var urlrequest = URLRequest(url: url!)
urlrequest.httpMethod = "GET"
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: urlrequest) { (data, response, error) in
do {
guard let getResponseDic = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: AnyObject]
else
{
print("error trying to convert data to JSON")
return
}
// now we have the todo, let's just print it to prove we can access it
print(getResponseDic as NSDictionary)
let dic = getResponseDic as NSDictionary
let msg = dic.object(forKey: "message")
print(dic)
let arrObj = dic.object(forKey: "teacherDetail") as! NSArray
print(arrObj)
// let arr = dic.value(forKey: "TeacherName")as! NSArray
print(((dic.value(forKey: "teacherDetail") as! NSArray).object(at: 0) as! NSDictionary).value(forKey: "TeacherName") as! String)
// the todo object is a dictionary
// so we just access the title using the "title" key
// so check for a title and print it if we have one
// print("The title is: " + todoTitle)
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()

Resources