diff --git a/iOS/Projects/Features/Record/Project.swift b/iOS/Projects/Features/Record/Project.swift index df42ccc9..9dc04129 100644 --- a/iOS/Projects/Features/Record/Project.swift +++ b/iOS/Projects/Features/Record/Project.swift @@ -8,6 +8,7 @@ let project = Project.makeModule( dependencies: [ ProjectTargetDependency.Trinet, ProjectTargetDependency.DesignSystem, + ProjectTargetDependency.TNCocoaCombine, ], isTestable: true ) diff --git a/iOS/Projects/Shared/TNCocoaCombine/Project.swift b/iOS/Projects/Shared/TNCocoaCombine/Project.swift new file mode 100644 index 00000000..40e52f03 --- /dev/null +++ b/iOS/Projects/Shared/TNCocoaCombine/Project.swift @@ -0,0 +1,8 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project.makeModule( + name: "TNCocoaCombine", + product: .framework, + isTestable: false +) diff --git a/iOS/Projects/Shared/TNCocoaCombine/Sources/EventSubscription.swift b/iOS/Projects/Shared/TNCocoaCombine/Sources/EventSubscription.swift new file mode 100644 index 00000000..63fb205b --- /dev/null +++ b/iOS/Projects/Shared/TNCocoaCombine/Sources/EventSubscription.swift @@ -0,0 +1,36 @@ +// +// EventSubscription.swift +// TNCocoaCombine +// +// Created by MaraMincho on 11/15/23. +// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved. +// + +import Combine +import UIKit + +class EventSubscription: + Subscription where EventSubscriber.Input == UIControl, EventSubscriber.Failure == Never { + func request(_: Subscribers.Demand) {} + + func cancel() { + subscriber = nil + control.removeTarget(self, action: #selector(eventDidOccur), for: event) + } + + @objc func eventDidOccur() { + _ = subscriber?.receive(control) + } + + let control: UIControl + let event: UIControl.Event + var subscriber: EventSubscriber? + + init(control: UIControl, event: UIControl.Event, subscriber: EventSubscriber) { + self.control = control + self.event = event + self.subscriber = subscriber + + control.addTarget(self, action: #selector(eventDidOccur), for: event) + } +} diff --git a/iOS/Projects/Shared/TNCocoaCombine/Sources/UIControl+Publisher.swift b/iOS/Projects/Shared/TNCocoaCombine/Sources/UIControl+Publisher.swift new file mode 100644 index 00000000..f561035b --- /dev/null +++ b/iOS/Projects/Shared/TNCocoaCombine/Sources/UIControl+Publisher.swift @@ -0,0 +1,29 @@ +// +// UIControl+Publisher.swift +// TNCocoaCombine +// +// Created by MaraMincho on 11/15/23. +// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved. +// + +import Combine +import UIKit + +public extension UIControl { + func publisher(_ event: UIControl.Event) -> EventPublisher { + return EventPublisher(control: self, event: event) + } + + struct EventPublisher: Publisher { + public typealias Output = UIControl + public typealias Failure = Never + + let control: UIControl + let event: UIControl.Event + + public func receive(subscriber: S) where S: Subscriber, Never == S.Failure, UIControl == S.Input { + let subscription = EventSubscription(control: control, event: event, subscriber: subscriber) + subscriber.receive(subscription: subscription) + } + } +} diff --git a/iOS/Tuist/ProjectDescriptionHelpers/TargetDependency.swift b/iOS/Tuist/ProjectDescriptionHelpers/TargetDependency.swift index 1d712a49..a26fb817 100644 --- a/iOS/Tuist/ProjectDescriptionHelpers/TargetDependency.swift +++ b/iOS/Tuist/ProjectDescriptionHelpers/TargetDependency.swift @@ -11,4 +11,5 @@ public enum ProjectTargetDependency { public static let DesignSystem: TargetDependency = .project(target: "DesignSystem", path: .relativeToRoot("Projects/Shared/DesignSystem")) public static let Trinet: TargetDependency = .project(target: "Trinet", path: .relativeToRoot("Projects/Core/Network")) public static let Record: TargetDependency = .project(target: "RecordFeature", path: .relativeToRoot("Projects/Features/Record")) + public static let TNCocoaCombine: TargetDependency = .project(target: "TNCocoaCombine", path: .relativeToRoot("Projects/Shared/TNCocoaCombine")) }