diff --git a/Example/Gluon.xcodeproj/project.pbxproj b/Example/Gluon.xcodeproj/project.pbxproj index 26979991..fb48e22b 100644 --- a/Example/Gluon.xcodeproj/project.pbxproj +++ b/Example/Gluon.xcodeproj/project.pbxproj @@ -216,12 +216,12 @@ 607FACCF1AFB9204008FA782 = { CreatedOnToolsVersion = 6.3.1; DevelopmentTeam = H4Z9Z4RD2G; - LastSwiftMigration = 0900; + LastSwiftMigration = 1000; }; 607FACE41AFB9204008FA782 = { CreatedOnToolsVersion = 6.3.1; DevelopmentTeam = H4Z9Z4RD2G; - LastSwiftMigration = 0900; + LastSwiftMigration = 1000; TestTargetID = 607FACCF1AFB9204008FA782; }; }; @@ -508,8 +508,7 @@ MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -524,8 +523,7 @@ MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Release; }; @@ -546,8 +544,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gluon_Example.app/Gluon_Example"; }; name = Debug; @@ -565,8 +562,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Gluon_Example.app/Gluon_Example"; }; name = Release; diff --git a/Example/Gluon/AppDelegate.swift b/Example/Gluon/AppDelegate.swift index 734283b5..d8c03f0b 100644 --- a/Example/Gluon/AppDelegate.swift +++ b/Example/Gluon/AppDelegate.swift @@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } diff --git a/Example/Gluon/Base.lproj/Main.storyboard b/Example/Gluon/Base.lproj/Main.storyboard index b00a8796..7243ce07 100644 --- a/Example/Gluon/Base.lproj/Main.storyboard +++ b/Example/Gluon/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -20,6 +20,16 @@ + + + diff --git a/Example/Gluon/ViewController.swift b/Example/Gluon/ViewController.swift index 243adf7f..62cdcc44 100644 --- a/Example/Gluon/ViewController.swift +++ b/Example/Gluon/ViewController.swift @@ -9,6 +9,25 @@ import UIKit import Gluon +struct TodoList: Store { + enum Action { + case add(String, Int) + case remove(Int) + case update(String, Int) + } + + func apply(action: Action, to state: inout [String]) { + switch action { + case let .add(item, index): + state.insert(item, at: index) + case let .update(item, index): + state[index] = item + case let .remove(index): + state.remove(at: index) + } + } +} + final class Counter: Component { struct State: StateType { var counter = 0 diff --git a/Gluon/Classes/Classes.swift b/Gluon/Classes/Classes.swift index 1ad4c985..bf5ac27c 100644 --- a/Gluon/Classes/Classes.swift +++ b/Gluon/Classes/Classes.swift @@ -63,6 +63,9 @@ open class BaseComponent: ComponentType { } } +final class Fragment: BaseComponent { +} + extension BaseComponent where Props: Default { public static func node(childrenFactory: () -> [Node]) -> Node { return self.node(Props(), childrenFactory: childrenFactory) @@ -91,6 +94,10 @@ extension Node { public init(_ string: String) { factory = { string } } + + public init(_ nodes: [Node]) { + factory = { Fragment(props: NoProps(), children: nodes) } + } } public final class StackView: BaseComponent { diff --git a/Gluon/Classes/Store.swift b/Gluon/Classes/Store.swift new file mode 100644 index 00000000..d3427f5f --- /dev/null +++ b/Gluon/Classes/Store.swift @@ -0,0 +1,27 @@ +// +// Store.swift +// Gluon +// +// Created by Max Desiatov on 12/10/2018. +// + +import Foundation + +public protocol Store: Equatable { + associatedtype State + associatedtype Action + + func apply(action: Action, to: inout State) +} + +// FIXME: need context working for its implementation +public final class StoreProvider: Component +where S: Store, S.State: StateType { + struct Props: Equatable { + var store: S + } + + public func render() -> Node { + return Node(children) + } +}