BOID
[iOS] REST API 호출 방법 & 구현 해보자- HoonIOS 본문
안녕하세요, HoonIOS입니다. :)
이번에는 API통신을 REST 방식으로 호출하고 GET으로 불러와 테이블 뷰 컨트롤러의 테이블 뷰 셀들에게 뿌려주도록 하겠습니다.
※ 참고
이번 포스팅에서 나오는 API는 꼼꼼한 재은씨 기본 편에서 나오는 API를 통하여 예를들어 포스팅하겠습니다.
API를 받아서 영화 앱 구현하기
API를 이용하여 앱을 개발하는 순서
- 사용할 오픈 API를 검색하여 찾습니다.
- 오픈 API 사용신청을 하고 인증키를 발급 받습니다.
- API의 데이터 분석을 합니다.
- API를 호출해서 데이터를 받아오도록 코드를 구현해 줍니다.
- 전달 받은 데이터를 파싱해서 사용합니다.
이번에 사용할 API는 https://swiftapi.rubypaper.co.kr:2029/hoppin/movies?version=오픈API버전&count=불러올 개수&page=불러올페이지&version=오픈API버전 입니다.
이 API는 REST프로토콜 형식으로 되어 있고 GET메서드를 이용하여 호출이 됩니다.
이 URL api에서 각 파라미터에 대해 알아보겠습니다.
- URL API의 파라미터
파라미터 | 타입 | 설명 |
version | 정수형 | API버전 정보 |
page | 정수형 | 조회할 목록의 페이지 지정 - page값이: 0,1일 경우 모두 1로 지정 |
count | 정수형 | 페이지에 표시될 데이터 개수 |
genreld | 정수형 | 영화 장르의 id |
order | 문자열 | 정렬방식을 지정 - releasedateasc: 개봉일 오래된순 - releasedatedesc : 개봉일 최근순 |
이 API 버전은 2 버전이고 2번째 페이지, 한 페이지당 5개의 데이터를 모든 장르를 최신순으로 보여주세요라고 하면
http://swiftapi.rubypaper.co.kr:2029/hoppin/moviesversion=2&page=2&count=5&genreld=&order=releasedatedesc
이런 식으로 URL API의 파라미터들을 설정을 해주면 됩니다.
이 API를 인터넷 검색창에 치면 아래와 같은 결과가 나옵니다.
* 응답데이터
- 이렇게 요청해서 받아온 응답 데이터를 한번 살펴보겠습니다.
형태를 보면 JSON형태로 되어있는 것을 보실 수 있는데 뭐라고요 잘 안 보인다고요? 키가 hoppin, totalcount, movie로 되어있어 이 형태를 한번 보시면 되실것 같습니다.
그런데 이렇게 봐도 이해하기 힘들고 저 같은 초보 개발자 같은 경우는 보기 더 힘드네요 ㅠㅠ 한번 보기 쉽게 정렬을 해보겠습니다.
- 위에 결과물을 보면 확실히 JSON객체랑 JSON배열이 잘 보이네요
hoppin은 데이터의 최상위 노드이고 이 데이터의 개수는 4266이라고 알려주는 게 보이실 겁니다.
movie키 안에 JSON객체로 하나의 영화 정보 목록을 보여주고 movie는 데이터 배열로 영화 정보가 안에 배열로 표시가 됩니다.
이제 API 정보에 대해 알아봤으니 이제 프로젝트에 구현을 한번 해보겠습니다.
API 구현
이 API는 GET방식으로 호출해서 데이터를 읽어온다고 말씀을 드렸는데요
get방식으로 REST API데이터를 읽어오는 방법에 대해 알아보겠습니다.
- var data = DATA(contents: URL)
- 이 초기화 방식은 GET방식으로 RESTful을 호출하고 응답을 받아올 수 있도록 지원을 합니다.
- DATA는 파운데이션 프레임워크에서 제공하는 클래스로 다양한 종류의 데이터를 변환하는 과정 없이 그대로 사용하기 위해 사용됩니다.
텍스트, 이미지, 동영상 같은 바이너리 데이터도 담을 수 있어서 응답을 받아올 때 많이 지원합니다. - 이렇게 DATA를 사용하면 복잡하지 않게 GET방식을 통하여 응답을 받아올 수 있습니다.
- 이 방식은 만약 URL에 에러가 있으면 nl값이 담아져서 오기 때문에 이 인스턴스는 옵셔널 타입으로 생성이 됩니다.
※DATA 클래스
- 위에서 말씀드린것처럼 파운데이션 프레임워크에서 제공하는 클래스로 이 객체는 텍스트, 이미지, 동영상를 바이너리 데이터로 담을수 있어서 여러 타입의 종류를 처리하는데 매우 효율적입니다.
- NSDATA클래스 기능을 그대로 가지고 있어서 어느 객체로 쓸지 서로 필요한 객체로 타입캐스팅을 통해 바꿔서 사용을 할수 있습니다.
이제 REST API를 통해 받아온 요청 데이터를 읽어와 보겠습니다.
* 코드 설명
- API 2 버전의 2번째 페이지 5개의 데이터를 읽어와 최신순으로 정렬을 하기 위한 url을 설정해 줬습니다.
- 위에서 말씀드린 것처럼 GET호출은 DATA(contentsOf:)가 담당을 하지만 호출을 할 때 필요한 URL객체 타입을 넣어줘야 합니다.
- 이 사진의 URL클래스는 파운데이션 프레임워크에 정의된 객체로, NSURL클래스를 바탕으로 스위프트에 적합하도록 구현된 객체입니다.
위의 url값인 문자열 형태로 주소를 인자 값으로 받아서 파운데이션 프레임워크에서 사용하는 주소 객체를 생성합니다.
이제 url도 받아왔겠다 요청을 한번 해보겠습니다.
* 코드 설명
- REST API을 GET프로토콜로 요청을 하는 부분입니다.
- try! 는 오류처리를 위한 문법으로 반환 타입이 언래핑을 통해 옵셔널 형태가 벗겨져서 나오는데 만약 이 값이 nil을 반환하면 크러시가 생겨 앱을 강제 종료하게 됩니다.
- URL객체를 이용해서 만들어준 REST API를 호출해서 응답받은 데이터를 Data객체로 저장을 합니다.
* 코드 설명
- 데이터를 전송받은 결과를 로그로 만들어서 출력하는 부분으로 API통신을 하는데 필요한 부분은 아니지만 데이터를 잘 전달받았는지 확인을 하기 위해 만든 구문입니다.
- NSString 타입으로 data타입으로 받은 데이터를 문자열로 변환하는 과정입니다.
NSString(data: <Data 객체>, encoding: <인코딩 형식>) - 이렇게 문자열로 변환을 하면 Data객체는 개발자가 데이터를 눈으로 볼 수 있는 형태인 문자열로 변환이 됩니다.
- 이미지 동영상 같은 미디어 타입들을 문자열로 변환할 때 nil이 반환이 됩니다. 따라서 nil이 나오면 빈 문자열로 반환을 시킵니다.
※ 참조
- 왜 String이 아니라 NSString으로 문자열 변환을 할까요?
그 이유는 NSString은 Data객체를 문자열로 변환해주는 메서드가 구현되어 있지만 String은 구현되어 있지 않아서 직접 구현을 해줘야 하기 때문입니다.
정말 당연하면서도 간단한 이유네요...ㅎ
- NSString 하고 String의 가장 큰 차이는 무엇일까요?
정답은, NSString은 프레임워크에 정의된 클래스 형태이고 String은 언어에서 자체 정의된 구조체라는 것입니다.
그럼 이제 받은 데이터를 문자열로 변환한 결괏값을 한번 봐볼까요?
값을 보시면 아까 API를 호출해서 받았던 JSON 데이터를 보실 수 있으실 겁니다.
※ 참조
혹시 만약 따라 하시다가 출력이 안되네? 그러면 ATS라고 하는 보안 규칙을 설정 안 해주셔서 그런 것입니다.
SSL 보안 프로토콜이 적용되지 않은 네트워크에 적용을 하려면 info.plist에 해당 보안규칙을 추가해줘야 합니다.
즉 ATS를 설정을 해줘야 한다는 것입니다.
이 설정은 모든 url에서 설정해주는 것은 아닌고 호출했던 URL을 보면 http://을 사용하고 있으면 SSL 보안 프로토콜이 적용이 되지 않은네트워크이므로 설정을 해줘야한고 https://은 SSL보안 프로토콜이 적용되어 있어 설정을 해줄 필요가 없습니다.
여기서 http, https 통신 어느 것으로 할 것인가는 클라이언트에서 설정을 하는 것이 아니라 서버에서 설정을 해줘야 하는 부분입니다. ㅠㅠㅠ
그럼 한번 info.plist에 ATS를 설정하겠습니다.
이렇게 Boolean값에 YES를 넣어주면 ATS설정이 완료된 것입니다.
URL로 전달받은 데이터도 봤으니 이제 파싱 해서 화면에 출력을 해야겠습니다.
화면에 값을 보여주기 위해서 코드를 구현하기 제일 좋은 위치는 viewDidLoad()입니다.
메모리에 뷰가 올라가자마자 실행되는 메서드이죠 만약에 viewWillAppear()에 구현을 하면 화면이 떴는데도 화면에 값이 보여주는 불상사가 있기 때문에 viewDidLoad에 구현해주는 것이 좋습니다.
만약 뷰 생명주기에 대해 헷갈리시면 이곳에 가서 한번 읽고 오시는 것을 추천드립니다.
그럼 이제 값을 가져와서 나눠 보겠습니다. 만약 키-값으로 딕셔너리 데이터 구조(JSON 객체)가 되어있으면 JSONObject포맷과 호환되는 NSDictionary객체로 변환을 해야 하고
데이터가 배열, 리스트 형태(JSON 배열)로 전달을 받으면 JSONarray포맷과 호환되는 NSArray 객체로 변환해야 합니다.
* 코드 설명
- 데이터를 파싱 할 때는 파운데이션 프레임워크에서 제공을 하는 JSONSerialization객체의 jsonObject를 사용합니다.
이 jsonObject는 2개의 매개변수를 사용하는데요, 첫 번째는 파싱 할 데이터, 두 번째는 파싱 옵션입니다. - 만약 파싱 부분에서 에러가 발생하면 에러를 catch 하기 위해서 do - try - catch구문으로 감싸주었습니다.
- 파싱을 왜 해 굳이?..라고 생각을 하신 분들을 위해서 파싱 하면 얼마나 이쁜 정렬된 값이 나오는지 확인해보겠습니다.
어떤가요? 눈에 보이게 딱 한 열에 한 개의 데이터만 보이게 설정되어 있는 것이 보이고 클론(:)에서 =으로 데이터를 구분한 것을 볼 수 있습니다.
단 파싱을 하면 이 리턴 값은 옵셔널 타입과 Any타입으로 리턴이 되기 때문에 입력된 데이터에 따라서 NSDictionary, NSArray형태로 캐스팅을 해줘야 합니다.
그럼 이 파싱 한 값을 토대로 키 값과 함께 캐스팅을 해주겠습니다.
* 코드 설명
- 데이터 구조에 따라서 차례대로 해당하는 타입으로 캐스팅을 해줬습니다.
- hoppin으로 시작하는 노트는 딕셔너리 타입이며로 NSDictionary타입으로, movies로 시작하는 하위 노드도 딕셔너리 타입이므로 NSDictionary로 movie는 JSON배열 타입이므 선언이 되었기 때문에 NSArray타입으로 캐스팅을 해줬습니다.
이렇게 큰 맨 위 노드에서 하위 노드로 순서대로 접근을 해서 값을 읽어와줘야 합니다. - 하나씩 키값을 읽어오면 어떤 값들을 반환하게 되는지 한번 확인해보겠습니다.
- hoppin키 값으로 딕셔너리 값을 가져오면 다음과 같은 값들을 가져오게 됩니다.
hoppins키가 빠진 값들이 읽어온 것을 확인할 수 있습니다. - movies키 값으로 딕셔너리 값을 가져오면 다음과 같은 값을 가져오게 됩니다.
movies키가 빠진 값들이 들어오는 것을 확인할 수 있습니다. - 이제 movie키를 기준으로 객체 배열 값을 가져오면 어떤 값들이 가져오는지 확인해 보겠습니다.
최종적으로 맨 아래에 있는 노드의 값인 배열 값을 가져오게 되었습니다.
- hoppin키 값으로 딕셔너리 값을 가져오면 다음과 같은 값들을 가져오게 됩니다.
이제 이 값들을 데이터 소스의 배열 값에 넣어주겠습니다.
* 코드 설명
- movie 배열값 즉 NSArray로 캐스팅했던 JSON 값들을 MovieVO인 모델 클래스 값에 넣어서 해당하는 변수 값에 값을 넣어주고 list 배열에 그 객체 값들을 하나씩 넣어줬습니다.
- json배열로 받은 데이터는 딕셔너리 객체로 되어있을 테니 row값을 NSDictionary으로 넣어줬습니다.
그 이유는 위에서 movie는 JSON배열로 되어 있어 NSArray타입으로 캐스팅을 해줬지만 하나의 JSON배열 안에 값들은 JSON객체로 되어있어 딕셔너리 형태로 되어있어 하나의 배열 값들을 NSDictionary로 캐스팅해줘야 합니다.
이해가 안 되실 수 있어서 그림을 하나 가져왔습니다.
여기서 movies는 JSON객체로 되어 있고 movie끼리는 JSON배열 값으로 되어 있지만 하나의 movie데이터 안에는 dictionary로 되어 있어서 이 값을 넣어줄 때는 array값으로 되어 있는 Movie를 NSDictionary로 캐스팅을 해야 되는 것입니다. - 여기서 rating은 double값이기 때문에 String값을 double으로 바꿔줘야 합니다.
그래서 double로 바꿔주는 속성이 있는 NSString으로 캐스팅을 하고. doubleValue속성을 통해서 string값을 double값으로 바꿔주었습니다.
이제 이 list의 배열 값을 통해서 cellforrowat 테이블 뷰 데이터 소스 메서드에 가서 해당하는 행에 가서 값을 넣어주면 끝나는 것입니다.!
여기서는 restAPI구현만 하는 것이니 여기 까지만 하겠습니다. :)
REST API네트워크는 현재도 많이 쓰는 통신이니 만큼 한번 포스팅을 해봤습니다. :) 긴 글 읽어주셔서 감사합니다.
'IOS 시작기' 카테고리의 다른 글
[iOS] 비동기와 동기에 대해 - HoonIOS (0) | 2021.05.10 |
---|---|
[iOS] 테이블 뷰 컨트롤러에서 페이징 처리 구현하기 - HoonIOS (0) | 2021.05.09 |
[iOS] UICollectionViewFlowlayout 설정 & 적용하기 - HoonIOS (1) | 2021.05.05 |
[iOS] 컬렉션뷰 데이터소스& 델리게이트 구현해보고 뽀시자! - HoonIOS (0) | 2021.05.04 |
[iOS] 컬렉션뷰의 델리게이트 & 데이터소스 뽀시기 - HooniOS (0) | 2021.05.04 |