Merge branch 'download-dynamic-infrastructure'

This commit is contained in:
Davide De Rosa 2019-11-30 12:33:15 +01:00
commit 49729592c8
10 changed files with 92 additions and 35 deletions

View File

@ -66,12 +66,14 @@ class ProductManager: NSObject {
SKPaymentQueue.default().remove(self) SKPaymentQueue.default().remove(self)
} }
func listProducts(completionHandler: (([SKProduct]) -> Void)?) { func listProducts(completionHandler: (([SKProduct]?, Error?) -> Void)?) {
inApp.requestProducts(withIdentifiers: Product.all) { _ in inApp.requestProducts(withIdentifiers: Product.all, completionHandler: { _ in
log.debug("In-app products: \(self.inApp.products.map { $0.productIdentifier })") log.debug("In-app products: \(self.inApp.products.map { $0.productIdentifier })")
completionHandler?(self.inApp.products) completionHandler?(self.inApp.products, nil)
} }, failureHandler: {
completionHandler?(nil, $0)
})
} }
func product(withIdentifier identifier: Product) -> SKProduct? { func product(withIdentifier identifier: Product) -> SKProduct? {

View File

@ -1048,6 +1048,12 @@ internal enum L10n {
} }
} }
internal enum Provider { internal enum Provider {
internal enum Alerts {
internal enum Unavailable {
/// Could not download provider infrastructure, please retry later.
internal static let message = L10n.tr("Core", "wizards.provider.alerts.unavailable.message")
}
}
internal enum Cells { internal enum Cells {
internal enum UpdateList { internal enum UpdateList {
/// Update list /// Update list

View File

@ -187,8 +187,12 @@ extension MFMailComposeViewController {
// FIXME: load from index JSON // FIXME: load from index JSON
extension Infrastructure.Metadata { extension Infrastructure.Metadata {
var logo: UIImage { var logo: UIImage? {
return ImageAsset(name: name.lowercased()).image let bundle = Bundle(for: AppDelegate.self)
guard let image = AssetImageTypeAlias(named: name.lowercased(), in: bundle, compatibleWith: nil) else {
return Asset.Providers.placeholder.image
}
return image
} }
} }

View File

@ -27,6 +27,9 @@ import UIKit
import StoreKit import StoreKit
import PassepartoutCore import PassepartoutCore
import Convenience import Convenience
import SwiftyBeaver
private let log = SwiftyBeaver.self
class DonationViewController: UITableViewController, StrongTableHost { class DonationViewController: UITableViewController, StrongTableHost {
private var donationList: [Product] = [] private var donationList: [Product] = []
@ -81,7 +84,11 @@ class DonationViewController: UITableViewController, StrongTableHost {
ProductManager.shared.listProducts { ProductManager.shared.listProducts {
self.isLoading = false self.isLoading = false
self.setProducts($0) guard let products = $0 else {
log.error("Unable to list products: \($1?.localizedDescription ?? "")")
return
}
self.setProducts(products)
} }
} }

View File

@ -474,13 +474,9 @@ extension OrganizerViewController {
let cell = Cells.setting.dequeue(from: tableView, for: indexPath) let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
let rowProfile = profileKey(at: indexPath) let rowProfile = profileKey(at: indexPath)
if rowProfile.context == .provider { if rowProfile.context == .provider {
if let metadata = InfrastructureFactory.shared.metadata(forName: rowProfile.id) { let metadata = InfrastructureFactory.shared.metadata(forName: rowProfile.id)
cell.imageView?.image = metadata.logo cell.imageView?.image = metadata?.logo
cell.leftText = metadata.description cell.leftText = metadata?.description ?? rowProfile.id
} else {
cell.imageView?.image = Asset.Providers.placeholder.image
cell.leftText = rowProfile.id
}
} else { } else {
cell.imageView?.image = nil cell.imageView?.image = nil
cell.leftText = rowProfile.id cell.leftText = rowProfile.id

View File

@ -58,23 +58,61 @@ class WizardProviderViewController: UITableViewController, StrongTableHost {
reloadModel() reloadModel()
} }
private func next(withMetadata metadata: Infrastructure.Metadata) { private func tryNext(withMetadata metadata: Infrastructure.Metadata) {
guard ProductManager.shared.isEligible(forProvider: metadata.name) else { guard ProductManager.shared.isEligible(forProvider: metadata.name) else {
presentPurchaseScreen(forProduct: metadata.product) presentPurchaseScreen(forProduct: metadata.product)
return return
} }
// make sure that infrastructure exists locally
guard let _ = InfrastructureFactory.shared.infrastructure(forName: metadata.name) else {
let hud = HUD(view: view)
_ = InfrastructureFactory.shared.update(metadata.name, notBeforeInterval: nil) { [weak self] in
hud.hide()
guard let _ = $0 else {
self?.alertMissingInfrastructure(forName: metadata.name, error: $1)
return
}
self?.next(withMetadata: metadata)
}
return
}
next(withMetadata: metadata)
}
private func next(withMetadata metadata: Infrastructure.Metadata) {
let profile = ProviderConnectionProfile(name: metadata.name) let profile = ProviderConnectionProfile(name: metadata.name)
createdProfile = profile createdProfile = profile
let accountVC = StoryboardScene.Main.accountIdentifier.instantiate() let accountVC = StoryboardScene.Main.accountIdentifier.instantiate()
let infrastructure = InfrastructureFactory.shared.infrastructure(forName: metadata.name) guard let infrastructure = InfrastructureFactory.shared.infrastructure(forName: metadata.name) else {
fatalError("Moving to credentials with nil infrastructure, not downloaded properly?")
}
accountVC.usernamePlaceholder = infrastructure.defaults.username accountVC.usernamePlaceholder = infrastructure.defaults.username
accountVC.infrastructureName = infrastructure.name accountVC.infrastructureName = infrastructure.name
accountVC.delegate = self accountVC.delegate = self
navigationController?.pushViewController(accountVC, animated: true) navigationController?.pushViewController(accountVC, animated: true)
} }
private func alertMissingInfrastructure(forName name: Infrastructure.Name, error: Error?) {
var message = L10n.Core.Wizards.Provider.Alerts.Unavailable.message
if let error = error {
log.error("Unable to download missing \(name) infrastructure (network error): \(error.localizedDescription)")
message.append(" \(error.localizedDescription)")
} else {
log.error("Unable to download missing \(name) infrastructure (API error)")
}
let alert = UIAlertController.asAlert(name, message)
alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
if let ip = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: ip, animated: true)
}
}
private func finish(withCredentials credentials: Credentials) { private func finish(withCredentials credentials: Credentials) {
guard let profile = createdProfile else { guard let profile = createdProfile else {
fatalError("No profile created?") fatalError("No profile created?")
@ -94,10 +132,14 @@ class WizardProviderViewController: UITableViewController, StrongTableHost {
return return
} }
ProductManager.shared.listProducts { _ in ProductManager.shared.listProducts { (products, error) in
hud.hide()
if let error = error {
log.error("Unable to list products: \(error)")
return
}
self?.reloadModel() self?.reloadModel()
self?.tableView.reloadData() self?.tableView.reloadData()
hud.hide()
} }
} }
} }
@ -153,7 +195,7 @@ extension WizardProviderViewController {
switch row { switch row {
case .provider: case .provider:
let metadata = available[indexPath.row] let metadata = available[indexPath.row]
next(withMetadata: metadata) tryNext(withMetadata: metadata)
case .updateList: case .updateList:
tableView.deselectRow(at: indexPath, animated: true) tableView.deselectRow(at: indexPath, animated: true)

View File

@ -90,7 +90,7 @@ class PurchaseViewController: UITableViewController, StrongTableHost {
super.viewDidAppear(animated) super.viewDidAppear(animated)
let hud = HUD(view: view) let hud = HUD(view: view)
ProductManager.shared.listProducts { [weak self] _ in ProductManager.shared.listProducts { [weak self] (_, _) in
self?.reloadModel() self?.reloadModel()
self?.isLoading = false self?.isLoading = false
self?.tableView.reloadData() self?.tableView.reloadData()

View File

@ -14,7 +14,7 @@ def shared_pods
pod 'SSZipArchive' pod 'SSZipArchive'
for spec in ['About', 'Alerts', 'Dialogs', 'InApp', 'Misc', 'Options', 'Persistence', 'Reviewer', 'Tables', 'WebServices'] do for spec in ['About', 'Alerts', 'Dialogs', 'InApp', 'Misc', 'Options', 'Persistence', 'Reviewer', 'Tables', 'WebServices'] do
pod "Convenience/#{spec}", :git => 'https://github.com/keeshux/convenience', :commit => '7fe7dcf' pod "Convenience/#{spec}", :git => 'https://github.com/keeshux/convenience', :commit => '3a191e8'
#pod "Convenience/#{spec}", :path => '../../personal/convenience' #pod "Convenience/#{spec}", :path => '../../personal/convenience'
end end
end end

View File

@ -36,16 +36,16 @@ PODS:
- TunnelKit/Core - TunnelKit/Core
DEPENDENCIES: DEPENDENCIES:
- Convenience/About (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/About (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/Alerts (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/Alerts (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/Dialogs (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/Dialogs (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/InApp (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/InApp (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/Misc (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/Misc (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/Options (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/Options (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/Persistence (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/Persistence (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/Reviewer (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/Reviewer (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/Tables (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/Tables (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Convenience/WebServices (from `https://github.com/keeshux/convenience`, commit `7fe7dcf`) - Convenience/WebServices (from `https://github.com/keeshux/convenience`, commit `3a191e8`)
- Kvitto - Kvitto
- MBProgressHUD - MBProgressHUD
- SSZipArchive - SSZipArchive
@ -63,7 +63,7 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
Convenience: Convenience:
:commit: 7fe7dcf :commit: 3a191e8
:git: https://github.com/keeshux/convenience :git: https://github.com/keeshux/convenience
TunnelKit: TunnelKit:
:commit: 8b17a13 :commit: 8b17a13
@ -71,7 +71,7 @@ EXTERNAL SOURCES:
CHECKOUT OPTIONS: CHECKOUT OPTIONS:
Convenience: Convenience:
:commit: 7fe7dcf :commit: 3a191e8
:git: https://github.com/keeshux/convenience :git: https://github.com/keeshux/convenience
TunnelKit: TunnelKit:
:commit: 8b17a13 :commit: 8b17a13
@ -87,6 +87,6 @@ SPEC CHECKSUMS:
SwiftyBeaver: 3d3e93a12d648bd400b6f2948a7ef128b5b183c7 SwiftyBeaver: 3d3e93a12d648bd400b6f2948a7ef128b5b183c7
TunnelKit: 4b70c0d8b6727b407248b4271b7613225f63204b TunnelKit: 4b70c0d8b6727b407248b4271b7613225f63204b
PODFILE CHECKSUM: 10c7cb879b6ee3d5185f541e6a2c6d14e988ff0b PODFILE CHECKSUM: 5b0c1f2c23e4a3ffa33152e231291a97351d7165
COCOAPODS: 1.8.4 COCOAPODS: 1.8.4

@ -1 +1 @@
Subproject commit 5e25f768fb66832c4a539e7ff6ba7fa80d918a12 Subproject commit ad0c3922813e0e7261e2e90e8386604abb5cd9c5