diff --git a/Podfile b/Podfile index ae4814446795..a5710fbd385f 100644 --- a/Podfile +++ b/Podfile @@ -44,7 +44,7 @@ end def wordpress_kit pod 'WordPressKit', '~> 4.1-beta' - #pod 'WordPressKit', :git => 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', :branch => 'bug/allow-specifying-limit-for-summary-queries' + #pod 'WordPressKit', :git => 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', :branch => 'feature/stats-fetch-likes-separately' #pod 'WordPressKit', :path => '../WordPressKit-iOS' end diff --git a/Podfile.lock b/Podfile.lock index 7414b88d8974..7e12675848b0 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -176,9 +176,9 @@ PODS: - Starscream (3.0.6) - SVProgressHUD (2.2.5) - UIDeviceIdentifier (1.1.4) - - WordPress-Aztec-iOS (1.6.5) - - WordPress-Editor-iOS (1.6.5): - - WordPress-Aztec-iOS (= 1.6.5) + - WordPress-Aztec-iOS (1.6.6) + - WordPress-Editor-iOS (1.6.6): + - WordPress-Aztec-iOS (= 1.6.6) - WordPressAuthenticator (1.5.0): - 1PasswordExtension (= 1.8.5) - Alamofire (= 4.7.3) @@ -191,7 +191,7 @@ PODS: - WordPressKit (~> 4.1.1-beta) - WordPressShared (~> 1.8.0-beta) - WordPressUI (~> 1.0) - - WordPressKit (4.1.2-beta.1): + - WordPressKit (4.1.2-beta.2): - Alamofire (~> 4.7.3) - CocoaLumberjack (~> 3.4) - NSObject-SafeExpectations (= 0.0.3) @@ -384,10 +384,10 @@ SPEC CHECKSUMS: Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5 SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 UIDeviceIdentifier: 8f8a24b257a4d978c8d40ad1e7355b944ffbfa8c - WordPress-Aztec-iOS: a571396f85f97dc37d4f48ccbb8975f3f92b1617 - WordPress-Editor-iOS: f56cb8ccf5d4c69aef498e72d043696e72c07e8f + WordPress-Aztec-iOS: 0f52944080a5d49a977d2260f2d1f613a789ee76 + WordPress-Editor-iOS: b744ea2f6ca051bf2fd965f9b3ac12eef3272419 WordPressAuthenticator: 958545e13b06d39d064d96b2cfdd92c250fe6ead - WordPressKit: 841679f76215ec001dc37dca1f0ec71c0aa5a7b7 + WordPressKit: b6bc843b191537af99e81ff2697d2a13357e34e9 WordPressShared: f48dfc3925e88fc55ba21baad58518a3ab7d97b3 WordPressUI: c98c9f6c2347a8d70d6c3a7e3b9ef61faecf3ab0 WPMediaPicker: 8cff8dff846f3440c0c6d088c12240ab85570ee5 @@ -396,6 +396,6 @@ SPEC CHECKSUMS: ZendeskSDK: cbd49d65efb2f2cdbdcaac84e618896ae87b861e ZIPFoundation: 89df685c971926b0323087952320bdfee9f0b6ef -PODFILE CHECKSUM: 3081e0cc8108f65ce0d2d8a391b480b54912a924 +PODFILE CHECKSUM: a0b06c22940440a5752e3cc537f3c735d7639dd8 COCOAPODS: 1.6.1 diff --git a/WordPress/Classes/Stores/StatsPeriodStore.swift b/WordPress/Classes/Stores/StatsPeriodStore.swift index ee6eeef81681..4a17b1c049e0 100644 --- a/WordPress/Classes/Stores/StatsPeriodStore.swift +++ b/WordPress/Classes/Stores/StatsPeriodStore.swift @@ -6,6 +6,7 @@ enum PeriodAction: Action { // Period overview case receivedSummary(_ summary: StatsSummaryTimeIntervalData?, _ error: Error?) + case receivedLikesSummary(_ likes: StatsLikesSummaryTimeIntervalData?, _ error: Error?) case receivedPostsAndPages(_ postsAndPages: StatsTopPostsTimeIntervalData?, _ error: Error?) case receivedPublished(_ published: StatsPublishedPostsTimeIntervalData?, _ error: Error?) case receivedReferrers(_ referrers: StatsTopReferrersTimeIntervalData?, _ error: Error?) @@ -110,6 +111,7 @@ struct PeriodStoreState { var summary: StatsSummaryTimeIntervalData? var fetchingSummary = false var fetchingSummaryHasFailed = false + var fetchingSummaryLikes = false var topPostsAndPages: StatsTopPostsTimeIntervalData? var fetchingPostsAndPages = false @@ -169,6 +171,8 @@ class StatsPeriodStore: QueryStore { switch periodAction { case .receivedSummary(let summary, let error): receivedSummary(summary, error) + case .receivedLikesSummary(let likes, let error): + receivedLikesSummary(likes, error) case .receivedPostsAndPages(let postsAndPages, let error): receivedPostsAndPages(postsAndPages, error) case .receivedReferrers(let referrers, let error): @@ -328,6 +332,16 @@ private extension StatsPeriodStore { self.actionDispatcher.dispatch(PeriodAction.receivedSummary(summary, error)) } + statsRemote.getData(for: period, endingOn: date, limit: 14) { (likes: StatsLikesSummaryTimeIntervalData?, error: Error?) in + if error != nil { + DDLogInfo("Error fetching likes summary: \(String(describing: error?.localizedDescription))") + } + + DDLogInfo("Stats: Finished fetching likes summary.") + + self.actionDispatcher.dispatch(PeriodAction.receivedLikesSummary(likes, error)) + } + statsRemote.getData(for: period, endingOn: date) { (posts: StatsTopPostsTimeIntervalData?, error: Error?) in if error != nil { DDLogInfo("Error fetching posts: \(String(describing: error?.localizedDescription))") @@ -719,6 +733,39 @@ private extension StatsPeriodStore { } } + func receivedLikesSummary(_ likesSummary: StatsLikesSummaryTimeIntervalData?, _ error: Error?) { + // This is a workaround for how our API works — the requests for summary for long periods of times + // can take extreme amounts of time to finish (and semi-frequenty fail). In order to not block the UI + // here, we split out the views/visitors/comments and likes requests. + // This method splices the results of the two back together so we can persist it to Core Data. + guard + let summary = likesSummary, + let currentSummary = state.summary, + summary.summaryData.count == currentSummary.summaryData.count + else { + return + } + + let newSummaryData = currentSummary.summaryData.enumerated().map { index, obj in + return StatsSummaryData(period: obj.period, + periodStartDate: obj.periodStartDate, + viewsCount: obj.viewsCount, + visitorsCount: obj.visitorsCount, + likesCount: summary.summaryData[index].likesCount, + commentsCount: obj.commentsCount) + } + + let newSummary = StatsSummaryTimeIntervalData(period: currentSummary.period, + periodEndDate: currentSummary.periodEndDate, + summaryData: newSummaryData) + + transaction { state in + state.fetchingSummaryLikes = false + state.summary = newSummary + } + + } + func receivedPostsAndPages(_ postsAndPages: StatsTopPostsTimeIntervalData?, _ error: Error?) { transaction { state in state.fetchingPostsAndPages = false @@ -852,6 +899,7 @@ private extension StatsPeriodStore { func setAllAsFetchingOverview(fetching: Bool = true) { state.fetchingSummary = fetching + state.fetchingSummaryLikes = fetching state.fetchingPostsAndPages = fetching state.fetchingReferrers = fetching state.fetchingClicks = fetching @@ -959,6 +1007,10 @@ extension StatsPeriodStore { state.fetchingCountries } + var isFetchingSummaryLikes: Bool { + return state.fetchingSummaryLikes + } + var isFetchingPostsAndPages: Bool { return state.fetchingPostsAndPages } diff --git a/WordPress/Classes/ViewRelated/Stats/Period Stats/Overview/OverviewCell.swift b/WordPress/Classes/ViewRelated/Stats/Period Stats/Overview/OverviewCell.swift index 0a92da891637..868b96c70913 100644 --- a/WordPress/Classes/ViewRelated/Stats/Period Stats/Overview/OverviewCell.swift +++ b/WordPress/Classes/ViewRelated/Stats/Period Stats/Overview/OverviewCell.swift @@ -3,12 +3,14 @@ import UIKit struct OverviewTabData: FilterTabBarItem { var tabTitle: String var tabData: Int + var tabDataStub: String? var difference: Int var differencePercent: Int - init(tabTitle: String, tabData: Int, difference: Int, differencePercent: Int) { + init(tabTitle: String, tabData: Int, tabDataStub: String? = nil, difference: Int, differencePercent: Int) { self.tabTitle = tabTitle self.tabData = tabData + self.tabDataStub = tabDataStub self.difference = difference self.differencePercent = differencePercent } @@ -19,7 +21,14 @@ struct OverviewTabData: FilterTabBarItem { attributedTitle.addAttributes([.font: WPStyleGuide.Stats.overviewCardFilterTitleFont], range: NSMakeRange(0, attributedTitle.string.count)) - let attributedData = NSMutableAttributedString(string: tabData.abbreviatedString()) + let dataString: String = { + if let tabDataStub = tabDataStub { + return tabDataStub + } + return tabData.abbreviatedString() + }() + + let attributedData = NSMutableAttributedString(string: dataString) attributedData.addAttributes([.font: WPStyleGuide.Stats.overviewCardFilterDataFont], range: NSMakeRange(0, attributedData.string.count)) diff --git a/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift b/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift index 759a7589dab2..8febd512a3f1 100644 --- a/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift +++ b/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift @@ -134,9 +134,15 @@ private extension SiteStatsPeriodViewModel { difference: visitorsData.difference, differencePercent: visitorsData.percentage) + + // If Summary Likes is still loading, show dashes (instead of 0) + // to indicate it's still loading. + let likesLoadingStub = store.isFetchingSummaryLikes ? "----" : nil + let likesData = intervalData(summaryData: summaryData, summaryType: .likes) let likesTabData = OverviewTabData(tabTitle: StatSection.periodOverviewLikes.tabTitle, tabData: likesData.count, + tabDataStub: likesLoadingStub, difference: likesData.difference, differencePercent: likesData.percentage)