I decided to skip posting last week because I was on vacation and ended up doing significantly more actual relaxing than I usually do and stayed away from xCode for the most part.
This week, I’m unexpectedly skipping posting again because I have other things weighing on my mind.
I will be back next week.
A Broad, but Not Deep Implementation of Dithering
So after about a week of fiddling, I now have a mostly complete set of dithering functions. I still would like to add a few features, in particular bleed reduction and different patterns for traversing the image data and applying the dither.
The things that are missing are optimization, and having the code connected to a real app. Right now I think the code needs some serious optimization, but that may change when the code isn’t running in a playground.
After seeing how much optimization is needed, I’ll be picking apart some of the Swift implementation of dithering, but for now feel free to check out the state of the library on github, I have some examples of output from the playground ready to show off:
Sierra (3row) Dithered
Not the Procrastinating Kind Though
In an attempt to batch process some images to a printable black and white format, I tried to use ImageMagick to resize the content, then dither from grayscale to true black and white. After a lot of fiddling, I got an OK process working using random dithering, but I’d really like to have a system that applies a more advanced dither, so I’m tooling around with core image and wrote a basic thresholding function, and can write thresholded colors back to the image.
The next step is going to be working out the error diffusion, which seems relatively straightforward from the math that I read, and I’ll be interested to actually implement the diffusion. There’s a lot of potential for later optimization as right now I’m iterating over a pointer of RGBA values and brute forcing the math. Hopefully by next week I’ll have a playground with with dithering working and ready to show off.
Less Code, More Control, In Theory
One of the many interesting design decisions to look at when designing an app is how to encapsulate talking to the API. This isn’t a question that has a universal answer, and there are a lot of libraries that solve parts of the problem very well, but the final combination that takes you from hitting the API to displaying the result (including errors) isn’t a turn-key process.
In an effort to build on a recent services layer that I worked with, I went all in with operation, and tried to reduce duplicated code with liberal use of generics and protocols. At a high level the design consists of:
APIClient: Holds high level state for the API such as top level url session configuration, is loaded by
APIService objects on init.
APIService: Manages which operation queue each step of API progress is handled on, and coordinates dependancies between “run network task”, “parse data” and “completion” tasks. Most of the logic here is implemented in the
perform(action:completion) -> [Operation] function.
APIAction: Defines how to talk to each endpoint on the server, includes all of the configuration details for each request, and the functionality for parsing the response out of the returned data from the server.
So far with a whopping one endpoint and some unit tests, it’s been properly flexible and doesn’t require spreading configuration code over multiple files to hit a new endpoint, and clever use of subclassing means that most of the shared configuration only needs to be written once.
It’s too early to judge if this system is a total win, but it’s a promising start. It also feels very strange that I didn’t write most of the code for the final product. I code reviewed it, and I wrote the initial spec, but another developer on the team built the thing.
Hopefully a Plan that Works
For the first time since starting at Raizlabs, I’m the lead developer on a project. It’s not the first time running a project, but it is my first time running a project with a real process, and with a real team.
One of the great resources that I have getting this thing off the ground is some well designed bits of process designed to help in planning through the entire project. The first big part of this is a formal process for writing up the plan for the project, then making a presentation to other developers to see what they think of the thing.
Having to think through the “gotchas” list, plan through the data model, and put together a coherent plan for the services layer of the app has helped get some early plans for shape and structure in place, and will hopefully make for a better execution now that the project is starting to get underway.
The other interesting side effect to this is that I’ve been too busy planning to write code for the project, so I’ve been forced to write up / talk through bit sized bits of project architecture to then hand off to the other developer on the project to implement. It’s been interesting seeing bits of plan that I’ve assembled come together, especially as my plan for services layer involves layering generics, protocols, and Operations in a slightly novel way, hopefully saving a lot of fuss and effort in the longer run.