Reputation: 163
I have a JSON result from Alamofire and SwiftyJSON and am trying to create a dictionary from it to create an array
JSON Result
JSON: [
{
"p_589b6a49a0bfd" : {
"path" : "\/uploads\/588fa43eba3c9\/588fa43eba3c9_1486580297.jpg",
"likes" : "0",
"userid" : "588fa43eba3c9",
"caption" : "Bae",
"comments" : "0",
"date" : "1486580297"
}
},
{
"p_589b7f1c540f1" : {
"path" : "\/uploads\/588fa43eba3c9\/588fa43eba3c9_1486585628.jpg",
"likes" : "0",
"userid" : "588fa43eba3c9",
"caption" : "Hot stuff bitch ",
"comments" : "0",
"date" : "1486585628"
}
}
]
Request/Response
Alamofire.request(BASE_URL + "index.php/feed/build", method: .get, headers: headers).responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
case .failure(let error):
print(error)
}
}
I have then set up a simple class called 'FeedPost' which will store each of the elements in JSON response (this is the function in the FeedPost class)
init(postid: String, postData: Dictionary<String, AnyObject>) {
self._postid = postid
if let caption = postData["caption"] as? String {
self._caption = caption
}
if let path = postData["path"] as? String {
self._path = path
}
if let likes = postData["likes"] as? Int {
self._likes = likes
}
if let comments = postData["comments"] as? Int {
self._comments = comments
}
if let userid = postData["userid"] as? String {
self._userid = userid
}
if let date = postData["date"] as? String {
self._date = date
}
}
I need to somehow cycle through the JSON to create a dictionary to pass to FeedPost then add each FeedPost to another array called Posts during the request. The string that starts with 'p_' I want to use as the postid
Upvotes: 1
Views: 6623
Reputation: 14477
Below is the code which can be used for your case, This code is copied from playgrounds.
import UIKit
typealias JSONDictionary = [String: AnyObject]
class Post {
let id: String
let userId: String?
let date: Double?
let caption: String?
let comments: Double?
let likes: Double?
let path: String?
init?(with dictionary: JSONDictionary) {
guard let postId = dictionary.keys.first, let postInfo = dictionary[postId] as? JSONDictionary else { return nil }
self.id = postId
self.userId = postInfo["userid"] as? String
self.date = postInfo["date"] as? Double
self.caption = postInfo["caption"] as? String
self.comments = postInfo["comments"] as? Double
self.likes = postInfo["likes"] as? Double
self.path = postInfo["path"] as? String
}
}
Parsing JSON array will be like this.
case .success(let value):
let jsonArray = value["JSON"] as? [JSONDictionary]
let posts = jsonArray?.flatMap(Post.init(with:))
print("Posts \(posts)"
case .failure: break
I have tried this using a local JSON file in a Playgrounds & code was something like this.
let url = Bundle.main.url(forResource: "data", withExtension: "json")
let data = try! Data(contentsOf: url!)
let jsonArray = try! JSONSerialization.jsonObject(with: data , options: .allowFragments) as? [JSONDictionary]
let posts = jsonArray?.flatMap(Post.init(with:))
Upvotes: 1
Reputation: 72410
With Alamofire response you have used SwiftyJSON and with your FeedPost init you are using swift native dictionary. So I'm suggesting you to either work with SwiftyJSON or with swift's native type. Since you have already added init
with dictionary I'm answering your answer with native type.
Alamofire.request(BASE_URL + "index.php/feed/build", method: .get, headers: headers).responseJSON { response in
switch response.result {
case .success(let value):
If let dic = value as? [String: Any],
let array = DIC["JSON"] as? [[String: Any]] {
for item in array {
for (key, value) in item {
If let subDic = value as? [String: Any] {
let obj = FeedPost(postid: key, postData: subDic)
}
}
}
}
print("JSON: \(json)")
case .failure(let error):
print(error)
}
}
Note: Correct Dictionary notation for JSON in swift 3 is [String: Any]
not [String: AnyObject]
so change your init parameter postData's type to [String: Any]
.
Upvotes: 3