You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何解决‘() throws -> Bool无法转换为Bool’报错?

Fixing the '() throws -> Bool' is not convertible to 'Bool' Error in Swift

Hey there! I know how frustrating it is to get stuck on a syntax snag when you're just starting out with Swift—let's break this down and get your code working.

What's Causing the Error?

The core issue here is a type mismatch. Your ThrowableCallBack defines a closure that throws an error and returns a Bool, but it looks like the authenticated parameter in services.login is expecting either a plain Bool value or a closure that accepts a Bool (not one that returns a throwing Bool). The compiler is yelling because it can't convert your throwing closure to the type the method is asking for.

Step-by-Step Fixes

1. Adjust the Closure to Match the Expected Type

First, let's assume your login method's authenticated parameter is meant to handle a success/failure boolean result. Here's how to rewrite your authenticate() function correctly, with safer practices:

// Update the callback type to match what login expects
typealias AuthCallback = (Bool) -> Void

func authenticate() {
    let services = ServiceManager()
    
    // Safely unwrap text fields to avoid crashes (no more force ! unwraps!)
    guard let email = emailField.text, !email.isEmpty,
          let password = passwordField.text, !password.isEmpty else {
        let alert = UIAlertController(title: "Oops", message: "Please fill in both email and password.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
        return
    }
    
    services.login(username: email, password: password, authenticated: { authResult in
        self.loadingDialog.dismiss(animated: true)
        
        if authResult {
            // Handle successful authentication (e.g., navigate to home screen)
            self.navigationController?.pushViewController(HomeViewController(), animated: true)
        } else {
            // Handle failed login
            let alert = UIAlertController(title: "Login Failed", message: "Invalid email or password.", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Try Again", style: .default))
            self.present(alert, animated: true)
        }
    })
}

2. If You Need to Handle Errors in the Callback

If you do need the callback to handle errors (not just a success/failure flag), you'll need to adjust both the callback type and how you use it with do/catch:

First, update the callback type and your login method (if you control it) to support throwing closures:

typealias ThrowableAuthCallback = (Bool) throws -> Void

// Inside ServiceManager, update the login method signature:
func login(username: String, password: String, authenticated: ThrowableAuthCallback) throws {
    // Perform your network request and check the response code...
    let isAuthenticated = true // Replace with actual response logic
    
    // Call the callback (which might throw an error)
    try authenticated(isAuthenticated)
}

Then update your authenticate() function to catch any thrown errors:

func authenticate() {
    let services = ServiceManager()
    
    guard let email = emailField.text, !email.isEmpty,
          let password = passwordField.text, !password.isEmpty else {
        let alert = UIAlertController(title: "Oops", message: "Please fill in both email and password.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
        return
    }
    
    do {
        try services.login(username: email, password: password, authenticated: { authResult in
            self.loadingDialog.dismiss(animated: true)
            
            if authResult {
                // Success case: navigate to home
                self.navigationController?.pushViewController(HomeViewController(), animated: true)
            } else {
                // Throw an error for failed authentication
                throw LoginError.invalidCredentials
            }
        })
    } catch {
        // Handle any thrown errors
        self.loadingDialog.dismiss(animated: true)
        let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        self.present(alert, animated: true)
    }
}

// Custom error type for login-specific issues
enum LoginError: Error, LocalizedError {
    case invalidCredentials
    
    var localizedDescription: String {
        switch self {
        case .invalidCredentials:
            return "Invalid email or password. Please try again."
        }
    }
}

Quick Tips for Swift Newbies

  • Ditch force unwraps (!) whenever you can—use guard let or if let to safely handle optional values and avoid unexpected crashes.
  • Closure types are strict: Always make sure the closure you pass matches exactly what the function expects (parameters, return type, and whether it throws).
  • Use do/catch for thrown errors: Any time you call a function or closure marked throws, wrap it in a do block and catch errors in the catch block.

内容的提问来源于stack exchange,提问作者João Serra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:24:47