Moya Library Github - https://github.com/Moya/Moya
오늘은 Moya에 대해 공부를 해보았는데요!
<이해한 걸 바탕으로 써보았기 때문에 주저리주저리가 들어있어여..>
우선, iOS에서는 URLSession을 통해서 기본적으로 네트워킹을 진행합니다.
여기서 한 단계 추상화시킨 방식이 우리가 많이 사용하고 있는 Alamofire 라이브러리입니다.
URLSession을 기반으로 하고 있죠!
🤔 그렇다면 도대체 Moya가 몰까요?
Moya는 이런 Alamofire에서 한 번 더 추상화하였으며,
일반적으로 열거형(enum)을 사용하여 네트워크 요청을 타입 안전(type-safe)한 방식으로 캡슐화하는데 초점을 맞춘
네트워킹 라이브러리입니다.
❓타입 안전한 방식(type-safe)이 몬데?
찾아보니 스위프트는 Type Safety Language 라네요.
쉽게 말하면 String 타입의 변수에는 String 타입만 저장 가능하다는..
다른 타입은 할당할 수 없다는 것이며 그 말은 즉, 코드를 작성 시에 변수가 어떤 타입인지 명확하게 한다는 것입니다.
그래서 엑코는 재빠르게 우리가 코드를 작성하면 type check를 진행하고 오류를 확인해줍니다.
이를 통해서 개발자는 빠르게 오류를 수정해 방지합니다.
❓여기서 추상화가 뭘까요?
-> 객체 지향 프로그래밍의 특징(추상화, 캡슐화, 은닉화, 상속성, 다형성) 중 하나로
객체들의 공통적인 부분을 뽑아내서 따로 구현해놓은 것을 말합니다.
공통적인 부분들만 추려놓았기 때문에 구체적인 정보를 담아두지 못했고, 추상적인 정보가 모였기 때문에 '추상화'라고 부릅니다.
(중복되는 코드를 추상화했기 때문에 재사용이 편리합니다.)
-> 이때, 보통 캡슐화와 은닉화라는 특징도 추상화와 같이 붙습니다.
캡슐화는 객체의 속성과 행위를 하나로 묶는 것을,
은닉화는 실제 구현 내용 일부를 외부에 감추는 것을 의미합니다.
Moya 깃허브에 있는 그림을 가져온 건데 원래는 왼쪽의 그림처럼 Network Layer를 통해서 API를 관리하고,
자유로운 방식을 통해서 네트워킹을 구현한다면
Moya는 오른쪽 그림처럼 깔끔한 레이어를 가지며 자체적으로 네트워킹을 수행하지 않고 Alamofire를 통해서 수행합니다.
(그리고 Network Layer를 템플릿화 시켜서 재사용할 수 있게 만들어준다는 점이 장점인 것 같아요!)
그렇기 때문에 Moya는 기존 네트워킹 수행 방식이 가지고 있던 다양한 문제들을 해결해줍니다.
❓endpoint 는 또 뭐임..?
-> API란 두 시스템, 어플리케이션이 상호작용(소통)할 수 있게 하는 프로토콜의 총 집합이라면
ENDPOINT란 API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL.
메소드(GET 등)는 같은 URL들에 대해서도 다른 요청을 하게끔 구별하게 해주는 항목이 바로 'Endpoint'입니다.
🔗 - https://velog.io/@kho5420/Web-API-그리고-EndPoint
🔗 - https://velog.io/@djaxornwkd12/API와-ENDPOINT란-무엇인가
그러면 Moya를 통해 직접 통신을 해봅시다.
1. 우선 LookService와 관련된 네트워킹을 담당할 열거체를 하나 만들어주었습니다.
import Moya enum LookService { case other case otherDetail(String, Int) }
2. TargetType 프로토콜을 따르는 extension을 통해 열거체에 필요한 속성을 구현해줍니다.
TargetType은 MoyaProvider에 필요한 규격을 정의하는데 사용되는 프로토콜입니다.
그러니까 TargetType을 채택 후 제공하는 속성들을 통해서 구현을 해야만 통신이 가능한 것 같습니다.
- MoyaProvider는 Request가 이뤄지는 유일한 클래스라고 나와있는데 사실 아직 이해가 안가고..;
🌈 TargetType에서 제공하는 속성들입니다.
1️⃣ baseURL : 서버의 base URL / Moya는 이를 통하여 endpoint객체 생성
2️⃣ path : 서버의 base URL 뒤에 추가 될 Path (일반적으로 API)
3️⃣ method : HTTP Method (ex. .get / .post / .delete 등등)
4️⃣ sampleData : 테스트용 Mock Data (테스트를 위한 목업 데이터를 제공할 때 사용)
5️⃣ task : 리퀘스트에 사용되는 파라미터 설정
- plain request : 추가 데이터가 없는 request
- data request : 데이터가 포함된 requests body
- parameter request : 인코딩된 매개 변수가 있는 requests body
- JSONEncodable request : 인코딩 가능한 유형의 requests body
- upload request
6️⃣ validationType : 허용할 response의 타입
7️⃣ headers : HTTP headers
extension LookService: TargetType {
public var baseURL: URL {
// GeneralAPI 라는 구조체 파일에 서버 도메인이나 토큰 값을 적어두고 불러왔습니다.
return URL(string: GeneralAPI.baseURL)!
}
var path: String {
switch self {
case .other:
return "/other"
case .otherDetail(let userID, let index):
return "/other/detail/\(userID)/\(index)"
}
}
var method: Moya.Method {
switch self {
case .other,
.otherDetail:
return .get
}
}
var sampleData: Data {
return "@@".data(using: .utf8)!
}
var task: Task {
switch self {
case .other:
return .requestPlain
case .otherDetail(let userID, let index):
return .requestPlain
}
}
var headers: [String: String]? {
let accessToken = UserDefaultStorage.accessToken
switch self {
default:
return ["Content-Type": "application/json",
"token": accessToken] // GeneralAPI.token
}
}
}
위와 같이 해주면 속성들을 부여해주면 VC에서 LookService를 사용해주면 됩니다.
3. 실제로 ViewController 에서 사용하기
3-1 )
Moya Target과 상호작용할 때 사용하는 클래스는 MoyaProvider입니다.
그래서 우리는 제네릭 타입으로 TargetType을 가진 MoyaProvider 인스턴스를 생성해줍니다.
제네릭 타입으로 생성하는 이유는 어떠한 타입으로도 구현해줄 수 있기 때문입니다.
class CharacterVC: UIViewController {
// MARK: - Network
private let authLookProvider = MoyaProvider<LookService>
3-2)
request를 할 때 위에서 말했다시피 Moya Provider를 통해서 할 수 있다고 했죠?
우리가 VC 초반에 생성한 인스턴스에 접근해 request를 요청해주면 됩니다!
LookService에서 열거체로 나열해줬던 것 중 하나인 otherDetail을 통해 데이터를 요청하면 됩니다!
Completion Handler를 통해서 내부에서 response로 넘어온 데이터를 필요에 따라 가공해주면 끝입니다.
extension CharacterVC {
// MARK: - Network : fetchLookDetail
func fetchLookDetail() {
authLookProvider.request(.otherDetail(userId, index)) { response in
switch response {
case .success(let result):
do {
print(result)
// 여기에 통신 성공 시에 원하는 결과를 작성해주세요.
} catch(let err) {
print(err.localizedDescription)
}
case .failure(let err):
print(err.localizedDescription)
}
}
}
}
👀 Moya 공부 후기...
-> 100% 이해한 건 아니지만...
Alamofire를 살짝 깔짝댄 수준에서 프로젝트를 하면서 처음으로 Moya를 쓰게 됐는데
왜? 쓰는지조차 모르고 리드 개발자 언니 따라서 썼는데 이번 기회에 공부하면서
Moya가 Alamofire보다 좋은 점은 간단하게 말하자면 파일을 여러 개 안 만들어도 된다는 점이다.
비슷한 Service를 사용할 경우에는 하나의 템플릿 내에서 case를 추가/변경해주면 되기 때문에 엄청 편리하다.
다음에는 Moya로 multipart 통신하는 방법에 대해 공부해서 가져올게염... 꼭!!
'⭐️ 개발 > iOS & Swift' 카테고리의 다른 글
[iOS] 데이터 직접 전달 방식(4) - NotificationCenter을 통해 전달 (0) | 2021.07.29 |
---|---|
[iOS] NotificationCenter? (0) | 2021.07.29 |
[iOS] TextView - 플레이스홀더, 패딩, 글자 수 제한, 커서, 키보드 dismiss (0) | 2021.07.22 |
[iOS] Alamofire Multipart/formdata를 통한 이미지 서버 통신 (3) | 2021.07.19 |
[iOS] DateFormatter (2) | 2021.06.24 |