I want to send a POST request to my php 7 server which accepts data as application/x-www-form-urlencoded. The data I have is inside a Struct and I want to get every property of this struct as a parameter when I submit it.
This is the struct which handles my urlSession requests both GET and POST
XHR.swift
struct XHR {
    enum Result<T> {
        case success(T)
        case failure(Error)
    }
    func urlSession<T>(method: String? = nil, file: String, data: Data? = nil, completionHandler: @escaping (Result<T>) -> Void) where T: Codable {
        let file = file.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
        // Set up the URL request
        guard let url = URL.init(string: file) else {
            print("Error: cannot create URL")
            return
        }
        var urlRequest = URLRequest(url: url)
        if method == "POST" {
            urlRequest.httpMethod = "POST";
            urlRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
            urlRequest.httpBody = data
            print(urlRequest.httpBody)
        }
        // set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
        // vs let session = URLSession.shared
        // make the request
        let task = session.dataTask(with: urlRequest, completionHandler: {
            (data, response, error) in
            DispatchQueue.main.async { // Correct
                guard let responseData = data else {
                    print("Error: did not receive data")
                    return
                }
                let decoder = JSONDecoder()
                print(String(data: responseData, encoding: .utf8))
                do {
                    let todo = try decoder.decode(T.self, from: responseData)
                    completionHandler(.success(todo))
                } catch {
                    print("error trying to convert data to JSON")
                    //print(error)
                    completionHandler(.failure(error))
                }
            }
        })
        task.resume()
    }
}
This is the functions which sends a POST request to the server:
VideoViewModel.swift
struct User: Codable {
    let username: String
    let password: String
    static func archive(w:User) -> Data {
        var fw = w
        return Data(bytes: &fw, count: MemoryLayout<User>.stride)
    }
    static func unarchive(d:Data) -> User {
        guard d.count == MemoryLayout<User>.stride else {
            fatalError("BOOM!")
        }
        var w:User?
        d.withUnsafeBytes({(bytes: UnsafePointer<User>)->Void in
            w = UnsafePointer<User>(bytes).pointee
        })
        return w!
    }
}
enum Login {
    case success(User)
    case failure(Error)
}
func login(username: String, password: String, completionHandler: @escaping (Login) -> Void) {
    let thing = User(username: username, password: password)
    let dataThing = User.archive(w: thing)
    xhr.urlSession(method: "POST", file: "https://kida.al/login_register/", data: dataThing) { (result: XHR.Result<User>) in
        switch result {
        case .failure(let error):
            completionHandler(.failure(error))
        case .success(let user):
            //let convertedThing = User.unarchive(d: user)
            completionHandler(.success(user))
        }
    }
}
And I call it like this:
videoViewModel.login(username: "rexhin", password: "bonbon") { (result: VideoViewModel.Login) in
    switch result {
    case .failure(let error):
        print("error")
    case .success(let user):
        print(user)
    }
}
From PHP I can see that a POST request is submitted successfully but when I try to get the username field by doing $_POST["username"] I get Undefined index:
Full code of the app can be seen here https://gitlab.com/rexhin/ios-kida.git
 
     
     
     
    