JSON data serialization in Swift - json

I am new to Xcode and Swift, and I am trying to serialize JSON data from a url using the code below and get the error
'NSJSONReadingOptions' is not convertible to 'NSJSONWritingOptions'
on the line
var jsonResult = NSJSONSerialization.dataWithJSONObject(data, options: NSJSONReadingOptions.MutableContainers, error: nil)!
I cannot see my error, from online sources others use the same code and its works?
let task = session.dataTaskWithURL(loginUrl!, completionHandler: { (data, response, error) -> Void in
if error != nil {
}else {
var jsonResult = NSJSONSerialization.dataWithJSONObject(data, options: NSJSONReadingOptions.MutableContainers, error: nil)!
println(jsonResult)
}
})
task.resume();

Read the docs for dataWithJSONObject. The options parameter needs to be a value from the NSJSONWritingOptions enum, not the NSJSONReadingOptions enum.
But if your goal here is to convert an NSData object to an NSArray or NSDictionary, then the problem is that you are calling the wrong method. You want to use JSONObjectWithData, not dataWithJSONObject.

Related

How to parsing we parsing dictionary of array in swift by using object mapper

I facing problem with this how to overcome this.
func addressApi()
{
let params = ["":""]
WebService.shared.apiGet(url: addressApiURL, parameters: params) { (response, error) in
if error == nil
{
guard let data = response?["data"] else{return}
guard let address = data["address"] as? string else{return}
}
}
}
I getting response like this : Response
I want to getting address and locationName from that response how is it.
I facing error this: Error
Here we are don't getting the values superately from array of dictionaries.
For that one you need to write the for loop.
If incase you are using Modelclass then then directly load that class into collection view or tableview

Errors in do catch statement in swift

I'm trying to explore this new (for me) language, and I'm making an app that like many others retrieve some json data from a server.
in this function (from a tutorial I found) I get 4 errors, and I'm unable to fix it:
func json_parseData(data: NSData) -> NSDictionary? {
do {
let json: AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)
print("[JSON] OK!")
return (json as? NSDictionary)
}catch _ {
print("[ERROR] An error has happened with parsing of json data")
return nil
}
}
the first one is at the "try", xcode suggest me to fix it using "try;"
the others at the "catch" and are this others:
Braced block of statement is an unused closure
Type of expression is ambiguous without more context
Expected while in do-while-loop
please help me to understand
It seems that you are using Xcode 6.x and Swift 1.x where the do-try-catch syntax is not available (only Xcode 7 and Swift 2)
This code has equivalent behavior:
func json_parseData(data: NSData) -> NSDictionary? {
var error: NSError?
// passing the error as inout parameter
// so it can be mutated inside the function (like a pointer reference)
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainerserror: &error)
if error == nil {
print("[JSON] OK!")
return (json as? NSDictionary)
}
print("[ERROR] An error has happened with parsing of json data")
return nil
}
Note: as of Xcode 7 beta 6 you can also use try? which returns nil if an error occurs.

Unexpectedly found nil while unwrapping an Optional value when using json API result and NSDictionary

I am trying to use an API to get json data every 0.5 seconds. The API allows thousands of requests per second however sometimes when running the application, I get this crash:
fatal error: unexpectedly found nil while unwrapping an Optional value
This is the code I am using to get the json data.
var url : String = "URL.COM"
var request : NSMutableURLRequest = NSMutableURLRequest
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse?, data: NSData?, error: NSError?) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary
Can anyone advise me how to prevent this? I understand why the data might be nil occasionally but I want the program to keep checking regardless of if it is nil or not, as it will soon be something other than nil.
You should add this, before the sterilization:
if data == nil
{
println("data is nil")
return
}
The problem lays in data. It can be nil, but you're unwrapping it using !, which means: "I know there's some data inside here, unwrap it". The problem is when there's no data.
To solve it, use this pattern in Swift:
if let myData = data {
// do something using myData. If data is nil, doen't even enter here
}
Complete code:
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse?, data: NSData?, error: NSError?) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
if let myData = data {
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(myData, options:NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary
}
})

Handling JSON in Swift

I'm trying to learn Swift and am struggling with understanding a piece about handling JSON and get "fatal error: unexpectedly found nil while unwrapping an Optional value" from using this code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let urlPath = "http://api.worldweatheronline.com/free/v2/marine.ashx?key=45e8e583134b4371a2fa57a9e5776&format=xml&q=45,-2"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
println("Task completed")
if ((error) != nil) {
println(error)
} else {
var err: NSError?
println("URL: \(url)")
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println(jsonResult)
}
})
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The API key I'm using is free so don't worry about using it. The JSON results should look something like this but I am instead greeted with:
Task completed
URL: http://api.worldweatheronline.com/free/v2/marine.ashx?key=45e8e583134b4371a2fa57a9e5776&format=xml&q=45,-2
fatal error: unexpectedly found nil while unwrapping an Optional value
I'm assuming the jsonResult variable is what's causing the problem, but even if I try to force unwrap it (I think that's what I'm doing?) with something like
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
it still fails with "expected type after 'as'."
Everything is fail-able here, a website can even return 200 but return nothing, the data can come corrupted, and, in your case, I tried calling the URL you are using and found out, it's actually XML, so... there's your problem?
A more robust approach (assuming that you still want to parse JSON, maybe from another site? The ISS has an open API) is to use the if let to unwrap optionals and then on the else case deal with the errors, rather than ! your way to success.
Here's a very extensive check of everything
task = session.dataTaskWithRequest(NSURLRequest(URL: url), completionHandler: { [unowned self] (data, response :NSURLResponse!, errorRequest) -> Void in
// Check the HTTP Header
if let responseHTTP = response as? NSHTTPURLResponse
{
if responseHTTP.statusCode != 200
{
println("Received status code \(responseHTTP.statusCode)")
return
}
}
else
{
println("Non-HTTP Response received")
return
}
var errorParsing : NSError?
if let JSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &errorParsing) as? NSDictionary
{
// Do the parsing
}
else
{
println("Error parsing: \(errorParsing)")
}
})
task!.resume()
NSJSONSerialization.JSONObjectWithData... returns an optional NSData?. This means that you can't cast it directly to NSDictionary. To fix the crash you will need to use ?as which means your jsonResult will either be a NSDictionary or nil
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) ?as NSDictionary
In your case, you can safely unwrap the optional by doing this.
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)
if let jsonResult = jsonResult ?as NSDictionary {
println(jsonResult)
}

How parse json in tableview using swift?

I am trying to read json date from url and parse it in Tableview using swift. how can I make variable "jsonResult " as global ?
or please guide me how can I populate the tableview with this data from json.
let urlPath = "http://omanevents.net/OmanEventsApp/testPullDate.php"
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println("error")
}else {
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
for var index = 0; index < jsonResult["Events"]?.count ; ++index {
println(jsonResult["Events"]?[index]["Location"])
}
}
})
task.resume()
I would highly recommend that you have a look at this tutorial.
http://www.raywenderlich.com/85578/first-core-data-app-using-swift
It shows you how to deal with core data but in the example it uses adding things to tableView, and saving data for use of the app at later stages. Ray Wnderlich is a great website.