Update to API v3

- Dynamic providers
- Add index.json to API
This commit is contained in:
Davide De Rosa 2019-11-23 14:22:34 +01:00
parent 8cef934a42
commit 97f458385c
12 changed files with 60 additions and 47 deletions

View File

@ -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

View File

@ -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"

View File

@ -111,10 +111,10 @@ enum Product: String {
}
}
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)")
guard let product = Product(rawValue: "com.algoritmico.ios.Passepartout.providers.\(self)") else {
fatalError("Product not found for provider \(self)")
}
return product
}

View File

@ -178,7 +178,7 @@ class ProductManager: NSObject {
return true
}
return purchasedFeatures.contains {
return $0.rawValue.hasSuffix("providers.\(name.rawValue)")
return $0.rawValue.hasSuffix("providers.\(name)")
}
}

View File

@ -189,9 +189,10 @@ extension MFMailComposeViewController {
}
}
extension Infrastructure.Name {
// FIXME: load from index JSON
extension Infrastructure.Metadata {
var logo: UIImage? {
return ImageAsset(name: rawValue.lowercased()).image
return ImageAsset(name: name.lowercased()).image
}
}

View File

@ -61,28 +61,32 @@ class AccountViewController: UIViewController, StrongTableHost {
guard let name = infrastructureName else {
return nil
}
// FIXME: make this dynamic?
let V = L10n.Core.Account.Sections.Guidance.Footer.Infrastructure.self
switch name {
case .mullvad:
return V.mullvad(name.rawValue)
return V.mullvad(name)
case .nordVPN:
return V.nordvpn(name.rawValue)
case .nordvpn:
return V.nordvpn(name)
case .pia:
return V.pia(name.rawValue)
return V.pia(name)
case .protonVPN:
return V.protonvpn(name.rawValue)
case .protonvpn:
return V.protonvpn(name)
case .tunnelBear:
return V.tunnelbear(name.rawValue)
case .tunnelbear:
return V.tunnelbear(name)
case .vyprVPN:
return V.vyprvpn(name.rawValue)
case .vyprvpn:
return V.vyprvpn(name)
case .windscribe:
return V.windscribe(name.rawValue)
return V.windscribe(name)
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
}

View File

@ -39,7 +39,7 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
private var hosts: [String] = []
private var availableProviderNames: [Infrastructure.Name]?
private var availableProviders: [Infrastructure.Metadata]?
private var didShowSubreddit = false
@ -177,7 +177,7 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
vc.setProfile(selectedProfile)
} else if let providerVC = destination as? WizardProviderViewController {
providerVC.availableNames = availableProviderNames ?? []
providerVC.available = availableProviders ?? []
}
}
@ -195,8 +195,8 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
}
private func addNewProvider() {
let names = service.availableProviderNames()
guard !names.isEmpty else {
let providers = service.availableProviders()
guard !providers.isEmpty else {
let alert = UIAlertController.asAlert(
L10n.Core.Organizer.Sections.Providers.header,
L10n.Core.Organizer.Alerts.ExhaustedProviders.message
@ -205,7 +205,7 @@ class OrganizerViewController: UITableViewController, StrongTableHost {
present(alert, animated: true, completion: nil)
return
}
availableProviderNames = names
availableProviders = providers
perform(segue: StoryboardSegue.Organizer.addProviderSegueIdentifier)
}
@ -479,12 +479,13 @@ 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, let metadata = InfrastructureFactory.shared.metadata(forName: rowProfile.id) {
cell.imageView?.image = metadata.logo
cell.leftText = metadata.description
} 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

View File

@ -27,7 +27,7 @@ import UIKit
import PassepartoutCore
class WizardProviderViewController: UITableViewController {
var availableNames: [Infrastructure.Name] = []
var available: [Infrastructure.Metadata] = []
private var createdProfile: ProviderConnectionProfile?
@ -37,17 +37,17 @@ class WizardProviderViewController: UITableViewController {
title = L10n.Core.Organizer.Sections.Providers.header
}
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
@ -73,20 +73,20 @@ class WizardProviderViewController: UITableViewController {
extension WizardProviderViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return availableNames.count
return available.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let name = availableNames[indexPath.row]
let metadata = available[indexPath.row]
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.imageView?.image = name.logo
cell.leftText = name.rawValue
cell.imageView?.image = metadata.logo
cell.leftText = metadata.description
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let name = availableNames[indexPath.row]
next(withName: name)
let metadata = available[indexPath.row]
next(withMetadata: metadata)
}
}

View File

@ -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) {

View File

@ -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 */; };
@ -258,6 +260,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>"; };
@ -545,6 +549,8 @@
isa = PBXGroup;
children = (
0ED31C1120CF0ABA0027975F /* Infrastructure.swift */,
0EA84519238C2AB500EFC500 /* Infrastructure+Metadata.swift */,
0EA84514238A9B5100EFC500 /* Infrastructure+Name.swift */,
0EBE3A83213C6ADE00BFA2F5 /* InfrastructureFactory.swift */,
0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */,
0ED31C0F20CF09A30027975F /* Pool.swift */,
@ -985,6 +991,7 @@
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 */,
@ -996,6 +1003,7 @@
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 */,

@ -1 +1 @@
Subproject commit 60b5c25a3cc79e0bffdd551c4593bdd18d291719
Subproject commit 0d2991f706fbb2a190ecccd390d5c993efd67c92

@ -1 +1 @@
Subproject commit 79cc4a739978b6fc98e910c65d7913431cb41915
Subproject commit c3ed76f010c51139eda1967055998a2308b1c730