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