Effective Swift本があるとしたなら、どんな目的で誰のための本?
- 何のため
- 言語の正しい理解と、簡潔で明瞭で正確なソフトウェアの設計に役立つ内容にしたい
- どうやる
- Effective〜な流儀に従って書籍スタイルは逆引きまとめスタイル
- 言語仕様が常に進化しているSwiftの動向をしっかり押さえながら、それらの最新の機能をどのように使うべきかについて実践的な観点から逆引きにしてその技法をまとめる
- 本当はどうあれば効果的?
| import Foundation | |
| import FirebaseRemoteConfig | |
| extension RemoteConfig { | |
| func addOnConfigUpdateListener() -> AsyncThrowingStream<Set<String>, Error> { | |
| .init { continuation in | |
| addOnConfigUpdateListener { configUpdate, error in | |
| if let error { | |
| continuation.finish(throwing: error) | |
| } else { |
| import FirebaseFirestore | |
| import FirebaseFirestoreSwift | |
| import Foundation | |
| // MARK: - CollectionReference | |
| public extension CollectionReference { | |
| @discardableResult | |
| func add<T: Encodable>( | |
| _ value: T, |
| import FirebaseFirestore | |
| // MARK: - async | |
| extension Query { | |
| func addSnapshotListener<T>( | |
| includeMetadataChanges: Bool = false | |
| ) -> AsyncThrowingStream<[T], Error> where T: Decodable{ | |
| .init { continuation in | |
| let listener = addSnapshotListener(includeMetadataChanges: includeMetadataChanges) { result in |
| import Foundation | |
| import ComposableArchitecture | |
| import FirebaseFirestore | |
| import FirebaseFirestoreSwift | |
| // MARK: - FirestoreClient | |
| struct FirestoreClient { | |
| enum Input { | |
| enum Create { |
| import ComposableArchitecture | |
| import FirebaseCore | |
| import FirebaseAuth | |
| import GoogleSignIn | |
| struct FirebaseAuthClient { | |
| var observeSignInState: () async -> AsyncStream<Bool> | |
| } | |
| extension FirebaseAuthClient { |
| import FirebaseFirestore | |
| @available(swift 5.0) | |
| public extension Query { | |
| func addSnapshotListener( | |
| includeMetadataChanges: Bool = false, | |
| listener: @escaping (Result<QuerySnapshot, Error>) -> () | |
| ) -> some ListenerRegistration { | |
| addSnapshotListener(includeMetadataChanges: includeMetadataChanges) { snapshot, error in | |
| if let error { |
| import Foundation | |
| var count = 0 | |
| // 結果を保持させてすでに重複しているかを確認 | |
| var set = Set<Int>() | |
| for item in 0..<10000 { | |
| let queue = DispatchQueue(label: "fuga") | |
| // データ競合以前にそもそもここでエラーになることもある。 error: Execution was interrupted. | |
| // The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation. |
| // https://www.avanderlee.com/swift/dependency-injection/ | |
| // MARK: - Example | |
| struct DataController { | |
| @Injected(\.networkProvider) var networkProvider: NetworkProviding | |
| func performDataRequest() { | |
| networkProvider.requestData() | |
| } |
| class Loan { | |
| // 借入元金 | |
| private var principle: Double | |
| // 貸出金利 もしくは 貸出利率 の 百分率。0%や100% | |
| private var rate: Double | |
| // 貸し出し期間 | |
| var period: TimeInterval | |
| // 借金総額 | |
| private var balance: Double { | |
| didSet { |