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")
}
Related
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.
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
}
}
I am currently struggling with obtaining a value from an array inside an array of dictionaries. Basically I want to grab the first "[0]" from an array stored inside an array of dictionaries. This is basically what I have:
var array = [[String:Any]]()
var hobbies:[String] = []
var dict = [String:Any]()
viewDidLoad Code:
dict["Name"] = "Andreas"
hobbies.append("Football", "Programming")
dict["Hobbies"] = hobbies
array.append(dict)
/// - However, I can only display the name, with the following code:
var name = array[0]["Name"] as! String
But I want to be able to display the first value in the array stored with the name, as well. How is this possible?
And yes; I know there's other options for this approach, but these values are coming from Firebase (child paths) - but I just need to find a way to display the array inside the array of dictionaries.
Thanks in advance.
If you know "Hobbies" is a valid key and its dictionary value is an array of String, then you can directly access the first item in that array with:
let hobby = (array[0]["Hobbies"] as! [String])[0]
but this will crash if "Hobbies" isn't a valid key or if the value isn't [String].
A safer way to access the array would be:
if let hobbies = array[0]["Hobbies"] as? [String] {
print(hobbies[0])
}
If you use a model class/struct things get easier
Given this model struct
struct Person {
let name: String
var hobbies: [String]
}
And this dictionary
var persons = [String:Person]()
This is how you put a person into the dictionary
let andreas = Person(name: "Andreas", hobbies: ["Football", "Programming"])
persons[andreas.name] = Andreas
And this is how you do retrieve it
let aPerson = persons["Andreas"]
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?
i'm updating my app to Swift 2.. lots of errors uff.. anyway i'm trying to read a store array in NSuserDefaults, in swift 1 worked but now i get nil error with EXC_Breakdown. i don't know how to fix that...
this is how i read it:
var DescriptionArray = save.objectForKey("NewsDescriptions")! as! NSArray
this i how i save it (Description is the array):
var SaveDescription = save.setObject(Description, forKey: "NewsDescriptions")
save.synchronize()
Here is an example of how you can store data into NSUserDefault in Swift 2.0. It is very similar to Objective-C concept, only different syntax.
Initialize your NSUserDefault Variable:
let userDefaults = NSUserDefaults.standardUserDefaults()
Initialize what type of data to save: In your case you used objectForKey, even though that should work, it's better to be more specific about your code.
var DescriptionArray = userDefaults.arrayForKey("NewsDescriptions")
Save your data:
userDefaults.setObject(Description, forKey: "NewsDescriptions")
Then you can synchronize to process the saving faster.
userDefaults.synchronize()
Here is an example with Swift 2:
func saveArray(value: NSArray) {
NSUserDefaults.standardUserDefaults().setObject(value, forKey:"NewsDescriptions")
NSUserDefaults.standardUserDefaults().synchronize()
}
func readArray() -> NSArray {
return NSUserDefaults.standardUserDefaults().arrayForKey("NewsDescriptions")!
}