Вам необходимо кодировать параметры логина и пароля в запросе при отправке запроса. Давайте создадим отдельный класс Network
, который имеет функцию loginRequest(username:password)
, которая отправляет запрос API на сервер с параметрами имени пользователя и пароля. У метода входа в систему есть closure
, который либо возвращает строку userId, либо Error.
class Networking {
enum NetworkError: Error {
case parsingData
case jsonParsing
case emptyData
case apiError(error: Error)
}
func parseJSON(from data: Data) throws -> Any {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
return json
} catch {
return error
}
}
func loginRequest(username: String, password: String, completion: @escaping (String?, NetworkError?) -> ()) {
var request = URLRequest(url: URL(string: "api.nahadeh.com/connect/token")!)
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let queryParams = "grant_type=password&username=\(username)&password=\(password)"
request.httpBody = queryParams.data(using: .utf8, allowLossyConversion: false)
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard error != nil else {
completion(nil, NetworkError.apiError(error: error!))
return
}
guard let data = data else {
return completion(nil, NetworkError.emptyData)
}
do {
let json = try self.parseJSON(from: data) as! [String: Any]
guard let accessToken = json["access_token"] as? String else {
completion(nil, NetworkError.jsonParsing)
return
}
completion(accessToken, nil)
} catch {
completion(nil, NetworkError.jsonParsing)
}
}.resume()
}
}
Теперь из вашего подкласса UIViewController вы можете создать экземпляр класса Networking и вызвать метод login с параметрами username и password
class LoginViewController: UIViewController {
let networking = Networking()
func login(username: String, password: String) {
networking.loginRequest(username: username, password: password) { (token, error) in
if let token = token {
print(token)
self.displayMessage("Successfully loged in. Go to home screen")
return
}
if let nError = error {
switch nError {
case .jsonParsing:
self.displayMessage("jsonParsingError")
case .emptyData:
self.displayMessage("emptyData")
case .apiError(let error):
print(error.localizedDescription)
self.displayMessage("Could not successfully perform this request , please try later.")
case .parsingData:
self.displayMessage("parsingData")
}
}
}
}
func displayMessage(_ message: String, completion: (() -> Void)? = nil) {
let alert = UIAlertController(title: "Message", message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
present(alert, animated: true, completion: completion)
}
}
Используя Alamofire очень просто сделать запрос API, просто передайте параметры и он сделает всю работу за вас
func loginRequest(username: String, password: String, completion: @escaping (String?, Error?) -> ()) {
let params: [String: String] = [
"grant_id": "password",
"username": username,
"password" : password
]
Alamofire.request("api.nahadeh.com/connect/token", method: .post, parameters: params, encoding: .httpBody, headers: nil).validate().response { (response) in
switch response.result {
case .success(let value):
let accessToken = value["access_token"]
completion(accessToken, nil)
case .failure(let error):
completion(nil, error)
}
}
}