Merge branch 'generalize-bundled-api'
This commit is contained in:
commit
12bd44a2c1
|
@ -14,6 +14,7 @@
|
||||||
0E05C5DC20D198B9006EE732 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E05C5DF20D198B9006EE732 /* Localizable.strings */; };
|
0E05C5DC20D198B9006EE732 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E05C5DF20D198B9006EE732 /* Localizable.strings */; };
|
||||||
0E05C5E420D1993C006EE732 /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05C5E320D1993C006EE732 /* SwiftGen+Strings.swift */; };
|
0E05C5E420D1993C006EE732 /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05C5E320D1993C006EE732 /* SwiftGen+Strings.swift */; };
|
||||||
0E05C61D20D27C82006EE732 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05C61C20D27C82006EE732 /* Theme.swift */; };
|
0E05C61D20D27C82006EE732 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05C61C20D27C82006EE732 /* Theme.swift */; };
|
||||||
|
0E0EABC821DF853C0069DAE7 /* Web in Resources */ = {isa = PBXBuildFile; fileRef = 0E0EABC721DF853C0069DAE7 /* Web */; };
|
||||||
0E1066C920E0F84A004F98B7 /* Cells.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1066C820E0F84A004F98B7 /* Cells.swift */; };
|
0E1066C920E0F84A004F98B7 /* Cells.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1066C820E0F84A004F98B7 /* Cells.swift */; };
|
||||||
0E158ADA20E11B0B00C85A82 /* EndpointViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */; };
|
0E158ADA20E11B0B00C85A82 /* EndpointViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */; };
|
||||||
0E1D72B2213BFFCF00BA1586 /* ProviderPresetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */; };
|
0E1D72B2213BFFCF00BA1586 /* ProviderPresetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */; };
|
||||||
|
@ -47,7 +48,6 @@
|
||||||
0E89DFC8213E8FC500741BA1 /* SessionProxy+Communication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */; };
|
0E89DFC8213E8FC500741BA1 /* SessionProxy+Communication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */; };
|
||||||
0E89DFCE213EEDFA00741BA1 /* WizardProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */; };
|
0E89DFCE213EEDFA00741BA1 /* WizardProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */; };
|
||||||
0E8D97E221388B52006FB4A0 /* InfrastructurePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */; };
|
0E8D97E221388B52006FB4A0 /* InfrastructurePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */; };
|
||||||
0E8D97E521389277006FB4A0 /* pia.json in Resources */ = {isa = PBXBuildFile; fileRef = 0E8D97E421389276006FB4A0 /* pia.json */; };
|
|
||||||
0EA068F4218475F800C320AD /* ParsingResult+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA068F3218475F800C320AD /* ParsingResult+Alerts.swift */; };
|
0EA068F4218475F800C320AD /* ParsingResult+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA068F3218475F800C320AD /* ParsingResult+Alerts.swift */; };
|
||||||
0EAAD71920E6669A0088754A /* GroupConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EDE8DED20C93E4C004C739C /* GroupConstants.swift */; };
|
0EAAD71920E6669A0088754A /* GroupConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EDE8DED20C93E4C004C739C /* GroupConstants.swift */; };
|
||||||
0EB60FDA2111136E00AD27F3 /* UITextView+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */; };
|
0EB60FDA2111136E00AD27F3 /* UITextView+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */; };
|
||||||
|
@ -134,6 +134,7 @@
|
||||||
0E05C5E120D198D6006EE732 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/Main.storyboard; sourceTree = "<group>"; };
|
0E05C5E120D198D6006EE732 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
0E05C5E320D1993C006EE732 /* SwiftGen+Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Strings.swift"; sourceTree = "<group>"; };
|
0E05C5E320D1993C006EE732 /* SwiftGen+Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Strings.swift"; sourceTree = "<group>"; };
|
||||||
0E05C61C20D27C82006EE732 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
0E05C61C20D27C82006EE732 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
||||||
|
0E0EABC721DF853C0069DAE7 /* Web */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Web; sourceTree = "<group>"; };
|
||||||
0E1066C820E0F84A004F98B7 /* Cells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cells.swift; sourceTree = "<group>"; };
|
0E1066C820E0F84A004F98B7 /* Cells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cells.swift; sourceTree = "<group>"; };
|
||||||
0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EndpointViewController.swift; sourceTree = "<group>"; };
|
0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EndpointViewController.swift; sourceTree = "<group>"; };
|
||||||
0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProviderPresetViewController.swift; sourceTree = "<group>"; };
|
0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProviderPresetViewController.swift; sourceTree = "<group>"; };
|
||||||
|
@ -170,7 +171,6 @@
|
||||||
0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+Communication.swift"; sourceTree = "<group>"; };
|
0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+Communication.swift"; sourceTree = "<group>"; };
|
||||||
0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardProviderViewController.swift; sourceTree = "<group>"; };
|
0E89DFCD213EEDFA00741BA1 /* WizardProviderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardProviderViewController.swift; sourceTree = "<group>"; };
|
||||||
0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructurePreset.swift; sourceTree = "<group>"; };
|
0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructurePreset.swift; sourceTree = "<group>"; };
|
||||||
0E8D97E421389276006FB4A0 /* pia.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = pia.json; sourceTree = "<group>"; };
|
|
||||||
0EA068F3218475F800C320AD /* ParsingResult+Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParsingResult+Alerts.swift"; sourceTree = "<group>"; };
|
0EA068F3218475F800C320AD /* ParsingResult+Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParsingResult+Alerts.swift"; sourceTree = "<group>"; };
|
||||||
0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Search.swift"; sourceTree = "<group>"; };
|
0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Search.swift"; sourceTree = "<group>"; };
|
||||||
0EB67D6A2184581E00BA6200 /* ImportedHostsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportedHostsViewController.swift; sourceTree = "<group>"; };
|
0EB67D6A2184581E00BA6200 /* ImportedHostsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportedHostsViewController.swift; sourceTree = "<group>"; };
|
||||||
|
@ -356,14 +356,6 @@
|
||||||
path = Organizer;
|
path = Organizer;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
0E8D97C621388679006FB4A0 /* Infrastructures */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
0E8D97E421389276006FB4A0 /* pia.json */,
|
|
||||||
);
|
|
||||||
path = Infrastructures;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
0EBE3AA2213DC1B000BFA2F5 /* Profiles */ = {
|
0EBE3AA2213DC1B000BFA2F5 /* Profiles */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -418,7 +410,7 @@
|
||||||
0ED31C1C20CF17CC0027975F /* Resources */ = {
|
0ED31C1C20CF17CC0027975F /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0E8D97C621388679006FB4A0 /* Infrastructures */,
|
0E0EABC721DF853C0069DAE7 /* Web */,
|
||||||
0E05C5DF20D198B9006EE732 /* Localizable.strings */,
|
0E05C5DF20D198B9006EE732 /* Localizable.strings */,
|
||||||
);
|
);
|
||||||
path = Resources;
|
path = Resources;
|
||||||
|
@ -658,9 +650,9 @@
|
||||||
0E05C5DC20D198B9006EE732 /* Localizable.strings in Resources */,
|
0E05C5DC20D198B9006EE732 /* Localizable.strings in Resources */,
|
||||||
0ED38ADA213F44D00004D387 /* Organizer.storyboard in Resources */,
|
0ED38ADA213F44D00004D387 /* Organizer.storyboard in Resources */,
|
||||||
0E57F64620C83FC7008323CF /* LaunchScreen.storyboard in Resources */,
|
0E57F64620C83FC7008323CF /* LaunchScreen.storyboard in Resources */,
|
||||||
|
0E0EABC821DF853C0069DAE7 /* Web in Resources */,
|
||||||
0E57F64320C83FC7008323CF /* Assets.xcassets in Resources */,
|
0E57F64320C83FC7008323CF /* Assets.xcassets in Resources */,
|
||||||
0E57F64120C83FC5008323CF /* Main.storyboard in Resources */,
|
0E57F64120C83FC5008323CF /* Main.storyboard in Resources */,
|
||||||
0E8D97E521389277006FB4A0 /* pia.json in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ class AppConstants {
|
||||||
class Store {
|
class Store {
|
||||||
static let serviceFilename = "ConnectionService.json"
|
static let serviceFilename = "ConnectionService.json"
|
||||||
|
|
||||||
static let infrastructureCacheDirectory = "Infrastructures"
|
static let webCacheDirectory = "Web"
|
||||||
|
|
||||||
static let providersDirectory = "Providers"
|
static let providersDirectory = "Providers"
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,6 @@ extension ConnectionProfile {
|
||||||
|
|
||||||
extension ConnectionProfile {
|
extension ConnectionProfile {
|
||||||
var description: String {
|
var description: String {
|
||||||
return "(\(context),\(id))"
|
return "(\(context):\(id))"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ private let log = SwiftyBeaver.self
|
||||||
|
|
||||||
class InfrastructureFactory {
|
class InfrastructureFactory {
|
||||||
private static func embedded(withName name: Infrastructure.Name) -> Infrastructure {
|
private static func embedded(withName name: Infrastructure.Name) -> Infrastructure {
|
||||||
guard let url = Bundle.main.url(forResource: name.webName, withExtension: "json") else {
|
guard let url = name.bundleURL else {
|
||||||
fatalError("Cannot find JSON for infrastructure '\(name)'")
|
fatalError("Cannot find JSON for infrastructure '\(name)'")
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
@ -44,7 +44,7 @@ class InfrastructureFactory {
|
||||||
guard let cacheDate = FileManager.default.modificationDate(of: cachedEntry.path) else {
|
guard let cacheDate = FileManager.default.modificationDate(of: cachedEntry.path) else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
guard let bundleURL = Bundle.main.url(forResource: name.webName, withExtension: "json") else {
|
guard let bundleURL = name.bundleURL else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
guard let bundleDate = FileManager.default.modificationDate(of: bundleURL.path) else {
|
guard let bundleDate = FileManager.default.modificationDate(of: bundleURL.path) else {
|
||||||
|
@ -53,7 +53,7 @@ class InfrastructureFactory {
|
||||||
return cacheDate > bundleDate
|
return cacheDate > bundleDate
|
||||||
}
|
}
|
||||||
|
|
||||||
static let shared = InfrastructureFactory(withCacheDirectory: AppConstants.Store.infrastructureCacheDirectory)
|
static let shared = InfrastructureFactory()
|
||||||
|
|
||||||
let allNames: [Infrastructure.Name] = [
|
let allNames: [Infrastructure.Name] = [
|
||||||
.pia
|
.pia
|
||||||
|
@ -67,14 +67,14 @@ class InfrastructureFactory {
|
||||||
|
|
||||||
private var lastUpdate: [Infrastructure.Name: Date]
|
private var lastUpdate: [Infrastructure.Name: Date]
|
||||||
|
|
||||||
private init(withCacheDirectory cacheDirectory: String) {
|
private init() {
|
||||||
var bundle: [Infrastructure.Name: Infrastructure] = [:]
|
var bundle: [Infrastructure.Name: Infrastructure] = [:]
|
||||||
allNames.forEach {
|
allNames.forEach {
|
||||||
bundle[$0] = InfrastructureFactory.embedded(withName: $0)
|
bundle[$0] = InfrastructureFactory.embedded(withName: $0)
|
||||||
}
|
}
|
||||||
self.bundle = bundle
|
self.bundle = bundle
|
||||||
|
|
||||||
cachePath = FileManager.default.userURL(for: .cachesDirectory, appending: cacheDirectory)
|
cachePath = FileManager.default.userURL(for: .cachesDirectory, appending: nil)
|
||||||
cache = [:]
|
cache = [:]
|
||||||
lastUpdate = [:]
|
lastUpdate = [:]
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,8 @@ class InfrastructureFactory {
|
||||||
let fm = FileManager.default
|
let fm = FileManager.default
|
||||||
let url = cacheURL(for: name)
|
let url = cacheURL(for: name)
|
||||||
do {
|
do {
|
||||||
try fm.createDirectory(at: cachePath, withIntermediateDirectories: true, attributes: nil)
|
let parent = url.deletingLastPathComponent()
|
||||||
|
try fm.createDirectory(at: parent, withIntermediateDirectories: true, attributes: nil)
|
||||||
let data = try JSONEncoder().encode(infrastructure)
|
let data = try JSONEncoder().encode(infrastructure)
|
||||||
try data.write(to: url)
|
try data.write(to: url)
|
||||||
try fm.setAttributes([.modificationDate: lastModified], ofItemAtPath: url.path)
|
try fm.setAttributes([.modificationDate: lastModified], ofItemAtPath: url.path)
|
||||||
|
@ -217,7 +218,7 @@ class InfrastructureFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func cacheURL(for name: Infrastructure.Name) -> URL {
|
private func cacheURL(for name: Infrastructure.Name) -> URL {
|
||||||
return cachePath.appendingPathComponent(name.webName).appendingPathExtension("json")
|
return cachePath.appendingPathComponent(name.bundleRelativePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func cacheModificationDate(for name: Infrastructure.Name) -> Date? {
|
private func cacheModificationDate(for name: Infrastructure.Name) -> Date? {
|
||||||
|
@ -225,12 +226,26 @@ class InfrastructureFactory {
|
||||||
return FileManager.default.modificationDate(of: url.path)
|
return FileManager.default.modificationDate(of: url.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func bundleURL(for name: Infrastructure.Name) -> URL {
|
|
||||||
return Bundle.main.url(forResource: name.webName, withExtension: "json")!
|
|
||||||
}
|
|
||||||
|
|
||||||
private func bundleModificationDate(for name: Infrastructure.Name) -> Date? {
|
private func bundleModificationDate(for name: Infrastructure.Name) -> Date? {
|
||||||
let url = bundleURL(for: name)
|
guard let url = name.bundleURL else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return FileManager.default.modificationDate(of: url.path)
|
return FileManager.default.modificationDate(of: url.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension Infrastructure.Name {
|
||||||
|
var bundleRelativePath: String {
|
||||||
|
let endpoint = WebServices.Endpoint.network(self)
|
||||||
|
|
||||||
|
// e.g. "Web", PIA="net/pia" -> "Web/net/pia.json"
|
||||||
|
return "\(AppConstants.Store.webCacheDirectory)/\(endpoint.path).json"
|
||||||
|
}
|
||||||
|
|
||||||
|
var bundleURL: URL? {
|
||||||
|
let endpoint = WebServices.Endpoint.network(self)
|
||||||
|
|
||||||
|
// e.g. "Web", PIA="net/pia" -> "[Bundle]:Web/net/pia.json"
|
||||||
|
return Bundle.main.url(forResource: "\(AppConstants.Store.webCacheDirectory)/\(endpoint.path)", withExtension: "json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ class WebServices {
|
||||||
var path: String {
|
var path: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .network(let name):
|
case .network(let name):
|
||||||
return "net/\(name.webName).json"
|
return "net/\(name.webName)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ class WebServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func get(_ endpoint: Endpoint) -> URLRequest {
|
private func get(_ endpoint: Endpoint) -> URLRequest {
|
||||||
let url = AppConstants.Web.url(path: endpoint.path)
|
let url = AppConstants.Web.url(path: "\(endpoint.path).json")
|
||||||
return URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: AppConstants.Web.timeout)
|
return URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: AppConstants.Web.timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue