(swift) 로그인 & 회원가입 DB 연동(post)

0

ios

목록 보기
5/6

어느정도의 UI작업이 진행 된 후, 백엔드쪽에서 만든 API를 프론트에서 받아와 연동하는 기능구현을 작업한다.

그 중, 제일 먼저 해야할 작업은 회원가입&로그인 구현이다.

간단하게 요약을 하자면,,,

  1. 회원가입을 할 때 textfield에 넣었던 text(아이디, 비밀번호, 닉네임 등)을 서버로 post를 날린다.
  2. 날아간 post 데이터(회원가입 완료된 데이터)를 토대로 로그인을 해서 일치했으면 로그인 완료.

한번 해보자,,,

1. 회원가입과 로그인 데이터 model 구성

백엔드에서 만든 swagger를 통해 얻을 수 있는 Json파일로 Model을 만들 수 있다.

<회원가입 Model 만들기>


<로그인 Model 만들기>


2. NetworkResult 만들기

3. 회원가입 및 로그인 서비스 만들기

1.SignUpService.swift

import Alamofire
//(1) 라이브러리 추가

class SignUpSercive {
    
    static let shared = SignUpSercive()
//(2)싱글통 객체를 선언해서 앱 어디에서든지 접근가능하도록 한다
    private init() {}
    
    func signup(nickname : String, email: String, password: String, completion: @escaping(NetworkResult<Any>) -> Void)
    {
        let url = APIConstants.signupURL //통신할 API 주소
        
        //HTTP Headers : 요청 헤더
        let header : HTTPHeaders = ["Content-Type" : "application/json"]
        
        //요청 바디
        let body : Parameters = [
            "email" : email,
            "nickname" : nickname,
            "password" : password
        ]
        
        //요청서 //Request 생성
        //통신할 주소, HTTP메소드, 요청방식, 인코딩방식, 요청헤더
        let dataRequest = AF.request(url,
                                    method: .post,
                                    parameters: body,
                                    encoding: JSONEncoding.default,
                                    headers: header)
                                    
        //request 시작 ,responseData를 호출하면서 데이터 통신 시작
        dataRequest.responseData{
            response in //데이터 통신의 결과가 response에 담기게 된다
            switch response.result {
            case .success: //데이터 통신이 성공한 경우에
                guard let statusCode = response.response?.statusCode else {return}
                guard let value = response.value else {return}
                
                let networkResult = self.judgeStatus(by: statusCode, value)
                completion(networkResult)
            case .failure:
                completion(.networkFail)
            }
        }
    }
    private func judgeStatus(by statusCode: Int, _ data: Data) -> NetworkResult<Any> {
        switch statusCode {
        case ..<300 : return isVaildData(data: data)
        case 400..<500 : return .pathErr
        case 500..<600 : return .serverErr
        default : return .networkFail
        }
    }
    //통신이 성공하고 원하는 데이터가 올바르게 들어왔을때 처리하는 함수
    private func isVaildData(data: Data) -> NetworkResult<Any> {
        let decoder = JSONDecoder() //서버에서 준 데이터를 Codable을 채택
        guard let decodedData = try? decoder.decode(SignupResponse.self, from: data)
        //데이터가 변환이 되게끔 Response 모델 구조체로 데이터를 변환해서 넣고, 그 데이터를 NetworkResult Success 파라미터로 전달
        else { return .pathErr }
        
        return .success(decodedData as Any)
    }
}

LoginService.swift

import Foundation
import Alamofire
//(1) 라이브러리 추가

class LoginSercive {
    
    static let shared = LoginSercive()
//(2)싱글통 객체를 선언해서 앱 어디에서든지 접근가능하도록 한다
    private init() {}
    
    func login(email: String, password: String, completion: @escaping(NetworkResult<Any>) -> Void)
    {
        let url = APIConstants.loginURL //통신할 API 주소
        
        //HTTP Headers : 요청 헤더
        let header : HTTPHeaders = ["Content-Type" : "application/json"]
        
        //요청 바디
        let body : Parameters = [
            "email" : email,
            "password" : password
        ]
        
        //요청서 //Request 생성
        //통신할 주소, HTTP메소드, 요청방식, 인코딩방식, 요청헤더
        let dataRequest = AF.request(url,
                                    method: .post,
                                    parameters: body,
                                    encoding: JSONEncoding.default,
                                    headers: header)
                                    
        //request 시작 ,responseData를 호출하면서 데이터 통신 시작
        dataRequest.responseData{
            response in //데이터 통신의 결과가 response에 담기게 된다
            switch response.result {
            case .success: //데이터 통신이 성공한 경우에
                guard let statusCode = response.response?.statusCode else {return}
                guard let value = response.value else {return}
                
                let networkResult = self.judgeStatus(by: statusCode, value)
                completion(networkResult)
                
                
            case .failure:
                completion(.networkFail)
            }
        }
    }
    private func judgeStatus(by statusCode: Int, _ data: Data) -> NetworkResult<Any> {
        switch statusCode {
        case ..<300 : return isVaildData(data: data)
        case 400..<500 : return .pathErr
        case 500..<600 : return .serverErr
        default : return .networkFail
        }
    }
    //통신이 성공하고 원하는 데이터가 올바르게 들어왔을때 처리하는 함수
    private func isVaildData(data: Data) -> NetworkResult<Any> {
        let decoder = JSONDecoder() //서버에서 준 데이터를 Codable을 채택
        guard let decodedData = try? decoder.decode(LoginResponse.self, from: data)
        //데이터가 변환이 되게끔 Response 모델 구조체로 데이터를 변환해서 넣고, 그 데이터를 NetworkResult Success 파라미터로 전달
        else { return .pathErr }
        
        return .success(decodedData as Any)
    }
}

이렇게 만든 Service를 통해 연결하고 싶은 VC로 가서 extension을 하여 함수를 만들고, 만든 함수를 가지고 viewDidLoad에 넣어주면 된다.

<예: 로그인 기능구현>

extension LoginViewController {
    
    
    func login() {
        
        guard let email = idtextField.text else { return }
        guard let passward = passwordtextField.text else { return }
        
        
        LoginSercive.shared.login(email: email, password: passward) { response in
            switch response {
            case .success(let data):
                
                guard let data = data as? LoginResponse else { return }
                if data.result == "SUCCESS"{
                    UserDefaults.standard.set(data.data?.jwtToken, forKey: "jwtToken")
                    let nav = UINavigationController()
                    nav.modalPresentationStyle = .fullScreen
                    nav.navigationBar.barTintColor = .white
                    nav.navigationBar.tintColor = UIColor(w: 42)
                    
                   //MARK: - 네비게이션 중복 수정 1/31
                    nav.navigationBar.isHidden = true
                    
                    let controller = TabBarViewController()
                    nav.viewControllers = [controller]
                    self.present(nav, animated: true, completion: nil)
                    print(data.message)
                }
                else {
                    let alert = UIAlertController(title: data.message, message: "", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "확인", style: .cancel, handler: nil))
        //            alert.addAction(UIAlertAction(title: "DEFAULT", style: .default, handler: nil))
        //            alert.addAction(UIAlertAction(title: "DESTRUCTIVE", style: .destructive, handler: nil))
                    
                    self.present(alert, animated: true, completion: nil)
                    print(data.message)
                }
                
            case .requestErr(let err):
                print(err)
            case .pathErr:
                print("pathErr")
            case .serverErr:
                print("serverErr")
            case .networkFail:
                print("networkFail")
            }
        }
    }
    
}

<만들어놨던 버튼에 함수 넣기>

이러면 로그인과 회원가입 완료!!

profile
00년차 iOS 개발자

0개의 댓글