Reputation: 6608
Hi i try to find a way to parse JSON in SWIFT, this works great for me but i run into a problem.
I let the user enter a username that is used for the JSON URL -> if the user type in a valid username all works fine.
But if he enter a wrong username my parsing fails, this is correct too, but for now my app only crashes and i looking for a way to make a work around.
This is my Code where it crashes,
let url0 = NSURL(string: newUrlPath!)
let session0 = NSURLSession.sharedSession()
let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
} else {
let summonorID_JSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
The Xcode Error
Error Domain=NSURLErrorDomain Code=-1002 "The operation couldn’t be completed. (NSURLErrorDomain error -1002.)" UserInfo=0x7c12d610 {NSErrorFailingURLKey=XX, NSErrorFailingURLStringKey=XX, NSUnderlyingError=0x7c12c8d0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1002.)"} fatal error: unexpectedly found nil while unwrapping an Optional value
All is fine cause this is the return page i get from my Request
And yes he can't parse this into a NSDirectory as its no JSON that returns (as its normally is) is there a way to take care that if this page comes up (so the user entered a wrong username) that i can exit my loop/take a other way ;)?
Upvotes: 0
Views: 1624
Reputation: 628
Since you are getting 404
on this request, I assume that this will happen every time something is bad with username, you should handle server response to fit that. First thing will be to check what server returned:
let httpResp: NSHTTPURLResponse = response as NSHTTPURLRespons
At this point you can access statusCode property, that will tell you if request was good or not (404). Having that information you can decide what to do, and for example, you can modify your code something like this:
let url0 = NSURL(string: newUrlPath!)
let session0 = NSURLSession.sharedSession()
let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
} else {
let httpResp: NSHTTPURLResponse = response as NSHTTPURLRespons
httpResp.statusCode != 404 {
let summonorID_JSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
} else {
// Handle error at this point, tell user to retype username etc.
}
})
Upvotes: 2
Reputation: 52530
You are using many operations which could all fail, and Swift is quite unforgiving about failure. Your code will crash if newURLPath is nil, if url0 is nil because newURLPath wasn't a valid URL.
So your URL request might return an error (the request itself failed), but you have the case that the URL request succeeded but gives unexpected results (not a JSON dictionary). Your code ending in "as NSDictionary" tells Swift: "I know I might not get a dictionary, but convert what you get to a dictionary and crash if this doesn't work". Just change this to
if let parsedJSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)
{
// Will still crash if the server sends a valid JSON array
let summonorID_JSON = parsedJSON as NSDictionary
}
else
{
// data wasn't valid JSON, handle it.
}
The difference is that the optional value returned by the JSON parser will be accepted without crashing, and you check whether you received valid JSON or not.
Upvotes: 3
Reputation: 10251
The url0
becomes nil
if user enter wrong data. If you use the nil value as url0!
app will crash.
When you add a ! after a variable you tell the compiler the value will not be nil.
so to avoid the crash, you have to check for nil condition before calling
let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
Upvotes: -1
Reputation: 23078
NSURL
is a failable initializer and exactly this happens when you give an invalid url: It fails to initialize.
So wrap your code in an conditional unwrap:
if let url0 = NSURL(string: newUrlPath!) {
...
}
Upvotes: 0