Skip to content

Moya 서버통신 환경 세부내용

Hyungyu Kim edited this page Apr 28, 2022 · 1 revision

✨ Moya 서버통신 환경 세부내용

  • AppModels: (파일명 변경)프로젝트 내에서 사용할 데이터 모델.
  • NetworkModels: 서버통신 시 사용할 데이터 모델. request body 에 넣을 데이터 모델도 여기서 정의.
    • request body 데이터 모델 네이밍 -> ~~Request 라고 선언하기.
  • MoyaLoggerPlugin : log 확인할 수 있도록 인터페이스 생성해둠.
  • ~~API : 서버통신을 위해 호출하는 함수의 모임.
    • 네이밍 -> (Service 에서 선언한 열거형) ex) cardListPatch : 카드리스트 조회
  • ~~Service : TargetType 채택해서 path, method, task, headers 설정.
    • headers → Const 에 선언해두었습니다. 엑세스 토큰을 필요로 하지 않는(=회원가입) 경우 / 엑세스 토큰을 필요로 하는 경우.
  • NetworkResult : 서버통신 결과 열거형 정의.
  • GenericResponse : 제네릭을 사용한 공통적인 데이터 모델. data 역할만 NetworkModels 에서 선언해서 사용.

✨ 폴더링딩동

  • Auth: /auth/
  • Room : /room/
  • Feed : /feed/
  • MyRoom : /myRoom/
  • User : /user/
  • Notice : /notice/

(뭔가 세부적으로 나누기엔 내용도 주제도 살짝씩 겹치는거 같아서 네이밍이 더 헷갈릴까봐 엔드포인트로 구분했어요)

✨ 뷰컨에서 다음과 같이 사용해요

기본적인 구조는 이렇게 하면 좋을거같고! 추가로 편집해두 되여!

// MARK: - Network
    
// ✅ 코드컨밴션에서 정한대로 ~WithAPI. prefix 로 http method 명시.(ex. get~, post~)
    func getNewPopoWithAPI(popoId: Int, contents: NewPopo, image: UIImage) {
    
// ✅ (Service 에서 선언한 열거형) 네이밍
        TodayAPI.shared.getNewPopoPatch(popoId: popoId, contents: contents, image: image) { response in
            switch response {
            case .success(let data):
// ✅ 옵셔널 바인딩을 통해서 data 를 사용해주세요.
            if let popoToday = data as? PopoToday {
// ✅ 변수에 data 를 넣거나 reloadData()하거나 response 내용이 없다면 비워도 됩니다.
            }
            case .requestErr(let message):
// ✅ 해당 함수의 메서드명을 명시해서 서버통신의 결과를 출력해주세요.
                print("getNewPopoWithAPI - requestErr: \(message)")
            case .pathErr:
                print("getNewPopoWithAPI - pathErr")
            case .serverErr:
                print("getNewPopoWithAPI - serverErr")
            case .networkFail:
                print("getNewPopoWithAPI - networkFail")
            }
        }
    }

✨ request-query..? request-parameter...?

- 쿼리 선배 : Get방식이지만 따로 request 데이터를 만들어줘야 한다.(ex. api/user?id=123)
task)
return .requestParameters(parameters: ["lastid": lastID,
                                                   "size": size],
                                      encoding: URLEncoding.queryString)

- 파라미터 선배 : Get방식이고 데이터를 따로 만들지 않아도 된다.(ex. user/post/12345)

case .detailReview(let postId):
            return "/api/v1/post/detail/\(postId)"
path 안에다가 써주면 들어가신다. 이분은 task 가 return.requestPlain 방식이다.

Request param,query, body 의 차이점

✨ 서버에서 null 을 넘겨줘요!

서버에서 null 를 넘겨주지만 괜찮습니다 ^^ 우리에게는 옵셔널이 있으니깐여 옵셔널로 쓰면된다네용! 혹시 정보가 필요하시면 아래의 키워드로 검색해주세용~

  • iOS null 디코딩

저희가 이미지의 경우는

"profileImg" : [
	null,
	null
]

이렇게 받자나여? 이럴땐 꼭 [String?] 이렇게 설정해주세여!

✨ pathErr? 꼭! 읽어주세요

pathErr 는 경로에러라고 써두었는데요. 코드는 디코딩하지 못한 경우에 속해있어요. 리드놈 왜 이렇게 코드 짰냐..! 할 수 있지만

우리가 보통 404번이 뜨면 경로에러를 서버에서 분기처리해줄거에요. 그래서 우리가 진짜 요청하는 path 의 경로에러는 여기서 받을 수 있어요!

그런데 pathErr 로 경로에러를 따로 구분해서 디코딩하지 못한 경우에 넣은 것은 다음과 같은 경우 때문이에요

  • path 를 /room 이라고 설정해줘야하는데 /myroom 으로 했을 경우, /room/myroom 둘다 서버 통신이 가능하다면 서버통신은 성공하고 200번을 받을 거에요.

근데 서로 다른 데이터 모델로 디코딩하기 때문에 데이터는 넘어오지 않을거에요..! 이런 경우를 저는 pathErr 라고 명명하였습니당.

대신 진짜 path 를 잘 못 입력하는 경우에

404번 에러와 requestErr 가 등장하는 것이지요. 이러한 분기처리를 위한 코드를 짰답니다!