새싹 커뮤니티 앱을 개발하면서 발생한 이슈를 정리한 페이지입니다.
이슈페이지는 평어체로 쓰도록 하겠습니다.
Moya 라이브러리 Access Token 처리 가이드 라인
https://github.com/Moya/Moya/blob/master/docs/Authentication.md
참고한 Moya 깃허브 Authentication 자료링크이다. Access Token Auth 부분에 Bearer Token을 처리하는 부분도 잘 명세되어 있다. 작업하라고 나와있는 Step 부분을 가져와 보았다.
친절하게 1번 ,2번 스탭으로 나누어 구성을 하라고 나와있다! 이해하기 쉽게 깔끔하게 정리되어있었음.
위의 가이드라인을 이용하여 SesacTarget 적용 모습
1번째 스탭
class CommonViewModel {
let tokenClosure: (TargetType) -> String = { _ in
print()
return TokenUtils.read(AppConfiguration.service, account: "accessToken") ?? ""
}
let provider: MoyaProvider<SesacTarget>
init() {
let authPlugin = AccessTokenPlugin(tokenClosure: tokenClosure)
provider = MoyaProvider<SesacTarget>(plugins: [authPlugin])
}
}
2번째 스탭
import Foundation
import Moya
typealias JsonType = [String: Any]
enum SesacTarget {
// Auth
case register(parameters: JsonType)
case login(parameters: JsonType)
case changePassword(parameters: JsonType)
// Post
case allPost(parameters: JsonType)
case composePost(parameters: JsonType)
case updatePost(index: Int, parameters: JsonType)
case deletePost(index: Int)
// Comment
case allComment(parameters: JsonType)
case createComment(parameters: JsonType)
case updateComment(index: Int, parameters: JsonType)
case deleteComment(index: Int)
}
extension SesacTarget: TargetType {
var baseURL: URL {
guard let url = URL(string: NetworkManager.environment.rawValue) else {
fatalError("fatal error - invalid url")
}
return url
}
var path: String {
switch self {
case .register:
return "auth/local/register"
case .login:
return "auth/local"
case .changePassword:
return "custom/change-password"
case .allPost:
return "posts"
case .composePost:
return "posts"
case .updatePost(index: let index, parameters: _):
return "posts/\(index)"
case .deletePost(index: let index):
return "posts/\(index)"
case .allComment,
.createComment:
return "comments"
case .updateComment(index: let index, parameters: _):
return "comments/\(index)"
case .deleteComment(index: let index):
return "comments/\(index)"
}
}
var method: Moya.Method {
switch self {
case .register,
.login,
.changePassword,
.composePost,
.createComment:
return .post
case .allPost,
.allComment:
return .get
case .updatePost,
.updateComment:
return .put
case .deletePost,
.deleteComment:
return .delete
}
}
var task: Task {
switch self {
case .deletePost ,
.deleteComment:
return .requestPlain
case .allPost(parameters: let parameters),
.allComment(parameters: let parameters):
return .requestParameters(parameters: parameters, encoding: URLEncoding.default)
case .register(let parameters),
.login(let parameters),
.changePassword(let parameters),
.composePost(let parameters),
.updatePost(_, let parameters),
.createComment(let parameters),
.updateComment(_, let parameters):
return .requestParameters(parameters: parameters, encoding: JSONEncoding.default)
}
}
var headers: [String : String]? {
return ["Content-type": "application/json"]
}
var authorizationType: AuthorizationType? {
switch self {
case .register,
.login:
return .none
default:
return .bearer
}
}
이슈 해결전 Moya 깃허브 라이브러리 가이드라인을 읽은뒤 Moya로 구성한 Target과 Provider 생성 구성 모습. 이슈해결전이라고 했으니 오류가 있는 코드라고 말할 수 있다.
위의 코드를 가지고 API요청을 하면 Success 응답이 와야함에도 불구하고, 요청에 성공하지 못하였음. 위의 오류 문구는 네트워크 요청시 Token에 문제가 있어서 발생한 오류 문구였다.
Moya를 처음 써보기도 했고, 컴파일, 런타임 오류도 없었기 때문에 이 이슈에서 꽤나 많은 시간을 보내게 되었다. Moya 라이브러리 이슈페이지에서 저와 같은 이슈가 있는 사람들이 있는지 계속 찾아보았다 그리고 Moya라이브러리 안의
AccessTokenPlugin.swift 파일 또한 뜯어보았는데도 못찾겠더라... 항상 깨닫는다... 🥲 오류는 찾으려고 하면 바로 찾을 수 없다는걸.. ㅎ 아무튼 이때는 시간 압박때문에 시야가 좁았었는지 Moya의 가이드라인대로는 해결하지 못했음 . 대신 다른 방법으로 해결함
Access Token , Header 딕셔너리에 추가해도 요청 성공하네?
var headers: [String : String]? {
switch self {
case .register,
.login:
return ["Content-Type": "application/json"]
default:
let token = TokenUtils.read(AppConfiguration.service, account: "accessToken")
return ["Content-Type": "application/json",
"Authorization": "Bearer \(token!)"]
}
}
가이드 라인대로는 아니지만 , 당시에 해결한 방법. Target코드에서 Header부분을 수정하였다. Moya도 결국 Alamofire를 이용하잖아? 생각이 문득 들어 Alamofire Header 구성방법대로 헤더 딕셔너리안에 Token정보를 넣었더니 요청이 잘 갔음.
그건그렇고 가이드라인 하라는 대로 했잖아... 무슨 에러야?
결과적으로 다른 방법으로 해결하였지만, 프로젝트 마감 기간 이후 무슨 에러인지 찾아보게 되었다. 혹시나 읽었던 가이드라인이 오래된 것인지, 지금은 Header 딕셔너리 안에 추가하는 방법으로 변경된것인지 찾아보았는데 그건 아니였음. 결론적으로 너무 허무하게도 Protocol
AccessTokenAuthorizable
이 아이를 Target에 추가하지 않아서 생겼던 오류였..ㅎ.. 얘를 추가하지 않더라도 컴파일, 런타임 오류는 없었음. 그래서 찾는데 오래걸렸다. 아무튼, 기존 작동하지 않는 코드에 이 프로토콜을 추가하니 Provider에 plugin으로 초기화 하였을 때, 네트워크 응답이 성공적으로 요청되는것을 확인하였다.
생각보다 허무한 오류로 2시간이상은 하도 많다보니 이젠 강철 멘탈이 되어 버렸다...허헙..
'🍒 iOS 개발 > 이슈' 카테고리의 다른 글
[SLP] 테이블뷰 Self-Sizing셀 안에 컬렉션뷰 Left-Align Self-Sizing와 Drop-Down 이슈 (0) | 2022.02.14 |
---|---|
[SLP] Rxswift 강한 참조 순환 해결 이슈 (2) | 2022.02.04 |
[SLP] 커스텀 뷰 UI 이슈 (0) | 2022.01.31 |