BiteofanApple Archive About Apps Microblog Photos Links
by Brian Schrader

A Sobering Thought

Posted on Mon, 11 Nov 2019 at 04:18 AM

Rarely do silver bullets actually exist; the truth resists simplicity. Tree planting often looked at as a cheap, effective, and catch-all solution to combatting carbon emissions, but that just isn't true. It's two of those things, sure, but it's not all we need to do. Don't get me wrong, I'm a huge fan of planting trees to help trap and store carbon emissions, but it can't be the only thing we do.

Earlier this morning, I watched a video from The Economist which covered the topic pretty well (there's even more videos and information in the linked article). While the through-line of the video is that tree planting, when done correctly, can have huge benefits and help combat climate change, Professor Simon Lewis drives home a really sobering point right at the end (emphasis mine):

Ultimately though, the trouble with trees tackling climate change is space. There’s just not enough land in the world to plant enough trees to offset all the carbon emissions from fossil fuels. We could say, let’s restore forest on every single piece of land that used to have forest on from before agriculture. And if we did that it would be about 200bn tonnes of carbon. Now that sounds a lot, but to put it in context, that’s about 20 years worth of emissions at present rates.

- Professor Simon Lewis

So go ahead, plant trees.* Just know: we need a lot more than just trees.

* TeamTrees is a super easy way to donate to tree planting, btw.

High-Tech Empires

Posted on Thu, 07 Nov 2019 at 01:20 AM

Ben Thompson →

In the long run, though, it is very problematic that such a powerful player in our democracy has no accountability. Liberty is not simply about laws, or culture, it is also about structure, and it is right to be concerned about the centralized nature of companies like Facebook.

Manton Reece →

Platforms that have as many problems as Facebook does can always be improved, but by design they can never be good enough because their size alone is one of the problems.

A difference in scale can become a difference in kind. Facebook and other large Tech companies have more users than most nations have citizens. We look down on autocratic governments, and will hopefully continue to do so. We can't forget that these large corporations are a new form of the same thing.

We have a words to describe organizations of large enough size that exert control over vastly different groups of people and that aren't answerable to their constituents. We call them autocracies; we call them empires.

Remembering Things is Hard

Posted on Sun, 03 Nov 2019 at 06:59 PM

I'm not very good at remembering things, even simple things, and I'm even worse at grinding (doing a simple or repetitive task more than once). That's one reason why I love being a developer: often times, I can script simple, repetitive, and common tasks.

When it comes to development, although most of my projects leverage some form of automated continuous testing and linting, by the time I've pushed up my code and the tests have run, I've moved on to some other task. This means that when my code has a failing test or a linting error, I have to stop the new thing that I'm doing, stash my changes, and fix the error. I should remember to run the tests before I push my code, but I never do.

So in lieu of doing the hard work to remember to run the tests and becoming a better person in the process, I've written a pre-commit script that runs before I commit my code. That way I can't commit my code without fixing the error, or explicitly ignoring it (with the -n flag).*

* This also helps avoid the unprofessional looking "Fixes linting" commits.

Here's my .git/hooks/pre-commit file for any Django project. Give it a shot yourself and let me know if it helps you write better code.

#! /bin/bash
set -e;
log() { echo "[$(date)] $1"; }

cat << EOF
Running the tests...
You might want to get a coffee. ☕️
log "Linting the code..."
log "Running the tests..."
./ test
log "Done."


Posted on Tue, 08 Oct 2019 at 01:34 AM

Today marks the release of's Fall Update. It's a release I've been working on for months now and it feels great to finally get it out into the world. With this release, is now what I'd wanted it to be when I started dreaming of what a the open web could do. On, you can follow your interests, keep up with the latest news, and join the conversation by starting a blog. I can finally say that the core features I want are in place.

Obviously my goals for have expanded since I originally thought of the idea in 2014 (and began writing it in 2016), so there's still a lot to do.

A New Adventure

Posted on Sun, 18 Aug 2019 at 01:25 AM

Last week, I bought a camera. I've wanted one for a while, but I'd never really looked around for something that would fit my needs. A few of my friends and family are actual photographers, and I knew that I didn't want to do what they do. I'd be carelessly jumping into a deep end to swim with reel big fish.

I haven't owned a dedicated camera in over a decade. Ever since 2010, the only camera I've owned came with an iPhone attached to it. However, while the iPhone X's camera is great, it's just not enough for a whole myriad of situations, and in the last year I've found myself ever more limited by what my phone's camera could and couldn't do.

There's an old adage: "the best camera is the one you have with you", and if I was going to have this camera with me, even a fraction of the time that I have my phone with me, it had to meet some pretty strict qualifications: It had to be really versatile (inter-changeable lenses was a hard requirement), it had to be compact enough to take almost anywhere, and it had to be a camera that could grow with me as I delve into this new-fangled world. So I talked to some people, read a bunch of articles, watched a bunch of reviews, and got this:

I've heard from quite a few people that Sony's α6000 and α6400 are really good for people who want a great camera, but aren't willing to dive into DSLRs. I don't know much about that second bit, but that description matched me to a T. As I've only had it a week so far, my opinions are still riddled with Ney Toy Syndrome. That said, I really like this camera. It's small and light enough to fit in the spare pocket of my daily carry bag, and it uses Sony's E-Mount which means that there's tons of compatible lenses, making it really versatile.

I ended up getting the α6000 mostly because of the price. The α6400 was more than I wanted to spend and anything below the α6000 didn't have a viewfinder, which was a dealbreaker. I'm still rocking the kit lens for now, but I plan on getting a 50/55mm Prime lens pretty soon. Before that though, I need to get a much more intuitive grasp of how to properly use what I have, and it'll probably take me a while to get the basics down.

A Checkpoint in Time

While I'll probably be posting most of the good shots I take to my photoblog, below are a few of my favorite shots from the last week. I'm posting them here so that they serve as a record of my skills as a photographer right now. Hopefully, as time goes on and my skills improve, I'll look back on these pictures like I look back on old code I've written: with fond memories, and mild disgust.

Don't Ban Infinite Scrolling, License Engineers Instead

Posted on Wed, 31 Jul 2019 at 05:46 PM

Yesterday, the Verge reported that Sen. Josh Hawley sponsored a bill that aims to reduce the tech industry’s use of "addictive design" practices by putting a ban on features like infinite scrolling and autoplaying video. While I applaud Congress for focusing on this important issue, the proposed solution is both naive and unproductive. When a surgeon is accused of malpractice, the appropriate solution is not to ban their use of the scalpel, it's to revoke their license.

I have long argued that Software Engineers (especially those at large companies that affect the lives of millions of people) should be licensed. Requiring a license to practice Software Engineering would finally place software in the realm of the other classical engineering fields and require practitioners to use their skills ethically and for the benefit of society. It would also help educate engineers on the risks and trade-offs with the decisions they make and give the government a lever to pull when trying to encourage ethical practices across the industry. Likewise, licensed engineers are able to refuse to implement unethical or unsafe designs when they fear that they could lose their license.

One common argument against this point is that the tech industry is filled with lots of independent developers and others who operate relatively small businesses and that licensing them would put an damper on overall innovation in the industry. However, while we do often require Civil Engineers to have a license, we don't apply the same logic to carpenters, and we can apply the same kinds of criteria to Software Enginering licensure.

We've required licenses for those practicing classical Engineering, Medicine, and Law for a long time1, and those licenses have helped governments and the licensed individuals themselves steer industry practice away from things that can be considered unethical or unsafe. Instead of trying to take powerful tools away from Engineers, we should instead be focused on enabling and educating them to make ethical and societally beneficial decisions. The Internet is part of the infrastructure of our modern world, so let's ensure that the people who build and maintain it have society's best interests at heart.

1 As an aside, we even license hairdressers and locksmiths. If unlocking cars or cutting hair requires a license, why doesn't building software that impacts 20% of the world's population?

The Social Web

Posted on Sun, 28 Jul 2019 at 06:35 AM

Things have been quiet here recently, and that's largely because I've been really busy working on lots of cool new stuff for While the last few months have been full of steady progress, there's still a ways to go before the next set of features are ready for the world. If everything goes according to plan, the next major release should allow premium users to start their own blog on the site.

So far, has been mostly focused on being a good feed reader, and while I think it is, there's so much more that can be done with feeds and blogs than just read them.

Feed Readers are the First Step

I've wanted to support custom blogs since the beginning, and that's largely because I think that by making it easier to both read and write on the open web, we can give people a viable alternative to more traditional social networks and offer them an escape from the problems those platforms have.

Using tools and technologies that have existed for years, the web itself can be a social network, but in order for people to embrace that idea there have to be easy-to-use tools that are new and powerful, but also familiar and approchable, and importantly, there also have to be people to talk to; the web has to feel like a social network.

Pushing Forward

One of the things I've come to strongly believe is that as developers (or as anyone who makes a thing) we can work to push the world toward we think it should be, and I think that the Web can and should be our shared social network.

This is why I'm so excited by what I see as the future for If we want people to move off of the platforms we think are the cause of so many problems in our world, we need to give those people a place to go. Most people aren't going to start a blog and use a feed reader unless we, as the people with the skills to do so, make the Social Web better than Social Media.

Updates on using NSOperation

Posted on Sat, 29 Jun 2019 at 07:31 PM

Last time I talked about NSOperation, I mentioned that I really liked using it to do things like networking and asynchronous operations in my app. Well, I've made a few tweaks to my BackgroundNetworkingController recently (alas a new name was not among them) and I think the new version is even more readable and expressive.

For those who don't know, NSOperation (or just Operation in Swift) is a class that when paired with (NS)OperationQueue allow you to order and track long running and often asynchronous tasks in your apps. You can use it to do API calls, animate transitions, walk a user through a process, and a lot more.

In my last blog post I demoed this piece of code as an example of how I use Operations in the app.

func updateTimeline() {
    let reauthorize = TokenReauthorizationOperation()
    let fetchTimeline = FetchTimelineOperation()
    fetchTimeline.delegate = self
        [reauthorize, fetchTimeline],
        waitUntilFinished: false

And while that example is pretty straight forward, I knew it could be better. There's so many times when I just need to tell my app: do these things in the background, in this order, and tell me when you're done (and let me know if something comes up). Operations allow me to do that, but setting up delegates and adding dependencies seems like cruft that I don't really want to care about.

With that in mind, I added a new set of methods to my queue controller: performInSeries(operations:) and performInSeries(operations: with:). Using those instead, the above example becomes:

    operations: [
    with: self

This code sets up the given operation with each previous operation as a dependency and assigns their delegate to self. Reading this it becomes pretty clear that I want these operations to be performed in the order I specify and I want them to alert me if anything comes up, which is exactly what I want.

Even the most complex uses in all of the app still retain their readability (aside from array concatenation). This example reauthorizes the user's token, then fetches the most recent posts in each of the user's timelines, finds any new posts that the user has liked, and finally calls the given completionHandler to let the app know that it has completed updating its data.

        [ ReauthorizationTask() ]
        + { FetchNewestPostsInTimeline(timeline: $0) }
        + [ FetchLikesOperation(), BlockOperation { completionHandler?(self.fetchResult) }],
    with: self

There's still a bit further I can go with this, but I'm really happy with the readability and clarity improvement that these changes have made to my codebase.

Lots of Little Things

Posted on Sat, 29 Jun 2019 at 04:02 AM

Recently I've been focused on finishing the next set of major features for, but as happens from time-to-time I got a bit distracted and ended up knocking out a whole lot of little features that I've wanted to build for a long time. Today's update was entirely server-side, and I'll have a new update for the iOS app coming in a few days.

Wordpress Enhancements

In addition to making a lot of things just plain faster, I've also added a new feature for Wordpress users so that when users post on their blog, Wordpress will automatically let know and their posts show up much more quickly in their (and other user's) timelines.

For me, this feature involved yet another foray into undocumented XML-RPC APIs from over a decade ago. So much of the information just isn't easy to find anymore so building features that use them is more archeology than software development.

API Keys and Webhooks

Users that want to write scripts using (or build custom applications) can now get an API key quickly and easily that lets you access the full range of APIs.

For those who want to dive even deeper into their data with, users can now add a Webhook URL if they'd like to receive updates from whenever a feed they're subscribed to changes.

API Documentation Revamp

I've completely redone the API documentation. Hopefully this makes it much easier for developers to discover and use the Directory API. The new documentation includes much more detailed information about the throttling limits, what to expect from each endpoint, and much much more. If you're looking to use the Directory API in your app or service you can find out more from the documentation here.

A lot of these developer-focused features are test runs for much broader features that I have cooking in the background. Meanwhile I'm trying to keep the majority of what I do with a lot more user-focused.

Changing Tides

Posted on Sun, 09 Jun 2019 at 02:43 AM

It's a big day: is now free to use! has been out for over a year now and it's been getting better and better over that time. However, although quite a few people have signed up, most have stopped short of signing up for a premium subscription. At first I thought that adding a free trial to would help, but that doesn't seem to do much to encourage signups.

I want to be useful to as many people as possible because I think and a lot of other Open Web tools (i.e., Mastodon, etc) represent what social networking should be. In order to reach a wide audience, needs to let people know what it is and then convince them to use it. I've made pretty good progress on that first goal:'s traffic numbers keep going up and responses are generally positive, it's just that those numbers don't really translate into subscriptions.

In that light, no longer requires a subscription to use: just create a free account and you're good to go! If you want to organize your feeds into multiple timelines or start a blog* you'll still need a premium subscription, and don't worry, you still get a free trial.

At time of writing, the newest version of the iOS app is "Waiting for App Review", so you'll have to sign up on the website to start a free account, but you can use the app once you've created your account.

*Coming soon!



Creative Commons License