Reputation: 1712
I have create a client service class to make call GET
request from web api. I tried to extended but have more web method POST
,PUT
,Delete
.I don't find good example in how to create POST,PUT,Delete using swift closure.I just want to ask how to add POST,PUT,Delete to client service?
import Foundation
class ClientService{
func getClients(searchstring:String,pageNumber:Int,callBack:(NSArray)->()){
request("\(_settings.baseUrl)Client/\(searchstring)/\(String(pageNumber))/rrn/brns", callBack: callBack)
}
func request(url:String,callBack:(NSArray)->()){
let nsURL = NSURL(string:url);
let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL!){
(data,response,error) in
do {
let response = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
callBack(response)
} catch let error as NSError {
print("json error: \(error.localizedDescription)")
}
}
task.resume()
}
init(){
self._settings = Settings();
}
var _settings:Settings!;
}
Upvotes: 0
Views: 12733
Reputation: 650
Swift 4 version (I think):
func restRequest(url:String, method: String, params: [String: String], completion: @escaping ([AnyObject])->() ){
if let nsURL = NSURL(string:url) {
let request = NSMutableURLRequest(url: nsURL as URL)
if method == "POST" {
// convert key, value pairs into param string
let postString = params.map { "\($0.0)=\($0.1)" }.joined(separator: "&")
request.httpMethod = "POST"
request.httpBody = postString.data(using: String.Encoding.utf8)
}
else if method == "GET" {
let postString = params.map { "\($0.0)=\($0.1)" }.joined(separator: "&")
request.httpMethod = "GET"
}
else if method == "PUT" {
let putString = params.map { "\($0.0)=\($0.1)" }.joined(separator: "&")
request.httpMethod = "PUT"
request.httpBody = putString.data(using: String.Encoding.utf8)
}
// Add other verbs here
let task = URLSession.shared.dataTask(with: request as URLRequest) {
(data, response, error) in
do {
// what happens if error is not nil?
// That means something went wrong.
// Make sure there really is some data
if let data = data {
let response = try JSONSerialization.JSONObjectWithData(data, options: JSONSerialization.ReadingOptions.MutableContainers)
completion(response)
}
else {
// Data is nil.
}
} catch let error as NSError {
print("json error: \(error.localizedDescription)")
}
}
task.resume()
}
else{
// Could not make url. Is the url bad?
// You could call the completion handler (callback) here with some value indicating an error
}
}
Upvotes: 1
Reputation: 4219
You are on the right track. I make a separate function for get, post, put, delete etc. But you could make them in a one function if you want.
Bear in mind, this code is just to illustrate how to do it. You will need to modify it for your needs.
func request(url:String, method: String, params: [String: String], completion: ([AnyObject])->() ){
if let nsURL = NSURL(string:url) {
let request = NSMutableURLRequest(URL: nsURL)
if method == "POST" {
// convert key, value pairs into param string
postString = params.map { "\($0.0)=\($0.1)" }.joinWithSeparator("&")
request.HTTPMethod = "POST"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
}
else if method == "GET" {
postString = params.map { "\($0.0)=\($0.1)" }.joinWithSeparator("&")
request.HTTPMethod = "GET"
}
else if method == "PUT" {
putString = params.map { "\($0.0)=\($0.1)" }.joinWithSeparator("&")
request.HTTPMethod = "PUT"
request.HTTPBody = putString.dataUsingEncoding(NSUTF8StringEncoding)
}
// Add other verbs here
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(data, response, error) in
do {
// what happens if error is not nil?
// That means something went wrong.
// Make sure there really is some data
if let data = data {
let response = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)
completion(response)
}
else {
// Data is nil.
}
} catch let error as NSError {
print("json error: \(error.localizedDescription)")
}
}
task.resume()
}
else{
// Could not make url. Is the url bad?
// You could call the completion handler (callback) here with some value indicating an error
}
}
Call it like this:
request("http://somedomain.etc", "POST", ["key1" : "value1", "key2", "values2"]) {
(result) in
// Handle result here.
}
You will note that I eliminated NSArray. [AnyObject] is the Swift way to do this.
I recommend that you add some sort of error indicator in the completion handler. That would let you detect that something went wrong and handle it.
Be very cautious when using ! to unwrap variables. This is the most common reason for apps crashing.
Upvotes: 3
Reputation: 371
Instead of using dataTaskWithUrl
, you could create an HTTP request like this:
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = jsonData
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(String (jsonData?.length), forHTTPHeaderField: "Content-Length")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { data, res, error in
// etc etc
Everything else in your example above would be the same. You'd have to provide the json data, of course. For that, you could do something like this:
let data: [String: AnyObject] = ["nameValue": dataValue]
var jsonData: NSData? = nil
do {
jsonData = try NSJSONSerialization.dataWithJSONObject(data, options: NSJSONWritingOptions(rawValue: 0))
} catch {
// some error serializing
}
Upvotes: 1
Reputation: 2496
i use for mes projects Alamofire (Elegant HTTP Networking in Swift), and i love it
so example how to use POST
let parameters = [
"foo": "bar",
"baz": ["a", 1],
"qux": [
"x": 1,
"y": 2,
"z": 3
]
]
Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters)
// HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3
and here how to use Delete
Alamofire.request(.DELETE, "https://httpbin.org/delete")
go to documentation is very good https://github.com/Alamofire/Alamofire and if you want use swift without framework
this is example how to use POST
var request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:4567/login"))
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var params = ["username":"jameson", "password":"password"] as Dictionary<String, String>
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
var success = parseJSON["success"] as? Int
println("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: \(jsonStr)")
}
}
})
task.resume()
Upvotes: 3