Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse JSON in Swift using NSURLSession

Tags:

json

swift

I am trying to parse JSON but getting this error:

type of expression is ambiguous without more context

My code is:

func jsonParser() {

    let urlPath = "http://headers.jsontest.com/"
    let endpoint = NSURL(string: urlPath)
    let request = NSMutableURLRequest(URL:endpoint!)

    let session = NSURLSession.sharedSession()
    NSURLSession.sharedSession().dataTaskWithRequest(request){ (data, response, error) throws -> Void in

        if error != nil {
            print("Get Error")
        }else{
            //var error:NSError?
            do {
                let json:AnyObject =  try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as? NSDictionary

            print(json)

        } catch let error as NSError {
            // error handling
            print(error?.localizedDescription)
        }
        }
    }
    //task.resume()
}

This is working fine with out try catch in Xcode 6.4 but this is not working in Xcode 7.

like image 702
Vipulk617 Avatar asked Aug 04 '15 09:08

Vipulk617


People also ask

What is JSONPath parse?

JSONPath is an expression language to parse JSON data. It's very similar to the XPath expression language to parse XML data. The idea is to parse the JSON data and get the value you want. This is more memory efficient because we don't need to read the complete JSON data.

What is Jsonserialization in Swift?

An object that converts between JSON and the equivalent Foundation objects.


3 Answers

Don't declare an AnyObject type for your decoded object since you want it to be an NSDictionary and you're performing a conversion to do this.

Also it's better to use zero options for NSJSONSerialization instead of random ones.

In my example I've also used a custom error type just for demonstration.

Note, if you're using a custom error type, you have to also include a generic catch to be exhaustive (in this example, with a simple downcasting to NSError).

enum JSONError: String, ErrorType {
    case NoData = "ERROR: no data"
    case ConversionFailed = "ERROR: conversion from JSON failed"
}

func jsonParser() {
    let urlPath = "http://headers.jsontest.com/"
    guard let endpoint = NSURL(string: urlPath) else {
        print("Error creating endpoint")
        return
    }
    let request = NSMutableURLRequest(URL:endpoint)
    NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
        do {
            guard let data = data else {
                throw JSONError.NoData
            }
            guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else {
                throw JSONError.ConversionFailed
            }
            print(json)
        } catch let error as JSONError {
            print(error.rawValue)
        } catch let error as NSError {
            print(error.debugDescription)
        }
   }.resume()
}

The same with Swift 3.0.2:

enum JSONError: String, Error {
    case NoData = "ERROR: no data"
    case ConversionFailed = "ERROR: conversion from JSON failed"
}

func jsonParser() {
    let urlPath = "http://headers.jsontest.com/"
    guard let endpoint = URL(string: urlPath) else {
        print("Error creating endpoint")
        return
    }
    URLSession.shared.dataTask(with: endpoint) { (data, response, error) in
        do {
            guard let data = data else {
                throw JSONError.NoData
            }
            guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary else {
                throw JSONError.ConversionFailed
            }
            print(json)
        } catch let error as JSONError {
            print(error.rawValue)
        } catch let error as NSError {
            print(error.debugDescription)
        }
    }.resume()
}
like image 193
Eric Aya Avatar answered Oct 26 '22 02:10

Eric Aya


Apple declare here.

func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask

Fix it:

NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
       // Your handle response here!
}

UPDATE:

func jsonParser() {
    let urlPath = "http://headers.jsontest.com/"
    let endpoint = NSURL(string: urlPath)
    let request = NSMutableURLRequest(URL:endpoint!)

    NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
        print(error)
    }.resume()
}

RESULT:

Optional(Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSUnderlyingError=0x7f8873f148d0 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}, NSErrorFailingURLStringKey=http://headers.jsontest.com/, NSErrorFailingURLKey=http://headers.jsontest.com/, NSLocalizedDescription=The resource could not be loaded because the App >Transport Security policy requires the use of a secure connection.})

Hope this helps!

like image 38
Long Pham Avatar answered Oct 26 '22 02:10

Long Pham


For Swift 4 Web service Call , Post Method using URLSession

 func WebseviceCall(){
        var request = URLRequest(url: URL(string: "YOUR_URL")!)
        request.httpMethod = "POST"
        let postString = "PARAMETERS"
        request.httpBody = postString.data(using: .utf8)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")

        let task = URLSession.shared.dataTask(with: request) { data, response, error in

            guard let data = data, error == nil else {
                print("error=\(error)")
                return
            }

            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(response)")
            }

            do {
                if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
                    // Print out dictionary
                    print(convertedJsonIntoDict)
               }
            } catch let error as NSError {
                print(error.localizedDescription)
            }
        }
        task.resume()
    }
like image 39
Akshay Mirgal Avatar answered Oct 26 '22 01:10

Akshay Mirgal