-
Notifications
You must be signed in to change notification settings - Fork 0
[#602] 앱이 독에 내려갔을 때 Todo Fetch 요청이 되는 현상을 해결한다 #657
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // | ||
| // WidgetConfigurationProvider.swift | ||
| // DevLogData | ||
| // | ||
| // Created by opfic on 6/28/26. | ||
| // | ||
|
|
||
| public protocol WidgetConfigurationProvider { | ||
| func currentWidgetKinds() async throws -> Set<String> | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,5 +9,7 @@ import Combine | |||||||
|
|
||||||||
| public protocol WidgetSyncEventBus { | ||||||||
| func publish(_ event: WidgetSyncEvent) | ||||||||
| func request() | ||||||||
| func confirmRequest() -> Bool | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. confirmRequest() 메서드는 반환값을 무시하고 호출하는 경우가 많으므로, 호출부에서 _ =를 사용하지 않고도 경고 없이 호출할 수 있도록 @discardableResult 속성을 추가하는 것이 좋습니다.
Suggested change
|
||||||||
| func observe() -> AnyPublisher<WidgetSyncEvent, Never> | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // | ||
| // WidgetConfigurationProviderImpl.swift | ||
| // DevLogWidget | ||
| // | ||
| // Created by opfic on 6/28/26. | ||
| // | ||
|
|
||
| import WidgetKit | ||
| import DevLogData | ||
|
|
||
| public final class WidgetConfigurationProviderImpl: WidgetConfigurationProvider { | ||
| public init() { } | ||
|
|
||
| public func currentWidgetKinds() async throws -> Set<String> { | ||
| try await withCheckedThrowingContinuation { continuation in | ||
| WidgetCenter.shared.getCurrentConfigurations { result in | ||
| continuation.resume( | ||
| with: result.map { configurations in | ||
| Set(configurations.map(\.kind)) | ||
| } | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,17 +6,35 @@ | |||||||
| // | ||||||||
|
|
||||||||
| import Combine | ||||||||
| import Foundation | ||||||||
| import DevLogData | ||||||||
|
|
||||||||
| public final class WidgetSyncEventBusImpl: WidgetSyncEventBus { | ||||||||
| private let subject = PassthroughSubject<WidgetSyncEvent, Never>() | ||||||||
| private let lock = NSLock() | ||||||||
| private var isRequested = false | ||||||||
|
|
||||||||
| public init() { } | ||||||||
|
|
||||||||
| public func publish(_ event: WidgetSyncEvent) { | ||||||||
| subject.send(event) | ||||||||
| } | ||||||||
|
Comment on lines
+14
to
21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WidgetSyncEventBusImpl에서 PassthroughSubject는 스레드 안전(Thread-safe)하지 않으므로, 여러 스레드에서 동시에 publish(_:)를 호출할 경우 크래시가 발생할 수 있습니다. 또한, 이벤트 버스의 특성상 이벤트를 구독하는 측(Subscriber)에서 동기적으로 다시 이벤트를 발행하거나 상태를 확인할 가능성이 있습니다. 이때 일반 NSLock을 사용하면 동일한 스레드에서 락을 중복 취득하려다 데드락(Deadlock)이 발생할 수 있습니다. 따라서 NSLock 대신 NSRecursiveLock을 사용하고, publish(_:) 메서도 락으로 보호하여 스레드 안전성을 확보하는 것을 권장합니다. private let lock = NSRecursiveLock()
private var isRequested = false
public init() { }
public func publish(_ event: WidgetSyncEvent) {
lock.lock()
defer { lock.unlock() }
subject.send(event)
} |
||||||||
|
|
||||||||
| public func request() { | ||||||||
| lock.lock() | ||||||||
| defer { lock.unlock() } | ||||||||
| isRequested = true | ||||||||
| } | ||||||||
|
|
||||||||
| public func confirmRequest() -> Bool { | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 프로토콜 정의에 맞춰 구현체에도 @discardableResult 속성을 추가하여 반환값을 생략할 수 있도록 합니다.
Suggested change
|
||||||||
| lock.lock() | ||||||||
| defer { lock.unlock() } | ||||||||
|
|
||||||||
| guard isRequested else { return false } | ||||||||
| isRequested = false | ||||||||
| return true | ||||||||
| } | ||||||||
|
|
||||||||
| public func observe() -> AnyPublisher<WidgetSyncEvent, Never> { | ||||||||
| subject.eraseToAnyPublisher() | ||||||||
| } | ||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
confirmRequest()에 @discardableResult 속성이 추가되면, 불필요한 _ = 대입 식을 제거하고 더 깔끔하게 호출할 수 있습니다.