I have an object taken from Parse and I want to save its columns into a Dictionary or something else (if it's better).
I want to have a Dictionary like this: ["name" : "Mike", "lastname" : "vorisis", "id" : "advsas"]
Below is the code I use to take my results:
func queryEvents() {
let query = PFQuery(className: "eventController")
query.limit = 1000
query.includeKey("idEvent")
query.includeKey("eventType")
query.includeKey("idEvent.idMagazi")
query.findObjectsInBackgroundWithBlock { (objects, error)-> Void in
if let objects = objects {
for object in objects {
var post = object["idEvent"] as? PFObject
var post2 = post!["idMagazi"]
print("retrieved related post: \(post2["name"]!)")
}
}
}
}
Something else (if it's better) is a custom class.
Change the type of idMagazi to the real type.
class Event {
let post : PFObject
let name : String
let idMagazi : String
init(object : PFObject) {
self.post = object
self.name = object["name"] as! String
self.idMagazi = object["idMagazi"] as! String
}
}
And use it
...
if let objects = objects as? [PFObject] {
var events = [Event]()
for object in objects {
let post = Event(object: object)
events.append(post)
print("retrieved related post: \(post.name)")
}
}
...
In Swift Dictionary<T,V> is equivalent to [T: V]. Type is inferred if not explicitly declared.
Empty dictionary creation (all equivalent):
var dict1: Dictionary<String, String> = [:]
var dict2: [String: String] = [:]
var dict3 = Dictionary<String, String>()
var dict4 = [String: String]()
Dictionary with values (all equivalent):
var dict5 = ["Foo": "Bar", "Foo1": "Bar1", "Foo2": "Bar2"]
var dict6: Dictionary<String, String> = ["Foo": "Bar", "Foo1": "Bar1", "Foo2": "Bar2"]
var dict7: [String: String] = ["Foo": "Bar", "Foo1": "Bar1", "Foo2": "Bar2"]
Add values to an existing dictionary:
dict["Foo"] = "Bar"
In your specific scenario, you could use this:
let dict = ["name" : name, "lastname" : lastname , "id" : id]
where name, lastname and id are String variables.
Update based on your own answer:
Having this struct:
struct Event {
var nameEvent: String
var nameMagazi: String
}
You can use this approach, that avoid having an external index and uses an array instead of a dictionary for storing the results.
var events: [Event]?
guard let objects = objects else { return }
events = objects.map { object in
let post = object["idEvent"] as? PFObject
let post2 = post!["idMagazi"] as? PFObject
let nameEvent = post!["name"] as! String
let idEvent = post?.objectId
let nameMagazi = post2!["name"] as! String
return Event(nameEvent: nameEvent , nameMagazi: nameMagazi)
}
I finally found it out how can i do it.
I use a struct with what I want like this:
var userDictionary = [Int : Event]()
struct Event {
var nameEvent: String
var nameMagazi: String
}
And then i use this:
if let objects = objects {
for object in objects {
let post = object["idEvent"] as? PFObject
let post2 = post!["idMagazi"] as? PFObject
let nameEvent = post!["name"] as! String
let idEvent = post?.objectId
let nameMagazi = post2!["name"] as! String
self.events[self.i] = Event(nameEvent: nameEvent , nameMagazi: nameMagazi)
self.i += 1
}
print(self.events[1]!.nameEvent)
}
Thank you all for your answers!
Create dictionary like this:
var dict = ["name" : "Mike", "lastname" : "vorisis" , "id" : "advsas"]
OR
var dict = Dictionary<String,String>
dict.setValue("Mike", forKey: "name")
A dictionary can be made using this line:
var dictionaryArray: [Dictionary<String,String,Int>] = []
Then values can be added by appending them to the dictionary.
dictionaryArray.append(["name" : "Mike", "lastname" : "vorisis" , "id" : "advsas"])
Hope this helps.
Related
How to convert json into dictionary for POST api call Swift
info contains an array of object that have User and Address keys You need
let dict1 : [String:Any] = ["ID" : "User123", "Name" : "Virat", "UserID" : 0]
let dict2 : [String:Any] = ["city" : "Delhi", "pin" : 123]
let addressDict : [String:Any] = ["User" : dict1,"Address" : dict2]
let infoDict : [String:Any] = ["info" :[addressDict]]
To better understand look to
// MARK: - Empty
struct Empty: Codable {
let info: [Info]
}
// MARK: - Info
struct Info: Codable {
let user: User
let address: Address
enum CodingKeys: String, CodingKey {
case user = "User"
case address = "Address"
}
}
// MARK: - Address
struct Address: Codable {
let city: String
let pin: Int
}
// MARK: - User
struct User: Codable {
let id, name: String
let userID: Int
enum CodingKeys: String, CodingKey {
case id = "ID"
case name = "Name"
case userID = "UserID"
}
}
You can also use the models above and convert the model to Data with JSONEncodable
The issue is that you're adding user and address as separate dictionaries on the array.
The JSON you posted has an array for info key but its ONE dictionary with two keys.
You need to combine the address and user dicts into one declaration and then wrap that in an array.
For ex:
let dict1 : [String:Any] = ["ID" : "User123", "Name" : "Virat", "UserID" : 0]
let dict2 : [String:Any] = ["city" : "Delhi", "pin" : 123]
let dicts : [String:Any] = ["User": dict1, "Address" : dict2]
let arr = [dicts]
let infoDict : [String:Any] = ["info" : arr]
EDIT: I would agree with SH_Khan that a much better way of doing this would be to create a Codable model
The issue is you are make dictionary per object.
try this code:
let userDict : [String:Any] = ["ID" : "User123", "Name" : "Virat", "UserID" : 0]
let addressDict : [String:Any] = ["city" : "Delhi", "pin" : 123]
let infoDict : [String:Any] = ["info" : ["User": addressDict, "Address": addressDict]]
Try this:
func getDictionaryFromString(_ json: String) -> [String: Any]? {
if let data = json.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
override func viewDidLoad() {
super.viewDidLoad()
let json = """
{"info": [{
"User": {"ID": "user123",
"Name": "Virat",
"UserID": 0
},
"Address": {"city": "Delhi",
"pin": 123
}
}
]
}
"""
if let dict = getDictionaryFromString(json) {
print(dict["info"] as! NSArray)
}
}
//Printed:
> (
> {
> Address = {
> city = Delhi;
> pin = 123;
> };
> User = {
> ID = user123;
> Name = Virat;
> UserID = 0;
> };
> } )
I'm using Json Object to display in tableview.I parsed Json successfully print data also. and I'm using foreach statement to get the data into variable But the problem is I'm getting in variable the last item in json object. I want to display user to name variable to present name on it
here is my Json data
{
"Categories": [
"school, class"
],
"Tags": [
{
"Value": "ashok",
"Key": "Name"
}, {
"Value": "III",
"Key": "class"
}, {
"Value": "A",
"Key": "section"
}
]
}
here is my model array
struct classInfo: Decodable {
let Categories: String
let Tags: String
let Value: String
let Key: String
var Name: String
let class: String
}
here is my code
var ClassList = [classInfo]()
var name: String = ""
var class: String = ""
In JSONSerialization FUNCTION
do{
let json = try JSONSerialization.jsonObject(with: data!, options: []) as! [String: AnyObject]
print(json as AnyObject)
let cat = json["Categories"] as? [String: Any]
print(cat!)
if let array = json["Tags"] as? [[String: Any]] {
for obj in array {
if let dict = obj as? NSDictionary {
// Now reference the data you need using:
let Value = dict.value(forKey: "Value")
let Key = dict.value(forKey: "Key")
print(Value!)
print(Key!)
self.name = tag["Value"] as! String
print(self.name)
self.class = tag["Value"] as! String
print(self.class)
}
}
}
IN CELL FOR ROW FUNCTION
cell.Name.text = "Name:\(name)"
cell.class.text = "class: \(class)"
use this
class ModelClass{ var name:String ; var classs:String }
class ModelDataClass { static var modelData = [ModelClass]() }
in your viewController. - add values in models and
in you cellForRowAt -- >
cell.nameTextLabel.text = ModelDataClass.modelData[indexPath.row].name
cell.classsTextLabel.text = ModelDataClass.modelData[indexPath.row].classs
heyy , try this then ,
class ModelClass {var name:String}
now create a custom tableView cell
class CustomTableViewCell:UITableViewCell {
var dataModel : ModelClass?{
didSet{
guard let model = dataModel else {return}
print(model.name)
// set label text here : ex := myLabel.text = model.name
}
}
// declare all IBLayouts or create them programmatically... its your choice
}
in Your tableView cell (cellForRowAt ---> )
use this snippet
var dataModel = [ModelClass]()
dataModel = [ModelClass(name:"Rishabh"),ModelClass(name:"Adi"),ModelClass(name:"FFFf")]
now pass this dataModel to cellDAtaModel by using
let cell = tableView.deq() as! CustomTableViewCell //deq() - > to lazy to type whole lol ;P type by yourself
cell.dataModel = dataModel[indexPath.row]
My firebase data is as follows:
Matches
items
platinium
standard
-LQTnujHvgKsnW03Qa5s
code: "111"
date: "27/11/2018"
predictions
-0
prediction: "Maç Sonucu 1"
predictionRatio: "2"
startTime: "01:01"
I read this with the following code
databaseHandle = ref.observe(.childAdded, with: { (snapshot) in
if let matchDict = snapshot.value as? Dictionary<String, AnyObject> {
let m_key = snapshot.key
let m = Match(matchKey: m_key, matchData: matchDict)
self.matches.append(m)
}
self.matchesTableView.reloadData()
})
I have two datamodels
1 is match
2 is prediction
I can read code, date and starttime from database but with match object prediction data is not coming it says its nil, How can I get that data with match object?
You can set up the Model class as follows
class ListModel: NSObject {
var UID:String?
var Code:String?
var Date:String?
var PredictionsArr:[PredictionsObj]?
var StartTime:String?
}
class PredictionsObj : NSObject {
var Prediction : String?
var PredictionRatio : String?
}
In your ViewController you can add the below code
var ListArr = [ListModel]()
let ref = Database.database().reference().child("Matches").child(“items”).child(“standard”)
ref.observe(.childAdded, with: { (snapshot) in
print(snapshot)
guard let dictionary = snapshot.value as? [String : AnyObject] else {
return
}
let Obj = ListModel()
Obj.UID = snapshot.key
Obj.Code = dictionary["code"] as? String
Obj.Date = dictionary["date"] as? String
Obj.StartTime = dictionary["startTime"] as? String
let myPredictionsArr = dictionary["predictions"] as? NSArray
var myPredictionsObj = [PredictionsObj]()
if myPredictionsArr != nil{
for dict in myPredictionsArr as! [[String: AnyObject]] {
let detail = PredictionsObj()
detail.Prediction = dict["prediction"] as? String
detail.PredictionRatio = dict["predictionRatio"] as? String
myPredictionsObj.append(detail)
}
}
Obj.PredictionsArr = myPredictionsObj
self.ListArr.append(Obj)
self.ListTV.delegate = self
self.ListTV.dataSource = self
self.ListTV.reloadData()
}, withCancel: nil)
I have created model class for the user as below.
public class SignUpUser {
public var fullName : String?
public var id : Int?
public var city : String?
public var email : String?
public var address : String?
public var lastName : String?
public var countryCode : String?
public var firstName : String?
public var zipCode : Int?
public var contactNumber : Int?
public var sex : String?
public var dob : String?
public var signupType : String?
public var verified : String?
public var emailTokenExpiration : String?
public var updatedAt : String?
public var createdAt : String?
/**
Returns an array of models based on given dictionary.
Sample usage:
let user_list = User.modelsFromDictionaryArray(someDictionaryArrayFromJSON)
- parameter array: NSArray from JSON dictionary.
- returns: Array of User Instances.
*/
public class func modelsFromDictionaryArray(array:NSArray) -> [SignUpUser]
{
var models:[SignUpUser] = []
for item in array
{
models.append(SignUpUser(dictionary: item as! NSDictionary)!)
}
return models
}
/**
Constructs the object based on the given dictionary.
Sample usage:
let user = User(someDictionaryFromJSON)
- parameter dictionary: NSDictionary from JSON.
- returns: User Instance.
*/
init?() {}
required public init?(dictionary: NSDictionary) {
fullName = dictionary["fullName"] as? String
id = dictionary["id"] as? Int
city = dictionary["city"] as? String
email = dictionary["email"] as? String
address = dictionary["address"] as? String
lastName = dictionary["lastName"] as? String
countryCode = dictionary["countryCode"] as? String
firstName = dictionary["firstName"] as? String
zipCode = dictionary["zipCode"] as? Int
contactNumber = dictionary["contactNumber"] as? Int
sex = dictionary["sex"] as? String
dob = dictionary["dob"] as? String
signupType = dictionary["signupType"] as? String
verified = dictionary["verified"] as? String
emailTokenExpiration = dictionary["emailTokenExpiration"] as? String
updatedAt = dictionary["updatedAt"] as? String
createdAt = dictionary["createdAt"] as? String
}
/**
Returns the dictionary representation for the current instance.
- returns: NSDictionary.
*/
public func dictionaryRepresentation() -> NSDictionary {
let dictionary = NSMutableDictionary()
dictionary.setValue(self.fullName, forKey: "fullName")
dictionary.setValue(self.id, forKey: "id")
dictionary.setValue(self.city, forKey: "city")
dictionary.setValue(self.email, forKey: "email")
dictionary.setValue(self.address, forKey: "address")
dictionary.setValue(self.lastName, forKey: "lastName")
dictionary.setValue(self.countryCode, forKey: "countryCode")
dictionary.setValue(self.firstName, forKey: "firstName")
dictionary.setValue(self.zipCode, forKey: "zipCode")
dictionary.setValue(self.contactNumber, forKey: "contactNumber")
dictionary.setValue(self.sex, forKey: "sex")
dictionary.setValue(self.dob, forKey: "dob")
dictionary.setValue(self.signupType, forKey: "signupType")
dictionary.setValue(self.verified, forKey: "verified")
dictionary.setValue(self.emailTokenExpiration, forKey: "emailTokenExpiration")
dictionary.setValue(self.updatedAt, forKey: "updatedAt")
dictionary.setValue(self.createdAt, forKey: "createdAt")
return dictionary
}
}
I am trying to conver the object to JSON with following way but getting error saying "invalid top-level type in json write"
let signUpuser = SignUpUser()
signUpuser?.fullName = "Teswt"
signUpuser?.id = 1
signUpuser?.city = "Test"
signUpuser?.email = "Test"
signUpuser?.address = "Test"
signUpuser?.lastName = "Test"
signUpuser?.countryCode = "Test"
signUpuser?.firstName = "Test"
signUpuser?.zipCode = 380004
signUpuser?.contactNumber = 12345
signUpuser?.sex = "Test"
signUpuser?.dob = "Test"
signUpuser?.signupType = "Test"
signUpuser?.verified = "Test"
signUpuser?.emailTokenExpiration = "Test"
signUpuser?.updatedAt = "Test"
signUpuser?.createdAt = "Test"
if let jsonData = try? JSONSerialization.data(withJSONObject: signUpuser, options: []) {
let theJSONText = String(data: jsonData, encoding: .utf8)
AppLog.debug(tag: TAG, msg: theJSONText!)
}
In Android using Google's gson library we can easily convert JSON to Object and vice versa but in iOS it seems bit difficult.
I also tried to wrap the SignupUser object inside other class object but no luck.
"Wrapping inside other class..."
let wrapperObject = JSONServerRequest(data: signUpuser)
if let jsonData = try? JSONSerialization.data(withJSONObject: wrapperObject, options: []) {
let theJSONText = String(data: jsonData, encoding: .utf8)
AppLog.debug(tag: TAG, msg: theJSONText!)
}
I don't wish to do this with Dictionary as I have to write the keys every time, I prefer to work with objects so If anyone has any clue please kindly guide me.
Add this method in your model class
func toDictionary() -> [String : Any] {
var dictionary = [String:Any]()
let otherSelf = Mirror(reflecting: self)
for child in otherSelf.children {
if let key = child.label {
dictionary[key] = child.value
}
}
print("USER_DICTIONARY :: \(dictionary.description)")
return dictionary
}
This will give the dictionary representation of your model class
so you can access like youclassObj.toDictionary()
and follow as per requirement : Convert Dictionary to JSON in Swift
Hello I am trying to parse through this json file: http://pastebin.com/TCdkJnvZ
Here is the class I made of the information I want to parse out:
public class Recipe: NSObject {
var recipeID : NSNumber?
var categoryName : String?
var ingredients : [Int : Ingredients]?
var nutrition : [Nutrition]?
var imageName : String?
var instructions : [Int : String]?
}
class Ingredients : NSObject {
var id : NSNumber?
var name : String?
var quantity: NSNumber?
var unit : String?
}
class Nutrition : NSObject {
var serving : String?
var calories : NSNumber?
var fat : String?
var carbs : NSNumber?
}
This image is the current issue.. I am really not sure what I am doing wrong here.. so if I can get any help on fixing my logic/issue it would be appreciated.
func parseToJSON(data: Any) {
// add meals to here
var recipes : [Recipe]
// single meals here
var meals : Recipe
do {
if let json = try JSONSerialization.jsonObject(with: data as! Data) as? [String: Any],
meals.recipeID == json["recipeID"] as! NSNumber? ,
meals.imageName == json["ImageURL"] as! String?,
//meals.instructions == meals.parseInstructions(instructions: (json["Instructions"] as! String)),
meals.categoryName == "Meals" ,
let ingredients = json["Ingredients"] as! [[String: Any]]? {
for items in ingredients {
var i : Int = 0
var groceryItems : Ingredients
groceryItems.id = items["IngredientID"] as? NSNumber
groceryItems.name = items["Name"] as? String
groceryItems.quantity = items["Quantity"] as? NSNumber
groceryItems.unit = items["Unit"] as? String
meals.ingredients?[i] = groceryItems
}
};
let nutritionInfo = json["NutritionInfo"] as! [[String: Any]]? {
for items in nutritionInfo {
var nutrition : Nutrition
nutrition.serving = items["SingularYieldUnit"] as? String
nutrition.calories = items["TotalCalories"] as? NSNumber
nutrition.fat = items["TotalFat"] as? String
nutrition.carbs = items["TotalCarbs"] as NSNumber
meals.nutrition = nutrition
}
};
}
catch{
}
}
It looks like you have a variety of syntax errors, but the compiler can only show one issue at a time. I've cleaned up the code slightly for you, which should push you in the right direction. I can't completely fix it because I don't know what your exact intentions are.
Here is the updated parseToJSON function:
func parseToJSON(data: Any) {
let meals = Recipe()
do {
if let json = try JSONSerialization.jsonObject(with: data as! Data) as? [String: Any] {
meals.recipeID == json["recipeID"] as! NSNumber?
meals.imageName == json["ImageURL"] as! String?
//meals.instructions == meals.parseInstructions(instructions: (json["Instructions"] as! String)),
meals.categoryName == "Meals"
if let ingredients = json["Ingredients"] as! [[String: Any]]? {
for items in ingredients {
let groceryItems = Ingredients()
groceryItems.id = items["IngredientID"] as? NSNumber
groceryItems.name = items["Name"] as? String
groceryItems.quantity = items["Quantity"] as? NSNumber
groceryItems.unit = items["Unit"] as? String
meals.ingredients?.append(groceryItems)
}
}
if let nutritionInfo = json["NutritionInfo"] as! [[String: Any]]? {
for items in nutritionInfo {
let nutrition = Nutrition()
nutrition.serving = items["SingularYieldUnit"] as? String
nutrition.calories = items["TotalCalories"] as? NSNumber
nutrition.fat = items["TotalFat"] as? String
nutrition.carbs = items["TotalCarbs"] as? NSNumber
meals.nutrition?.append(nutrition)
}
}
}
}
catch{
}
}
I also changed the Recipe object's ingredients property to:
var ingredients : [Ingredients]?
The main issue was that a lot of your code was inside of an if let expression and your indentation was off so you couldn't as easily tell.