Reputation: 15
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
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:
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).
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.
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")
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.
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.)
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