분류 전체보기
-
* Presentation Layer만을 다루는 아키텍쳐 패턴들- MVC/MVP/MVVM- ReactorKit = UIKit + 상태지향- TCA = SwiftUI + 상태지향 * 앱의 전반적인 부분을 다루는 아키텍쳐- Clean Architecture
MVVM, ReactorKit, TCA, Clean Architecture(작성중)* Presentation Layer만을 다루는 아키텍쳐 패턴들- MVC/MVP/MVVM- ReactorKit = UIKit + 상태지향- TCA = SwiftUI + 상태지향 * 앱의 전반적인 부분을 다루는 아키텍쳐- Clean Architecture
2024.06.13 -
https://showcove.medium.com/library-framework-%EA%B7%B8%EB%A6%AC%EA%B3%A0-xcframework-15387031964b Library, Framework 그리고 XCFrameworkLibrary, Framework, XCFramework 각각의 차이점에 대해 알아보자.showcove.medium.comhttps://tech.kakao.com/posts/521 Swift Package Manager 적용기 - tech.kakao.com안녕하세요! 카페앱개발파트에서 iOS 개발을 하고 있는 셀린(Celine.jin)...tech.kakao.comhttps://dev.gmarket.com/53 iOS Framework 에서 다른 Framework 사용시..
[스크랩] Framework, Library, ...https://showcove.medium.com/library-framework-%EA%B7%B8%EB%A6%AC%EA%B3%A0-xcframework-15387031964b Library, Framework 그리고 XCFrameworkLibrary, Framework, XCFramework 각각의 차이점에 대해 알아보자.showcove.medium.comhttps://tech.kakao.com/posts/521 Swift Package Manager 적용기 - tech.kakao.com안녕하세요! 카페앱개발파트에서 iOS 개발을 하고 있는 셀린(Celine.jin)...tech.kakao.comhttps://dev.gmarket.com/53 iOS Framework 에서 다른 Framework 사용시..
2024.06.13 -
https://velog.io/@ictechgy/SwiftUI%EC%9D%98-View-%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%80-%EC%96%B8%EC%A0%9C-%EC%9D%B4%EB%A3%A8%EC%96%B4%EC%A7%80%EB%8A%94%EA%B0%80
[스크랩] SwiftUI의 View 렌더링은 언제 이루어지는가?https://velog.io/@ictechgy/SwiftUI%EC%9D%98-View-%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%80-%EC%96%B8%EC%A0%9C-%EC%9D%B4%EB%A3%A8%EC%96%B4%EC%A7%80%EB%8A%94%EA%B0%80
2024.04.19 -
https://garrettjavalia.github.io/posts/2023-06-26-beejs-guide-to-network-programming/
[스크랩] Beej’s Guide to Network Programming(소켓 프로그래밍 가이드) 한국어판https://garrettjavalia.github.io/posts/2023-06-26-beejs-guide-to-network-programming/
2024.04.16 -
많은 사람들이 싱글턴은 안티 패턴이라는 얘기를 한다. 그 이유로 가장 많이 이야기하는 것이 testability이다. 맞는 말이다. 싱글턴 객체는 스터빙할 수 없기 때문에 테스팅을 어렵게 만든다. 최근 TDD와 Unit 테스팅을 강조하는 개발 조직이 많아졌기 때문에 이 부분이 가장 크게 두각되는 것 같다. 하지만 Unit 테스팅을 하지 않는다면? 그리고 또 많이 이야기하는 부분이 SOLID 원칙을 위반한다는 이야기다. 이 역시 맞는 말이다. 하지만 so what? 그게 실제로 어떤 문제를 발생시킨다는 건가? 또 상속을 할 수 없다는 이야기도 한다. 하지만 굳이 상속을 할 필요가 없다면? Unit 테스트를 작성하지도 않고 SOLID 원칙도 무시하며 상속도 굳이 사용할 필요가 없는 경우라면 싱글턴을 쓰지 말..
싱글턴의 진짜 문제점많은 사람들이 싱글턴은 안티 패턴이라는 얘기를 한다. 그 이유로 가장 많이 이야기하는 것이 testability이다. 맞는 말이다. 싱글턴 객체는 스터빙할 수 없기 때문에 테스팅을 어렵게 만든다. 최근 TDD와 Unit 테스팅을 강조하는 개발 조직이 많아졌기 때문에 이 부분이 가장 크게 두각되는 것 같다. 하지만 Unit 테스팅을 하지 않는다면? 그리고 또 많이 이야기하는 부분이 SOLID 원칙을 위반한다는 이야기다. 이 역시 맞는 말이다. 하지만 so what? 그게 실제로 어떤 문제를 발생시킨다는 건가? 또 상속을 할 수 없다는 이야기도 한다. 하지만 굳이 상속을 할 필요가 없다면? Unit 테스트를 작성하지도 않고 SOLID 원칙도 무시하며 상속도 굳이 사용할 필요가 없는 경우라면 싱글턴을 쓰지 말..
2024.01.30 -
지난 3년 여 간의 경험을 토대로 두 가지 개념에 대해 정리를 해보고자 한다. MVVM 먼저 한동안 모바일 애플리케이션 아키텍쳐에 큰 바람을 일으켰던 MVVM부터 리뷰를 해보자면 View를 사용자의 action을 입력받으면 ViewModel로 전달되고 ViewModel은 Model에 변경사항을 저장한다. 그러면 Model에 생긴 변화는 다시 ViewModel에게 전달되어 ViewModel의 state에 변화를 일으키고 이에 바인딩되어 있는 View가 다시 렌더링되어 사용자에게 보여진다. ViewModel이 Model에 데이터를 저장하고 변경된 데이터를 받아오는 과정은 데이터가 실제 물리적으로 어디에 저장되는지를 감추는 Repository라는 추상화된 데이터 저장소 객체를 사용하는 경우가 최근 일반화되고 ..
MVVM과 Clean Architecture지난 3년 여 간의 경험을 토대로 두 가지 개념에 대해 정리를 해보고자 한다. MVVM 먼저 한동안 모바일 애플리케이션 아키텍쳐에 큰 바람을 일으켰던 MVVM부터 리뷰를 해보자면 View를 사용자의 action을 입력받으면 ViewModel로 전달되고 ViewModel은 Model에 변경사항을 저장한다. 그러면 Model에 생긴 변화는 다시 ViewModel에게 전달되어 ViewModel의 state에 변화를 일으키고 이에 바인딩되어 있는 View가 다시 렌더링되어 사용자에게 보여진다. ViewModel이 Model에 데이터를 저장하고 변경된 데이터를 받아오는 과정은 데이터가 실제 물리적으로 어디에 저장되는지를 감추는 Repository라는 추상화된 데이터 저장소 객체를 사용하는 경우가 최근 일반화되고 ..
2023.12.05 -
그동안 수없이 사용했던 캡쳐리스트에 대해 오해하고 있었던 것 같아서 다시 정리한다.클로져를 사용할 때 같은 컨텍스트에 있는 변수들을 캡쳐리스트 없이 사용하게 되면 reference type이든, value type이든 무조건 reference로 캡쳐된다.캡쳐리스트를 사용하면 value type은 클로져 생성 시의 값을 그대로 복사하여 value를 캡쳐할 수 있다.단 reference type은 캡쳐 리스트를 사용해도 reference로 캡쳐가 되기 때문에 weak, unowned 를 사용하여 retain cycle을 피할 수 있도록 해야 한다. 명시하지 않으면 strong 캡쳐가 기본이다.(Edit)value type은 캡처리스트 없이 캡쳐해도 값 그대로 복사되는 것 같은데?이거 검증이 좀 필요한 것 같..
캡쳐리스트그동안 수없이 사용했던 캡쳐리스트에 대해 오해하고 있었던 것 같아서 다시 정리한다.클로져를 사용할 때 같은 컨텍스트에 있는 변수들을 캡쳐리스트 없이 사용하게 되면 reference type이든, value type이든 무조건 reference로 캡쳐된다.캡쳐리스트를 사용하면 value type은 클로져 생성 시의 값을 그대로 복사하여 value를 캡쳐할 수 있다.단 reference type은 캡쳐 리스트를 사용해도 reference로 캡쳐가 되기 때문에 weak, unowned 를 사용하여 retain cycle을 피할 수 있도록 해야 한다. 명시하지 않으면 strong 캡쳐가 기본이다.(Edit)value type은 캡처리스트 없이 캡쳐해도 값 그대로 복사되는 것 같은데?이거 검증이 좀 필요한 것 같..
2023.11.17 -
코로나 시대에 음성채팅이 새로운 커뮤니케이션으로 주목받았던 때가 잠깐! 있었다. 그때가 기업용 메신저를 개발하고 있었을 때였는데 음성채팅 기능을 2~3개월 안에 급하게 추가해달라는 요구사항이 내리 꽂혔다. 갑자기 모든 과제가 밀리면서 음성채팅 과제가 가장 중요한 몇개의 과제 중 하나로 떠올랐고 모든 리더들이 달려들어 회의를 하기 시작했다. 당시 일부 가입, 로그인 페이지를 제외하고는 앱의 대부분의 코드는 네이티브였고 웹페이지와의 인터페이스도 웹에서의 리다이렉션 URL의 파라미터를 통해 몇몇 정보들을 받아오는 정도가 전부였다. 그런데 과제가 꾸려지면 기본적으로 iOS, Android, Windows, MacOS 4종 클라이언트 개발자를 비롯해서 REST API 서버팀, 기획, 디자인과 협업이 필요한데, 음..
주도적으로 의견을 내며 리딩했던 경험코로나 시대에 음성채팅이 새로운 커뮤니케이션으로 주목받았던 때가 잠깐! 있었다. 그때가 기업용 메신저를 개발하고 있었을 때였는데 음성채팅 기능을 2~3개월 안에 급하게 추가해달라는 요구사항이 내리 꽂혔다. 갑자기 모든 과제가 밀리면서 음성채팅 과제가 가장 중요한 몇개의 과제 중 하나로 떠올랐고 모든 리더들이 달려들어 회의를 하기 시작했다. 당시 일부 가입, 로그인 페이지를 제외하고는 앱의 대부분의 코드는 네이티브였고 웹페이지와의 인터페이스도 웹에서의 리다이렉션 URL의 파라미터를 통해 몇몇 정보들을 받아오는 정도가 전부였다. 그런데 과제가 꾸려지면 기본적으로 iOS, Android, Windows, MacOS 4종 클라이언트 개발자를 비롯해서 REST API 서버팀, 기획, 디자인과 협업이 필요한데, 음..
2023.11.17 -
이는 기업용 메신저 개발 당시 자주 겪던 문제 중의 하나인데 맥북을 사용하는 사람이라면 잘 알겠지만 맥북을 덮으면 기본적으로(별다른 설정이나 특별한 앱을 설치해두지 않았다면) 슬립상태가 되고 다시 열면 깨어나는데 이 때 네트워크 환경 등의 문제로 앱이 깨어났지만 미묘한 타이밍 문제로 네트워크를 사용할 수 없는 상태인 경우가 자주 발생했었다. 메신저 특성상 소켓 통신을 사용하고 있었기 때문에 슬립모드에서는 소켓을 끊고 깨어나면 소켓을 다시 연결해주어야 했는데 소켓을 연결할 때는 서버에서 발급한 엑세스 토큰을 사용하고 있었고 운 나쁘게도 슬립에서 돌아올 때 이 토큰이 만료되어 있는 경우에는 토큰을 갱신한 다음 다시 소켓을 연결하도록 되어 있었다. 슬립모드에서 깨어남 -> 소켓 재연결 시도 -> 토큰 만료 -..
macOS 슬립모드에서 돌아올 때 소켓 연결 복원이 되지 않는 문제이는 기업용 메신저 개발 당시 자주 겪던 문제 중의 하나인데 맥북을 사용하는 사람이라면 잘 알겠지만 맥북을 덮으면 기본적으로(별다른 설정이나 특별한 앱을 설치해두지 않았다면) 슬립상태가 되고 다시 열면 깨어나는데 이 때 네트워크 환경 등의 문제로 앱이 깨어났지만 미묘한 타이밍 문제로 네트워크를 사용할 수 없는 상태인 경우가 자주 발생했었다. 메신저 특성상 소켓 통신을 사용하고 있었기 때문에 슬립모드에서는 소켓을 끊고 깨어나면 소켓을 다시 연결해주어야 했는데 소켓을 연결할 때는 서버에서 발급한 엑세스 토큰을 사용하고 있었고 운 나쁘게도 슬립에서 돌아올 때 이 토큰이 만료되어 있는 경우에는 토큰을 갱신한 다음 다시 소켓을 연결하도록 되어 있었다. 슬립모드에서 깨어남 -> 소켓 재연결 시도 -> 토큰 만료 -..
2023.11.16 -
이미 다 아시는 내용일 수도 있지만... Rx를 많이 쓰다보면 아래와 같은 크래시 로그를 마주하는 것이 낯설지 않죠.. 그런데 QA나 CS로 들어오는 크래시 로그는 위의 경우 처럼 정작 애플리케이션 코드(위에서는 UseCase라고 되어 있는 부분)의 콜스택은 symbolification되어 있지 않은 경우가 많습니다. 이 경우에 RxSwift 콜스택을 이용하면 의외로 쉽게 문제가 된 지점을 찾아낼 수 있습니다. 위의 콜스택에서 protocol witness for ObserverType.on(_:) in conformance XXXSink 라고 되어있는 콜스택은 Rx의 XXX 오퍼레이터를 사용한 부분이라고 볼 수 있고 따라서 이 경우는 다음과 같은 순서로 Rx 오퍼레이터가 사용된 곳이라고 볼 수 있습니다..
[Tip] RxSwift 콜스택만 잔뜩있는 크래시 로그로 디버깅하기이미 다 아시는 내용일 수도 있지만... Rx를 많이 쓰다보면 아래와 같은 크래시 로그를 마주하는 것이 낯설지 않죠.. 그런데 QA나 CS로 들어오는 크래시 로그는 위의 경우 처럼 정작 애플리케이션 코드(위에서는 UseCase라고 되어 있는 부분)의 콜스택은 symbolification되어 있지 않은 경우가 많습니다. 이 경우에 RxSwift 콜스택을 이용하면 의외로 쉽게 문제가 된 지점을 찾아낼 수 있습니다. 위의 콜스택에서 protocol witness for ObserverType.on(_:) in conformance XXXSink 라고 되어있는 콜스택은 Rx의 XXX 오퍼레이터를 사용한 부분이라고 볼 수 있고 따라서 이 경우는 다음과 같은 순서로 Rx 오퍼레이터가 사용된 곳이라고 볼 수 있습니다..
2023.11.16 -
Swift /** https://www.acmicpc.net/problem/1260 문제 그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다. 입력 첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다. 출력 첫째 줄에 DFS를 수행한 결과를, 그 다음 줄..
DFS와 BFSSwift /** https://www.acmicpc.net/problem/1260 문제 그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다. 입력 첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다. 출력 첫째 줄에 DFS를 수행한 결과를, 그 다음 줄..
2023.11.09 -
Swift import Foundation extension Array where Element: Comparable { private mutating func partition(_ left: Int, _ right: Int) -> Int { var low = left var high = right + 1 let pivot = self[left] print("partition(\(left), \(right))") repeat { repeat { low += 1 } while low = left && self[high] > pivot print("low: \(low), high: \(high)") if low < high { swapAt(low, high) print("swapAt(\(low), \(hig..
퀵소트Swift import Foundation extension Array where Element: Comparable { private mutating func partition(_ left: Int, _ right: Int) -> Int { var low = left var high = right + 1 let pivot = self[left] print("partition(\(left), \(right))") repeat { repeat { low += 1 } while low = left && self[high] > pivot print("low: \(low), high: \(high)") if low < high { swapAt(low, high) print("swapAt(\(low), \(hig..
2023.08.03