반응형
Combine과 Property Wrapper를 이용해서 UserDefault를 쉽게 사용하기
UserDefault<Value>를 Property Wrapper로 선언하기
import Combine
protocol AnyOptional {
var isNil: Bool { get }
}
extension Optional: AnyOptional {
public var isNil: Bool { self == nil }
}
/**
UserDefault 간편사용
```
// How to use
UserDefaults.server = 2
var subscribers = Set<AnyCancellable>()
UserDefaults.$server.sink { server in
print("New server: \(server)")
}.store(in: &subscribers)
```
*/
@propertyWrapper
struct UserDefault<Value> {
let key: String
let defaultValue: Value
var container = UserDefaults(suiteName: "group.com.bitmusa") ?? UserDefaults.standard
private let publisher = PassthroughSubject<Value, Never>()
var wrappedValue: Value {
get {
return container.object(forKey: key) as? Value ?? defaultValue
}
set {
if let optional = newValue as? AnyOptional, optional.isNil {
container.removeObject(forKey: key)
} else {
container.set(newValue, forKey: key)
container.synchronize()
}
publisher.send(newValue)
}
}
var projectedValue: AnyPublisher<Value, Never> {
return publisher.eraseToAnyPublisher()
}
}
extension UserDefault where Value: ExpressibleByNilLiteral {
init(key: String, _ container: UserDefaults = .standard) {
self.init(key: key, defaultValue: nil, container: container)
}
}
UserDefault에 저장할 값을 변수로 선언해서 사용하기
// MARK: - UserDefaults
extension UserDefaults {
/// 인증 토큰
@UserDefault(key: "authToken")
static var authToken: String?
}
// How to use
UserDefaults.authToken = "12345"
print(UserDefaults.authToken)
반응형
'iOS > Combine' 카테고리의 다른 글
PassthroughSubject vs CurrentValueSubject (1) | 2023.12.01 |
---|---|
Throttle과 Debounce의 차이점 (0) | 2023.05.31 |
PassthroughSubject (0) | 2023.05.31 |
사용자 정의(custom) 구독자(subscriber) 만들기 (0) | 2023.05.10 |
Combine with Timer (0) | 2023.05.09 |
UIKit(UIControl) + Combine을 위한 Extension (0) | 2022.11.09 |
MVVM with Combine Tutorial for iOS (1) | 2019.09.05 |
RxSwift 와 Combine (0) | 2019.07.26 |