Commit 5eca46cbe680b989832cb52a7a99c866f3d3ede1

Authored by Artem Talko
1 parent 471c93e5

subscription changes + fixed tab openning

added subscription expiration handling. fixed creating snapshot of webpage
Showing 84 changed files with 248 additions and 174 deletions
No preview for this file type
... ... @@ -36,6 +36,7 @@
36 36 194206C52B10D267000C1263 /* ProductList.plist in Resources */ = {isa = PBXBuildFile; fileRef = 194206C42B10D267000C1263 /* ProductList.plist */; };
37 37 194206C82B10DFC6000C1263 /* RemoveAdvertTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 194206C72B10DFC6000C1263 /* RemoveAdvertTableViewCell.swift */; };
38 38 194635D62ADD738E00993D91 /* HistoryDataBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 194635D52ADD738E00993D91 /* HistoryDataBase.swift */; };
  39 + 1946D8792B178A9F00B5A735 /* SubscriptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1946D8782B178A9F00B5A735 /* SubscriptionsModel.swift */; };
39 40 19696AF52AE80DBD00D1F8F9 /* blockerList.json in Resources */ = {isa = PBXBuildFile; fileRef = 19696AF42AE80DBD00D1F8F9 /* blockerList.json */; };
40 41 19696AF72AE80DBD00D1F8F9 /* ContentBlockerRequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19696AF62AE80DBD00D1F8F9 /* ContentBlockerRequestHandler.swift */; };
41 42 19696AFB2AE80DBD00D1F8F9 /* AdBlocker.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 19696AF22AE80DBC00D1F8F9 /* AdBlocker.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
... ... @@ -44,7 +45,7 @@
44 45 1975347B2B109A37000818D3 /* SubscriptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1975347A2B109A37000818D3 /* SubscriptionTableViewCell.swift */; };
45 46 197C2A242B0E3A7B0010B386 /* AdBlockButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A232B0E3A7B0010B386 /* AdBlockButton.swift */; };
46 47 197C2A282B0F65840010B386 /* OpenBrowserHomeTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */; };
47   - 197C2A2D2B0F9EEB0010B386 /* StoreKitManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A2C2B0F9EEB0010B386 /* StoreKitManager.swift */; };
  48 + 197C2A2D2B0F9EEB0010B386 /* SubscriptionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */; };
48 49 197FC3EF2AC21E1F007F429C /* PayloadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */; };
49 50 197FC3F22AC2AF9A007F429C /* AdvantagesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197FC3F12AC2AF9A007F429C /* AdvantagesTableViewCell.swift */; };
50 51 197FC3F42AC2BCD7007F429C /* SearchBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197FC3F32AC2BCD7007F429C /* SearchBarView.swift */; };
... ... @@ -137,6 +138,7 @@
137 138 194206C42B10D267000C1263 /* ProductList.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = ProductList.plist; sourceTree = "<group>"; };
138 139 194206C72B10DFC6000C1263 /* RemoveAdvertTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAdvertTableViewCell.swift; sourceTree = "<group>"; };
139 140 194635D52ADD738E00993D91 /* HistoryDataBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryDataBase.swift; sourceTree = "<group>"; };
  141 + 1946D8782B178A9F00B5A735 /* SubscriptionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsModel.swift; sourceTree = "<group>"; };
140 142 19696AF22AE80DBC00D1F8F9 /* AdBlocker.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = AdBlocker.appex; sourceTree = BUILT_PRODUCTS_DIR; };
141 143 19696AF42AE80DBD00D1F8F9 /* blockerList.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = blockerList.json; sourceTree = "<group>"; };
142 144 19696AF62AE80DBD00D1F8F9 /* ContentBlockerRequestHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentBlockerRequestHandler.swift; sourceTree = "<group>"; };
... ... @@ -146,7 +148,7 @@
146 148 1975347A2B109A37000818D3 /* SubscriptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionTableViewCell.swift; sourceTree = "<group>"; };
147 149 197C2A232B0E3A7B0010B386 /* AdBlockButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdBlockButton.swift; sourceTree = "<group>"; };
148 150 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenBrowserHomeTransition.swift; sourceTree = "<group>"; };
149   - 197C2A2C2B0F9EEB0010B386 /* StoreKitManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreKitManager.swift; sourceTree = "<group>"; };
  151 + 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionManager.swift; sourceTree = "<group>"; };
150 152 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadViewController.swift; sourceTree = "<group>"; };
151 153 197FC3F12AC2AF9A007F429C /* AdvantagesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvantagesTableViewCell.swift; sourceTree = "<group>"; };
152 154 197FC3F32AC2BCD7007F429C /* SearchBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarView.swift; sourceTree = "<group>"; };
... ... @@ -238,7 +240,7 @@
238 240 190DB9FD2AC459CD000A7BF3 /* Managers */ = {
239 241 isa = PBXGroup;
240 242 children = (
241   - 197C2A2C2B0F9EEB0010B386 /* StoreKitManager.swift */,
  243 + 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */,
242 244 190DB9FF2AC45A3C000A7BF3 /* CachingManager.swift */,
243 245 193B3B892ACAF714002161ED /* TabManager.swift */,
244 246 1907D6962ADE766F00C40E9F /* HistoryDBManager.swift */,
... ... @@ -634,6 +636,7 @@
634 636 children = (
635 637 19B739752AE276360073AA59 /* HistoryElement.swift */,
636 638 1926E82E2B03BED200FEBCFB /* HistoryToolbarMenuCases.swift */,
  639 + 1946D8782B178A9F00B5A735 /* SubscriptionsModel.swift */,
637 640 );
638 641 path = Models;
639 642 sourceTree = "<group>";
... ... @@ -695,6 +698,12 @@
695 698 19F65A722ACBFD7300B50F61 /* Common */ = {
696 699 isa = PBXGroup;
697 700 children = (
  701 + 19B739742AE275FF0073AA59 /* Models */,
  702 + 199DB1EC2AD3FCE1007E6A81 /* Services */,
  703 + 190DB9FD2AC459CD000A7BF3 /* Managers */,
  704 + 19F65A712ACBFCB500B50F61 /* Resources */,
  705 + 193B3B812ACAF36C002161ED /* DataBases */,
  706 + 190DBA012AC45CDA000A7BF3 /* Extentions */,
698 707 19F65A732ACBFDD100B50F61 /* Transitions */,
699 708 );
700 709 path = Common;
... ... @@ -732,15 +741,9 @@
732 741 19FCBF202AC1727800F83A7F /* browser */ = {
733 742 isa = PBXGroup;
734 743 children = (
735   - 19B739742AE275FF0073AA59 /* Models */,
736 744 19FCBF382AC17A4800F83A7F /* Modules */,
737   - 199DB1EC2AD3FCE1007E6A81 /* Services */,
738   - 19F65A722ACBFD7300B50F61 /* Common */,
739   - 190DBA012AC45CDA000A7BF3 /* Extentions */,
740   - 193B3B812ACAF36C002161ED /* DataBases */,
741   - 19F65A712ACBFCB500B50F61 /* Resources */,
742   - 190DB9FD2AC459CD000A7BF3 /* Managers */,
743 745 19FCBF352AC1779800F83A7F /* Navigation */,
  746 + 19F65A722ACBFD7300B50F61 /* Common */,
744 747 19FCBF212AC1727800F83A7F /* AppDelegate.swift */,
745 748 19FCBF2F2AC1727900F83A7F /* Info.plist */,
746 749 194206C42B10D267000C1263 /* ProductList.plist */,
... ... @@ -948,7 +951,7 @@
948 951 197FC4032AC41EB7007F429C /* ToolbarView.swift in Sources */,
949 952 19B7396A2AE1554E0073AA59 /* URLConstants.swift in Sources */,
950 953 197534782B1096A7000818D3 /* SubscriptionView.swift in Sources */,
951   - 197C2A2D2B0F9EEB0010B386 /* StoreKitManager.swift in Sources */,
  954 + 197C2A2D2B0F9EEB0010B386 /* SubscriptionManager.swift in Sources */,
952 955 19EECA472ACED48000094AFB /* SearchResultViewController.swift in Sources */,
953 956 191BB8572AC5B4AC00A2DEB9 /* OpenedTabsCollectionViewCell.swift in Sources */,
954 957 190DB9FC2AC450F6000A7BF3 /* RemoveAdvertViewController.swift in Sources */,
... ... @@ -986,6 +989,7 @@
986 989 197FC3F92AC2FB69007F429C /* SettingViewController.swift in Sources */,
987 990 1984BF5A2AFB973C0050F816 /* TermsView.swift in Sources */,
988 991 197FC3FC2AC2FBA0007F429C /* SettingView.swift in Sources */,
  992 + 1946D8792B178A9F00B5A735 /* SubscriptionsModel.swift in Sources */,
989 993 191BB8622AC6A01500A2DEB9 /* SearchingViewController.swift in Sources */,
990 994 1975347B2B109A37000818D3 /* SubscriptionTableViewCell.swift in Sources */,
991 995 197FC4012AC31D5C007F429C /* NavigationViewController.swift in Sources */,
... ...
No preview for this file type
... ... @@ -9,7 +9,6 @@ import UIKit
9 9 window = UIWindow(frame: screenRect)
10 10
11 11 if let window = window {
12   - let notification = NotificationManager()
13 12 let navigationViewController = NavigationViewController()
14 13 window.rootViewController = navigationViewController
15 14 window.makeKeyAndVisible()
... ...
... ... @@ -11,19 +11,30 @@ final class CachingManager {
11 11 private enum Keys {
12 12 static let isFirstAppLoad = "IsFirstAppLoad"
13 13 static let isAdBlocking = "IsAdBlocking"
  14 + static let expirationDate = "ExpirationDate"
14 15 }
15 16
16   - private init() {}
17   -
18 17 static let shared = CachingManager()
19 18 private let userDefaults = UserDefaults.standard
20 19
  20 + private init() {}
  21 +
21 22 var isFirstAppLoad: Bool {
22 23 get { return userDefaults.bool(forKey: Keys.isFirstAppLoad) }
23 24 set { userDefaults.set(newValue, forKey: Keys.isFirstAppLoad) }
24 25 }
25   - var isAdBlocking: Bool {
  26 + var adBlockerState: Bool {
26 27 get { return userDefaults.bool(forKey: Keys.isAdBlocking) }
27 28 set { userDefaults.set(newValue, forKey: Keys.isAdBlocking) }
28 29 }
  30 + var expirationDate: Double? {
  31 + get {
  32 + if userDefaults.object(forKey: Keys.expirationDate) == nil {
  33 + return nil
  34 + }
  35 +
  36 + return userDefaults.double(forKey: Keys.expirationDate)
  37 + }
  38 + set { userDefaults.set(newValue, forKey: Keys.expirationDate) }
  39 + }
29 40 }
... ...
... ... @@ -6,10 +6,20 @@
6 6 //
7 7
8 8 import Foundation
  9 +import UIKit
9 10
10 11
11 12 final class DateManager {
12 13 static let shared = DateManager()
  14 +
  15 + let currentDate = Date()
  16 + let currentTimestamp = Date().timeIntervalSince1970
  17 +
  18 + var dateFormatter: DateFormatter{
  19 + let obj = DateFormatter()
  20 + obj.dateFormat = "EEEE, d MMM"
  21 + return obj
  22 + }
13 23
14 24 private init() {}
15 25
... ... @@ -19,15 +29,20 @@ final class DateManager {
19 29 return timeFormatter.string(from: date ?? Date())
20 30 }
21 31
22   - var dateFormatter: DateFormatter{
23   - let obj = DateFormatter()
24   - obj.dateFormat = "EEEE, d MMM"
25   - return obj
26   - }
27   -
28   - var currentDate: Date {
29   - let obj = Date()
30   - return obj
  32 + func getSubscriptionExpirationDate() {
  33 + guard CachingManager.shared.expirationDate != nil else {
  34 + Task {
  35 + if let activeSubscription = SubscriptionManager.shared.purchasedSubscriptions.first {
  36 + switch await activeSubscription.latestTransaction {
  37 + case .verified(let transaction):
  38 + CachingManager.shared.expirationDate = transaction.expirationDate?.timeIntervalSince1970
  39 + default:
  40 + return
  41 + }
  42 + }
  43 + }
  44 + return
  45 + }
31 46 }
32 47 }
33 48
... ...
... ... @@ -12,31 +12,23 @@ fileprivate enum StoreError: Error {
12 12 case failedVerification
13 13 }
14 14
15   -final class StoreKitManager: ObservableObject {
16   - @Published
17   - var storeProducts: [Product] = []
18   - @Published
19   - var purchasedSubscriptions : [Product] = []
  15 +final class SubscriptionManager: ObservableObject {
  16 + static let shared = SubscriptionManager()
20 17
21   - private var updateListenerTask: Task<Void, Error>? = nil
  18 + @Published var storeProducts: [Product] = []
  19 + @Published var purchasedSubscriptions : [Product] = []
22 20
  21 + private var updateListenerTask: Task<Void, Error>? = nil
23 22 private let productDict: [String : String]
24 23
25 24 init() {
26   - if let plistPath = Bundle.main.path(forResource: "ProductList", ofType: "plist"),
27   - let plist = FileManager.default.contents(atPath: plistPath) {
28   - productDict = (try? PropertyListSerialization.propertyList(from: plist, format: nil) as? [String : String]) ?? [:]
29   - } else {
30   - productDict = [:]
31   - }
  25 + productDict = SubscriptionsModel.subscriptionInfo
32 26 updateListenerTask = listenForTransactions()
33 27
34 28 Task {
35 29 await requestProducts()
36 30 await updateCustomerProductStatus()
37 31 }
38   -
39   - print("controller called")
40 32 }
41 33
42 34 deinit {
... ... @@ -57,7 +49,6 @@ final class StoreKitManager: ObservableObject {
57 49 }
58 50 }
59 51
60   - @MainActor
61 52 func requestProducts() async {
62 53 do {
63 54 storeProducts = try await Product.products(for: productDict.values)
... ... @@ -113,4 +104,8 @@ final class StoreKitManager: ObservableObject {
113 104 func isPurchased(_ product: Product) async throws -> Bool {
114 105 return purchasedSubscriptions.contains(product)
115 106 }
  107 +
  108 + func restorePurchase() async throws {
  109 + try await AppStore.sync()
  110 + }
116 111 }
... ...
  1 +//
  2 +// SubscriptionsModel.swift
  3 +// Pro-Seecurity-VPN
  4 +//
  5 +// Created by Artem Talko on 29.11.2023.
  6 +//
  7 +
  8 +import Foundation
  9 +
  10 +struct SubscriptionsModel {
  11 + static var subscriptionInfo: [String: String] {
  12 + return ["adBlocker": "com.browser.adblocker"]
  13 + }
  14 +}
... ...
... ... @@ -21,15 +21,4 @@ final class SnapshotService {
21 21 }
22 22 return siteSnapshotImage
23 23 }
24   -
25   - func makeWKWebViewSnapshot(_ wkWV: WKWebView?, completion: @escaping (UIImage?) -> Void) {
26   - wkWV?.takeSnapshot(with: snapshotConfiguration) { (image, error) in
27   - if let snaphotIMG = image {
28   - completion(snaphotIMG)
29   - } else if let error = error {
30   - print(error)
31   - completion(nil)
32   - }
33   - }
34   - }
35 24 }
... ...
... ... @@ -24,6 +24,16 @@ final class HistoryViewController: UIViewController {
24 24 }
25 25 }
26 26
  27 + init() {
  28 + super.init(nibName: nil, bundle: nil)
  29 +
  30 + historyData = HistoryDBManager.shared.getHistoryDataForTableView()
  31 + }
  32 +
  33 + required init?(coder: NSCoder) {
  34 + fatalError("init(coder:) has not been implemented")
  35 + }
  36 +
27 37 override func viewWillAppear(_ animated: Bool) {
28 38 super.viewWillAppear(animated)
29 39
... ... @@ -52,16 +62,6 @@ final class HistoryViewController: UIViewController {
52 62 navigationController?.isNavigationBarHidden = false
53 63 navigationItem.title = "History"
54 64 }
55   -
56   - init() {
57   - super.init(nibName: nil, bundle: nil)
58   -
59   - historyData = HistoryDBManager.shared.getHistoryDataForTableView()
60   - }
61   -
62   - required init?(coder: NSCoder) {
63   - fatalError("init(coder:) has not been implemented")
64   - }
65 65 }
66 66
67 67 //MARK: - TableView Extention
... ...
... ... @@ -30,6 +30,21 @@ final class BrowserHomeViewController: UIViewController {
30 30 }
31 31 }
32 32
  33 + init(url: String?, currentTabId: Int?) {
  34 + searchResultViewController = SearchResultViewController(searchLink: String())
  35 + searchingViewController = SearchingViewController(dataForReq: [])
  36 + subscriptions = []
  37 + searchRequestURL = URLConstants.googleURL
  38 +
  39 + super.init(nibName: nil, bundle: nil)
  40 + self.url = url
  41 + self.currentTabId = currentTabId
  42 + }
  43 +
  44 + required init?(coder: NSCoder) {
  45 + fatalError("init(coder:) has not been implemented")
  46 + }
  47 +
33 48 override func viewDidLoad() {
34 49 super.viewDidLoad()
35 50 view.backgroundColor = ColorConstants.lightGray
... ... @@ -58,21 +73,6 @@ final class BrowserHomeViewController: UIViewController {
58 73 view = mainView
59 74 }
60 75
61   - init(url: String?, currentTabId: Int?) {
62   - searchResultViewController = SearchResultViewController(searchLink: String())
63   - searchingViewController = SearchingViewController(dataForReq: [])
64   - subscriptions = []
65   - searchRequestURL = URLConstants.googleURL
66   -
67   - super.init(nibName: nil, bundle: nil)
68   - self.url = url
69   - self.currentTabId = currentTabId
70   - }
71   -
72   - required init?(coder: NSCoder) {
73   - fatalError("init(coder:) has not been implemented")
74   - }
75   -
76 76 override func viewWillDisappear(_ animated: Bool) {
77 77 super.viewWillDisappear(animated)
78 78 NotificationCenter.default.removeObserver(self)
... ... @@ -189,8 +189,6 @@ extension BrowserHomeViewController {
189 189 return (controllers.first(where: { $0 is TabsViewController }) as? TabsViewController)
190 190 }
191 191
192   -
193   -
194 192 private func didTabButtonTapped(type: ToolbarElementType) {
195 193 switch type {
196 194 case .history:
... ...
... ... @@ -21,6 +21,7 @@ final class BrowserHomeView: GradientView {
21 21
22 22 return obj
23 23 }()
  24 +
24 25 let settingButton: UIButton = {
25 26 let obj = UIButton()
26 27 obj.setImage(UIImage(named: "Settings")?.withTintColor(.systemBlue), for: .normal)
... ...
... ... @@ -11,8 +11,19 @@ final class PayloadViewController: UIViewController {
11 11 private let mainView = PayloadView()
12 12 private let payloadTableViewData: [String]
13 13
  14 + init(){
  15 + payloadTableViewData = StringConstants.payloadViewControllerData
  16 +
  17 + super.init(nibName: nil, bundle: nil)
  18 + }
  19 +
  20 + required init?(coder: NSCoder) {
  21 + fatalError("init(coder:) has not been implemented")
  22 + }
  23 +
14 24 override func viewDidLoad() {
15 25 super.viewDidLoad()
  26 +
16 27 initViewController()
17 28 }
18 29
... ... @@ -27,16 +38,6 @@ final class PayloadViewController: UIViewController {
27 38 view = mainView
28 39 }
29 40
30   - init(){
31   - payloadTableViewData = StringConstants.payloadViewControllerData
32   -
33   - super.init(nibName: nil, bundle: nil)
34   - }
35   -
36   - required init?(coder: NSCoder) {
37   - fatalError("init(coder:) has not been implemented")
38   - }
39   -
40 41 override func viewWillDisappear(_ animated: Bool) {
41 42 super.viewWillDisappear(animated)
42 43
... ...
... ... @@ -10,23 +10,14 @@ import UIKit
10 10 final class RemoveAdvertViewController: UIViewController {
11 11 private let mainView = RemoveAdvertView()
12 12
13   - private let tableViewData = StringConstants.tableViewData
14   -
15   - var storeKit: StoreKitManager
  13 + private let notification: NotificationManager
  14 + private var storeKit: SubscriptionManager
16 15
17   - override func viewDidLoad() {
18   - super.viewDidLoad()
19   -
20   - initViewController()
21   - }
  16 + private let tableViewData = StringConstants.tableViewData
22 17
23   - private func initViewController() {
24   - addTargets()
25   - setupTableView()
26   - }
27   -
28 18 init() {
29   - self.storeKit = StoreKitManager()
  19 + storeKit = SubscriptionManager()
  20 + notification = NotificationManager()
30 21
31 22 super.init(nibName: nil, bundle: nil)
32 23 }
... ... @@ -35,16 +26,32 @@ final class RemoveAdvertViewController: UIViewController {
35 26 fatalError("init(coder:) has not been implemented")
36 27 }
37 28
  29 + override func viewDidLoad() {
  30 + super.viewDidLoad()
  31 +
  32 + initViewController()
  33 + }
  34 +
38 35 override func loadView() {
39 36 view = mainView
40 37 }
  38 +
  39 + private func initViewController() {
  40 + addTargets()
  41 + setupTableView()
  42 + }
41 43 }
42 44
43 45 //MARK: - Action
44 46 extension RemoveAdvertViewController {
45 47 @objc
46 48 private func adBlockerButtonPressed(_ sender: UIButton) {
47   - viewAdBlockingHandler()
  49 + if CachingManager.shared.adBlockerState {
  50 + turnOffAdBlocker()
  51 + } else {
  52 + subscriptionHandler()
  53 + }
  54 +
48 55 }
49 56
50 57 @objc
... ... @@ -58,6 +65,50 @@ extension RemoveAdvertViewController {
58 65
59 66 //MARK: Helpers
60 67 extension RemoveAdvertViewController {
  68 + private func subscriptionHandler() {
  69 + if storeKit.purchasedSubscriptions.isEmpty {
  70 + Task {
  71 + try? await storeKit.restorePurchase()
  72 +
  73 + if storeKit.purchasedSubscriptions.isEmpty {
  74 + presentSubscriptionHandler()
  75 + } else {
  76 + if let restoreDate = CachingManager.shared.expirationDate {
  77 + if Date().timeIntervalSince1970 < restoreDate {
  78 + turnOnAdBlocker()
  79 + } else {
  80 + presentSubscriptionHandler()
  81 + }
  82 + } else {
  83 + DateManager.shared.getSubscriptionExpirationDate()
  84 + let restoreDate = CachingManager.shared.expirationDate
  85 + if Date().timeIntervalSince1970 < restoreDate ?? 0 {
  86 + turnOnAdBlocker()
  87 + } else {
  88 + presentSubscriptionHandler()
  89 + }
  90 + }
  91 + }
  92 + }
  93 + } else {
  94 + if let restoreDate = CachingManager.shared.expirationDate {
  95 + if Date().timeIntervalSince1970 < restoreDate {
  96 + turnOnAdBlocker()
  97 + } else {
  98 + presentSubscriptionHandler()
  99 + }
  100 + } else {
  101 + DateManager.shared.getSubscriptionExpirationDate()
  102 + let restoreDate = CachingManager.shared.expirationDate
  103 + if Date().timeIntervalSince1970 < restoreDate ?? 0 {
  104 + turnOnAdBlocker()
  105 + } else {
  106 + presentSubscriptionHandler()
  107 + }
  108 + }
  109 + }
  110 + }
  111 +
61 112 private func addTargets() {
62 113 mainView.adBlockButton.addTarget(self, action: #selector(adBlockerButtonPressed(_ :)), for: .touchUpInside)
63 114
... ... @@ -65,13 +116,19 @@ extension RemoveAdvertViewController {
65 116 }
66 117
67 118 private func presentSubscriptionHandler() {
68   - if(storeKit.purchasedSubscriptions.isEmpty) {
69   - let subcriptionViewController = SubscriptionViewController()
  119 + let subcriptionViewController = SubscriptionViewController(storeKit: storeKit, complition: testHandler)
70 120 subcriptionViewController.modalPresentationStyle = .fullScreen
71 121 subcriptionViewController.modalTransitionStyle = .crossDissolve
72 122
73 123 present(subcriptionViewController, animated: true)
74   - }
  124 + }
  125 +
  126 + private func testHandler() {
  127 + let alert = UIAlertController(title: "Congradulations!", message: "Success by subscription", preferredStyle: .alert)
  128 + let okAction = UIAlertAction(title: "OK", style: .default)
  129 + alert.addAction(okAction)
  130 + present(alert, animated: true)
  131 + turnOnAdBlocker()
75 132 }
76 133
77 134 private func setupTableView() {
... ... @@ -79,33 +136,21 @@ extension RemoveAdvertViewController {
79 136 mainView.adBlockTableView.delegate = self
80 137 mainView.adBlockTableView.register(RemoveAdvertTableViewCell.self, forCellReuseIdentifier: RemoveAdvertTableViewCell.cellID)
81 138 }
82   -
83   - func successfullPurchaseHandler() {
84   - self.mainView.adBlockButton.buttonImageView.image = .adBlockOnState
85   - self.mainView.tapActionLabel.textColor = ColorConstants.SearchbarTintBlue
86   - self.mainView.tapActionLabel.text = StringConstants.turnOff
  139 +
  140 + private func turnOnAdBlocker() {
  141 + mainView.adBlockButton.buttonImageView.image = .adBlockOnState
  142 + mainView.tapActionLabel.textColor = ColorConstants.SearchbarTintBlue
  143 + mainView.tapActionLabel.text = StringConstants.turnOff
87 144
88   - CachingManager.shared.isAdBlocking = true
  145 + CachingManager.shared.adBlockerState = true
89 146 }
90 147
91   - func viewAdBlockingHandler() {
92   - if CachingManager.shared.isAdBlocking {
93   - mainView.adBlockButton.buttonImageView.image = .adBlockOffState
94   - mainView.tapActionLabel.textColor = ColorConstants.customPink
95   - mainView.tapActionLabel.text = StringConstants.turnOn
96   -
97   - CachingManager.shared.isAdBlocking = false
98   - } else {
99   - if !storeKit.purchasedSubscriptions.isEmpty {
100   - mainView.adBlockButton.buttonImageView.image = .adBlockOnState
101   - mainView.tapActionLabel.textColor = ColorConstants.SearchbarTintBlue
102   - mainView.tapActionLabel.text = StringConstants.turnOff
103   -
104   - CachingManager.shared.isAdBlocking = true
105   - } else {
106   - presentSubscriptionHandler()
107   - }
108   - }
  148 + private func turnOffAdBlocker() {
  149 + mainView.adBlockButton.buttonImageView.image = .adBlockOffState
  150 + mainView.tapActionLabel.textColor = ColorConstants.customPink
  151 + mainView.tapActionLabel.text = StringConstants.turnOn
  152 +
  153 + CachingManager.shared.adBlockerState = false
109 154 }
110 155 }
111 156
... ... @@ -121,7 +166,7 @@ extension RemoveAdvertViewController: UITableViewDelegate, UITableViewDataSource
121 166 return UITableViewCell()
122 167 }
123 168 cell.advantagesCellLabel.text = tableViewData[indexPath.row]
124   -
  169 +
125 170 return cell
126 171 }
127 172 }
... ...
... ... @@ -10,7 +10,7 @@ import UIKit
10 10 final class AdBlockButton: UIButton {
11 11 var buttonImageView: UIImageView = {
12 12 let obj = UIImageView()
13   - let userDefaultsAdBlockingValue = CachingManager.shared.isAdBlocking
  13 + let userDefaultsAdBlockingValue = CachingManager.shared.adBlockerState
14 14
15 15 if userDefaultsAdBlockingValue {
16 16 obj.image = .adBlockOnState
... ...
... ... @@ -53,11 +53,10 @@ final class RemoveAdvertView: GradientView {
53 53
54 54 let tapActionLabel: UILabel = {
55 55 let obj = UILabel()
56   - let userDefaultsAdBlockerValue = CachingManager.shared.isAdBlocking
  56 + let userDefaultsAdBlockerValue = CachingManager.shared.adBlockerState
57 57
58 58 obj.text = StringConstants.turnOn
59 59 obj.font = FontConstants.semiboldFont_24
60   - //ok
61 60 if userDefaultsAdBlockerValue {
62 61 obj.textColor = ColorConstants.SearchbarTintBlue
63 62 } else {
... ...
... ... @@ -45,6 +45,7 @@ final class SearchResultViewController: UIViewController {
45 45 }
46 46 }
47 47
  48 +//MARK: URL handling
48 49 extension SearchResultViewController {
49 50 private func urlChecker(_ url: String) {
50 51 let request = URLRequest(url: URL(string: url) ?? URL(fileURLWithPath: ""))
... ... @@ -56,7 +57,7 @@ extension SearchResultViewController {
56 57 //MARK: AdBlocker
57 58 extension SearchResultViewController {
58 59 private func setupAdBlocker() {
59   - let userDefaultsAdblockKey = CachingManager.shared.isAdBlocking
  60 + let userDefaultsAdblockKey = CachingManager.shared.adBlockerState
60 61 if userDefaultsAdblockKey {
61 62 WKContentRuleListStore.default().getAvailableContentRuleListIdentifiers { res in
62 63 if let url = Bundle.main.url(forResource: "blockerList", withExtension: "json"),
... ...
... ... @@ -28,12 +28,14 @@ final class SettingViewController: UIViewController {
28 28
29 29 override func viewDidLoad() {
30 30 super.viewDidLoad()
  31 +
31 32 view.backgroundColor = .white
32 33 initViewController()
33 34 }
34 35
35 36 private func initViewController() {
36 37 navigationController?.isNavigationBarHidden = false
  38 +
37 39 setupSettingTableView()
38 40 addTargets()
39 41 }
... ... @@ -104,7 +106,7 @@ extension SettingViewController {
104 106 setupMessage()
105 107 case 5:
106 108 Task {
107   - try? await AppStore.sync()
  109 + try? await SubscriptionManager.shared.restorePurchase()
108 110 }
109 111 default:
110 112 break
... ...
... ... @@ -10,19 +10,17 @@ import StoreKit
10 10
11 11
12 12 final class SubscriptionViewController: UIViewController {
  13 +
13 14 private let mainView = SubscriptionView()
14 15
15 16 private let tableViewData: [String]
16   -
17   -
18   - override func viewDidLoad() {
19   - super.viewDidLoad()
20   -
21   - initViewController()
22   - }
  17 + private let storeKitManager: SubscriptionManager
  18 + private let successCompletion: () -> Void
23 19
24   - init() {
25   - self.tableViewData = StringConstants.removeAdvertTableViewData
  20 + init(storeKit: SubscriptionManager, complition: @escaping() -> Void) {
  21 + tableViewData = StringConstants.removeAdvertTableViewData
  22 + storeKitManager = storeKit
  23 + successCompletion = complition
26 24
27 25 super.init(nibName: nil, bundle: nil)
28 26 }
... ... @@ -31,6 +29,12 @@ final class SubscriptionViewController: UIViewController {
31 29 fatalError("init(coder:) has not been implemented")
32 30 }
33 31
  32 + override func viewDidLoad() {
  33 + super.viewDidLoad()
  34 +
  35 + initViewController()
  36 + }
  37 +
34 38 override func loadView() {
35 39 view = mainView
36 40 }
... ... @@ -70,6 +74,17 @@ extension SubscriptionViewController {
70 74 mainView.advantagesTableView.delegate = self
71 75 mainView.advantagesTableView.register(SubscriptionTableViewCell.self, forCellReuseIdentifier: SubscriptionTableViewCell.cellID)
72 76 }
  77 +
  78 + @MainActor
  79 + private func buySubscription() async throws {
  80 + if let adblockerProduct = storeKitManager.storeProducts.first(where: { $0.id == SubscriptionsModel.subscriptionInfo["adBlocker"]}) {
  81 + if let transaction = try await storeKitManager.purchase(adblockerProduct) {
  82 + CachingManager.shared.expirationDate = transaction.expirationDate?.timeIntervalSince1970 ?? 0
  83 + dismiss(animated: true)
  84 + successCompletion()
  85 + }
  86 + }
  87 + }
73 88 }
74 89
75 90
... ... @@ -82,29 +97,14 @@ extension SubscriptionViewController {
82 97
83 98 @objc
84 99 private func buyAdblocker(_ sender: UIButton) {
85   - guard let navigationController = presentingViewController as? NavigationViewController else {
86   - return
87   - }
88   - for viewController in navigationController.viewControllers {
89   - guard let removeAdvertViewController = viewController as? RemoveAdvertViewController else {
90   - return
91   - }
92   - Task {
93   - do {
94   - if let adblockerProduct = removeAdvertViewController.storeKit.storeProducts.first(where: { $0.id == "com.browser.adblocker" }) {
95   - if (try await removeAdvertViewController.storeKit.purchase(adblockerProduct)) != nil {
96   - removeAdvertViewController.successfullPurchaseHandler()
97   -
98   - self.dismiss(animated: true)
99   - } else {
100   - print("Purchase cancelled or pending.")
101   - }
102   - } else {
103   - print("Adblocker product not found.")
104   - }
105   - } catch {
106   - print("Failed to purchase Adblocker: \(error)")
107   - }
  100 + Task {
  101 + do {
  102 + try await buySubscription()
  103 + } catch {
  104 + let alert = UIAlertController(title: "Fail!", message: "Error with subscription", preferredStyle: .alert)
  105 + let okAction = UIAlertAction(title: "OK", style: .default)
  106 + alert.addAction(okAction)
  107 + present(alert, animated: true)
108 108 }
109 109 }
110 110 }
... ...
... ... @@ -17,7 +17,7 @@ final class SubscriptionView: GradientView {
17 17 return obj
18 18 }()
19 19
20   - let shieldView: UIImageView = {
  20 + private let shieldView: UIImageView = {
21 21 let obj = UIImageView()
22 22 obj.image = .shield
23 23 obj.contentMode = .scaleAspectFit
... ... @@ -96,15 +96,16 @@ final class SubscriptionView: GradientView {
96 96 setup()
97 97 }
98 98
  99 + required init?(coder: NSCoder) {
  100 + fatalError("init(coder:) has not been implemented")
  101 + }
  102 +
99 103 override func layoutSubviews() {
100 104 super.layoutSubviews()
101 105
102 106 gradientLayer.frame = subscribeButton.bounds
103 107 }
104   -
105   - required init?(coder: NSCoder) {
106   - fatalError("init(coder:) has not been implemented")
107   - }
  108 +
108 109
109 110 private func setup() {
110 111 addSubview(closeButton)
... ...
... ... @@ -74,7 +74,6 @@ extension TabsViewController: UICollectionViewDataSource, UICollectionViewDelega
74 74
75 75 }
76 76
77   -
78 77 //MARK: - Action
79 78 extension TabsViewController {
80 79 private func didTabButtonTapped(type: HistoryToolbarElementType) {
... ...
... ... @@ -16,7 +16,6 @@ final class NavigationViewController: UINavigationController {
16 16 }
17 17
18 18 private func initViewController() {
19   - view.backgroundColor = .black
20 19 delegate = self
21 20
22 21 setStartControllers()
... ... @@ -28,6 +27,7 @@ extension NavigationViewController {
28 27 private func setStartControllers() {
29 28 let payloadViewController = PayloadViewController()
30 29 let removeAdvertViewController = RemoveAdvertViewController()
  30 +
31 31 let cachingManager = CachingManager.shared
32 32
33 33 if cachingManager.isFirstAppLoad == false {
... ...
Please register or login to post a comment