Remote 저장소를 local 저장소로 강제화(?) 시켜주고 싶을 때 다음 명령어를 사용합니다 저는 소스트리에서 reset 명령어로 local 저장소를 원하는 커밋까지 초기화시켜준후 이 명렁어를 통해 remote저장소도 local 저장소와 같아지게끔 강제 푸쉬시켰습니다 (협업하는 경우, 굉장히 위험한 명령어가 될 수 있습니다. 저는 예제용 개인프로젝트라서 진행해줬습니다) 참고 https://www.christianengvall.se/git-reset-origin-master-to-commit/ https://velog.io/@leehaeun0/실무에서-유용했던-git-명령어-4w0oxm3e
viewController가 deinit 될때, 그 안의 Pulisher가 auto-cancel 되는지 실험해봅시다 --! 5초 후에 이벤트를 발행하는 Publisher와 3초 후에 deinit되는 viewController가 있습니다 1) stream을 안담아줄 때 viewController가 deinit되어도 스트림이 살아있습니다 2) stream을 Cancellable에 담아줄 때 viewController가 deinit되어도 여전히 스트림이 살아있습니다 3) stream을 Cancellable에 담아주고 deinit 때 cancel 시켜줄 때 이렇게 deinit 될때 cancel시키는 코드를 넣어줘야지 스트림이 같이 끝납니다 4) stream을 AnyCancellable에 담아줄 때 AnyCanc..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/dHvNm7/btqwooYrxwK/fCkneGkJkjsvfS0c7jGb30/img.png)
이 포스팅을 이해하려면 RxSwift vs Combine - 스펙 / 성능 / 개념 비교를 읽고 오세요 ☺️ Rxcocoa(for UIKit) + RxSwift 로 짰던 코드를 -> UIKit + Combine -> SwiftUI + Combine 이렇게 두 가지 버전으로 바꿔보았습니다 :) 우선 Model/ViewModel 쪽 코드는 큰 차이가 없었습니다 APIManager 안에 있는 fetch 함수를 예로 봅시다 (isbn number를 받아서 책정보를 주는 함수입니다) Observalbe을 AnyPulisher로 바꾸면 끝입니다 그 다음 APIMananger의 fetch 함수를 부르는 ViewModel 쪽 코드를 봅시다 여기도 subscribe를 sink로 바꿔주면 끝입니다 하지만 UIBinding..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/EXqwN/btqwpnRLJJJ/LdQrlbCxE2Gj2N7eBGMd11/img.png)
WWDC 2019에서 Combine이 발표되었다. Combine은 Rx와 똑같다! 라고 말하던데 정말 똑같을까..? 🤔 Rx와 Combine을 비교해보자 1. 스펙 비교 Rx와 Combine은 모두 Reactive 프로그래밍을 위한 framework이다 하지만 Rx는 iOS 8이상부터, Combine은 iOS 13이상부터 사용할 수 있다 (그래서 Combine을 실제 프로덕트에서 쓰기까지는 최소 1년에서 최대 3년까지 걸릴 것이라고 말한다) Rx는 Third party framework인 반면 Combine은 애플에서 만든 buit-in framework이다...! 그리고 Rx는 Rxcocoa와 Combine은 SwiftUI와 UIBinding을 하도록 설계되어졌다 (하지만 Combine은 SwitUI와..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/YdRfy/btqvWSZtkhv/cyVJEt7lNrF6gauBrMbqsK/img.png)
로그인도 Auth의 signIn 함수면 간단히 끝 -! FirebaseManager에 다음메소드를 추가하고 class func login(email: String, password: String, completion: @escaping (Result) -> Void) { Auth.auth().signIn(withEmail: email, password: password) { (result, error) in if let result = result { completion(.success(result)) } else if let error = error { completion(.failure(error)) } } } LoginViewModel도 구현해준다 struct LoginViewModel { stru..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/bbp6gk/btqvZih3ciV/zgAMYky6BpmSxnbkU11A8K/img.png)
회원가입은 Auth의 createUser라는 함수만 불러주면 쉽게 할 수 있다 FirebaseManager에 signup 메소드를 추가해준다 extension FirebaseManager { class func signup(email: String, password: String, completion: @escaping (Result) -> Void) { Auth.auth().createUser(withEmail: email, password: password) { (result, error) in if let result = result { completion(.success(result)) } else if let error = error { completion(.failure(error)) } } ..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/crZYmZ/btqvRHw07zu/nMMQNwLUW2UCcWZPrASwg1/img.png)
enum의 rawValue, CaseIterable 같은 여러 속성들을 다 사용하고 싶었으나, 안되는 case들이 있어서 정리를 해본다 1) CaseIterable 과 연관값(associated value) 를 함께 사용할 수 없다 이렇게 allCases 라는 변수를 직접 선언해주어야지 Test.allCases 로 사용할 수 있다 Enum입장에서는(?) 연관값이 있으면 연관값에 따라 여러 케이스들이 있다는 것이라서 개발자가 연관값과 함께 케이스로 해줄 것들을 알려달라고 하는 것이 자연스러운 것 같다 : ) 2) rawValue와 연관값(associated value) 를 함께 사용할 수 없다 이렇게 따로 rawValue라는 변수를 만들어주는 수 밖에 없다 ㅠ.ㅠ
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/FHFmP/btqvFXfUAgo/TYpw03wZp2b6davh3epRUK/img.png)
firebase-modify라는 feature브랜치를 만들어줍니다 프로젝트에서는 modify 대신 change라는 용어를 사용하고 있는데, change라는 네이밍을 사용하여 코딩해주겠습니다 FirebaseManager에 change함수를 추가해줍니다 수정할 메모의 키값과 새로운 메모를 받는 함수입니다 class func change(key: String, to memo: Memo) { let rootRef = Database.database().reference() let memoRef = rootRef.child("memos").child(key) memoRef.setValue(memo.toDictionary()) } 수정을 누르면 이렇게 AlertViewController가 떠야하므로 textfiel..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/bSWzMg/btqvDjCo4i4/KCmL3qGxEkJE9oRs74A9Bk/img.png)
firebase-delete라는 feature 브랜치를 하나 만들어줍니다 FirebaseManager 안에 delete라는 class fucntion을 만듭니다 class func delete(key: String) { let rootRef = Database.database().reference() let memoRef = rootRef.child("memos").child(key) memoRef.removeValue() } delete하려면 각 데이터(메모)의 key 값을 알고 있어야합니다 현재는 Memo를 Firebase에 추가할 때 firebase가 자동으로 key값(혹은 아이디 값) 을 만들어주게 설정되어있습니다 class func add(memo: Memo) { let rootRef = Dat..
- Total
- Today
- Yesterday
- ipad multitasking
- cocoapod
- flutter dynamic link
- 구글 Geocoding API
- Watch App for iOS App vs Watch App
- github actions
- Python Type Hint
- METAL
- SerializerMethodField
- Django Heroku Scheduler
- flutter 앱 출시
- DRF APIException
- Flutter 로딩
- Django FCM
- Flutter Clipboard
- Django Firebase Cloud Messaging
- drf custom error
- PencilKit
- flutter deep link
- ribs
- flutter build mode
- Sketch 누끼
- 장고 URL querystring
- 플러터 싱글톤
- 장고 Custom Management Command
- Flutter getter setter
- Flutter Spacer
- 플러터 얼럿
- Flutter Text Gradient
- Dart Factory
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |