Jared contains the ability to load .bundle
plugin files to add additional commands. These bundle contain a principle class which conforms to a protocol and is loaded dynamically at runtime. In this instance, I was experimenting with a bundle whose class started a HTTP web server using Telegraph.
I originally noticed strange behavior because when reloading plugins. The application would crash upon reload, due to the server trying to re-bind the same port, even though I was stopping the server in the module’s deinit
statement. Setting a breakpoint, the deinit was never called.
After unloading the server module, I ran an experiment by mashing the reload plugins button repeatedly.
Digging into Xcode’s Debug Memory graph, and filtering on filtering on leaked blocks, it’s clear that old copies of RoutingModules are sticking around in memory.
Looking closer into the pertinent part of the memory graph:
The route has a clear strong reference cycle between itself and an array, causing it to stick around. All modules do provide an array of routes. Narrowing down the pertinent code:
After some research, it was evident that the issue lied in the reference to a self
method in the callback parameter. The purpose of the callback is to provide the routing module with the appropriate method to call when a triggering message is received. It is not meant to live beyond the memory scope of the containing class. However, because it was a strong self
reference, it was causing any module to never be deallocated. The class contained a list of elements that depend on itself, so as far as ARC is concerned, the resource never reached a zero reference count.
This behavior is explicitly called out in the Swift documentation:
A strong reference cycle can also occur if you assign a closure to a property of a class instance, and the body of that closure captures the instance. This capture might occur because the closure’s body accesses a property of the instance, such as self.someProperty, or because the closure calls a method on the instance, such as self.someMethod(). In either case, these accesses cause the closure to “capture” self, creating a strong reference cycle.
As a simple solution, I simply provided the callback as a weak
self reference instead:
The weak
reference allows you to reference self, without keeping a strong hold on it. This prevents a strong reference cycle, and allows my Module
classes to be deallocated appropriately. After changing to a weak self reference in all Routes, the issue resolved itself, and I’m free to mash that reload button without incurring a memory leak. Thus solving a long lived bug in my application.
tl;dr: You should be very careful when using self
in callbacks. It is very likely that you should use a reference to weak self
instead of a strong reference.
Melodrama - Lorde
1989 - Taylor Swift
E•MO•TION - Carly Rae Jepsen
Norman Fucking Rockwell - Lana Del Rey
Pure Heroine - Lorde
Gone Now - Bleachers
Ghost Stories - Coldplay
Ultraviolence - Lana Del Rey
Every Open Eye - Chvrches
Days Are Gone - HAIM
How Big, How Blue, How beautiful - Florence and the Machine
Nothing’s Real - Shura
BADLANDS - Halsey
Persona 4 Golden
The Last of Us
Persona 5
Shin Megami Tensei IV
Tetris 99 / Tetris Effect
The last episode aired in 2010 so it counts
]]>Best thing I’ve done all year. #HomeKit #homebridge pic.twitter.com/4uWfUkBkt0
— Zeke (@ZekeSnider) April 18, 2019
(Note: the amazon links are affiliate links.)
The specifics will obviously differ based on what type of blinds you have. My blinds are twist blinds, which conveniently have a removable grip on the bottom of the rod, with has a hole on the bottom. I noticed this, and thought it would be perfect for screwing to a servo.
You’ll need a screwdriver extension to properly screw into the servo through the grip. My extension was overkill on length, but got the job done.
I attached the grip back onto the blind rod, and we’re almost good to go. Except I needed to attach it to the wall, and still have the flexibility to remove it in case I need to manually slide the blinds. I’m also renting this apartment so I didn’t want a permanent solution like screwing into the wall.
Command strips were a good solution for me. I’m sure this is super amateur hour, but it worked for my use case.
I then plugged in my raspberry pi to the wall (running raspbian), and wired up the servo to the pi using the wiring guide here.
Because my ultimate goal was to connect to homekit, I installed homebridge, and set it up to run in the background. Then I stumbled upon the homebridge-minimal-http-blinds plugin, which allowed me to bind a blinds accessory to an http server. So then I set out to write a server that exposed the correct endpoints.
I ended up writing it in Node, and using pigpio to control the servo. You can see (and use) the source here. The nice thing about this solution is it allowed me to implement percentage based setting of the blinds.
The server’s implementation also includes rubber-banding on request. So for example, if the blinds are at 0%, you request 100% then request 20% after they reach 50%, they will immediately turn back. Newest request takes priority, and it checks which direction it should be turning on every iteration of the control loop.
After much tinkering via HTTP requests to determine the correct config parameters, I arrived at a final set of values. Then I setup my application to run persistently using systemd, and updated my homebridge config file to point at the new accessory. Afterwards it was all good to go.
I’m very happy with my final product and am currently working on implementing on the other blinds in my apartment!
]]>Add user to run homebridge under
sudo useradd --system homebridge
Create directory for it
sudo mkdir /var/lib/homebridge
Own the directory permissions
sudo chown -R homebridge:homebridge /var/lib/homebridge
sudo chmod 777 -R /var/lib/homebridge
Copy your home directory’s config (if you don’t have one already, edit it instead)
sudo cp ~/.homebridge/config.json /var/lib/homebridge/config.json
Copy your home directory’s persist directory (if it exists)
sudo cp -R ~/.homebridge/persist /var/lib/homebridge/persist
Determine where homebridge is aliased
which homebridge
Edit the systemd service
sudo nano /etc/systemd/system/homebridge.service
Paste in the contents of homebridge.service
from here. Make sure to replace /usr/local/bin/homebridge
with where homebridge is actually installed.
Exit nano
control + x, Y
sudo nano /etc/default/homebridge
Paste in the contents of homebridge
from here.
Reload systemd configs
sudo systemctl daemon-reload
Enable and start the service
sudo systemctl enable homebridge
sudo systemctl start homebridge
Check on its status
sudo systemctl status homebridge
If something is wrong, check the logs.
journalctl -u homebridge
At this point if there are any issues, live vicariously via google and stackoverflow.
🏝
]]>For the uninitiated, iMessage is Apple’s messaging platform that is only available on Apple devices. If you text another iPhone user from an iPhone, the bubble will be blue (sent via iMessage).
Apple has tried to lock down iMessage as much as possible, and there is no public API for common chat bot hooks. As far as I know, I was the first to attempt to write any sort of chat bot for iMessage. Because of how obtuse it is, I assume most would rather write for a platform that actually encourages development of bots, but I was in it for the challenge! iMessage is my favorite messaging service, and I wanted to build on it.
There are only a few hooks available to iMessage:
❌ iMessage Apps (introduced in iOS 10). These provide very limited hooks that would not provide a chat bot like is implemented in Jared. All input would need to be in the context of the message extension, as these apps cannot read messages, names, or any personal information. They also can only send messages with the user’s explicit consent.
❌ Siri Shortcuts (introduced in iOS 12). Shortcuts have interesting potential, but they are also limited. They can only be triggered manually, and user consent is needed to send messages with images. They cannot read conversation history.
✅ AppleScript support via Messages.app for the Mac.
The Messages.app on the Mac has existed before the introduction of iMessage. It originally only supported AIM, Google Talk, and Jabber accounts. It was just Apple’s instant messenger client. Of course it has evolved and now only supports iMessage, but the base code base has remained the same. For that reason (I’m assuming), it still (had) full AppleScript support.
AppleScript is basically a local RPC framework for automating actions on the Mac. Its syntax is very… strange (English like)? It’s not so much an elegant programming language, but it is good for its use as an automation language. There is also a technology called JXA which allows you to use AppleScript actions from JavaScript instead, but it is not very well documented and I haven’t spent much time with it. But I think all the AppleScript in this project could be replaced with JXA.
For my purposes, two pieces of functionality were key in the Message App’s AppleScript dictionary:
This is triggered when a message is received. It provides the content of the message as well information on the sender. From then we can do routing on it, and if needed…
Send a message to a specified recipient. This even supports attachments, and sending to group chats making it extremely useful to me. These two pieces were all I need to implement my chat bot.
The first take (which I have not open sourced because of how sloppy it is), was functional but not elegant. Everything was implemented in one AppleScript handler file. It did not call into any other languages or frameworks.
Because everything is in one file, it became quite bloated quickly. In addition, AppleScript syntax is very verbose and not well catered towards writing scalable software. It was really intended for small macro automations.
And thus brought v2, a full rewrite…
This (current) version uses a native app written in Swift that exposes an AppleScript interface. The Applescript handler in messages is very simple and just passes data to the Swift app. This solves several issues of the initial implementation.
These improvements allowed for much more flexibility. Many bottlenecks were removed, and it also allowed for adding things like database persistence for various state parameters, background processing jobs for scheduling, etc.
A simple send script is called for sending outgoing messages. It is called by making an osascript shell call from Swift.
This solution was great, until Apple made a change in macOS High Sierra 10.13.4.
They removed the option to specify an AppleScript handler in Messages.app. I would like to think I caused this, but more realistically an engineer at Apple probably discovered this menu option one day and asked why the functionality exists at all.
The message send action still exists, but now there is no way to receive the hooks for incoming messages, which brings us back a few steps.
In ~/Library/Messages
there is a messages.db SQLite database that contains the contents of all message history. It gets updated when new messages are received/sent. Suprisingly, it is a standard SQLite database, and it is not encrypted. So, as a workaround to the AppleScript handler, we can instead query the database on a set interval (5s)? For all new records since the last query. This will allow us to batch process all new messages received.
In addition, there are lots of fields in the database that are available in the database, that were not available via AppleScript, such as read receipts, and more. Although it will be difficult/impossible to query on changes to fields that do not trigger update of a date field.
This solution works around the removal of the AppleScript handler preference, while still keeping most of the codebase the same.
This is not fully implemented yet, as I’ve been working on it on a branch which hasn’t been merged yet. Progress can be tracked on this issue. Credit to Github user mezeipetister for the idea of repeatedly querying the database. Unfortunately I’ve neglected this project too much, but I hope to complete this fix in the near future, so that we can get Jared working on Mojave 😀. I will likely write another update post once that is done.
You may ask, isn’t there some private API call you can use to bypass AppleScript for sending messages. Well, there is in theory, but I haven’t been able to get any of them to work properly (read: at all). I’ve used class-dump to retrieve header files, and tried to use methods of the Messages private framework, but haven’t had any luck.
This is something I should probably spend some more time on, but it’s pretty tedious and unsatisfying. A hundred different things could be preventing the method calls from working, but because it’s a private API, it’s very difficult to diagnose it. If anyone has anyone to share on this, please let me know!
So there you have it, the complete story of Jared thus far. If you want to try it out, check it out on GitHub and give it a star. Hit me up by Twitter or email if you have any questions!
]]>Also, I am hereby committing to posting a technical blog post about the status of Jared within the next week!!
Once you start using a clipboard manager on your computer and adapt your work-flow around it, you can never go back.
You can un-subscribe from junk mail by paying $2 for a 10 year membership at the Direct Marketing Association (DMA). You can also un-subcribe from credit card offers in the mail. (More info from the FTC here).
If you live in California it’s worth investing in some N95 masks.
If you post really long ridiculous captions on Instagram of a product and tag it with #ad, everyone will believe you’ve been sponsored by Coke (even though you have like 50 followers) and ask you about it the next time they see you.
I’ll soon (maybe) finally get CarPlay in my car. This will be a truly incredible day 2 years in the making. I don’t even know what else in life I’m waiting for at that point.
I’ve been made aware that a HomeKit supported essential oil diffuser is available, and this is so ridiculous that I might just need to own one.
There are many trade offs to using Sublime vs a full featured IDE and I don’t think I’ll ever be fully happy with either.
Dark Mode on Mojave is nice.
Not having to use Windows ever ever is a great blessing that I will never take for granted. Not having to use Windows APIs is an even bigger blessing.
👏👏 House Majority Leader Nancy Pelosi 👏👏
Check it out:
]]>My favorite password manager is excellent on iOS. A must have for me.
Overcast is by far my favorite podcast app on iOS. According to the settings panel, Overcast’s smart speed feature has saved me 55 hours of listening time. The app is very nicely designed, features smart speed & voice boost, and has a robust sync service backing it. If you are using another podcast app, I highly recommend giving Overcast a try.
Tweetbot is a beautifully designed third party twitter client. The default twitter app is gross, I only use it to access polls or other features which Tweetbot is unable to add due to lack of API support from Twitter.
Perhaps this goes without saying, but I really enjoy using Instagram.
I have an automatic dingus in my car, and the app is great at letting me view past routes, and interesting statistics and such.
If you’re looking for a more advanced calculator than the system default (or you need an iPad calculator), PCalc is excellent. It is feature rich and is frequently updated with any new features added to the OS.
The better ride sharing app. (Uber is a terrible company)
The fastest and easiest way to send money to friends or family. We’re done using those other apps.
Up to the minute weather notifications that really work. Getting a notification on your wrist when rain is about to arrive is often very useful. The app also provides more detailed weather info than available in the default weather app. I still use the default app as well, but Dark Sky is a great backup.
The best way to automate common tasks on iOS. A really powerful tool. So good it got bought out by Apple. My favorite workflow: one that quick-plays Melodrama by Lorde.
My favorite Japanese dictionary on iOS.
Day One is how I journal. I’ve written in detail about it in my Mac Apps post, and the iOS app has feature parity. It’s delightful.
I enjoy browsing stack exchange sites, and the app is surprisingly native and feature rich. Recommended if you’re a frequent visitor to any stack exchange sites.
My favorite news site has a solid iOS app. I prefer scrolling through in the WaPo app instead of Apple’s News app because of how nicely it is laid out.
]]>1Password is a must app for anybody, in my opinion. It is an easy to use and well designed application that makes it super easy to manage unique passwords for all of your online accounts. It autofills in all browsers, and stores everything else important in your life like Pin codes, credit card numbers, etc. It also supports 2 factor auth codes. It’s a lifeline for me. And it syncs easily between all my devices. 5/5.
Terrific journaling App. Makes it easy to log your life, and syncs with the iOS and watchOS apps as well. Really well designed, and makes it easy to get writing, format it how you like, and attach images or locations. I think journaling is really important, and Day One fills an important need. There are pros and cons to digital journling, but a few things I like:
Easy tagging / searching.
It’s so easy to find old posts by tags, locations, date, etc. Much easier than searching through physical pages. It’s also fun to look at the different views such as the map with all your journal posts.
Password protection
You can use a passcode (or TouchID) to secure your journal. That way nobody, even with physical access can access my journal. And with end to end encryption, even if Day One servers are hacked, my data is safe. Since my journal contains my most personal thoughts, this is very important.
Backup
There are backups of my journal on Day One’s server, as well as my iCloud backup, Time Machine, Backblaze, etc. There’s little risk of me losing my journal with so many replications of it. With a physical journal, there’s only one.
Convienience
I can type out an entry whenever I want. Sometimes I’ll create a quick entry from my watch with the time and location, then fill it in later. Always accessible.
I get the appeal of a physical journal, but for me, writing digitally is way easier. It’s personal preference. Also my hand would get so tired when I write long winded journals…
An up and coming open source video player. Plays nearly every format and the UI is more native and prettier than VLC. If you’re a old time VLC user because of format compatibility, give IINA a try.
A fantastic Twitter client for macOS. Way better than using the website if you’re a regular Twitter user. Has feature parity with the iOS version and the UI design is great.
My preferred way to see how the disk space on my mac is being used. Allows me to find and delete unneeded files when I need to make space.
A native content blocker for macOS & safari. Because it uses Apple’s content blocker API, it’s faster and has better privacy by design that other ad blockers. All the rules and filters sync with the iOS app as well.
A vector design app that is mostly used for user interfaces. Great for designers, but I also like prototyping in it, as it is sometimes faster and easier than messing with interface builder.
My favorite drop in Photoshop replacement. No subscription, fairly cheap (~$15), and fully native.
I’ll admit I’m terrible with vectors. But this looks like a great app. I’ve tried it a few times…
I use screens to connect to my work iMac when I need to work from home. And it does the job well. Syncs with the iOS app as well.
Developed by Panic, one of my favorite software companies. This is definitely one of the best designed apps on the platform. A nearly perfect FTP/SFTP client. If you need to upload files of any sort to a web server, this is how to get it done.
A nice text editor.
Paw is terrific for simulating HTTP(S) requests to test the web services you’re developing, or play with public APIs. I use this everyday at work. Postman is the more well known cross platform alternative, but I like Paw way better.
The best way to the contents of your database. I use it during development, but I’m sure it could also be used in production. It’s fast, and just works.
The best git client I have used on the Mac. Some things are still a little unwiedly and sometimes I’ll have to go back to command line git, but for most operations Tower gets the job done well. If you’re looking for a free solution, Source Tree is fine as well.
]]>I still think Medium is a great platform, and I will probably continue to cross-post my important pieces there. There’s still a lot of insightful content I read on Medium. However, I would like to have a place I completely manage and own, so that’s why we’re here. I think it’s important that the web doesn’t become too centralized on large services. I post enough of my content on Twitter, Instagram, etc. Some of it should be hosted by me.
Also Medium has added dickbars and some other questionable design decisions that take away from the most import thing: content.
When deciding what blogging engine to use, I was mainly debating between Wordpress and Ghost. Wordpress is a battle tested CMS that is used very widely. I’ve used it a lot in the past and have done some contracting work with it. Wordpress is great at what it does.
But it does come with its fair share of bloat. And upkeep with installing security upgrades, patching PHP, managing the server, installing plugins, etc. And because of its wide range of functionality, I find that theming it can be overly complicated. I wanted to keep it simple for my blog, and I just thought that managing a Wordpress install and theme would be overkill.
So I also took a look at Ghost, which is a new up and comer in the area. It’s built using Node.js and Express, which is a stack I am fond of. I spun up a $10 digital ocean droplet to take Ghost for a spin. I liked it, but again seemed overkill for what I wanted. Also it seems a lot of open source themes I was trying out weren’t working due to lack of updates for the latest versions of Ghost.
Ghost overall seemed very promising, but again overkill. A lot of the themes I was looking at weren’t striking my fancy. And hosting it on Digital Ocean would incur additional costs over the shared hosting I’m already paying for at dreamhost.
This brings us to Jekyll, which is what I ended up going with. Jekyll is an awesome tool which allows you to generate a completely static site using Markdown. The templates are easily modifiable, and you have complete control over what goes into your site.
Let me just say, I love Jekyll. I am a total convert. The default theme is awesome, minimal, and was easy to customize to my liking. I am very satisfied with how the look of my blog ended up. I wanted something minimal and easy to read, with nice colors, and a unique style so that it doesn’t look like a generic template.
I am a huge promponent of Markdown, so the writing format is a huge plus for me. I want to write my posts in Markdown no matter what engine I’m using. I really like how Jekyll formats and organizes the project files as well.
Stepping back down to a completely static site is actually very nice. The current WWW has so many sites with insane bloat, it’s nice to keep my site to a fast loading lean machine. Just content, that’s it. My site does not have a single line of JavaScript. Hopefully it can stay that way. No need for AMP here, just natively fast loading pages.
I only had 4 posts on Medium, so this wasn’t a huge undertaking. I decided to do it manually because of how few posts I have. There’s no importer plugin that I know of. I would of written one myself if I had more posts, but it just wouldn’t be worth it with the number I have.
In a few hours I was done. Most of my issues were relating to layout of images. Jekyll doesn’t have many images helpers built in, so I added some which mimick the responsive layout functionality of Medium’s image embeds. I still have some tweaking to do, but I think it’s pretty good for the most part. Because I implemented them with _includes, they will be easy to modify later.
JSON Feed is a very new (May 2017) syndication format designed by Manton Reece and Brent Simmons. I really like the idea of it, and wanted to support it on my blog for the novelty of it if possible.
Luckily, there is already an open source project which implements JSON feed for Jekyll. With some minor modifications, my JSON Feed was ready to go. You can check it out here! Even if there’s not much that parses JSON feed yet, I like the idea of supporting it.
I wanted to add the meta tags used by Twitter/Facebook to create rich previews. Also because they are used by iMessage, and I really wanted the previews to look nice in there. This was fairly easy to accomplish by modifying my header template. There are some great articles out there already which helped out a lot.
With some minor modification and tweaking in Facebook’s open graph validator, my rich content previews were set.
Jekyll has awesome integration with Github Pages, which allows for free and easy hosting of your jekyll site with built in source control. This is a excellent option for most, especially considering the price (free) and ease of use.
Unfortunately, Github Pages does not current support HTTPS for custom domains. They support HTTPS for *.github.io domains which is great, but I really want to host my site on my own domain (zekesnider.com). So I decided to just copy over the files to my Dreamhost shared hosting instance.
I might set up a better automatic commit pull workflow in the future, but for now I just copy over the _site directory using Transmit. I already had a letsencrypt cert setup, so I customized the .htaccess file, and I was set! If GitHub adds support for HTTPS on custom domains in the future, I will probably switch over to that.
I would like to improve the deployment workflow in the future, just so I can easily update my blog on the go from my iPad (or iPhone). Hoping this is possible with some combination of Working Copy, Coda, and better server tooling. This is a nice to have, hopefully the frequency of my postings will necessitate this in the future.
I didn’t want any ad tracking JavaScript on my site at all. In fact, the site currently has no JavaScript on it all. But I also wanted to have a general access log so I know how many people are visiting my site.
Dreamhost Site Statistics seemed like the best solution to this problem (considering it’s built into the hosting). I have yet to fully configure it, but I might do another post on this once I get some actionable data built up.
So there you have it. With Jekyll I have a very fast loading, nice looking site with no ad tracking and 0 lines of JavaScript. It fits my needs very well, and I hope that I can keep the blogging habbit for this redesign to be worth my effort. Thanks for reading, and stay tuned for more! You can check out the source for my blog here if you like.
]]>