11import Combine
22import Foundation
33import os
4- import Toolbox
54
65/// A controller that handles all the ForceUpdate feature logic.
76public actor ForceUpdateController {
8- // MARK: Init
7+ // MARK: Interface
98
10- private init ( ) { }
9+ /// JSONDecoder used for decoding the App Store lookup result
10+ public let appStoreLookupDecoder : JSONDecoder
1111
12- // MARK: Properties
12+ /// JSONDecoder used for decoding the Public Version lookup result
13+ public let publicVersionLookupDecoder : JSONDecoder
1314
14- private var checkForUpdateTask : Task < Void , Never > ?
15- private nonisolated let onForceUpdateNeededSubject = PassthroughSubject < URL ? , Never > ( )
15+ /// Configures the timeout used for fetching App Store informations
16+ public let appStoreLookupTimeout : TimeInterval
1617
17- // MARK: Interface
18+ /// Configures the timeout used for fetching version info from configured version URL
19+ public let publicVersionLookupTimeout : TimeInterval
20+
21+ /// Configures the URL for fetching the public version JSON file hosted by you
22+ public let publicVersionURL : URL
23+
24+ /// Configures the URL for fetching the App Store information of your already published app.
25+ ///
26+ /// Defaults to `https://itunes.apple.com/lookup?bundleId=\(Bundle.main.bundleIdentifier)&country=at`
27+ public let appStoreLookupURL : URL
1828
19- /// Singleton
20- public static let shared = ForceUpdateController ( )
29+ public init (
30+ publicVersionURL: URL ,
31+ appStoreLookupURL: URL = URL (
32+ string: " https://itunes.apple.com/lookup?bundleId= \( Bundle . main. bundleIdentifier!) &country=at "
33+ ) !,
34+ appStoreLookupDecoder: JSONDecoder = Decoders . iso801,
35+ publicVersionLookupDecoder: JSONDecoder = Decoders . standardJSON,
36+ appStoreLookupTimeout: TimeInterval = 120.0 ,
37+ publicVersionLookupTimeout: TimeInterval = 120.0
38+ ) {
39+ self . publicVersionURL = publicVersionURL
40+ self . appStoreLookupURL = appStoreLookupURL
41+ self . appStoreLookupDecoder = appStoreLookupDecoder
42+ self . publicVersionLookupDecoder = publicVersionLookupDecoder
43+ self . appStoreLookupTimeout = appStoreLookupTimeout
44+ self . publicVersionLookupTimeout = publicVersionLookupTimeout
45+ }
2146
2247 /// AsyncSequence that emits a value if the force update screen should be displayed. Returns AppStore URL of the app.
2348 public private( set) nonisolated lazy var onForceUpdateNeededAsyncSequence = onForceUpdateNeededSubject. values
@@ -47,45 +72,6 @@ public actor ForceUpdateController {
4772 /// Returns the AppStore look up result, if available.
4873 public private( set) var appStoreLookUp : AppStoreLookUpResult ?
4974
50- /// JSONDecoder used for decoding the App Store lookup result
51- public var appStoreLookupDecoder : JSONDecoder = Decoders . iso801
52-
53- /// JSONDecoder used for decoding the Public Version lookup result
54- public var publicVersionLookupDecoder : JSONDecoder = Decoders . standardJSON
55-
56- /// Configures the timeout used for fetching App Store informations
57- public var appStoreLookupTimeout : TimeInterval = 120.0
58-
59- /// Configures the timeout used for fetching version info from configured version URL
60- public var publicVersionLookupTimeout : TimeInterval = 120.0
61-
62- /// Configures the URL for fetching the public version JSON file hosted by you
63- public var publicVersionURL : URL !
64-
65- /// Configures the URL for fetching the App Store information of your already published app.
66- ///
67- /// Defaults to `https://itunes.apple.com/lookup?bundleId=\(Bundle.main.bundleIdentifier)&country=at`
68- public var appStoreLookupURL : URL !
69-
70- /// Call this before using the `ForceUpdateController` to configure it.
71- public func configure(
72- publicVersionURL: URL ,
73- appStoreLookupURL: URL = URL (
74- string: " https://itunes.apple.com/lookup?bundleId= \( Bundle . main. bundleIdentifier!) &country=at "
75- ) !,
76- appStoreLookupDecoder: JSONDecoder ? = nil ,
77- publicVersionLookupDecoder: JSONDecoder ? = nil ,
78- appStoreLookupTimeout: TimeInterval = 120.0 ,
79- publicVersionLookupTimeout: TimeInterval = 120.0
80- ) {
81- self . publicVersionURL = publicVersionURL
82- self . appStoreLookupURL = appStoreLookupURL
83- self . appStoreLookupDecoder = appStoreLookupDecoder ?? Decoders . iso801
84- self . publicVersionLookupDecoder = publicVersionLookupDecoder ?? Decoders . standardJSON
85- self . appStoreLookupTimeout = appStoreLookupTimeout
86- self . publicVersionLookupTimeout = publicVersionLookupTimeout
87- }
88-
8975 /// Checks for updates. Thread-safe.
9076 /// Fetches current version from AppStore and from project version JSON.
9177 public func checkForUpdate( ) async {
@@ -103,7 +89,10 @@ public actor ForceUpdateController {
10389 return await checkForUpdateTask. value
10490 }
10591
106- // MARK: Helpers
92+ // MARK: Private
93+
94+ private var checkForUpdateTask : Task < Void , Never > ?
95+ private nonisolated let onForceUpdateNeededSubject = PassthroughSubject < URL ? , Never > ( )
10796
10897 private func internalCheckForUpdate( ) async {
10998 os_log ( . info, " checking for app update... " )
0 commit comments