Skip to content

Instantly share code, notes, and snippets.

View sorin-ref's full-sized avatar

Sorin sorin-ref

  • Cluj-Napoca, Romania
View GitHub Profile
import Foundation
public class Framer {
public func getFrameName() -> String {
return "My frame"
}
}
import Cocoa
public class Frame: NSView {
public override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
let framer = Framer()
framer.getFrameName().draw(in: bounds)
}
}
import UIKit
public class Frame: UIView {
public override func draw(_ rect: CGRect) {
// Drawing code
let framer = Framer()
framer.getFrameName().draw(in: bounds)
}
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
let framer = Framer()
let name = framer.getFrameName()
XCTAssertEqual(name, "My frame")
}
// 1. Service with hardcoded input and output. Cleanest usage, but no client side extensibility (too much encapsulation).
public class Service1 {
public init() { }
func input() -> Bool {
return true
}
func output(text: String) {
print(type(of: self), text)
}
public func doSomething() {
// 2. Service with default implementations that may be overriden at the client level through inheritance. Clients remain clean, and they can override only some of the open members, but they must have the service as their base class for this (and that's not always acceptable).
open class Service2 {
public init() { }
open func input() -> Bool {
return false
}
open func output(text: String) {
print(type(of: self), text)
}
public func doSomething() {
// 3. Service that requests input and output from a client as @escaping or optional closures (i.e. the functional approach). No more inheritance, and the service can still provide default implementations whenever needed. But the clients need to capture weak/unowned self if they want to use their current state within the body of the custom closures passed to the service (in order to avoid memory leaks, i.e. they need to know how ARC works).
public class Service3 {
public init(inputFunction: @escaping InputFunction, outputFunction: OutputFunction? = nil) {
self.inputFunction = inputFunction
self.outputFunction = outputFunction
}
private var inputFunction: InputFunction
private var outputFunction: OutputFunction?
public func doSomething() {
if inputFunction() {
// 4. Service that weakly delegates input and output to a client that aggregates (i.e. references and uses) the service (instead of inheriting from it). Allows weak/unowned definition for the delegate reference on service side, ensuring no memory leaks would be caused (even if client side developers don't know about ARC). And through the use of an extension, default implementations may still be provided whenever needed (and when there is no delegate set at all, a fallback implementation can be defined by the service itself too).
public class Service4 {
public init() { }
public weak var delegate: Service4Delegate?
public func doSomething() {
if delegate?.input() ?? false {
delegate?.output(text: "done")
}
}
}
/// 5. All-in-one service solution, supporting: inheritance, functional programming, delegate, default implementation.
open class Service5 {
public init() { }
public var inputFunction: InputFunction?
public var outputFunction: OutputFunction?
public weak var delegate: Service5Delegate?
open func input() -> Bool {
return inputFunction?() ?? delegate?.input() ?? false
}
open func output(text: String) {
mkdir "${BUILD_DIR}/Release-iphoneaggregate"
cp -R "${BUILD_DIR}/Release-iphoneos/FramisTouch.framework/." "${BUILD_DIR}/Release-iphoneaggregate/FramisTouch.framework"
cp -R "${BUILD_DIR}/Release-iphonesimulator/FramisTouch.framework/Modules/FramisTouch.swiftmodule/." "${BUILD_DIR}/Release-iphoneaggregate/FramisTouch.framework/Modules/FramisTouch.swiftmodule"
lipo "${BUILD_DIR}/Release-iphoneos/FramisTouch.framework/FramisTouch" "${BUILD_DIR}/Release-iphonesimulator/FramisTouch.framework/FramisTouch" -output "${BUILD_DIR}/Release-iphoneaggregate/FramisTouch.framework/FramisTouch" -create
open "${BUILD_DIR}/Release-iphoneaggregate"