Skip to content

Instantly share code, notes, and snippets.

// Swift's untyped errors are a goddam PiTA. Here's the pattern I use to try to work around this.
// The goal is basically to try to guarantee that every throwing function in the app throws an
// ApplicationError instead of some unknown error type. We can't actually enforce this statically
// But by following this convention we can simplify error handling
enum ApplicationError: Error, CustomStringConvertible {
// These are application-specific errors that may need special treatment
case specificError1
case specificError2(SomeType)
@nicklockwood
nicklockwood / error-propagation.swift
Last active August 17, 2017 06:56
Typed error use-case example
enum ValueError: Error {
case notFound
case typeMismatch
}
struct PropertyError: Error {
let name: String
let error: ValueError
}

A very basic JSON parser, written in [new language]. Only supports String, Int and Array so far.

json := "[42, \"hello\", [\"good\", \"bye\"]]"

JSON = String|Int|[JSON] // TODO: true, false, null, object

skipSpace(json: String) String {
    input := json
    while input.first == " " {
@nicklockwood
nicklockwood / wishlist.md
Last active June 9, 2016 15:40
App Store Wishlist

App Store Wishlist

Some changes (besides the subscriptions features added recently) that I'd like to see in the App Store.

NOTE: This is in no way an attempt at an exhaustive list of all things wrong with the App Store. The focus of this list is mostly around improvements to make it easier for developers to make money from their apps without annoying customers. Other problems such as the broken review process, or inability to contact customers directly, etc. are out of scope.

  • Time or feature-limited demos with IAP to get full version. You could argue that this is already possible, but time-limits are against App Store policy, and apps that do it appear in the "Free" section with "Offers IAP" messaging, making them indistinguishable from pay-to-win junk. These would appear under "Paid" (and/or in their own category) and would have clear messaging that this was a free trial of a paid app. There would be other benefits too: You'd be able to gift a copy of the full app to someone witho
@nicklockwood
nicklockwood / gist:493da04de6ea5cbc7a7e
Last active December 28, 2016 16:02
Animating layer contents when bounds changes
@interface AnimatedContentsLayer: CALayer
@property (nonatomic, assign) CGSize animatedSize;
@end
@implementation AnimatedContentsLayer
@dynamic animatedSize;
@nicklockwood
nicklockwood / gist:21495c2015fd2dda56cf
Last active August 13, 2020 13:57
Thoughts on Swift 2 Errors

Thoughts on Swift 2 Errors

When Swift was first announced, I was gratified to see that one of the (few) philosophies that it shared with Objective-C was that exceptions should not be used for control flow, only for highlighting fatal programming errors at development time.

So it came as a surprise to me when Swift 2 brought (What appeared to be) traditional exception handling to the language.

Similarly surprised were the functional Swift programmers, who had put their faith in the Haskell-style approach to error handling, where every function returns an enum (or monad, if you like) containing either a valid result or an error. This seemed like a natural fit for Swift, so why did Apple instead opt for a solution originally designed for clumsy imperative languages?

I'm going to cover three things in this post:

@nicklockwood
nicklockwood / Carousel.js
Created May 28, 2015 16:24
Simple React Native Module for iCarousel
@nicklockwood
nicklockwood / gist:7dbc0d4834ef6ad5e30f
Last active April 1, 2017 06:16
Matrix math in Swift using Accelerate framework
import Accelerate
struct Matrix4 {
var m11: Float
var m12: Float
var m13: Float
var m14: Float
var m21: Float
var m22: Float
var m23: Float
@nicklockwood
nicklockwood / gist:54c87830ed80de6eae27
Created October 25, 2014 19:35
Combining CryptoCoding and FastCoding
- (void)writeObject:(id)object toFile:(NSString *)file withPassword:(NSString *)password
{
NSData *data = [FastCoder dataWithRootObject:object];
CryptoArchive *archive = [[CryptoArchive alloc] initWithRootObject:data password:password];
data = [FastCoder dataWithRootObject:archive];
[data writeToFile:file atomically:YES];
}
- (id)readObjectFromFile:(NSString *)file withPassword:(NSString *)password
{
@nicklockwood
nicklockwood / gist:e940105c6c0a62b6a0b7
Last active August 29, 2015 14:06
Mutable collection worst case
//here is an array factory method
@interface Foo: NSObject
@end
@implementation Foo
+ (NSArray *)newArray
{