Apple Developer Academy @ POSTECH

[회고] Apple Developer Academy @ POSTECH 3기 9주차 회고

Xerath(제라스) 2024. 5. 6. 16:23
728x90
반응형

서론

안녕하세요. 개발자 제라스입니다~!👋🏻 🤖 👋🏻

이번주도 어김없이 회고로 돌아왔습니다~!!

 

요즘 날씨가 한창 더워지고 포항-서울도 자주 왔다갔다 하고 정신없는 나날입니다.

뭔가 지지난주까지는 하고싶은 공부를 잘 찾았던 것 같은데 요즘은 해야 할 게 눈에 계속 띄네요 ㅋㅋㅋㅋㅋㅋㅋ

하지만! 뭐 어떡하겠어요... 그냥 하나씩 해나가는 거죠 ㅋㅋㅋ

 

이번주는 연휴도 끼고 일이 있어서 긴 시간을 서울에서 보내고 왔지만 그래도 주말까지 꾸준히 학습했다는 거에 만족합니다 ㅎㅎ

그럼 한번 이번 주도 회고를 시작해보겠습니다!

너 ObservableObject 알아?

아뇨!

사실 아는데...학습했는데... 잘 모릅니다!

최근에 어떤 분께 이 개념을 질문을 받았습니다!

이걸 설명을 해야하는데 뭔가 그 유명한 Counter 예제 그거밖에 생각이 안나더라구요...ㅠㅠ

(참고: https://pilgwon.github.io/post/state-object-vs-observed-object)

 

근데 이게 과연 개념인가라고 했을 땐 그렇다고 보기도 어려웠어요......

개념적으로는 SOT에 저장된다, View의 라이프사이클과 동일한 생명주기를 따른다 정도가 있지만,

이걸 과연 어떻게 쓰느냐는 완전 다르니까요...!

 

특히 iOS17의 Observable 매크로를 활용한 방식 밖에 제대로 써보질 않으니

'과연 이전의 방식으로는 언제 어떻게 두 프로퍼티 래퍼를 각각 쓸까?' 란 의문을 제대로 겪어보지 못했습니다.

 

그래서 이번주에는 두 개념의 차이를 중심으로 학습을 하려고 했는데 사실 또 자세히 보면 두 개념이 대등한 비교대상이라기보단 상하위 개념? 아예 다른 사용방식으로의 개념이라서 이 둘의 사용되는 상황을 기준으로 학습해보았습니다.

이유는 개념적 차이(SOT, 생명주기 등)는 있지만 이걸 기준으로 보려고 하면 코드 내에서 언제 StateObject로 쓰고, 언제 ObservedObject로 써도 되는지를 알기 힘들더라구요.

 

그리고 막연하게 ObservableObject의 동작원리를 잘 모르고 있었는데, 이걸 알게 되면서 아 Combine 공부 더해야겠다는 생각이...ㅋㅋㅋㅋㅋㅋㅋ

(학습의 선순환ㅎㅎㅎ)

 

혹시나 궁금하신 분은 아래 글을 참고해보시면 감사드리겠습니다!

https://xerathcoder.tistory.com/281

 

[Swift 지식] @ObservedObject vs @StateObject의 사용 상황의 차이점 (feat.Observation)

서론안녕하세요~! 개발자 제라스입니다! 👋🏻🤖👋🏻 오늘은 아주 기본적인 개념을 들고 왔습니다ㅎㅎㅎSwiftUI 학습 초반에 많이들 배우겠지만 사실 요즘 워낙 iOS17의 입김이 센 요즘이기에

xerathcoder.tistory.com

다시 끄집어볼 줄 아는 용기

요즘 한창 애플 아카데미에서는 MC2가 진행 중이에요.

지난번의 NC1은 혼자서 모든 걸 하는 프로젝트였다면 이번 MC2는 함께 프로젝트를 기획-디자인-구현까지 하는데 구현도 하나로 다같이 함께 만드는 프로젝트입니다.

(MC1 때는 디자인부터는 각자가 만들었었거든요 ㅎㅎ)

 

사실 하나의 앱을 다같이 분업해서 만든다는게 너무나도 일반적이기에 저는 오히려 마음이 편하고 좀 더 구현보다는 기술에 집중해볼 수 있을 것 같아 좋은 것 같습니다ㅎㅎ (시간적 여유가 생기는 느낌이랄까...??)

 

지금은 한창 기획 중인데 저희의 앱 챌린지인 '자운드(팀원)가 16살 차이나는 동생(들이)과의 소통을 늘릴 수 있도록 도와주기'를 기반으로 기획을 해나가고 있습니다.

사실 초반부터 어느정도 기획이 잘 되어가고 있었는데 챌린지를 refine하는 과정에서 뭔가 부족함이 느껴졌어요.

 

일단 소통이란 걸 해야하니까 소통을 어떻게(수단) 할 지를 찾아보다가

'선물하기' 라는 아주 기똥찬 컨셉을 정해서 그 안에서 다양한 소통의 수단(방식+주제)을 생각해보게 되었습니다.

 

근데...근데!!!

생각해보니까 자운드의 입장에서만 생각해보고 들이는 왜 형과 소통을 하고 싶을까에 대해서는 쏙 빠져있더라구요.

심지어 현재 둘의 소통이 어느 정도인지도 모르면서 무작정 늘려야겠다는 생각만 했었던 거죠...!

즉, 현재 상황을 제대로 파악하지 못한 채 늘릴 방법만 생각했음요 ㅋㅋㅋㅋㅋㅋㅋ

 

그래서 이번주에 다시 2차 인터뷰를 진행했습니다.

팀원 중 가장 토끼를 닮으신 젠께서 토끼 캐릭터를 쓰고서 화상 인터뷰를 진행했어요.

후...상당한 그의 뒤태... 들이 탈덕 힘들다...

1시간 가량을 인터뷰한 덕분에 꽤 많은 요소들을 뽑아내었는데

 

이 대화들을 기반으로 문제 요소를 짚어내고 자운드가 들이와 대화하는 방식에 있어서 개선시킬 기회요소들을 탐색해서 챌린지를 더욱 refine해볼까 합니다 ㅎㅎ

 

이렇게 앞으로만 향하는 기획 방식에서 계속 뒤돌아보고 끄집어보고 문제를 다시 덮어두는게 아니라 해결하기 위해 꺼내서 잘 채워넣어 보았습니다.

이 덕분에 팀원들 모두가 만족을 하며 기획을 해나가고 있단 걸 함께 느끼고 있는 요즘입니다ㅎㅎㅎ

 

조만간 이 기획이 마무리되고 금주에는 Apple의 Asia 지역 아카데미 전체를 매니징하고 있는 Gilbert Ho가 방문한다고 하는데 그때 저희의 기획을 잘 설명해보고 좋은 피드백들 적극 수용해봐야겠습니다!

(어...영어 공부해야겠는데...? 어라라...🤦🏻‍♂️🤦🏻‍♂️)

유행만을 좇지 않는 내가 되는 방법

지난 주 회고에서도 언급이 되었지만 요즘 UIKit 공부를 좀 많이 해보고 있습니다 ㅎㅎ

한창 3월부터는 SwiftUI 학습에 매진했었는데 4월 말부터는 이 둘을 함께 병행하다보니 꽤 학습시간 분배가 어렵더라구요 ㅠㅠ

 

근데 이와중에 주변에서 어떤 공부하고 있다, 이런 거 아냐? 이런 대화들을 하다보면 '우왁...!! 저거 공부하고 싶다!!' 이러는데 결국 학습 ADHD가 도져버리는 것 같아요 ㅋㅋㅋㅋㅋㅋㅋ

 

그래서 이제는 키워드 수집에 흔들리지 않고 천천히 하고자 했던 학습, 그리고 순서에 맞게 학습해나가야겠다는 생각을 많이 했습니다.

물론 하고싶은 공부 너무나도 많고 모른다는 걸 인지하는 순간 '아...! 저거 공부해야지!!' 싶지만 몸은 한개고 하루는 24시간인데 어떻게 다 하겠어요 ㅋㅋㅋ

지금 정말 해결해야할 거라도 하나씩 해나가는게 저한테 지금은 필요한 거 같습니다.

 

하지만...키워드는 계속 모아둬야죠 ㅎㅎㅎ 그래야 모르는 걸 모르는 일이 줄어들 테니까요...!!

 

코드 리뷰는 맛있는 시간이다

이번 주중에 같은 러너인 브루클린으로부터 연락이 왔었어요.

지난 NC1을 하면서 진행했던 프로젝트에 대한 코드리뷰에 대한 부탁이었는데 저한테는 너무 감사한 일이었죠 ㅎㅎ

다른 개발자의 코드를 리뷰해볼 수 있다는 거...! 너무 행복했습니다 ㅠㅠ

특히, SwiftUI는 제가 큰 프로젝트를 진행해본 경험도 없고 해서 다른 사람들이 짜는 코드를 살펴보는 것만으로도 스스로에게 큰 성장을 가져다 줄 수 있었거든요!

그래서 금요일에 리이오, 라뮤와 함께 브루클린의 코드리뷰 시간을 가졌습니다! :-)

 

이번에 리뷰를 하면서 배웠던 건 

1. ObservableObject의 메모리 차지 문제
2. ViewBuilder와 struct View를 쓰는 타이밍

 

크게는 이 2가지였습니다.

 

1번은 앱의 음악 검색 기능에서 MusicKit에서 받아온 url로 노래 썸네일을 5개만 받아오는데 렌더링이 너무 오래걸린다는 이슈였습니다.

이 부분에 대해서 함께 리뷰어로 참여했던 라뮤가 breakPoint를 걸어서 확인해보니 계속 받아온 데이터를 그리지 않고 빙글빙글 돌면서 데이터를 다시 바꾸는 문제가 있었습니다.

 

이 문제가 왜 발생했는지 생각해보니 검색어와 음악 데이터가 같은 ObservableObject에서 둘 다 @Published로 되어있다보니 검색어가 바뀜에 따라 계속해서 다시 그리는 문제가 발생했고, 그 과정에서 계속 Song이 새로 추가되는 Task가 돌게 되는 이슈가 생겼습니다.

class MusicSearchManager: ObservableObject {
    @Published var songs: [Song] = []
    @Published var searchTerm: String = ""
    
    static let shared = MusicSearchManager()
    
    func requestUpdatedSearchResults() async {
        ...
    }
}
struct MusicSearchView: View {
	...
    let imageManager = ImageManager()
    ...
    
    var body: some View {
        NavigationStack {
            VStack {
                searchResultList()
            }
            .searchable(text: $searchManager.searchTerm, prompt: "오늘의 음악을 골라볼까요?")
            .onChange(of: searchManager.searchTerm) {
                /// Mark : 검색 시 느려지는 현상
                Task {
                    await MusicSearchManager.shared.requestUpdatedSearchResults()
                }
            }
            .onAppear {
                musicauthorizationManager.requestCloudServiceAuthorization()
            }
        }
    }
    
    @ViewBuilder
    func searchResultList() -> some View {
        ...
    }
}

이렇게 해두다보니 searchTerm이 바뀔 때마다 계속 검색을 하게 되고,

그 과정에서 songs도 매번 계속 바뀌게 되는 그런 현상이 발생을 했습니다.

 

이건 사실 지난주에 제가 구현해보았던 AppStore Search 과정에서 발생했던 과부하 문제와도 비슷했던 것 같았습니다.

그래서 저는 이걸 searchTerm을 굳이 계속 저장하고 구독할 필요가 없으니 ObservableObject에서 빼고 View에서 @State로 값을 관리하되 검색을 완료 시 요청하는 방식으로 수정을 요청드렸습니다.

 

이 부분은 전에 경험한 debouncing을 적용한다면 조금 더 나은 UX가 될 수도 있겠네요 ㅎㅎ

 

다만, 아직 저도 이 부분에서 고민인 건 limit을 5로 두어 검색결과가 5개만 넘어오는데 List를 개당 2번씩 돌아서 총 10번을 도는 이슈를 발견했습니다. 이건 대체 어떤 이유에서인지는 조금 더 고민을 해봐야겠습니다.

 

2번은 제가 자주 쓰지 않던 'ViewBuilder를 어떤 View의 SubView로서 사용하는데 과연 이걸 기본 컴포넌트에서 extension이 아니라 ViewBuilder로 구현해서 쓰는게(마치 커스텀한 Modifier를 구현하듯이) 괜찮은 걸까?' 하는 고민이었습니다.

이 부분에 대해서는 어떤 View에서 쓰일 ViewBuilder는 그곳에 구현을 하고 subView로써의 목적을 가진 코드란 걸 드러내주는게 좋다는 것과 func지만 대문자로 작성을 해서 View임을 제대로 명시해주는 것이 좋다는 걸 배울 수 있는 기회였습니다.

 

앞으로 구현하면서 종종 ViewBuilder로 작성을 해봐야겠습니다 ㅎㅎ 너무 익숙하지가 않아서리...ㅠㅠ

번외지만 다른 러너인 모수는 이걸 거의 대부분 다 붙여버린다고 하더라구요...!

이런 점에서 분명 ViewBuilder도 확실히 알아두고 쓴다면 효과적일 것 같습니다!

 

이외에도 다양한 학습거리들이 있었는데 코드리뷰 시간이 확실히 예시도 제대로 나타나고 문제 해결이나 개선 혹은 코드 리팩토링에 초점이 맞춰져있다보니 짧은 시간에 학습도 되고 키워드도 많이 얻을 수 있는 것 같습니다. 

 

다음 주의 나에게

이번주는 뭔가 어수선할 수도 있었던 한 주였던 거 같습니다.

다만 이번 주 연휴동안 쉬지 않고 계속 학습하려한 것에 나름 스스로 만족하면서 넘어갈 수 있었던 거 같네요ㅎㅎ

 

아 맞다!

이번주에 32인치 4K 모니터를 샀는데... 너무 만족스러워요 ㅋㅋㅋㅋㅋㅋㅋ

배경은 제 최애 가수 한로로입니다...👍🏻👍🏻

그래서 뭔가 이제는 아카데미 세션이 끝나면 방에 돌아와서 학습을 하게 되지 않을까 싶네요...!!😃😃

 

다음주에는 한번 SwiftUI-MVVM 방식의 코드를 학습해 볼 예정이에요!

어제 밤에 모수와 개발 얘기를 나누면서 SwiftUI에서의 아키텍쳐 얘기도 잠깐 했었는데

한번 그 형태를 찬찬히 살펴보고, 왜 모수가 MVVM과 SwiftUI가 그렇게 안 어울린다고 했는지 직접 경험해보려구요!

양방향성의 SwiftUI를 강제로 끊어놓으려는 시도가 얼마나 '굳이?이잉???굳이?' 하는 포인트들을 만들어낼 지 기대가 됩니다! :-)

 

그럼 이번 10주차도 알차게 지내보고 10번째 회고로 돌아오겠습니다! :-D

728x90
반응형