SwiftDeveloper SwiftDeveloper - 15 days ago 20
JSON Question

How to use httpMethod = POST on Swift 3 , URLRequest?

I have working

json
fetching codes with
GET
methods but when i convert it to
POST
with adding;

request.httpMethod = "POST"


gives me ;


Cannot assign to property: 'httpMethod' is a get-only property Error


My codes under below how can fix it ? How can i convert it to
POST


@discardableResult
open func getLoginMethod(_ method: String, parameters: String, completionHandler: @escaping (_ login: [Login]?, _ error: Error?) -> Void) -> URLSessionTask! {
let session = URLSession.shared
guard let url = NSURL(string: parameters) else {
completionHandler(nil, myErrors.InvalidUrlError)
return nil
}
let request = NSURLRequest(url: url as URL)

let task = session.dataTask(with: request as URLRequest) { data, response, error in
if error != nil {
completionHandler(nil, myErrors.getError)
} else {
do {
let login = try self.getLogin(jsonData: data! as NSData)
completionHandler(login, nil)
} catch {
completionHandler(nil, error)
}
}
}
task.resume()

return task
}


Also my calling codes under below for
get
method my variables inside
parameters
, for
POST
method which changes i need to do ?

AWLoader.show(blurStyle: .dark, shape: .Circle)

DispatchQueue.global(qos: .background).async {
myApp.sharedInstance().getLoginMethod("", parameters: "http://bla.com/Post?Phone=\(self.phone.text)") {login, error in
if error != nil {
DispatchQueue.main.async {
// self.showAlert()

print(error!)

AWLoader.hide()
}
} else {
DispatchQueue.main.async {
self.getlogin = login!
// self.collectionView.reloadData()
// AWLoader.hide()

// self.loginButton.alpha = 0
print(self.getlogin)


AWLoader.hide()
}
}
}


}


Thanks

Answer

You need to use NSMutableURLRequest to be able to modify httpMethod. Using NSURLRequest won't do.

Example:

let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"

But even better, you should be using URLRequest struct:

var request = URLRequest(url: url)
request.httpMethod = "POST"

Your refactored code with additional improvements:

@discardableResult
open func getLoginMethod(_ method: String, parameters: String,
                     session: URLSession = .shared,
                     completionHandler: @escaping (_ login: [Login]?, _ error: Error?) -> Void) -> URLSessionTask! {

    guard let url = URL(string: parameters) else {
        completionHandler(nil, myErrors.InvalidUrlError)
        return nil
    }
    var request = URLRequest(url: url)
    request.httpMethod = method
    let task = session.dataTask(with: request) { data, _, _ in
        guard let responseData = data else {
            completionHandler(nil, myErrors.getError)
            return
        }
        do {
            let login = try self.getLogin(jsonData: data as NSData)
            completionHandler(login, nil)
        } catch {
            completionHandler(nil, error)
        }
    }
    task.resume()

    return task
}

EDIT: To answer your second part of the question. It depends on what kind of data format your API is expecting - whether it should be multipart/form-data or json format, it all depends. But in general, assuming that you are using URLRequest struct that I've mentioned, you should just convert it to Data using your serializer and use it like this:

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = <your parameters converted to Data>

Usually, your API will expect proper Content-Type header added to your URLRequest:

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