본문 바로가기

전체 글52

[RxDart] Stream과 RxDart: 유효성 검사 기능으로 비교해보기 RxDart는 Dart의 Stream API를 기반으로 설계되어 있다.RxDart의 Subject는 내부적으로 StreamController를 사용하고 있어RxDart를 사용하다보면 Stream 확장판 쓰는 느낌..기존 Stream API와 연계하여 사용하기 너무 편하고 StreamBuilder로 매끄럽게 UI 렌더링 로직으로 이어진다. Rx의 강력함을 설명할 겸, Stream과 RxDart의 미묘한 차이를 파악할 겸로그인 기능을 각각 Stream API와 RxDart로 구현해보면서 비교해보고자 한다.구현하고자 하는 기능은 간단하다. 아이디와 비밀번호를 입력 받고,각각의 유효성 검사를 진행하여 로그인 버튼을 활성화 여부를 결정하게 만드는 기능이다. 1. LoginBloc (기본 Stream 버전)impo.. 2024. 8. 22.
[Swift/Xcode] 하나의 빌드 설정에 여러 xconfig을 등록하는 방법 카카오 로그인을 구현하는 와중에 Native App Key, API key 등을 숨기고 싶어secret 키들을 담고 있는 xcconfig 를 따로 만들어 깃에 업로드되지 않도록 관리하고 싶었다. 문제는 debug, release 빌드 설정에 이미 CocoaPod에서 생성한 xcconfig 파일이 등록된 상태이 상황에서 두 xcconfig 을 하나의 빌드 설정에 모두 적용하고 싶었다.  #include#include 지시자를 사용하면 하나의 xcconfig 파일에서 다른 xcconfig 파일의 내용을 포함할 수 있다.#include "Pods/Target Support Files/Pods-walkbook/Pods-walkbook.debug.xcconfig"KAKAO_API_KEY = "APIKEY"  주의.. 2024. 7. 27.
[RxSwift] AsyncSubject AsyncSubject는 Observable이 emit한 마지막 값만 emit 하며 Observable이 complete된 후에만 emit 된다. 즉, onCompleted 를 기다렸다가 마지막에 emit 받은 값만 emit 한다.import RxSwiftlet disposeBag = DisposeBag()let asyncSubject1 = AsyncSubject()asyncSubject1.subscribe( onNext: { value in print("Value: \(value)") }, onError: { error in print("Error: \(error)") }, onCompleted: { print("Completed") .. 2024. 7. 26.
[Swift] 이미지 크기 Resize 방법 세 가지 1. UIGraphicsBeginImageContextWithOptionsextension UIImage { func resize(targetSize: CGSize) -> UIImage? { let size = self.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height let newSize = CGSize(width: size.width * min(widthRatio, heightRatio), height: size.height * min(widthRatio, hei.. 2024. 7. 20.
[Swift] Coordinator 패턴으로 화면 전환 +DIContainer(Swinject) 1. Coordinator 패턴의 목적구현 방식을 이야기하기 전에 Coordinator 패턴이 고안된 이유를 살펴보면ViewController(혹은 ViewModel)에서 화면 전환 로직을 포함한 다양한 로직들을 담게 되는 상황에서비대해진 ViewController 혹은 ViewModel에서 화면 전환 로직을 분리하자는 목적으로 고안되었다고 한다. 기존의 일반적인 방식대로면 ViewController 내부에서 직접 어떤 화면으로 어떻게 화면을 전환할 것인지 로직을 작성했다.하지만 이를 Coordinator라는 클래스에 따로 작성하여 ViewController 프로퍼티로 이 객체를 전달하여 화면 전환에 필요한 메서드만 호출하여 사용한다.이런 방식은 ViewController에서 다음 화면이 어떤 ViewC.. 2024. 7. 13.
[Swift] Dictionary(grouping:by:) https://developer.apple.com/documentation/swift/dictionary/init(grouping:by:) init(grouping:by:) | Apple Developer DocumentationCreates a new dictionary whose keys are the groupings returned by the given closure and whose values are arrays of the elements that returned each key.developer.apple.com 낯선 방식의 생성자이어서 기록해본다. let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]let studentsByLette.. 2024. 7. 12.
[Swift] KeyPath 이해하기 객체 속성에 접근할 때 타입 안전하게 접근하는 방법 : KeyPathSwift4에서 도입객체의 특정 속성에 대한 경로를 표현하는데 사용됨KeyPath를 통해 객체의 속성에 접근하면 컴파일 타임에 타입 체크가 이루어지기 때문에 안전한 코드 작성 가능KVO(Key-Value Observing)과 함께 사용되는 케이스가 있음struct Person { var name: String var age: Int}let nameKeyPath = \Person.namelet ageKeyPath = \Person.agelet person = Person(name: "John", age: 30)print(person[keyPath: nameKeyPath]) // "John"print(person[keyPath: .. 2024. 7. 11.
SwiftUI Tutorial 8 - Interfacing with UIKit 1. Create a view to represent a UIPageViewControllerUIViewControllerRepresentable 프로토콜을 준수하는 구조체를 만든다.UIViewControllerRepresentable이 요구하는 메서드를 구현한다.SwiftUI 는 뷰를 보여줄 준비가 되었을 때 makeUIViewController(context:)를 호출하고updateUIViewController는 해당 뷰 컨트롤러가 업데이트되어야 할 때마다 호출한다.import SwiftUIimport UIKitstruct PageViewController: UIViewControllerRepresentable { var pages: [Page] func makeUIViewControlle.. 2024. 7. 10.
SwiftUI Tutorial 7 - Composing complex interfaces 1. Add a category viewimport SwiftUIstruct CategoryHome: View { var body: some View { NavigationSplitView { Text("Hello, World!") .navigationTitle("Featured") } detail: { Text("Select a Landmark") } }} 2. Create a category listLandmark 구조체에 Category enum과 프로퍼티를 추가한다. struct Landmark: Hashable, Codable, Identifiable { var id: Int .. 2024. 7. 9.