How to handle Void success case with Result lib (success/failure)

前端 未结 3 2020
Happy的楠姐
Happy的楠姐 2021-01-11 14:49

Introduction:

I\'m introducing a Result framework (antitypical) in some points of my app. In example, given this function:

func find         


        
相关标签:
3条回答
  • 2021-01-11 15:11

    Try this

    Note this is example you can change as per your test

    typealias resultHandler = (_ responseItems: AnyObject, _ error: Error) -> Void
    
    func deleteItem(byId: Int, completion: resultHandler){
           completion(Items, error) 
     }
    

    Calling

    self.deleteItem(byId: 1) { (result, error) in
                if error ==nil{
    
                }
            }
    
    0 讨论(0)
  • 2021-01-11 15:16

    The best way is exactly what you've done: Error? where nil indicates success. It's quite clear and simple.

    That said, another answer (and one that I've used) is exactly in your question: "How to handle Void success case with Result." The success case passes Void, so pass Void:

    Result<Void, Error>
    

    "Void" doesn't mean "returns nothing." It's a type in Swift, a type that has exactly one value: the empty tuple (). That also happens to be the type:

    public typealias Void = ()
    

    As a matter of convention, we use Void to mean the type, and () to mean the value. The one thing that's a bit strange about using Void this way in a Result is the syntax. You wind up with something like:

    return .success(())
    

    The double-parentheses are a little ugly and slightly confusing. So even though this is nicely parallel to other Result-using code, I typically just use Error? in this case. If I had a lot of it, though, I'd consider creating a new type for it:

    enum VoidResult {
        case .success
        case .failure(Error)
    }
    
    0 讨论(0)
  • 2021-01-11 15:24

    I found Rob's answer really interesting and smart. I just want to contribute with a possible working solution to help others:

    enum VoidResult {
        case success
        case failure(Error)
    }
    
    /// Performs a request that expects no data back but its success depends on the result code
    /// - Parameters:
    ///   - urlRequest: Url request with the request config
    ///   - httpMethodType: HTTP method to be used: GET, POST ...
    ///   - params: Parameters to be included with the request
    ///   - headers: Headers to be included with the request
    ///   - completion: Callback trigered upon completion
    func makeRequest(url: URL,
                     httpMethodType: HTTPMethodType,
                     params: [String:Any],
                     headers: [String:String],
                     completion: @escaping (VoidResult) -> Void){
        let alamofireHTTPMethod = httpMethodType.toAlamofireHTTPMethod()
        
        let parameterEncoder: ParameterEncoding
        switch alamofireHTTPMethod {
        case .get:
            parameterEncoder = URLEncoding.default
        case .post:
            parameterEncoder = JSONEncoding.default
        default:
            parameterEncoder = URLEncoding.default
        }
        
        Log.d(message: "Calling: \(url.absoluteString)")
        AF.request(url,
                   method: alamofireHTTPMethod,
                   parameters: params,
                   encoding:parameterEncoder,
                   headers: HTTPHeaders(headers)).response { response in
                    guard let statusCode = response.response?.statusCode,
                        (200 ..< 300) ~= statusCode else {
                            completion(.failure(NetworkFetcherError.networkError))
                            return
                    }
                    completion(.success)
                    
        }
        
      }
    
    0 讨论(0)
提交回复
热议问题