Samuel Goodwin

Samuel Goodwin

91 posts Samuel Goodwin
  1. How I Approach Rat-Nest CoreData Projects

    Part of my job involves working with existing projects, some with overly complicated Core Data implementations. Usually clients request that I help fix performance problems in the project or at least clean them up. Here is how I approach each project: 1: Clear out the cobwebs First thing I do is look through the whole project for unused classes, methods, variables, etc. For Objective-C projects, this is the one thing I use AppCode for. For Swift projects, there are tools such as fus to help. For one project, I was able to delete 30 thousand lines of code this way. No refactoring yet, simply deleting unused stuff. Most projects that have been around for longer than 6 months have unused bits to delete I've found. 2: Refactor Next I look for eveywhere an NSManagedObjectContext is used. Anywhere a context is used, the operation/function/class should be told what context

    Samuel Goodwin
  2. Core Data Performance

    My talk about Core Data performance was recorded here at a local meetup. Enjoy! Samuel Goodwin - Core Data Performance from Swift Usergroup Netherlands on Vimeo.

    Samuel Goodwin
  3. Ghost's API

    Ghost is a blogging platform written in Node JS that was released a few years ago after a successful Kickstarter campaign. They promised a blogging platform without all the complications of Wordpress and even partnered with companies like Digital Ocean to make it easy for users to try and use. One of the promises of Ghost was that the web admin tool was built using an API from day one rather than adding an API after the fact. It used EmberJS and provided a fairly nice web interface. The API, however, remained private and only worked with this JS front-end. Years later, they added the ability for third party clients to authenticate and access the API, but it was still a private API and therefore subject to change whenever they felt like it. Last year, they even released a "desktop" client. It made use of Electron to essentially just provide

    Samuel Goodwin
  4. The Case of the Broken Buttons

    On a client project the other day, I spent most of the day tracking down a rather serious bug. All UIBarButtonItems were nearly un-tappable on iOS 11. These were not especially crafty buttons, most of them were using either an icon of reasonable size or a title. Some were even using the system standard items. None of them worked. Icons were un-tappable, back buttons were only tappable on the edges. All users on iOS 11 were left out in the cold and would not be happy. Instantly I assumed there was some clever code hiding somewhere that was causing the problem. I searched the project (this was a fairly new client so I did not know all of what lurked there) for subclasses of UINavigationController and UINavigationBar. I looked for categories and extensions on UIBarButtonItem as well as the navigation classes. I even assumed the problem was with one of

    Samuel Goodwin
  5. How To Write IRC: Part 6

    This is a continuation of the article published yesterday: How To Write IRC: Part 5 Framework-ification After all this work, it was time to make the actual framework. I started by making a new project with the Cocoa Framework template and copying over the important files from my demo project. Next, I setup support for Carthage for people to bring this into their own apps. I could support Cocoapods as well, but I don't especially care, so I left that for someone to submit a pull request to add. Supporting Carthage was fairly straightforward, I followed the directions on their front page without much of an issue. One minor thing I ran into: because I was developing this using the latest Xcode Beta and not normal Xcode, I needed to use xcode-select to tell command-line xcodebuild (which Carthage uses) to use my beta version of Xcode instead of the default.

    Samuel Goodwin
  6. How To Write IRC: Part 5

    This is a continuation of the article published yesterday: How To Write IRC: Part 4 More Tests! Next larger feature I wanted to test was joining a channel. As I planned before, joining a channel should create a new object to give developers a way to interact. For this I modified the first test I wrote which had the basic parts laid out already. It didn't really test anything anyway, so I made it do something useful. func testJoiningAChannel() { let user = IRCUser(username: "sgoodwin", realName: "Samuel Goodwin", nick: "mukman") let server = IRCServer.connect("127.0.0.1", port: 6667, user: user, session: fakeSession) let channel = server.join("clearlyafakechannel") struct ChannelDelegate: IRCChannelDelegate { let expectation = XCTestExpectation(description: "Any message receieved") func didReceieveMessage(_ channel: IRCChannel, message: String) { expectation.fulfill() } } let channelDelegate = ChannelDelegate() channel.delegate = channelDelegate wait(for: [channelDelegate.expectation], timeout: 1.0) } After clearing out everything not directly related, I was left with

    Samuel Goodwin
  7. How to Write IRC: Part 4

    This is a continuation of the article published yesterday: How To Write IRC: Part 3 Async Integration Testing Some of you might be reading along and think to yourself, "This guy hasn't tested anything! He doesn't assert anything. What kind of lies is he trying to sell?". To that I say, "Give me a minute, it gets better". One of the nice things about code is that nothing you write really needs to be permanent. Especially when you're starting a thing, it's fine if you have to change it a bunch. You don't need to know exactly what you're going to do right when you start. That would be boring. The very next thing I wrote was an actual test with actual assertions. func testServerDelegateGetsServerMessages() { let user = IRCUser(username: "sgoodwin", realName: "Samuel Goodwin", nick: "mukman") let server = IRCServer.connect("irc.freenode.org", port: 6667, user: user) struct ServerDelegate: IRCServerDelegate { var

    Samuel Goodwin
  8. How To Write IRC: Part 3

    This is a continuation of the article published yesterday: How To Write IRC: Part 2 Defining the API Before you run off and make a framework, it can be helpful to do a bit of brainstorming and plotting or scheming first. For this part I pulled out a sweet notebook and my fancy pencil. After some doodling and discussion with a friend of mine, I came up with this: I wanted the idea of a channel to be a first-class object rather than an interface where you send along the channel name as a string and say "hey send this message to this channel". Directly having a channel object to send messages to sounded nicer to me. With this vague idea in mind, I started writing tests. This way I could work out exactly what the API would look like by attempting to actually use the API. After some debate

    Samuel Goodwin
  9. How To Write IRC: Part 2

    This is a continuation of the article published yesterday: How To Write IRC: Part 1 Spike! When I write a framework, I don't start by making a framework. First I mess around and build what you might call a "spike" to get an vague idea how things work. I was fairly familiar with the IRC protocol when I started, but not this new API from Apple. Writing something right off the bat with tests is quite difficult if you're not even very sure what you need to make your code do. After some time to play around, I had a better sense of direction and could be confident writing tests. Walking Skeleton Last thing I needed before I could write any tests was the skeleton of an app. You can see what I wrote in this initial commit on Github. Mostly it is Xcode's new-project template for a Mac app,

    Samuel Goodwin
  10. How To Write IRC: Part 1

    IRC is a fairly old protocol for chatting with people on the internet. It's not super popular these days because even more technical people have migrated to things like Slack or Hipchat which may or may not be more friendly to use. Still, I decided to try to write a library for interacting with IRC for a few reasons: I think a big reason for Slack/Hipchat popularity over IRC is the clients. Every IRC client I've ever tried seems fairly technical and does not try to simplify the experience very much. The library and my writing explaining it can serve as nice example of how to make a framework and how to write Swift in general using tests. Even if it never gets used in an exciting IRC client. The library can also serve as an example for implementing support for an internet protocol that isn't already supported for

    Samuel Goodwin Featured
  11. Making SwiftKilo Part 2: Raw mode

    In the next chapter of the tutorial, I went through the steps to enable raw mode. In a typical command line app, you print some things on the screen and maybe wait for input for the user on the next line. The terminal is setup by default to send your program this input one line at a time which means waiting until the user hits return/enter. For a text editor where we want to handle things like keyboard shortcuts and special characters, this isn't good enough. Fortunately, the terminal can be told to change its behavior and send each individual keypress to your program one at a time. Unfortunately, it takes several steps to do this. Also, since you're changing the behavior of your terminal for your program, you need to make sure you turn the settings back to normal when your program is done. Many of the functions

    Samuel Goodwin
  12. Core Data unique constraints

    There's a bug with Core Data such that if you have two entities, A and B, with a one-to-one relationship between them, that relationship will not be setup properly. This bug doesn't care wether you do your work in Objective-C or Swift or both. The steps to reproduce are as follows: Create two entities, one A and one B. Give each a property, such as name. Add a one-to-one relationship between the two. Generate the class file for each by any method you wish. Doesn't matter which. In your app, create an instance of each and link them by their relationship property. let context = persistentContainer.viewContext let a = A(context: context) a.name = "I'm alive" let b = B(context: context) b.name = "I'm also alive" a.thing = b try! context.save() Fetch all A entities and print out their B's. Do the same the other away around too. let context

    Samuel Goodwin
  13. Making SwiftKilo Part 1: Setup

    Some time ago, I read about AntiRez writing a text editor in C. This dude is pretty hardcore in C and does things like maintain Redis, an in-memory database nearly every startup you ever heard of is using or will soon use. It was super cool to flip through and read about the editor. I was especially impressed by his ability to add search and syntax highlighting even. Some time later, Snaptoken wrote a very thorough tutorial explaining how to make the editor step by step instead of browsing through Antirez's final product. At this point I thought it might be interesting to follow along with the tutorial, but to do it in Swift and write about the differences. Maybe the Swift version will take less lines of code? Maybe more? The differences between the Swift and C versions of this editor start right at the beginning of this tutorial.

    Samuel Goodwin
  14. You Belong Here

    Everyone around you right now, all those people who intimidate you or make you feel like you're a fraud have been where you are now. Nobody leaped from a test-tube as a fully-formed senior developer. They all had to start with no clue and find out how to move forward. Many of those people remember what it's like to be where you are and will be happy to help get you moving. The others you can ignore because they're either heartless monsters or drowning in their own issues. Even those of us who have been at it for a while experience what we call "Imposter Syndrome". That's where you're an experienced developer and still feel like maybe you have no clue what you're doing and everyone around you might soon figure that out. A career in software development can mostly be a career spent starting things you don't understand (mabye

    Samuel Goodwin
  15. Turning 30

    The people I looked up to when I learned to program are now getting to about 50 and I've seen many of them suffer from stress and endless sitting. I've seen some try to do something about it and several succeed even. This has motivated me to make sure I take care of myself. In high school I was forced to play sports (which turned out to be a good thing). In college I discovered skateboarding and loved doing it so much that I never had to think about keeping active. Lately I've taken specific action to make sure health and strength don't just accidentally happen. I've tried working with a personal trainer, capoeira training, and velodrome training, and have arrived at my own calisthenics plan which continues to make me stronger. This time last year I could not do one pull up, for example, to save my life on

    Samuel Goodwin
  16. Adventures in Vimscript

    Last week Vim 8.0 came out. I was pretty excited because, among other things, Vim now supports asynchronously running code in plugins. Until now, if your plugin code took time (like compiling your project or some auto-completion code) it would cause Vim to freeze until it was finished. No typing, no moving the cursor, you could do nothing. This has been one of the things that sucked about Vim compared to the many other good editors that exist. There are projects like neovim which are attempts to make a version of Vim which could handle asynchronous plugins, but the last time I tried this it caused a kernel panic (I'm sure that's fixed by now). Now that Vim supports it out of the box, I was excited to dig in and see if I could live my dream of doing iOS development in Vim. There are a few things

    Samuel Goodwin
  17. Modifier Keys

    A keyboard big enough to have all the possible letters and symbols you would need to type when coding or even writing an email would need to be huge. You'd need a key for every letter, lower case and upper case, including the letters less common in English like é or æ, every symbol like , and ; and "", and other useful keys like return and backspace. Back in the day we figured out that this was going to be a bit absurd and different systems developed different ways to allow you to type all these things without a board with 200+ keys. While these systems differed, they converged on some similar concepts. In order to type more symbols with less keys, we started making use of modifier keys. Using one or more modifier keys in concert with other existing keys, you get many more letters and symbols than you get on

    Samuel Goodwin
  18. Transference

    One of the signs of an expert programmer is a thing I call transference. I learned about it while reading a book about learning to play music and it applies to programmers as well. A novice musician is hard at work studying exactly what to do with their fingers and exactly the patterns necessary to play a piece of music. With enough practice even, they can play pieces perfectly and beautifully. An expert musician, however, sees past the exact patterns and sees the bigger picture: the keys and the chords. Learning a piece of music becomes much faster because they recognize the similarities between that piece and others they have already learned. Many popular songs from the last 39 years, for example, use the exact same chord progressions and are maybe just played in a different key or speed. When a musician makes it past that initial barrier of simply

    Samuel Goodwin
  19. Building the KC60

    Recently I have been super pumped on mechanical keyboards. I found one small enough to easily use when I'm on the couch or in a café which made it easier to spend most of my time using one and get used to it. At this point it feels weird and uncomfortable when I use my regular laptop keyboard! Keyboards can be a bit of a rabbit hole. Once you get into it, there are opportunities to tweak and change things for quite some time. Something even as simple sounding as changing the caps, maybe for a popular set like this can bring on many choices. What kind or material do you want your caps made out of? Do you want letters printed on the top? the side? not at all? what color? what shape? so many choices! I went even further down and decided that, instead of choosing a keyboard

    Samuel Goodwin Featured
  20. Fun With Typing

    As a developer, I spend quite a bit of time typing. Typing code, typing email responses to clients and recruiters, typing jokes in Slack. As a child, I was fortunate enough to have access to a computer at home and the internet. Our computer was not fancy enough though to play any of the games the other kids were playing, like Starcraft or Counter Strike, so I spent quite a bit of time playing text-based games instead. No need for graphics cards when all your computer needs to do is show text scrolling by. No need for a fast internet connection even. Playing these games involved so much typing I could not help but get faster. I had no formal typing training, so my methods were far from conventional, but they worked. Years later I read articles like Why You Should Use a Mechanical Keyboard and bought a fancy new

    Samuel Goodwin