Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
23bff28
Add basic structure for fetching time-based data
jklausa Feb 18, 2019
c57d427
Add `SearchTermStatsType`
jklausa Feb 18, 2019
674f8a2
add mocked data for stats search term query
jklausa Feb 18, 2019
61bc6f7
add support for fetching Authors stats
jklausa Feb 19, 2019
c44a11d
clean up time-based stats data parsing
jklausa Feb 19, 2019
77c8dfb
add support for fetching vidoes stats
jklausa Feb 19, 2019
89b7d0f
add support for fetching countries
jklausa Feb 19, 2019
0b070a1
Merge pull request #95 from wordpress-mobile/feature/fetching-time-se…
jklausa Feb 19, 2019
1381af8
Merge pull request #96 from wordpress-mobile/feature/fetching-time-se…
jklausa Feb 19, 2019
280b4d7
Add support for fetching Clicks data
jklausa Feb 19, 2019
ff42cac
Add support for fetching clicks and referrer data
jklausa Feb 19, 2019
d85fab8
Address code review feedback
jklausa Feb 20, 2019
522c23c
Update podfile
jklausa Feb 20, 2019
63f022b
Merge pull request #97 from wordpress-mobile/feature/fetching-clicks-…
jklausa Feb 20, 2019
9e4d535
Add support for fetching top posts
jklausa Feb 20, 2019
2b35702
Fix a bug causing strange build issues
jkmassel Feb 20, 2019
e60a153
update podfile.lock
jklausa Feb 20, 2019
d254e1c
Remove outdated comment
jklausa Feb 20, 2019
ce344c1
Split out `StatsServiceRemoteV2` generic specialisations into an exte…
jklausa Feb 20, 2019
b069031
Merge pull request #99 from wordpress-mobile/fix/a-weird-pods-issue
jklausa Feb 21, 2019
9979e34
cosmetic fixes
jklausa Feb 21, 2019
47f20c0
add support for fetching published posts
jklausa Feb 21, 2019
20d48e4
Add support for fetching Visits/Summary data
jklausa Feb 21, 2019
8ec3037
Fix queries for the SummaryStatsType
jklausa Feb 21, 2019
0683f28
fix a typo
jklausa Feb 21, 2019
263f75a
omit pointless `?`
jklausa Feb 21, 2019
39b26d3
Merge pull request #100 from wordpress-mobile/feature/fetching-postin…
jklausa Feb 21, 2019
2ea8fca
Merge branch 'develop' into feature/fetching-top-posts
jklausa Feb 21, 2019
9e3935d
unbreak build after bad merge
jklausa Feb 21, 2019
a9dd073
Merge pull request #98 from wordpress-mobile/feature/fetching-top-posts
jklausa Feb 21, 2019
fe9e21f
Add support for fetching detail stats for specific post
jklausa Feb 22, 2019
8e0726b
Merge branch 'develop' into feature/fetching-visits
jklausa Feb 22, 2019
1435aeb
fix typo in comment
jklausa Feb 22, 2019
c71c6c1
Merge pull request #101 from wordpress-mobile/feature/fetching-visits
jklausa Feb 22, 2019
4908722
Merge branch 'develop' into feature/stats-fetch-post-details
jklausa Feb 22, 2019
0f98a2c
fix broken merge
jklausa Feb 22, 2019
520e927
Merge pull request #102 from wordpress-mobile/feature/stats-fetch-pos…
jklausa Feb 22, 2019
818ac9d
Bump version to 2.1.0
loremattei Feb 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ plugin 'cocoapods-repo-update'
## =============
##
target 'WordPressKit' do
pod "WordPressKit", :path => "./"
pod 'Alamofire', '~> 4.7.3'
pod 'CocoaLumberjack', '3.4.2'
pod 'WordPressShared', '~> 1.4'
pod 'NSObject-SafeExpectations', '~> 0.0.3'
pod 'wpxmlrpc', '0.8.4'
pod 'UIDeviceIdentifier', '~> 1.1.4'

target 'WordPressKitTests' do
inherit! :search_paths
Expand Down
20 changes: 6 additions & 14 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,21 @@ PODS:
- OHHTTPStubs/Swift (6.1.0):
- OHHTTPStubs/Default
- UIDeviceIdentifier (1.1.4)
- WordPressKit (2.1.0-beta.2):
- Alamofire (~> 4.7.3)
- CocoaLumberjack (= 3.4.2)
- NSObject-SafeExpectations (= 0.0.3)
- UIDeviceIdentifier (~> 1.1.4)
- WordPressShared (~> 1.4)
- wpxmlrpc (= 0.8.4)
- WordPressShared (1.7.0):
- CocoaLumberjack (~> 3.4)
- FormatterKit/TimeIntervalFormatter (= 1.8.2)
- wpxmlrpc (0.8.4)

DEPENDENCIES:
- Alamofire (~> 4.7.3)
- CocoaLumberjack (= 3.4.2)
- NSObject-SafeExpectations (~> 0.0.3)
- OCMock (~> 3.4.2)
- OHHTTPStubs (= 6.1.0)
- OHHTTPStubs/Swift (= 6.1.0)
- WordPressKit (from `./`)
- UIDeviceIdentifier (~> 1.1.4)
- WordPressShared (~> 1.4)
- wpxmlrpc (= 0.8.4)

SPEC REPOS:
https://github.com/cocoapods/specs.git:
Expand All @@ -58,10 +55,6 @@ SPEC REPOS:
- WordPressShared
- wpxmlrpc

EXTERNAL SOURCES:
WordPressKit:
:path: "./"

SPEC CHECKSUMS:
Alamofire: c7287b6e5d7da964a70935e5db17046b7fde6568
CocoaLumberjack: db7cc9e464771f12054c22ff6947c5a58d43a0fd
Expand All @@ -70,10 +63,9 @@ SPEC CHECKSUMS:
OCMock: 43565190abc78977ad44a61c0d20d7f0784d35ab
OHHTTPStubs: 1e21c7d2c084b8153fc53d48400d8919d2d432d0
UIDeviceIdentifier: 8f8a24b257a4d978c8d40ad1e7355b944ffbfa8c
WordPressKit: 36e5966f63f88efc51c6a3de4aa07dbd66eb15cc
WordPressShared: cfbda56868419842dd7a106a4e807069a0c17aa9
wpxmlrpc: 6ba55c773cfa27083ae4a2173e69b19f46da98e2

PODFILE CHECKSUM: 96aee46d567751451860e27dd476d15d79b40f44
PODFILE CHECKSUM: 34d4f957f37c097c360d2863370ce2e5e06511cc

COCOAPODS: 1.5.3
2 changes: 1 addition & 1 deletion WordPressKit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "WordPressKit"
s.version = "2.1.0-beta.2"
s.version = "2.1.0"
s.summary = "WordPressKit offers a clean and simple WordPress.com and WordPress.org API."

s.description = <<-DESC
Expand Down
102 changes: 100 additions & 2 deletions WordPressKit.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

62 changes: 62 additions & 0 deletions WordPressKit/Insights/StatsLastPostInsight.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
public struct StatsLastPostInsight {
public let title: String
public let url: URL
public let publishedDate: Date
public let likesCount: Int
public let commentsCount: Int
public let viewsCount: Int
public let postID: Int
}

extension StatsLastPostInsight: InsightProtocol {

//MARK: - InsightProtocol Conformance
public static var queryProperties: [String: String] {
return ["order_by": "date",
"number": "1",
"type": "post",
"fields": "ID, title, URL, discussion, like_count, date"]
}

public static var pathComponent: String {
return "posts/"
}

public init?(jsonDictionary: [String: AnyObject]) {
fatalError("This shouldn't be ever called, instead init?(jsonDictionary:_ views:_) be called instead.")
}

//MARK: -

private static let dateFormatter = ISO8601DateFormatter()

public init?(jsonDictionary: [String: AnyObject], views: Int) {

guard
let title = jsonDictionary["title"] as? String,
let dateString = jsonDictionary["date"] as? String,
let urlString = jsonDictionary["URL"] as? String,
let likesCount = jsonDictionary["like_count"] as? Int,
let postID = jsonDictionary["ID"] as? Int,
let discussionDict = jsonDictionary["discussion"] as? [String: Any],
let commentsCount = discussionDict["comment_count"] as? Int
else {
return nil
}

guard
let url = URL(string: urlString),
let date = StatsLastPostInsight.dateFormatter.date(from: dateString)
else {
return nil
}

self.title = title.trimmingCharacters(in: CharacterSet.whitespaces).stringByDecodingXMLCharacters()
self.url = url
self.publishedDate = date
self.likesCount = likesCount
self.commentsCount = commentsCount
self.viewsCount = views
self.postID = postID
}
}
148 changes: 148 additions & 0 deletions WordPressKit/StatsPostDetails.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
public struct StatsPostDetails {
public let fetchedDate: Date
public let totalViewsCount: Int

public let recentWeeks: [StatsWeeklyBreakdown]
public let dailyAveragesPerMonth: [StatsPostViews]
public let monthlyBreakdown: [StatsPostViews]
public let lastTwoWeeks: [StatsPostViews]
}

public struct StatsWeeklyBreakdown {
public let startDay: DateComponents
public let endDay: DateComponents

public let totalViewsCount: Int
public let averageViewsCount: Int
public let changePercentage: Double

public let days: [StatsPostViews]
}

public struct StatsPostViews {
public let period: StatsPeriodUnit
public let date: DateComponents
public let viewsCount: Int
}

extension StatsPostDetails {
init?(jsonDictionary: [String: AnyObject]) {
guard
let fetchedDateString = jsonDictionary["date"] as? String,
let date = type(of: self).dateFormatter.date(from: fetchedDateString),
let totalViewsCount = jsonDictionary["views"] as? Int,
let monthlyBreakdown = jsonDictionary["years"] as? [String: AnyObject],
let monthlyAverages = jsonDictionary["averages"] as? [String: AnyObject],
let recentWeeks = jsonDictionary["weeks"] as? [[String: AnyObject]],
let data = jsonDictionary["data"] as? [[Any]]
else {
return nil
}

self.fetchedDate = date
self.totalViewsCount = totalViewsCount

// It's very hard to describe the format of this response. I tried to make the parsing
// as nice and readable as possible, but in all honestly it's still pretty nasty.
// If you want to see an example response to see how weird this response is, check out
// `stats-post-details.json`.
self.recentWeeks = StatsPostViews.mapWeeklyBreakdown(jsonDictionary: recentWeeks)
self.monthlyBreakdown = StatsPostViews.mapMonthlyBreakdown(jsonDictionary: monthlyBreakdown)
self.dailyAveragesPerMonth = StatsPostViews.mapMonthlyBreakdown(jsonDictionary: monthlyAverages)
self.lastTwoWeeks = StatsPostViews.mapDailyData(data: Array(data.suffix(14)))
}

static var dateFormatter: DateFormatter {
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POS")
df.dateFormat = "yyyy-MM-dd"
return df
}
}

extension StatsPostViews {
static func mapMonthlyBreakdown(jsonDictionary: [String: AnyObject]) -> [StatsPostViews] {
return jsonDictionary.flatMap { yearKey, value -> [StatsPostViews] in
guard
let yearInt = Int(yearKey),
let monthsDict = value as? [String: AnyObject],
let months = monthsDict["months"] as? [String: Int]
else {
return []
}

return months.compactMap { monthKey, value in
guard
let month = Int(monthKey)
else {
return nil
}

return StatsPostViews(period: .month,
date: DateComponents(year: yearInt, month: month),
viewsCount: value)
}
}
}
}

extension StatsPostViews {
static func mapWeeklyBreakdown(jsonDictionary: [[String: AnyObject]]) -> [StatsWeeklyBreakdown] {
return jsonDictionary.compactMap {
guard
let totalViews = $0["total"] as? Int,
let averageViews = $0["average"] as? Int,
let days = $0["days"] as? [[String: AnyObject]]
else {
return nil
}

let change = ($0["change"] as? Double) ?? 0.0

let mappedDays: [StatsPostViews] = days.compactMap {
guard
let dayString = $0["day"] as? String,
let date = StatsPostDetails.dateFormatter.date(from: dayString),
let viewsCount = $0["count"] as? Int
else {
return nil
}

return StatsPostViews(period: .day,
date: Calendar.autoupdatingCurrent.dateComponents([.year, .month, .day], from: date),
viewsCount: viewsCount)
}

guard !mappedDays.isEmpty else {
return nil
}


return StatsWeeklyBreakdown(startDay: mappedDays.first!.date,
endDay: mappedDays.last!.date,
totalViewsCount: totalViews,
averageViewsCount: averageViews,
changePercentage: change,
days: mappedDays)
}

}
}

extension StatsPostViews {
static func mapDailyData(data: [[Any]]) -> [StatsPostViews] {
return data.compactMap {
guard
let dateString = $0[0] as? String,
let date = StatsPostDetails.dateFormatter.date(from: dateString),
let viewsCount = $0[1] as? Int
else {
return nil
}

return StatsPostViews(period: .day,
date: Calendar.autoupdatingCurrent.dateComponents([.year, .month, .day], from: date),
viewsCount: viewsCount)
}
}
}
Loading