-2

I am using this code below to send a HTTP request to my PHP API

static func submitNumber(parameters: [String: Any]){
    print("parameters", parameters)
    guard let url = URL(string: Constants.phoneVerifyUrl) else {
        print("URL not found")
        return
    }
    let datas = try! JSONSerialization.data(withJSONObject: parameters, options: [])
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = datas
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    
    let urlSession = URLSession.shared.dataTask(with: request) { data, _, error in
        if error != nil {
            print("error", error?.localizedDescription ?? "")
            return
        }
        do {
            if let data = data {
                print("data", data)
                let decodedData = try JSONDecoder().decode(DataModels.self, from: data)
                DispatchQueue.main.async {
                    let noError = decodedData.noError
                    let dataStr = decodedData.dataStr
                    print("noError", noError)
                    print("dataStr", dataStr)
                }
            } else {
                print("No Data received")
            }
        } catch let JsonError {
            print("JSON error", JsonError.localizedDescription)
        }
    }
    urlSession.resume()
}

And then in my PHP API, I try to receive the data like this

<?php
    if(isset($_POST)){
        $phoneNumber = $_POST['phoneNumber'];
        
        //Run Code here
        
    }
?>

When I do

print("parameters", parameters)

This is what I get (As expected)

parameters ["phoneNumber": "1234567890"]

But then, for a reason I don't know, the code in my PHP API is not executing. The PHP code is perfectly working because I use the same API for my Android app and it works fine, so I know the issue is not from my PHP API

And when I also do this print("data", data) I get a random number like this data 8402 bytes

For me, I believe I'm not passing the parameters in the right way to my API, Since I'm new to Swift, I don't know how it's done

And for my URL string Constants.phoneVerifyUrl, it's okay

Please note: I don't want to temper with my PHP API as I also use it for my Android app. So I need only to fix my Swift code

KANAYO AUGUSTIN UG
  • 2,078
  • 3
  • 17
  • 31
  • FYI `$_POST` is always set - [demo](https://ideone.com/G8mn2H) – DarkBee Jun 09 '22 at 07:18
  • Does this answer your question? [Receive JSON POST with PHP](https://stackoverflow.com/questions/18866571/receive-json-post-with-php) – CBroe Jun 09 '22 at 07:20
  • 2
    _"I don't want to temper with my PHP API"_ - then you need to stop sending this as `application/json`, and send one of the two formats that make PHP actually populate $_POST instead. https://www.php.net/manual/en/reserved.variables.post.php: _"An associative array of variables passed to the current script via the HTTP POST method **when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type** in the request."_ – CBroe Jun 09 '22 at 07:21
  • No... Your suggested Answer has nothing to do with SWIFT, and like I said, I don't want to temper with my PHP API – KANAYO AUGUSTIN UG Jun 09 '22 at 07:24
  • @CBroe... I changed my Content-Type to ***multipart/form-data*** but still, no difference – KANAYO AUGUSTIN UG Jun 09 '22 at 07:34
  • Of course not, you need to change the way you prepare your data as well. Right now, you are still _sending_ JSON, and just pretend that it was something else. – CBroe Jun 09 '22 at 07:38
  • @CBroe... Okay. I'm totally a newbie to Swift, so please can you try put me through on how to go about it. Maybe you can post an answer or a comment showing how it's done – KANAYO AUGUSTIN UG Jun 09 '22 at 07:41
  • 1
    You should really do a bit of basic research. "swift application/x-www-form-urlencoded" typed into Google, leads to results such as https://medium.com/@serge.works.io/swift-how-to-create-a-http-post-request-with-application-x-www-form-urlencoded-body-bfd9cd26d6d5 in no time. – CBroe Jun 09 '22 at 07:46
  • 1
    "And when I also do this print("data", data) I get a random number like this data 8402 bytes" -> That's the the `description` of a `(NS)Data` instance, it's normal. Try `print("Data as Strinig: \(String(data: data, encoding: .utf8)`), and also, get rid of all `error.localizedDescription` when printing, print `error`. – Larme Jun 09 '22 at 07:59

2 Answers2

0

I found an answer from to create post body request data using below code.

var jsonData:Data?
do {
   jsonData = try JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted)
} catch {
  print(error.localizedDescription)
}

and then create the request like this.

let url = URL(string: "https://blah.com/server/dudes/decide/this")!
var request = URLRequest(url: url)

request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept") 
request.httpMethod = "POST"
request.httpBody = jsonData
0

Okay... My first answer was wrong, but I've got it figured out.

First I removed this lines

request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")

And replaced it with this

request.addValue("application/json", forHTTPHeaderField: "Accept")

Then I changed my Data parameters dictionary from JSON to String

var datas = parameters.toQueryString.data(using: .utf8)!

Below is the Dictionary extension of toQueryString

extension Dictionary {
    var toQueryString: String? {
        return self.reduce("") { "\($0!)\($1.0)=\($1.1)&" }
    }
}
KANAYO AUGUSTIN UG
  • 2,078
  • 3
  • 17
  • 31