Suyeon9911 / TIL

매일 오전에 적는 미라클 TIL 🥣
10 stars 0 forks source link

[iOS] 서버에 대한 모든 것 (Feat. Alamofire) #39

Closed Suyeon9911 closed 2 years ago

Suyeon9911 commented 2 years ago

네트워크

데이터를 서버에 요청하고 받기 클라이언트와 서버 관계

요청과 응답 ! -> 간단하면서도 중요한 개념 휴대폰에서 어떤 액션을 취했을 때 서버에게 원하는 데이터를 요청을 하고, 서버에서는 요청에 따른 적절한 응답을 다시 해준다 !

클라이언트 : 앱에서의 어떠한 동작을 처리하기 위해 서버에 데이터에 관련 처리를 요청함

서버 : 클라이언트의 요청에 대해 응답

프로토콜 (HTTP프로토콜) : 일련의 규칙, 정해진 형태 => 클라와 서버는 서로 알아들을 수 있는 규칙을 만들어서 요청,응답을 수행하게 됩니다.

클라이언트의 역할은 무엇일까요??

프로토콜

HTTP: Hypertext Transfer Protocol

REST API 사용

Representational State Transfer

3가지 요소

  1. 자원 : URI를 통해 자원에 접근, URL란 자원의 위치를 나타내는 주소
  2. 행위 : HTTP Method - GET/POST/PUT/DELETE 4가지 메서드로 접근
  3. 표현(메시지) : JSON 포맷의 데이터
Suyeon9911 commented 2 years ago

면접 끝나고 해야징 ~~꼭 .. 난 왤케 감자일까? ㅜ 울지마 ..................................................................................... 뿌에에ㅔ에에엥

Suyeon9911 commented 2 years ago

JSON

Suyeon9911 commented 2 years ago

HTTP 메서드

HTTP 응답

200번대 : 성공 400번대 : 클라이언트 에러 500번대 : 서버에러

200 : 요청 성공 201 : 요청 성공, 새로운 리소스가 생성, POST, PUT 이후에 응답 202 : 요청 접수, 아직 미처리

400: 클라이언트의 요청이 유효하지 않은 상태 401: 클라이언트가 권한이 없어서 작업을 진행하지 못하는 상태 , 인증필요 403: 서버가 요청을 거부할때, 사용자가 리소스에 대한 필요 권한을 가지고 있지 않을 떄 404 : 서버가 요청한 페이지를 찾지 못했을 때, 존재하지 않은 페이지를 요구 405: 클라이언트의 요청이 허용되지 않은 메서드인 경우

500: 서버에 오류가 발생하여 요청을 수행할 수 없는 경우 501: 서버에 해당요청을 수행할 수 있는 기능이 없는 경우 - 요청메서드를 인식 못함 503: 일시적으로 서버를 이용할 수 없는 경우 - 서버 오버로드, 유지관리 위한 다운

Suyeon9911 commented 2 years ago

API 명세서에서 주의깊게 봐야할 것 들

  1. BaseURL
  2. HTTP Method
  3. Path
  4. Request - Header, Parameter, Body
  5. Response - StatusCode, Value
Suyeon9911 commented 2 years ago

서버통신 흐름 정리

-클라이언트가 서버에게 특정 URI로 요청을 하면 JSON형태로 데이터를 받는 것

Encode: 암호화하는 과정 - Swift 코드를 JSON 형식으로 바꾸는 과정

Decode: 해독하는 과정 : JSON을 Swift로 바꾸는 과정

인코딩을 통해 스위프트코드를 json으로 변환 -> 요청서를 가지고 서버에 요청을 보냄 -> JSON 데이터로 응답을 보내줌 -> 디코딩을 통해 JSON 데이터를 Swift로 변환

Suyeon9911 commented 2 years ago

CocoaPods ; iOS에서 사용되는 의존성 관리 도구 중 하나

Carthage : 빌드 시 라이브러리를 프로잭트와 통합하지 않고 관리

빠른 빌드 속도, 동적라이브러리

Suyeon9911 commented 2 years ago

서버통신 순서 !

  1. API 명세 확인하기

  2. 포스트맨 테스트하기 --- 서버 파트원과 필요한 데이터 논의 , api 테스트 과정

  3. 사전준비 1) http 통신을 위한 plist 설정

  4. 사전준비 2) APIConstants

  5. 사전준비 3) NetworkResult

  6. 데이터 모델 생성

  7. Service 코드 작성

  8. Service 코드 호출

Suyeon9911 commented 2 years ago

2단계 사전 준비

1) plist 설정

애플 측에서는 앱 자체의 보안성을 위해서 ATS 라는 정책을 통해 기본적으로 https 통신을 하도록 유도하고 있습니다. 그래서 http 서버와 통신을 하려고 하면 에러가 발생합니다.

2) APIConstants : 어디에 있는 자원을 찾을 것인지 URI를 관리하기 쉽게 API주소를 모아놓은 파일 만들기

3) NetworkResult : 서버통신 결과를 처리하기 위한 파일 만들기

Suyeon9911 commented 2 years ago

3단계 서버통신

  1. 넘겨받은 JSON을 Swift 객체 형태로 잘 사용할 수 있도록 DataModel을 만들고
  2. 실제로 서버에 Request하는 코드와
  3. 서버에서 넘겨받은 Response를 받아보는 코드를 작성 !

작성한 서버통신 코드를 뷰컨에서 호출

1) DataModel

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

데이터 모델을 encode하거나 decode 하려면 프로토콜 채택이 필요합니다. 바로 , Encodable, Decodable 프로토콜 !

Codable이라는 프로토콜을 사용해서 한꺼번에 ! 인코더블 과 디코더블의 묶음 !



### 데이터 부분은 왜 옵셔널일까 ?? 
- 로그인이 성공했을때는 data가 넘어오는데 실패했을 때는 data가 안넘어오기 때문 !

준비 완료 
api 주소모음 구조체, 서버통신 결과처리 열거형, 서버통신 결과로 받는 응답 바디를 디코딩할 데이터보델 !!
Suyeon9911 commented 2 years ago

Request. Response

1) import Alamofire 2) Service 클래스를 만들어주고 싱글톤 객체를 선언한다 : 앱 어디에서든지 접근할 수 있도록

싱글톤 ?

1) 로그인 통신을 할 때 사용할 함수를 정의 - 필요한 값을 파라미터로 받자 .

2) URI, Request header, Request Body 준비

3) 요청서 만들기 : Alamofire에서 제공하는 여러가지 메서드가 있는데요, 그 중에서 encoding이라는 파이미터가 들어간 함수로 request를 만들 거에욤 !

4) 만든 요청서의 responseData메서드를 호출 : 데이터 통신 시작 !

dataRequest.responseData { response in 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) } }

- 성공이면 데이터 처리 
- 실패면 networkfil 값을 담아서 뷰컨에 넘겨줌 !!

### 성공인 경우로 가보자
- 먼저, 통신 결과의 statuscode와 value값을 가져옵니다. 
- 그리고 가져온 값들을 만들어 놓은 judgeStatus() 메서드를 이용해 정제된 networkResult를 받아서 그 값을 completion 파라미터에 넣습니다 . 

- judgeStatus()

```swift
private func judgeStatus(by statusCode: Int, _ data: Data) -> NetworkResult<Any> {
    switch statusCode {
    case 200: return isVaildData(data: data)
    case 400: return .pathErr
    case 500: return .serverErr
    default: return .networkFail
   }
}

: 서버통신 자체는 성공일지라도 응답 실패로 우리가 원하는 데이터를 받지 못한 상태일 때를 분기처리하기 위한 메서드

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.data as Any)
}

: 통신이 성공하고 원하는 데이터가 올바르게 들어왔을 때 데이터 처리를 위한 함수 .

4) 작성한 서비스 코드를 뷰 컨트롤러에서 호출

Suyeon9911 commented 2 years ago

수고했어잉 ~