SherWiin
SherWiin

Reputation: 15

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

I'm trying to connect to server

Please if you got solution write it down for me

how can I know what changes in newer version of swift?

a lot of differences exist between swift 2 and swift 3

Is swift 4 a lot different than swift 3?

in swift 3 I get this error:

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()

Upvotes: 1

Views: 402

Answers (1)

Rob
Rob

Reputation: 437392

The problem is almost certainly the return value of server.execute(). Maybe it's a NSURL or NSURLRequest rather than URL or URLRequest. Maybe it's an optional. Maybe it's something completely different. Bottom line, if the parameter to dataTask is not a non-optional URL or URLRequest, you can get the error you did. Without seeing what execute returns, we're just guessing, but it's the likely culprit.


A couple of unrelated observations:

  1. I wouldn't use Data or URLResponse as parameter names to the dataTask closure. Those are names of data types. I would use data and response (or don't even specify response because you're not using it), instead, to avoid confusion (for both you and the compiler).

  2. You have a lot of extraneous casts that only add noise to the code. E.g. windows is an array of UIWindow, so why bother doing as UIWindow when you get the first item from that array.

  3. You have a couple of optional chaining sequences that you later force unwrap. There's no point in doing that. Eliminate the optional chaining in that process. Thus, instead of storyboard? followed by ! later:

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

    You can just use storyboard!:

    let controller = self.storyboard!.instantiateViewController(withIdentifier: "tab_bar")
    
  4. You've got a couple of extraneous options that you can remove if you want. E.g. .allowFragments for JSONSerialization is unnecessary (and probably undesirable). Or a completion of nil for your UIAlertAction and present is unnecessary, too. Not a big deal, but it just adds noise to your code.

  5. As a matter of convention, we don't use _ characters to separate words in a variable name. We use camelCase. So, for example, rather than current_view, we'd use currentView. (Or, because that's a window, I'd actually use window, which is even simpler.)

  6. There's no point in using do-try-catch pattern if you're not doing anything in the catch block. Why throw an error if you're not going to do anything when you catch it. Just use try? if all you care about is whether it succeeded or not.

Thus, the code can be cleaned up a bit to something like:

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()

Now, I've replaced server.execute() with request because I don't know what execute is doing, but use whatever is appropriate (see the beginning of this answer).

Upvotes: 0

Related Questions