Skip to content

Instantly share code, notes, and snippets.

@PaulWoodIII
Last active September 12, 2019 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PaulWoodIII/ddf58a823f3ff0b99c582b16f5f2047c to your computer and use it in GitHub Desktop.
Save PaulWoodIII/ddf58a823f3ff0b99c582b16f5f2047c to your computer and use it in GitHub Desktop.
import Foundation
class Box<T> {
typealias Observer = (T) -> Void
var observer: Observer?
func bind(observer: Observer?) {
self.observer = observer
}
var value: T {
didSet {
observer?(value)
}
}
init(_ v: T) {
value = v
}
}
// Reference type at the Obj-C level for persistence
public class HeroMO: NSObject {
var id = UUID()
var name: String = ""
var organization: OrganizationMO?
}
// Reference type at the Obj-C level for persistence
class OrganizationMO: NSObject {
var id = UUID() // basically a NSManagedObjectID
var name: String = ""
var heros: Set<HeroMO> = []
}
class UniverseMO: NSObject {
}
public class HeroDatabase: NSObject {
// using a dictionary because it ensures the uniqueness of Heros by name
// this is the source of truth and could be considered the result of a fetch request
private var allHeros = [String: HeroMO]()
// using a dictionary because it ensures the uniqueness of Organizations by name
// this is a source of truth and could be considered the result of a fetch request
private var allOrganizations = Dictionary<String,OrganizationMO>()
private var ordering: Array<UUID> = [] {
didSet {
arrangeHeros()
}
}
// source of truth from the Views Perspective
var displayItems: Box<ComicbookCharacters> = Box(ComicbookCharacters(universes: []))
func addHero(_ h: Hero) {
guard allHeros[h.name] == nil else { return }
let heroMO = HeroMO()
heroMO.name = h.name
allHeros[h.name] = heroMO
ordering.append(heroMO.id)
}
func removeHero(_ h: Hero) {
}
// our source of truth has changed so we need to update the displayItems
private func arrangeHeros() {
}
private func addHero(_: HeroMO) {
}
private func add(hero: HeroMO, toOrg: OrganizationMO) {
}
private func move(_ hero: HeroMO, to index: Int){
}
}
struct ComicbookCharacters {
var universes: [Universe]
func displayAll() {
universes.forEach({ u in
u.displayAll()
})
}
}
struct Universe {
var name: String
var items: [ListItem]
func displayAll() {
items.forEach({ item in
item.display()
})
}
}
/// represents an interface all items and collection of items have in common
protocol Displayable {
var displayString: String { get }
func display() // this could be any mutation or side affect but lets just print
func asType() -> ListItemRepresentable
}
extension Displayable {
func display(){
print(displayString)
}
}
// heres a HeroType that defines its values as well as its Displayable properties in one place
struct Hero: Displayable {
func display() {
print(name)
}
var name: String
var displayString: String { return name }
func asType() -> ListItemRepresentable {
return .person(self)
}
}
struct Organization {
var title: String
var members: [Hero]
func printAllMembers() {
members.map({ print($0) })
}
}
// Quick Example of how to conform a type, perhaps a 3rd party struct to Displayable in your codebase, many people just prefer extensions over a long definition
extension Organization: Displayable {
var displayString: String { return title }
func asType() -> ListItemRepresentable {
return .organization(self)
}
func display() {
print(title)
printAllMembers()
}
}
enum ListItemRepresentable {
case person(_ : Hero)
case organization(_ : Organization)
}
// Prepare this struct to be displayed in a List in SwiftUI by having an id and conform to Identifiable
struct ListItem: Identifiable {
// this coold be cached on a per object basis but lets perform based on the type on call for an example of that
func display() {
switch type {
case .person(let person):
person.display()
case .organization(let organization):
organization.display()
}
}
// this could be generated but lets use caching as an example
var displayString: String
var type: ListItemRepresentable
// used to handle identifying this item in a list especially collection differences
var id = UUID()
init(displayable : Displayable) {
self.displayString = displayable.displayString
self.type = displayable.asType()
}
}
let spiderMan = Hero(name: "Peter Parker")
let captain = Hero(name: "Steve Rogers")
let ironMan = Hero(name: "Tony Stark")
let thor = Hero(name: "Dr Donald Blake")
let avengers = Organization(title: "Avengers",
members: [captain,ironMan,thor])
let dareDevil = Hero(name: "Matt Murdock")
// we have a homogeneous array that represents a heterogeneous collection
var listOfMarvelCharacters = [
ListItem(displayable: spiderMan),
ListItem(displayable: avengers),
ListItem(displayable: dareDevil),
]
var marvel = Universe(name: "Marvel", items: listOfMarvelCharacters)
let batman = Hero(name: "Bruce Wayne")
let superman = Hero(name: "Clark Kent")
let wonderWoman = Hero(name: "Diana Prince")
let justiceLeage = Organization(title: "Justice Leage",
members: [batman,superman,wonderWoman])
let greenArrow = Hero(name: "Oliver Queen")
let listOfDCCharacters = [ListItem(displayable: justiceLeage),
ListItem(displayable: greenArrow)
]
let dc = Universe(name: "DC", items: listOfDCCharacters)
let comics = ComicbookCharacters(universes: [marvel,dc])
comics.displayAll()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment