cast dictionary elements of different types - arrays

I am using such code to get JSON from server:
var jsonresult = NSArray()
do {
jsonresult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
}
It helps me to get an array of dictionaries in jsonresult variable.
Then I am looping through array to add all dictionaries to another array.
for i in jsonresult {
print(i)
self.otherArray.append(i as! Dictionary<String, AnyObject>)
}
I am using Dictionary type because there are strings values as well as Double values.
Problem is that after data is inserted I can not use "double" values. I get such error: Could not cast value of type 'NSTaggedPointerString' (0x10c472860) to 'NSNumber'
Yes, I know that I can use (value as! NSString).doubleValue but it would be better to cast NSTaggedPointerString into NSNumber in the begining.
Any ideas how can I do it? Maybe I can cast each element of dictionary while adding them to self.otherArray?

Related

How to store array of dictionaries into class variable?

I have an array of dictionaries that is being read in from a JSON file as seen below. I would like to store that value (jsonResult) into a class variable so that I can use it to populate a tableview. However, I don't quite understand how to store that value.
Here is how I am getting my array of dictionaries (jsonResult):
if let path = Bundle.main.path(forResource: filename, ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as! [String:Any]
self.tableData = jsonResult // WHAT GOES HERE?
} catch {
// handle error
}
}
And this is my class variable that I want to store my array of dictionaries into:
var tableData = [Dictionary<String, String>]()
How can I correctly store jsonResult into tableData? I do not want to use a struct as the structure of the dictionaries can vary.
You state the JSON is an array of dictionary but you are casting the result of JSONSerialization.jsonObject to just a dictionary. Since you seem to be expected an array of dictionary with both string keys and values, cast the result accordingly. But do it safely. Never use ! when working with JSON.
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [[String:String]] {
self.tableData = jsonResult
} else {
// Error - unexpected JSON result
}
This assumes you want the top level of the JSON result. If in fact jsonResult should be a dictionary and that top-level dictionary has a key to the actual array of dictionary you want then you need to fix the code accordingly.

How to save 2d array data permanently using userdefaults.standard

I'm trying to save 2d array data using userdefaults, but i'm getting this error Cannot convert value of type '[[String]]' to expected argument type 'String' here is my code
var tempQuestion2 = [tempQuestion]
if var tempData = UserDefaults.standard.stringArray(forKey: "tempData")
{
tempData.append(tempQuestion2)
tempQuestion2 = tempData
}
UserDefaults.standard.set(tempQuestion2, forKey: "tempData")
tempQuestion is a string array with data like [“9+1=10”, “5+4=9”] and i want tempQuestion2 to be [["9+1=10, "5+4=9"], ["3+4=7", "4+1=5"]] I'm guessing my issue is at UserDefaults.standard.stringArray. My question is different from the link because that question is about dictionary not array of array.
There's no problem saving and loading arrays of arrays to UserDefaults, to save your data use:
UserDefaults.standard.set(tempQuestion2, forKey: "tempData")
To read back (and update) the array of arrays use:
// Assuming tempQuestion is [String]
if var tempData = UserDefaults.standard.array(forKey: "tempData") as? [[String]] {
tempData.append(tempQuestion2)
UserDefaults.standard.set(tempData, forKey: "temp")
}

Swift Can't access Single object array

I am trying to access data from a json file. The problem is that some of the values are NSSingleObjectArrays (Arrays with only item) which I can't turn into strings.
class CarObject {
var pictureURL: String!
var carURL: String!
var carPrice: String!
required init(json: [String: AnyObject]) {
pictureURL = json["galleryURL"] as! String
carURL = json["viewItemURL"] as! String
carPrice = json["currentPrice"] as! String
}
}
I get the following error message:
Could not cast value of type '__NSSingleObjectArrayI' (0x10a2ec548) to 'NSString' (0x109729440).
I tried to access them like this:
"json["galleryURL"][0] as String!"
but I get the following error:
Type 'Any?' has no subscript members
The values look like this:
galleryURL = ("one value");
Do you guys know a way how to access them easily?
Thanks!
Just cast things to the appropriate types first. It sounds like your values are arrays containing a single string, so something like this:
var pictureURL: URL
required init?(json: [String: AnyObject]) {
guard let pictureURLString = (json["galleryURL"] as? [String])?.first,
let pictureURL = URLComponents(string: pictureURLString)?.url else {
return nil
}
self.pictureURL = pictureURL
}
Also, you may want to reconsider the types you're using for your properties. The pictureURL and carURL properties are URLs, so they make more sense typed as URL. The carPrice property is likely numeric, so it makes more sense as a Double.

Swift3 how do I get the value of a specific key in a string?

I've got a server response returning
(
{
agreementId = "token.virtual.4321";
city = AMSTERDAM;
displayCommonName = "bunch-of-alphanumeric";
displaySoftwareVersion = "qb2/ene/2.7.14";
houseNumber = 22;
postalCode = zip;
street = "";
}
)
how do I get the value of agreementId? response['agreementId'] is not working. i've tried some example code with .first but I cannot get it working.
Some extra information, I do a http call to a server with alamofire. I try to parse the json to a constant response:
let response = JSON as! NSDictionary
However that returns a error message
Could not cast value of type '__NSSingleObjectArrayI' (0x1083600) to 'NSDictionary' (0x108386c).
So now parse the json to an array, which seems to be working. The code above is what
let response = JSON as! NSArry
print(response)
spits out.
Now I only need to retrieve the value from the key "agreementId" and I have no clue how to do that.
In swift you need to use Swift's native type Array/[] and Dictionary/[:] instead of NSArray and NSDictionary, if you specify the type like above means more specific then the compiler won't complain. Also use optional wrapping with if let or guard let to prevent crash.
if let array = JSON as? [[String:Any]] {//Swift type array of dictionary
if let dic = array.first {
let agreementId = dic["agreementId"] as? String ?? "N/A"//Set default value instead N/A
print(agreementId)
//access the other key-value same way
}
}
Note: If you having more than one object in your array then you need to simply loop through the array to access each dictionary of array.
if let array = JSON as? [[String:Any]] {//Swift type array of dictionary
for dic in array {
let agreementId = dic["agreementId"] as? String ?? "N/A"//Set default value instead N/A
print(agreementId)
//access the other key-value same way
}
}

PFObject Array Sort

I'm using Parse and I have an array of PFObjects called "scorecardData". Each PFObject has a "score" property that is of type Int. I'm trying to sort my array by "score" but I'm getting the following error: "Binary operator '<' cannot be applied to two 'AnyObject?' operands". I'm not sure what I'm doing wrong here. I also tried down casting the objectForKey("score") as! Int but its not letting me do this. Any suggestions? Thanks in advance.
var scorecardData = [PFObject]()
scorecardData.sortInPlace({$0.objectForKey("score") < $1.objectForKey("score")})
You declared scorecardData variable as Array of PFObject. Why are you trying access PFObject property using objectForKey: reserved? Anyway I am not parse expert. But if you declared your array as [PFObject] you can use:
scorecardData.sortInPlace({$0.score < $1.score})
But this won't work unless you subclass PFObject for a more native object-oriented class structure. If you do that remember also to specify:
var scorecardData = [YOUR_NEW_CLASS]()
I strongly recommend subclassing PFObject to make use of all swift type-safe goodies.
But if you want to keep your data structure you can use:
scorecardData.sortInPlace({($0["score"] as! Int) < ($1["score"] as! Int)})
Keep in mind that it's dangerous, and in future avoid it.
If you want to Sort your array of PFOject... You can do this
extension Array where Element:PFObject {
func sort() -> [PFObject] {
return sort { (first, second) -> Bool in
let firstDate = first.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
let secondDate = second.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
return firstDate.compare(secondDate) == .OrderedAscending
}
}
}
Have you tried doing this?
var query = PFQuery(className:"ScoreCard")
// Sorts the results in ascending order by the score field
query.orderByDescending("score")
query.findObjectsInBackgroundWithBlock {

Resources