본문 바로가기
Swift랑 친해지기/라이브러리

[URLSession, Alamofire] Naver Papago API 로 번역하기 (iOS)

by 데브킹덕 2023. 7. 25.

 1. Naver Developers 에서 API를 사용하기 위해 애플리케이션 등록

 

NAVER Developers

네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음

developers.naver.com

 

2. Client ID 와 Client Secret를 발급 받는다.

 

3. POST 방식으로 JSON파일을 받아 올 수 있다.

 

👨‍💻 POST 기본 지식

 

- HTTP 방식에는 크게 요청메시지, 응답메시지로 구분된다.

- 이 메시지는 크게 라인,헤더,바디로 구성이 된다.

 

- 라인 (전송메서드/요청 내용경로/요청 형식 버전정보)

//예제
POST /userAccount/login HTTP/1.1

 

- 헤더 (Key-Value로 구성)

Host = 도메인,포트번호

Content-Type = 메시지 타입

Content-Type: "application/x-www-form-urlencoded; charset=UTF-8"

 

- 바디 (실제 내용)

헤더에 Content-Type과 일치해야함

"source=en&target=ko&text=\(str)"

 

결론

1. URL - "https://openapi.naver.com/v1/papago/n2mt" 에 요청을 보낸다.

2. 헤더에 Content-Type과 Client ID, Secret을 담아서

3. 바디에는 "source=en&target=ko&text=\(str)" 라는 UTF-8 타입을 담아서 보낼거다.

 

 

4. JSON 형식에 알맞게 Codable 프로토콜을 채택한 구조체를 만듬

 

Post man을 이용해서 JSON이 어떤 구조로 되어 있는지 확인 할 수 있었음

message안에 result와 @type,@service,@version이 있고,

result안에 srcLangType, tarLangType, translatedText, engineType이 있는 구조임

 

 

5.구조체를 형식에 맞게 자료형을 지정하였고 CodingKey를 이용해서 변수 첫글자에 특수기호를 쓸 수 없는 것을 해결해줄 수 있었다.

struct PaPago: Codable{
    var message: PaPagoMessage
}

struct PaPagoResult: Codable{
    var engineType: String
    var srcLangType: String
    var tarLangType: String
    var translatedText: String
}

struct PaPagoMessage: Codable{
    
    var service: String
    var type: String
    var version: String
    var result: PaPagoResult
    
    enum CodingKeys: String, CodingKey{
        case service = "@service"
        case type = "@type"
        case version = "@version"
        case result
    }
}

 

 

URLSession 전체 코드

func translate(str: String){
        let url = "https://openapi.naver.com/v1/papago/n2mt"
        
        //str타입을 URL로 바꿈
        guard let url = URL(string: url) else {
            print("Error: cannot create URL")
            return
        }
        var request = URLRequest(url: url)
        
        //1.POST방식을 이용한다.
        request.httpMethod = "POST"
        
        //2.HTTPHeaderFiel는 Key - Value 값임 (ContentType,id,Secret 추가)
        request.addValue("application/x-www-form-urlencoded; charset=UTF-8", forHTTPHeaderField: "Content-Type")
        request.addValue("여긴 클라이언트 아이디", forHTTPHeaderField: "X-Naver-Client-Id")
        request.addValue("여긴 클라이언트 시크릿", forHTTPHeaderField: "X-Naver-Client-Secret")
        
        
        //3.헤더에 ContentType과 타입이 일치해야함
        let param = "source=en&target=ko&text=\(str)"
        request.httpBody = param.data(using: .utf8)
        
        //4.URLSession을 이용해 통신을 요청함
        URLSession.shared.dataTask(with: request){ data, response, error in
            guard error == nil else{
                print("Error: error calling GET")
                return
            }
            guard let data = data else{
                print("Error: Did not recieve data")
                return
            }
            
            guard let response = response as? HTTPURLResponse, (200 ..< 300) ~= response.statusCode else {
                if let res = response as? HTTPURLResponse, (400 ..< 500) ~= res.statusCode{
                    print(res.statusCode.description)
                }
                
                print("Error: HTTP request failed")
                return
            }
            
            //PaPago라는 구조체를 만들어서 알맞게 디코딩 하였음
            guard let output = try? JSONDecoder().decode(PaPago.self,from: data) else{
                print("PaPago JSON Parsing failed")
                return
            }
            
            //Label을 바꾸는 UI작업으로 main큐에서 작업
            DispatchQueue.main.async {
                self.jokeLabel.text = output.message.result.translatedText
            }
            
        }.resume()
        
        
    }

Alamofire - 전체코드

func translationFromEnglishToKorean(str: String){
        let url = "https://openapi.naver.com/v1/papago/n2mt"
        guard let url = URL(string: url) else {
            print("Error: cannot create URL")
            return
        }
        
        let param: Parameters = ["source" : "en",
                                 "target" : "ko",
                                 "text" : str]
        
        /*
        method - 통신 방식
        parameters - body에 들어갈 내용
        encoding - 서버에서 잘못 받아 드릴 수 있어 URLEncoding
        headers - 헤더에 들어갈 내용
        validate - 서버응답 유효성
        responseDecodable - 원하는 형태로 디코딩
        */
        AF.request(url, method: .post,
                   parameters: param,
                   encoding: URLEncoding.default,
                   headers: ["Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
                             "X-Naver-Client-Id" : Storage().naverClientID, "X-Naver-Client-Secret" : Storage().naverClientSecret])
        .validate(statusCode: 200..<300)
        .responseDecodable(of: PaPago.self){ response in
            switch response.result{
            case.success(let data):
                DispatchQueue.main.async {
                 //원하는 UI 작업
                }
            case.failure(_):
                print("Papago API POST failed")
            }
            
        }
        
        
    }

 

URLEncoding

- encoding하는 이유 -> 한글이나 특수문자의 경우 서버에서 잘못 알아 들을 수 있다.

- encoding 파라미터에는 ParameterEncoding을 준수하는 열거형,구조체,클래스가 들어갈 수 있다.

- methodDependent : 메소드 타입에 따라 인코딩 타입 결정

- queryString: GET 방식에 쿼리스트링으로 인코딩됨

- httpBody:  content-Type이 'application/x-www-from-urlencoded:utf-8'으로 설정된다.