結論
例えば次のようなExtensionどうよ、というのを思いついた。
extension Error {
var isTimeOut: Bool {
let nsError = self as NSError
return (nsError.domain == NSURLErrorDomain && nsError.code == NSURLErrorTimedOut) ? true : false
}
}
導入
FoundationのNSErrorでタイムアウトかどうかを判定する時、ErrorをNSErrorにキャストしてたりすると処理が冗長になったりする。
例えばこんな感じ
let nsError as error
if nsError.domain == NSURLErrorDomain && nsError.code == NSURLErrorTimedOut {
// タイムアウト
}
このような2つの定数と比較するの短くしたいよねっていう思いつきの話です。
んで、APIKitを使っていると、SessionTaskErrorのenumからErrorを取り出さないといけなかったりする。
// APIKitのSessionTaskError
public enum SessionTaskError: Error {
/// Error of `URLSession`.
case connectionError(Error)
/// Error while creating `URLReqeust` from `Request`.
case requestError(Error)
/// Error while creating `Request.Response` from `(Data, URLResponse)`.
case responseError(Error)
}
ViewControllerでエラーに従ってハンドリングしたくなった場合はViewControllerでまずerrorを取り出して...とかやってるとコード読むの大変だなと。
if let error = error {
if case .connectionError(let urlSessionError) = error, nsError.domain == NSURLErrorDomain && nsError.code == NSURLErrorTimedOut)
urlSessionError.isTimeOut {
なので、最初の結論に上げたようにExtensionでやったらどうなのよってのを思いついたわけです。
もちろん最初のコードは一行で書けるのでそこは好みや決めでいいとは思います。
extension Error {
var isTimeOut: Bool {
return (self as NSError).domain == NSURLErrorDomain && (self as NSError).code == NSURLErrorTimedOut
}
}
最初、何で三項演算子使ってたかというと、条件判定の.domainと.codeが条件通りかどうかというのと、このメソッドがtrueかfalse返すのは結果がたまたま同じだから、その結果は別という考えがあるからです。理解されないかもしれないけど、条件は条件、結果は結果として表現したい。だからそのまま結果を返さなかったというわけです。
みなさんはどんな感じでしょうか?
追記
こうすれば簡単に比較できるんでextensionなんて作らないほうが良さそうですね...
if let error = self as? URLError, error.code == URLError.timedOut {
return true
}
as URLError とか as CocoaError としてやると、codeにenum型がついていいですよ
— おもちメタル (@omochimetaru) 2018年11月28日