Created
December 28, 2016 07:33
-
-
Save banjun/da559f37b742cba79a13df3a748767fc to your computer and use it in GitHub Desktop.
App Transport Security (ATS) connection test & report
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Eureka | |
import SVProgressHUD | |
import BrightFutures | |
class ViewController: FormViewController { | |
init() { | |
super.init(style: .grouped) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
edgesForExtendedLayout = [] // for screenshot | |
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(share)) | |
func urlRow(_ url: String) -> LabelRow { | |
return LabelRow() { | |
$0.title = url | |
$0.cellStyle = .value1 | |
$0.cell.selectionStyle = .default | |
$0.onCellSelection { cell, row in | |
row.deselect(animated: true) | |
self.connect(URL(string: url)!) | |
.onSuccess { status in | |
row.value = "Status: \(status)" | |
cell.detailTextLabel?.textColor = #colorLiteral(red: 0.2745098174, green: 0.4862745106, blue: 0.1411764771, alpha: 1) | |
}.onFailure { error in | |
switch error { | |
case .ats: | |
row.value = "Blocked by ATS" | |
cell.detailTextLabel?.textColor = #colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1) | |
case let .ssl(e): | |
row.value = e.localizedDescription | |
cell.detailTextLabel?.textColor = #colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1) | |
case let .other(e): | |
row.value = e?.localizedDescription | |
cell.detailTextLabel?.textColor = #colorLiteral(red: 0.7254902124, green: 0.4784313738, blue: 0.09803921729, alpha: 1) | |
} | |
}.onComplete {_ in row.reload()} | |
} | |
} | |
} | |
form +++ Section("Current ATS Settings") | |
<<< TextAreaRow() { | |
$0.value = Bundle.main.infoDictionary!["NSAppTransportSecurity"].map {String(describing: $0)} ?? "nothing" | |
$0.disabled = true | |
} | |
+++ Section("Connection Tests") | |
<<< urlRow("https://google.com/") | |
<<< urlRow("http://google.com/") | |
<<< urlRow("http://banjun.local/") | |
<<< urlRow("http://banjun.local./") | |
<<< urlRow("http://banjun/") | |
<<< urlRow("http://127.0.0.1/") | |
} | |
enum ConnectionError: Error { | |
case ats | |
case ssl(Error) | |
case other(Error?) | |
} | |
func connect(_ url: URL) -> Future<Int, ConnectionError> { | |
let p = Promise<Int, ConnectionError>() | |
SVProgressHUD.show(withStatus: url.absoluteString) | |
let task = URLSession.shared.dataTask(with: url) { data, response, error in | |
SVProgressHUD.dismiss() | |
let status = (response as? HTTPURLResponse)?.statusCode | |
if let s = status { | |
p.success(s) | |
} else { | |
let e = error as? NSError | |
switch (e?.domain, e?.code) { | |
case (NSURLErrorDomain?, NSURLErrorAppTransportSecurityRequiresSecureConnection?): | |
p.failure(.ats) | |
case (NSURLErrorDomain?, (NSURLErrorCannotLoadFromNetwork...NSURLErrorSecureConnectionFailed)?): | |
p.failure(.ssl(e!) default: | |
p.failure(.other(e)) | |
} | |
} | |
} | |
task.resume() | |
return p.future | |
} | |
func share() { | |
guard let tv = tableView else { return } | |
let prevFrame = tv.frame | |
tv.frame = CGRect(origin: .zero, size: tv.contentSize) | |
tv.reloadData() | |
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { // 遅らせる(為念) | |
UIGraphicsBeginImageContextWithOptions(tv.contentSize, false, 0) | |
tv.layer.render(in: UIGraphicsGetCurrentContext()!) | |
let image = UIGraphicsGetImageFromCurrentImageContext()! | |
UIGraphicsEndImageContext() | |
let ac = UIActivityViewController(activityItems: [image], applicationActivities: nil) | |
ac.completionWithItemsHandler = { _ in | |
tv.frame = prevFrame | |
} | |
self.present(ac, animated: true) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment