This repository was archived by the owner on Sep 15, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathStatsSubscribersSummaryData.swift
More file actions
94 lines (78 loc) · 3.07 KB
/
Copy pathStatsSubscribersSummaryData.swift
File metadata and controls
94 lines (78 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import Foundation
public struct StatsSubscribersSummaryData: Equatable {
public let history: [SubscriberData]
public let period: StatsPeriodUnit
public let periodEndDate: Date
public init(history: [SubscriberData], period: StatsPeriodUnit, periodEndDate: Date) {
self.history = history
self.period = period
self.periodEndDate = periodEndDate
}
}
extension StatsSubscribersSummaryData: StatsTimeIntervalData {
public static var pathComponent: String {
return "stats/subscribers"
}
static var hourlyDateFormatter: DateFormatter {
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POSIX")
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
return df
}
static var dateFormatter: DateFormatter = {
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POS")
df.dateFormat = "yyyy-MM-dd"
return df
}()
static var weeksDateFormatter: DateFormatter = {
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POS")
df.dateFormat = "yyyy'W'MM'W'dd"
return df
}()
public struct SubscriberData: Equatable {
public let date: Date
public let count: Int
public init(date: Date, count: Int) {
self.date = date
self.count = count
}
}
public init?(date: Date, period: StatsPeriodUnit, jsonDictionary: [String: AnyObject]) {
guard
let fields = jsonDictionary["fields"] as? [String],
let data = jsonDictionary["data"] as? [[Any]],
let dateIndex = fields.firstIndex(of: "period"),
let countIndex = fields.firstIndex(of: "subscribers")
else {
return nil
}
let history: [SubscriberData?] = data.map { elements in
guard elements.indices.contains(dateIndex) && elements.indices.contains(countIndex),
let dateString = elements[dateIndex] as? String,
let date = StatsSubscribersSummaryData.parsedDate(from: dateString, for: period)
else {
return nil
}
let count = elements[countIndex] as? Int ?? 0
return SubscriberData(date: date, count: count)
}
let sorted = history.compactMap { $0 }.sorted { $0.date < $1.date }
self = .init(history: sorted, period: period, periodEndDate: date)
}
private static func parsedDate(from dateString: String, for period: StatsPeriodUnit) -> Date? {
switch period {
case .hour:
// Example: "2025-07-17 09:00:00" (in a site timezone)
return self.hourlyDateFormatter.date(from: dateString)
case .week:
return self.weeksDateFormatter.date(from: dateString)
case .day, .month, .year:
return self.dateFormatter.date(from: dateString)
}
}
public static func queryProperties(with date: Date, period: StatsPeriodUnit, maxCount: Int) -> [String: String] {
return ["quantity": String(maxCount), "unit": period.stringValue]
}
}