SHcommit / LearnMoreSwiftInUdemy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Clone/Instagram] 데이터 파싱 기능 개선, Feed 게시물 구현 | 새롭게 알게 된 개념 & 느낀점 #11

SHcommit opened this issue · comments

구현영상

  • 이번에는 앱의 전반적인 중복 함수 제거, async 처리 가 주를 이뤘다. 추가로 UplaodPostController에서 사용자가 게시글을 작성할 경우 FeedVC에서 글을 보여주도록 구현했다.

강의와 다르게 구현한 기능

  • Async/Await. Concurrency

Concurrency 처리는 현재 앱의 특성상 적용할게 없는 것 같다. 추후에 Feed VC 게시물이나 SearchController의 모든 사용자 프로필에 대해서 부분적으로 적용할 수 있으면 해볼 계획이다.

계속해서 파이어베이스의 데이터를 다운받고 이미지도 다운받는 작업이 어떻게하면 효율적으로 개선될 수 있을지 고민하고 있었다. @escaping 을 통해 비동기적으로 받은 파이어베이스 함수들의 completionHandler의 값을 또 @escaping completion으로 처리를 하고 있다.

근데 상황에 따라서 사용자의 uid를 얻고 그 후에 또 사용자의 이름, 닉네임 등의 정보를 얻기 위해 중첩으로 클로저 안에 클로저를 사용하고 그 값을 또 받는 곳애서 클로저로 사용하는 등 연달아 클로저를 호출 했었는데 컴파일러의 오류 메세지가 떴다 "너무 클로저를 남발하지 마세요..." ( 너무 completion에 의존한것 같기도 하고..)

에러2

함수가 종료된 후에도 메모리에 지워지지 않고 저장되어 있다가 호출 된 후에야 없어지는?(강력 순환 참조 발생시 안 사라질 수도?) @escaping 클로저를 계속해서 사용하는 것은 너무 쉬웠다. 그런데 약간씩 코드가 꼬이는 것을 볼 수 있었다.

이미지도 나름대로 백그라운드에서 다운받고 메인 스레드로 호출을 했는데

애러1

이런 에러가 계속 발생했다. (아흑 운영체제 때 배웠던 세마포어가 여기서도 사용 되는구나,,)

이참에 클론을 잠시 멈추고 앱의 성능을 향상 시키기 위해, 새로운 기능을 적용하기 위해 Async, Await 그리고 thread에 대해서 공부를 했다.

지금 일부 API호출을 async, await를 적용했는데 성공했다.+_+ (30분짜리 강의를 시청하는데 5시간이 걸린 결과인가..,....) 거의 절반 가량의 데이터 파싱 함수들을 Async, Await로 구현했다.

  • try catch구문을 사용했다.

  • 텍스트 필드 클래스를 만들어서 간단하게 델리게이트 구현후 count에 따라 현재 몇 글자인지 갱신하는 것과 일정 크기를 넘지 않도록 구현 했다. 근데 알고보니 textViewDelegate에도 텍스트 체인지 델리게이트가 있었는데 난 새로 구현해버렸다.

  • 코드를 리펙터링할 때 Clean Code의 느낌을 살려서 코드화 해봤다.
    클린코드

추가로 공부한 것

  • 에러처리 EmilY님 링크

  • 에러 처리 공식 문서 링크

  • Async/await WWDC 2021 링크 (외국 영상이라 그런지 모조리 쓰면서.. 영상에 나오는 개발자분의 말 하나하나 쓰고 정리하면서 공부를 했는데 30분짜리 영상을 5시간이나 공부했다;;; )

  • task WWDC 2021 링크

  • @escaping 개념 공부와 정리


새로 알게 된 개념

  • 지금 async. await을 거의 적용해간다. 열심히 떱떱디시에서 공부했다.
    그리고 적용하려고 하는데 예외처리 추가로 예외처리에 대해 공부했다.

  • selectedIndex

이 인덱스 값을 입력하면 해당 vc로 이동한다.

  • tabBarControllerDelegate의
    tabBarController(_:shouldSelect:)

현재 VC의 델리게이트 등록하고
이를 통해 특정 탭바 버튼으로 vc가 로드되기 전에 tabBarController(:shouldSelect:) 메소드가 실행된다. 오잉?? 해당 컨트롤러의 viewWillAppear(:) 와 다른점은 무엇이지??

  • 인디케이터의 start, end 함수는 extension에서 구현했는데 프로퍼티는 선언이 안 되서 못 만드는 줄 알았는데 static 변수는 선언이 가능하다는 것을 알게 되었다.

  • 텍스트의 일정 크기가 넘을 경우

deleteBackward() 함수를 사용하자.

func checkMaxLine(_ textView: UITextView, maxLength: Int) {
   if textView.text.count > maxLength {
   	textView.deleteBackward()
   }
}

궁금한 것

1
2

- 지금 궁금한 것은 특정 프레임워크 함수가 에러를 발생할 수 있는데 이 에러를 정확하게 enum으로 정의해서 특정 case로 catch할 수 있도록 할 수 있을지가 궁금하다..

그러니까 내가 정의하거나 gaurd else구문을 통해서 내가 던진 에러는 처리할 수 있는데 프레임워크 함수에서 던져지는,, 데이터 파싱하다가 실패했을 때 발생되는 error는 어떻게 내 커스텀 enum : Error에서 받아서 처리해주는지 궁금하다.

음 임시적으로 떠오른 방법은 try? gaurd를 사용해서 throw해버리는거

try임시적처리

이게 맞는지는 모르겠다. 하지만 내 생각으로 try?처리를한 후에 다음 함수가 에러가 있을 경우 nil을 반환한다면? 그걸 guard로 바인딩해서 바인딩 실패되면 throw 처리해주는 방법이다. -> 맞는 것 같다. try? 처리의 경우 옵셔널 타입의 value or nil을 반환하는데 nil일 경우 특정 함수가 throw로 에러를 던진 것이다. 아닐수도... 더 좋은 방법을 계속해서 찾을 것이다.

개선해야 할 것

  • 인디케이터 static으로 선언하고 각각의 vc로 선언된 인디케이터 변수 없애기.

  • searchList의 이미지 처리를 cache로 활용하기 (필수..)

  • 몇몇개의 source 코드 보면 controller에 helper가 있는데 VM으로 분리 시켜야한다. 추후에

  • 11월 14~ 20일까지 약 일주일동안 컴바인과 task, Actor에 대해 공부해서 로직을 업데이트할 것이다. 컴바인으로 완벽하게 Controller로부터 분리를 시킬 예정이다.. 헤헿