Convert JSON output to an array with SwiftyJSON - json

I have this subJSON["guestpics"] as JSON data from SwiftyJSON.
When I print(subJSON["guestpics"]) I have this:
[
"/images\/profile_pic\/1.jpg",
"/images\/profile_pic\/2.jpg",
"/images\/profile_pic\/3.jpg"
]
How can I convert this to an array ?
for (_, subJSON): (String, JSON) in json[0]["data"] {
print(subJSON["guestpics"])
}

SwiftyJSON has already parsed your JSON data and prepared typed objects.
If the key subJSON["guestpics"] contains an array, then use SwiftyJSON's optional getter .array to get it:
if let guestPicsArray = subJSON["guestpics"].array {
// here "guestPicsArray" is your array
}

Why not directly storing the value of the key in the array? as it look like array
Does it show any error/crash when you are trying to store ?
if let arrGuest = subJSON["guestpics"] as? Array<String> {
}
Or if you are more familiar with Objective-c
if let arrGuest = arr as? NSArray {
}
you can get the array in the arrGuest object

Related

SWIFT: Iterate through a JSON object that's convert to a dictionary

NOTE: Somewhat similar questions have been already asked. And yet none of them provides how to solve this seemingly simple task. So I hope it gets resolved here once and for all.
MY PROBLEM:
I am receiving this nested JSON object:
print("type(of: JSON) \( type(of: JSON))") //__NSDictionaryI
completion(true, nil, JSON as? [String: Any], nil)
Alamofire module converts it, as you see, to a Dictionary.
I have been trying for hours on end to access the nested values with different methods (Something, I thought that should be straightforward compared to JavaScript), inside this Dictionary but I couldn't find a single way that works.
So except for the high-level values, I couldn't access anything else:
for (key,movieData) in moviesData! { // moviesData is the JSON dictionary object
// Do some logic
}
So is there anyway to easily manipulate/access the received JSON data?
This is a far from being an ideal solution but it works. So here it is:
for (key,movieData) in moviesData! {
if let nestedDictionary = moviesData![key] as? [String: Any] {
print("nestedDictionary: ",nestedDictionary) // logs the result part of the JSON object
// Trying to access nested values
for (key,value) in nestedDictionary {
print("nestedDictionary.key: ",key)
print("nestedDictionary.type(of:value): ",type(of:value) )
print("nestedDictionary.value: ",value)
// Testing if sections is an array of dictionaries
if let arrayOfDictionaries = nestedDictionary[key] as? [[String: Any]] {
print("nestedDictionary: ",nestedDictionary) // logs the result part of the JSON object
// Trying to access array items which are sections
for item in arrayOfDictionaries {
print("arrayOfDictionaries.item: ",item)
}
}
}
}
}
It is based on the tip mentioned here:
if let dictionary = jsonWithObjectRoot as? [String: Any] {
if let number = dictionary["someKey"] as? Double {
// access individual value in dictionary
}
for (key, value) in dictionary {
// access all key / value pairs in dictionary
}
if let nestedDictionary = dictionary["anotherKey"] as? [String: Any] {
// access nested dictionary values by key
}
}
The key idea is to check if there's a nested dictionary or a nested array inside the json and then iterate accordingly.

How to parse JSON data and eliminate duplicates in Swift?

I have a very large JSON file that I have downloaded from the web, and I need to parse this in Swift. The JSON construction is an array of dictionaries. Each dictionary object contains a key of "phone" (referring to the phone number), and whose value is the actual phone number in the form of a string.
What I would like to do, is iterate through the entire list of dictionary objects in the array, and ensure that there are no dictionary objects that have the same value for the key, "phone". If a duplicate is found, I would like to eliminate it from the list, and print it out to the console.
Here is the relevant code that I have:
guard let json = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]] else {
print("error")
return
}
for dict in json! {
//This is where I would do the check
}
How would I accomplish this?
You can do as
var ph = [String]()
var newjson = [[String:String]]()
for dict in json {
if ph.contains(dict["Phone"]!) {
print("duplicate phone \(dict["Phone"]!)")
} else {
ph.append(dict["Phone"]!)
newjson.append(dict)
}
}
print(newjson)
Hare newjson is the new array of dictionary that do not have duplicate phone
Use the array extension method to remove the duplicates from the json object
extension Array where Element: Equatable {
mutating func removeDuplicates() {
var result = [Element]()
for value in self {
if !result.contains(value) {
result.append(value)
}
}
self = result
}
}
Alamofire.request(apiURL, method: .get, parameters:parameters, headers:headers)
.responseJSON { response in
if let result = response.result.value {
let json = JSON(result)
var listArray = json["somekey"].arrayValue
listArray.removeDuplicates()
print(listArray)
}
}

Alamofire in Swift: converting response data in usable JSON dictionary

I would like to handle a JSON string that is returned as data from a HTTP call made using Alamofire.
This question uses SwiftyJSON.
However I wanted to go a little bit "lower level" and understand how to convert the response object into a dictionary.
Reasoning is that it feels that a dictionary may be a simple / easy way to access to the JSON values in the response (rather than having to go through the process of converting the response to a JSON object).
This is under the assumption that JSON objects and dictionaries are the same thing (are they?).
Here is the sample function that I wrote:
func question() -> Void{
let response : DataRequest = Alamofire.request("http://aapiurl", parameters: nil)
// Working with JSON Apple developer guide:
// https://developer.apple.com/swift/blog/?id=37
response.responseJSON { response in
if let JSON = response.result.value
{
print("JSON: \(JSON)") // Works!
let data = JSON as! NSMutableDictionary
// Casting fails
// Could not cast value of type '__NSCFArray' (0x19f952150) to 'NSMutableDictionary' (0x19f9523f8).
print("Data: \(data)")
}
}
}
EDIT:
The JSON object seems to be of type Any and does not have any of the methods that are suggested in the answers below.
I have tried to convert it to a Dictionary and got the error below:
A JSON object IS a Dictionary (or possibly an Array at top level).
Note that you should not be using NSMutableDictionary or NSDictionary (or NSArray or NSMutableArray) in Swift.
Also, JSON objects are not working objects. JSON is a way to move data around. It is not to be used as a data source.
If you want to edit the information you get from JSON then you should construct proper data objects from that JSON and work with them.
If you then need to send JSON from this new data then you take your data objects and convert them back to dictionaries and arrays (i.e. JSON objects) and send that data.
Alamofire has the result value of type Any because it usually would be an array or a dictionary. In Swift you normally shouldn't use NS* classes, but rather native swift types such as Array and Dictionary.
You can (should) use optionals to look into the returned JSON object:
if let array = response.result.value as? [Any] {
print("Got an array with \(array.count) objects")
}
else if let dictionary = response.result.value as? [AnyHashable: Any] {
print("Got a dictionary: \(dictionary)")
}
...
Depending on what you expect from your backend, you can treat each of the cases as a success or a failure.
Alamofire.request(myUrl)
.responseJSON {
response in
if let dict = response.result.value as? [String : Any] {
debugPrint(dict)
wishLists.removeAll() //[[String:Any]]
let lists = dict["wishlists"] as! [String: Any]
debugPrint(lists)
for (key, value) in lists {
var list = value as! [String: Any]
wishLists.append(list)
}
debugPrint(wishLists)
self.tableView.reloadData()
}
}

How to get array from nsdisctionary swift

I have below json object. i am parsing json and storing this as disctionary. now i want to get these array from disctionary but when i am using objectForKey("upcomingAppointments") it given me nothing
{
"upcomingAppointments": [],
"upcomingFollowUps": [],
"followUps": []
}
Try this:
var dictionary = //NSDictionary from somewhere...
if let upcomingAppointments = dictionary["upcomingAppointments"] as? NSArray {
//Process your appointments here.
}
//Same goes for other such json fields.

Swift JSON add new key to existing dictionary

I'm using Alamofire and SwiftyJSON to get and manage data from an API
After making my initial request I end up with nested collection of type JSON
According to SwiftyJSON I can loop through data like so
https://github.com/SwiftyJSON/SwiftyJSON#loop
for (key: String, subJson: JSON) in json {
//Do something you want
}
Again, according to SwiftyJSON I should be able to set new values like so:
https://github.com/SwiftyJSON/SwiftyJSON#setter
json["name"] = JSON("new-name")
I have a nested collection of data and I can dig in as deep as I want, but I'm unable to alter the object and set new key:value pair. How would I got about doing this in Swift?
Here's my code :
for (key: String, stop: JSON) in stops {
var physicalStops = stop["physicalStops"]
for (key: String, physicalStop: JSON) in physicalStops {
println("Prints out \(physicalStop) just fine")
// physicalStop["myNewkey"] = "Somevalue" // DOES NOT WORK (#lvalue is not identical to 'JSON)
// physicalStop["myNewkey"] = JSON("Somevalue") //SAME Story
}
}
Basically I'd like to keep the very same structure of the original JSON object, but add additional key:value on the second level nesting for each sub object.
First, you can use var in for-loop to make value modifiable inside the loop. However, JSON is struct so it behaves as a value type, so in your nested example, you have to reassign also the child JSON to the parent JSON otherwise it just modifies the value inside the loop but not in the original structure
var json: JSON = ["foo": ["amount": 2], "bar": ["amount": 3]]
for (key: String, var item: JSON) in json {
println("\(key) -> \(item)")
item["price"] = 10
json[key] = item
}
println(json)
Below is code that runs fine in Swift 2 playground and does not require Swifty:
var json: [String:AnyObject] = ["foo": ["amount": 2], "bar": ["amount": 3]]
for (key,item) in json {
print("\(key) -> \(item)")
let newItem = ["price": 10]
json[key] = newItem
}
print(json)