web-dev-qa-db-ja.com

Swift 3であなた自身のエラーコードを生成する

私が達成しようとしているのは、Swift 3でURLSessionリクエストを実行することです。(GETとPOSTに別々にコードを書かないように)このアクションを別の関数で実行し、URLSessionDataTaskを返してクロージャーで成功と失敗を処理。このようなソート -

let task = URLSession.shared.dataTask(with: request) { (data, uRLResponse, responseError) in

     DispatchQueue.main.async {

          var httpResponse = uRLResponse as! HTTPURLResponse

          if responseError != nil && httpResponse.statusCode == 200{

               successHandler(data!)

          }else{

               if(responseError == nil){
                     //Trying to achieve something like below 2 lines
                     //Following line throws an error soo its not possible
                     //var errorTemp = Error(domain:"", code:httpResponse.statusCode, userInfo:nil)

                     //failureHandler(errorTemp)

               }else{

                     failureHandler(responseError!)
               }
          }
     }
}

この関数のエラー状態を処理したくないので、応答コードを使用してエラーを生成し、このエラーが返されてこの関数が呼び出された場所ならどこでもそれを処理します。誰もがこれをどうやって行けばいいのか教えてもらえますか?それとも、そのような状況に対処するための「迅速な」方法ではありませんか。

58
Rikh

あなたの場合、エラーはあなたがErrorインスタンスを生成しようとしているということです。 Swift 3のErrorは、カスタムエラーを定義するために使用できるプロトコルです。この機能は特に純粋なSwiftアプリケーションが異なるOS上で動作するためのものです。

IOSの開発ではNSErrorクラスはまだ利用可能で、Errorプロトコルに準拠しています。

あなたの目的がこのエラーコードを伝播することだけであるのであれば、あなたは簡単に置き換えることができます

var errorTemp = Error(domain:"", code:httpResponse.statusCode, userInfo:nil)

var errorTemp = NSError(domain:"", code:httpResponse.statusCode, userInfo:nil)

それ以外の場合は、カスタムエラータイプの作成方法についてSandeep Bhandarianswer を確認してください。

79
Luca D'Alberti

SwiftのLocalizedErrorプロトコルに準拠したプロトコルを、次の値で作成できます。

protocol OurErrorProtocol: LocalizedError {

    var title: String? { get }
    var code: Int { get }
}

これにより、次のような具体的なエラーを作成できます。

struct CustomError: OurErrorProtocol {

    var title: String?
    var code: Int
    var errorDescription: String? { return _description }
    var failureReason: String? { return _description }

    private var _description: String

    init(title: String?, description: String, code: Int) {
        self.title = title ?? "Error"
        self._description = description
        self.code = code
    }
}
57
Harry Bloom

あなたはエラーを処理するためにenumを作成することができます:)

enum RikhError: Error {
    case unknownError
    case connectionError
    case invalidCredentials
    case invalidRequest
    case notFound
    case invalidResponse
    case serverError
    case serverUnavailable
    case timeOut
    case unsuppotedURL
 }

そして、HTTPレスポンスコードを受け取り、それに対応するエラーを返すように、enum内にメソッドを作成します。

static func checkErrorCode(_ errorCode: Int) -> RikhError {
        switch errorCode {
        case 400:
            return .invalidRequest
        case 401:
            return .invalidCredentials
        case 404:
            return .notFound
        //bla bla bla
        default:
            return .unknownError
        }
    }

最後に、RikhError型の単一パラメータを受け入れるように失敗ブロックを更新します。

ここではSwift3を使用して、従来のObjective-Cベースのオブジェクト指向ネットワークモデルを最新のプロトコル指向モデルに再構築する方法について詳細なチュートリアルを提供しています https://learnwithmehere.blogspot.in ご覧ください。

それが役に立てば幸い :)

38

NSErrorオブジェクトを使うべきです。

let error = NSError(domain:"", code:401, userInfo:[ NSLocalizedDescriptionKey: "Invalid access token"])

それからNSErrorをErrorオブジェクトにキャストします

27
Ahmed Lotfy

LocalizedErrorを実装します。

struct StringError : LocalizedError
{
    var errorDescription: String? { return mMsg }
    var failureReason: String? { return mMsg }
    var recoverySuggestion: String? { return "" }
    var helpAnchor: String? { return "" }

    private var mMsg : String

    init(_ description: String)
    {
        mMsg = description
    }
}

たとえば、答えの1つで説明されているように単純にErrorを実装すると失敗し(少なくともSwift 3では)、localizedDescriptionを呼び出すと文字列 "操作を完了できませんでした。(.StringError error 1.)"が返されます。 「

14
prewett

私はあなたがすでに答えに満足していることを知っていますが、あなたが正しいアプローチを知ることに興味があるなら、これはあなたにとって役に立つかもしれません。 http-responseのエラーコードとエラーオブジェクトのエラーコードを混同しないようにします(混乱しましたか?もう少し読んでください...)。

Httpレスポンスコードは、レスポンスが受信されたときの一般的な状況を定義するhttpレスポンスに関する標準エラーコードであり、1xxから5xxまで変化する(例えば、200 OK、408リクエストタイムアウト、504ゲートウェイタイムアウトなど - http:// www。 restapitutorial.com/httpstatuscodes.html

NSErrorオブジェクトのエラーコードは、オブジェクトがアプリケーション/製品/ソフトウェアの特定のドメインについて記述するエラーの種類を非常に具体的に識別します。例えば、あなたのアプリケーションは "このレコードを1日に複数回更新することはできません"に1000を使用したり、 "このリソースにアクセスするには管理者の役割が必要です"と1001と言います。論理。

非常に小さなアプリケーションでは、これら2つの概念がマージされることがあります。しかしそれらはあなたが見ることができるように完全に異なっていて、そして大規模なソフトウェアを設計しそして働くために非常に重要で助けになります。

そのため、コードをより適切に処理するには2つの方法があります。

1.完了コールバックはすべてのチェックを行います

completionHandler(data, httpResponse, responseError) 

あなたのメソッドは成功とエラーの状況を決定してから対応するコールバックを呼び出します

if nil == responseError { 
   successCallback(data)
} else {
   failureCallback(data, responseError) // failure can have data also for standard REST request/response APIs
}

ハッピーコーディング:)

1
Tushar
protocol CustomError : Error {

    var localizedTitle: String
    var localizedDescription: String

}

enum RequestError : Int, Error {

    case badRequest         = 400
    case loginFailed        = 401
    case userDisabled       = 403
    case notFound           = 404
    case methodNotAllowed   = 405
    case serverError        = 500
    case noConnection       = -1009
    case timeOutError       = -1001

}

func anything(errorCode: Int) -> CustomError? {

      return RequestError(rawValue: errorCode)
}
1
Daniel.scheibe
 let error = NSError(domain:"", code:401, userInfo:[ NSLocalizedDescriptionKey: "Invaild UserName or Password"]) as Error
            self.showLoginError(error)

nSErrorオブジェクトを作成してErrorに型キャストし、どこにでも表示する

private func showLoginError(_ error: Error?) {
    if let errorObj = error {
        UIAlertController.alert("Login Error", message: errorObj.localizedDescription).action("OK").presentOn(self)
    }
}
1
Suraj K Thomas