Retrieve JSON data in swift - arrays

I can't retrieve and print the jobDate data. what's wrong my code?
let retrievetime = UserDefaults().value(forKey: "retrieve")as? NSDictionary
print(retrievetime!)
if let job = retrievetime!["jobs"] as? [String:Any], let jobTitle = job["jobDate"] as? String {
self.navigationItem.title = jobTitle
print(jobTitle)
}
//self.navigationItem.title = "Test"
print retrieve time! json output:
{
jobs =({
jobDate = "2017-08-31";
jobEndTime = 1504144800;
jobID = 87;
jobTime = 1504137600;
});
message = "Retrieve Sucessfully";
result = success;
}

First of all use use the standard singleton instance and optional bindings to safely get data from UserDefaults – unless you registered the key/value pairs.
Second of all never use value(forKey with UserDefaults and never use NSDictionary in Swift unless the compiler tells you to do.
Finally as mentioned in the comments the value for key jobs – as the plural form implies – is an array, you have to get the first object of the array
if let retrievetime = UserDefaults.standard.object(forKey: "retrieve") as? [String:Any] {
print(retrievetime)
if let jobs = retrievetime["jobs"] as? [[String:Any]],
let job = jobs.first,
let jobTitle = job["jobDate"] as? String {
self.navigationItem.title = jobTitle
print(jobTitle)
}
}

let retrievetime = UserDefaults().value(forKey: "retrieve")as? NSDictionary
print(retrievetime!)
if let job = retrievetime!["jobs"] as? [String:Any], let jobTitle = ((retrievetime!["jobs"] as? [String:Any])[0] as? NSDictionary)["jobDate"] as? String {
self.navigationItem.title = jobTitle
print(jobTitle)
}
//self.navigationItem.title = "Test"

Related

How to append new value in index of the null value in NSArray in swift

I wrote an API which returns the username and amount and at what time the transaction was placed. I got the response from the backend as an array of objects and I stored it as NSArray in client side. And I want to attach that response to labels so I converted that NSArray into String and In Database some fields are empty so the response returns the null values whenever the response returns the null values I am getting this error like "Could not cast the value of NSNUll to NSString". What I thought is replace the null value in that array with string. I tried so much but it always shows the same error how to resolve that problem. This is my code :
let response = JSON as! NSDictionary
//example if there is an id
let deyaPaybalance = response.object(forKey: "Details")
print(deyaPaybalance!)
let Amount1:[Double] = (response.object(forKey: "Amount")) as! [Double]
print("Amount is",Amount1)
for ele:Double in Amount1 {
self.amo += [String(ele)]
}
print("amount is in string",self.amo)
let time = response.object(forKey: "Time") as! NSArray
print("time is", time)
let id = response.object(forKey: "TransactionID")
print("id is",id!)
let name:NSArray = response.object(forKey: "RName") as!NSArray
print("name is",name)
// let len = name.count
for (object) in name.enumerated() {
if let i = name.index(of: "null") {
print("hey it's nnull")
//name.index(of: "null")
}
else {
print("hello")
}
}
print("name",name)
// It is used to get the date from the time tsamp
for element in time {
let ele = element
let formatter = ISO8601DateFormatter()
//print("date is",date1!)
formatter.formatOptions = [.withFullDate,
.withTime,
.withDashSeparatorInDate,
.withColonSeparatorInTime]
self.date2 = formatter.date(from: ele as! String)!
self.anotherFormatter.dateFormat = "MMM dd yyyy, h:mm a" // It is used to to show the date in th form of month year and time
self.anotherFormatter.string(from: self.date2)
let b = self.anotherFormatter.string(from: self.date2)
let final = b.replacingOccurrences(of: ",", with: " ")
let trimmedString = final.trimmingCharacters(in: .whitespaces)
self.dt += [trimmedString] // it is stored the final date and time
print("final tim is",trimmedString)
}
// End of the for loop
print(self.dt)
let contactViewController = self.storyboard?.instantiateViewController(withIdentifier: "TransactionDetails")as! TransactionDetails
contactViewController.method = deyaPaybalance as! [String]
contactViewController.amount = self.amo
contactViewController.timestamp = self.dt
contactViewController.transactionid = id as! [String]
contactViewController.name = name as! [String]// I am getting error here.
self.navigationController?.pushViewController(contactViewController, animated: true)
self.dismiss(animated: false, completion: nil)
UIApplication.shared.endIgnoringInteractionEvents()
You need to use like this to handle null in swift.
if let arr_name = name as? [String]{
contactViewController.name = arr_name
}else{
contactViewController.name = []
}
For replacing nil value in [String]
var name = ["a",nil,"3"]
if let nil_index = name.index(of: nil){
name[nil_index] = "empty"
}
print(name as! [String]) // Output is ["a", "empty", "3"]

firebase swift empty array out of observer

In my viewController I have an array of class Users named arrayUtenti, with the code below I need to add that user to that array but for some reason that i cannot understand I get an empty array, what could happened?
**************EDITED WORKS**************
func vengodaEditPremuto(completionHandler:#escaping ([Users]) -> ()){ self.root.child("users").child("ZJq98gvOEHaLUqYTbp4xF52f2K23").observeSingleEvent(of: .value, with: { (snapshot) in
var TempArray: [Users] = []
guard
let value = snapshot.value as? [String:AnyObject],
let userid = value["id"],
let username = value["name"],
let useremail = value["email"]
else {return}
let utenteesistente = Users(id: userid as? String, name: username as? String, email: useremail as? String)
TempArray.append(utenteesistente)
self.arrayUtenti = TempArray
completionHandler(self.arrayUtenti)
print(self.arrayUtenti) //here is ok
})
print(self.arrayUtenti) //here the array is empty!!
}
Your code looks fine after my comment. This is the last thing you need to do to make a correct call:
vengodaEditPremuto(){ result in
print(result)
}

Swift Array sort with JSON

Data:
tried get data from JSON
has code with Swift run on Playground
var roadWayStatusArray = [AnyObject]()
let url = URL(string: "http://od.moi.gov.tw/data/api/pbs")
let data = try? Data(contentsOf: url!)
let json = try? JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
if let results = json as? [String : AnyObject] {
if let result = results["result"] as? [[String : AnyObject]] {
for data in result {
let happendate = data["happendate"] as? String
roadWayStatusArray.append(data as AnyObject!)
}
}
}
I has tried using roadWayStatusArray.sort(by: >) but Xcode report me Ambiguous reference member '>'
How to create sort by hapendate or happentime
Your roadWayStatusArray is an array of AnyObject. There is no > operator defined for AnyObject.
The objects in roadWayStatusArray are actually dictionaries that look like this:
{
UID = "10602090007-0";
areaNm = "\U4e2d\U5c71\U9ad8\U901f\U516c\U8def-\U570b\U9053\Uff11\U865f";
comment = "\U5317\U4e0a.\U4e2d\U58e2\U670d\U52d9\U5340 \U51fa\U53e3\U531d\U9053\U4e2d \U53f3\U5074 \U5c0f\U5ba2\U8eca\U505c\U653e\Uff0c\U99d5\U99db\U7591\U4f3c\U7761\U8457\U4e86";
direction = "\U5317\U4e0a";
happendate = "2017-02-09";
happentime = "01:08:00.0000000";
modDttm = "2017-02-09 01:15:43.603";
region = N;
road = "";
roadtype = "\U5176\U4ed6";
srcdetail = "\U71b1\U5fc3\U807d\U773e";
x1 = "121.73558";
y1 = "25.12263";
}
You need to call sort(by:) with a closure that determines the sort order. For example, if you want to sort by happendate and then happentime:
roadWayStatusArray.sort(by: { (lhsAny, rhsAny) -> Bool in
let lhs = lhsAny as? [String: AnyObject]
let rhs = lhsAny as? [String: AnyObject]
let lhsKey = (lhs?["happendate"] as? String ?? "", lhs?["happentime"] as? String ?? "")
let rhsKey = (rhs?["happendate"] as? String ?? "", rhs?["happentime"] as? String ?? "")
return lhsKey < rhsKey
})

How to access nested JSON in brackets in Swift?

I have a JSON response which is in brackets and I struggle to access the inner fields e.g. display_name with Swift. How can I do that?
Optional(["result": {
user = {
"display_name" = "Max Test";
email = "test.max#gmail.com";
"fb_id" = 10209982554704497;
roles = (
stu
);
schools = "<null>";
};
}])
The code I used to access the JSON:
self.restApi.getProfileDetails() {responseObject, error in
//parse down the first layer of array
let response = responseObject as? [String:AnyObject]
print("response object when MyDetailsController opened")
print(response)
let result = response!["result"] as? [AnyObject]
print("result object")
print(result)
//parse down the second layer of JSON object
if let result = response!["result"] as? [AnyObject] {
print("result object when MyDetailsController opened")
// work with the content of "result", for example:
if let user = result[0] as? [String:AnyObject]{
print(user)
let displayName = user["display_name"]
print("displayName")
print(displayName)
}
}
It seems that I address the result in the wrong way as it is always nil:
The console output:
result object
nil
In response result is dictionary not array, try to get like this
let result = response!["result"] as? [String:AnyObject]
1-Get the result object from response
2-Get the user object from result object
3-Get the user info as String from user object .
let response = responseObject as? [String: AnyObject]
let result = response!["result"] as? [String: AnyObject]
if let user = result!["user"] as? [String: AnyObject] {
let displayName = user["display_name"] as? String
let email = user["email"] as? String
}

How we can find an element from [AnyObject] type array in swift

I have [AnyObject] array
var updatedPos = [AnyObject]()
I am setting data in that according to my requirement like!
let para:NSMutableDictionary = NSMutableDictionary()
para.setValue(posId, forKey: "id")
para.setValue(posName, forKey: "job")
let jsonData = try! NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions())
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
self.updatedPos.append(jsonString)
Now in my code i have some requirement to remove the object from this array where id getting matched according to requirement Here is the code which i am trying to implement
for var i = 0; i < updatedPos.count; i++
{
let posItem = updatedPos[i]
print("Id=\(posItem)")
let pId = posItem["id"] as? String
print("secRId=\(pId)")
if removeId! == pId!
{
updatedPos.removeAtIndex(i)
}
}
Here print("Id=\(posItem)") give me output asId={"id":"51","job":"Programmer"} but here i am not able to access id from this object. here print("secRId=\(pId)") give me nil
First of all use native Swift collection types.
Second of all use types as specific as possible.
For example your [AnyObject] array can be also declared as an array of dictionaries [[String:AnyObject]]
var updatedPos = [[String:AnyObject]]()
Now create the dictionaries and add them to the array (in your example the dictionary is actually [String:String] but I keep the AnyObject values).
let para1 : [String:AnyObject] = ["id" : "51", "job" : "Programmer"]
let para2 : [String:AnyObject] = ["id" : "12", "job" : "Designer"]
updatedPos.append(para1)
updatedPos.append(para2)
If you want to remove an item by id use the filter function
let removeId = "12"
updatedPos = updatedPos.filter { $0["id"] as? String != removeId }
or alternatively
if let indexToDelete = updatedPos.indexOf{ $0["id"] as? String == removeId} {
updatedPos.removeAtIndex(indexToDelete)
}
The JSON serialization is not needed for the code you provided.
PS: Never write valueForKey: and setValue:forKey: unless you know exactly what it's doing.
After some little bit stuffs I have found the very easy and best solution for my question. And I want to do special thanks to #vadian. Because he teach me new thing here. Hey Thank you very much #vadian
Finally the answer is I had covert posItem in json Format for finding the id from Id={"id":"51","job":"Programmer"} this string
And the way is
let data = posItem.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
if let dict = json as? [String: AnyObject] {
let id = dict["id"]
if removeId! == id! as! String
{
updatedLoc.removeAtIndex(i)
}
}
}
catch {
print(error)
}

Resources