Merge branch 'dynamic-providers'
This commit is contained in:
commit
acf6663b26
|
@ -40,11 +40,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
|
|||
|
||||
override init() {
|
||||
AppConstants.Log.configure()
|
||||
InfrastructureFactory.shared.preload()
|
||||
super.init()
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
InfrastructureFactory.shared.loadCache()
|
||||
Theme.current.applyAppearance()
|
||||
Reviewer.shared.eventCountBeforeRating = AppConstants.Rating.eventCount
|
||||
|
||||
|
|
|
@ -77,8 +77,8 @@ class IssueReporter: NSObject {
|
|||
var bodyMetadata = "--\n\n"
|
||||
bodyMetadata += DebugLog(raw: "").decoratedString()
|
||||
if let infrastructure = issue.infrastructure {
|
||||
bodyMetadata += "Provider: \(infrastructure.name.rawValue)\n"
|
||||
if let lastUpdated = InfrastructureFactory.shared.modificationDate(for: infrastructure.name) {
|
||||
bodyMetadata += "Provider: \(infrastructure.name)\n"
|
||||
if let lastUpdated = InfrastructureFactory.shared.modificationDate(forName: infrastructure.name) {
|
||||
bodyMetadata += "Last updated: \(lastUpdated)\n"
|
||||
}
|
||||
bodyMetadata += "\n"
|
||||
|
|
|
@ -26,21 +26,28 @@
|
|||
import Foundation
|
||||
import PassepartoutCore
|
||||
|
||||
enum Product: String {
|
||||
struct Product: RawRepresentable, Equatable, Hashable {
|
||||
private static let bundle = "com.algoritmico.ios.Passepartout"
|
||||
|
||||
private static let donationsBundle = "\(bundle).donations"
|
||||
|
||||
private static let featuresBundle = "\(bundle).features"
|
||||
|
||||
private static let providersBundle = "\(bundle).providers"
|
||||
|
||||
// MARK: Donations
|
||||
|
||||
case tinyDonation = "com.algoritmico.ios.Passepartout.donations.Tiny"
|
||||
static let tinyDonation = Product(donationDescription: "Tiny")
|
||||
|
||||
case smallDonation = "com.algoritmico.ios.Passepartout.donations.Small"
|
||||
static let smallDonation = Product(donationDescription: "Small")
|
||||
|
||||
case mediumDonation = "com.algoritmico.ios.Passepartout.donations.Medium"
|
||||
static let mediumDonation = Product(donationDescription: "Medium")
|
||||
|
||||
case bigDonation = "com.algoritmico.ios.Passepartout.donations.Big"
|
||||
static let bigDonation = Product(donationDescription: "Big")
|
||||
|
||||
case hugeDonation = "com.algoritmico.ios.Passepartout.donations.Huge"
|
||||
static let hugeDonation = Product(donationDescription: "Huge")
|
||||
|
||||
case maxiDonation = "com.algoritmico.ios.Passepartout.donations.Maxi"
|
||||
static let maxiDonation = Product(donationDescription: "Maxi")
|
||||
|
||||
static let allDonations: [Product] = [
|
||||
.tinyDonation,
|
||||
|
@ -51,15 +58,19 @@ enum Product: String {
|
|||
.maxiDonation
|
||||
]
|
||||
|
||||
private init(donationDescription: String) {
|
||||
self.init(rawValue: "\(Product.donationsBundle).\(donationDescription)")!
|
||||
}
|
||||
|
||||
// MARK: Features
|
||||
|
||||
case unlimitedHosts = "com.algoritmico.ios.Passepartout.features.unlimited_hosts"
|
||||
static let unlimitedHosts = Product(featureId: "unlimited_hosts")
|
||||
|
||||
case trustedNetworks = "com.algoritmico.ios.Passepartout.features.trusted_networks"
|
||||
static let trustedNetworks = Product(featureId: "trusted_networks")
|
||||
|
||||
case siriShortcuts = "com.algoritmico.ios.Passepartout.features.siri"
|
||||
static let siriShortcuts = Product(featureId: "features.siri")
|
||||
|
||||
case fullVersion = "com.algoritmico.ios.Passepartout.features.full_version"
|
||||
static let fullVersion = Product(featureId: "full_version")
|
||||
|
||||
static let allFeatures: [Product] = [
|
||||
.unlimitedHosts,
|
||||
|
@ -67,55 +78,64 @@ enum Product: String {
|
|||
.siriShortcuts,
|
||||
.fullVersion
|
||||
]
|
||||
|
||||
private init(featureId: String) {
|
||||
self.init(rawValue: "\(Product.featuresBundle).\(featureId)")!
|
||||
}
|
||||
|
||||
// MARK: Providers
|
||||
|
||||
case mullvad = "com.algoritmico.ios.Passepartout.providers.Mullvad"
|
||||
|
||||
case nordVPN = "com.algoritmico.ios.Passepartout.providers.NordVPN"
|
||||
|
||||
case pia = "com.algoritmico.ios.Passepartout.providers.PIA"
|
||||
|
||||
case protonVPN = "com.algoritmico.ios.Passepartout.providers.ProtonVPN"
|
||||
|
||||
case tunnelBear = "com.algoritmico.ios.Passepartout.providers.TunnelBear"
|
||||
|
||||
case vyprVPN = "com.algoritmico.ios.Passepartout.providers.VyprVPN"
|
||||
|
||||
case windscribe = "com.algoritmico.ios.Passepartout.providers.Windscribe"
|
||||
|
||||
static let allProviders: [Product] = [
|
||||
.mullvad,
|
||||
.nordVPN,
|
||||
.pia,
|
||||
.protonVPN,
|
||||
.tunnelBear,
|
||||
.vyprVPN,
|
||||
.windscribe
|
||||
]
|
||||
static var allProviders: [Product] {
|
||||
return InfrastructureFactory.shared.allMetadata.map {
|
||||
return Product(providerId: $0.description)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate init(providerId: String) {
|
||||
self.init(rawValue: "\(Product.providersBundle).\(providerId)")!
|
||||
}
|
||||
|
||||
// MARK: All
|
||||
|
||||
static let all: [Product] = allDonations + allFeatures + allProviders
|
||||
static var all: [Product] {
|
||||
return allDonations + allFeatures + allProviders
|
||||
}
|
||||
|
||||
var isDonation: Bool {
|
||||
return Product.allDonations.contains(self)
|
||||
return rawValue.hasPrefix(Product.donationsBundle)
|
||||
}
|
||||
|
||||
var isFeature: Bool {
|
||||
return Product.allFeatures.contains(self)
|
||||
return rawValue.hasPrefix(Product.featuresBundle)
|
||||
}
|
||||
|
||||
var isProvider: Bool {
|
||||
return Product.allProviders.contains(self)
|
||||
return rawValue.hasPrefix(Product.providersBundle)
|
||||
}
|
||||
|
||||
// MARK: RawRepresentable
|
||||
|
||||
let rawValue: String
|
||||
|
||||
init?(rawValue: String) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
static func ==(lhs: Product, rhs: Product) -> Bool {
|
||||
return lhs.rawValue == rhs.rawValue
|
||||
}
|
||||
|
||||
// MARK: Hashable
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
rawValue.hash(into: &hasher)
|
||||
}
|
||||
}
|
||||
|
||||
extension Infrastructure.Name {
|
||||
extension Infrastructure.Metadata {
|
||||
var product: Product {
|
||||
guard let product = Product(rawValue: "com.algoritmico.ios.Passepartout.providers.\(rawValue)") else {
|
||||
fatalError("Product not found for provider \(rawValue)")
|
||||
}
|
||||
return product
|
||||
return Product(providerId: description)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,11 +67,9 @@ class ProductManager: NSObject {
|
|||
}
|
||||
|
||||
func listProducts(completionHandler: (([SKProduct]) -> Void)?) {
|
||||
guard inApp.products.isEmpty else {
|
||||
completionHandler?(inApp.products)
|
||||
return
|
||||
}
|
||||
inApp.requestProducts(withIdentifiers: Product.all) { _ in
|
||||
log.debug("In-app products: \(self.inApp.products.map { $0.productIdentifier })")
|
||||
|
||||
completionHandler?(self.inApp.products)
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +176,7 @@ class ProductManager: NSObject {
|
|||
return true
|
||||
}
|
||||
return purchasedFeatures.contains {
|
||||
return $0.rawValue.hasSuffix("providers.\(name.rawValue)")
|
||||
return $0.rawValue.hasSuffix("providers.\(name)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -284,6 +284,7 @@ internal enum Asset {
|
|||
internal static let mullvad = ImageAsset(name: "mullvad")
|
||||
internal static let nordvpn = ImageAsset(name: "nordvpn")
|
||||
internal static let pia = ImageAsset(name: "pia")
|
||||
internal static let placeholder = ImageAsset(name: "placeholder")
|
||||
internal static let protonvpn = ImageAsset(name: "protonvpn")
|
||||
internal static let tunnelbear = ImageAsset(name: "tunnelbear")
|
||||
internal static let vyprvpn = ImageAsset(name: "vyprvpn")
|
||||
|
|
|
@ -1047,6 +1047,14 @@ internal enum L10n {
|
|||
}
|
||||
}
|
||||
}
|
||||
internal enum Provider {
|
||||
internal enum Cells {
|
||||
internal enum UpdateList {
|
||||
/// Update list
|
||||
internal static let caption = L10n.tr("Core", "wizards.provider.cells.update_list.caption")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,9 +189,10 @@ extension MFMailComposeViewController {
|
|||
}
|
||||
}
|
||||
|
||||
extension Infrastructure.Name {
|
||||
var logo: UIImage? {
|
||||
return ImageAsset(name: rawValue.lowercased()).image
|
||||
// FIXME: load from index JSON
|
||||
extension Infrastructure.Metadata {
|
||||
var logo: UIImage {
|
||||
return ImageAsset(name: name.lowercased()).image
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "placeholder@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "placeholder@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
BIN
Passepartout-iOS/Providers.xcassets/placeholder.imageset/placeholder@2x.png
vendored
Normal file
BIN
Passepartout-iOS/Providers.xcassets/placeholder.imageset/placeholder@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
Passepartout-iOS/Providers.xcassets/placeholder.imageset/placeholder@3x.png
vendored
Normal file
BIN
Passepartout-iOS/Providers.xcassets/placeholder.imageset/placeholder@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
|
@ -58,31 +58,35 @@ class AccountViewController: UIViewController, StrongTableHost {
|
|||
}
|
||||
|
||||
private var guidanceString: String? {
|
||||
guard let name = infrastructureName else {
|
||||
guard let name = infrastructureName, let metadata = InfrastructureFactory.shared.metadata(forName: name) else {
|
||||
return nil
|
||||
}
|
||||
// XXX: should make this dynamic
|
||||
let V = L10n.Core.Account.Sections.Guidance.Footer.Infrastructure.self
|
||||
switch name {
|
||||
switch metadata.name {
|
||||
case .mullvad:
|
||||
return V.mullvad(name.rawValue)
|
||||
return V.mullvad(metadata.description)
|
||||
|
||||
case .nordVPN:
|
||||
return V.nordvpn(name.rawValue)
|
||||
case .nordvpn:
|
||||
return V.nordvpn(metadata.description)
|
||||
|
||||
case .pia:
|
||||
return V.pia(name.rawValue)
|
||||
return V.pia(metadata.description)
|
||||
|
||||
case .protonVPN:
|
||||
return V.protonvpn(name.rawValue)
|
||||
case .protonvpn:
|
||||
return V.protonvpn(metadata.description)
|
||||
|
||||
case .tunnelBear:
|
||||
return V.tunnelbear(name.rawValue)
|
||||
case .tunnelbear:
|
||||
return V.tunnelbear(metadata.description)
|
||||
|
||||
case .vyprVPN:
|
||||
return V.vyprvpn(name.rawValue)
|
||||
case .vyprvpn:
|
||||
return V.vyprvpn(metadata.description)
|
||||
|
||||
case .windscribe:
|
||||
return V.windscribe(name.rawValue)
|
||||
return V.windscribe(metadata.description)
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +270,7 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
|
|||
fatalError("Sign-up shown when not a provider profile")
|
||||
}
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.leftText = L10n.Core.Account.Cells.Signup.caption(name.rawValue)
|
||||
cell.leftText = L10n.Core.Account.Cells.Signup.caption(name)
|
||||
cell.applyAction(.current)
|
||||
return cell
|
||||
}
|
||||
|
|
|
@ -39,8 +39,6 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
|
|||
|
||||
private var hosts: [String] = []
|
||||
|
||||
private var availableProviderNames: [Infrastructure.Name]?
|
||||
|
||||
private var didShowSubreddit = false
|
||||
|
||||
// MARK: StrongTableHost
|
||||
|
@ -176,8 +174,6 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
|
|||
}
|
||||
|
||||
vc.setProfile(selectedProfile)
|
||||
} else if let providerVC = destination as? WizardProviderViewController {
|
||||
providerVC.availableNames = availableProviderNames ?? []
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,8 +191,7 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
|
|||
}
|
||||
|
||||
private func addNewProvider() {
|
||||
let names = service.availableProviderNames()
|
||||
guard !names.isEmpty else {
|
||||
guard service.hasAvailableProviders() else {
|
||||
let alert = UIAlertController.asAlert(
|
||||
L10n.Core.Organizer.Sections.Providers.header,
|
||||
L10n.Core.Organizer.Alerts.ExhaustedProviders.message
|
||||
|
@ -205,7 +200,6 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
|
|||
present(alert, animated: true, completion: nil)
|
||||
return
|
||||
}
|
||||
availableProviderNames = names
|
||||
perform(segue: StoryboardSegue.Organizer.addProviderSegueIdentifier)
|
||||
}
|
||||
|
||||
|
@ -479,12 +473,18 @@ extension OrganizerViewController {
|
|||
case .profile:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
let rowProfile = profileKey(at: indexPath)
|
||||
if rowProfile.context == .provider, let providerName = Infrastructure.Name(rawValue: rowProfile.id) {
|
||||
cell.imageView?.image = providerName.logo
|
||||
if rowProfile.context == .provider {
|
||||
if let metadata = InfrastructureFactory.shared.metadata(forName: rowProfile.id) {
|
||||
cell.imageView?.image = metadata.logo
|
||||
cell.leftText = metadata.description
|
||||
} else {
|
||||
cell.imageView?.image = Asset.Providers.placeholder.image
|
||||
cell.leftText = rowProfile.id
|
||||
}
|
||||
} else {
|
||||
cell.imageView?.image = nil
|
||||
cell.leftText = rowProfile.id
|
||||
}
|
||||
cell.leftText = rowProfile.id
|
||||
cell.rightText = service.isActiveProfile(rowProfile) ? L10n.Core.Organizer.Cells.Profile.Value.current : nil
|
||||
return cell
|
||||
|
||||
|
|
|
@ -25,29 +25,50 @@
|
|||
|
||||
import UIKit
|
||||
import PassepartoutCore
|
||||
import Convenience
|
||||
import SwiftyBeaver
|
||||
|
||||
class WizardProviderViewController: UITableViewController {
|
||||
var availableNames: [Infrastructure.Name] = []
|
||||
private let log = SwiftyBeaver.self
|
||||
|
||||
class WizardProviderViewController: UITableViewController, StrongTableHost {
|
||||
private var available: [Infrastructure.Metadata] = []
|
||||
|
||||
private var createdProfile: ProviderConnectionProfile?
|
||||
|
||||
// MARK: StrongTableHost
|
||||
|
||||
let model = StrongTableModel<SectionType, RowType>()
|
||||
|
||||
func reloadModel() {
|
||||
available = TransientStore.shared.service.availableProviders()
|
||||
|
||||
model.clear()
|
||||
model.add(.availableProviders)
|
||||
model.add(.listActions)
|
||||
model.set(.provider, count: available.count, forSection: .availableProviders)
|
||||
model.set([.updateList], forSection: .listActions)
|
||||
}
|
||||
|
||||
// MARK: UIViewController
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
title = L10n.Core.Organizer.Sections.Providers.header
|
||||
reloadModel()
|
||||
}
|
||||
|
||||
private func next(withName name: Infrastructure.Name) {
|
||||
guard ProductManager.shared.isEligible(forProvider: name) else {
|
||||
presentPurchaseScreen(forProduct: name.product)
|
||||
private func next(withMetadata metadata: Infrastructure.Metadata) {
|
||||
guard ProductManager.shared.isEligible(forProvider: metadata.name) else {
|
||||
presentPurchaseScreen(forProduct: metadata.product)
|
||||
return
|
||||
}
|
||||
|
||||
let profile = ProviderConnectionProfile(name: name)
|
||||
let profile = ProviderConnectionProfile(name: metadata.name)
|
||||
createdProfile = profile
|
||||
|
||||
let accountVC = StoryboardScene.Main.accountIdentifier.instantiate()
|
||||
let infrastructure = InfrastructureFactory.shared.get(name)
|
||||
let infrastructure = InfrastructureFactory.shared.infrastructure(forName: metadata.name)
|
||||
accountVC.usernamePlaceholder = infrastructure.defaults.username
|
||||
accountVC.infrastructureName = infrastructure.name
|
||||
accountVC.delegate = self
|
||||
|
@ -63,6 +84,23 @@ class WizardProviderViewController: UITableViewController {
|
|||
service.addOrReplaceProfile(profile, credentials: credentials)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateProvidersList() {
|
||||
let hud = HUD(view: view)
|
||||
InfrastructureFactory.shared.updateIndex { [weak self] in
|
||||
if let error = $0 {
|
||||
hud.hide()
|
||||
log.error("Unable to update providers list: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
ProductManager.shared.listProducts { _ in
|
||||
self?.reloadModel()
|
||||
self?.tableView.reloadData()
|
||||
hud.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction private func close() {
|
||||
dismiss(animated: true, completion: nil)
|
||||
|
@ -72,21 +110,55 @@ class WizardProviderViewController: UITableViewController {
|
|||
// MARK: -
|
||||
|
||||
extension WizardProviderViewController {
|
||||
enum SectionType {
|
||||
case availableProviders
|
||||
|
||||
case listActions
|
||||
}
|
||||
|
||||
enum RowType {
|
||||
case provider
|
||||
|
||||
case updateList
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return model.numberOfSections
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return availableNames.count
|
||||
return model.numberOfRows(forSection: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let name = availableNames[indexPath.row]
|
||||
let row = model.row(at: indexPath)
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.imageView?.image = name.logo
|
||||
cell.leftText = name.rawValue
|
||||
switch row {
|
||||
case .provider:
|
||||
let metadata = available[indexPath.row]
|
||||
cell.apply(.current)
|
||||
cell.imageView?.image = metadata.logo
|
||||
cell.leftText = metadata.description
|
||||
|
||||
case .updateList:
|
||||
cell.applyAction(.current)
|
||||
cell.imageView?.image = nil
|
||||
cell.leftText = L10n.Core.Wizards.Provider.Cells.UpdateList.caption
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let name = availableNames[indexPath.row]
|
||||
next(withName: name)
|
||||
let row = model.row(at: indexPath)
|
||||
switch row {
|
||||
case .provider:
|
||||
let metadata = available[indexPath.row]
|
||||
next(withMetadata: metadata)
|
||||
|
||||
case .updateList:
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
updateProvidersList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ class ServiceViewController: UIViewController, StrongTableHost {
|
|||
self.profile = profile
|
||||
vpn.profile = profile
|
||||
|
||||
title = profile?.id
|
||||
title = profile?.screenTitle
|
||||
navigationItem.rightBarButtonItem = (profile?.context == .host) ? itemEdit : nil
|
||||
if reloadingViews {
|
||||
reloadModel()
|
||||
|
@ -95,10 +95,9 @@ class ServiceViewController: UIViewController, StrongTableHost {
|
|||
setProfile(service.activeProfile)
|
||||
}
|
||||
if let providerProfile = profile as? ProviderConnectionProfile {
|
||||
lastInfrastructureUpdate = InfrastructureFactory.shared.modificationDate(for: providerProfile.name)
|
||||
lastInfrastructureUpdate = InfrastructureFactory.shared.modificationDate(forName: providerProfile.name)
|
||||
}
|
||||
|
||||
title = profile?.id
|
||||
navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
|
||||
navigationItem.leftItemsSupplementBackButton = true
|
||||
|
||||
|
@ -596,7 +595,7 @@ class ServiceViewController: UIViewController, StrongTableHost {
|
|||
|
||||
let alert = UIAlertController.asAlert(
|
||||
L10n.Core.Service.Alerts.Download.title,
|
||||
L10n.Core.Service.Alerts.Download.message(providerProfile.name.rawValue)
|
||||
L10n.Core.Service.Alerts.Download.message(providerProfile.name)
|
||||
)
|
||||
alert.addCancelAction(L10n.Core.Global.cancel)
|
||||
alert.addPreferredAction(L10n.Core.Global.ok) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
0E0C0729236087A100155AAC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E0C072B236087A100155AAC /* InfoPlist.strings */; };
|
||||
0E1066C920E0F84A004F98B7 /* Cells.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1066C820E0F84A004F98B7 /* Cells.swift */; };
|
||||
0E158ADA20E11B0B00C85A82 /* EndpointViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */; };
|
||||
0E1C0A4F238FC7A5009FC087 /* InfrastructureFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1C0A4E238FC7A5009FC087 /* InfrastructureFactory.swift */; };
|
||||
0E1D72B2213BFFCF00BA1586 /* ProviderPresetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */; };
|
||||
0E1D72B4213C118500BA1586 /* ConfigurationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1D72B3213C118500BA1586 /* ConfigurationViewController.swift */; };
|
||||
0E24273A225950450064A1A3 /* About.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E24273C225950450064A1A3 /* About.storyboard */; };
|
||||
|
@ -38,7 +39,6 @@
|
|||
0E3152C6223FA04800F61841 /* VPNProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED38AF1214177920004D387 /* VPNProvider.swift */; };
|
||||
0E3152C7223FA04800F61841 /* VPNStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E5E5DDE215119AF00E318A3 /* VPNStatus.swift */; };
|
||||
0E3152C8223FA04D00F61841 /* Infrastructure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED31C1120CF0ABA0027975F /* Infrastructure.swift */; };
|
||||
0E3152C9223FA04D00F61841 /* InfrastructureFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBE3A83213C6ADE00BFA2F5 /* InfrastructureFactory.swift */; };
|
||||
0E3152CA223FA04D00F61841 /* InfrastructurePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */; };
|
||||
0E3152CB223FA04D00F61841 /* Pool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED31C0F20CF09A30027975F /* Pool.swift */; };
|
||||
0E3152CC223FA04D00F61841 /* WebServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E39BCEF214B9EF10035E9DE /* WebServices.swift */; };
|
||||
|
@ -89,6 +89,8 @@
|
|||
0E9CD7872257462800D033B4 /* Providers.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E9CD7862257462800D033B4 /* Providers.xcassets */; };
|
||||
0E9CD789225746B300D033B4 /* Flags.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E9CD788225746B300D033B4 /* Flags.xcassets */; };
|
||||
0E9CDB6723604AD5006733B4 /* ServerNetworkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E9CDB6623604AD5006733B4 /* ServerNetworkViewController.swift */; };
|
||||
0EA84515238A9B5200EFC500 /* Infrastructure+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA84514238A9B5100EFC500 /* Infrastructure+Name.swift */; };
|
||||
0EA8451A238C2AB500EFC500 /* Infrastructure+Metadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA84519238C2AB500EFC500 /* Infrastructure+Metadata.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 */; };
|
||||
0EB67D6B2184581E00BA6200 /* ImportedHostsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB67D6A2184581E00BA6200 /* ImportedHostsViewController.swift */; };
|
||||
|
@ -169,6 +171,7 @@
|
|||
0E0C072C236087C800155AAC /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; 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>"; };
|
||||
0E1C0A4E238FC7A5009FC087 /* InfrastructureFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InfrastructureFactory.swift; path = Submodules/Core/Passepartout/Sources/Services/InfrastructureFactory.swift; sourceTree = SOURCE_ROOT; };
|
||||
0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProviderPresetViewController.swift; sourceTree = "<group>"; };
|
||||
0E1D72B3213C118500BA1586 /* ConfigurationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationViewController.swift; sourceTree = "<group>"; };
|
||||
0E23B4A12298559800304C30 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
|
||||
|
@ -258,6 +261,8 @@
|
|||
0E9CD7862257462800D033B4 /* Providers.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Providers.xcassets; sourceTree = "<group>"; };
|
||||
0E9CD788225746B300D033B4 /* Flags.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Flags.xcassets; sourceTree = "<group>"; };
|
||||
0E9CDB6623604AD5006733B4 /* ServerNetworkViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerNetworkViewController.swift; sourceTree = "<group>"; };
|
||||
0EA84514238A9B5100EFC500 /* Infrastructure+Name.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Infrastructure+Name.swift"; path = "Submodules/Core/Passepartout/Sources/Services/Infrastructure+Name.swift"; sourceTree = SOURCE_ROOT; };
|
||||
0EA84519238C2AB500EFC500 /* Infrastructure+Metadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Infrastructure+Metadata.swift"; path = "Submodules/Core/Passepartout/Sources/Services/Infrastructure+Metadata.swift"; sourceTree = SOURCE_ROOT; };
|
||||
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>"; };
|
||||
0EB9EB7223867E7F009C0A1C /* TrustedNetworksUI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrustedNetworksUI.swift; sourceTree = "<group>"; };
|
||||
|
@ -272,7 +277,6 @@
|
|||
0EBE2FD72360F89600F0D5AB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
0EBE2FD82360F89600F0D5AB /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
0EBE3A78213C4E5400BFA2F5 /* OrganizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrganizerViewController.swift; sourceTree = "<group>"; };
|
||||
0EBE3A83213C6ADE00BFA2F5 /* InfrastructureFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructureFactory.swift; sourceTree = "<group>"; };
|
||||
0EBE3A8F213C6F4000BFA2F5 /* TrustPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustPolicy.swift; sourceTree = "<group>"; };
|
||||
0EBE3A9E213DC1A100BFA2F5 /* ConnectionProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionProfile.swift; sourceTree = "<group>"; };
|
||||
0EBE3A9F213DC1A100BFA2F5 /* ConnectionService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionService.swift; sourceTree = "<group>"; };
|
||||
|
@ -545,7 +549,9 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
0ED31C1120CF0ABA0027975F /* Infrastructure.swift */,
|
||||
0EBE3A83213C6ADE00BFA2F5 /* InfrastructureFactory.swift */,
|
||||
0EA84519238C2AB500EFC500 /* Infrastructure+Metadata.swift */,
|
||||
0EA84514238A9B5100EFC500 /* Infrastructure+Name.swift */,
|
||||
0E1C0A4E238FC7A5009FC087 /* InfrastructureFactory.swift */,
|
||||
0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */,
|
||||
0ED31C0F20CF09A30027975F /* Pool.swift */,
|
||||
0E66A26F225FE25800F9C779 /* PoolCategory.swift */,
|
||||
|
@ -969,6 +975,7 @@
|
|||
0E3152C6223FA04800F61841 /* VPNProvider.swift in Sources */,
|
||||
0E3152DA223FA05800F61841 /* PlaceholderConnectionProfile.swift in Sources */,
|
||||
0E3152D0223FA05400F61841 /* ConnectionService+Migration.swift in Sources */,
|
||||
0E1C0A4F238FC7A5009FC087 /* InfrastructureFactory.swift in Sources */,
|
||||
0E3152D5223FA05400F61841 /* SessionProxy+Communication.swift in Sources */,
|
||||
0E3152D7223FA05400F61841 /* TrustedNetworks.swift in Sources */,
|
||||
0E3152DB223FA05800F61841 /* ProfileKey.swift in Sources */,
|
||||
|
@ -985,17 +992,18 @@
|
|||
0E3152CA223FA04D00F61841 /* InfrastructurePreset.swift in Sources */,
|
||||
0E3152CE223FA05400F61841 /* ConnectionService.swift in Sources */,
|
||||
0ED993B1223FF8C700B0F9C9 /* IntentDispatcher.swift in Sources */,
|
||||
0EA84515238A9B5200EFC500 /* Infrastructure+Name.swift in Sources */,
|
||||
0EEF23412321AC55000AEBE3 /* Issue.swift in Sources */,
|
||||
0E3152C3223FA04800F61841 /* StandardVPNProvider.swift in Sources */,
|
||||
0E3152D1223FA05400F61841 /* Credentials.swift in Sources */,
|
||||
0E3152CD223FA05400F61841 /* ConnectionProfile.swift in Sources */,
|
||||
0E3152BC223FA03D00F61841 /* ApplicationError.swift in Sources */,
|
||||
0E3152C9223FA04D00F61841 /* InfrastructureFactory.swift in Sources */,
|
||||
0E3152D3223FA05400F61841 /* EndpointDataSource.swift in Sources */,
|
||||
0E3152D4223FA05400F61841 /* Preferences.swift in Sources */,
|
||||
0EFB901822764689006405E4 /* ProfileNetworkSettings.swift in Sources */,
|
||||
0E3152C0223FA03D00F61841 /* Utils.swift in Sources */,
|
||||
0E3152CB223FA04D00F61841 /* Pool.swift in Sources */,
|
||||
0EA8451A238C2AB500EFC500 /* Infrastructure+Metadata.swift in Sources */,
|
||||
0EB9EB7323867E7F009C0A1C /* TrustedNetworksUI.swift in Sources */,
|
||||
0E3CAFC0229AAE770008E5C8 /* Intents.intentdefinition in Sources */,
|
||||
0E3152C7223FA04800F61841 /* VPNStatus.swift in Sources */,
|
||||
|
|
2
Podfile
2
Podfile
|
@ -14,7 +14,7 @@ def shared_pods
|
|||
pod 'SSZipArchive'
|
||||
|
||||
for spec in ['About', 'Alerts', 'Dialogs', 'InApp', 'Misc', 'Options', 'Persistence', 'Reviewer', 'Tables', 'WebServices'] do
|
||||
pod "Convenience/#{spec}", :git => 'https://github.com/keeshux/convenience', :commit => 'cfd2e57'
|
||||
pod "Convenience/#{spec}", :git => 'https://github.com/keeshux/convenience', :commit => '7fe7dcf'
|
||||
#pod "Convenience/#{spec}", :path => '../../personal/convenience'
|
||||
end
|
||||
end
|
||||
|
|
26
Podfile.lock
26
Podfile.lock
|
@ -36,16 +36,16 @@ PODS:
|
|||
- TunnelKit/Core
|
||||
|
||||
DEPENDENCIES:
|
||||
- Convenience/About (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/Alerts (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/Dialogs (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/InApp (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/Misc (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/Options (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/Persistence (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/Reviewer (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/Tables (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/WebServices (from `https://github.com/keeshux/convenience`, commit `cfd2e57`)
|
||||
- Convenience/About (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/Alerts (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/Dialogs (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/InApp (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/Misc (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/Options (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/Persistence (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/Reviewer (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/Tables (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Convenience/WebServices (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`)
|
||||
- Kvitto
|
||||
- MBProgressHUD
|
||||
- SSZipArchive
|
||||
|
@ -63,7 +63,7 @@ SPEC REPOS:
|
|||
|
||||
EXTERNAL SOURCES:
|
||||
Convenience:
|
||||
:commit: cfd2e57
|
||||
:commit: 7fe7dcf
|
||||
:git: https://github.com/keeshux/convenience
|
||||
TunnelKit:
|
||||
:commit: 8b17a13
|
||||
|
@ -71,7 +71,7 @@ EXTERNAL SOURCES:
|
|||
|
||||
CHECKOUT OPTIONS:
|
||||
Convenience:
|
||||
:commit: cfd2e57
|
||||
:commit: 7fe7dcf
|
||||
:git: https://github.com/keeshux/convenience
|
||||
TunnelKit:
|
||||
:commit: 8b17a13
|
||||
|
@ -87,6 +87,6 @@ SPEC CHECKSUMS:
|
|||
SwiftyBeaver: 3d3e93a12d648bd400b6f2948a7ef128b5b183c7
|
||||
TunnelKit: 4b70c0d8b6727b407248b4271b7613225f63204b
|
||||
|
||||
PODFILE CHECKSUM: 51463b0e66ae367dd35c273e67cfc84659a41432
|
||||
PODFILE CHECKSUM: 10c7cb879b6ee3d5185f541e6a2c6d14e988ff0b
|
||||
|
||||
COCOAPODS: 1.8.4
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 60b5c25a3cc79e0bffdd551c4593bdd18d291719
|
||||
Subproject commit 72d464ab9291d7cb7521603742b04b3928d1d2c5
|
|
@ -1 +1 @@
|
|||
Subproject commit 79cc4a739978b6fc98e910c65d7913431cb41915
|
||||
Subproject commit 5e25f768fb66832c4a539e7ff6ba7fa80d918a12
|
Loading…
Reference in New Issue