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()