Skip to content

Instantly share code, notes, and snippets.

Avatar

Rob Napier rnapier

View GitHub Profile
View LengthLimitedTextField.swift
struct LengthLimitedTextField: UIViewRepresentable {
var title: String
@Binding var text: String
var maxLength: Int
var onCommit: () -> Void
init(_ title: String, text: Binding<String>, maxLength: Int = 255, onCommit: @escaping () -> Void) {
self.title = title
self._text = text
self.maxLength = maxLength
@rnapier
rnapier / pointvector.swift
Created Sep 14, 2016
Point and vector operations
View pointvector.swift
// Vectors can be inverted
private prefix func - (operand: CGVector) -> CGVector {
return CGVector(dx: -operand.dx, dy: -operand.dy)
}
// Vectors can be added and subtracted
private func + (lhs: CGVector, rhs: CGVector) -> CGVector {
return CGVector(dx: lhs.dx + rhs.dx, dy: lhs.dy + rhs.dy)
}
private func - (lhs: CGVector, rhs: CGVector) -> CGVector {
View TitleDecodable.swift
// From https://stackoverflow.com/questions/54129682/use-swift-codable-to-decode-json-with-values-as-keys
import Foundation
let json = Data("""
{
"7E7-M001" : {
"Drawer1" : {
"101" : {
"Partnumber" : "F101"
},
View decodeJSON.swift
// Based on https://twitter.com/ravibastola/status/1249555595285291008?s=20
extension Bundle {
// This is synchronous, which is bad if called on the main queue.
func decodeJSON<T: Decodable>(_ type: T.Type = T.self, from filename: String) throws -> T {
guard let path = self.url(forResource: filename, withExtension: nil) else {
throw NSError(domain: NSCocoaErrorDomain,
code: CocoaError.fileNoSuchFile.rawValue,
userInfo: [NSFilePathErrorKey: filename])
}
View JSONStringConvertible.swift
import Foundation
public protocol JSONStringConvertible: class {
var jsonString: String { get }
}
extension Logger {
// Converts an arbitrary object into some that is JSON-safe
static func makeJSONObject(_ object: Any) -> Any {
if let jsonObj = object as? JSONStringConvertible {
@rnapier
rnapier / gist:7515273
Created Nov 17, 2013
Exploration of thread priorities vs queue priorities
View gist:7515273
// Main thread priorty = 0.758065
NSLog(@"main:%@:%f", [NSThread currentThread], [NSThread threadPriority]);
// High priority = 0.532258
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"high:%@:%f", [NSThread currentThread], [NSThread threadPriority]);
// run forever! Note that other queues still happily process, even though our high-priority block never ends
while(1) {}
});
@rnapier
rnapier / TypeCoder.swift
Last active Jun 13, 2019
Decode based on a type field
View TypeCoder.swift
import Foundation
/// Simple example of decoding different values based on a "type" field
let json = Data("""
[{
"type": "user",
"name": "Alice"
},
{
View APIClient.swift
import Foundation
// Provides a nice bare-init for ID types
protocol IDType: Codable, Hashable {
associatedtype Value
var value: Value { get }
init(value: Value)
}
extension IDType {
View RepositoryStorage.swift
// Fully type-erased solution for
// https://stackoverflow.com/questions/55549318/avoiding-type-erasure-when-implementing-the-repository-pattern/55550454
// I don't like type-erasers like this; I believe it can be sliced a better way.
// Compare https://gist.github.com/rnapier/f7f0fa6202b0d6586af188635f54b28b, which I like, but relies on a common
// currency of serializing everything to Data and working with that instead of having storage that can deals with Element
// directly.
// FURTHER THOUGHTS:
//
// This example is interesting because, like so many of these toy projects, its design is completely broken and wouldn't
View DataStore.swift
import Foundation
protocol DataStorage {
subscript(identifier: String) -> Data? { get set }
}
extension UserDefaults: DataStorage {
subscript(identifier: String) -> Data? {
get { return data(forKey: identifier) }
set { set(newValue, forKey: identifier) }