SlideShare uma empresa Scribd logo
1 de 30
Baixar para ler offline
2022 summer let us: Go! With SSG
dSunny(전선수)
SSG의 뻔하지 않은 SwiftUI 도입 고민
(feat. WWDC22)
저는..


개발을 좋아하는, 더클회색을 꿈꾸는


ENFP 클라이머입니다 🧗
SSG + SwiftUI
도입을 검토하게 된 배경(현재 SSG의 상황)
• 2022년 하반기 중 SSG 앱 최소 지원버전을 iOS 13으로 상향 예정

• SSG의 매장은 모듈화가 잘 되어있는 화면들로 구성되어 있음

• 앱 운영 시 높은 유지보수성을 위해 XIB + AutoLayout 사용 빈도가 높음

SSG + SwiftUI
도입을 검토하게 된 배경(SwiftUI 도입 시)
• 2022년 하반기 중 SSG 앱 최소 지원버전을 iOS 13으로 상향 예정

SwiftUI는 iOS 13부터 사용 가능

• SSG의 매장은 모듈화가 잘 되어있는 화면들로 구성되어 있음

모듈 유닛 하나 하나를 단일의 SwiftUI View로 변경 용이

• 앱 운영 시 높은 유지보수성을 위해 XIB + AutoLayout 사용 빈도가 높음

SwiftUI의 Preview로 같은 효과를 낼 수 있음
그런데 1.


iOS 13 + SwiftUI로는


할 수 있는 것이 너무 한정적이다.
SwiftUI + iOS 14
(iOS 13에서는 할 수 없지만, 상관 없는 기능들)
• TextEditor

UIKit -> UITextView에 대응. SSG의 매장 내 사용 영역 X

• ProgressView

UIKit -> UIActivityIndicatorView + UIProgressView에 대응.

SSG는 독자적인 로딩바를 갖고 있음

• Map

MapKit -> MKMapView에 대응, SSG 내 네이티브 지도 사용 영역 X

• DatePicker

UIKit -> UIDatePicker에 대응. SSG의 매장 내 사용 영역 X
SwiftUI + iOS 14
(최소 버전이 iOS 14여야만 했던 이유)
• LazyVStack, LazyHStack

VStack, HStack 사용 시 대량의 데이터를 lazy loading 가능.

(기존에는 퍼포먼스 문제가 있었음)

• LazyHGrid, LazyVGrid

Grid 형태의 화면을 그릴 때 사용하며 마찬가지로 lazy loading 가능.

(가로스크롤되는 SSG의 매장 내 유닛에서 사용하기 좋음)

• ScrollViewReader, ScrollViewProxy

코드로 ScrollView의 포지션 제어.

(SSG의 많은 매장에서 스크롤 지점의 컨트롤 필요)

• onChange modi
fi
er

main thread 단에서 side e
ff
ect을 트리거.

(Combine 없이 이벤트 캐치 용이)
그럼에도 불구하고 2.


기존 유닛이 모듈화가 잘 돼있어


SwiftUI로 금방 전환할 수 있다.
SSG의 모듈매장 구조
재사용 가능한 UI로 유닛 단위 개발이 되어 있음
똑같은 SSG 홈 매장 내의 유닛이지만, 이 2개의 유닛은 다른 유닛이 아닌

재사용 가능한 타이틀유닛으로 매장 기획자가 언제든 원하는 위치에 꽂을 수 있다.
SwiftUI 전환을 위한 Step-up
SSG의 타이틀 모듈유닛을 예제로
• ObservableObject에 사용될 ViewModel을 준비

(TitleUnitPresentable(타이틀 유닛 UI 표시 가능한)을 adopt하는 샘플 클래스 정의)

• UI대로 그린다. 내부 구성 요소가 2개 있는 구조이며, 2px 간격이라고 하면,

VStack(alignment: .leading, spacing: 2)에 대응

• 두 UILabel은 Text로 정의하여 font, foregroundColor 설정

두 타이틀은 최대 2줄이므로 lineLimit을 2로 적용

• 이 모듈유닛의 여백을 상단 45 좌우 15, 하단 0이라 하면,

가장 외곽에 padding을 이 수치로 적용
각 셀들의 SwiftUI View 전환 용이
속도만 붙으면 수십 개의 셀을 금방 만들어낼 수 있음
그래서 3.


SwiftUI + Preview 조합으로


기존 XIB, autolayout을 대체 가능한가?
XIB + Autolayout의 장단점
frame 방식에 비해 성능은 열세이나, 유지보수성이 높다
• XIB는 필연적으로 파일 시스템을 거쳐 XIB을 메모리로 불러와야 함

(frame 방식은 이 과정이 필요 없으며, 매우 오래 걸리는 과정)

• Autolayout은 XIB에서 사용했을 때 GUI 사용성이 좋고,

코딩으로 사용하는 것보다 훨씬 소스코드가 간결해진다.

• frame 방식은 물리적으로 속도가 가장 빠른 방법이지만,

개발자가 수정을 원하는 뷰, 영향을 받는 뷰를 모두 알고 수정해야 한다.

따라서 개발자의 생산성이 매우 저해되고 유지보수성이 낮다고 할 수 있다.

• 따라서 SSG에서는 성능이 아주 중요한 화면이 아니라면(쓱톡 - 채팅)

유지보수성이 높은 XIB + Autolayout 개발 방식을 주로 사용해왔음
XIB + Autolayout vs
실제로 타이틀 모듈유닛을 개발한다면?
1. 간단한 디자인의 변경은 XIB 파일 내 Autolayout 추가 및 수정으로 모두 처리할 수 있다.

이로 인해 개발-기획-디자인 간 업무 생산성이 높아진다.

(별도의 디자인 검수 일정이 불필요하며, 개발 속도도 빠르므로)

2. 많이 사용될 때 성능이 느린가?

SSG의 모듈 유닛들은 원자적 단위로 하나의 일만, 하나의 책임만 맡게 설계하는 것이 원칙.

따라서 고객이 체감할 때 생각보다 좋은 퍼포먼스를 보여주고 있다.

3. 그럼에도 두 개 이상의 파일을 열어서 수정 부분을 같이 봐야 하는 경우가 많다.

간단한 디자인 수정이라면 XIB만 봐도 되겠지만, 추가되는 것이 있다면 필연적으로 swift 파일을 열어보아야 함.

하나의 파일만 열어서 간단하게 수정 작업을 한다면 생산성이 더 높아질 것이다.
vs frame
frame 방식으로 타이틀 모듈유닛을 개발한다면?
1. 코드가 굉장히 길어져 가독성이 매우 떨어진다.

2. 즉, 디자인 변경 시마다 코드를 분석해야 한다.

(원작자가 아니면 분석 시간은 배로 걸린다.)

3. 또한 하나를 수정해도 이에 영향을 주는 다른 뷰도 봐야 한다.

이 과정에서 객체의 책임을 잘 생각해야 함.

필요에 따라 모든 구성요소가 영향을 받을 수 있고,

간단한 수정인데도 전부 수정을 해야 할 수도 있다.

Autolayout은 객체 간의 의존성을 자동으로 해결해주지만,

객체 간 의존성 문제를 전부 코드로 해결해야 한다.

4. 그럼에도 성능 상의 이득은 분명히 있다.

(SSG 매장에서도 이렇게 개발된 영역이 있는데,

채팅 - 쓱톡처럼 가변의 데이터가 대량으로 실시간으로 있고,

스크롤 시 부드럽고 빠르게 되어야 하는 상황이었음)

정리하면 성능 상 이득을 보는 대비

생산성(유지보수성)이 극도로 떨어지는 것이 문제이다.
vs SwiftUI + Preview
frame처럼 코드에서 작업이 필요하지만 유지보수성이 높음
1. 이전과 다르게 다른 요소와의 의존성이 적다.

2. 하나의 디자인 수정에 하나만 집중할 수 있다.

3. XIB를 로드하는 시간이 없어 성능 상 유리하다.

(대신 compile time을 어느 정도 기다려야 한다.)

4. RxCocoa 등 외부 오픈소스의 니즈가 거의 없다.

(SSG 매장에서는 사용하지 않고 있음)

5. XIB, swift 파일이 분리되어 있지 않아

한 파일에서 작업이 가능하다.
Flutter, React Native로 입문자에게는

SwiftUI가 금방 익숙해질 수 있다.

vs



Autolayout에 익숙하다면 사고의 방식을

전환하는 데 러닝 커브가 존재한다.
하지만 4.


여전히 해결되지 못한 문제가 있었으니..


UICollectionView를 대체할 수 있을까?
UICollectionView를 대체하는 방법 1
ScrollView + VStack
실제로 Reuse가 전혀 되지 않는다는 치명적인 단점이 있어 대체 불가능.

(LazyVStack도 마찬가지의 단점을 공유)
UICollectionView를 대체하는 방법 2
List + HStack
ForEach 를 이중으로 선언하여 UICollectionViewFlowLayout 을 구현하는 것처럼 하나의 line이 하나의 HStack이며, Reuse도 가능하다.

(이 예제에서는 1줄이 꽉 차는 타이틀 유닛만 있으므로 ForEach 하나를 생략하였음)

그러나 iOS 13, 14, 15 버전별로 separator를 없애야 하는 처리가 다르고 핏이 UITableView와 유사한 List를 그대로 쓸 수는 없다.
UICollectionView를 대체하는 방법 3
UIViewRepresentable
기존 UIColelctionView를 embed 하는 방식.

실제 SSG에서 사용 불가능한 방법.

1. SSG의 UICollectionView는 dataSource와 delegate를 한 곳에서 처리하는 Adapter 패턴을 사용 중.

Adapter의 data만 바인딩하는 구조로, 아래처럼 특정 delegate를 구현하는 방법을 사용할 수 없음.
2. 전체 껍데기를 SwiftUI만 써서는 각 모듈유닛을 SwiftUI로 만드는 것이 무의미하다.

(기존의 cell을 그대로 사용할 수 있는데, 뭐하러 힘들게 SwiftUI로 변환을…)
UICollectionView를 대체하는 방법 4
UIHostingController
Cell 내에 XIB를 없애고 SwiftUI로 대체하는 방법으로 껍데기만 UICollectionView를 쓰는 문제도 해결되며, 이전의 디자인 패턴 문제도 해결된다.
이렇게 SwiftUI를 쓰게되면 CollectionView가 외부의 정보를 전달해야 한다.

그러나 SwiftUI는 SwiftUI의 요소들로부터 외부에서 내부의 컨텐츠를 채워가는 방향이 이상적이다.

심지어 SSG에서는 성능을 위해 모듈유닛들의 물리적인 사이즈를 캐싱하고 있다.

결국 UICollectionView가 각 item의 size를 구하도록 하는 이벤트를 불러야 한다.

사이즈만 구하는 곳을 따로 구현을 하자니 관리의 포인트가 두 곳이 된다.
디자인 수정이 발생하면 사이즈 구하는 곳도 고치고, 내부 SwiftUI도 고쳐야 하는 불합리한 상황인 것이다.
어떻게 해야 할까?
UICollectionView를 대체하는 방법 5
PreferenceKey + GeometryReader
아래처럼 GeometryReader와 SizePreferenceKey를 추가하면 동적인 사이즈를 꼼수로! 제공받을 수 있다.

원리는 View의 background color를 강제로 세팅하여 세팅한 뷰의 크기를 Key Value로 Observing하는 곳에 Value로 넘기는 것.
이렇게 넘기는 사이즈로 각 모듈유닛의 사이즈를 캐시할 수 있으나, 이는 Apple이 권장하는 방법이 아니다.
Apple이 의도하는 대로 SwiftUI를 사용하지 않고 전통적인 방식의 UIKit을 사용하는 것처럼 회귀하는 것.
결론.


SwiftUI를 Apple의 의도대로 사용하는 것이 중요하다고 생각했으나,


SSG의 매장 내 모듈유닛은 Apple의 이상대로


SwiftUI에 맞춰줄 수 없었다. 적어도 최소버전이 iOS 13에서는…
그렇다면 SwiftUI를 야심차게 내놓은
Apple의 방향성은 무엇이었을까?


이번 WWDC22를 통해 엿볼 수 있다.
UICollectionViewCell + SwiftUI
UIHostingCon
fi
guration
놀랍게도 최소버전이 iOS 16이라면 UICollectionViewCell 내부에 SwiftUI 코드를 내장할 수 있다.

즉, SwiftUI로 미리미리 재사용가능한, 모듈화된 Custom View를 잘 구성해놓는다면

별도의 처리 없이 XIB + Autolayout을 쓰는 경우 효과적인 soft landing이 될 수 있을 것이다.
하지만 여기서 중요한 것은 존버하면(존중하면서 버티면) 알아서 쓸 수 있다는 결론이 아니다!

개발자에게 더 편해질 미래가 오는 것은 맞지만,

SwiftUI를 통해 보여주는 Apple의 숨은 메시지를 잘 해석해야 한다.
Apple은 앞으로 UIKit으로 시작한 개발자에게, UI를 설계할 때

만드는 뷰를 캡슐화하여 설계할 수 있도록 가이드를 준 것이다.

1. 이미 Objectrive-C부터 CFArrayRef, CFStringRef 등이 Opaque Type이었으며

2. SwiftUI로 만드는 화면도 사실 some View를 return함으로써 Opaque Type으로 만든 것이다.
Opaque Type과 캡슐화
some View로 return했을 때의 장점 = Opaque Type의 이점
이 View를 가져다쓰는 쪽에서는 내부 구현(= 실제 타입)이 숨겨진다.

또한 디자인 수정이 있어 View 내부 구성을 바꾸더라도(HStack이 하나 더 늘어난다거나 등)

가져다쓰는 쪽에서 이 타입을 일일이 변경해 주어야 하는 수고를 덜어준다.

개발자는 오직 이 some View를 return하는 곳에만 집중하여 개발할 수 있다.
SSG 코어매장파트 개발자, 디써니의 입장에서 캡슐화가 중요한 이유
서로 다른 두 모듈유닛은 서로에 영향을 주지 않아야 한다.

하나의 모듈유닛은 하나의 역할만 해야 한다는 설계 원칙을 지켜서 개발해야 한다.

그래서 디자인 수정이 필요하더라도 그 모듈유닛이 서브로 포함된 다른 유닛까지 모두 수정할 일은 없어야 하고, 실제로 그렇게 개발돼있다.

미래에 SwiftUI로 전환하더라도, 모든 모듈유닛은 캡슐화되어 있어야 하며, some 키워드를 사용하여 return한다면, 내부 뷰를 Opaque Type으로 쓸 수 있을 것이다.

지금 당장은 UIKit을 사용하지만, 이 설계 원칙은 잘 따라가서 준비할 필요가 있다는 것을 느꼈음.
그런데 상황에 따라서는 호출하는 곳에서 타입을 알아야 할 수가 있다면?
그럴땐 반대되는 개념인 Generic을 사용하면 된다.
Generic이 필요한 상황
Generic을 사용하는 이유
Apple은 Parametric Polymorphism을 확보하기 위해 사용한다고 안내하지만, 구체적으로는 무슨 뜻일까?
현업에서 Generic을 사용하는 이유
타입에 의존하지 않는 범용 코드를 작성하기 위해, 중복을 피하고 코드를 유연하게 작성하기 위함.

Apple도 Foundation 프레임워크 내부의 타입은 Generic으로 처리하는 것을 알 수 있음.
왼쪽 예제는 서로 다른 카테고리탭, 개인화 카테고리 모듈이

하나의 필터 액션만 하도록 개발되었다.

예를 들어, 두 개의 데이터 타입은 달라도

이전에 받은 서버 데이터를 저장하는 동작은 같아야 한다.
누가 봐도 이런 코드보다는 Generic을 사용한 이 코드가 더 깔끔함을 알 수 있다.
그러나 현업에서는 Generic 메소드가 훨씬 복잡하다. 요구사항에 따라 두 개 이상이 들어가는 상황이 많으며,
save라는 메소드를 이해하는 것 자체가 어려울 정도로 가독성이 떨어질 수 있다.
이런 문제를 어떻게 해결해야 할까?
Swift 5.7부터 생기는 변화
WWDC22 세션 중 Embrace Swift generics 중에서
AS-IS
TO-BE (Swift 5.7부터)
Swift 5.7부터는 놀랍게도 some 키워드를 파라미터에 쓸 수 있게 됨으로써 마치 Opaque Type을 받는 것처럼 보기 편해졌다.

이로써 미래에는 불필요한 where절이나 <T: Type1, U: Type2, V: Type3, W: Type4> 이런 구문은 보지 않아도 될 것이다.
그러나 현업에서는 단일 Animal이 아니라 Animal을 adopt하는 여러 데이터 타입이 담긴 Array에서 같은 액션을 해야 하는 경우도 있을 것이다.

Apple은 WWDC22에서 여기에 대한 해답도 any 키워드를 사용할 수 있도록 답을 내놓았다.
Apple은 WWDC22를 통해


개발자들이 더 세련된 자료구조와 UI를 설계하도록


Swift 5.7의 신기능을 여러 세션에 걸쳐 공개했다. 그 중에서도


Opaque Type, Generic, Protocol을 특히 눈여겨봐야 할 것이다.
감사합니다.

Mais conteúdo relacionado

Destaque

How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...DevGAMM Conference
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationErica Santiago
 
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellGood Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellSaba Software
 
Introduction to C Programming Language
Introduction to C Programming LanguageIntroduction to C Programming Language
Introduction to C Programming LanguageSimplilearn
 

Destaque (20)

How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy Presentation
 
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellGood Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
 
Introduction to C Programming Language
Introduction to C Programming LanguageIntroduction to C Programming Language
Introduction to C Programming Language
 

20220716 SSG의 뻔하지 않은 SwiftUI 도입 고민(feat. WWDC22)

  • 1. 2022 summer let us: Go! With SSG dSunny(전선수) SSG의 뻔하지 않은 SwiftUI 도입 고민 (feat. WWDC22)
  • 2. 저는.. 
 개발을 좋아하는, 더클회색을 꿈꾸는 
 ENFP 클라이머입니다 🧗
  • 3. SSG + SwiftUI 도입을 검토하게 된 배경(현재 SSG의 상황) • 2022년 하반기 중 SSG 앱 최소 지원버전을 iOS 13으로 상향 예정
 • SSG의 매장은 모듈화가 잘 되어있는 화면들로 구성되어 있음
 • 앱 운영 시 높은 유지보수성을 위해 XIB + AutoLayout 사용 빈도가 높음

  • 4. SSG + SwiftUI 도입을 검토하게 된 배경(SwiftUI 도입 시) • 2022년 하반기 중 SSG 앱 최소 지원버전을 iOS 13으로 상향 예정
 SwiftUI는 iOS 13부터 사용 가능 • SSG의 매장은 모듈화가 잘 되어있는 화면들로 구성되어 있음
 모듈 유닛 하나 하나를 단일의 SwiftUI View로 변경 용이 • 앱 운영 시 높은 유지보수성을 위해 XIB + AutoLayout 사용 빈도가 높음
 SwiftUI의 Preview로 같은 효과를 낼 수 있음
  • 5. 그런데 1. iOS 13 + SwiftUI로는 할 수 있는 것이 너무 한정적이다.
  • 6. SwiftUI + iOS 14 (iOS 13에서는 할 수 없지만, 상관 없는 기능들) • TextEditor
 UIKit -> UITextView에 대응. SSG의 매장 내 사용 영역 X • ProgressView
 UIKit -> UIActivityIndicatorView + UIProgressView에 대응.
 SSG는 독자적인 로딩바를 갖고 있음 • Map
 MapKit -> MKMapView에 대응, SSG 내 네이티브 지도 사용 영역 X • DatePicker
 UIKit -> UIDatePicker에 대응. SSG의 매장 내 사용 영역 X
  • 7. SwiftUI + iOS 14 (최소 버전이 iOS 14여야만 했던 이유) • LazyVStack, LazyHStack
 VStack, HStack 사용 시 대량의 데이터를 lazy loading 가능.
 (기존에는 퍼포먼스 문제가 있었음) • LazyHGrid, LazyVGrid
 Grid 형태의 화면을 그릴 때 사용하며 마찬가지로 lazy loading 가능.
 (가로스크롤되는 SSG의 매장 내 유닛에서 사용하기 좋음) • ScrollViewReader, ScrollViewProxy
 코드로 ScrollView의 포지션 제어.
 (SSG의 많은 매장에서 스크롤 지점의 컨트롤 필요) • onChange modi fi er
 main thread 단에서 side e ff ect을 트리거.
 (Combine 없이 이벤트 캐치 용이)
  • 8. 그럼에도 불구하고 2. 기존 유닛이 모듈화가 잘 돼있어 SwiftUI로 금방 전환할 수 있다.
  • 9. SSG의 모듈매장 구조 재사용 가능한 UI로 유닛 단위 개발이 되어 있음 똑같은 SSG 홈 매장 내의 유닛이지만, 이 2개의 유닛은 다른 유닛이 아닌
 재사용 가능한 타이틀유닛으로 매장 기획자가 언제든 원하는 위치에 꽂을 수 있다.
  • 10. SwiftUI 전환을 위한 Step-up SSG의 타이틀 모듈유닛을 예제로 • ObservableObject에 사용될 ViewModel을 준비
 (TitleUnitPresentable(타이틀 유닛 UI 표시 가능한)을 adopt하는 샘플 클래스 정의) • UI대로 그린다. 내부 구성 요소가 2개 있는 구조이며, 2px 간격이라고 하면,
 VStack(alignment: .leading, spacing: 2)에 대응 • 두 UILabel은 Text로 정의하여 font, foregroundColor 설정
 두 타이틀은 최대 2줄이므로 lineLimit을 2로 적용 • 이 모듈유닛의 여백을 상단 45 좌우 15, 하단 0이라 하면,
 가장 외곽에 padding을 이 수치로 적용
  • 11. 각 셀들의 SwiftUI View 전환 용이 속도만 붙으면 수십 개의 셀을 금방 만들어낼 수 있음
  • 12. 그래서 3. SwiftUI + Preview 조합으로 기존 XIB, autolayout을 대체 가능한가?
  • 13. XIB + Autolayout의 장단점 frame 방식에 비해 성능은 열세이나, 유지보수성이 높다 • XIB는 필연적으로 파일 시스템을 거쳐 XIB을 메모리로 불러와야 함
 (frame 방식은 이 과정이 필요 없으며, 매우 오래 걸리는 과정) • Autolayout은 XIB에서 사용했을 때 GUI 사용성이 좋고,
 코딩으로 사용하는 것보다 훨씬 소스코드가 간결해진다. • frame 방식은 물리적으로 속도가 가장 빠른 방법이지만,
 개발자가 수정을 원하는 뷰, 영향을 받는 뷰를 모두 알고 수정해야 한다.
 따라서 개발자의 생산성이 매우 저해되고 유지보수성이 낮다고 할 수 있다. • 따라서 SSG에서는 성능이 아주 중요한 화면이 아니라면(쓱톡 - 채팅)
 유지보수성이 높은 XIB + Autolayout 개발 방식을 주로 사용해왔음
  • 14. XIB + Autolayout vs 실제로 타이틀 모듈유닛을 개발한다면? 1. 간단한 디자인의 변경은 XIB 파일 내 Autolayout 추가 및 수정으로 모두 처리할 수 있다.
 이로 인해 개발-기획-디자인 간 업무 생산성이 높아진다.
 (별도의 디자인 검수 일정이 불필요하며, 개발 속도도 빠르므로) 2. 많이 사용될 때 성능이 느린가? SSG의 모듈 유닛들은 원자적 단위로 하나의 일만, 하나의 책임만 맡게 설계하는 것이 원칙. 따라서 고객이 체감할 때 생각보다 좋은 퍼포먼스를 보여주고 있다. 3. 그럼에도 두 개 이상의 파일을 열어서 수정 부분을 같이 봐야 하는 경우가 많다.
 간단한 디자인 수정이라면 XIB만 봐도 되겠지만, 추가되는 것이 있다면 필연적으로 swift 파일을 열어보아야 함.
 하나의 파일만 열어서 간단하게 수정 작업을 한다면 생산성이 더 높아질 것이다.
  • 15. vs frame frame 방식으로 타이틀 모듈유닛을 개발한다면? 1. 코드가 굉장히 길어져 가독성이 매우 떨어진다. 2. 즉, 디자인 변경 시마다 코드를 분석해야 한다.
 (원작자가 아니면 분석 시간은 배로 걸린다.) 3. 또한 하나를 수정해도 이에 영향을 주는 다른 뷰도 봐야 한다. 이 과정에서 객체의 책임을 잘 생각해야 함. 필요에 따라 모든 구성요소가 영향을 받을 수 있고, 간단한 수정인데도 전부 수정을 해야 할 수도 있다.
 Autolayout은 객체 간의 의존성을 자동으로 해결해주지만,
 객체 간 의존성 문제를 전부 코드로 해결해야 한다. 4. 그럼에도 성능 상의 이득은 분명히 있다.
 (SSG 매장에서도 이렇게 개발된 영역이 있는데,
 채팅 - 쓱톡처럼 가변의 데이터가 대량으로 실시간으로 있고,
 스크롤 시 부드럽고 빠르게 되어야 하는 상황이었음) 정리하면 성능 상 이득을 보는 대비 생산성(유지보수성)이 극도로 떨어지는 것이 문제이다.
  • 16. vs SwiftUI + Preview frame처럼 코드에서 작업이 필요하지만 유지보수성이 높음 1. 이전과 다르게 다른 요소와의 의존성이 적다. 2. 하나의 디자인 수정에 하나만 집중할 수 있다. 3. XIB를 로드하는 시간이 없어 성능 상 유리하다. (대신 compile time을 어느 정도 기다려야 한다.) 4. RxCocoa 등 외부 오픈소스의 니즈가 거의 없다.
 (SSG 매장에서는 사용하지 않고 있음) 5. XIB, swift 파일이 분리되어 있지 않아
 한 파일에서 작업이 가능하다. Flutter, React Native로 입문자에게는
 SwiftUI가 금방 익숙해질 수 있다. vs
 
 Autolayout에 익숙하다면 사고의 방식을
 전환하는 데 러닝 커브가 존재한다.
  • 17. 하지만 4. 여전히 해결되지 못한 문제가 있었으니.. UICollectionView를 대체할 수 있을까?
  • 18. UICollectionView를 대체하는 방법 1 ScrollView + VStack 실제로 Reuse가 전혀 되지 않는다는 치명적인 단점이 있어 대체 불가능.
 (LazyVStack도 마찬가지의 단점을 공유)
  • 19. UICollectionView를 대체하는 방법 2 List + HStack ForEach 를 이중으로 선언하여 UICollectionViewFlowLayout 을 구현하는 것처럼 하나의 line이 하나의 HStack이며, Reuse도 가능하다.
 (이 예제에서는 1줄이 꽉 차는 타이틀 유닛만 있으므로 ForEach 하나를 생략하였음) 그러나 iOS 13, 14, 15 버전별로 separator를 없애야 하는 처리가 다르고 핏이 UITableView와 유사한 List를 그대로 쓸 수는 없다.
  • 20. UICollectionView를 대체하는 방법 3 UIViewRepresentable 기존 UIColelctionView를 embed 하는 방식. 실제 SSG에서 사용 불가능한 방법.
 1. SSG의 UICollectionView는 dataSource와 delegate를 한 곳에서 처리하는 Adapter 패턴을 사용 중.
 Adapter의 data만 바인딩하는 구조로, 아래처럼 특정 delegate를 구현하는 방법을 사용할 수 없음. 2. 전체 껍데기를 SwiftUI만 써서는 각 모듈유닛을 SwiftUI로 만드는 것이 무의미하다.
 (기존의 cell을 그대로 사용할 수 있는데, 뭐하러 힘들게 SwiftUI로 변환을…)
  • 21. UICollectionView를 대체하는 방법 4 UIHostingController Cell 내에 XIB를 없애고 SwiftUI로 대체하는 방법으로 껍데기만 UICollectionView를 쓰는 문제도 해결되며, 이전의 디자인 패턴 문제도 해결된다. 이렇게 SwiftUI를 쓰게되면 CollectionView가 외부의 정보를 전달해야 한다.
 그러나 SwiftUI는 SwiftUI의 요소들로부터 외부에서 내부의 컨텐츠를 채워가는 방향이 이상적이다. 심지어 SSG에서는 성능을 위해 모듈유닛들의 물리적인 사이즈를 캐싱하고 있다. 결국 UICollectionView가 각 item의 size를 구하도록 하는 이벤트를 불러야 한다. 사이즈만 구하는 곳을 따로 구현을 하자니 관리의 포인트가 두 곳이 된다. 디자인 수정이 발생하면 사이즈 구하는 곳도 고치고, 내부 SwiftUI도 고쳐야 하는 불합리한 상황인 것이다. 어떻게 해야 할까?
  • 22. UICollectionView를 대체하는 방법 5 PreferenceKey + GeometryReader 아래처럼 GeometryReader와 SizePreferenceKey를 추가하면 동적인 사이즈를 꼼수로! 제공받을 수 있다.
 원리는 View의 background color를 강제로 세팅하여 세팅한 뷰의 크기를 Key Value로 Observing하는 곳에 Value로 넘기는 것. 이렇게 넘기는 사이즈로 각 모듈유닛의 사이즈를 캐시할 수 있으나, 이는 Apple이 권장하는 방법이 아니다. Apple이 의도하는 대로 SwiftUI를 사용하지 않고 전통적인 방식의 UIKit을 사용하는 것처럼 회귀하는 것.
  • 23. 결론. 
 SwiftUI를 Apple의 의도대로 사용하는 것이 중요하다고 생각했으나, SSG의 매장 내 모듈유닛은 Apple의 이상대로 SwiftUI에 맞춰줄 수 없었다. 적어도 최소버전이 iOS 13에서는…
  • 24. 그렇다면 SwiftUI를 야심차게 내놓은 Apple의 방향성은 무엇이었을까? 
 이번 WWDC22를 통해 엿볼 수 있다.
  • 25. UICollectionViewCell + SwiftUI UIHostingCon fi guration 놀랍게도 최소버전이 iOS 16이라면 UICollectionViewCell 내부에 SwiftUI 코드를 내장할 수 있다. 즉, SwiftUI로 미리미리 재사용가능한, 모듈화된 Custom View를 잘 구성해놓는다면 별도의 처리 없이 XIB + Autolayout을 쓰는 경우 효과적인 soft landing이 될 수 있을 것이다. 하지만 여기서 중요한 것은 존버하면(존중하면서 버티면) 알아서 쓸 수 있다는 결론이 아니다! 개발자에게 더 편해질 미래가 오는 것은 맞지만, SwiftUI를 통해 보여주는 Apple의 숨은 메시지를 잘 해석해야 한다. Apple은 앞으로 UIKit으로 시작한 개발자에게, UI를 설계할 때 만드는 뷰를 캡슐화하여 설계할 수 있도록 가이드를 준 것이다. 1. 이미 Objectrive-C부터 CFArrayRef, CFStringRef 등이 Opaque Type이었으며 2. SwiftUI로 만드는 화면도 사실 some View를 return함으로써 Opaque Type으로 만든 것이다.
  • 26. Opaque Type과 캡슐화 some View로 return했을 때의 장점 = Opaque Type의 이점 이 View를 가져다쓰는 쪽에서는 내부 구현(= 실제 타입)이 숨겨진다. 또한 디자인 수정이 있어 View 내부 구성을 바꾸더라도(HStack이 하나 더 늘어난다거나 등) 가져다쓰는 쪽에서 이 타입을 일일이 변경해 주어야 하는 수고를 덜어준다. 개발자는 오직 이 some View를 return하는 곳에만 집중하여 개발할 수 있다. SSG 코어매장파트 개발자, 디써니의 입장에서 캡슐화가 중요한 이유 서로 다른 두 모듈유닛은 서로에 영향을 주지 않아야 한다. 하나의 모듈유닛은 하나의 역할만 해야 한다는 설계 원칙을 지켜서 개발해야 한다. 그래서 디자인 수정이 필요하더라도 그 모듈유닛이 서브로 포함된 다른 유닛까지 모두 수정할 일은 없어야 하고, 실제로 그렇게 개발돼있다. 미래에 SwiftUI로 전환하더라도, 모든 모듈유닛은 캡슐화되어 있어야 하며, some 키워드를 사용하여 return한다면, 내부 뷰를 Opaque Type으로 쓸 수 있을 것이다. 지금 당장은 UIKit을 사용하지만, 이 설계 원칙은 잘 따라가서 준비할 필요가 있다는 것을 느꼈음. 그런데 상황에 따라서는 호출하는 곳에서 타입을 알아야 할 수가 있다면? 그럴땐 반대되는 개념인 Generic을 사용하면 된다.
  • 27. Generic이 필요한 상황 Generic을 사용하는 이유 Apple은 Parametric Polymorphism을 확보하기 위해 사용한다고 안내하지만, 구체적으로는 무슨 뜻일까? 현업에서 Generic을 사용하는 이유 타입에 의존하지 않는 범용 코드를 작성하기 위해, 중복을 피하고 코드를 유연하게 작성하기 위함. Apple도 Foundation 프레임워크 내부의 타입은 Generic으로 처리하는 것을 알 수 있음. 왼쪽 예제는 서로 다른 카테고리탭, 개인화 카테고리 모듈이 하나의 필터 액션만 하도록 개발되었다.
 예를 들어, 두 개의 데이터 타입은 달라도 이전에 받은 서버 데이터를 저장하는 동작은 같아야 한다. 누가 봐도 이런 코드보다는 Generic을 사용한 이 코드가 더 깔끔함을 알 수 있다. 그러나 현업에서는 Generic 메소드가 훨씬 복잡하다. 요구사항에 따라 두 개 이상이 들어가는 상황이 많으며, save라는 메소드를 이해하는 것 자체가 어려울 정도로 가독성이 떨어질 수 있다. 이런 문제를 어떻게 해결해야 할까?
  • 28. Swift 5.7부터 생기는 변화 WWDC22 세션 중 Embrace Swift generics 중에서 AS-IS TO-BE (Swift 5.7부터) Swift 5.7부터는 놀랍게도 some 키워드를 파라미터에 쓸 수 있게 됨으로써 마치 Opaque Type을 받는 것처럼 보기 편해졌다. 이로써 미래에는 불필요한 where절이나 <T: Type1, U: Type2, V: Type3, W: Type4> 이런 구문은 보지 않아도 될 것이다. 그러나 현업에서는 단일 Animal이 아니라 Animal을 adopt하는 여러 데이터 타입이 담긴 Array에서 같은 액션을 해야 하는 경우도 있을 것이다. Apple은 WWDC22에서 여기에 대한 해답도 any 키워드를 사용할 수 있도록 답을 내놓았다.
  • 29. Apple은 WWDC22를 통해 개발자들이 더 세련된 자료구조와 UI를 설계하도록 Swift 5.7의 신기능을 여러 세션에 걸쳐 공개했다. 그 중에서도 Opaque Type, Generic, Protocol을 특히 눈여겨봐야 할 것이다.