Compare the key with array of dictionaries in iOS swift 4 - ios

I am trying to compare the studentId with the array of dictionaries which has multiple studentId's. I need to get the dictionary which matches with the particular StudentID..Can any one please suggest the perfect solution. I am new to swift.
"students" : [
{
"studentId" : "STUDENT123456789",
"middleName" : "Evangeline",
"firstName" : "Dia",
"rollNo" : "1001",
"studentClass" : {
"className" : "Grade 10",
"classId" : "CLASS123456789",
}
}
{
"studentId" : "STUDENT14354678960",
"middleName" : "Joseph",
"firstName" : "Parker",
"rollNo" : "1002",
"studentClass" : {
"className" : "Grade 10",
"classId" : "CLASS15468975467",
}
}
]
I have students array which is an array of dictionaries.Now I have to compare student Id with this existing array containing multiple studentID's. so when it matches with the student ID, I need to get that particular dictionary data.
For example, I have studentId as "STUDENT14354678960" so I need to get the data containing related to this Id..

Use first, it returns the first found object or nil
if let student = students.first(where: {$0["studentId"] as! String == "STUDENT123456789"}) {
print(student["firstName"])
} else {
print("not found")
}
It's highly recommended to use a custom struct or class for the student data for example
let jsonString = """
{"students" : [
{"studentId" : "STUDENT123456789", "middleName" : "Evangeline", "firstName" : "Dia", "rollNo" : "1001", "studentClass" : { "className" : "Grade 10", "classId" : "CLASS123456789"}},
{"studentId" : "STUDENT14354678960", "middleName" : "Joseph", "firstName" : "Parker", "rollNo" : "1002", "studentClass" : {"className" : "Grade 10", "classId" : "CLASS15468975467"}}
]}
"""
struct Root : Decodable {
let students : [Student]
}
struct Student : Decodable {
let studentId, middleName, firstName, rollNo : String
let studentClass : StudentClass
}
struct StudentClass : Decodable {
let className, classId : String
}
let data = Data(jsonString.utf8)
do {
let result = try JSONDecoder().decode(Root.self, from: data)
let students = result.students
if let student = students.first(where: {$0.studentId == "STUDENT123456789" }) {
print(student)
}
} catch {
print(error)
}

You can use where with a closure:
let search = students.first { (element) -> Bool in
if let dict = element as? [String:Any] {
return dict["studentId"] == yourID
}
}

Related

store dictionary into userdefault as single array - Alamofire - SwiftyJSon

{
"message" : "success ",
"status" : "1",
"Result" : {
"name" : "abc",
"lastname" : null,
"middlename" : null,
"id" : 20431
}
}
i want to store result object into single userdefaults using model and how to retrieve it
From the docs here. Have you tried like this:
//convert the JSON to a raw String
if let rawString = json.rawString() {
userDefaults.set(rawString, forKey: "jsonData")
} else {
print("json.rawString is nil")
}
First create a model for this, using Codable protocol
struct MyJSON : Codable {
let message : String?
let status : String?
let result : JSONResult? // Don't use Result, a keyword in swift
}
struct JSONResult : Codable {
let name : String?
let lastname : String?
let middlename : String?
let id : Int?
}
Then Use the protocol to map the JSON, save the model in UserDefaults.
let jsonString =
"""
{
"message" : "success ",
"status" : "1",
"result" : {
"name" : "abc",
"lastname" : null,
"middlename" : null,
"id" : 20431
}
}
"""
let jsonData = Data(jsonString.utf8)
let data = try JSONDecoder().decode(MyJSON.self, from: jsonData)
// save model in userDefaults
func saveModel() {
if let encoded = try? JSONEncoder().encode(data) {
UserDefaults.standard.set(encoded, forKey: "MySavedValue")
}
}
//get the model
func getModel() -> MyJSON? {
guard let data = UserDefaults.standard.object(forKey: "MySavedValue") as? Data else {
return nil
}
return try? JSONDecoder().decode(MyJSON.self, from: data)
}
how to use
saveModel()
print(getModel()?.message) // print("Success")

How to parse Json response in Swift

I need to parse out "choices" and save 123347 and save "option" to a string from the following String:
{
"type" : "radiobuttons",
"patient" : false,
"text" : "How are you today",
"id" : 63339,
"position" : 2,
"options" : "123344:ok today;123345:see you tomorrow;123346:call friend;123347:call lisa;",
"required" : true,
"choices" : {
"123347" : {
"value" : 3,
"option" : "iOS"
},
"123345" : {
"option" : "Android",
"value" : 1
},
"123346" : {
"option" : "Windows",
"value" : 2
},
"123344" : {
"option" : "MAC",
"value" : 0
}
}
}
let json = try? JSONSerialization.jsonObject(with: str, options: [])
Swift 5
Try to serialize and decode it
let jsonResponse = try JSONSerialization.data(withJSONObject: responseObject as Any, options: JSONSerialization.WritingOptions.sortedKeys)
let customObject = try JSONDecoder().decode(CustomObject.self, from: jsonResponse)
guard let requiredChoice = customObject.choices["123347"] else{
return
}
let option = requiredChoice.option
print(option)
CustomObject for your json:
struct CustomObject: Codable {
let type: String
let patient: Bool
let text: String
let id, position: Int
let options: String
let customObjectRequired: Bool
let choices: [String: Choice]
enum CodingKeys: String, CodingKey {
case type, patient, text, id, position, options
case customObjectRequired = "required"
case choices
}
}
struct Choice: Codable {
let option: String
let value: Int
}
There are many tools available to easily create struct/class for your json:
E.g: https://app.quicktype.io

JSON to Multidimensional Array

I'm trying to take my JSON from a HTTP POST and put it in a multidimensional array to use for sections / table cells in Swift.
I would like each table section to use these dynamic keys (submitid) and insert the cell data for each:
15302992338145
15301374235890
15302930963080
My JSON:
let swiftyJsonVar = JSON(data!)
{
"data" : {
"15302992338145" : [
{
"date" : "2018-06-27",
"username" : "user1",
"submitid" : 15302992338145,
"notes" : "Testing"
},
{
"date" : "2018-06-28",
"username" : "user1",
"submitid" : 15302992338145,
"notes" : "Testing"
}
],
"15301374235890" : [
{
"date" : "2018-06-21",
"username" : "user2",
"submitid" : 15301374235890,
"notes" : "Comments one two three"
},
{
"date" : "2018-06-22",
"username" : "user2",
"submitid" : 15301374235890,
"notes" : "N/A"
}
],
"15302930963080" : [
{
"date" : "2018-07-03",
"username" : "user3",
"submitid" : 15302930963080,
"notes" : "Hello"
}
]
}
}
I've tried but with no luck:
if let resData = swiftyJsonVar["data"][].arrayObject {
self.arrRes = resData as! [String: [[String:AnyObject]]]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return arrRes.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath)
// Configure the cell...
var dict = arrRes[indexPath.section][indexPath.row]
cell.dateLabel?.text = dict["date"]
return cell
}
You should stop using SwiftyJSON and move up to Swift 4 and Decodable:
struct User : Decodable {
let date : String
let username : String
let submitid : Int
let notes : String
}
struct Result : Decodable {
let data : [[User]]
struct AnyCodingKey : CodingKey {
var stringValue: String
var intValue: Int?
init(_ codingKey: CodingKey) {
self.stringValue = codingKey.stringValue
self.intValue = codingKey.intValue
}
init(stringValue: String) {
self.stringValue = stringValue
self.intValue = nil
}
init(intValue: Int) {
self.stringValue = String(intValue)
self.intValue = intValue
}
}
init(from decoder: Decoder) throws {
let con = try! decoder.container(keyedBy: AnyCodingKey.self)
let intermediate = try! con.decode([String:[User]].self,
forKey: AnyCodingKey(stringValue:"data"))
var data = [[User]]()
for d in intermediate {
data.append(d.value)
}
self.data = data
}
}
// jsondata is your original JSON data, as you downloaded it
let result = try! JSONDecoder().decode(Result.self, from: jsondata)
After that, result.data is an array of array of User.
[[User(date: "2018-07-03", username: "user3",
submitid: 15302930963080, notes: "Hello")],
[User(date: "2018-06-27", username: "user1",
submitid: 15302992338145, notes: "Testing"),
User(date: "2018-06-28", username: "user1",
submitid: 15302992338145, notes: "Testing")],
[User(date: "2018-06-21", username: "user2",
submitid: 15301374235890, notes: "Comments one two three"),
User(date: "2018-06-22", username: "user2",
submitid: 15301374235890, notes: "N/A")]]

How to create a function to show reviews in a view of my application (Swift-JSON)

I'm following https://developers.google.com/places/web-service/details this doc to add all the information about a place, and for example to add "geometry"
"geometry" : {
"location" : {
"lat" : -33.866651,
"lng" : 151.195827
},
i created this function in my class that work well
private let geometryKey = "geometry"
private let locationKey = "location"
private let latitudeKey = "lat"
private let longitudeKey = "lng"
class EClass: NSObject {
var location: CLLocationCoordinate2D?
init(placeInfo:[String: Any]) {
placeId = placeInfo["place_id"] as! String
// coordinates
if let g = placeInfo[geometryKey] as? [String:Any] {
if let l = g[locationKey] as? [String:Double] {
if let lat = l[latitudeKey], let lng = l[longitudeKey] {
location = CLLocationCoordinate2D.init(latitude: lat, longitude: lng)
}
}
}
}
but but i'm having difficulty adding "reviews"
"reviews" : [
{
"author_name" : "Robert Ardill",
"author_url" : "https://www.google.com/maps/contrib/106422854611155436041/reviews",
"language" : "en",
"profile_photo_url" : "https://lh3.googleusercontent.com/-T47KxWuAoJU/AAAAAAAAAAI/AAAAAAAAAZo/BDmyI12BZAs/s128-c0x00000000-cc-rp-mo-ba1/photo.jpg",
"rating" : 5,
"relative_time_description" : "a month ago",
"text" : "Awesome offices. Great facilities, location and views. Staff are great hosts",
"time" : 1491144016
}
],
i tried to follow the same concept of the function i created for geometry like this
if let t = place.details?["reviews"] as? [String:Any] {
if let n = t["author_name"], let m = t["text"] {
Mylabel.text = "\(t)"
}
but is not working, i also tried to add a breakpoint and only the first line enters. What can i do? How can i create a build to show the review with a label or anything i need?
Take advantage of Codable in Swift 4. You can simply convert your JSON into a specific struct. e.g. Based on your JSON:
let json = """
{
"reviews" : [
{
"author_name" : "Robert Ardill",
"author_url" : "https://www.google.com/maps/contrib/106422854611155436041/reviews",
"language" : "en",
"profile_photo_url" : "https://lh3.googleusercontent.com/-T47KxWuAoJU/AAAAAAAAAAI/AAAAAAAAAZo/BDmyI12BZAs/s128-c0x00000000-cc-rp-mo-ba1/photo.jpg",
"rating" : 5,
"relative_time_description" : "a month ago",
"text" : "Awesome offices. Great facilities, location and views. Staff are great hosts",
"time" : 1491144016
}
]
}
"""
You can convert it into a Response struct using the following code:
struct Response: Codable {
struct Review: Codable, CustomStringConvertible {
let text: String
let authorName: String
var description: String {
return "Review text: \(text) authorName: \(authorName)"
}
enum CodingKeys: String, CodingKey {
case text
case authorName = "author_name"
}
}
let reviews: [Review]
}
do {
if let data = json.data(using: .utf8) {
let decoder = JSONDecoder()
let decoded = try decoder.decode(Response.self, from: data)
print(decoded.reviews)
} else {
print("data is not available")
}
} catch (let e) {
print(e)
}
In your code t is not a Dictionary it is an Array instead. So try doing something like this. Rest of that you can change as per your logic.
if let t = place.details?["reviews"] as? [String:Any] {
for dic in t {
if let n = dic["author_name"], let m = dic["text"] {
Mylabel.text = "\(t)"
}
}
}
Yeah, but You can also try to make it like that:
struct reviews: Codable{
var reviews: [review]?
}
struct review: Codable{
var author_name: String?
var author_url: String?
var language: String?
var profile_photo_url: String?
var rating: Int?
var relative_time_description: String?
var text: String?
var time: Int?
}
And then:
if let dict = place.details?["reviews"] as? [String: Any],
let dataToDecode = dict.data(using: .utf8){
do{
let decodedReviews = try JSONDecoder().decode(reviews.self, from: dataToDecode)
// here you have decoded reviews in array
}catch let err{
print(err)
}
}

Retrieve values from a path with several unknown childs with Firebase and Swift

Here is my database:
"asks" : {
"US" : {
"Los Angeles" : {
"task1" : {
"ID1" : {
"address" : "example1",
"date" : "28-02-2017",
"price" : "222",
"user" : "userID1",
}
}
"task2" : {
"ID2" : {
"address" : "example2",
"date" : "28-02-2017",
"price" : "252",
"user" : "userID2",
}
}
}
}
}
I want to retrieve all numbers and append them into an array asksList. But the childs task and ID has unknown name. I'm using a class to append data in an array.
Here is my code:
refHande = ref.child("asks").child("FR").child("Île-de-France").observe(.childAdded, with: { (snapshot) in
if let dict = snapshot.value as? [String : AnyObject] {
print(dict)
let ask = asksArround()
ask.setValuesForKeys(dict)
self.asksList.append(ask)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}})
Here is my askAround class:
class asksArround: NSObject {
var name: String?
var email: String?
var tel: String?
var address: String?
}
This code "bypass" the task child whose the name is unknown. May be I should do this with the dict I retrieved, but how?

Resources