দ্রুত 3 এ আপনার নিজস্ব ত্রুটি কোড তৈরি করুন


91

আমি যা অর্জনের চেষ্টা করছি তা হ'ল URLSessionদ্রুতগতিতে একটি অনুরোধ সম্পাদন করা I আমি এই ক্রিয়াটি একটি পৃথক ফাংশনে সম্পাদন করছি (যাতে জিইটি এবং পোষ্টের জন্য আলাদাভাবে কোডটি লেখা না হয়) এবং ফিরে আসা 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!)
               }
          }
     }
}

আমি এই ফাংশনটিতে ত্রুটির শর্তটি পরিচালনা করতে চাই না এবং প্রতিক্রিয়া কোডটি ব্যবহার করে একটি ত্রুটি উত্পন্ন করতে চাই এবং এই ক্রিয়াকলাপটি যেখানেই ডেকে আনা হয়েছে সেখানে হ্যান্ডেল করতে এই ত্রুটিটি ফিরিয়ে আনতে চাই না। কেউ আমাকে কীভাবে এটি সম্পর্কে বলতে পারেন? বা এই জাতীয় পরিস্থিতি পরিচালনার জন্য এটি কি "সুইফট" উপায় নয়?


ঘোষণার NSErrorপরিবর্তে Error( var errorTemp = NSError(...))
লুকা ডি'এলবার্টি

এটি সমস্যার সমাধান করে তবে আমি ভেবেছিলাম যে সুইফট 3 এনএস ব্যবহার করে চালিয়ে যেতে চান না?
রখ

এটি আইওএস বিকাশে করে। খাঁটি সুইফ্ট বিকাশের জন্য আপনার নিজের ত্রুটি উদাহরণটি Errorপ্রোটোকল অনুসারে তৈরি করতে হবে
লুকা ডি'এলবার্টি

@ লুকাড 'আলবার্তি ঠিক আছে আপনার সমাধান সমস্যার সমাধান করেছে, এটিকে উত্তর হিসাবে নির্দ্বিধায় যোগ করুন যাতে আমি এটি গ্রহণ করতে পারি!
রিখ

উত্তর:


74

আপনি 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
    }
}

4
ক) আওয়ারআরপ্রোটোকল তৈরি করার দরকার নেই, কাস্টমআরারের সরাসরি ত্রুটি কার্যকর করা উচিত। খ) এটি কাজ করে না (কমপক্ষে সুইফ্ট 3 এ: স্থানীয়ীকৃত বিবরণ কখনই কল করা হয় না এবং আপনি "ক্রিয়াকলাপটি শেষ করতে পারেনি।") পান। পরিবর্তে আপনাকে লোকালাইজড এয়ারার প্রয়োগ করতে হবে; আমার উত্তর দেখুন।
প্রিভিট

@ প্রিভিট আমি ঠিক লক্ষ্য করেছি কিন্তু আপনি ঠিক বলেছেন! স্থানীয়করণেরে ত্রুটির বিবরণ ক্ষেত্রটি বাস্তবায়িত করে উপরে বর্ণিত হিসাবে আমার পদ্ধতিটি ব্যবহার না করে বার্তাটি সেট করে। আমি এখনও "আওয়ারআরপ্রোটোকল" র‌্যাপারটি রাখছি, কারণ আমার পাশাপাশি স্থানীয়করণের শীর্ষস্থানীয় ক্ষেত্রও প্রয়োজন। যে ইশারা জন্য ধন্যবাদ!
হ্যারি ব্লুম

106

আপনার ক্ষেত্রে, ত্রুটিটি হ'ল আপনি Errorউদাহরণ তৈরি করার চেষ্টা করছেন । Errorসুইফ্ট 3 এ এমন একটি প্রোটোকল যা কাস্টম ত্রুটির সংজ্ঞা দিতে ব্যবহৃত হতে পারে। এই বৈশিষ্ট্যটি বিশেষত খাঁটি সুইফট অ্যাপ্লিকেশনগুলির জন্য বিভিন্ন ওএসে চালিত হয়।

আইওএস বিকাশে NSErrorক্লাসটি এখনও উপলব্ধ এবং এটি Errorপ্রোটোকল অনুসারে।

সুতরাং, যদি আপনার উদ্দেশ্য কেবল এই ত্রুটি কোডটি প্রচার করা হয় তবে আপনি সহজেই প্রতিস্থাপন করতে পারেন

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

সঙ্গে

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

অন্যথায় কীভাবে কাস্টম ত্রুটি টাইপ তৈরি করবেন সে সম্পর্কে সন্দীপ ভান্ডারীর উত্তরটি পরীক্ষা করে দেখুন


15
আমি শুধু ভুল পান: Error cannot be created because it has no accessible initializers
সুপারট্যাকনোবফ

@ অভিষেক থাপলিয়াল দয়া করে আপনার মন্তব্যটি আরও কিছুটা ব্যাখ্যা করতে পারেন? আমি কী বলতে চাইছি তা বুঝতে পারছি না।
লুকা ডি'এলবার্টি

4
সুইচ 4-তে লুকাড'এলবার্টি যেমন এর ত্রুটি তৈরি করা যায় না কারণ ত্রুটি অবজেক্ট তৈরি করার সময় এটির কোনও অ্যাক্সেসযোগ্য আরম্ভকারী নেই।
মাহীপ

4
@ মাহীপ আমি আমার উত্তরে যা পরামর্শ দিচ্ছি তা ব্যবহার করা নয় Error, তবে NSError। অবশ্যই ব্যবহার করে Errorএকটি ত্রুটি ছুঁড়েছে।
লুকা

ত্রুটি হ'ল প্রোটোকল। সরাসরি ইনস্ট্যান্ট করা যাবে না।
স্লোবোডানস

52

আপনি ত্রুটি মোকাবেলা করতে enums তৈরি করতে পারেন :)

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

এবং তারপরে এনএমএসের অভ্যন্তরে একটি পদ্ধতি তৈরি করুন যাতে প্রতিক্রিয়া কোডটি পাওয়া যায় এবং বিনিময়ে সংশ্লিষ্ট ত্রুটিটি ফিরে পাওয়া যায় :)

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

রাইখেরর টাইপের একক প্যারামিটার গ্রহণ করতে অবশেষে আপনার ব্যর্থতা ব্লকটি আপডেট করুন :)

আমার এখানে কীভাবে traditionalতিহ্যবাহী উদ্দেশ্য - সি ভিত্তিক অবজেক্ট ওরিয়েন্টেড নেটওয়ার্ক মডেলটিকে আধুনিক প্রোটোকল ওরিয়েন্টেড মডেলটিতে সুইফট 3 ব্যবহার করে পুনর্গঠন করা যায় তার একটি বিশদ টিউটোরিয়াল আছে এখানে দেখুন https://learnwithmehere.blogspot.in দেখুন :)

আশা করি এটা সাহায্য করবে :)


আহ তবে কি আমাকে নিজে সব মামলা পরিচালনা করতে হবে না? ত্রুটি কোড টাইপ করা হয়?
রিখ

হ্যাঁ আপনাকে করতে হবে: ডি তবে একই সাথে আপনি প্রতিটি ত্রুটির স্থিতির সাথে সম্পর্কিত বিভিন্ন ক্রিয়া গ্রহণ করতে পারেন :) এখন আপনার ত্রুটি মডেলটির উপর নিয়ন্ত্রণ রয়েছে যদি আপনি এটি করতে না চান তবে আপনি কেস 400 ব্যবহার করতে পারেন ... 404 {... just কেবল জেনেরিক কেসগুলি হ্যান্ডেল করুন :)
সন্দীপ ভান্ডারী

আহ্ হাঁ! ধন্যবাদ
রিখ

একাধিক এইচটি কোড কোড ধরে নিলে একই ক্ষেত্রে আপনি কেবল রিখেরর করতে পারবেন: ইন্ট, ত্রুটি {কেস অবৈধ = 400} এবং তারপরে এটি রিকআরার তৈরি করতে (কাঁচা মূল্য: httpCode)
ব্রায়ান এফ লেটি

51

আপনার এনএসইরর অবজেক্টটি ব্যবহার করা উচিত।

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

তারপরে এনএসইররকে ত্রুটিযুক্ত বস্তুতে কাস্ট করুন


29

বিশদ

  • এক্সকোড সংস্করণ 10.2.1 (10E1001)
  • সুইফট 5

কোনও অ্যাপে ত্রুটিগুলি সংগঠিত করার সমাধান

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

ব্যবহার

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

16

স্থানীয়ায়িত ত্রুটি প্রয়োগ করুন:

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

নোট করুন যে সহজভাবে প্রয়োগের ত্রুটি, উদাহরণস্বরূপ, উত্তরের একটিতে বর্ণিত হিসাবে ব্যর্থ হবে (কমপক্ষে সুইফট 3 এ), এবং স্থানীয়করণ বিবরণ কল করার ফলে "ক্রিয়াকলাপটি সম্পন্ন করা যায়নি ((স্ট্রিংএরর ত্রুটি ১।)" "


এটি এমএমএসজি = হওয়া উচিত
ব্রেট

4
উফ, ঠিক আছে। আমি "msg" "বর্ণনায়" পরিবর্তিত হয়েছি, আশা করি এটি আমার আসলটি থেকে কিছুটা পরিষ্কার।
প্রিভিট

4
আপনি এটি হ্রাস করতে পারেন struct StringError : LocalizedError { public let errorDescription: String? }, এবং এটি কেবল হিসাবে ব্যবহার করুনStringError(errorDescription: "some message")
কোয়েন।

7
 let error = NSError(domain:"", code:401, userInfo:[ NSLocalizedDescriptionKey: "Invaild UserName or Password"]) as Error
            self.showLoginError(error)

একটি এনএসইরর অবজেক্ট তৈরি করুন এবং এটিকে ত্রুটিতে টাইপকাস্ট করুন, এটি যে কোনও জায়গায় দেখান

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

6

আমি এখনও মনে করি যে হ্যারির উত্তরটি সবচেয়ে সহজ এবং সমাপ্ত তবে আপনার যদি আরও সাধারণ কিছু প্রয়োজন হয় তবে ব্যবহার করুন:

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

এবং এটি ব্যবহার করুন বা এটি পরীক্ষা করুন:

printError(error: AppError(message: "My App Error!!!"))

func print(error: Error) {
    print("We have an ERROR: ", error.localizedDescription)
}

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

1

আমি জানি আপনি ইতিমধ্যে একটি উত্তরে সন্তুষ্ট হয়েছেন তবে আপনি যদি সঠিক পদ্ধতির বিষয়ে জানতে আগ্রহী হন তবে এটি আপনার পক্ষে সহায়ক হতে পারে। আমি ত্রুটি বস্তুটিতে ত্রুটি কোডের সাথে HT-প্রতিক্রিয়া ত্রুটি কোডটি মিশ্রিত করতে পছন্দ করব না (বিভ্রান্ত? দয়া করে কিছুটা পড়া চালিয়ে যান ...)।

HTTP প্রতিক্রিয়া কোডগুলি জেনেরিক পরিস্থিতি সংজ্ঞায়িত কোনও HTTP প্রতিক্রিয়া সম্পর্কে স্ট্যান্ডার্ড ত্রুটি কোডগুলি হয় যখন প্রতিক্রিয়া প্রাপ্ত হয় এবং 1xx থেকে 5xx পর্যন্ত পরিবর্তিত হয় (উদাহরণস্বরূপ 200 ঠিক আছে, 408 অনুরোধের সময়সীমা শেষ হয়েছে, 504 গেটওয়ের সময়সীমা ইত্যাদি) - http://www.restapitorial.com/ httpstatuscodes.html )

এনএসইরর অবজেক্টের ত্রুটি কোডটি অ্যাপ্লিকেশন / পণ্য / সফ্টওয়্যারটির একটি নির্দিষ্ট ডোমেনের জন্য বস্তুর যে ধরণের ত্রুটি বর্ণনা করে তার জন্য খুব নির্দিষ্ট সনাক্তকরণ সরবরাহ করে। উদাহরণস্বরূপ আপনার অ্যাপ্লিকেশনটি "দুঃখিত, আপনি এই রেকর্ডটি দিনে একবারের বেশি আপডেট করতে পারবেন না" বা "এই সংস্থানটি অ্যাক্সেস করার জন্য আপনার পরিচালকের ভূমিকা প্রয়োজন" জন্য 1001 বলতে পারেন ... যা আপনার ডোমেন / অ্যাপ্লিকেশনের সাথে সুনির্দিষ্ট যুক্তি

খুব ছোট অ্যাপ্লিকেশনটির জন্য, কখনও কখনও এই দুটি ধারণাকে একত্রিত করা হয়। আপনি দেখতে পাচ্ছেন এবং এগুলি সম্পূর্ণ আলাদা এবং বৃহত সফ্টওয়্যারটি ডিজাইন এবং কাজের জন্য গুরুত্বপূর্ণ এবং সহায়ক।

সুতরাং, কোডটি আরও ভালভাবে পরিচালনা করার জন্য দুটি কৌশল থাকতে পারে:

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
}

শুভ কোডিং :)


সুতরাং মূলত আপনি যা বলতে চাইছেন সেটি "ডেটা" পরামিতিটি পাস করার ক্ষেত্রে যদি কোনও নির্দিষ্ট ত্রুটি কোডটি সার্ভার থেকে ফিরে আসার সাথে সাথে প্রদর্শিত হয়? (দুঃখিত, আমি সময়ে সময়ে কিছুটা ধীর হতে পারি!)
রিখ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.