diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 456e3835d..7b791e38e 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -635,7 +635,6 @@ C35E8AA82485C85800ACB629 /* GeoLite2-Country-Locations-English.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA52485C85400ACB629 /* GeoLite2-Country-Locations-English.csv */; }; C35E8AA92485C85800ACB629 /* GeoLite2-Country-Blocks-IPv4.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */; }; C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAD2485E51D00ACB629 /* IP2Country.swift */; }; - C35E8AB02485E86A00ACB629 /* GeneralUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAF2485E86A00ACB629 /* GeneralUtilities.swift */; }; C36B8707243C50C60049991D /* SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 453518921FC63DBF00210559 /* SignalMessaging.framework */; }; C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */; }; C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; }; @@ -1519,7 +1518,6 @@ C35E8AA52485C85400ACB629 /* GeoLite2-Country-Locations-English.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Locations-English.csv"; sourceTree = ""; }; C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Blocks-IPv4.csv"; sourceTree = ""; }; C35E8AAD2485E51D00ACB629 /* IP2Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IP2Country.swift; sourceTree = ""; }; - C35E8AAF2485E86A00ACB629 /* GeneralUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralUtilities.swift; sourceTree = ""; }; C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = ""; }; C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = ""; }; C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupSuggestionSheet.swift; sourceTree = ""; }; @@ -2910,7 +2908,6 @@ children = ( B8544E3223D50E4900299F14 /* AppearanceUtilities.swift */, C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */, - C35E8AAF2485E86A00ACB629 /* GeneralUtilities.swift */, C35E8AAD2485E51D00ACB629 /* IP2Country.swift */, B84664F4235022F30083A1CD /* MentionUtilities.swift */, B886B4A82398BA1500211ABE /* QRCode.swift */, @@ -4251,7 +4248,6 @@ 34D1F0831F8678AA0066283D /* ConversationInputTextView.m in Sources */, 340FC8B6204DAC8D007AEB0F /* OWSQRCodeScanningViewController.m in Sources */, 4CB5F26920F7D060004D1B42 /* MessageActions.swift in Sources */, - C35E8AB02485E86A00ACB629 /* GeneralUtilities.swift in Sources */, 340FC8B5204DAC8D007AEB0F /* AboutTableViewController.m in Sources */, 34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */, 340FC8B9204DAC8D007AEB0F /* UpdateGroupViewController.m in Sources */, diff --git a/Signal/src/Loki/Utilities/GeneralUtilities.swift b/Signal/src/Loki/Utilities/GeneralUtilities.swift deleted file mode 100644 index 777925584..000000000 --- a/Signal/src/Loki/Utilities/GeneralUtilities.swift +++ /dev/null @@ -1,3 +0,0 @@ - -@inline(never) -public func touch(_ x: Any?) { } diff --git a/Signal/src/Loki/Utilities/IP2Country.swift b/Signal/src/Loki/Utilities/IP2Country.swift index f715cee02..d187e25d3 100644 --- a/Signal/src/Loki/Utilities/IP2Country.swift +++ b/Signal/src/Loki/Utilities/IP2Country.swift @@ -2,16 +2,17 @@ import SwiftCSV final class IP2Country { - private let ipv4Table = try! CSV(name: "GeoLite2-Country-Blocks-IPv4", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)! - private let countryNamesTable = try! CSV(name: "GeoLite2-Country-Locations-English", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)! + private lazy var ipv4Table = try! CSV(name: "GeoLite2-Country-Blocks-IPv4", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)! + private lazy var countryNamesTable = try! CSV(name: "GeoLite2-Country-Locations-English", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)! var countryNamesCache: [String:String] = [:] + static var isInitialized = false + // MARK: Lifecycle static let shared = IP2Country() private init() { - populateCacheIfNeeded() - NotificationCenter.default.addObserver(self, selector: #selector(populateCacheIfNeeded), name: .pathsBuilt, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(populateCacheIfNeededAsync), name: .pathsBuilt, object: nil) } deinit { @@ -42,23 +43,29 @@ final class IP2Country { return getCountryInternal() } - @objc private func populateCacheIfNeeded() { + @objc func populateCacheIfNeededAsync() { DispatchQueue.global(qos: .userInitiated).async { - if OnionRequestAPI.paths.count < OnionRequestAPI.pathCount { - let storage = OWSPrimaryStorage.shared() - storage.dbReadConnection.read { transaction in - OnionRequestAPI.paths = storage.getOnionRequestPaths(in: transaction) - } - } - guard OnionRequestAPI.paths.count >= OnionRequestAPI.pathCount else { return } - let pathToDisplay = OnionRequestAPI.paths.first! - pathToDisplay.forEach { snode in - let _ = self.cacheCountry(for: snode.ip) // Preload if needed - } - DispatchQueue.main.async { - NotificationCenter.default.post(name: .onionRequestPathCountriesLoaded, object: nil) + let _ = self.populateCacheIfNeeded() + } + } + + func populateCacheIfNeeded() -> Bool { + if OnionRequestAPI.paths.count < OnionRequestAPI.pathCount { + let storage = OWSPrimaryStorage.shared() + storage.dbReadConnection.read { transaction in + OnionRequestAPI.paths = storage.getOnionRequestPaths(in: transaction) } - print("[Loki] Finished preloading onion request path countries.") } + guard OnionRequestAPI.paths.count >= OnionRequestAPI.pathCount else { return false } + let pathToDisplay = OnionRequestAPI.paths.first! + pathToDisplay.forEach { snode in + let _ = self.cacheCountry(for: snode.ip) // Preload if needed + } + DispatchQueue.main.async { + IP2Country.isInitialized = true + NotificationCenter.default.post(name: .onionRequestPathCountriesLoaded, object: nil) + } + print("[Loki] Finished preloading onion request path countries.") + return true } } diff --git a/Signal/src/Loki/View Controllers/HomeVC.swift b/Signal/src/Loki/View Controllers/HomeVC.swift index 578b328f0..28138f6c3 100644 --- a/Signal/src/Loki/View Controllers/HomeVC.swift +++ b/Signal/src/Loki/View Controllers/HomeVC.swift @@ -84,7 +84,6 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol // MARK: Lifecycle override func viewDidLoad() { super.viewDidLoad() - touch(IP2Country.shared) SignalApp.shared().homeViewController = self setUpGradientBackground() if navigationController?.navigationBar != nil { @@ -154,6 +153,10 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol appDelegate.createRSSFeedsIfNeeded() appDelegate.startRSSFeedPollersIfNeeded() } + // Populate onion request path countries cache + DispatchQueue.global(qos: .userInitiated).async { + let _ = IP2Country.shared.populateCacheIfNeeded() + } // Do initial update reload() } diff --git a/Signal/src/Loki/View Controllers/PathVC.swift b/Signal/src/Loki/View Controllers/PathVC.swift index f34f9d344..35b1aded2 100644 --- a/Signal/src/Loki/View Controllers/PathVC.swift +++ b/Signal/src/Loki/View Controllers/PathVC.swift @@ -157,7 +157,7 @@ final class PathVC : BaseVC { } private func getPathRow(snode: LokiAPITarget, location: LineView.Location, dotAnimationStartDelay: Double, dotAnimationRepeatInterval: Double, isGuardSnode: Bool) -> UIStackView { - let country = IP2Country.shared.countryNamesCache[snode.ip] ?? "Resolving..." + let country = IP2Country.isInitialized ? (IP2Country.shared.countryNamesCache[snode.ip] ?? "Resolving...") : "Resolving..." let title = isGuardSnode ? NSLocalizedString("Entry Node", comment: "") : NSLocalizedString("Service Node", comment: "") return getPathRow(title: title, subtitle: country, location: location, dotAnimationStartDelay: dotAnimationStartDelay, dotAnimationRepeatInterval: dotAnimationRepeatInterval) }