对成员 'dataTask(with:completionHandler:)' 的不明确引用连接到服务器

Ambiguous reference to member 'dataTask(with:completionHandler:)' connect to server

我正在尝试连接到服务器

如果你有解决办法请写下来给我

我怎么知道 swift 的新版本有什么变化?

swift 2 和 swift 3

之间存在很多差异

swift 4 与 swift 3 有很大不同吗?

在 swift 3 我得到这个错误:

let task = URLSession.shared.dataTask(with: server.execute())
{Data,URLResponse,error in
    if error != nil{
    print(error as Any)
        return
    }
    do{
        let json = try JSONSerialization.jsonObject(with: Data!, options: .allowFragments)
        if let json_result = json as? [String: Any]
        {
            let result = json_result ["result"] as? String
            if result == "0"
            {
                DispatchQueue.main.async {
                    let alert = UIAlertController(title:"Incorrect Username",message : "The username you entered doesn't appear to belong to an account. Please check your username and try again", preferredStyle : .alert)
                    let alert_action = UIAlertAction(title: "Try Again", style: .default, handler: nil)
                    alert.addAction(alert_action)
                    self.present(alert, animated: true, completion: nil)
                }
            }
            else
            {
                DispatchQueue.main.async {
                    UserDefaults.standard.set(result!, forKey: "user_id")
                    //" use of unresolved identifier 'result' "
                    let current_view=UIApplication.shared.windows[0] as UIWindow
                    let new_view=(self.storyboard? .instantiateViewController(withIdentifier: "tab_bar"))! as UIViewController
                    UIView.transition(from: (current_view.rootViewController? .view)!, to:new_view.view , duration: 0.65, options: .transitionFlipFromRight, completion: {(action) in current_view.rootViewController=new_view
                    })
                }

            }
        }
        else{
            // Error in jsonSerialization
        }   }
    catch{
    }
}
task.resume()

问题几乎可以肯定是 server.execute() 的 return 值。也许它是 NSURLNSURLRequest 而不是 URLURLRequest。也许这是一个可选的。也许这是完全不同的东西。最重要的是,如果 dataTask 的参数不是非可选的 URLURLRequest,您会得到您所做的错误。没有看到 execute return 是什么,我们只是在猜测,但这可能是罪魁祸首。


一些不相关的观察结果:

  1. 我不会使用 DataURLResponse 作为 dataTask 闭包的参数名称。这些是数据类型的名称。我会使用 dataresponse (或者甚至不指定 response 因为你没有使用它),以避免混淆(对于你和编译器)。

  2. 您有很多无关的转换,它们只会给代码增加噪音。例如。 windows 是一个 UIWindow 的数组,所以当你从那个数组中得到第一个项目时,为什么还要费心做 as UIWindow

  3. 您有几个可选的链接序列,您稍后会强制解包。这样做没有意义。消除该过程中的可选链接。因此,而不是 storyboard? 后跟 !

    let new_view = (self.storyboard?.instantiateViewController(withIdentifier: "tab_bar"))! as UIViewController
    

    你可以直接使用storyboard!:

    let controller = self.storyboard!.instantiateViewController(withIdentifier: "tab_bar")
    
  4. 您有几个无关的选项,您可以根据需要删除这些选项。例如。 .allowFragments 对于 JSONSerialization 是不必要的(并且可能是不可取的)。或者,您的 UIAlertActionpresentnilcompletion 也是不必要的。没什么大不了的,但它只会给你的代码增加噪音。

  5. 按照惯例,我们不使用 _ 字符来分隔变量名中的单词。我们使用驼峰命名法。因此,例如,我们将使用 currentView 而不是 current_view。 (或者,因为那是 window,我实际上会使用 window,这更简单。)

  6. 如果你没有在 catch 块中做任何事情,那么使用 do-try-catch 模式是没有意义的。如果您在捕获错误时不打算做任何事情,为什么要抛出错误。如果您只关心它是否成功,请使用 try?

因此,代码可以稍微清理一下,如下所示:

let task = URLSession.shared.dataTask(with: request) { data, _, error in
    if let error = error {
        print(error)
        return
    }

    guard let data = data,
        let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any],
        let result = json["result"] as? String else {
            print("no result")
            return
    }

    DispatchQueue.main.async {
        if result == "0" {
            let alert = UIAlertController(title: "Incorrect Username", message: "The username you entered doesn't appear to belong to an account. Please check your username and try again", preferredStyle: .alert)
            let action = UIAlertAction(title: "Try Again", style: .default)
            alert.addAction(action)
            self.present(alert, animated: true)
        } else {
            UserDefaults.standard.set(result, forKey: "user_id")
            let window = UIApplication.shared.windows[0]
            let controller = self.storyboard!.instantiateViewController(withIdentifier: "tab_bar")
            UIView.transition(from: window.rootViewController!.view, to: controller.view, duration: 0.65, options: .transitionFlipFromRight, completion: { _ in
                window.rootViewController = controller
            })
        }
    }
}
task.resume()

现在,我已将 server.execute() 替换为 request,因为我不知道 execute 在做什么,但可以使用任何合适的方法(请参阅此答案的开头) .