swift 错误:表达式类型不明确,没有更多上下文

dm7nw8vv  于 2022-11-21  发布在  Swift
关注(0)|答案(1)|浏览(103)

我尝试从一个带有dataTask的API函数返回一个值。在编辑代码时,我收到错误:
表达式类型不明确,没有更多上下文。
我添加了下面的代码。有人知道如何解决这个问题吗?我是斯威夫特的新手。

func getNonce() {
    let headers = [
      "accept": "application/json",
      "content-type": "application/json"
    ]
    let parameters = [
      "id": 1,
      "jsonrpc": "2.0",
      "params": [addressETH, "pending"],
      "method": "eth_getTransactionCount"
    ] as [String : Any]
    let postData = try? JSONSerialization.data(withJSONObject: parameters, options: [])
    let request = NSMutableURLRequest(url: NSURL(string: "https://eth-goerli.g.alchemy.com/v2/myapikeygoeshere")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData! as Data
    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> String in
        if (error != nil) {
            print(error as Any)
        } else {
            let dataString = String(data: data!, encoding: .utf8)!
            let start = dataString.index(dataString.startIndex, offsetBy: 36)
            let end = dataString.index(dataString.endIndex, offsetBy: -2)
            let range = start..<end
            let user_Nonce = String(dataString[range])
            return user_Nonce?
        }
    })
    dataTask.resume()
}

错误位于此行:

let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> String in

我试图返回值,但弹出错误。

njthzxwz

njthzxwz1#

您应该仔细阅读swift中的完成处理程序或async await是如何工作的。这里有一些例子说明如何构建这个函数--您必须在调用点考虑完成处理程序或async await。还有相当多的强制展开(!),这是应该避免的,与try?相同。捕获这些条件并向调用方报告错误。

// Example using closures

func getNonce(completion: @escaping (Result<String, Error>) -> Void) {
    let headers = [
      "accept": "application/json",
      "content-type": "application/json"
    ]
    
    let parameters = [
      "id": 1,
      "jsonrpc": "2.0",
      "params": ["addressETH", "pending"],
      "method": "eth_getTransactionCount"
    ] as [String : Any]
    
    let postData = try? JSONSerialization.data(withJSONObject: parameters, options: [])
    var request = URLRequest(url: NSURL(string: "https://eth-goerli.g.alchemy.com/v2/myapikeygoeshere")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData!
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(.failure(error))
        } else {
            let dataString = String(data: data!, encoding: .utf8)!
            let start = dataString.index(dataString.startIndex, offsetBy: 36)
            let end = dataString.index(dataString.endIndex, offsetBy: -2)
            let range = start..<end
            let user_Nonce = String(dataString[range])
            completion(.success(user_Nonce))
        }
    }
    task.resume()
}

// Example using async await

func getNonce() async throws -> String {
    let headers = [
      "accept": "application/json",
      "content-type": "application/json"
    ]
    
    let parameters = [
      "id": 1,
      "jsonrpc": "2.0",
      "params": ["addressETH", "pending"],
      "method": "eth_getTransactionCount"
    ] as [String : Any]
    
    let postData = try? JSONSerialization.data(withJSONObject: parameters, options: [])
    var request = URLRequest(url: NSURL(string: "https://eth-goerli.g.alchemy.com/v2/myapikeygoeshere")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData!
    
    let (data, _) = try await URLSession.shared.data(for: request)
    let dataString = String(data: data, encoding: .utf8)!
    let start = dataString.index(dataString.startIndex, offsetBy: 36)
    let end = dataString.index(dataString.endIndex, offsetBy: -2)
    let range = start..<end
    let user_Nonce = String(dataString[range])

    return user_Nonce
}

// Assuming called from viewDidLoad in a view controller

override func viewDidLoad() {
    super.viewDidLoad()

    // How to call using closure example
    
    getNonce { result in
        switch result {
        case .success(let nonce):
            print("got nonce: \(nonce)")
            
        case .failure(let error):
            // handle error
            break
        }
    }
    
    // How to call using async await example
    Task {
        do {
            let nonce = try await getNonce()
            print("got nonce: \(nonce)")
        } catch {
            // handle error
        }
    }
}

相关问题