Create Dependency Injection module

This commit is contained in:
Djorkaeff Alexandre 2024-01-19 16:51:44 -03:00
parent 64bd23ed19
commit cf1cbb7d61
6 changed files with 107 additions and 11 deletions

View File

@ -0,0 +1,28 @@
import Combine
extension Publisher {
func retryWithDelay<S>(
retries: Int,
delay: S.SchedulerTimeType.Stride,
scheduler: S
) -> AnyPublisher<Output, Failure> where S: Scheduler {
self
.delayIfFailure(for: delay, scheduler: scheduler)
.retry(retries)
.eraseToAnyPublisher()
}
private func delayIfFailure<S>(
for delay: S.SchedulerTimeType.Stride,
scheduler: S
) -> AnyPublisher<Output, Failure> where S: Scheduler {
self.catch { error in
Future { completion in
scheduler.schedule(after: scheduler.now.advanced(by: delay)) {
completion(.failure(error))
}
}
}
.eraseToAnyPublisher()
}
}

View File

@ -0,0 +1,10 @@
@propertyWrapper
struct Dependency<T> {
var wrappedValue: T {
guard let dependency = Store.resolve(T.self) else {
fatalError("No service of type \(ObjectIdentifier(T.self)) registered!")
}
return dependency
}
}

View File

@ -0,0 +1,40 @@
import Foundation
protocol StoreInterface {
static func register<T>(_ type: T.Type, factory: @autoclosure @escaping () -> T)
static func resolve<T>(_ type: T.Type) -> T?
}
final class Store: StoreInterface {
private static var factories: [ObjectIdentifier: () -> Any] = [:]
private static var cache: [ObjectIdentifier: Any] = [:]
static func register<T>(_ type: T.Type, factory: @autoclosure @escaping () -> T) {
let identifier = ObjectIdentifier(type)
factories[identifier] = factory
}
static func resolve<T>(_ type: T.Type) -> T? {
let identifier = ObjectIdentifier(type)
if let dependency = cache[identifier] {
return dependency as? T
} else {
let dependency = factories[identifier]?() as? T
if let dependency {
cache[identifier] = dependency
}
return dependency
}
}
}
private final class WeakRef<T: AnyObject> {
weak var value: T?
init(value: T) {
self.value = value
}
}

View File

@ -1,7 +1,11 @@
import Foundation
final class RocketChatAppRouter: ObservableObject {
@Storage("current_server") var currentServer: URL?
protocol RocketChatAppRouting {
func route(to route: Route)
}
final class RocketChatAppRouter: ObservableObject, RocketChatAppRouting {
@Storage(.currentServer) private var currentServer: URL?
@Published var route: Route = .serverList {
didSet {
@ -38,9 +42,7 @@ final class RocketChatAppRouter: ObservableObject {
}
}
extension RocketChatAppRouter {
enum Route {
case roomList(Server)
case serverList
}
enum Route {
case roomList(Server)
case serverList
}

View File

@ -1,18 +1,22 @@
import Foundation
enum StorageKey: String {
case currentServer = "current_server"
}
@propertyWrapper
struct Storage<T: Codable> {
private let key: String
private let key: StorageKey
private let defaultValue: T?
init(_ key: String, defaultValue: T? = nil) {
init(_ key: StorageKey, defaultValue: T? = nil) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T? {
get {
guard let data = UserDefaults.standard.object(forKey: key) as? Data else {
guard let data = UserDefaults.standard.object(forKey: key.rawValue) as? Data else {
return defaultValue
}
@ -22,7 +26,7 @@ struct Storage<T: Codable> {
set {
let data = try? JSONEncoder().encode(newValue)
UserDefaults.standard.set(data, forKey: key)
UserDefaults.standard.set(data, forKey: key.rawValue)
}
}
}

View File

@ -77,6 +77,9 @@
1E2F61642512955D00871711 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2F61632512955D00871711 /* HTTPMethod.swift */; };
1E2F61662512958900871711 /* Push.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2F61652512958900871711 /* Push.swift */; };
1E470E832513A71E00E3DD1D /* RocketChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E470E822513A71E00E3DD1D /* RocketChat.swift */; };
1E4AFC152B5AF09800E2AA7D /* Dependency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4AFC142B5AF09800E2AA7D /* Dependency.swift */; };
1E4AFC172B5AF09C00E2AA7D /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4AFC162B5AF09C00E2AA7D /* Store.swift */; };
1E4AFC1B2B5AFC6A00E2AA7D /* Publisher+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4AFC1A2B5AFC6A00E2AA7D /* Publisher+Extensions.swift */; };
1E51D962251263CD00DC95DE /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D961251263CD00DC95DE /* MessageType.swift */; };
1E51D965251263D600DC95DE /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D964251263D600DC95DE /* NotificationType.swift */; };
1E598AE42515057D002BDFBD /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE32515057D002BDFBD /* Date+Extensions.swift */; };
@ -385,6 +388,9 @@
1E2F61632512955D00871711 /* HTTPMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = "<group>"; };
1E2F61652512958900871711 /* Push.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Push.swift; sourceTree = "<group>"; };
1E470E822513A71E00E3DD1D /* RocketChat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RocketChat.swift; sourceTree = "<group>"; };
1E4AFC142B5AF09800E2AA7D /* Dependency.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dependency.swift; sourceTree = "<group>"; };
1E4AFC162B5AF09C00E2AA7D /* Store.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = "<group>"; };
1E4AFC1A2B5AFC6A00E2AA7D /* Publisher+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Publisher+Extensions.swift"; sourceTree = "<group>"; };
1E51D961251263CD00DC95DE /* MessageType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageType.swift; sourceTree = "<group>"; };
1E51D964251263D600DC95DE /* NotificationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationType.swift; sourceTree = "<group>"; };
1E598AE32515057D002BDFBD /* Date+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Extensions.swift"; sourceTree = "<group>"; };
@ -651,6 +657,7 @@
children = (
1E29A3092B585B370093C03C /* Data+Extensions.swift */,
1E29A30B2B585D1D0093C03C /* String+Extensions.swift */,
1E4AFC1A2B5AFC6A00E2AA7D /* Publisher+Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -859,6 +866,8 @@
isa = PBXGroup;
children = (
1ED033C72B55CE78004F4930 /* DependencyStore.swift */,
1E4AFC142B5AF09800E2AA7D /* Dependency.swift */,
1E4AFC162B5AF09C00E2AA7D /* Store.swift */,
);
path = DependencyInjection;
sourceTree = "<group>";
@ -1838,9 +1847,11 @@
1E29A3242B5874FF0093C03C /* MessageComposerView.swift in Sources */,
1EB375892B55DBFB00AEC3D7 /* Server.swift in Sources */,
1E29A3162B5868DF0093C03C /* MessageListView.swift in Sources */,
1E4AFC172B5AF09C00E2AA7D /* Store.swift in Sources */,
1E29A2F42B585B070093C03C /* SubscriptionsResponse.swift in Sources */,
1E29A2F92B585B070093C03C /* SubscriptionsRequest.swift in Sources */,
1E29A2F22B585B070093C03C /* HistoryResponse.swift in Sources */,
1E4AFC152B5AF09800E2AA7D /* Dependency.swift in Sources */,
1ED033BA2B55B5F6004F4930 /* ServerView.swift in Sources */,
1E29A2D02B58582F0093C03C /* RoomView.swift in Sources */,
1E29A2FD2B585B070093C03C /* RoomsRequest.swift in Sources */,
@ -1849,6 +1860,7 @@
1E9A716F2B59CBCA00477BA2 /* AttachmentView.swift in Sources */,
1E29A3002B585B070093C03C /* JSONAdapter.swift in Sources */,
1E29A3022B585B070093C03C /* DateCodingStrategy.swift in Sources */,
1E4AFC1B2B5AFC6A00E2AA7D /* Publisher+Extensions.swift in Sources */,
1ED033B62B55B4A5004F4930 /* ServerListView.swift in Sources */,
1E29A3202B5871C80093C03C /* RoomFormatter.swift in Sources */,
1EDFD0FA2B589B8F002FEE5F /* MessagesLoader.swift in Sources */,