diff --git a/Package.swift b/Package.swift index 67cab4c..4139741 100644 --- a/Package.swift +++ b/Package.swift @@ -155,7 +155,7 @@ targets += [ let package = Package( name: "swift-react", - platforms: [.macOS(.v14)], + platforms: [.macOS(.v14), .iOS(.v17)], products: [ .library(name: "React", targets: ["React"]), ], diff --git a/Sources/React/Hooks/Context/Context.swift b/Sources/React/Hooks/Context/Context.swift index 8c330e3..53150d1 100644 --- a/Sources/React/Hooks/Context/Context.swift +++ b/Sources/React/Hooks/Context/Context.swift @@ -1,7 +1,7 @@ import SRTCore @propertyWrapper -public struct Context: _AnyContextHook { +public struct Context: _AnyHookWrapper { public init() {} public var wrappedValue: Value { @@ -16,16 +16,10 @@ public struct Context: _AnyContextHook { _object.value = object ?? Object() } - var valueType: any ContextValue.Type { Value.self } - - func setHolder(_ holder: ContextValueHolder?, disposable: (any Disposable)?) { - object.holder = holder - object.disposable = disposable - } - - final class Object { + final class Object: _AnyContextHookObject { init() {} + var valueType: any ContextValue.Type { Value.self } var disposable: (any Disposable)? weak var holder: ContextValueHolder? @@ -39,7 +33,8 @@ public struct Context: _AnyContextHook { } } -protocol _AnyContextHook: _AnyHookWrapper { +protocol _AnyContextHookObject: AnyObject { var valueType: any ContextValue.Type { get } - func setHolder(_ holder: ContextValueHolder?, disposable: (any Disposable)?) + var holder: ContextValueHolder? { get set } + var disposable: (any Disposable)? { get set } } diff --git a/Sources/React/Hooks/Effect.swift b/Sources/React/Hooks/Effect.swift index 83a88d2..6f7cc4c 100644 --- a/Sources/React/Hooks/Effect.swift +++ b/Sources/React/Hooks/Effect.swift @@ -1,7 +1,7 @@ import SRTCore @propertyWrapper -public struct Effect: _AnyEffectHook { +public struct Effect: _AnyHookWrapper { public typealias Setup = () -> Cleanup? public typealias Cleanup = () -> Void @@ -89,7 +89,3 @@ public struct Effect: _AnyEffectHook { } } } - -protocol _AnyEffectHook: _AnyHookWrapper { - var effectObject: Effect.Object { get } -} diff --git a/Sources/React/Hooks/Hook.swift b/Sources/React/Hooks/Hook.swift index 6085a2d..de5435a 100644 --- a/Sources/React/Hooks/Hook.swift +++ b/Sources/React/Hooks/Hook.swift @@ -3,14 +3,14 @@ public protocol Hook { } protocol _AnyHookWrapper: Hook { - associatedtype Object + associatedtype Object: AnyObject var object: Object { get } func prepare(object: Object?) } extension _AnyHookWrapper { - func _prepareAny(object: Any?) { + func _prepareAny(object: AnyObject?) { prepare(object: object.map { $0 as! Object }) } } diff --git a/Sources/React/Hooks/Ref.swift b/Sources/React/Hooks/Ref.swift index d01623c..47d30cb 100644 --- a/Sources/React/Hooks/Ref.swift +++ b/Sources/React/Hooks/Ref.swift @@ -1,7 +1,7 @@ import SRTCore @propertyWrapper -public struct Ref: _AnyRef { +public struct Ref: _AnyHookWrapper { public init() {} typealias Object = RefObject @@ -31,9 +31,6 @@ public struct Ref: _AnyRef { } } -protocol _AnyRef: _AnyHookWrapper { -} - public final class RefObject: IdentityHashable { public init() {} diff --git a/Sources/React/Hooks/State.swift b/Sources/React/Hooks/State.swift index 5a5f7c5..0f1f088 100644 --- a/Sources/React/Hooks/State.swift +++ b/Sources/React/Hooks/State.swift @@ -1,7 +1,7 @@ import SRTCore @propertyWrapper -public struct State: _AnyStateHook { +public struct State: _AnyHookWrapper { public init(wrappedValue: Value) { self.initialValue = wrappedValue } @@ -21,16 +21,13 @@ public struct State: _AnyStateHook { _object.value = object ?? Object(value: initialValue) } - func setDidChange(_ newValue: (() -> Void)?) { - object.didChange = newValue - } - - final class Object { + final class Object: _AnyStateHookObject { init(value: Value) { self.value = value } private var value: Value + var didChange: (() -> Void)? func getValue() -> Value { value } @@ -50,6 +47,6 @@ extension State where Value: ExpressibleByNilLiteral { } } -protocol _AnyStateHook: _AnyHookWrapper { - func setDidChange(_ newValue: (() -> Void)?) +protocol _AnyStateHookObject: AnyObject { + var didChange: (() -> Void)? { get set } } diff --git a/Sources/React/Renderer/Instance.swift b/Sources/React/Renderer/Instance.swift index 57a1ee8..8884c9b 100644 --- a/Sources/React/Renderer/Instance.swift +++ b/Sources/React/Renderer/Instance.swift @@ -13,23 +13,23 @@ package final class Instance { } weak var owner: VNode? - var hooks: [any _AnyHookWrapper] = [] + var hooks: [AnyObject] = [] public var dom: JSNode? var attributes: Attributes = [:] var listeners: [String: ListenerBridge] = [:] var contextValueHolder: ContextValueHolder? var isDirty: Bool = false - var contextHooks: [any _AnyContextHook] { - hooks.compactMap { $0 as? any _AnyContextHook } + var contextHooks: [any _AnyContextHookObject] { + hooks.compactMap { $0 as? any _AnyContextHookObject } } - var stateHooks: [any _AnyStateHook] { - hooks.compactMap { $0 as? any _AnyStateHook } + var stateHooks: [any _AnyStateHookObject] { + hooks.compactMap { $0 as? any _AnyStateHookObject } } - var effectHooks: [any _AnyEffectHook] { - hooks.compactMap { $0 as? any _AnyEffectHook } + var effectHooks: [Effect.Object] { + hooks.compactMap { $0 as? Effect.Object } } func renderDOMAttributes( @@ -58,7 +58,6 @@ package final class Instance { ) throws { let dom = try (self.dom?.asHTMLElement()).unwrap("dom.asHTMLElement") - // コピー必要なんだっけ? for (type, bridge) in Array(self.listeners) { if bridge.swift != newListeners[type] { if let js = bridge.js { diff --git a/Sources/React/Renderer/ReactRoot.swift b/Sources/React/Renderer/ReactRoot.swift index 5929c6f..5d7a1f9 100644 --- a/Sources/React/Renderer/ReactRoot.swift +++ b/Sources/React/Renderer/ReactRoot.swift @@ -267,12 +267,12 @@ public final class ReactRoot { hook._prepareAny(object: nil) } } else { - for (new, old) in zip(hooks, instance.hooks) { - new._prepareAny(object: old.object) + for (hook, object) in zip(hooks, instance.hooks) { + hook._prepareAny(object: object) } } - instance.hooks = hooks + instance.hooks = hooks.map { $0.object } } private func subscribeHooks(instance: Instance) { @@ -284,15 +284,16 @@ public final class ReactRoot { for context in instance.contextHooks { if let holder = contextValueHolders[ObjectIdentifier(context.valueType)] { - let dsp = holder.emitter.on(handler: updater) - context.setHolder(holder, disposable: dsp) + context.holder = holder + context.disposable = holder.emitter.on(handler: updater) } else { - context.setHolder(nil, disposable: nil) + context.holder = nil + context.disposable = nil } } for state in instance.stateHooks { - state.setDidChange(updater) + state.didChange = updater } } @@ -304,7 +305,7 @@ public final class ReactRoot { private func postRender(instance: Instance) throws { for effect in instance.effectHooks { - if let task = effect.effectObject.taskIfShouldExecute() { + if let task = effect.taskIfShouldExecute() { scheduleEffect(task) } } @@ -314,7 +315,7 @@ public final class ReactRoot { try instance.dom?.remove() for effect in instance.effectHooks { - if let task = effect.effectObject.cleanupTask() { + if let task = effect.cleanupTask() { scheduleEffect(task) } }