Moya 간단 사용법 –


Moya 간단 사용법 - 1


Moya 간단 사용법 - 2

저는 최근 2월에 완료한 협회 동아리인 UMC에서 3학년 때 협동 프로젝트를 완료했습니다. 와 친구iOS 파트를 담당했습니다.


Moya 간단 사용법 - 3
2월 16일 UMC 3차 데모데이 웹사이트

내 프로젝트에서 네트워크 통신을 위해 Moya를 사용하여 네트워크 통신 정보를 추상화하고 있습니다.

UMC의 3학기 동안 강의가 Alamofire에 대한 내용이 대부분이었기 때문에 어떻게 사용하는지에 대해 정리해 보겠습니다.


모야로 다루기 쉬울 것 같아서 작업했는데 처음 해보시면 많이 헷갈릴 것 같아요. 한번 보시면 정리가 쉬울 것 같아요.

1. Codable 구조 선언

서버 측에서 받은 API 사양에 JSON 예제가 있습니다. 게시물을 등록하는 API를 예로 들어보겠습니다.

{
     "postTitle":"1번째 게시글",
     "categoryName": "운동",
     "postMember": 0,
     "tag1": "umc",
     "tag2": "wowmate",
     "tag3": null,
     "tag4": null,
     "tag5": null,
     "postContext": "첫번째 게시글 등록 완료"
}

그냥 복사 퀵타입.io 그것을 가지고


Moya 간단 사용법 - 4

QuickType은 언어에 따라 JSON 형식의 모델을 자동으로 생성합니다. null 값이 있으면 nullable로 처리할 수 있습니다. Swift의 선택적 처리에는 형식 안전상의 이유로 강제 해제 대신 guard-let을 사용하여 언래핑 또는 null 병합이 필요합니다.

이 구조는 새 파일을 만들고 복사합니다. 포스트 관련 모델들을 한곳에 모아두면 좋을 것 같아서 Post.swift 파일에 넣어두겠습니다.

// Post.swift 

import Foundation

// MARK: - PostRegister
struct PostRegister: Codable {
    let postTitle, categoryName: String
    let postMember: Int
    let tag1, tag2, tag3, tag4: String
    let tag5, postContext: String
}

2. Moya의 TargetType을 사용하여 네트워크를 통해 통신할 콘텐츠를 선언합니다.

왜 이러는 거지 앞에서 배운 Alamofire로 AF.request를 하고 메서드, 헤더, 매개변수 등을 주입하면 뷰 컨트롤러 코드에 의존성이 너무 많아 코드 재사용이 어려워진다. 그리고 나중에 수정해야 할 경우 일일이 찾아서 수정해야 하는 번거로움이 있습니다. 우려 사항을 가능한 한 코드에서 의미론적 단위로 분해하는 것은 미래의 재사용성과 유지 관리에 필수적입니다.

데이터/모델 폴더에서 이전에 정리한 내용을 살펴보겠습니다.

끝점. 빠른 기본 URL을 입력합니다. 우리 notion.so/wowmatte 있다면 아이디어.소 베이스에 해당합니다. 이미 붙여넣었으니 걱정하지 않으셔도 됩니다.

```swift
// Endpoint.swift

import Foundation

enum ServiceAPI {
    static let baseURL = "<http://ec2-13-209-29-182.ap-northeast-2.compute.amazonaws.com:8080>"
}
```

Post.swift 에 아까 만든 모델을 넣어줍니다. 

```swift
/* 게시글 등록 (post - posts) */
// MARK: - PostRegister
struct PostRegister: Codable {
    let postTitle, categoryName: String
    let postMember: Int
    let tag1, tag2, tag3, tag4, tag5, postContext: String
}
```

PostAPI는 통신 유형별로 구성합니다. 저희는 사후등록으로 그에 따라 모델명을 변경하였으니 이름에 따라 열거형에 경우를 추가합니다.

콘텐츠를 받아서 삽입해야 하므로 연관된 열거형 값을 통해 매개변수를 삽입합니다. 추가 및 참조 정보는 아래 코드에 설명되어 있습니다.

//PostAPI.swift

enum PostAPI {
    case posts
    case mockPosts
		case postRegister(param: PostRegister) // <- New! 연관값으로 값을 받아줍니다.
}

TargetType으로 확장한 코드에서 나머지를 채웁니다.

extension PostAPI: TargetType {
    var baseURL: URL {
        switch self {
        case .mockPosts:
            return URL(string: "<https://63ba608856043ab3c79a44ce.mockapi.io/api/v1>")!
        default:
            return URL(string: ServiceAPI.baseURL)! // 이미 열거형에 베이스를 선언했으므로
        }
        
    }
	var path: String {
        switch self {
        case .posts, .postRegister: // path 둘다 동일합니다.
            return "/posts"
        case .mockPosts:
            return "/posts"
        }
    }
	var method: Moya.Method {
        switch self {
        case .posts:
            return .get
        case .postRegister: // 게시글등록하는 경우 .post 메서드를 사용합니다.
            return .post
        case .mockPosts:
            return .get
        }
    }
	var task: Moya.Task {
        switch self {
        case .posts:
            return .requestPlain
        case .postRegister(let param):
            return .requestJSONEncodable(param) // 받아둔 값을 JSON 형태로 보내기
        case .mockPosts:
            return .requestPlain
        }
    }
	var headers: (String : String)? {
        switch self {
        default:
            return ("Content-Type": "application/json") // 토큰이 들어갈 경우 여기에 들어감.
        }
    }

로그인, 편집 또는 게시물 작성과 같은 많은 작업에는 헤더 페이지에서 인증이 필요합니다. 이 부분은 스펙이 업데이트 되면 추가하도록 하겠습니다. 보통 컨텐츠 타입은 JSON 형식으로 데이터를 보내는 서버에서 주로 사용하는 것 같습니다. 이전에는 null 이었지만 추가합시다. 이 헤더 부분은 HTTPHeader입니까? 모양으로도 정의할 수 있습니다.

삼. 싱글톤으로 관리할 네트워크 관리자 파일에 메소드 추가하다.

이미 생성된 PostManager.swift로 진행합니다. 사양의 응답 패턴을 보면 그렇게 나와 있습니다.

"isSuccess": true, "code": 200, "message": "SUCCESS!", "data1": { "postId": 2 } }

메시지의 성공과 실패의 이유는 메시지를 보내는 것만으로도 충분해 보인다.

아래와 같이 탈출 브리치로 배치했습니다.

import Foundation
import Moya

class PostManager { 

	private init() {} 
	static let shared = PostManager() 
	let provider = MoyaProvider<PostAPI>() // 게시글 등록 

	func registerPost(post: PostRegister, completion: @escaping (Result<String, Error>) -> Void ) { 
 		provider.request(.postRegister(param: post)) { result in 
        	switch result { 
            	case .success(let data): 
                	if let json = try? JSONSerialization.jsonObject(with: data.data,options: ()) as? (String : Any) { 
                    	if let message = json("message") as? String { 
                        	completion(.success(message)) 
                            } 
                        } 
                case .failure(let error): 
                	completion(.failure(error)) 
                
           	} 
        } 
    }
}

4. 리얼뷰 컨트롤러에서 사용해보기

사용자로부터 받은 내용을 PostRegister 구조체로 저장한 후 다음과 같이 내용을 삽입합니다. 네트워크 통신의 성공 여부에 따라 필요한 조치를 추가할 수 있습니다.

let postByUser = PostRegister(postTitle: "제목", categoryName: "카테고리", postMember: 2, tag1: "태그1", tag2: "태그2", tag3: "태그3", tag4: "", tag5: "", postContext: "내용")
PostManager.shared.registerPost(post: postByUser) { result in
    switch result {
    case .success(let success):
        print(success)
    case .failure(let failure):
        print(failure)
    }
}



Moya 간단 사용법 - 5

오늘 읽어주셔서 감사합니다.

질문이 있거나 공유하고 싶은 것이 있으면 댓글로 알려주세요!

재미있게 읽으셨다면 공감과 구독은 큰 힘이 됩니다.

영원히 감사합니다

이 기사 doy.oopy.io 또한 출판될 것입니다.