Apa yang saya coba capai adalah melakukan URLSession
permintaan dengan cepat 3. Saya melakukan tindakan ini dalam fungsi terpisah (agar tidak menulis kode secara terpisah untuk GET dan POST) dan mengembalikan URLSessionDataTask
serta menangani keberhasilan dan kegagalan dalam penutupan. Semacam seperti ini-
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!)
}
}
}
}
Saya tidak ingin menangani kondisi kesalahan dalam fungsi ini dan ingin menghasilkan kesalahan menggunakan kode respons dan mengembalikan Kesalahan ini untuk menanganinya dari mana pun fungsi ini dipanggil. Adakah yang bisa memberi tahu saya bagaimana melakukan ini? Atau bukankah ini cara "Cepat" untuk menangani situasi seperti itu?
ios
swift3
nsurlsession
Rikh
sumber
sumber
NSError
alih-alihError
di deklarasi (var errorTemp = NSError(...)
)Error
protokolJawaban:
Anda dapat membuat protokol, sesuai dengan
LocalizedError
protokol Swift , dengan nilai-nilai berikut:protocol OurErrorProtocol: LocalizedError { var title: String? { get } var code: Int { get } }
Ini kemudian memungkinkan kita untuk membuat kesalahan konkret seperti:
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 } }
sumber
Dalam kasus Anda, kesalahannya adalah Anda mencoba membuat sebuah
Error
instance.Error
di Swift 3 adalah protokol yang dapat digunakan untuk menentukan kesalahan khusus. Fitur ini khusus untuk aplikasi Swift murni yang dijalankan pada OS yang berbeda.Dalam pengembangan iOS,
NSError
kelas masih tersedia dan sesuai denganError
protokol.Jadi, jika tujuan Anda hanya untuk menyebarkan kode kesalahan ini, Anda dapat dengan mudah mengganti
var errorTemp = Error(domain:"", code:httpResponse.statusCode, userInfo:nil)
dengan
var errorTemp = NSError(domain:"", code:httpResponse.statusCode, userInfo:nil)
Jika tidak memeriksa Sandeep Bhandari 's jawaban tentang bagaimana untuk membuat jenis kesalahan kustom
sumber
Error cannot be created because it has no accessible initializers
.Error
, tapiNSError
. Tentu saja menggunakanError
lemparan kesalahan.Anda dapat membuat enum untuk menangani kesalahan :)
enum RikhError: Error { case unknownError case connectionError case invalidCredentials case invalidRequest case notFound case invalidResponse case serverError case serverUnavailable case timeOut case unsuppotedURL }
dan kemudian buat metode di dalam enum untuk menerima kode respons http dan mengembalikan kesalahan yang sesuai :)
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 } }
Terakhir, perbarui blok kegagalan Anda untuk menerima parameter tunggal tipe RikhError :)
Saya memiliki tutorial mendetail tentang cara merestrukturisasi model jaringan Objective - C berbasis Object Oriented tradisional menjadi model Protocol Oriented modern menggunakan Swift3 di sini https://learnwithmehere.blogspot.in Lihat :)
Semoga membantu :)
sumber
Anda harus menggunakan objek NSError.
let error = NSError(domain:"", code:401, userInfo:[ NSLocalizedDescriptionKey: "Invalid access token"])
Kemudian transmisikan NSError ke objek Error
sumber
Detail
Solusi kesalahan pengorganisasian dalam suatu aplikasi
import Foundation enum AppError { case network(type: Enums.NetworkError) case file(type: Enums.FileError) case custom(errorDescription: String?) class Enums { } } extension AppError: LocalizedError { var errorDescription: String? { switch self { case .network(let type): return type.localizedDescription case .file(let type): return type.localizedDescription case .custom(let errorDescription): return errorDescription } } } // MARK: - Network Errors extension AppError.Enums { enum NetworkError { case parsing case notFound case custom(errorCode: Int?, errorDescription: String?) } } extension AppError.Enums.NetworkError: LocalizedError { var errorDescription: String? { switch self { case .parsing: return "Parsing error" case .notFound: return "URL Not Found" case .custom(_, let errorDescription): return errorDescription } } var errorCode: Int? { switch self { case .parsing: return nil case .notFound: return 404 case .custom(let errorCode, _): return errorCode } } } // MARK: - FIle Errors extension AppError.Enums { enum FileError { case read(path: String) case write(path: String, value: Any) case custom(errorDescription: String?) } } extension AppError.Enums.FileError: LocalizedError { var errorDescription: String? { switch self { case .read(let path): return "Could not read file from \"\(path)\"" case .write(let path, let value): return "Could not write value \"\(value)\" file from \"\(path)\"" case .custom(let errorDescription): return errorDescription } } }
Pemakaian
//let err: Error = NSError(domain:"", code: 401, userInfo: [NSLocalizedDescriptionKey: "Invaild UserName or Password"]) let err: Error = AppError.network(type: .custom(errorCode: 400, errorDescription: "Bad request")) switch err { case is AppError: switch err as! AppError { case .network(let type): print("Network ERROR: code \(type.errorCode), description: \(type.localizedDescription)") case .file(let type): switch type { case .read: print("FILE Reading ERROR") case .write: print("FILE Writing ERROR") case .custom: print("FILE ERROR") } case .custom: print("Custom ERROR") } default: print(err) }
sumber
Terapkan 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 } }
Perhatikan bahwa menerapkan Error, misalnya, seperti yang dijelaskan di salah satu jawaban, akan gagal (setidaknya di Swift 3), dan memanggil localizedDescription akan menghasilkan string "Operasi tidak dapat diselesaikan. (.StringError error 1.) "
sumber
struct StringError : LocalizedError { public let errorDescription: String? }
, dan itu hanya digunakan sebagaiStringError(errorDescription: "some message")
let error = NSError(domain:"", code:401, userInfo:[ NSLocalizedDescriptionKey: "Invaild UserName or Password"]) as Error self.showLoginError(error)
buat objek NSError dan ketik ke Error, tunjukkan di mana saja
private func showLoginError(_ error: Error?) { if let errorObj = error { UIAlertController.alert("Login Error", message: errorObj.localizedDescription).action("OK").presentOn(self) } }
sumber
Saya masih berpikir bahwa jawaban Harry adalah yang paling sederhana dan lengkap tetapi jika Anda membutuhkan sesuatu yang lebih sederhana, gunakan:
struct AppError { let message: String init(message: String) { self.message = message } } extension AppError: LocalizedError { var errorDescription: String? { return message } // var failureReason: String? { get } // var recoverySuggestion: String? { get } // var helpAnchor: String? { get } }
Dan gunakan atau uji seperti ini:
printError(error: AppError(message: "My App Error!!!")) func print(error: Error) { print("We have an ERROR: ", error.localizedDescription) }
sumber
protocol CustomError : Error { var localizedTitle: String var localizedDescription: String } enum RequestError : Int, CustomError { 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) }
sumber
Saya tahu Anda sudah puas dengan sebuah jawaban tetapi jika Anda tertarik untuk mengetahui pendekatan yang tepat, maka ini mungkin berguna untuk Anda. Saya lebih suka untuk tidak mencampur kode kesalahan http-respon dengan kode kesalahan di objek kesalahan (bingung? Lanjutkan membaca sedikit ...).
Kode respons http adalah kode kesalahan standar tentang respons http yang menentukan situasi umum saat respons diterima dan bervariasi dari 1xx hingga 5xx (misalnya 200 OK, 408 Permintaan habis waktu, 504 Gateway timeout, dll - http://www.restapitutorial.com/ httpstatuscodes.html )
Kode kesalahan dalam objek NSError memberikan identifikasi yang sangat spesifik untuk jenis kesalahan yang dijelaskan objek untuk domain aplikasi / produk / perangkat lunak tertentu. Misalnya aplikasi Anda dapat menggunakan 1000 untuk "Maaf, Anda tidak dapat memperbarui catatan ini lebih dari sekali dalam sehari" atau mengatakan 1001 untuk "Anda memerlukan peran manajer untuk mengakses sumber daya ini" ... yang khusus untuk domain / aplikasi Anda logika.
Untuk aplikasi yang sangat kecil, terkadang kedua konsep ini digabungkan. Tetapi mereka sama sekali berbeda seperti yang Anda lihat dan sangat penting & membantu untuk merancang dan bekerja dengan perangkat lunak besar.
Jadi, ada dua teknik untuk menangani kode dengan cara yang lebih baik:
1. Callback penyelesaian akan melakukan semua pemeriksaan
2. Metode Anda menentukan situasi sukses dan kesalahan dan kemudian memanggil callback yang sesuai
if nil == responseError { successCallback(data) } else { failureCallback(data, responseError) // failure can have data also for standard REST request/response APIs }
Selamat coding :)
sumber