我有这两个JSON,它们共享一个字段userId
这个:
{
"oldest": "2019-01-24T00:00:00+00:00",
"activities": [
{
"message": "<strong>Henrik</strong> didn't resist a guilty pleasure at <strong>Starbucks</strong>.",
"amount": 2.5,
"userId": 2,
"timestamp": "2019-05-23T00:00:00+00:00"
},
{
"message": "<strong>Johan</strong> made a roundup.",
"amount": 0.32,
"userId": 3,
"timestamp": "2019-05-22T00:00:00+00:00"
},
{
"message": "<strong>You</strong> didn't resist a guilty pleasure at <strong>Starbucks</strong>.",
"amount": 15,
"userId": 1,
"timestamp": "2019-05-21T00:00:00+00:00"
}
]
还有一个:
[
{
"userId": 1,
"displayName": "Mikael",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/mikael.jpg"
},
{
"userId": 2,
"displayName": "Henrik",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/henrik.jpg"
},
{
"userId": 3,
"displayName": "Johan",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/johan.jpg"
},
{
"userId": 4,
"displayName": "Erik",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/erik.jpg"
},
{
"userId": 5,
"displayName": "George",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/george.jpg"
},
{
"userId": 6,
"displayName": "Daniel",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/daniel.jpg"
}
]
现在我有第一个这样整理出来的:
struct Root: Decodable {
var oldest: Date
var activities: [Activity]
}
struct Activity: Decodable {
var message: String
var amount: Float
var userId: Int
var timestamp: Date
}
请注意,Activity(第一个JSON)中的userId
变量也出现在第二个JSON上。我正在使用这些结构填充我的TableViewController。
我最终需要在消息和日期标签(检查图像)旁边显示头像图像。为此,我认为我需要将第一个JSON与第二个JSON连接/关联(不知道这个词),如果我错了,请更正我。我还需要User的另一个结构吗?
这是我的联网代码:
let userJSONURLString = "https://qapital-ios-testtask.herokuapp.com/users"
let activitiesJSONURLString = "https://qapital-ios-testtask.herokuapp.com/activities?from=2016-05-23T00:00:00+00:00&to=2019-05-23T00:00:00+00:00"
guard let userURL = URL(string: userJSONURLString) else { return }
guard let activitiesURL = URL(string: activitiesJSONURLString) else { return }
URLSession.shared.dataTask(with: activitiesURL) { (data, response, err) in
// perhaps check err
// also perhaps check response status 200 OK
guard let data = data else { return }
do {
// Activities
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let result = try decoder.decode(Root.self, from: data)
self.activities = result.activities
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print("Error serializing json: ", error)
}
}.resume()
这是我的cellForRowAt(如果需要):
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ActivityCell", for: indexPath) as! MainTableViewCell
let activity = activities[indexPath.row]
// Amount
cell.amountLabel.text = String(format: "$%.2f", activity.amount)
// Message
let formattedString = activity.message.htmlAttributedString().with(font:UIFont(name: "Helvetica Neue", size: 15)!)
cell.descriptionLabel.attributedText = formattedString
// Date
// cell.dateLabel
// Avatar
return cell
}
更新的代码:
struct Activity: Decodable {
var message: String
var amount: Float
var userId: Int
var timestamp: Date
var avatar : UIImage = UIImage(named: "user-icon-image-placeholder-300-grey.jpg")!
private enum CodingKeys : String, CodingKey { case message, amount, userId, timestamp }
}
URLSession.shared.dataTask(with: activitiesURL) { (data, response, err) in
guard let data = data else { return }
do {
// Activities
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let result = try decoder.decode(Root.self, from: data)
self.activities = result.activities
URLSession.shared.dataTask(with: userURL) { (data, response, err) in
guard let data = data else { return }
do {
// Users
let usersJson = try JSONSerialization.jsonObject(with: data, options: [])
guard let jsonArray = usersJson as? [[String: Any]] else { return }
for dic in jsonArray {
guard let avatarUrl = dic["avatarUrl"] as? String else { return }
print(avatarUrl)
}
} catch {
print("Error serializing json: ", error)
}
}.resume()
} catch {
print("Error serializing json: ", error)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}.resume()
答案 0 :(得分:0)
在Activity
结构中添加CodingKeys
和化身URL的额外成员
struct Activity: Decodable {
let message: String
let amount: Float
let userId: Int
let timestamp: Date
var avatar : URL = // some default URL to a placeholder image on disk
private enum CodingKeys : String, CodingKey { case message, amount, userId, timestamp }
}
CodingKeys
的目的是仅对前4个结构成员进行解码。
在第一个数据任务的完成处理程序中,添加第二个数据任务以加载用户数据。
JSONSerialization
将JSON解码为字典数组。 userId
的活动并更新头像URL。