Skip to content

Instantly share code, notes, and snippets.

View Winchariot's full-sized avatar

Jim G Winchariot

  • Austin, TX
View GitHub Profile
@Winchariot
Winchariot / AppDelegate.swift
Created December 3, 2017 21:11
Set app's root VC in code
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = MyInitialViewController()
return true
}
@Winchariot
Winchariot / AppDelegate.swift
Last active September 27, 2019 16:03
3-phase app startup pattern
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
doPreUISetup()
doWindowSetup()
doPostUISetup()
return true
}
func doPreUISetup() {
//place code here that is required for app startup, especially anything the UI might rely on:
@Winchariot
Winchariot / MyPlistLoader.swift
Last active December 3, 2017 21:31
Load data from a plist
func loadValueFromPlist() {
guard let plistPath: String = Bundle.main.path(forResource: "Info", ofType: "plist"),
let dict = NSDictionary(contentsOfFile: plistPath) else { return }
if let myValue = dict["myKey"] as? String {
//make use of myValue
}
}
@Winchariot
Winchariot / MyView.swift
Last active December 3, 2017 22:35
Instantiate and use in code a custom UIView subclass that you designed in IB
//MyView was designed in IB (xib not included in this gist)
// In IB, you need not set the file's owner, as Bundle.main.loadNibNamed() sets that for you.
// You should, however, still set its custom class on the View
import UIKit
class MyView: UIView {
class func createFromNib() -> MyView {
//loadNibNamed returns all of the top-level objects in that nib, but .first is always your UIView object
return Bundle.main.loadNibNamed("MyView", owner: self, options: nil)?.first as! MyView
@Winchariot
Winchariot / MyView.swift
Last active December 3, 2017 22:34
Use a custom UIView that you designed in IB as a building block in another ViewController
//This is a valuable method to accomplish the following:
// You designed your view, MyView, in IB in its own .xib
// You have a VC, MyViewController, on which you want to lay out 1 or more MyView elements
//Here are the steps to follow after your view + VC have been laid out:
// In IB on MyViewController, lay out a placeholder View and set its custom class to MyView
// In IB on MyView, ensure the file's owner is set to MyView
// (It then becomes unnecessary to set the custom class on MyView in IB. Let it think it's just a UIView)
import UIKit
@Winchariot
Winchariot / ClientClass+Init.swift
Created December 4, 2017 17:02
Simple class-level Dependency Injection
//By separating the convenience init into its own file, you can instantiate ClientClass() easily in your project.
// Your unit tests only need to include the ClientClass.swift source and not this init
extension ClientClass {
convenience init() {
self.init(myDependency: MyDependencyConcreteImplementation())
}
}
@Winchariot
Winchariot / CodableType.swift
Created December 12, 2017 15:53
Codable types
//It is generally nicest to make the variables in your codable types optional, so your decoding can still succeed
// even if the JSON is missing 1 or more fields
struct MyCodableType: Codable {
var myVar1: String?
var myVar2: [Bool]?
var myVar3: SomeOtherCodableType?
//A CodingKeys enum is required if your variable names don't match the JSON names, case-sensitive.
// The cases here should match your clientside variable names, and the associated values should match the JSON
@Winchariot
Winchariot / QuestionnaireFeedback.swift
Last active December 14, 2017 16:06
Encodable enum with associated values - keyed container
enum QuestionnaireFeedback {
case numeric(Int)
case text(String)
}
extension QuestionnaireFeedback: Encodable {
enum CodableKeys: String, CodingKey {
case numeric
case text
}
@Winchariot
Winchariot / QuestionnaireFeedback.swift
Created December 14, 2017 16:05
Encodable enum with associated values - single value container
//Encoding an enum with associated values is super simple.
enum Answer {
case rating(Int)
case freetextResponse(String)
}
extension Answer: Encodable {
@Winchariot
Winchariot / String+Extensions.swift
Created December 18, 2017 16:06
Validate nonempty string
extension String {
//Validate both that a string is nonempty and that it contains something besides whitespace.
// Useful for driving things like enabling a submit button only when a user has entered (meaningful) text
var isVisuallyEmpty: Bool {
return self.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
}
}