AlamoFire(JiraApi 연동)

YongJunCha·2021년 9월 22일
0

swift

목록 보기
8/18
post-thumbnail

최근 Jira api 연동을 위해 이것 저것 공부하면서 샘플 코드로 안드로이드 팀 코틀린 코드를 받았는데, retrofit이라는 것을 쓰고있었다.

*retrofit 은 안드로이드에서 애플리케이션에서 통신에 쓰는 기능들을 쉽고 빠르게 쓰기위해 만든 라이브러리이다.

swift 에서도 비슷한 기능을 하는 라이브러리를 찾아야할 것 같았다.

What is AlamoFire?

  • iOS, MacOS 를 위한 Swift 기반의 Http 네트워크 라이브러리이다.
  • Retrofit 처럼 통신에 쓰는 기능을 쓰기쉽게 모아놓은 라이브러리 라고 생각하면 될듯 하다.

Post

func addJiraIssue(summary: String, description: String) -> Future<Bool, Error> {
        Future<Bool, Error> { promise in
            self.addIssueAsync(summary: summary, description: description, promise: promise)
        }
    }
    
// Jira Issue 등록하기
    func addIssueAsync(summary: String, description: String, promise: @escaping(Result<Bool,Error>) -> Void) {
        let url = JiraApiConstant.BASE_URL + JiraApiConstant.POST
        
        // 복사타입 생성
        var parameter = JiraAddIssueRequest()
        // Jira Issue Title
        parameter.fields.summary = summary
        // Jira Isuue Description
        parameter.fields.description = description
        // 나머지 프로젝트 타입과 설명은 JiraAddIssueRequest에서 초기값으로 설정 돼있음.
        
        // Json Encoding
        guard let serializedParameter = jsonEncoding(parameter: parameter) else { return }
        // Log
        print("\(serializedParameter)")
    
        // AlamoFire Post
        AF.request(url, method: .post, parameters: serializedParameter as? Parameters, encoding: JSONEncoding.default, headers: JiraApiConstant.HEADER)
        .validate(statusCode: 200..<300).responseString() { response in
            switch response.result {
                case .success(_):
                    do {
                        let decoder = JSONDecoder()
                        
                        // PostResponse : IssueKey, 글 ID, Url을 받는다.
                        let jiraPostResponse = try decoder.decode(JiraPostResponse.self, from: response.data!)
                        appendIssueKeyToUserDefault(issueKey: jiraPostResponse.key)
                        print("Jira Post Response Success\(jiraPostResponse)")
                        promise(.success(true))
                    } catch {
                        print("Jira Post Response Error : \(error)")
                    }
                    
                case .failure(let err):
                    print("Jira Post Fail \(response) / Error : \(err)")
                    promise(.failure(err))
                }
            }
    }
  • Combine의 한 종류인 Future를 썼다.
  • Future는 CallBack 기반이다.
  • AlamoFire로 포스트 Request를 보낸 후 그에 대한 Response를 받는다.
  • 자료를 요청할 때는 JsonEncoding이 자료를 받을 때는 JsonDecoding 과정이 필요하다.
// Issue 불러오기 Future
    func getJiraIssue(issueKey: String) -> Future<JiraIssueVo, Error> {
        Future<JiraIssueVo, Error> { promise in
            self.getIssueAsync(issueKey: issueKey, promise: promise)
        }
    }
    
    // Jira Issue 불러오기 (issueKey를 통해)
    private func getIssueAsync(issueKey : String, promise: @escaping(Result<JiraIssueVo, Error>) -> Void) {
        
        let url = JiraApiConstant.BASE_URL + JiraApiConstant.GET + issueKey
        var jiraGetResponse = JiraGetResponse()
        var issueVo = JiraIssueVo()
        
        // AlamoFire Get * Get은 따로 parameter 설정 안 함.
        AF.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: JiraApiConstant.HEADER)
            .validate(statusCode: 200..<300).responseString(){ response in
                switch response.result {
                case .success(_):
                    print("Jira Get Success : \(response)")
                    do {
                        let decoder = JSONDecoder()
                        
                        // JiraAddIssueRequest로 따로 Decoder 설정 안 하고 그대로 받아도 된다.
                        jiraGetResponse = try decoder.decode(JiraGetResponse.self, from: response.data!)
                        
                        // 사용의 편의를 위해 Vo 객체를 사용
                        issueVo.issueKey = issueKey
                        issueVo.projectKey = jiraGetResponse.fields.project.key
                        issueVo.summary = jiraGetResponse.fields.summary
                        issueVo.description = jiraGetResponse.fields.description
                        issueVo.issueTypeid = jiraGetResponse.fields.issuetype.id
                        issueVo.created = jiraGetResponse.fields.created
                        
                        // Comments Buffer 생성
                        var Buffer = CommentInfo()
                        
                        jiraGetResponse.fields.comment.comments.compactMap{
                            $0
                        }.forEach{ response in
                            // Buffer 코멘트 내용과 작성된 시간을 넣어준다.
                            Buffer.body = response.body
                            Buffer.created = response.created
                            // Vo 객체의 Comments 부분에 append 시켜준다.
                            issueVo.comments.append(Buffer)
                            issueVo.isCommented = true
                        }
                       
                        
                        // 성공시 issueVo 를 receiveValue return
                        promise(.success(issueVo))
                        print("Issue Vo Comments : \(issueVo.comments)")
                        print("Jira Get Response Success : \(jiraGetResponse)")
                    } catch {
                        print("Jira Get Response Error : \(error)")
                    }
                case .failure(let err):
                    print("Jira Get Fail : \(response) / Error : \(err)")
                    promise(.failure(err))
                }
            }
    }
  • Get을 할 때는 AlamoFire에 Parameter가 필요하지 않다.

느낀점

  • AlamoFire를 통해 Api 통신을 해봤는데, 다른 서비스들과 통신할 수 있다면 앱의 확장 가능성이 크게 늘어난다는 생각을 했다.
  • 처음할 때는 AlamoFire의 문법이나 기능들을 쓰는 게 어려운 것이 아니라 JsonEcoding, JsonDecoding 과정이 복잡했고
  • 공식 문서를 보고 response 형식을 확인한 후 형식에 맞춰 object를 만들고 이해하는 것이 굉장히 까다로웠다.
  • 기능구현을 마치고 나니 Api 연동에 대한 막연한 두려움이 사라졌고, 오래 걸렸지만 믿고 맡겨주고 기다려준 동료들에게 감사했다.

연동테스트 사이트 포스트 맨
alamofire 참고사이트

0개의 댓글