Skip to content

Instantly share code, notes, and snippets.

@DevAndArtist
Last active October 8, 2017 08:59
Show Gist options
  • Save DevAndArtist/c8ef89de7cba79d1b01edc12b9e991b2 to your computer and use it in GitHub Desktop.
Save DevAndArtist/c8ef89de7cba79d1b01edc12b9e991b2 to your computer and use it in GitHub Desktop.
func ?? <T>(_ optional: T?, _ trap: @autoclosure () -> Never) -> T {
	switch optional {
	case .some(let value):
		return value
	case .none:
		trap()
	}
}

protocol Object : AnyObject {}

extension Object {
	
	@discardableResult
	func with(_ update: (Self) throws -> Void) rethrows -> Self {
		try update(self)
		return self
	}
}

extension Object where Self : NSObject {
	
	@discardableResult
	init(_ update: (Self) throws -> Void) rethrows {
		self.init()
		try update(self)
	}
}

extension NSObject : Object {}

struct InterfaceBuilder<Base : UIViewController> {
	
	let base: Base
	
	init(_ base: Base) {
		base.loadViewIfNeeded()
		self.base = base
	}
}

protocol InterfaceBuilderCompatible : AnyObject {}

extension InterfaceBuilderCompatible where Self : UIViewController {
	
	var ib: InterfaceBuilder<Self> {
		get { return InterfaceBuilder(self) }
		set { /* */ }
	}
}

class ViewController : UIViewController {

	@IBOutlet weak var foo: UIView?
	@IBOutlet weak var bar: UIView?
	
	override func viewDidLoad() {
		super.viewDidLoad()
		ib.foo.backgroundColor = .red
		ib.bar.backgroundColor = .green
	}
}

extension ViewController : InterfaceBuilderCompatible {}

extension InterfaceBuilder where Base : ViewController {

	var foo: UIView {
		// Trap if needed
		return base.foo ?? fatalError("Some error message")
	}
	
	var bar: UIView {
		// Fallback to a default 
		return base.bar ?? UIView { base.bar = $0 }
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment