1+ import Foundation
2+
13public struct StatsPostDetails : Equatable {
24 public let fetchedDate : Date
35 public let totalViewsCount : Int
@@ -6,6 +8,81 @@ public struct StatsPostDetails: Equatable {
68 public let dailyAveragesPerMonth : [ StatsPostViews ]
79 public let monthlyBreakdown : [ StatsPostViews ]
810 public let lastTwoWeeks : [ StatsPostViews ]
11+ public let data : [ StatsPostViews ]
12+
13+ public let highestMonth : Int ?
14+ public let highestDayAverage : Int ?
15+ public let highestWeekAverage : Int ?
16+
17+ public let yearlyTotals : [ Int : Int ]
18+ public let overallAverages : [ Int : Int ]
19+
20+ public let fields : [ String ] ?
21+
22+ public let post : Post ?
23+
24+ public struct Post : Equatable {
25+ public let postID : Int
26+ public let title : String
27+ public let authorID : String ?
28+ public let dateGMT : Date ?
29+ public let content : String ?
30+ public let excerpt : String ?
31+ public let status : String ?
32+ public let commentStatus : String ?
33+ public let password : String ?
34+ public let name : String ?
35+ public let modifiedGMT : Date ?
36+ public let contentFiltered : String ?
37+ public let parent : Int ?
38+ public let guid : String ?
39+ public let type : String ?
40+ public let mimeType : String ?
41+ public let commentCount : String ?
42+ public let permalink : String ?
43+
44+ init ? ( jsonDictionary: [ String : AnyObject ] ) {
45+ guard
46+ let postID = jsonDictionary [ " ID " ] as? Int ,
47+ let title = jsonDictionary [ " post_title " ] as? String
48+ else {
49+ return nil
50+ }
51+
52+ let dateFormatter = DateFormatter ( )
53+ dateFormatter. locale = Locale ( identifier: " en_US_POSIX " )
54+ dateFormatter. dateFormat = " yyyy-MM-dd HH:mm:ss "
55+
56+ var dateGMT : Date ?
57+ var modifiedGMT : Date ?
58+
59+ if let postDateGMTString = jsonDictionary [ " post_date_gmt " ] as? String {
60+ dateGMT = dateFormatter. date ( from: postDateGMTString)
61+ }
62+ if let postModifiedGMTString = jsonDictionary [ " post_modified_gmt " ] as? String {
63+ modifiedGMT = dateFormatter. date ( from: postModifiedGMTString)
64+ }
65+
66+ self . postID = postID
67+ self . title = title
68+ self . authorID = jsonDictionary [ " post_author " ] as? String
69+ self . dateGMT = dateGMT
70+ self . content = jsonDictionary [ " post_content " ] as? String
71+ self . excerpt = jsonDictionary [ " post_excerpt " ] as? String
72+ self . status = jsonDictionary [ " post_status " ] as? String
73+ self . commentStatus = jsonDictionary [ " comment_status " ] as? String
74+ self . password = jsonDictionary [ " post_password " ] as? String
75+ self . name = jsonDictionary [ " post_name " ] as? String
76+ self . modifiedGMT = modifiedGMT
77+ self . contentFiltered = jsonDictionary [ " post_content_filtered " ] as? String
78+ self . parent = jsonDictionary [ " post_parent " ] as? Int
79+ self . guid = jsonDictionary [ " guid " ] as? String
80+ self . type = jsonDictionary [ " post_type " ] as? String
81+ self . mimeType = jsonDictionary [ " post_mime_type " ] as? String
82+ self . commentCount = jsonDictionary [ " comment_count " ] as? String
83+ self . permalink = jsonDictionary [ " permalink " ] as? String
84+ }
85+ }
986}
1087
1188public struct StatsWeeklyBreakdown : Equatable {
@@ -15,6 +92,7 @@ public struct StatsWeeklyBreakdown: Equatable {
1592 public let totalViewsCount : Int
1693 public let averageViewsCount : Int
1794 public let changePercentage : Double
95+ public let isChangeInfinity : Bool
1896
1997 public let days : [ StatsPostViews ]
2098}
@@ -26,7 +104,7 @@ public struct StatsPostViews: Equatable {
26104}
27105
28106extension StatsPostDetails {
29- init ? ( jsonDictionary: [ String : AnyObject ] ) {
107+ public init ? ( jsonDictionary: [ String : AnyObject ] ) {
30108 guard
31109 let fetchedDateString = jsonDictionary [ " date " ] as? String ,
32110 let date = type ( of: self ) . dateFormatter. date ( from: fetchedDateString) ,
@@ -35,13 +113,15 @@ extension StatsPostDetails {
35113 let monthlyAverages = jsonDictionary [ " averages " ] as? [ String : AnyObject ] ,
36114 let recentWeeks = jsonDictionary [ " weeks " ] as? [ [ String : AnyObject ] ] ,
37115 let data = jsonDictionary [ " data " ] as? [ [ Any ] ]
38- else {
39- return nil
116+ else {
117+ return nil
40118 }
41119
42120 self . fetchedDate = date
43121 self . totalViewsCount = totalViewsCount
44122
123+ self . data = StatsPostViews . mapDailyData ( data: data)
124+
45125 // It's very hard to describe the format of this response. I tried to make the parsing
46126 // as nice and readable as possible, but in all honestly it's still pretty nasty.
47127 // If you want to see an example response to see how weird this response is, check out
@@ -50,6 +130,42 @@ extension StatsPostDetails {
50130 self . monthlyBreakdown = StatsPostViews . mapMonthlyBreakdown ( jsonDictionary: monthlyBreakdown)
51131 self . dailyAveragesPerMonth = StatsPostViews . mapMonthlyBreakdown ( jsonDictionary: monthlyAverages)
52132 self . lastTwoWeeks = StatsPostViews . mapDailyData ( data: Array ( data. suffix ( 14 ) ) )
133+
134+ // Parse new fields
135+ self . highestMonth = jsonDictionary [ " highest_month " ] as? Int
136+ self . highestDayAverage = jsonDictionary [ " highest_day_average " ] as? Int
137+ self . highestWeekAverage = jsonDictionary [ " highest_week_average " ] as? Int
138+
139+ self . fields = jsonDictionary [ " fields " ] as? [ String ]
140+
141+ // Parse yearly totals
142+ var yearlyTotals : [ Int : Int ] = [ : ]
143+ if let years = monthlyBreakdown as? [ String : [ String : AnyObject ] ] {
144+ for (yearKey, yearData) in years {
145+ if let yearInt = Int ( yearKey) , let total = yearData [ " total " ] as? Int {
146+ yearlyTotals [ yearInt] = total
147+ }
148+ }
149+ }
150+ self . yearlyTotals = yearlyTotals
151+
152+ // Parse overall averages
153+ var overallAverages : [ Int : Int ] = [ : ]
154+ if let averages = monthlyAverages as? [ String : [ String : AnyObject ] ] {
155+ for (yearKey, yearData) in averages {
156+ if let yearInt = Int ( yearKey) , let overall = yearData [ " overall " ] as? Int {
157+ overallAverages [ yearInt] = overall
158+ }
159+ }
160+ }
161+ self . overallAverages = overallAverages
162+
163+ // Parse post object using the new Post model
164+ if let postDict = jsonDictionary [ " post " ] as? [ String : AnyObject ] {
165+ self . post = Post ( jsonDictionary: postDict)
166+ } else {
167+ self . post = nil
168+ }
53169 }
54170
55171 static var dateFormatter : DateFormatter {
@@ -93,19 +209,30 @@ extension StatsPostViews {
93209 let totalViews = $0 [ " total " ] as? Int ,
94210 let averageViews = $0 [ " average " ] as? Int ,
95211 let days = $0 [ " days " ] as? [ [ String : AnyObject ] ]
96- else {
97- return nil
212+ else {
213+ return nil
98214 }
99215
100- let change = ( $0 [ " change " ] as? Double ) ?? 0.0
216+ var change : Double = 0.0
217+ var isChangeInfinity = false
218+
219+ if let changeValue = $0 [ " change " ] {
220+ if let changeDict = changeValue as? [ String : AnyObject ] ,
221+ let isInfinity = changeDict [ " isInfinity " ] as? Bool {
222+ isChangeInfinity = isInfinity
223+ change = isInfinity ? Double . infinity : 0.0
224+ } else if let changeDouble = changeValue as? Double {
225+ change = changeDouble
226+ }
227+ }
101228
102229 let mappedDays : [ StatsPostViews ] = days. compactMap {
103230 guard
104231 let dayString = $0 [ " day " ] as? String ,
105232 let date = StatsPostDetails . dateFormatter. date ( from: dayString) ,
106233 let viewsCount = $0 [ " count " ] as? Int
107- else {
108- return nil
234+ else {
235+ return nil
109236 }
110237
111238 return StatsPostViews ( period: . day,
@@ -122,9 +249,9 @@ extension StatsPostViews {
122249 totalViewsCount: totalViews,
123250 averageViewsCount: averageViews,
124251 changePercentage: change,
252+ isChangeInfinity: isChangeInfinity,
125253 days: mappedDays)
126254 }
127-
128255 }
129256}
130257
0 commit comments