[iOS] Modularization(2) - Loose Coopling
2023. 5. 18. 01:31
iOS/iOS
"모듈화"란 Software를 각 기능별로 분할하여 설계하는 기법이다. 지난 포스팅에서 모듈화가 적용이 안된 모노리틱 앱 구조는 코드의 영향 범위를 파악하기 어렵고, 앱의 규모가 커질 경우 빌드시간이 오래 걸리게 된다. 이에 따라 Swift에서 모듈화를 진행하는 방법에 대해 알아보았다. 하지만, 이러한 물리적인 코드의 분리는 반쪽짜리 모듈화에 지나지 않는다. "좋은 모듈화"는 용도에 맞게 잘 구분된 기능을 가진 독립적인 모듈로 나누는 것이다.모듈의 독립성은 응집도와 결합도로 판단하게 된다. 모듈의 "응집도"란 모듈 내부의 기능적인 집중도를 의미한다.모듈의 "결합도"란 다른 모듈간의 상호 의존성을 의미한다. 즉, 좋은 모듈이란 응집도는 높고 결합도는 낮아야 한다. 이번 포스팅에선 모듈간의 느슨한 결합..
[Design Pattern] DI(Dependency Injection)
2023. 5. 8. 01:10
iOS/Pattern
"의존성 주입"이란, 객체가 의존관계에 있을 때 "직접 생성"하는 것이 아닌, DIP를 적용하여 "외부에서 제공"받는 패턴을 말한다. 한 번에 이해하기 어려우니 천천히 알아보자. Dependency 대부분의 프로그램에서 여러 객체들은 협력하게 되기 때문에, 객체 사이의 의존성은 존재하게 된다. 예를 들어, User의 정보를 Networking을 통해 가져와 이를 화면에 출력시키는 객체가 있다 하자. class UserRepository { func fetchUser() -> User { ... return User(name: "Jung", id: "111") } } class UsersPresentation { private let usersRepository = UserRepository() func ..
[iOS] Modularization(1) - Library, Framework, Swift Package
2023. 5. 4. 01:55
iOS/iOS
Xcode에서 Project를 생성하면, 하나의 App Target이 자동으로 생성된다. 이때의 App Target은 하나의 Module이 된다. 별도의 Framework를 추가하지 않는 이상,모든 코드는 Single Target에 추가되게 된다. 위와 같이 하나의 Module로 이루어진 App을 "Monolitic App"이라 부른다. 이러한 Monolitic App은 여러 가지 단점을 가지고 있다.하나의 모듈에 모든 소스코드가 들어있기 때문에 internal과 public을 구분할 수 없다. 이로 인해, 객체들은 무분별하게 참조될 가능성이 있으며, 이는 코드 변경의 영향 범위를 파악하기 어려워진다. 또한, 특정 기능만 테스트하고 싶다 해도 Project내의 모든 소스코드를 빌드해야 한다. App의..
[Architecture Pattern] MVP
2023. 3. 24. 23:20
iOS/Pattern
iOS에서 MVC패턴은 Controller를 담당하는 UIViewController가 View와의 연결성이 너무 강하다는 단점이 존재하였다. 따라서, Controller는 Controller의 역할만이 아닌, View의 Life Cycle관련, 레이아웃 관련 등등 너무나 많은 역할을 담당하게 된다. 이는, Controller의 코드가 많아지는 것과 Unit Test를 진행하기 어렵다는 단점으로 이어졌다. MVP Architecture Pattern MVP 패턴은 Model-View-Presenter의 약자이다. 기존 MVC패턴에선, Controller 역할을 UIViewController가 담당했다. 이는 View와 너무 밀접하게 연관이 있어 Controller의 부담이 늘어나는 결과로 이어졌다. 이를 ..
[Architecture Pattern] MVC
2023. 3. 22. 11:21
iOS/Pattern
아키텍쳐 패턴의 핵심은 "관심사의 분리(SoC)"이다. "관심사의 분리"에 대해 잘 이해가 가지 않는다면 해당 포스팅을 참고 바란다. [Architecture Pattern] SoftWare Architecture 아키텍처(Architecture)란 위키피디아에 따르면 "소프트웨어의 구성요소들 사이에서 유기적 관계를 표현하고 소프트웨어의 설계와 업그레이드를 통제하는 지침과 원칙"을 의미한다. 말이 어렵지만 seokyoungg.tistory.com UI Logic과 Buiness Logic은 특성도 다르고 UI Logic의 경우 자주 바뀌기 때문에 변경 주기도 다르다. 따라서, UI Logic과 Business Logic을 분리하기 위함이 MVC 패턴의 탄생 배경이다. MVC Architecture Pat..
[iOS] 동시성 프로그래밍(12) - Actors
2023. 2. 22. 18:23
iOS/iOS
Data Race는 shared mutable data에 대해 여러 Thread에서 동시에 접근하여 발생한다. 동시성 환경에서 자주 발생하는 문제 중 하나이지만, Debug 하기는 어렵다. class Counter { var value = 0 func increment() -> Int { value += 1 return value } } let counter = Counter() Task.detached { print(counter.increment()) } Task.detached { print(counter.increment()) } 해당 코드에서, counter의 0인 상태에 동시에 접근하게 되어 둘 다 1의 결과가 출력될 수도, value += 1 코드에 동시에 접근하게 되어 둘 다 2의 결과가 ..
[iOS] 동시성 프로그래밍(11) - Unstructured Concurrency
2023. 2. 22. 18:15
iOS/iOS
저번 포스팅에서 살펴보았던 Structured Concurrency는 Task는 부모 - 자식 관계를 통해 계층구조로 이루어져 있다. 하지만, 특정 Task에는 structured pattern이 없는 경우가 있다. 대표적인 예로, 동기 context에서 실행되는 비동기 작업들은 Parent Task가 존재하지 않는다. 이러한 경우에 Swift에서는 Unstructured Concurrency를 제공한다. Unstructured Concurrency Unstructured Task들은 life time이 그들의 scop보다 오래 존재할 수 있다. 이미지를 다운로드 Task가 있고, 이 Task를 중간에 cancel 시켜 다운로드를 취소시킬 수 있는 기능을 제공할 수 있다. 또한, Parent Task가 ..
[iOS] 동시성 프로그래밍(10) - Structured Concurrency
2023. 2. 16. 17:35
iOS/iOS
Structured Concurrency(구조화된 동시성)란 Structured Programming에 기반을 둔 개념이다. Structured Programming은 procedual하게 읽을 수 있고, 해당 코드의 output을 예측할 수 있는 프로그래밍을 의미한다. 앞선 포스팅에서 살펴본, async & await는 비동기 작업에 대해 Structured Programming이 가능하도록 지원해 주었다. 하지만 저번 포스팅에서 알아본 async & await로 구현한 코드는 단순 비동기이지, parallel한 실행은 할 수 없었다. func fetchOneThumbnail(withID id: String) async throws -> UIImage { let imageReq = imageReques..
[iOS] 동시성 프로그래밍(9) - async, await
2023. 2. 12. 23:26
iOS/iOS
async와 await는 Swift5.5에서 추가된 Concurrency Model로 더 safe, easy, fast 하게 다루기 위해 나온 기능이다. call-back기반의 비동기 함수의 문제점 기존의 비동기 작업이 끝나는 시점을 completion handler를 통해 알 수 있었는데, 이는 procedual(절차적인) 코드가 아니게 되기에 읽기 어려운 부분이 있다. 썸네일을 가져오는 fetchThumbnail 함수가 있다고 정의해 보자. fetchThumbnail 함수 내부에서 위와 같은 작업들이 진행된다. 이 중, dataTask와 preapreThumbnail은 오래 걸리는 작업이기에 비동기 작업으로 진행되어야 한다. 또한, dataTask의 return 값이 이후의 과정에서 쓰이기 때문에, ..
[iOS] Layout(2) - Auto Layout
2023. 2. 2. 02:57
iOS/iOS
view를 화면에 배치하기 위해서는 다음과 같은 정보가 필요하다. size (width, height) location (x, y) Frame-based Layout은 frame을 통해 이러한 정보(size, location)들을 value로 직접 지정한다. 이는 원하는 위치에 설정하면 되기에 유연하며 성능이 빠르다는 장점이 있었지만, Externel changes(외부 변화) 혹은 Internal changes(내부 변화)가 발생하면 개발자가 직접 관리해주어야 한다. External changes란 superview의 size나 shape이 변경될 때 발생한다. 디바이스 회전, 다른 크기의 스크린 지원과 같은 예시가 있다. Internal changes란 UI변경으로 인해 view의 size가 변경될 ..
[iOS] Layout(1) - Frame-Based Layout
2023. 1. 21. 23:02
iOS/iOS
"Frame-Based Layout"은 Programmatically하게 view들의 frame을 지정해주는 방식이다. Frame "Frame Rectangle"은 superView로부터 view의 location과 size를 정의한다. var frame: CGRect { get set } frame은 CGRect 타입의 변수인데, CGRect은 location을 저장할 수 있는 origin프로퍼티와 size를 정의할 수 있는 size 프로퍼티가 존재한다. public struct CGRect { public init() public init(origin: CGPoint, size: CGSize) public var origin: CGPoint public var size: CGSize } 이때 정의한 ..
[Swift] Properties(2) - Wrappers, Type
2023. 1. 18. 23:40
iOS/Swift
Property Wrapper Property Wrapper는 프로퍼티가 저장되는 방식을 관리하는 코드와 프로퍼티가 정의되는 코드 사이에 분리된 계층을 추가해 준다. 즉, 도형의 각 변의 최대 길이를 정하고 싶다고 가정해 보자. 그렇다면 코드는 아래와 같이 구현해야 한다. class Rectangular { private var _width: Int = 10 private var _height: Int = 15 private var maxLegth: Int = 30 var width: Int { get { return _width } set { _width = min(maxLegth, _width) } // 저장하는 방식을 관리하는 코드 } var height: Int { get { return _hei..