类型 'Void' 在具有枚举结果<T> 的函数中没有成员

Type 'Void' has no member in function with enum Result<T>

我有这个代码:

enum ApiConstans {
    static let BaseUrl = "http://myname.pl"
    static let iosPath = "/pub/ios/"
    static let jsonPath = "json.php"

    static var fullPath: String { return BaseUrl + iosPath + jsonPath }
}


struct Connect {
    enum Result<T> {
        case succes(T)
        case error(String)
    }

    func getJsonFromServer(parameters: String) -> Result<String> {

        let fullUrlString = ApiConstans.fullPath + parameters
        guard let url = URL(string: fullUrlString) else {
            return .error("Error 100: Problem with url")
        }

        URLSession.shared.dataTask(with: url) {  (data, response, error) in
            guard error == nil else {
                return .error("Error 100: Problem with url")
            }

            guard let data = data else {
                return .error("Error 101: Problem with url")
            }

            debugPrint("R> \(fullUrlString)")
            return .succes(data)
        }
    }

    func checkUsersLogin(login: String?, password: String?) ->  Result<String> {
        getJsonFromServer(parameters: "?action=LOGOWANIE&login=\(login!)&password=\(password!)")
    }

}

我遇到所有错误的问题 return:类型 'Void' 没有成员 'error' 并且类型 'Void' 没有成员 'succes'

我可以请你修复这段代码吗?

编译器告诉你你 return 你的 Result 来自异步 dataTask 处理程序,它不应该 return 你的自定义类型。

您的代码的主要问题是您以同步方式执行异步操作(调用服务器)(立即 returning 结果)。相反,您应该将回调闭包传递给 getJsonFromServer,您在 dataTask 处理程序中调用它。

从服务器接收数据时,您应该对 return 数据使用闭包。

typealias completionHandler = (Result<Data >) -> ()

func getJsonFromServer(parameters: String, completion: @escaping completionHandler) {
    let fullUrlString = ApiConstans.fullPath + parameters
    guard let url = URL(string: fullUrlString) else {
        return completion(.error("Error 100: Problem with url"))
    }

    URLSession.shared.dataTask(with: url) {  (data, response, error) in
        guard error == nil else {
            return completion(.error("Error 100: Problem with url"))
        }

        guard let data = data else {
            return completion(.error("Error 101: Problem with url"))
        }

        debugPrint("R> \(fullUrlString)")
        return completion(.succes(data))
    }
}

在块的情况下,默认的 return 类型是 Void,因此 return 引用块 return 类型。您需要使用完成处理程序方式使其工作。

enum ApiConstans {
    static let BaseUrl = "http://myname.pl"
    static let iosPath = "/pub/ios/"
    static let jsonPath = "json.php"

    static var fullPath: String { return BaseUrl + iosPath + jsonPath }
}


struct Connect {
    enum Result<T> {
        case succes(T)
        case error(String)
    }

    func getJsonFromServer(parameters: String, completion: @escaping (Result<String>) -> Void) {

        let fullUrlString = ApiConstans.fullPath + parameters
        guard let url = URL(string: fullUrlString) else {
            completion(Result.error("Error 100: Problem with url"))
            return
        }

        URLSession.shared.dataTask(with: url) {  (data, response, error) in
            guard error == nil else {
                completion(Result.error("Error 100: Problem with url"))
                return
            }

            guard let data = data else {
                completion(Result.error("Error 100: Problem with url"))
                return
            }

            print("R> \(fullUrlString)")
            completion(Result.succes("CONVERT DATA TO STRING USE DATA HERE "))
        }
    }

    func checkUsersLogin(login: String?, password: String?, completion: @escaping (Result<String>) -> Void) {
        self.getJsonFromServer(parameters: "?action=LOGOWANIE&login=\(login!)&password=\(password!)", completion: completion)
    }

}

你可以通过完成,你也必须等待 API 完成,所以我建议使用处理程序技术来实现适当的流程。