Created
July 2, 2017 14:00
-
-
Save mzaks/c1428efcbbbb0c0c430537715afea8c6 to your computer and use it in GitHub Desktop.
EntitasKit Options Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AppDelegate.swift | |
// OptionsSampleApp | |
// | |
// Created by Maxim Zaks on 02.07.17. | |
// Copyright © 2017 Maxim Zaks. All rights reserved. | |
// | |
import UIKit | |
import EntitasKit | |
@UIApplicationMain | |
class AppDelegate: UIResponder, UIApplicationDelegate { | |
var window: UIWindow? | |
var optionsLoop: ReactiveLoop? | |
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { | |
setupOptionsContext() | |
optionsLoop = ReactiveLoop(ctx: optionsCtx, systems: [ | |
PersistOptionsSystem(), | |
SwitchChildrenOfOptionASystem(), | |
UpdateOptionsDisplaySystem(), | |
SwitchParentOfOptionASystem() | |
]) | |
return true | |
} | |
func applicationWillResignActive(_ application: UIApplication) { | |
} | |
func applicationDidEnterBackground(_ application: UIApplication) { | |
} | |
func applicationWillEnterForeground(_ application: UIApplication) { | |
} | |
func applicationDidBecomeActive(_ application: UIApplication) { | |
} | |
func applicationWillTerminate(_ application: UIApplication) { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// OptionsContext.swift | |
// OptionsSampleApp | |
// | |
// Created by Maxim Zaks on 02.07.17. | |
// Copyright © 2017 Maxim Zaks. All rights reserved. | |
// | |
import Foundation | |
import EntitasKit | |
let optionsCtx = Context() | |
struct OptionsBoolValueComponent: Component { | |
let value: Bool | |
} | |
struct TitleComponent: Component { | |
let value: String | |
} | |
struct DescriptionComponent: Component { | |
let value: String | |
} | |
struct IndexComponent: Component { | |
let value: Int | |
} | |
enum OptionsKey: String { | |
case OptionA, OptionB, OptionA1, OptionA2 | |
} | |
struct OptionsKeyComponent: Component { | |
let value: OptionsKey | |
} | |
struct OptionsConfigData { | |
let key: OptionsKey | |
let index: Int | |
let title: String | |
let description: String | |
let defaultValue: Bool | |
} | |
let optionsConfig = [ | |
OptionsConfigData(key: .OptionA, | |
index: 0, | |
title: "Enable A", | |
description: "By enabling A we will get ...", | |
defaultValue: true | |
), | |
OptionsConfigData(key: .OptionB, | |
index: 3, | |
title: "Enable B", | |
description: "By enbaling B we will get ...", | |
defaultValue: false | |
), | |
OptionsConfigData(key: .OptionA1, | |
index: 1, | |
title: "Enable A1", | |
description: "By enabling A1 we will get ...", | |
defaultValue: true | |
), | |
OptionsConfigData(key: .OptionA2, | |
index: 2, | |
title: "Enable A2", | |
description: "By enbaling A2 we will get ...", | |
defaultValue: true | |
) | |
] | |
func setupOptionsContext() { | |
for option in optionsConfig { | |
let e = optionsCtx.createEntity() | |
.set(OptionsKeyComponent(value: option.key)) | |
.set(IndexComponent(value: option.index)) | |
.set(TitleComponent(value: option.title)) | |
.set(DescriptionComponent(value: option.description)) | |
let value = (UserDefaults.standard.object(forKey: option.key.rawValue) as? Bool) ?? option.defaultValue | |
e.set(OptionsBoolValueComponent(value: value)) | |
} | |
} | |
let optionsKeyIndex = optionsCtx.index { (comp: OptionsKeyComponent) -> OptionsKey in | |
return comp.value | |
} | |
struct OptionsDisplayComponent: UniqueComponent { | |
weak var ref: ViewController? | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// OptionsLoop.swift | |
// OptionsSampleApp | |
// | |
// Created by Maxim Zaks on 02.07.17. | |
// Copyright © 2017 Maxim Zaks. All rights reserved. | |
// | |
import Foundation | |
import EntitasKit | |
class PersistOptionsSystem: ReactiveSystem { | |
let collector: Collector = Collector( | |
group: optionsCtx.group( | |
Matcher( | |
all: [OptionsBoolValueComponent.cid, OptionsKeyComponent.cid] | |
) | |
), | |
type: .updated | |
) | |
let name = "Options persisting" | |
func execute(entities: Set<Entity>) { | |
for e in entities { | |
guard let boolComponent: OptionsBoolValueComponent = e.get(), | |
let keyComponent: OptionsKeyComponent = e.get() else { | |
continue | |
} | |
UserDefaults.standard.set(boolComponent.value, forKey: keyComponent.value.rawValue) | |
} | |
} | |
} | |
class SwitchChildrenOfOptionASystem: ReactiveSystem { | |
let collector: Collector = Collector( | |
group: optionsCtx.group( | |
Matcher( | |
all: [OptionsBoolValueComponent.cid, OptionsKeyComponent.cid] | |
) | |
), | |
type: .updated | |
) | |
let name = "Switching off A1 and A2 when A got switched off" | |
func execute(entities: Set<Entity>) { | |
guard | |
let optionA = entities.first(where: { (e) -> Bool in | |
return e.get(OptionsKeyComponent.self)?.value == .OptionA | |
}), | |
let aIsOn = optionA.get(OptionsBoolValueComponent.self)?.value, | |
let optionA1 = optionsKeyIndex[.OptionA1].first, | |
let optionA2 = optionsKeyIndex[.OptionA2].first | |
else { | |
return | |
} | |
if aIsOn == false { | |
if optionA1.get(OptionsBoolValueComponent.self)?.value != false { | |
optionA1.set(OptionsBoolValueComponent(value: false)) | |
} | |
if optionA2.get(OptionsBoolValueComponent.self)?.value != false { | |
optionA2.set(OptionsBoolValueComponent(value: false)) | |
} | |
} | |
} | |
} | |
class SwitchParentOfOptionASystem: ReactiveSystem { | |
let collector: Collector = Collector( | |
group: optionsCtx.group( | |
Matcher( | |
all: [OptionsBoolValueComponent.cid, OptionsKeyComponent.cid] | |
) | |
), | |
type: .updated | |
) | |
let name = "Switching on A when A1 or A2 got switched on" | |
func execute(entities: Set<Entity>) { | |
for e in entities { | |
guard e.get(OptionsKeyComponent.self)?.value == .OptionA1 || e.get(OptionsKeyComponent.self)?.value == .OptionA2 else { | |
continue | |
} | |
guard let isON = e.get(OptionsBoolValueComponent.self)?.value, | |
let optionA = optionsKeyIndex[.OptionA].first | |
else { | |
continue | |
} | |
if isON && optionA.get(OptionsBoolValueComponent.self)?.value != true { | |
optionA.set(OptionsBoolValueComponent(value: true)) | |
} | |
} | |
} | |
} | |
class UpdateOptionsDisplaySystem: ReactiveSystem { | |
let collector: Collector = Collector( | |
group: optionsCtx.group( | |
Matcher( | |
all: [OptionsBoolValueComponent.cid, IndexComponent.cid] | |
) | |
), | |
type: .updated | |
) | |
let name = "Update options cells on value change" | |
func execute(entities: Set<Entity>) { | |
for e in entities { | |
guard let index = e.get(IndexComponent.self)?.value else { | |
continue | |
} | |
optionsCtx.uniqueComponent(OptionsDisplayComponent.self)?.ref?.updateCell(at: index) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import EntitasKit | |
class ViewController: UITableViewController { | |
var items = optionsCtx.group(Matcher(all:[OptionsKeyComponent.cid, IndexComponent.cid])) | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
optionsCtx.setUniqueComponent(OptionsDisplayComponent(ref: self)) | |
} | |
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return items.count | |
} | |
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
guard let cell = tableView.dequeueReusableCell(withIdentifier: "BoolOptionCell") as? BoolOptionCell else { | |
return UITableViewCell() | |
} | |
cell.setEntity(e: getItem(indexPath: indexPath)) | |
return cell | |
} | |
private func getItem(indexPath: IndexPath) -> Entity{ | |
return items.sorted(forObject: ObjectIdentifier(self), by: { (e1, e2) -> (Bool) in | |
let i1 = e1.get(IndexComponent.self)?.value ?? 0 | |
let i2 = e2.get(IndexComponent.self)?.value ?? 0 | |
return i1 < i2 | |
})[indexPath.row] | |
} | |
func updateCell(at: Int) { | |
let indexPath = IndexPath(row: at, section: 0) | |
guard let cell = tableView.cellForRow(at: indexPath) as? BoolOptionCell else { | |
return | |
} | |
cell.setEntity(e: getItem(indexPath: indexPath)) | |
} | |
} | |
class BoolOptionCell: UITableViewCell { | |
@IBOutlet weak var titleLabel: UILabel! | |
@IBOutlet weak var descriptionLabel: UILabel! | |
@IBOutlet weak var optionsSwitch: UISwitch! | |
weak var entity: Entity? | |
@IBAction func optionSwitched(_ sender: UISwitch) { | |
entity?.set(OptionsBoolValueComponent(value: sender.isOn)) | |
} | |
func setEntity(e : Entity){ | |
self.entity = e | |
titleLabel.text = e.get(TitleComponent.self)?.value | |
descriptionLabel.text = e.get(DescriptionComponent.self)?.value | |
if let boolComponent: OptionsBoolValueComponent = e.get() { | |
optionsSwitch.setOn(boolComponent.value, animated: true) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment