Skip to content

Commit

Permalink
[FEAT] 로그인 화면 서버 통신
Browse files Browse the repository at this point in the history
  • Loading branch information
513sojin committed May 7, 2022
1 parent effb3b3 commit d84c178
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// APIConstants.swift
// week-4-seminar
//
// Created by Sojin Lee on 2022/05/07.
//

import Foundation

struct APIConstants{
// MARK: - Base URL
static let baseURL = "http://13.124.62.236/"

// MARK: - Feature URL
static let loginURL = baseURL + "auth/signin"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// LoginModel.swift
// week-4-seminar
//
// Created by Sojin Lee on 2022/05/07.
//

/*
{}: 중괄호 - Object
[]: 배열
*/

import Foundation

struct LoginResponse: Codable{
let status: Int
//let success: Bool?
let message: String
let data: LoginData?
}

struct LoginData: Codable{
let name: String
let email: String
}

struct MessageData: Codable{
let reason: String
let location: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// NetworkResult.swift
// week-4-seminar
//
// Created by Sojin Lee on 2022/05/07.
//

import Foundation

enum NetworkResult<T>{
case success(T)
case requestErr(T)
case pathErr
case serverErr
case networkFail
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// UserService.swift
// week-4-seminar
//
// Created by Sojin Lee on 2022/05/07.
//

import Foundation
import Alamofire

class UserService{
static let shared=UserService() //앱 어디서든 UserService에 접근할 수 있도록 함. 싱글톤 변수
private init() {}

func login(name: String, email:String, password: String, completion: @escaping (NetworkResult<Any>) -> Void)
{
let url = APIConstants.loginURL
let header: HTTPHeaders = ["Content-type": "application/json"]
let body: Parameters = [
"name": name,
"email": email,
"password": password
]

let dataRequest = AF.request(url, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header)

dataRequest.responseData { response in
// 요청(Request)를 하고 넘겨받은 응답의 결과를 가지고 성공 또는 실패 분기 처리를 합니다.
switch response.result {
case .success:
// 성공 시에는 상태코드(Status Code)와 값(Value)이 넘어오겠죠?
guard let statusCode = response.response?.statusCode else { return }
guard let value = response.value else { return }

// 해당 응답을 가지고 case 분기처리를 합니다. (200, 400, 500인지 - 200: 성공을 해서 데이터를 잘 받았는지 확인합니다.)
let networkResult = self.judgeStatus(by: statusCode, value)
completion(networkResult)

// 실패 시에는 바로 networkFail(통신 실패)라는 신호를 알립니다.
case .failure:
completion(.networkFail)
}
}
}

// 상태 코드와 값(value, data)를 가지고 통신의 결과를 핸들링하는 함수입니다.
private func judgeStatus(by statusCode: Int, _ data: Data) -> NetworkResult<Any> {
switch statusCode {
// 성공 시에는 넘겨받은 데이터를 decode(해독)하는 함수를 호출합니다.
case 200: return isVaildData(data: data)
case 400: return .pathErr
case 500: return .serverErr
default: return .networkFail
}
}

// 성공 시 넘겨받은 데이터를 decode하는 함수입니다.
// 이 때 우리가 codable을 채택해서 만들어 놓은 구조체 형식의 데이터 모델을 사용합니다.
private func isVaildData(data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(LoginResponse.self, from: data)
else { return .pathErr }

return .success(decodedData as Any)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// ViewController.swift
// week-4-seminar
//
// Created by Sojin Lee on 2022/05/07.
//

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var loginBtn: UIButton!

@IBAction func loginBtnTap(_ sender: Any) {
login()
}

override func viewDidLoad() {
super.viewDidLoad()
}
}

extension ViewController{
func login(){
// 각각의 텍스트 필드의 있는 값을 받아옵니다.
guard let name = nameTextField.text else { return }
guard let email = emailTextField.text else { return }
guard let password = passwordTextField.text else { return }

// 서버 통신 서비스 코드를 싱글톤 변수를 통해서 접근하고 있네요.
// 호출 후에 받은 응답을 가지고, 적절한 처리를 해주고 있습니다.
UserService.shared.login(
name: name,
email: email,
password: password) { response in
switch response {
case .success(let data):
guard let data = data as? LoginResponse else { return }
print(data)
self.alert(message: data.message)
case .requestErr(let err):
print(err)
case .pathErr:
print("pathErr")
case .serverErr:
print("serverErr")
case .networkFail:
print("networkFail")
}
}
}

// 알림창을 띄우는 함수입니다.
func alert(message: String) {
let alertVC = UIAlertController(title: message, message: nil, preferredStyle: .alert)
let okAction = UIAlertAction(title: "확인", style: .default, handler: nil)
alertVC.addAction(okAction)
present(alertVC, animated: true)
}
}

0 comments on commit d84c178

Please sign in to comment.