Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 060bd54

Browse files
committed
Update StatsCommentsInsight to use Codable
1 parent 09163c8 commit 060bd54

File tree

1 file changed

+50
-39
lines changed

1 file changed

+50
-39
lines changed
Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
public struct StatsCommentsInsight {
1+
public struct StatsCommentsInsight: Codable {
22
public let topPosts: [StatsTopCommentsPost]
33
public let topAuthors: [StatsTopCommentsAuthor]
44

@@ -7,6 +7,11 @@ public struct StatsCommentsInsight {
77
self.topPosts = topPosts
88
self.topAuthors = topAuthors
99
}
10+
11+
private enum CodingKeys: String, CodingKey {
12+
case topPosts = "posts"
13+
case topAuthors = "authors"
14+
}
1015
}
1116

1217
extension StatsCommentsInsight: StatsInsightData {
@@ -17,23 +22,17 @@ extension StatsCommentsInsight: StatsInsightData {
1722
}
1823

1924
public init?(jsonDictionary: [String: AnyObject]) {
20-
guard
21-
let posts = jsonDictionary["posts"] as? [[String: AnyObject]],
22-
let authors = jsonDictionary["authors"] as? [[String: AnyObject]]
23-
else {
24-
return nil
25+
do {
26+
let jsonData = try JSONSerialization.data(withJSONObject: jsonDictionary, options: [])
27+
let decoder = JSONDecoder()
28+
self = try decoder.decode(StatsCommentsInsight.self, from: jsonData)
29+
} catch {
30+
return nil
2531
}
26-
27-
let topPosts = posts.compactMap { StatsTopCommentsPost(jsonDictionary: $0) }
28-
let topAuthors = authors.compactMap { StatsTopCommentsAuthor(jsonDictionary: $0) }
29-
30-
self.topPosts = topPosts
31-
self.topAuthors = topAuthors
3232
}
33-
3433
}
3534

36-
public struct StatsTopCommentsAuthor {
35+
public struct StatsTopCommentsAuthor: Codable {
3736
public let name: String
3837
public let commentCount: Int
3938
public let iconURL: URL?
@@ -45,9 +44,15 @@ public struct StatsTopCommentsAuthor {
4544
self.commentCount = commentCount
4645
self.iconURL = iconURL
4746
}
47+
48+
private enum CodingKeys: String, CodingKey {
49+
case name
50+
case commentCount = "comments"
51+
case iconURL = "gravatar"
52+
}
4853
}
4954

50-
public struct StatsTopCommentsPost {
55+
public struct StatsTopCommentsPost: Codable {
5156
public let name: String
5257
public let postID: String
5358
public let commentCount: Int
@@ -62,26 +67,34 @@ public struct StatsTopCommentsPost {
6267
self.commentCount = commentCount
6368
self.postURL = postURL
6469
}
70+
71+
private enum CodingKeys: String, CodingKey {
72+
case name
73+
case postID = "id"
74+
case commentCount = "comments"
75+
case postURL = "link"
76+
}
6577
}
6678

6779
private extension StatsTopCommentsAuthor {
68-
init?(jsonDictionary: [String: AnyObject]) {
69-
guard
70-
let name = jsonDictionary["name"] as? String,
71-
let avatar = jsonDictionary["gravatar"] as? String,
72-
let comments = jsonDictionary["comments"] as? String,
73-
let commentCount = Int(comments)
74-
else {
75-
return nil
80+
public init(from decoder: Decoder) throws {
81+
let container = try decoder.container(keyedBy: CodingKeys.self)
82+
let name = try container.decode(String.self, forKey: .name)
83+
let commentCount: Int
84+
if let comments = try? container.decodeIfPresent(String.self, forKey: .commentCount) {
85+
commentCount = Int(comments) ?? 0
86+
} else {
87+
commentCount = 0
7688
}
89+
let iconURL = try container.decodeIfPresent(String.self, forKey: .iconURL)
7790

78-
self.init(name: name, avatar: avatar, commentCount: commentCount)
91+
self.init(name: name, avatar: iconURL, commentCount: commentCount)
7992
}
8093

81-
init?(name: String, avatar: String, commentCount: Int) {
94+
init(name: String, avatar: String?, commentCount: Int) {
8295
let url: URL?
8396

84-
if var components = URLComponents(string: avatar) {
97+
if let avatar, var components = URLComponents(string: avatar) {
8598
components.query = "d=mm&s=60" // to get a properly-sized avatar.
8699
url = components.url
87100
} else {
@@ -95,20 +108,18 @@ private extension StatsTopCommentsAuthor {
95108
}
96109

97110
private extension StatsTopCommentsPost {
98-
init?(jsonDictionary: [String: AnyObject]) {
99-
guard
100-
let name = jsonDictionary["name"] as? String,
101-
let postID = jsonDictionary["id"] as? String,
102-
let commentString = jsonDictionary["comments"] as? String,
103-
let commentCount = Int(commentString),
104-
let postURL = jsonDictionary["link"] as? String
105-
else {
106-
return nil
111+
public init(from decoder: Decoder) throws {
112+
let container = try decoder.container(keyedBy: CodingKeys.self)
113+
let name = try container.decode(String.self, forKey: .name)
114+
let postID = try container.decode(String.self, forKey: .postID)
115+
let commentCount: Int
116+
if let comments = try? container.decodeIfPresent(String.self, forKey: .commentCount) {
117+
commentCount = Int(comments) ?? 0
118+
} else {
119+
commentCount = 0
107120
}
121+
let postURL = try container.decodeIfPresent(URL.self, forKey: .postURL)
108122

109-
self.init(name: name,
110-
postID: postID,
111-
commentCount: commentCount,
112-
postURL: URL(string: postURL))
123+
self.init(name: name, postID: postID, commentCount: commentCount, postURL: postURL)
113124
}
114125
}

0 commit comments

Comments
 (0)