From 716326351e5f0206b8f12c5fcfef01eaf75aabc9 Mon Sep 17 00:00:00 2001 From: CMK Date: Wed, 3 Nov 2021 14:24:52 +0800 Subject: [PATCH] feat: add store rating supports --- Mastodon.xcodeproj/project.pbxproj | 4 +++ .../xcschemes/xcschememanagement.plist | 8 +++--- .../Preference/StoreReviewPreference.swift | 26 +++++++++++++++++++ ...meTimelineViewController+DebugAction.swift | 6 +++++ .../HomeTimelineViewController.swift | 16 ++++++++++++ Mastodon/Service/StatusPublishService.swift | 2 +- Mastodon/Supporting Files/AppDelegate.swift | 5 ++++ 7 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 Mastodon/Preference/StoreReviewPreference.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index a2a357c8..5e23b578 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -321,6 +321,7 @@ DB66729C25F9F91F00D60309 /* ComposeStatusItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB66729B25F9F91F00D60309 /* ComposeStatusItem.swift */; }; DB67D08427312970006A36CF /* APIService+Following.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB67D08327312970006A36CF /* APIService+Following.swift */; }; DB67D08627312E67006A36CF /* WizardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB67D08527312E67006A36CF /* WizardViewController.swift */; }; + DB67D089273256D7006A36CF /* StoreReviewPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB67D088273256D7006A36CF /* StoreReviewPreference.swift */; }; DB68045B2636DC6A00430867 /* MastodonNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB68045A2636DC6A00430867 /* MastodonNotification.swift */; }; DB6804662636DC9000430867 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D939AB425EDD8A90076FA61 /* String.swift */; }; DB68046C2636DC9E00430867 /* MastodonNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB68045A2636DC6A00430867 /* MastodonNotification.swift */; }; @@ -1141,6 +1142,7 @@ DB66729B25F9F91F00D60309 /* ComposeStatusItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusItem.swift; sourceTree = ""; }; DB67D08327312970006A36CF /* APIService+Following.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Following.swift"; sourceTree = ""; }; DB67D08527312E67006A36CF /* WizardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardViewController.swift; sourceTree = ""; }; + DB67D088273256D7006A36CF /* StoreReviewPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreReviewPreference.swift; sourceTree = ""; }; DB68045A2636DC6A00430867 /* MastodonNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonNotification.swift; sourceTree = ""; }; DB68047F2637CD4C00430867 /* AppShared.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppShared.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DB6804812637CD4C00430867 /* AppShared.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppShared.h; sourceTree = ""; }; @@ -2447,6 +2449,7 @@ DB1D842F26566512000346B3 /* KeyboardPreference.swift */, DBCBCC0C2680B908000F5B51 /* HomeTimelinePreference.swift */, DBD376AB2692ECDB007FEC24 /* ThemePreference.swift */, + DB67D088273256D7006A36CF /* StoreReviewPreference.swift */, ); path = Preference; sourceTree = ""; @@ -4101,6 +4104,7 @@ DBE3CE01261D623D00430CC6 /* FavoriteViewModel+State.swift in Sources */, 2D82BA0525E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift in Sources */, 2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */, + DB67D089273256D7006A36CF /* StoreReviewPreference.swift in Sources */, DB5B7295273112B100081888 /* FollowingListViewController.swift in Sources */, 0F202201261326E6000C64BF /* HashtagTimelineViewModel.swift in Sources */, DB6D9F9726367249008423CD /* SettingsViewController.swift in Sources */, diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index fce31178..e6093a21 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ AppShared.xcscheme_^#shared#^_ orderHint - 44 + 35 CoreDataStack.xcscheme_^#shared#^_ orderHint - 43 + 38 Mastodon - ASDK.xcscheme_^#shared#^_ @@ -97,7 +97,7 @@ MastodonIntent.xcscheme_^#shared#^_ orderHint - 41 + 36 MastodonIntents.xcscheme_^#shared#^_ @@ -117,7 +117,7 @@ ShareActionExtension.xcscheme_^#shared#^_ orderHint - 42 + 37 SuppressBuildableAutocreation diff --git a/Mastodon/Preference/StoreReviewPreference.swift b/Mastodon/Preference/StoreReviewPreference.swift new file mode 100644 index 00000000..e3a403f6 --- /dev/null +++ b/Mastodon/Preference/StoreReviewPreference.swift @@ -0,0 +1,26 @@ +// +// StoreReviewPreference.swift +// Mastodon +// +// Created by Cirno MainasuK on 2021-11-3. +// + +import Foundation + +extension UserDefaults { + + @objc dynamic var processCompletedCount: Int { + get { + return integer(forKey: #function) + } + set { self[#function] = newValue } + } + + @objc dynamic var lastVersionPromptedForReview: String? { + get { + return string(forKey: #function) + } + set { self[#function] = newValue } + } + +} diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift index 6d79d060..6e75a17e 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift @@ -15,6 +15,7 @@ import FLEX import SwiftUI import MastodonUI import MastodonSDK +import StoreKit extension HomeTimelineViewController { var debugMenu: UIMenu { @@ -77,6 +78,11 @@ extension HomeTimelineViewController { guard let self = self else { return } self.showThreadAction(action) }, + UIAction(title: "Store Rating", image: UIImage(systemName: "star.fill"), attributes: []) { [weak self] action in + guard let self = self else { return } + guard let windowScene = self.view.window?.windowScene else { return } + SKStoreReviewController.requestReview(in: windowScene) + }, ] ) } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 6b547688..62695f21 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -14,6 +14,7 @@ import CoreDataStack import GameplayKit import MastodonSDK import AlamofireImage +import StoreKit final class HomeTimelineViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { @@ -144,6 +145,21 @@ extension HomeTimelineViewController { } .store(in: &disposeBag) + viewModel.homeTimelineNavigationBarTitleViewModel.state + .removeDuplicates() + .filter { $0 == .publishedButton } + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + guard let self = self else { return } + guard UserDefaults.shared.lastVersionPromptedForReview == nil else { return } + guard UserDefaults.shared.processCompletedCount > 3 else { return } + guard let windowScene = self.view.window?.windowScene else { return } + let version = UIApplication.appVersion() + UserDefaults.shared.lastVersionPromptedForReview = version + SKStoreReviewController.requestReview(in: windowScene) + } + .store(in: &disposeBag) + tableView.refreshControl = refreshControl refreshControl.addTarget(self, action: #selector(HomeTimelineViewController.refreshControlValueChanged(_:)), for: .valueChanged) diff --git a/Mastodon/Service/StatusPublishService.swift b/Mastodon/Service/StatusPublishService.swift index ed894f93..f5c4cb2d 100644 --- a/Mastodon/Service/StatusPublishService.swift +++ b/Mastodon/Service/StatusPublishService.swift @@ -12,6 +12,7 @@ import Combine import CoreData import CoreDataStack import MastodonSDK +import UIKit final class StatusPublishService { @@ -72,7 +73,6 @@ extension StatusPublishService { self.viewModels.value = viewModels os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: composeViewModel removed", ((#file as NSString).lastPathComponent), #line, #function) - } } diff --git a/Mastodon/Supporting Files/AppDelegate.swift b/Mastodon/Supporting Files/AppDelegate.swift index 87d16241..e2cb7c41 100644 --- a/Mastodon/Supporting Files/AppDelegate.swift +++ b/Mastodon/Supporting Files/AppDelegate.swift @@ -36,6 +36,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { UNUserNotificationCenter.current().delegate = self application.registerForRemoteNotifications() + // increase app process count + var count = UserDefaults.shared.processCompletedCount + count += 1 // Int64. could ignore overflow here + UserDefaults.shared.processCompletedCount = count + #if ASDK && DEBUG // PerformanceMonitor.shared().start() // ASDisplayNode.shouldShowRangeDebugOverlay = true