Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Domagoj Kulundžić
committed
Oct 5, 2019
1 parent
db2d9fd
commit bf7cdd5
Showing
17 changed files
with
528 additions
and
18 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// | ||
// Asset.swift | ||
// System | ||
// | ||
// Created by Domagoj Kulundzic on 13/08/2019. | ||
// Copyright © 2019 Martian & Machine. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public protocol Asset { | ||
var name: String { get } | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// ColorAsset.swift | ||
// System | ||
// | ||
// Created by Domagoj Kulundzic on 13/08/2019. | ||
// Copyright © 2019 Martian & Machine. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public protocol ColorAsset: Asset { | ||
var color: UIColor { get } | ||
} | ||
|
||
public extension ColorAsset { | ||
var color: UIColor { | ||
guard let color = UIColor(named: name) else { | ||
fatalError("Can't find the \(name) image asset.") | ||
} | ||
return color | ||
} | ||
} | ||
|
||
public extension ColorAsset where Self: RawRepresentable, Self.RawValue == String { | ||
var name: String { | ||
return rawValue | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// | ||
// ImageAsset.swift | ||
// System | ||
// | ||
// Created by Domagoj Kulundzic on 13/08/2019. | ||
// Copyright © 2019 Martian & Machine. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public protocol ImageAsset: Asset { | ||
var image: UIImage { get } | ||
} | ||
|
||
public extension ImageAsset { | ||
var image: UIImage { | ||
guard let image = UIImage(named: name) else { | ||
fatalError("Can't find the \(name) image asset.") | ||
} | ||
return image | ||
} | ||
|
||
var imageTemplate: UIImage { | ||
return image.withRenderingMode(.alwaysTemplate) | ||
} | ||
|
||
var imageOriginal: UIImage { | ||
return image.withRenderingMode(.alwaysOriginal) | ||
} | ||
} | ||
|
||
public extension ImageAsset where Self: RawRepresentable, Self.RawValue == String { | ||
var name: String { | ||
return rawValue | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Environment.swift | ||
// Template | ||
// | ||
// Created by Domagoj Kulundzic on 07/08/2019. | ||
// Copyright © 2019 Martian & Machine. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public enum Environment: String { | ||
case debug | ||
case staging | ||
case release | ||
} | ||
|
||
public extension Environment { | ||
static var current: Environment { | ||
#if DEBUG | ||
return .debug | ||
#elseif STAGING | ||
return .staging | ||
#elseif RELEASE | ||
return .release | ||
#endif | ||
} | ||
|
||
static var isDebug: Bool { | ||
return current == .debug | ||
} | ||
|
||
static var isStaging: Bool { | ||
return current == .staging | ||
} | ||
|
||
static var isProduction: Bool { | ||
return current == .release | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Global.swift | ||
// Template | ||
// | ||
// Created by Domagoj Kulundzic on 24/07/2018. | ||
// Copyright © 2018 Martian & Machine. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
/// Typealiases a single argumentless/voidless closure. | ||
public typealias Action = () -> Void | ||
|
||
/// Typealiases a parametrised single voidless closure. | ||
public typealias ParametrisedAction<T> = (T) -> Void | ||
|
||
/// Typealiases a success handler. | ||
public typealias SuccessHandler<T> = ((T) -> Void)? | ||
|
||
/// Typealiases a argumentless success handler. | ||
public typealias ArgumentlessSuccessHandler = (() -> Void)? | ||
|
||
/// Typealiases a failure handler. | ||
public typealias FailureHandler = ((Error) -> Void)? | ||
|
||
/// Invokes the action only if the current configuration is DEBUG. | ||
public func whenDebug(_ action: Action?) { | ||
#if DEBUG | ||
action?() | ||
#endif | ||
} | ||
|
||
/// Invokes the action only if the current configuration is RELEASE. | ||
public func whenRelease(_ action: Action?) { | ||
#if DEBUG | ||
#else | ||
action?() | ||
#endif | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// | ||
// KeyboardObserver.swift | ||
// Template | ||
// | ||
// Created by Domagoj Kulundzic on 03/10/2018. | ||
// Copyright © 2018 Martian & Machine. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
|
||
/// Defines methods to respond to keyboard appearance events. All methods have empty default implementations. | ||
public protocol KeyboardObserverDelegate: class { | ||
func keyboardWillShow(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) | ||
func keyboardWillHide(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) | ||
func keyboardDidShow(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) | ||
func keyboardDidHide(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) | ||
} | ||
|
||
public extension KeyboardObserverDelegate { | ||
func keyboardWillShow(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) { } | ||
func keyboardWillHide(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) { } | ||
func keyboardDidShow(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) { } | ||
func keyboardDidHide(keyboardHeight: CGFloat, animationDuration: TimeInterval, animationCurve: UIView.AnimationCurve) { } | ||
} | ||
|
||
/// A convenience utility that eases responding to keyboard appearance events by | ||
/// wrapping around the keyboard appearance notifications. | ||
/// | ||
/// The supported appearance methods are defined by the **KeyboardObserverDelegate**. | ||
public final class KeyboardObserver { | ||
/// The delegate to notify of keyboard appearance events. | ||
public weak var delegate: KeyboardObserverDelegate? | ||
|
||
/// Initialises a new instance. | ||
/// - parameter delegate: A **KeyboardObserverDelegate** conforming type. Defaults to **nil**. | ||
public init(delegate: KeyboardObserverDelegate? = nil) { | ||
self.delegate = delegate | ||
setupKeyboardObserving() | ||
} | ||
|
||
/// Since the **KeyboardObserver** will (in most cases) be defined as a **lazy var**, this method | ||
/// provides a sensical way of triggering the instance creation. | ||
public func observe() { } | ||
} | ||
|
||
private extension KeyboardObserver { | ||
func setupKeyboardObserving() { | ||
_ = NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { [weak self] in | ||
self?.processKeyboardNotification($0) { self?.delegate?.keyboardWillShow(keyboardHeight: $0, animationDuration: $1, animationCurve: $2) } | ||
} | ||
_ = NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: nil) { [weak self] in | ||
self?.processKeyboardNotification($0) { self?.delegate?.keyboardWillHide(keyboardHeight: $0, animationDuration: $1, animationCurve: $2) } | ||
} | ||
_ = NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidShowNotification, object: nil, queue: nil) { [weak self] in | ||
self?.processKeyboardNotification($0) { self?.delegate?.keyboardDidShow(keyboardHeight: $0, animationDuration: $1, animationCurve: $2) } | ||
} | ||
_ = NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification, object: nil, queue: nil) { [weak self] in | ||
self?.processKeyboardNotification($0) { self?.delegate?.keyboardDidHide(keyboardHeight: $0, animationDuration: $1, animationCurve: $2) } | ||
} | ||
} | ||
|
||
func processKeyboardNotification(_ notification: Foundation.Notification, processingHandler: ((CGFloat, TimeInterval, UIView.AnimationCurve) -> Void)?) { | ||
guard | ||
let keyboardHeight = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height, | ||
let animationDuration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue, | ||
let animationCurveRawValue = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.intValue, | ||
let animationCurve = UIView.AnimationCurve(rawValue: animationCurveRawValue) else { | ||
return | ||
} | ||
processingHandler?(keyboardHeight, animationDuration, animationCurve) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// | ||
// PropertyWrappers.swift | ||
// Template | ||
// | ||
// Created by Domagoj Kulundzic on 02/10/2019. | ||
// Copyright © 2019 Martian & Machine. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
@propertyWrapper | ||
public struct UserDefault<T> { | ||
public let key: String | ||
public let defaultValue: T | ||
|
||
public init(_ key: String, defaultValue: T) { | ||
self.key = key | ||
self.defaultValue = defaultValue | ||
} | ||
|
||
public var wrappedValue: T { | ||
get { return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue } | ||
set { UserDefaults.standard.set(newValue, forKey: key) } | ||
} | ||
} | ||
|
||
@propertyWrapper | ||
public struct Atomic<T> { | ||
private var value: T | ||
private let lock = NSLock() | ||
|
||
public init(wrappedValue value: T) { | ||
self.value = value | ||
} | ||
|
||
public var wrappedValue: T { | ||
get { return load() } | ||
set { store(newValue: newValue) } | ||
} | ||
|
||
public func load() -> T { | ||
lock.lock() | ||
defer { lock.unlock() } | ||
return value | ||
} | ||
|
||
public mutating func store(newValue: T) { | ||
lock.lock() | ||
defer { lock.unlock() } | ||
value = newValue | ||
} | ||
} |
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
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
Oops, something went wrong.