Swift 4 - SwiftyJson compare array and merge found values - ios

I have a JSON object which contains a list of names and values. I want to compare to it another array [String] and if the value is found in one of the JSON object value merge that value to a new object.
I have tried using merge(with) in a for loop however, it seems to be merge just one value.
> example:
>
> json_cat =
>
> {
> name: "aaa",
> surname: "aaa-1",
> grade: "aaa-2"
> },
> {
> name: "bbb",
> surname: "bbb-1",
> grade: "bbb-2"
> },
> {
> name: "ccc",
> surname: "ccc-1",
> grade: "ccc-2"
> }
>
//
> let arraytest:[String] = ["aaa", "ccc", "ddd"]
>
// array json_cat compare arraytest
> result = {
> name: "aaa",
> surname: "aaa-1",
> grade: "aaa-2"
> },
> {
> name: "ccc",
> surname: "ccc-1",
> grade: "ccc-2"
> }
let json_cat: JSON = "json from url"
let arraytest:[String] = ["aaa", "ccc", "ddd"]
var json_cat_array = JSON()
json_cat.forEach({ (index, json_p) in
if arraytest.contains(json_p["name"].string!) {
//print("\(index) - \(json_p)")
try! json_cat_array.merge(with: json_p)
}
})

You could implement your loop like this:
json_cat.forEach({ (index, json_p) in
if arraytest.contains(json_p["name"].string!) {
//print("\(index) - \(json_p)")
json_cat_array[json_p["name"].string!] = json_p
}
})
The merge function is really for merging data. Like in this example:
let original: JSON = [
"first_name": "John",
"age": 20,
"skills": ["Coding", "Reading"],
"address": [
"street": "Front St",
"zip": "12345",
]
]
let update: JSON = [
"last_name": "Doe",
"age": 21,
"skills": ["Writing"],
"address": [
"zip": "12342",
"city": "New York City"
]
]
let updated = original.merge(with: update)
// [
// "first_name": "John",
// "last_name": "Doe",
// "age": 21,
// "skills": ["Coding", "Reading", "Writing"],
// "address": [
// "street": "Front St",
// "zip": "12342",
// "city": "New York City"
// ]
// ]

This code uses Swift 4 foundation JSON parser. Swift 4 has got wonder parser by default.
import Foundation
let jsonString = """
[{
"surname": "Roxxy",
"grade": "neaou"
},
{
"name": "Puffi",
"surname": "Chips",
"grade": "meaou"
},
{
"name": "Taffy",
"surname": "Baby",
"grade": "mew-mew"
}]
"""
struct JsonCat: Decodable {
let name: String?
let surname: String
let grade: String
}
struct Cat {
let name: String
let surname: String
let grade: String
}
guard let jsonData = jsonString.data(using: .utf8), let jsonCats = try? JSONDecoder().decode([JsonCat].self, from: jsonData) else {
fatalError()
}
var cats: [Cat] = []
jsonCats.forEach { jsonCat in
guard let name = jsonCat.name else {
return
}
let cat = Cat(name: name, surname: jsonCat.surname, grade: jsonCat.grade)
cats.append(cat)
}
print(cats)

Related

Parse valid objects from JSON array in Swift

I have a codable struct like this
struct User: Codable {
let id: String
let registrationId: String
let firstName: String?
let lastName: String?
}
Now, the response from the server contains an array like this
[
{
"id": "1",
"registrationId": "r1",
"firstName": "Jon",
"lastName": "Doe"
},
{
"id": "2",
"registrationId": null,
"firstName": null,
"lastName": null
},
{
"id": "3",
"registrationId": null,
"firstName": null,
"lastName": null
},
{
"id": "4",
"registrationId": "r4",
"firstName": "Jon",
"lastName": "Snow"
}
]
I want to parse this as [User] but only those who have a valid(not null) registrationId. I know how to parse JSON in swift. But the problem here is because of the two invalid data in the middle the whole response will run into decoding error. But I want to parse it as an array of [User] containing valid ones(in this case first and last object).
Any hints or help is much appreciated.
1- Make registrationId an optional
let registrationId: String?
2-
let res = try JSONDecoder().decode([User].self,from:data)
let filtered = res.filter { $0.registrationId != nil }
after all, this data must come from a database or an array. By making the id parameter as the primary key, the registrationId parameter as a foreign key, and if you are working on the registrationId parameter, you can make a productive sequence or if it is on the array, you can link the method that generates the sequence for that registrationId.
Now I know how to achieve this.
struct User: Codable {
let id: String
let registrationId: String
let firstName: String?
let lastName: String?
}
struct WrappedDecodableArray<Element: Decodable>: Decodable {
let elements: [Element]
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var elements = [Element]()
while !container.isAtEnd {
if let element = try? container.decode(Element.self) {
elements.append(element)
} else {
// move the container currentIndex forward
_ = try container.decode(Block.self)
}
}
self.elements = elements
}
private struct Block: Decodable {}
}
func testUserParsing() {
let jsonStr = """
[
{
"id": "1",
"registrationId": "r1",
"firstName": "Jon",
"lastName": "Doe"
},
{
"id": "2",
"registrationId": null,
"firstName": null,
"lastName": null
},
{
"id": "3",
"registrationId": null,
"firstName": null,
"lastName": null
},
{
"id": "4",
"registrationId": "r4",
"firstName": "Jon",
"lastName": "Snow"
}
]
"""
let jsonData = jsonStr.data(using: .utf8)!
let wrappedArray = try! JSONDecoder().decode(WrappedDecodableArray<User>.self, from: jsonData)
print(wrappedArray.elements)
}
It would have been more elegant if we could override the init(from decoder: Decoder) for Array under certain conditions like extension Array where Element == User. But looks like this is not possible. Initializer inside the extension can not override the original one and hence never get called.
So for now looks like wrapping with a struct is the only solution.

How to get array in ascending order based on key value in Swift3 iOS

I am creating a database App in Swift3, where I have to display the data in UITableView from JSON. Below is my JSON :
{
"Success": 1,
"data": [{
"Session_Details": [{
"Start_Time": "08:00",
"End_Time": "10:00",
"Tag_Details": [{
"Tag_Id": 1,
"Tag_Name": "Test 1",
"Tag_Order": 4
}]
},
{
"Start_Time": "10:30",
"End_Time": "12:30",
"Tag_Details": [{
"Tag_Id": 2,
"Tag_Name": "Test 2",
"Tag_Order": 1
}]
},
{
"Start_Time": "10:30",
"End_Time": "12:30",
"Tag_Details": [{
"Tag_Id": 3,
"Tag_Name": "Test 3",
"Tag_Order": 3
}]
},
{
"Start_Time": "13:30",
"End_Time": "15:20",
"Tag_Details": [{
"Tag_Id": 1,
"Tag_Name": "Test 1",
"Tag_Order": 4
}]
}
]
}]
}
I have already parsed the JSON and getting all the JSON data.
My problem is I have to create an array of 'Tag_Details' that should have unique value, It means Tag_Id should be unique. Also I have to set the array in ascending order based on Tag_Order key.
I am trying below code but not working :
var sessions : [SessionData]! {
return AgendaDataManager.sharedInstance.sessionData
}
let sortedResults = session.tagDetails!.sortedArray(using: [NSSortDescriptor(key: "tagOrder", ascending: true)])
let sessionTag = ((session.tagDetails as AnyObject).allObjects as! [TagData])[0]
Please suggest me. Thank you.
If you are coding in Swift 3 and can't work with Codable protocol
First you should structure your json data. You can use this helper quick type that will give a pretty good start point:
struct Root {
let success: Bool
let data: [Datum]
}
struct Datum {
let sessionDetails: [SessionDetail]
}
struct SessionDetail {
let startTime: String
let endTime: String
let tagDetails: [TagDetail]
}
struct TagDetail {
let tagId: Int
let tagName: String
let tagOrder: Int
}
Them you would need to create a custom initialiser for your root structure that takes a Data parameter (JSON Data):
typealias Dictionary = [String: Any]
typealias Dictionaries = [[String: Any]]
extension Root {
init?(_ data: Data) {
let dictionary = (try? JSONSerialization.jsonObject(with: data)) as? Dictionary ?? [:]
success = dictionary["Success"] as? Bool == true
guard success else {
return nil
}
self.data = (dictionary["data"] as! Dictionaries).map(Datum.init)
}
}
And initialisers that takes a dictionary for all structures.
extension Datum {
init(dictionary: [String: Any]) {
sessionDetails = (dictionary["Session_Details"] as! Dictionaries)
.map(SessionDetail.init)
}
}
extension SessionDetail {
init(dictionary: [String: Any]) {
startTime = dictionary["Start_Time"] as! String
endTime = dictionary["End_Time"] as! String
tagDetails = (dictionary["Tag_Details"] as! Dictionaries).map(TagDetail.init)
}
}
extension TagDetail: CustomStringConvertible {
init(dictionary: [String: Any]) {
tagId = dictionary["Tag_Id"] as! Int
tagName = dictionary["Tag_Name"] as! String
tagOrder = dictionary["Tag_Order"] as! Int
}
var description: String {
return "TagDetail(Id: \(tagId) - Name: \(tagName) - Order: \(tagOrder))"
}
}
Next you will need to make TagDetail conform to Equatable and Comparable:
extension TagDetail: Equatable, Comparable {
static func == (lhs: TagDetail, rhs: TagDetail) -> Bool {
return lhs.tagId == rhs.tagId
}
static func < (lhs: TagDetail, rhs: TagDetail) -> Bool {
return lhs.tagOrder < rhs.tagOrder
}
}
Once you accomplish all these steps you can easily filter and sort your objects:
let data = Data("""
{
"Success": 1,
"data": [{
"Session_Details": [{
"Start_Time": "08:00",
"End_Time": "10:00",
"Tag_Details": [{
"Tag_Id": 1,
"Tag_Name": "Test 1",
"Tag_Order": 4
}]
},
{
"Start_Time": "10:30",
"End_Time": "12:30",
"Tag_Details": [{
"Tag_Id": 2,
"Tag_Name": "Test 2",
"Tag_Order": 1
}]
},
{
"Start_Time": "10:30",
"End_Time": "12:30",
"Tag_Details": [{
"Tag_Id": 3,
"Tag_Name": "Test 3",
"Tag_Order": 3
}]
},
{
"Start_Time": "13:30",
"End_Time": "15:20",
"Tag_Details": [{
"Tag_Id": 1,
"Tag_Name": "Test 1",
"Tag_Order": 4
}]
}
]
}]
}
""".utf8)
if let root = Root(data), root.success,
let sessionDetails = root.data.first?.sessionDetails {
for detail in sessionDetails {
print(detail)
}
let allTagDetails = sessionDetails.flatMap{$0.tagDetails}
let tagDetailsSorted = allTagDetails.sorted()
print("\n\n\n")
var set = Set<Int>()
let tagDetailsSortedSet = tagDetailsSorted.filter({ set.insert($0.tagId).inserted })
tagDetailsSortedSet.map{print($0)}
}
This will print
SessionDetail(startTime: "08:00", endTime: "10:00", tagDetails:
[TagDetail(Id: 1 - Name: Test 1 - Order: 4)])
SessionDetail(startTime:
"10:30", endTime: "12:30", tagDetails: [TagDetail(Id: 2 - Name: Test 2
- Order: 1)])
SessionDetail(startTime: "10:30", endTime: "12:30", tagDetails: [TagDetail(Id: 3 - Name: Test 3 - Order: 3)])
SessionDetail(startTime: "13:30", endTime: "15:20", tagDetails:
[TagDetail(Id: 1 - Name: Test 1 - Order: 4)])
and
TagDetail(Id: 2 - Name: Test 2 - Order: 1)
TagDetail(Id: 3 - Name: Test 3 - Order: 3)
TagDetail(Id: 1 - Name: Test 1 - Order: 4)

Did here existed a better solution to handle this api problem in Swift?

my raw json data maybe mislead you. The keys array were not always matched its value at the same index. So I rewrote my data to reflect my intentions.
Assume we have a table view to show songs with its json:
{
"albums": [
{
"title": "A",
"id": "174172",
"artistName": "Person X"
},
{
"title": "B",
"id": "19201827",
"artistName": "Person Y"
},
{
"title": "C",
"id": "1927",
"artistName": "Person Z"
}
],
"songs": [
{
"name": "Song A",
"albumName": "A",
"albumId": "174172",
"duration": 180
},
{
"name": "Song B",
"albumName": "A",
"albumId": "174172",
"duration": 200
},
{
"name": "Song C",
"albumName": "B",
"albumId": "19201827",
"duration": 216
},
{
"name": "Song D",
"albumName": "C",
"albumId": "1927",
"duration": 216
}
]
}
My schemas like this:
struct Album: Decodable {
let title: String
let id: String
let artistName: String
}
struct Song: Decodable {
let name: String
let albumName: String
let albumId: String
let duration: Int
}
The view controller fake code like this:
class ViewController: UIViewController {
var songs: [Song] = []
var albums: [Album] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return songs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "SongCell", for: indexPath) as! SongCell
let song = songs[indexPath.row]
let album = albums.first { $0.id == song.albumId }
cell.updateUI(withSong: song, album: album)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let song = songs[indexPath.row]
let album = albums.first { $0.id == song.albumId }
pushDetailSongViewController(song, album)
}
func pushDetailSongViewController(_ song: Song, _ album: Album?) {
}
}
When we have too many songs with albums, let album = albums.first { $0.id == song.albumId } is place with terrible performance problem.
So what data structure should we use here to handle updateing performance?
After parsing both keys and values, you could combine the two arrays to a dictionary and then have your table view's data source be that dictionary.
First, make your Song struct conform to the Hashable protocol:
struct Song: Hashable {
Create an array for both albums and songs:
var albums: [Album] = []
var songs: [Song] = []
Then, reduce the songs array to a dictionary as follows:
let data = songs.reduce([Album: Song]()) { (result, song) -> [Album: Song] in
guard let album = albums.first(where: { $0.id == song.albumID }) else { return result }
return result.merging([album: song], uniquingKeysWith: { (first, _) in first })
}
I tested this with two demo arrays:
let albums = [Album(id: "1", name: "one"), Album(id: "2", name: "two"), Album(id: "3", name: "three")]
let songs = [Song(albumID: "1", name: "ONE"), Song(albumID: "2", name: "TWO"), Song(albumID: "3", name: "THREE")]
Those turn data into:
[
<Album id: "1", name: "one"> : <Song albumID: "1", name: "ONE">,
<Album id: "2", name: "two"> : <Song albumID: "2", name: "TWO">,
<Album id: "3", name: "three">: <Song albumID: "3", name: "THREE">
]
Extra Credit
If you want all songs for each album, you have to make data [Album: [Song]]:
let data = albums.reduce([Album: [Song]]()) { (result, album) -> [Album: [Song]] in
let _songs = songs.filter({ $0.albumID == album.id })
guard !_songs.isEmpty else { return result }
return result.merging([album: _songs], uniquingKeysWith: { (first, _) in first })
}
With the following arrays:
let albums = [Album(id: "1", name: "one"), Album(id: "2", name: "two"), Album(id: "3", name: "three")]
let songs = [Song(albumID: "1", name: "ONE"), Song(albumID: "2", name: "TWO"), Song(albumID: "3", name: "THREE"),
Song(albumID: "1", name: "ONE-1"), Song(albumID: "1", name: "ONE-2"), Song(albumID: "3", name: "THREE-1")]
...you will get:
[
<Album name: three, id: 3>: [
<Song name: THREE, albumID: 3>
<Song name: THREE-1, albumID: 3>
],
<Album name: one, id: 1>: [
<Song name: ONE, albumID: 1>,
<Song name: ONE-1, albumID: 1>,
<Song name: ONE-2, albumID: 1>
],
<Album name: two, id: 2>: [
<Song name: TWO, albumID: 2>
]
]
You should create a struct like below after the JSON parsing has been completed.
struct DataSet {
let id: String
let name: String
let value: String
}
Moreover looking at your json, it seems like objects at same index of Key and Value arrays are same with respect to id and key . So, at the time of combining both the arrays, if you iterate one array, you will be knowing the index of another array (O(1)) . Hence time complexity of merging will be O(n).
If you don't want to change too much, maybe a mapDictionary will help:
let keyMaps = [String : String](uniqueKeysWithValues: keys.map{($0.id, $0.name)})
keyNamesInSequenceSameWithValues = values.map{ keyMaps[$0.key]! )

Array of dictionary comparision - swift3

I have 2 array of dictionaries. I want to write a function which compare these 2 arrays.
Function should return true only if main array contains sub array element.
Else it should return false.
Here is my logic-
let mainArry = [ ["id":"1","products":["pid": 1, "name": "A", "price": "$5"]], ["id":"3","products":["pid": 3, "name": "B", "price": "$1"]], ["id":"2","products":["pid": 14, "name": "C", "price": "$15"]]]
let array1 = [ ["id":"1","products":["pid": 1, "name": "A", "price": "$5"]], ["id":"3","products":["pid": 3, "name": "B", "price": "$1"]]]
let array2 = [ ["id":"1","products":["pid": 1, "name": "A", "price": "$5"]], ["id":"3","products":["pid": 4, "name": "B", "price": "$1"]]]
func compareDictionary(mainArry:[[String: Any]], arr2: [[String: Any]])-> Bool{
let itemsId = arr2.map { $0["id"]! } // 1, 3, 14
let filterPredicate = NSPredicate(format: "id IN %#", itemsId)
let filteredArray = mainArry.filter{filterPredicate.evaluate(with:$0) }
if filteredArray.count != arr2.count {
return false
}
for obj in filteredArray {
let prd = obj as Dictionary<String, Any>
let str = prd["id"] as! String
let searchPredicate = NSPredicate(format: "id == %#", str )
let filteredArr = arr2.filter{searchPredicate.evaluate(with:$0) }
if filteredArr.isEmpty {
return false
}
if !NSDictionary(dictionary: obj["products"] as! Dictionary<String, Any>).isEqual(to: filteredArr.last!["products"] as! [String : Any]) {
return false
}
}
return true
}
let result1 = compareDictionary(mainArry: mainArry, arr2: array1)
let result2 = compareDictionary(mainArry: mainArry, arr2: array2)
print("Result1 = \(result1)") // true
print("Result2 = \(result2)") //false
It is working. But I want to know the best way to achieve this.
Instead of using for-loop for comparision.
I want to use filter like this
let arrayC = filteredArray.filter{
let dict = $0
return !arr2.contains{ dict == $0 }
}
if arrayC is empty that means both arrays are equal.
I got it Finally!
We don't need to write big function.
let mainArry = [ ["id":"1","products":["pid": 1, "name": "A", "price": "$5"]], ["id":"3","products":["pid": 3, "name": "B", "price": "$1"]], ["id":"2","products":["pid": 14, "name": "C", "price": "$15"]]]
let array1 = [ ["id":"1","products":["pid": 1, "name": "A", "price": "$5"]], ["id":"3","products":["pid": 3, "name": "B", "price": "$1"]]]
let array2 = [ ["id":"1","products":["pid": 1, "name": "A", "price": "$5"]], ["id":"3","products":["pid": 4, "name": "B", "price": "$1"]]]
let result = array2.filter{
let dict = $0
return !mainArry.contains{
return NSDictionary(dictionary: dict).isEqual(to: $0)
}
}
if result.isEmpty {
print("Same key values")
} else {
print("Diff key values")
}

Use Swifty JSON to parse array

This is my json to parse (example):
[
{
"id": 1,
"name": "Team name",
"shower": {
"id": 1,
"status": 1,
"startLocation": {
"id": 1,
"name": "abc 16"
}
}
},
{
"id": 2,
"name": "Team name",
"shower": {
"id": 2,
"status": 1,
"startLocation": {
"id": 1,
"name": "efg 16"
}
}
}
]
paste it this json viewer to view it easily.
as you can see, it is an array (of teams).
I need to get each team and do something with it.
After many attempts, I tried using SwiftyJSON, because I thought it will be easier. But, it did not worked for me.
This is what I tried:
let array = JSON(response)
// print each subJSON in array
for team in array.arrayValue {
print(team)
}
But the loop does not work. It does not go in to the loop at all.
Maybe it does not understand that my json is an array.
I can see the array object in the debugger. It looks like this:
How can I get these sub-JSONs?
Thanks.
I think you should use
let array = JSON(parseJSON: response)
instead of
let array = JSON(response)
SwiftyJSON contains methods to parse JSON string into a JSON object, check documentation
/**
Parses the JSON string into a JSON object
- parameter json: the JSON string
- returns: the created JSON object
*/
public init(parseJSON jsonString: String) {
if let data = jsonString.data(using: .utf8) {
self.init(data)
} else {
self.init(NSNull())
}
}
/**
Creates a JSON from JSON string
- parameter string: Normal json string like '{"a":"b"}'
- returns: The created JSON
*/
#available(*, deprecated: 3.2, message: "Use instead `init(parseJSON: )`")
public static func parse(json: String) -> JSON {
return json.data(using: String.Encoding.utf8)
.flatMap{ JSON(data: $0) } ?? JSON(NSNull())
}
or alternatively you can convert son string into son object like
Swift 3:
let dataFromString = response.data(using: .utf8)
let jsonArray = JSON(data: dataFromString!)
In the following example, I save team names in an array. I've tested it.
var names = [String]()
if let array = json.array {
for i in 0..<array.count {
let name = array[i]["name"]
names.append(name.stringValue)
}
}
print(names) // ["Team name", "Team name"]
Here is the answer for Swift 5. In My case data response is something like below :
[
{
"Name": "Some Type",
"Data": [
{
"ParentId": 111,
"Code": "Personal",
"SortOrder": 1,
"Name": "Personal",
"Id": 323
},
{
"ParentId": null,
"Code": "Work",
"SortOrder": 2,
"Name": "Work",
"Id": 324
}
],
"KeyType": "Integer"
},
{
"Name": "Phone Type",
"Data": [
{
"ParentId": null,
"Code": "Phone",
"SortOrder": 1,
"Name": "Phone",
"Id": 785
},
{
"ParentId": null,
"Code": "Cell",
"SortOrder": 2,
"Name": "Cell",
"Id": 786
},
{
"ParentId": null,
"Code": "Fax",
"SortOrder": 3,
"Name": "Fax",
"Id": 787
},
{
"ParentId": null,
"Code": "Home",
"SortOrder": 4,
"Name": "Home",
"Id": 788
},
{
"ParentId": null,
"Code": "Office",
"SortOrder": 5,
"Name": "Office",
"Id": 789
}
],
"KeyType": "Integer"
}
]
I was handled it with following code.
struct responseObjectClass:BaseModel {
var responsearray: [arrayData]? = nil
init(json: JSON) {
responsearray = json.arrayValue.map { arrayData(json: $0) }
}
}
struct arrayData:BaseModel {
let Name: String?
var DataValue: [DataLookup]? = nil
let KeyType: String?
init(json: JSON) {
Name = json["Name"].stringValue
DataValue = json["Data"].arrayValue.map { DataLookup(json: $0) }
KeyType = json["KeyType"].stringValue
}
}
struct DataLookup:BaseModel {
let ParentId: Any?
let Code: String?
let SortOrder: Int?
let Name: String?
let Id: Int?
init(json: JSON) {
ParentId = json["ParentId"]
Code = json["Code"].stringValue
SortOrder = json["SortOrder"].intValue
Name = json["Name"].stringValue
Id = json["Id"].intValue
}
}
BaseModel is Optional it's just used for init Json.
protocol BaseModel {
init(json: JSON)
}
Without SwiftyJSON
Below is the valid JSON
data.json File
[{
"id": 1,
"name": "Team name",
"shower": {
"id": 1,
"status": 1,
"startLocation": {
"id": 1,
"name": "abc 16"
}
}
}, {
"id": 2,
"name": "Team name",
"shower": {
"id": 2,
"status": 1,
"startLocation": {
"id": 1,
"name": "efg 16"
}
}
}]
Below is the code to read your json.
if let path = Bundle.main.path(forResource: "data", ofType: "json") {
let url = URL(fileURLWithPath: path)
do {
let data = try Data(contentsOf: url)
if let jsonArray = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSArray {
for (_, item) in jsonArray.enumerated() {
let itemDict = item as! NSDictionary
let id = itemDict["id"] as! Int
let name = itemDict["name"] as! String
let shower = itemDict["shower"] as! NSDictionary
let showerId = shower["id"] as! Int
let showerStatus = shower["status"] as! Int
let startLocation = shower["startLocation"] as! NSDictionary
let startLocationId = startLocation["id"] as! Int
let startLocationName = startLocation["name"] as! String
}
}
} catch {
print("Error: \(error.localizedDescription)")
}
}
this is what worked for me:
// Convert JSON to Array
func JSONToArray(_ json: String) -> Array<Any>? {
if let data = json.data(using: String.Encoding.utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? Array
} catch let error as NSError {
print(error)
}
}
return nil
}
After using this function i could loop trough the sub JSONs.
Thanks.

Resources