Two weeks ago I’ve released Sourcery Pro, the most powerful Xcode extension that exists.
If you still didn’t check it out, you really should as it can save you 100+ hours by letting you automate a lot of repetitive code in your projects, from writing mocks through SwiftUI and Snapshots.
Now let me tell you a bit about what Xcode extension offer and a couple of ideas for what Xcode team could add in future releases, to make tools like Sourcery Pro more powerful.
How extensions work?
Currently when writing extensions you are only provided with 2 things:
- Current file text
- Current user selection (user can select multiple regions with multi-cursor)
The flow of extensions is following:
- When Xcode is launched it will load all extensions and that’s the only time Extensions can decide what actions they offer
- When the user selects an action it will callback to the Command class in Extension to perform its logic on the buffer
- The extension finishes by changing the text buffer and calling completion block
Problems
There is a lot of things that are missing from that flow to offer more powerful features, let’s look at some of the main ones:
Loading time
The fact that Extension is asked to register all its action just on Xcode launch is ok for basic extensions.
But when you have a tool like Sourcery Pro that lets you create your automation templates in its stand-alone application is quite annoying to have to restart Xcode to be able to pick up new templates
What I’d like to see is the ability to let the Xcode system know that there are new actions available in the extension, that way it can reload its menu.
Communicating with the user
Right now we don’t have a way to communicate what’s going on to the user when you do something non-standard, e.g. if you don’t touch the text buffer but instead generate code straight into pasteboard for the user
One can use a fake error to inform the user that something happened, but it’s not ideal because it shows as an error, not a dismissible message, Xcode could give us a proper messaging callback.
Lack of Context
We don’t know what’s the file name, project, or module that the extension is run on.
It would be great to at least get the module name so that you can automatically generate imports for the new generated code.
I work around that by using
<# Xcode Placeholder #>
that let me guide the user to pre-fill data quickly
Those limitations might be some security concerns, but let me throw a simple idea in that could help in a lot of workflows, add intents to Xcode extensions, and let one of those intents be New File Creation.
The extensions then could provide: - Placeholder title - Placeholder content
Xcode already has that functionality so it’s not a big ask and it would let me stream-line one of the popular workflows in Sourcery Pro:
Creating tests spec automatically, right now the flow is:
- Using a Sourcery Pro template configured to
generate into clipboard
- Creating a new empty file
- Pasting your clipboard
- Tabbing into placeholders to add missing data like module name
If Extensions provided an intent and module name, this flow would simply be - Execute Pro template - Confirm new file placement
Future
Those are basic things that shouldn’t be hard to ask or complicated to support and would already enable extensions to be much more powerful, but here are a few things I’d like to see in the future of Xcode:
- Project location/filename
This would enable me to build the full AST context of your project the same way as normal Sourcery does, enabling even more powerful Live templates, even if Extension remains sandboxed I could communicate with the standalone app running in the background to perform AST creation.
- Different extensions than just Text buffer editor:
- Console
- Project tree
- Ability to add views into Xcode e.g. workflow might to analyze console logs and create a view that show’s a button to jump to diff tool for failed snapshots
Just look at what community was building using Alcatraz, one example is my plugin that enabled clickable code links in Console
Conclusion
Why does it matter?
I think a proper extensible plugin system would enable community to create much more powerful tooling, and let Xcode team focus on more core features.
Just look at what people were able to do with Visual Studio Code, the basic editor is simple but there are tons of plugins around it turning it into an extremely powerful IDE when needed, e.g. Flutter integration in VS is amazing.
Will Apple listen?
Apple has its priorities, but community adoption has shuffled them before, remember when I did Sourcery in 2016 and everyone was using it for Equality, Hashing, and data encoding? Then we got Derived implementations of those in the language itself.
They have asked me twice before what I’d like to see improved in Xcode so I have some hopes for WWDC, let’s see what happens 🤞