Skip to content

Instantly share code, notes, and snippets.

View LukeSmith16's full-sized avatar

Luke Smith LukeSmith16

  • Northamptonshire, UK
View GitHub Profile
@LukeSmith16
LukeSmith16 / LoginViewModel.swift
Last active August 31, 2019 22:49
LoginViewModel - An example of how a LoginViewModel might look like for a login module, including: validation, talking to a repository, coordinator and view (via delegation).
import Foundation
protocol LoginViewModelInterface {
var viewDelegate: LoginViewModelDelegate? {get set}
func handleLogin(username: String, password: String)
}
/// You're coordinator implements this
protocol LoginViewModelCoordinatorDelegate: class {
func goToLoginSuccessful()
@LukeSmith16
LukeSmith16 / NetworkStatus.swift
Last active August 31, 2019 22:51
NetworkStatus - Monitor the network connection and subscribe for connectivity changes, uses the Network framework. I still don't think this is a perfect implementation to achieve this sort of behaviour but it's not too bad.
import Network
protocol NetworkStatusChangedDelegate {
func networkStatusChanged(_ status: NetworkConnection)
}
enum NetworkConnection {
case Connected
case Disconnected
}
@LukeSmith16
LukeSmith16 / Font.swift
Last active October 10, 2019 17:26
Font - As part of implementing a mobile design system interacting with fonts is a key element. This is a little wrapper around UIFont and makes managing fonts in your application a lot more easier and has a lot of room to scale with the project.
import UIKit
struct Font {
enum FontType {
case installed(FontName)
case custom(String)
case system
case systemBold
case systemItatic
case systemWeighted(weight: Double)
@LukeSmith16
LukeSmith16 / Cache.swift
Created September 29, 2019 11:47
A thin wrapper around NSCache
/// Removes stale objects after 12 hours.
final class Cache<Key: Hashable, Value> {
private let wrapped = NSCache<WrappedKey, Entry>()
private let dateProvider: () -> Date
private let entryLifetime: TimeInterval
init(dateProvider: @escaping () -> Date = Date.init,
entryLifetime: TimeInterval = 12 * 60 * 60) {
self.dateProvider = dateProvider
self.entryLifetime = entryLifetime
@LukeSmith16
LukeSmith16 / UserDefault.swift
Last active October 19, 2019 06:32
A good example of how we can use property wrappers in Swift 5 to make working with UserDefaults so much more cleaner. We can define a 'UserDefaultsConfig' type to contain all the values we want to persist making it easier to read!
@propertyWrapper
struct UserDefault<T> {
let key: String
let defaultValue: T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
@LukeSmith16
LukeSmith16 / ShoppingList.swift
Last active April 3, 2023 13:33
Example domain model with mock helper extension
struct ShoppingList: Codable {
let items: [String]
}
extension ShoppingList {
static func mock(with items: [String] = []) -> Self {
.init(items: items)
}
}
@LukeSmith16
LukeSmith16 / MockResponse.swift
Last active April 3, 2023 13:47
Responsible for creating a custom mock response and returning it given a path, domain model and status code
public struct MockResponse {
struct Content {
let statusCode: Int
let data: Data
}
enum Response {
case success(Content)
case error(Error)
@LukeSmith16
LukeSmith16 / UITestConnectionHandler.swift
Last active April 3, 2023 13:55
A custom URLProtocol subclass to handle returning mock data for network service requests for UITests
final class UITestConnectionHandler: URLProtocol {
private static var allowedResponses: [URL: MockResponse] = [:]
static func setAllowedResponse(with response: MockResponse) {
allowedResponses[response.url] = response
}
override class func canInit(with request: URLRequest) -> Bool {
@LukeSmith16
LukeSmith16 / ProcessInfo+UITests.swift
Last active April 2, 2023 17:17
An extension on ProcessInfo that checks if we are in a testing environment
extension ProcessInfo {
static var isRunningUITests: Bool {
processInfo.arguments.contains("UITests")
}
}
@LukeSmith16
LukeSmith16 / MyApp.swift
Last active April 2, 2023 18:46
Register a custom UITestConnectionManager in our app if we are running a testing environment
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
#if DEBUG
guard ProcessInfo.isRunningUITests else { return }