Undoubtedly, productivity apps are major time-savers over the use of homemade scripts and hacks. Not having to reinvent the wheel every time and getting a much improved experience is where the value comes from for the users. However, even the best apps are limited by the set of features the developer has bundled into, and sometimes it doesn’t cover all the needs a user may have.
Craft plugin displaying an interface in Sketch
Since the early days, Paw has been sticking to the system as a native, code-signed and fully sandboxed app. But I realized the need of extensibility the day the Apiary team showed interest in an integration with their open description format API Blueprint. The idea of Paw importing 3rd party API descriptions to let users visually test their API calls and generate client code was extremely attractive. It was late 2014 and I was working alone on Paw. I knew I wouldn’t be able to implement every feature request, so I wanted to make it scriptable and tell the Apiary folks: “go ahead, you can build it yourself”. It was challenging. But in just a few weeks I’ve been able to give them a beta version. Soon after, Kyle Fuller, an Apiary guy and core CocoaPods maintainer, built the two first Paw extensions (one to import & one to export API Blueprint). It was an amazing feeling to see others actually build stuff for the app I was developing.
I had a personal preference for Python. The fully bidirectional PyObjC bindings would have made nice API for Paw, and would give powerful control to the developers. Though, it had the same security concerns as CocoaScript, and OS X sandboxing would have become a challenge to achieve.
Exposing a public interface is great for your codebase
Giving access to the internals of Paw to 3rd party developers has been a great experience: it forces us to think bigger and build more reusable components of which we aren’t the only users anymore. It defines a clear contract between the application and the extensions, against which we’re building unit tests.
It’s always exciting when I see an app I love get an update. But too many
updates becomes bothersome, each requiring a new download and relaunch. It’s
where shipping features as extensions becomes great as it doesn’t require to
ship an update to fix a small issue in a component. We often improve the code
generators for Paw, and we’re currently refactoring all our importers/exporters:
everything will be shipped without updating the app’s binary.
Paw displays nonintrusive notifications for extension updates
The downside is if you’re building your own app, you’re going to have to implement your own extension update process. A typical Paw extension is compiled with Travis CI and pushed to a GitHub release. Our server only keeps the list of available extensions. When an update is needed, we just bump the Git tag number, and Travis and GitHub do the rest.
We would absolutely love to open source a significant chunk of Paw, but doing it right takes times, and time is the most valuable asset of a small team. Ultimately, we will do so by releasing some core components as beautiful libraries! Though, for extensions it was a no-brainer: we publish all our extensions on GitHub, users can help us improve them, and they use them as templates for new extensions.
It really worked! We’ve recently noticed a promising increase in the number of users asking questions about building extensions. People want to do more with Paw, make their workflow smoother, and use the app in scenarios we haven’t integrated yet.
all JSValues that belong to it are only accessed from that queue.
Originally posted on Medium / iOS App Development