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 / String+Extensions.swift
Created December 18, 2017 16:17
Encode String for URL param or request body
//Both implementations thanks to https://useyourloaf.com/blog/how-to-percent-encode-a-url-string/
//Upgraded/cleaned up for Swift 4
Extension String {
func percentEncodedForRFC3986() -> String? {
let unreserved = "-._~/?"
var allowed = CharacterSet.alphanumerics
allowed.insert(charactersIn: unreserved)
return self.addingPercentEncoding(withAllowedCharacters: allowed)
}
@Winchariot
Winchariot / ValueMaker.swift
Created September 27, 2019 16:16
Generic interface to service that can return many different types
//I am some 3P service. I can be asked for many different types of values.
class ValueMaker {
static func makeBool() -> Bool { return true }
static func makeInt() -> Int { return 3 }
}
//I am a 1P abstraction over that service.
// I want to save effort in the rest of my codebase by exposing 1 func for getting values,
// instead of needing a different func for each possible type our 3P service can vend. So I use a func with a generic return type.
func genericMaker<T: TypeEmittedByOur3PService>() -> T? {
@Winchariot
Winchariot / CompositeViewController.swift
Created September 27, 2019 16:46
VC Containment / Child View Controller hierarchy
import UIKit
//I represent a screen in my app that is relatively complicated. Suppose I'm a sort of scrollable activity feed in a financial app;
// I may have sections for balances, alerts, recent activity, credit score, a financial checkup quiz, etc.
// Separating those sections into their own child VCs is great for splitting up the workload and separating the code.
// Then I, the parent VC, can easily compose my feed using any subset of these child VCs and in any order using view controller containment.
class CompositeViewController: UIViewController {
private let scrollView: UIView?
@Winchariot
Winchariot / KeyboardAccessoryView.swift
Last active November 22, 2023 14:26
UIToolbar with a right-aligned "Done" button, for use as a keyboard accessory view
lazy var accessoryToolbarWithDoneButton: UIToolbar = {
let toolbar = UIToolbar(frame: CGRect.zero)
//only needs to be flexible in the dimension(s) you want it to be
//https://stackoverflow.com/questions/31822504/how-can-i-increase-the-height-of-an-inputaccessoryview
toolbar.autoresizingMask = [.flexibleWidth, .flexibleHeight]
let leftSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(keyboardDoneButtonTapped(_:)))
toolbar.items = [leftSpace, doneButton]
@Winchariot
Winchariot / .gitignore
Last active October 8, 2019 18:52
iOS template gitignore
#if using Cocoapods
Pods/
#if using bundler to manage Cocoapods version
.bundle
vendor/
.DS_Store
.idea
*.swp
@Winchariot
Winchariot / iPhoneModel.swift
Created October 22, 2019 19:57
Determine iPhone model... ish
//Phone model is not provided officially by any Cocoa API.
//It can be narrowed down to a few different models by checking the screen dimensions, but this shouldn't be relied upon
// and should NEVER drive any business logic.
//A good use for such knowledge is for something like error logging.
//https://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions
static var iPhoneModel: String? {
guard UIDevice().userInterfaceIdiom == .phone else { return nil }
switch UIScreen.main.nativeBounds.height {
case 1136: