2016-11-18 65 views
22

我所試圖實現的是執行迅速3. URLSession要求我在一個單獨的函數執行此操作(從而不單獨編寫代碼GET和POST)和返回URLSessionDataTask並處理關閉中的成功和失敗。有點像這個 -生成自己的錯誤代碼SWIFT 3

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!) 
       } 
      } 
    } 
} 

我不想處理這個函數的錯誤條件,並希望使用響應代碼產生錯誤並返回該錯誤來處理它無論這個功能是從調用。 有人可以告訴我該怎麼做?或者,這不是處理這種情況的「快速」方式嗎?

+0

嘗試在聲明中使用'NSError',而不是'Error'( 'var errorTemp = NSError(...)') –

+0

解決了這個問題,但是我認爲swift 3不希望繼續使用NS? – Rikh

+0

它在iOS開發中有用,對於純Swift開發,你應該創建你自己的錯誤實例通過符合'錯誤'協議 –

回答

41

在你的情況導向模式,錯誤是你想生成Error實例。 Swift 3中的Error是一個可用於定義自定義錯誤的協議。此功能特別適用於在不同操作系統上運行的純Swift應用程序。

在iOS開發的NSError類仍然可用,它符合Error協議。

所以,如果你的目的只是爲了傳播這種錯誤代碼,你可以很容易地更換

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

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

否則檢查桑迪普班達answer關於如何創建自定義錯誤類型

+0

我同意:)因此,投票:) –

19

您可以創建枚舉處理錯誤:)

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

,然後創建內部枚舉的方法來接收HTTP響應代碼,作爲回報:)

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 :)

的單一參數我對如何重組傳統的目的一個詳細的教程 - 基於C Objec牛逼面向網絡模型,以現代協議使用Swift3這裏https://learnwithmehere.blogspot.in看一看:)

希望它能幫助:)

+0

啊,但這不得不讓我手動處理所有的情況?那是鍵入錯誤代碼? – Rikh

+0

是的,你必須:D但在同一時間,你可以採取各種具體到每個錯誤狀態的行動:)現在你有一個很好的控制錯誤模型,如果你不想這樣做,你可以使用案例400 ... 404 {...}處理一般情況:) –

+0

啊!謝謝 – Rikh

1

我知道你已經滿意的答案,但如果你是INTE休息以瞭解正確的方法,那麼這可能對你有幫助。 我不希望在錯誤對象中混入http-響應錯誤代碼和錯誤代碼(困惑?請繼續閱讀一下...)。

HTTP響應碼時,接收到的響應,並從1XX變化到5XX約爲HTTP響應限定通用情形標準錯誤碼(例如200行,408請求超時,504網關超時等 - http://www.restapitutorial.com/httpstatuscodes.html

NSError對象中的錯誤代碼爲對象描述的特定應用程序/產品/軟件域的錯誤類型提供了非常具體的標識。例如,您的應用程序可能會使用1000作爲「對不起,您無法在一天內多次更新此記錄」,或者說1001「您需要管理員角色才能訪問此資源」...這些特定於您的域/應用程序邏輯。

對於一個非常小的應用程序,有時這兩個概念被合併。但它們完全不同,因爲您可以看到並且非常重要的設計和使用大型軟件很有幫助。

所以,可以有兩種方法來處理更好的辦法代碼:

1.完成回調將執行所有的檢查

completionHandler(data, httpResponse, responseError) 

2.你的方法決定成功和錯誤情況,然後調用對應的回調

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

快樂編碼:)

+0

因此,基本上你想說的是傳遞「數據」參數,以防從服務器返回特定錯誤代碼的情況下顯示一些特定的字符串? (對不起,我有時可能有點慢!) – Rikh

28

您可以創建一個協議,符合雨燕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 
    } 
} 
+2

這應該是被接受的答案。 – alicanbatur

+2

a)沒有必要創建OurErrorProtocol,只是讓CustomError直接實現Error。 b)這是行不通的(至少在Swift 3中:localizedDescription從來沒有被調用過,你會得到「操作無法完成」)。您需要改爲實現LocalizedError;看到我的答案。 – prewett

+0

@prewett我剛剛注意到,但你是對的!在LocalizedError中實現errorDescription字段實際上設置了消息,而不是像上面描述的那樣使用我的方法。 雖然我仍然保留「OurErrorProtocol」包裝,因爲我還需要localizedTitle字段。感謝您指出了這一點! –

6

實施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 
    } 
} 

請注意,簡單地實現Error,例如,如其中一個答案所述,將會失敗(至少在Swift 3中),並調用l ocalizedDescription將導致字符串「操作無法完成。 (.StringError錯誤1)」

+0

應該是mMsg =味精 – Brett

+1

糟糕,沒錯。我將「msg」改爲「description」,希望比我原來的更清晰。 – prewett

+0

你可以減少到'struct StringError:LocalizedError {public let errorDescription:String? }',並簡單地使用'StringError(error描述:「某個消息」)'' –

1

您應該使用NSError對象。

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

再投NSError到錯誤對象