It's my first experience with REST in iOS development with swift. I couldn't find any working or straight (simple) example for doing what i need here.
I have a login backend (https://myaddress.com/rest/login), where I need to pass 2 params: login and password. When I pass good values (user exists in database) I get 2 variables as a result: token (string) and firstLogin (bool). So when I get those values I know that login is successful and I can log in into my app.
So I am begging you for an example (just a simple function) of how to achieve that. If I get working code example I will know how to use it for other rest services in my app. I tried many solutions from tutorials I found, but any of them was working for me.. So to not waste my time searching I would like someone experienced to show me the way to achieve that.
I am not sure if Alamofire is so good to use, I know that swift 4 has it's own build neetwork services and to work with json. Any solution that works would be great.
Also, side question - if I would prefer to use Alamofire, do I need to use swiftyJSON also? Or it's just for parsing?
You can use URLSession
if you don't like to import Alamofire
in your Project to perform a simple task.
here are some method : GET, POST, DELETE METHODS and tutorial
GET METHOD
func makeGetCall() {
// Set up the URL request
let todoEndpoint: String = "https://jsonplaceholder.typicode.com/todos/1"
guard let url = URL(string: todoEndpoint) else {
print("Error: cannot create URL")
return
}
let urlRequest = URLRequest(url: url)
// set up the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// make the request
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error calling GET on /todos/1")
print(error!)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
// parse the result as JSON, since that's what the API provides
do {
guard let todo = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
// now we have the todo
// let's just print it to prove we can access it
print("The todo is: " + todo.description)
// the todo object is a dictionary
// so we just access the title using the "title" key
// so check for a title and print it if we have one
guard let todoTitle = todo["title"] as? String else {
print("Could not get todo title from JSON")
return
}
print("The title is: " + todoTitle)
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()
}
POST METHOD
func makePostCall() {
let todosEndpoint: String = "https://jsonplaceholder.typicode.com/todos"
guard let todosURL = URL(string: todosEndpoint) else {
print("Error: cannot create URL")
return
}
var todosUrlRequest = URLRequest(url: todosURL)
todosUrlRequest.httpMethod = "POST"
let newTodo: [String: Any] = ["title": "My First todo", "completed": false, "userId": 1]
let jsonTodo: Data
do {
jsonTodo = try JSONSerialization.data(withJSONObject: newTodo, options: [])
todosUrlRequest.httpBody = jsonTodo
} catch {
print("Error: cannot create JSON from todo")
return
}
let session = URLSession.shared
let task = session.dataTask(with: todosUrlRequest) {
(data, response, error) in
guard error == nil else {
print("error calling POST on /todos/1")
print(error!)
return
}
guard let responseData = data else {
print("Error: did not receive data")
return
}
// parse the result as JSON, since that's what the API provides
do {
guard let receivedTodo = try JSONSerialization.jsonObject(with: responseData,
options: []) as? [String: Any] else {
print("Could not get JSON from responseData as dictionary")
return
}
print("The todo is: " + receivedTodo.description)
guard let todoID = receivedTodo["id"] as? Int else {
print("Could not get todoID as int from JSON")
return
}
print("The ID is: \(todoID)")
} catch {
print("error parsing response from POST on /todos")
return
}
}
task.resume()
}
DELETE METHOD
func makeDeleteCall() {
let firstTodoEndpoint: String = "https://jsonplaceholder.typicode.com/todos/1"
var firstTodoUrlRequest = URLRequest(url: URL(string: firstTodoEndpoint)!)
firstTodoUrlRequest.httpMethod = "DELETE"
let session = URLSession.shared
let task = session.dataTask(with: firstTodoUrlRequest) {
(data, response, error) in
guard let _ = data else {
print("error calling DELETE on /todos/1")
return
}
print("DELETE ok")
}
task.resume()
}
Thanks @MAhipal Singh for you answer. I'll post here example with Alamafire that I used so it's all in one stack question. It's easier than I though, solutions I tried to use before were not working cause I had problems with pinning certificate about I forgot..
func loginRest(login:String, password:String, deviceId:String){
let urlStr = restServices.REST_MAIN_URL + restServices.REST_LOGIN
let params = ["login":login, "password":password, "deviceId":deviceId]
let paramsJson = try! JSONSerialization.data(withJSONObject: params)
var headers: HTTPHeaders = ["Content-Type": "application/json"]
Alamofire.request(urlStr, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in
switch response.result {
case .success:
print("SUKCES with \(response)")
case .failure(let error):
print("ERROR with '\(error)")
}
}
If the post is proper the response is (console print):
SUKCES with SUCCESS: {
firstLogin = 1;
token = "dfkafjkfdsakfadsjfksjkfaadjfkjdfkjfskjfdkafjakfjakfjsafksjdafjy878328hjh";
}