-1

I have test this link too. giving me bad request (400)

using native library not almafire

here is link i've cheeked send object as parameter

please vote me up

here is my full code

guard let url=URL(string: "http://test.com/google/getAddress") else{return}

let parameters=GoogleMap()

var requst=URLRequest(url: url)
requst.httpMethod="POST"
requst.addValue("application/json", forHTTPHeaderField: "Content-Type")
requst.httpMethod="POST"
guard let httpbody=try? JSONSerialization.data(withJSONObject: parameters, options: []) else{return}

requst.httpBody=httpbody

print(url)

let _=URLSession.shared.dataTask(with: requst) { (data, response, error) in
    if let data=data{

        do{
            let json=try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)

            print(json)
        }
        catch{

            print(error)
        }
    }
    }.resume()
    }

my model class

class Model {

    private var latitude:Double?
    private var longitude:Double?

    var _latitude:Double{
        get{
            return latitude!
        }
        set{
            latitude=newValue
        }
    }

    var _longitude:Double{

        get{
            return longitude!
        }
        set{
            longitude=newValue
        }
    }

    func toJSON() -> [String: Any] {
        return [ "latitude": latitude as Any, "longtide": longitude as Any]
    }

}

I have tested as a dictionary but server gives me "bad request" error in its JSON response.

Ryan110
  • 710
  • 4
  • 19

1 Answers1

1

The main problem is that your JSON is using the wrong key for the longitude. You're using longtide, which is obviously not what you intended. If you use longitude, it works fine.


A few unrelated observations:

  1. You are doing do-catch, but don't have a try. You are using try? which doesn't throw any errors, but rather just returns nil if there was a problem. Therefore is nothing to catch. Use try, not try? if you want to catch the error.

  2. You have a curious model object in which you have private properties, but then have computed properties that get and set the private property. If you're not doing anything valuable in your custom getter and setter, you should lose those computed properties entirely because this is just convoluted and inefficient. Plus the underscore convention is used for hidden, private properties, not for properties you expose.

  3. One is left to infer that your GoogleMap method is returning a [String: Any] produced by toJSON. In Swift 4, you can use JSONEncoder and make your model object Encodable (or Codable), and you can avoid that toJSON method. Just change GoogleMap to return the simple model object which you can then encode with JSONEncoder.

So, that leaves us with:

let url = URL(string: "http://test.com/google/getAddress")!

var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let coordinate = Coordinate(latitude: 34.05222, longitude: -118.242) // set this however you want
request.httpBody = try! JSONEncoder().encode(coordinate)

URLSession.shared.dataTask(with: request) { data, _, error in
    guard let data = data, error == nil else {
        print(error ?? "Unknown error")
        return
    }

    do {
        let responseObject = try JSONSerialization.jsonObject(with: data)
        print(responseObject)
    } catch let parseError {
        print(parseError)
    }
}.resume()

And your model object is reduced to merely:

struct Coordinate: Codable {
    var latitude: Double
    var longitude: Double
}

Or, if you really need it to be a reference type, a class:

class Coordinate: Codable {
    var latitude: Double
    var longitude: Double

    init(latitude: Double, longitude: Double) {
        self.latitude = latitude
        self.longitude = longitude
    }
}

If you're stuck in Swift 3, then go ahead and make a dictionary, but I'd make it [String: Double], e.g.

let url = URL(string: "http://ipinbar.net:8080/google/getAddress")!

var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let coordinate = Coordinate(latitude: 34.05222, longitude: -118.242) // set this however you want
request.httpBody = try! JSONSerialization.data(withJSONObject: coordinate.dictionary)

URLSession.shared.dataTask(with: request) { data, _, error in
    guard let data = data, error == nil else {
        print(error ?? "Unknown error")
        return
    }

    do {
        let responseObject = try JSONSerialization.jsonObject(with: data)

        print(responseObject)
    } catch let parseError {
        print(parseError)
    }
}.resume()

and

struct Coordinate {
    var latitude: Double
    var longitude: Double

    var dictionary: [String: Double] { return ["latitude": latitude, "longitude": longitude] }
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • hey Rob.tnx a lot. I'm using swift 3 and I can't update to 4 now.would you help with this line of code:request.httpBody = try! JSONEncoder().encode(coordinate). in swift 3 ??The equivalent of the JSONEncoder() – Ryan110 Apr 12 '18 at 05:17
  • @Ryan110 - Then that dictionary trick is fine, though the resulting model type is still a lot simpler than that original code snippet you supplied. ;) See expanded answer above. – Rob Apr 12 '18 at 05:31
  • you made my day...!! so there is question for your: why torsion() func not working but var dictionary works well.there for both are kinda same? – Ryan110 Apr 12 '18 at 06:48
  • and tnx to those who were vote me down for not logical reason – Ryan110 Apr 12 '18 at 06:51
  • @Ryan110 - Largely because, as I note in the beginning of my answer, I used `longitude` and you used `longtide` (you misspelled the name of the key). I think the casting of the optionals to `Any`, without unwrapping them, is dangerous, though I don’t think that was, technically, a problem. – Rob Apr 12 '18 at 09:59
  • tnx for being so kind Rob. my final question is I have a model class for parsed son.how can I parse my son into my model class? – Ryan110 Apr 12 '18 at 10:14
  • class Google{ init() { } let results:[results] = [] let status:String = "" } – Ryan110 Apr 12 '18 at 10:16
  • First, it’s too bad that you can’t contemplate transitioning to Swift 4 (a breeze in comparison to the Swift 2 to 3 transition process), because it makes this stuff so much easier. Second, in Swift 3, my approach would be to parse the JSON into a dictionary and then manually navigate through it. I’d write a `init?(dictionary: [String: Any])` method to convert the dictionary into your model object. If you have more questions, you should probably post a new question rather than continuing more comments here, under an answer that is only peripherally related to these new questions. – Rob Apr 12 '18 at 10:38
  • Rob I know this is to a good place to ask a question but they vote me down and I'm limited for asking new question. would you help me with this?? – Ryan110 Apr 15 '18 at 06:20
  • my model class :class Google{ var results:[Results] var status:String init(Json:[String:Any]) { status=Json["status"] as! String results=Json["results"] as! [Results] } – Ryan110 Apr 15 '18 at 06:26
  • and I'm init it this way. :let c = Google(Json:responseObject). but nil returns – Ryan110 Apr 15 '18 at 06:27
  • will you remove url address from source code please ? – Ryan110 May 04 '18 at 17:41
  • @Ryan110 - Done. And if that URL is highly confidential, you can "flag" your question for moderator attention to ask them to purge revision history for both your question and this answer, both of which have that URL in their respective revision histories. – Rob May 04 '18 at 17:46