HotCoffee
- 강의 보기전에 대략적인 UI를 구현했습니다. 이번엔 Autoresizing 레이아웃을 사용하지 않고 구현해봤다.
오호.. Hiroku로 간단하게 주간단하게 웹 서버가 동작하는 법을 살짝 맛봤다.
초기 order 서버에는 빈 배열만있는데 iOS로 새로운 데이터 전송을 하지않고 (네트워킹 툴)포스트맨에서도 쉽게 value를 추가 할 수있다. 근데 이 강의에서 소개한 서버는 한번 실행하면 몇시간만에 저장해둔 db 값들을 다시 싹 날려버린다. (헛;; 기존 서버가 만료됬나.. 요청 안됬는데 다행히 공지사항을 보니 새 서버 주소가 있네 휴..)
실제로 Web API를 test할 때는 포스트맨 같은 네트워킹 툴을 사용하면 휠씬 편하다.(잘 응답 되는지 등등+ 문서화도 가능)
이미지1 서버 정상동작
포스트맨을 사용하면 어플리케이션에서 POST방식으로 값을 서버로 전달하지 않고도 포스트맨에서 POST방식으로 값을 추가해준 후에 GET방식으로 변환해서 성공적으로 값이 서버에 저장되었는지 요청하면 볼 수있다. 정말 편하고 신기하다.
마주한 에러들
돌발상황 #1
오늘 마주한 에러이다...
Date: 22.09.03~22.09.04
새로운 개념을 알게 되었다 Codable... 그냥 데이터를 JSON형식으로 모델에 적용하는것은 쉬운데 Codable 프로토콜로 채택하는 것은 아주 많이 까다로웠다.
간단하게 responseString으로 값을 확인했을 때는 성공적으로 데이터가 존재하는데 decode(_:from:)를 했을 때 Codable 프로토콜이 적용되지 않은 채로 존재한다. 데이터 -> decode가 적용이 되지 않는다. 왜그럴까? 해결하려고 온갖 방법을 썼는데 그덕에 Alamofire의 여러 response 메소드를 강제로 다루게 되고 익숙해져버렸다;;;;;.... 하지만 문제는 여전히 해결할 수 없었다. URLRequest로 HTTP메서드 정의해서 URLSession으로 데이터를 파싱하려고해도 에러가...발생했다.
해결 과정은 아래에 작성.
돌발상황 #2
어떤 유저가 coffee size 타입을 Large로 보냈다. 하지만 내 Enum에는 소문자로 case가 되있어 Codable 조건이 만족되지 않았다.
-> singleValueContainer를 통해 Container>의 데이터를 받아와서 lowercased()적용했다. 그래서 CoffeeSize또한 lowercase()를 적용시키니 해결이 됬다.
돌발상황 #3
사용자가 주문을 할 경우 그 값들은 Order.create(_:)를 통해 만들 수 있다. 이건 Order 인스턴스이다. Codable타입이기에 JSONEncoder()로 인코딩을해서 데이터를 얻었다.
URLRequest말고 AF.request(_:method:...) 함수를 통해 다량으로 값을 넣어 전송하고 싶었다. 근데 reqeust의 경우 parameters로 값을 서버로 전송할 수 있는데 JSONSerialization.jsonObject(with:) as [String:Any]로 변환해주었는데 차꾸만 responseDecodable(of:) 과정에서 디코딩을 수행할 수 없었다..;;
그래서 결국 load
AF.request의 경우 url String을 요구하는것과 URL을 요구하는 두가지 함수 오버로딩이 되어있어서 send로 HTTP에 값을 전송할 때는 URLRequest인스턴스를 만들어서 AF를 사용했다.
돌발상황 #4
마지막으로 마주한 에러인데,, 사용자의 주문을 받으면 save버튼을 통해 주문 정보는 서버에, 그와 동시에 다시 메인화면으로 되돌아가야한다.
난 강의에서와 다르게 먼저 구현하고 강의를 보면서 공부했기에 화면 전환 구조가 살짝 달랐다. 그래서인지 모르게 에러가 발생했다.
UITableViewAlertForLayoutOutsideViewHierarchy error: Warning once only (iOS 13 GM)
이 에러가 발생했다. frame을 보니 메인 화면의 tableView에서 난 에러였다. 원인은 아마 메인 OrderTableVC 컨트롤러에서 테이블 뷰가 표시되지 않는데 segue된 화면에서 메인 테이블 뷰의 cell을 추가하는 코드를 구현 했기에 이런 에러가 발생했던 것 같다. (아.. 에러난 코드를 커밋하지 않았네 ㅠㅠ)
해결법은 viewWillAppear()에 tableView.reloadData()를 실행하고 AddOrderVC에서 오더를 받으면 단지 list에 값을 추가하기만 하는 방식으로 구현했다.
그리고 화면 전환을 segue로 했다. 되돌아갈 때는 navigationController의 popViewController(animated:) 메서드를 사용해 되돌아왔다.
새로 알게된 개념
1. JSON과 Codable 공부
Date: 22.09.03~22.09.06 위에서 마주한 에러를 해결하기 위해 약간의 공부를 했다. 간단하게 끝날 줄 알았는데 시간은 계속 흘렀다.
위의에러를 해결하기 위해서 RESTful API JSON 데이터 파싱 개념을 공부했고 URLSession과 URLReqeust에 대해 자세하게 공부했다. Codable을 적용하기 위해 Alamofire 도 공부를 했다. URLRequest + URLSession 과 Alamofire 공부를 충분히 한 후에 Codable 공부를 했다. 그리고 Codable이 진짜 좋은 프로토콜임을임을 알게 되었다.
근데 가장 좋은 건 친절하게 알려주신 StackOF 천사같은 어느 한 개발자님..정말 감사했다. 선 정답 답변을 통해 알고도 곧바로 이해를 못했지만 Codable공부를 완벽하게 끝낸 이후엔 내 코드에 CodingKeys정의부터 몇몇 문제가 있었음을 알 수 있었다. 그리고 에러를 해결했다.
2. 서버 root JSON 형식
새로 알게된 개념인데 RESTful API의 JSON 에서 root object as Array인 경우 OrderList라는 list구조체를 굳이 만들지 않아도 된다.
load(resource<[Order]>) { result in
// handle the response but now you will get the list of orders
}
를 통해 배열로된 list를 받을 수 있기 때문이다.
이와 반면에 root object as Object의 경우 OrderList를 생성해야 한다.
3. 화면 전환시 델리게이트
강의를 들으면서 정말 좋았던 것은 화면 전환시에 델리게이트를 프로토콜로 구현해 본 것이다. A(메인VC) B(subVC)가 존재하고 A->B로 화면 전환한 상태에서 B에서 발생한 정보를 A로 넘겨줄때 델리게이트를 프로토콜로 구현해서 사용했다.
B의 VC에서 A에서 수행해야 할 기능들을 프로토콜로 만들어 놓고 A의 화면에서 B의 화면으로 전환할 때 B VC인스턴스를 얻어 델리게이트 변수에 자기자신을 등록함으로써 B에서 기능들을 호출하면 A에서 구현한 델리게이트 메서드가 작동한다. 이때 화면 전환도 이루어진다.
4. JSON 파싱 POST 방법
RESTAPI에 대한 GET 방식은 거의 잘 이해했는데 POST방식은 이전에 메모 앱 만들때도 해봤지만 기억이 잘 안났다. 다행히 돌발상황 #3 과정을 겪으며 POST방식에 대해 어느정도 개념을 갖게 된 것 같다.
결론
요즘 클린코드를 읽고 있는데 클린코드의 저자 스타일을 쪼금이나마 실행에 옮겼다.
목적은 MVVM 패턴을 공부하는 것이지만 VM 구현하는 것 이외에도 공부한 것이 좀 있었던 실습이었다.
// save 시 서버에 데이터가 잘 추가되었는지? ( 잘 수행됨! )
'(TIL)Today I Learned' 카테고리의 다른 글
[Today I Learned] 22.09.12 (0) | 2022.09.12 |
---|---|
[Today I Learned] 22.09.11 (0) | 2022.09.12 |
[Today I Learned] 22.09.04 (0) | 2022.09.04 |