Convert from NSDictionary to [String:Any?] - swift

I am using xmartlabs/Eureka to build an app with a dynamic form.
In order to fill the form I have to use setValues(values: [String: Any?]).
But I have the form values in an NSDictionary variable and I cannot cast it to [String:Any?].
Is there a way to convert an NSDictionary to [String:Any?] ?

Just an example:
if let content = data["data"] as? [String:AnyObject] {
print(content)
}
The data is a JSON object here. Use it accordingly.

Hope this helps:
let dict = NSDictionary()
var anyDict = [String: Any?]()
for (value, key) in dict {
anyDict[key as! String] = value
}

Related

Swift update value inside Dictionary<String, Any> in an Array

I have an array of Dictionaries, like so
var myArray: [Dictionary<String, Any>] = [Dictionary<String, Any>]()
Somewhere in my class i add values there, like so:
var myDict = Dictionary<String, Any>()
myDict["Id"] = "someUniqueId"
myDict["v1"] = -42
self.myArray.append(myDict)
Then later i try to update the v1 inside this dict like so:
self.myArray.first(where: { $0["Id"] == "someUniqueId" })?["v1"] = -56
However, the compiler tells me:
Cannot assign through subscript: function call returns immutable value
Any way i can modify the value in array outside of copying the whole dictionary, removing it from array, and re-inserting?
UPDATE This dictionary is not strongly typed because what is inside the dictionary, both types and fieldnames, are controlled by the user in an external system. E.g. we download some metadata and then render controls for this dynamic data.
This is because Swift Dictionary is a value type.
Use a custom class or you can use NSMutableDictionary for this purpose (because NSDictionary is immutable).
var myArray = [NSMutableDictionary]()
var myDict = NSMutableDictionary()
myDict["Id"] = "someUniqueId"
myDict["v1"] = -42
myArray.append(myDict)
myArray.first(where: { $0["Id"] as? String == "someUniqueId" })?["v1"] = -56
print(myArray)
// [{
// Id = someUniqueId;
// v1 = "-56";
// }]
You can make it easier for yourself by wrapping your dictionary in a simple class
class Config {
private var dict: [String: Any]
init(_ dict: [String: Any]) {
self.dict = dict
}
func valueFor(_ key: String) -> Any? {
return dict[key]
}
func setValue(_ value: Any, forKey key: String) {
dict[key] = value
}
}
and use that in your array
var myArray = [Config]()
And use it like this
array.filter { $0.valueFor("Id") as? String == "someUniqueId" }
.first?.setValue(-56, forKey: "v1")
That way you can avoid using classes like NSMutableDictionary and keeping it more pure Swift. Another advantage with a custom class is that you can add functionality to it to simplify your code using it, so for instance if you will be looking up dictionaries by "Id" a lot we can add a computed property for it
var id: String? {
return valueFor("Id") as? String
}
and then the example above would become
array.filter { $0.id == "someUniqueId" }.first?.setValue(-56, forKey: "v1")

Not able to access data from Userdefaults - Swfit

I am accessing user default value as:
let data = UserDefaults.standard.object(forKey: identifier)
when I see the value in data it is visible as:
https://i.stack.imgur.com/UOjI8.png
type of data is
po type(of: data)
Swift.Optional<Any> . //Output
How can I access pageNumber?
since data is a dictionary in order to have access to pageNumber you need to cast data as a Dictionary
guard let data = UserDefaults.standard.value(forKey: identifier) as? [String: Any] else { //fallback here if you need return }
let pageNumber = data["pageNumber"] as? Int ?? 0
Simply use dictionary(forKey:) method on UserDefaults instance to directly fetch a dictionary from UserDefaults.
The dictionary returned is of type [String:Any]?
if let dict = UserDefaults.standard.dictionary(forKey: identifier) {
let pageNumber = dict["pageNumber"] as? Int
}
Note: pageNumber is of type Int?. Unwrap it to use further.

How to get some data out of an array in swift?

Here is my problem: I have an plist file, which have a simple strut:
root object is an array, and there are 2 sections in the array, each of them are dictionary including 2 pair key-value data:
and I'm going to create a tableView to show the datas, but I can't get the content out of the array :
here is how i declared my dataArray:
var plistArray = [AnyObject]()
can some one help me?
You need to properly cast at each level:
if let innerArray = plistArray[0] as? [AnyObject] {
if let dataDic = innerArray[indexPath.row] as? [String:String] {
if let imageName = dataDic["Pic"] {
cell?.imageView?.image = UIImage(named: imageName)
}
}
}
But why are you using AnyObject when you know what the plist contains? Use proper types. You know it's an array of arrays of dictionaries with String keys and String values.
var plistArray = [[[String:String]]]()
Then all you need is:
if let imageName = plistArray[0][indexPath.row]["Pic"] {
cell?.imageView?.image = UIImage(named: imageName)
}

Convert "Any" array to String in swift 3

Having this code:
let object = json as? [Any] {
if let questionari=object["questionnarie"] as? [Dictionary<String, AnyObject>]{
}
Compiler (of course) says to me that I can't use a String's index while it's [Any]: I can't find the proper why to cast it as String.
You should be casting your json object as so:
if let object = json as? [String:Any] {
...
Try this code-
if let object = json as? [String:Any] {
if let questionari=object["questionnarie"] as? [Dictionary<String, AnyObject>]{
}
you can make componentsJoined string with "," from any array.
like one line code see bellow example:
let yourStringVar = NSArray(array:ANY_ARRAY_NAME).componentsJoined(by: ",")

Using NSURLConnection With Swift

I am using the following code to get data from an API:
typealias JSONdic = [String: AnyObject]
if let json = json as? JSONdic, history = json["history"] as? JSONdic, hour = history["hour"] as? String {
println(hour)
}
However, Xcode tells me that "json" is not a recognized identifier. I believe this can be solved with NSURLConnection, but I have no idea how to use that. Can anyone provide any examples of this protocol in use?
You're declaring a variable by setting it to itself, which doesn't make any sense. In order to use a variable on the right hand side of an assignment, it needs to have already been declared. So let's give json a value outside of the casting statements and it works fine.
typealias JSONdic = [String: AnyObject]
let json: AnyObject = ["greeting": "Hello"]
if let json = json as? JSONdic, history = json["history"] as? JSONdic, hour = history["hour"] as? String {
println(hour)
}