1- public struct StatsDotComFollowersInsight {
1+ public struct StatsDotComFollowersInsight : Codable {
22 public let dotComFollowersCount : Int
33 public let topDotComFollowers : [ StatsFollower ]
44
@@ -7,6 +7,11 @@ public struct StatsDotComFollowersInsight {
77 self . dotComFollowersCount = dotComFollowersCount
88 self . topDotComFollowers = topDotComFollowers
99 }
10+
11+ private enum CodingKeys : String , CodingKey {
12+ case dotComFollowersCount = " total_wpcom "
13+ case topDotComFollowers = " subscribers "
14+ }
1015}
1116
1217extension StatsDotComFollowersInsight : StatsInsightData {
@@ -22,24 +27,19 @@ extension StatsDotComFollowersInsight: StatsInsightData {
2227 }
2328
2429 public init ? ( jsonDictionary: [ String : AnyObject ] ) {
25- guard
26- let subscribersCount = jsonDictionary [ " total_wpcom " ] as? Int ,
27- let subscribers = jsonDictionary [ " subscribers " ] as? [ [ String : AnyObject ] ]
28- else {
29- return nil
30+ do {
31+ let jsonData = try JSONSerialization . data ( withJSONObject: jsonDictionary, options: [ ] )
32+ let decoder = JSONDecoder ( )
33+ self = try decoder. decode ( StatsDotComFollowersInsight . self, from: jsonData)
34+ } catch {
35+ return nil
3036 }
31-
32- let followers = subscribers. compactMap { StatsFollower ( jsonDictionary: $0) }
33-
34- self . dotComFollowersCount = subscribersCount
35- self . topDotComFollowers = followers
3637 }
3738
38- // MARK: -
3939 fileprivate static let dateFormatter = ISO8601DateFormatter ( )
4040}
4141
42- public struct StatsFollower {
42+ public struct StatsFollower : Codable {
4343 public let id : String ?
4444 public let name : String
4545 public let subscribedDate : Date
@@ -54,39 +54,50 @@ public struct StatsFollower {
5454 self . avatarURL = avatarURL
5555 self . id = id
5656 }
57+
58+ private enum CodingKeys : String , CodingKey {
59+ case id = " ID "
60+ case name = " label "
61+ case subscribedDate = " date_subscribed "
62+ case avatarURL = " avatar "
63+ }
5764}
5865
5966extension StatsFollower {
60-
61- init ? ( jsonDictionary: [ String : AnyObject ] ) {
62- guard
63- let name = jsonDictionary [ " label " ] as? String ,
64- let avatar = jsonDictionary [ " avatar " ] as? String ,
65- let dateString = jsonDictionary [ " date_subscribed " ] as? String
66- else {
67- return nil
67+ public init ( from decoder: Decoder ) throws {
68+ let container = try decoder. container ( keyedBy: CodingKeys . self)
69+ self . name = try container. decode ( String . self, forKey: . name)
70+ if let id = try ? container. decodeIfPresent ( Int . self, forKey: . id) {
71+ self . id = " \( id) "
72+ } else if let id = try ? container. decodeIfPresent ( String . self, forKey: . id) {
73+ self . id = id
74+ } else {
75+ self . id = nil
6876 }
69- let id = jsonDictionary [ " ID " ] as? String
70- self . init ( name: name, avatar: avatar, date: dateString, id: id)
71- }
7277
73- init ? ( name: String , avatar: String , date: String , id: String ? = nil ) {
74- guard let date = StatsDotComFollowersInsight . dateFormatter. date ( from: date) else {
75- return nil
78+ let avatar = try ? container. decodeIfPresent ( String . self, forKey: . avatarURL)
79+ if let avatar, var components = URLComponents ( string: avatar) {
80+ components. query = " d=mm&s=60 " // to get a properly-sized avatar.
81+ self . avatarURL = components. url
82+ } else {
83+ self . avatarURL = nil
7684 }
7785
78- let url : URL ?
79-
80- if var components = URLComponents ( string: avatar) {
81- components. query = " d=mm&s=60 " // to get a properly-sized avatar.
82- url = components. url
86+ let dateString = try container. decode ( String . self, forKey: . subscribedDate)
87+ if let date = StatsDotComFollowersInsight . dateFormatter. date ( from: dateString) {
88+ self . subscribedDate = date
8389 } else {
84- url = nil
90+ throw DecodingError . dataCorruptedError ( forKey : . subscribedDate , in : container , debugDescription : " Date string does not match format expected by formatter. " )
8591 }
92+ }
8693
87- self . name = name
88- self . subscribedDate = date
89- self . avatarURL = url
90- self . id = id
94+ init ? ( jsonDictionary: [ String : AnyObject ] ) {
95+ do {
96+ let jsonData = try JSONSerialization . data ( withJSONObject: jsonDictionary, options: [ ] )
97+ let decoder = JSONDecoder ( )
98+ self = try decoder. decode ( StatsFollower . self, from: jsonData)
99+ } catch {
100+ return nil
101+ }
91102 }
92103}
0 commit comments