⭐️ 개발
![[Rx] NSObject+Rx 라이브러리](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F08FJ6%2FbtrWCzF52IC%2Fotgke3EcRF32XEwZlHSfN1%2Fimg.png)
[Rx] NSObject+Rx 라이브러리
disposeBag 속성을 자동으로 추가해 주는 라이브러리 let bag = DisposeBag() 이 코드를 안써도 된다 이거지!! https://github.com/RxSwiftCommunity/NSObject-Rx GitHub - RxSwiftCommunity/NSObject-Rx: Handy RxSwift extensions on NSObject, including rx.disposeBag. Handy RxSwift extensions on NSObject, including rx.disposeBag. - GitHub - RxSwiftCommunity/NSObject-Rx: Handy RxSwift extensions on NSObject, including rx.disposeBag. github..
![[Rx Operator 시리즈] 3. Zip](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI8YtK%2FbtrWpYZWAHm%2FGSAqEHXuMD0guawN0aYGJ1%2Fimg.jpg)
[Rx Operator 시리즈] 3. Zip
combineLatest와 다른 점? : 클로저에게 중복된 요소를 전달하지 않고, 인덱스를 기준으로 짝을 맞춰서 전달. 첫 번째 요소는 첫 번째 요소와 결합 두 번째 요소는 두 번째 요소와 결합 세 번째 요소는 세 번재 요소와 결합 Indexed Sequencing이라고 함 결합할 요소가 없으면 방출하지 않음 let numbers = PublishSubject() let strings = PublishSubject() Observable.zip(numbers, strings) { "\($0) - \($1)" } .subscribe { print($0) } .disposed(by: disposeBag) numbers.onNext(1) strings.onNext("One") // next(1 - One) n..
![[Rx Operator 시리즈] 2. CombineLatest](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FslfOq%2FbtrWqqooj1I%2F8qWRolZTCaA3Nt9CJ01Tp1%2Fimg.jpg)
[Rx Operator 시리즈] 2. CombineLatest
소스 옵저버블이 방출하는 최신 요소를 병합하는 combineLatest 연산자 소스 옵저버블들을 결합해 방출하는 최신 이벤트를 대상으로 연산자를 실행해 결과 옵저버블을 방출 enum MyError: Error { case error } let greetings = PublishSubject() let languages = PublishSubject() Observable .combineLatest(greetings, languages) { first, second -> String in return "\(first) \(second)" } .subscribe { print($0) } .disposed(by: disposeBag) greetings.onNext("Hi") languages.onNext("R..
[Rx Operator 시리즈] 1. map
map은 옵저버블이 배출하는 항목을 대상으로 함수를 실행하고 결과를 방출 map 연산자는 옵저버블이 방출하는 요소들을 대상으로 클로저를 실행하고 그 결과를 구독자에게 전달한다. 클로저 내에서 원하는 형식으로 바꿔서 리턴해 전달이 가능하다. let skills = ["Swift", "SwiftUI", "RxSwift"] Observable.from(skills) .map { $0.count } .subscribe { print($0) } .disposed(by: disposeBag) // 출력 next(5) next(7) next(7) let skills = ["Swift", "SwiftUI", "RxSwift"] Observable.from(skills) .map { "Hello, \($0)" } .su..
7. Traits - ControlProperty, ControlEvent, Driver
Traits은 UI에 특화된 옵저버블이다. 모든 작업은 Main Thread에서 작동해서 스케줄러를 지정할 필요가 없다. UI가 항상 올바른 Thread에서 동작하는 걸 보장한다. Traits을 구독하는 모든 구독자는 동일한 시퀀스를 구독한다. like share() Error Event를 전달하지 않는다. Traits의 종류로는 ControlProperty, ControlEvent, Driver, Signal이 있다. 이게 종류가 많은데 언제 뭘 쓰는지, 어떻게 적용해야 하는지가 어렵다. 어렵냐? 나도 어렵다. 이 글에서는 ControlProperty와 ControlEvent에 대해서 자세히 작성해보겠당.. Driver와 Signal은 나도 어렵당.. 1. ControlProperty ControlPr..
![6. Binder](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsl7pR%2FbtrWq2nm4jV%2FS0J32hl2KDkwro5Db4cc5K%2Fimg.png)
6. Binder
Binder 바인딩에는 데이터 생산자(Producer)와 데이터 소비자(Consumer)가 있다. - 생산자는 옵저버블이다. Observable 타입 전부가 다 생산자 - 소비자는 Label, ImageView, UIView 같은 UI Component 생산자가 생산한 데이터는 소비자에게 전달되어 데이터를 소비한다. 레이블은 전달 받은 텍스트를 레이블에 표시한다. 반대의 경우는 없다. (소비자가 데이터를 생산하는 경우는 없다는 것) 이게 말로 표현해둬서 어려울 수 있는데 코드를 보면서 빗대어 보면 이해가 쉽다. 그래서 앞뒤 맥락없이 Binder의 개념에 대한 설명없이 갑자기 코드를 들이밀고 설명을 해보자면 inputField.rx.editingDidEnd .map { UIColor.gray } .bind..
![[Rx] Error Operator](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEHBtB%2FbtrWdeWUMsJ%2FPxLwaHiYCLOAXDmbr3LS10%2Fimg.png)
[Rx] Error Operator
Error Handling catch, catchAndReturn, retry 상황 : 옵저버블이 네트워크 요청을 처리하고, 구독자가 ui를 업데이트한다. 에러이벤트가 전달되면 구독이 종료돼서 ui를 업데이트 하는 코드가 실행되지 않음. Rx는 이 경우, 1. 첫 번째 방법으로, catch 연산자를 통해 next / completed event는 그대로 전달하지만error event가 전달되면 새로운 옵저버블로 바꿔서 전달한다. 특히, 네트워크 요청 코드에서 많이 사용한다. catch 연산자는 클로저를 파라미터로 받고, Error 이벤트는 클로저의 파라미터로 전달되고, 클로저는 새로운 Observable을 반환한다. catch 연산자는 클로저가 반환하는 Observable과 같은 Observable 값을..
![[Rx] Input/Output 패턴 적용하기 - 비즈니스 로직 분리!!](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGLfz9%2FbtrP9AcZowB%2FPKB4xHN0FbWJpVKxsY2RP1%2Fimg.png)
[Rx] Input/Output 패턴 적용하기 - 비즈니스 로직 분리!!
인풋, 아웃풋을 공부하면서 느낀 것은 완전 뇌절티비. 처음에 설명을 들으면서 그리고 후에 실습 코드를 따라치고, 내 과제에 적용하면서 구글링하며 머리에 껴넣으려고 했는데 도무지 이해가 안돼서 엉엉 울 뻔 하다가 같이 수업 듣는 수강생 두 분께 설명을 듣고 감이 왔다. 진쨔 감사합니다!!!!!!!!! 진심. 이거 이해하려는데 카페 노랫소리 왤케 시끄러; 집중 안돼서 다 뽀갤 뻔 했다.ㅠㅠ Input/Output 패턴을 통한 비즈니스 로직 구분짓기 여튼, Input/Output 패턴을 적용해주는 이유가 뷰컨에 있는 비즈니스 로직을 모두 뷰모델에서 처리해주기 위해서다. 내가 이해 안됐던 부분이 이 말을 듣고 이해가 됐다. 그니까, 자잘자잘한 비즈니스 로직까지도 모두 뷰모델에서 처리해주기 위해서 - 사용자의 입..
![[Rx] TIL - Rx 개념 재복습 및 총정리](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccM6hJ%2FbtrP0gS0hkm%2FyKKUgxldtTYcAIxzHJBcO0%2Fimg.png)
[Rx] TIL - Rx 개념 재복습 및 총정리
Swift는 didset을 통해 데이터가 단방향으로 구성되어서 흘러간다. MVC에서는 데이터가 이렇게 단방향으로 구성되는 것에 뷰와 컨트롤러가 붙어 있기에 didset으로 충분히 처리가 가능해 고려해주지 않아도 됐다. MVVM은 View와 Model 사이를 ViewModel을 통해서 양방향 바인딩이 가능하다. 클로저 구문을 통해서 바인드 메소드를 사용했다. RxSwift는 이 양방향 바인딩을 도와주는 연산자가 들어있어 더 쉽게 처리가 가능하다. RxSwift 항상 옵저버블이 존재한다. - Observable : 이벤트를 관찰하는 객체 : 사용자가 버튼을 누른다 -> 어떤 일이 일어나? - Observer : 다양한 로직이 발생하면 처리하는 객체 이 Observer는 처리해야 하는 event가 있고, 이 ..
![[Rx] Observable, Observer, Disposable, Subject, Relay](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FesThv6%2FbtrPEC9t3GW%2FhwageulwGom2bHbqJ0WBq0%2Fimg.png)
[Rx] Observable, Observer, Disposable, Subject, Relay
이번주부터 Rx에 대해 모든 정리는 내가 이해한대로 말하듯이 쓸 것임. 틀린 부분이 있으면 댓글로 알려주시술... Observer Pattern Rx에서 가장 중요한 용어는 Observable과 Observer가 아닌가 싶다. 옵저버블은 이벤트를 전달하는 아이고 (방출하는), 옵저버는 이벤트를 전달받는 아이이다. 이게 말로는 쉬운데 개념을 화면 UI에 적용시키면 처음에 이해가 안가서.. 내가 처음 이해한 방식으로 말하자면.. 음,, 예를 들어서, 왈에서 발바닥 버튼을 눌러서 왈소리 라벨이 보이면 여기서 발바닥 버튼이 옵저버블이고 왈소리 라벨이 옵저버이다. 왜냐면 버튼의 이벤트로 왈소리가 보이게 됐기 때문이다. 버튼 눌렀으니까 라벨 내용 보여줘 수업 들으면서 헷갈린 부분이 이 아래 예시에서 어디가 옵저버블..
![[Git] Git 명령어 모음](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLmscB%2FbtrOyh6Rnjt%2FzVN5qy9WZTd8LDupyC2tI1%2Fimg.png)
[Git] Git 명령어 모음
global : 전체 환경에 관해 설정이 됨 local : 그 프로젝트에 한해서만 환경이 설정됨 git config user.name "jack" git config user.email "jack@naver.com" 이렇게 해주면 특정 테스트 프로젝트에 한해서는 사용자를 "jack"으로 간주하게 된다. 이게 왜 필요하냐.. 대략적으로 회사에서 회사컴으로 개인 프로젝트를 하고 싶은 경우에.. 분리해서 작업하고 싶을 때! local 설정으로 해주면 된다. Git에서는 커밋을 할 때 사용할 이름과 이메일을 지정할 수 있으며, 이 때 커밋에 기록된 이메일은 GitHub의 사용자를 연결할 때도 사용됩니다. git config --global init.defaultBranch "main" master 브랜치 네이밍..
![[Git] Shell명령어 모음](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF6x7a%2FbtrOxLmRIVw%2FXJiCKGY6Ht06yp78TRIE30%2Fimg.png)
[Git] Shell명령어 모음
CLI : Command Line Interface GUI : Graphical User Interface 절대경로 Absolute PATH ( / ) 시스템은 무조건적으로 절대 경로만 인식하게 되어 있어서 root 디렉토리를 기준으로 하는 경로를 인식하게 되어 있다. 시스템에 설치되어 있는 최상위 경로를 말한다. /Users/thisisme/Desktop ~ 이렇게 나는 시스템권한이 있어서 Users에 접근할 수 있는데 내 맥을 사용하는 일반 사용자는 Users에 접근할 수 없다. 상대경로 Relative PATH 내가 Desktop에 있는 상황이면 ~ 내가 thisisme에 있는 상황이면 ~ ... 과 같이 현재 내가 있는 위치 기준으로 상대경로가 결정된다. home Directory (~) 사용자가..
![[iOS] 20221012 TIL](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0bKbx%2FbtrOlDwsfvo%2F1TugQhjQhF3HWumpKKuh51%2Fimg.png)
[iOS] 20221012 TIL
오늘 TIL의 핵심은 결국 iOS에서는 APNs가 주체적으로 푸시를 담당하고 있다는 것. 우리가 파이어베이스를 쓰는 이유는 자체 서버를 사용해도 되는데 서버가 각 기기 별(애플/안드 등) 분기처리가 복잡함 파베가 알아서 분기처리를 해주기 때문에 보통 파베랑 같이 처리해주는 곳이 많음 출프에서는 어떤 유저가 어떤 토큰을 쓰는지 현재 모르는 상황이라 전체 메시지를 보낼 수만 있는 상황이다. 그럼에도 불구하고, 전체 유저에게 보내기에는 아쉬운데 약간의 구분을 하고 싶을 수 있을 때, 예를 들어, 투두를 100% 달성하는 유저한테 "할 일 왜 다 안하셨어요?"라고 보내면 안되잖아? 의미없는 푸시가 되버리는!! 그렇기 때문에 파베에서 약간의 대응을 할 수 있게끔 주제 단위로 보낼 수 있는 기능을 제공한다. 토픽 ..
![[iOS] Method Swizzling이 뭔가? (feat. 인스턴스/타입 메소드)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0oNnL%2FbtrOqMmhfKL%2FCwcSTTvmofsNwZvCHwFyo0%2Fimg.png)
[iOS] Method Swizzling이 뭔가? (feat. 인스턴스/타입 메소드)
Method Swizzling(메소드 재구성)이 뭘까? 기존 메소드의 기능을 런타임 때 원하는 메소드로 바꾸는 것 파베에서도 Method Swizzling으로 앱이 실행될 때 애플의 메소드를 살짝 탈취해서 APNs의 토큰과 파베의 토큰으로 매칭시켜서 구현하는 바이브로 처리한다고 한다. 또는 컨퍼런스에 들은 바로는 회사에서 사용되는 뷰컨과 스보가 너무 많아 지금 보고 있는 화면의 뷰컨의 이름을 알고 싶을 때 이 Method Swizzling을 통해서 뷰딛로드와 커스텀 메소드의 기능을 바꿔서 뷰컨의 이름을 찍는 방식으로 해결해줬다고 들었다. 구글링해보니까 메모리 누수를 체크하려고 뷰컨이 deinit 될 때 로그가 찍히도록 Method Swizzling을 사용해서 구현한 분도 계시네.. 만약 이 기법을 안사용..
![[iOS] Remote Notification](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FojoLs%2FbtrN5wdjI5g%2F8hg6W1hoGJRriSTNS9UKY1%2Fimg.png)
[iOS] Remote Notification
Remote Notification 1. APNs(애플 서버)한테 사용자(해당 기기)에게 identifier 같은 식별자를 제공해달라고 요청함 2. APNs 서버에 해당 기기를 등록해달라고 함 3. APNs 서버에서 푸쉬 받을 수 있게 식별자를 줌 (해당 식별자를 토큰이라고 함 - 쉽게 말해 기기 별로 민증번호를 발급함) 4. 발급 받은 민증번호(토큰)를 토대로 카톡 서버에 전달함 5. 그러면 Jack이 카톡 서버에 사용하는 id가 있겟지? 카톡 서버에서도 Jack이라는 유저에 해당하는 id와 매칭되는 민증번호가 있을 것임 만약 Jack이 Hue라는 유저에게 톡을 보내서 푸쉬를 보내고자 하면 6. 카톡 서버가 Hue라는 민증번호를 가진 사람한테 푸쉬를 보내라고 애플 서버한테 요청을 할 것임 좀 더 쉽게 ..