0

I'm getting an issue while sending an HTTP GET command to a server to retrieve JSONObjects.

here is the command:

        if let url: NSURL = NSURL(string: "http://11.22.33.44:8080/SRV/getAllUsers?owner=\(User.sharedInstance.email)") {
        print("\nSending URL: \(url)")
        let request = NSURLRequest(URL: url)
        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{
            (response: NSURLResponse?, data: NSData?, error: NSError?)-> Void in


            print("Response: \(response) \n")

            do{

                var datastring = NSString(data:data!, encoding:NSUTF8StringEncoding) as String?
                print("Data: \(datastring)")

                let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)

             print("Json: \(json)")

            }catch {
                print("Error with Json: \(error)")
            }

        });

I received a HTTP 200 with all header information, but I'm trying to print NSData as String (nil) and also trying to retrieve my JSONObjects, I get the following message:

Data: nil Error with Json: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}

I'm managing the server part, the servlet which is preparing JSONObjects is doing the following:

ObjectOutputStream objOut = new ObjectOutputStream(response.getOutputStream());   
JSONObject jsonObj = new JSONObject();
jsonObj.put("id","1234");
objOut.writeObject(jsonObj);
objout.flush();
jsonObj = new JSONObject();
jsonObj.put("id","5678");
objOut.writeObject(jsonObj);
objout.flush();

and a last important information, I'm able to retrieve those JSONObject from an Android application without any problem but it seems the format expected in swift for JSONObjects are not the same...

EDIT

I changed the way to send HTTP GET command by using NSURLSession but before treating the JSONObject, I'm trying at least to display data as String:

typealias Payload = [String: AnyObject]

        let url = NSURL(string: "http://11.22.33.44:8080/SRV/getAllUsers?owner=\(User.sharedInstance.email)")
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url!) { (data, response, error) -> Void in

            if(error == nil)
            {
                let err : NSError! = nil

                    print("Response \(response)")

                    guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
                        print("error")
                        return
                    }

                    let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                    print("Data: \(dataString)")

                    var json: Payload!

                    // 1
                    do {
                        json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as? Payload
                        print("JSon: \(json)")
                    } catch {
                        print(error)
                        //XCPlaygroundPage.currentPage.finishExecution()
                    }



            }
            else
            {
                print(error?.description)
            }

        }
        task.resume()

I Received a HTTP 200 with the right header information, so I'm sure the servlet is successfully called, but get nil in data

Data: nil Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

EDIT #2

by using the following line

guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
            print("error data")
            return
        }

        print("data: \(data?.debugDescription)")

I can retrieve the following:

data: Optional("OS_dispatch_data: data[0x7fc68bc45380] = { composite, size = >1067, num_records = 5 record[0] = { from = 0, length = 404, data_object = >0x7fc68bc999d0 }, record[1] = { from = 0, length = 135, data_object = >0x7fc68be1f830 }, record[2] = { from = 0, length = 264, data_object = >0x7fc68bc99a80 }, record[3] = { from = 0, length = 133, data_object = >0x7fc68bf97c20 }, record[4] = { from = 0, length = 131, data_object = >0x7fc68bca0b40 }, }>")

means I am able to retrieve data (at least!) but I don't know how I can extract from this data my JSONObject....

SOLUTION

I finally found my problem. server part needs to prepare JSONObject like this:

response.setContentType("application/json");
// Get the printwriter object from response to write the required json object to the output stream      
PrintWriter out = response.getWriter();
// Assuming your json object is **jsonObject**, perform the following, it will return your json object  
out.print(jsonObject);
out.flush();

instead of using ObjectOutPutStream.

Swift part can retrieve it like this:

let url_to_request = "http://11.22.33.44:8080/SRV/getAllUsers?owner=\(User.sharedInstance.email)"

    let url:NSURL = NSURL(string: url_to_request)!
    let session = NSURLSession.sharedSession()

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "GET"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
    request.timeoutInterval = 10


    let task = session.dataTaskWithRequest(request) {
        (
        let data, let response, let error) in

        guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
            print("error data")
            return
        }


        var json: AnyObject?

    do
    {
        json = try NSJSONSerialization.JSONObjectWithData(data, options: [])


        for anItem in json as! [Dictionary<String, AnyObject>] {
            let nom = anItem["nom"] as! String
            let prenom = anItem["prenom"] as! String
            let id = anItem["id"] as! String
            print("nom: \(nom) prenom: \(prenom) id: \(id)")
        }

    }
    catch
    {
        print("error Serialization")
        return
    }
    }

    task.resume()
tiamat
  • 879
  • 2
  • 12
  • 35
  • sendAsynchronousRequest was deprecated in iOS 9.0. I suggest you use the dataTaskWithRequest method instead. Here have a look at [this](http://stackoverflow.com/a/30935460/5654848) – Mtoklitz113 Jun 18 '16 at 11:51
  • thanks dershowitz123, I know...but I never succeeded by using something else (as I'm new to Swift) still get an error, at least I would like to understand where is the formatting error I have as it works perfectly on Android.... – tiamat Jun 18 '16 at 12:06
  • Did it work or no? I'm confused. – Mtoklitz113 Jun 18 '16 at 12:07
  • I would recommend you try Alamofire. An absolutely BRILLIANT library to deal with HTTP requests. And then try swiftyJSON to help you deal with JSON properly. Give it a shot. Come back and ask if u don't understand what to do. I'll help you out. :) – Mtoklitz113 Jun 18 '16 at 12:08
  • `Invalid value around character 0` means the JSON is invalid, the first character isn't `[` or `{` as expected. – Eric Aya Jun 18 '16 at 12:31
  • I also tried with Alamofire but get the same error....I assume I have a problem on JSON formatting but in that case why does it work on Android ? I can retrieve correctly my JSONObjects on android starting by {. I'm using net.sf.JSONOBject on server side, may be the formatting is different than the one expected on IOS ? – tiamat Jun 18 '16 at 13:00

0 Answers0