Unfortunately, I've decided to remove Qwiki from sale.
If you weren't aware, Qwiki was a Mac app that placed Wikipedia in your menu bar. It was pretty simple, you could search for a page, view a page, and there were a few methods to export links from the app.
Qwiki was first released in June 2016 and received updates until November 2019. At that point, I was relatively happy with the app, since it was only ever meant to be a minimal way to quickly search Wikipedia.
However, as time has gone on, the codebase has become stale, and the app, in general, doesn't feel at home on the more recent versions of macOS.
I've felt for a while that I shouldn't be offering an app that isn't being maintained, but my thoughts were that while people still used it, there could still be more that could get value from it. But after receiving a few support requests asking for Catalina, mainly around the text appearing too small, small icon resolution, and a few more things, I can't continue to make that excuse anymore. So therefore if I have no plans to ever update the app, I can't ask people to pay money for it.
I toyed with the idea of just making it free, but I still think a free app needs to be of a certain standard, and to a point, maintained.
This means that I now only have one app, Text Case, although it is available on iOS, iPadOS, and macOS. I do have plans to work on a new project this year, but nothing is in the works just yet.
At the start of last month, I released a major update to my app, Text Case. It got some good reviews, and that helped boost sales, which I'm very grateful for. But as you would expect, after a week or so, the initial surge ended, and it went dropped to a stable level every day.
But I was looking at the app analytics section App Store Connect one day and I saw a huge amount of impressions on the macOS version. It was around 1 million impressions, where usually it would be around a thousand a month.
In the end, it was around 3 million:
I immediately thought it meant that my app must have been linked somewhere popular, or that it was featured in the App Store. Turns out it was the latter. Text Case was in fact featured in the "Apps and Games We Love Right Now" section.
I started thinking that this could mean a sudden increase in downloads because so many people would know about the app.
But as it turned out, there may have been a small increase, where the sales didn't drop off as fast as it would have done without the feature, but it wasn't what I was expecting.
Below is the number of units during the same period as the above impressions (February):
After a while thinking about this experience, I've come to the conclusion that this just shows how much word-of-mouth and direct recommendations work, compared to simply being visible on the app store. If a few reviews can have the same impact as millions of impressions, then they must be pretty effective.
For a while, I always imagined that simply being featured could push an app to get a large number of sales. Maybe it's because Text Case is a particularly niche app, but I think this proves that directly reaching people that would benefit from your app is the best way to grow sales.
Maybe this won't surprise anyone, but it's a perspective that a few people may find interesting, so I thought I'd share.
After quite a long time of development, the major update to Text Case that I've been working on is finally ready for a public beta.
This update changes the focus of the app from simply using built-in formats, to focus on user-created flows. A flow is a collection of formats, which together can become a more complex text transformation.
Along with flows, 6 more complex formats have been added. The complexity in them is that they support parameters. So when you add them to your flow, you will need to configure them. The new formats are:
Replace all occurrences of text a specified string of text another string of text.
Replace the first occurrence of a specified string of text with another string of text.
Replace the last occurrence of a specified string of text with another string of text.
Remove all occurrences of a specified string of text.
Remove the first occurrence of a specified string of text.
Remove the last occurrence of a specified string of text.
As they are more complex actions, they have specific Shortcuts actions, Replace and Remove. You can obviously also access them if you add them as part of a flow, as flows are now accessible via the Shortcuts app too.
There's a few extra tweaks to the design, and also some configuration options for the Share extension. But that's essentially the main changes in this update. I'll write a much more comprehensive post when the update is finalised and ready to download from the App Store.
I had an interesting day at work today, as I was configuring a new project work with our CI server, and have things like Unit/UI Tests in a readable format, and also convert the code coverage into something that could be stored along with the build artefacts.
Just for some background, we use Bamboo as a server, and I’m pretty limited with what I can actually configure myself, without getting someone with higher privileges. So I try to work within my limitations, and see what I can come up with.
I use Fastlane as the main solution to manage the whole process. And that means I can use the scan and slather commands to do the heavy lifting for the testing/code coverage. The way I had to integrate it in our CI server was reasonably simple. The test results were handled by setting the output type to junit, and then adding a simple JUnit Parser task on Bamboo. The code coverage was slightly more complex, as it needed me to run a python package that converts it into a “Clover” format that Bamboo could understand.
What was more tricky, was getting this data nicely formatted when it was sent to our Slack room. The previous build plans all had notifications handled form Bamboo, and it just gave a short message with the number of tests that passed/failed. I wanted more insight this time though, as I knew the test data was available, and also that I had code coverage being generated. I decided that the simplest (maybe it wasn’t in the end) solution was to just find a way to read the information from the .xml files, and send a custom message to Slack as part of the Fastlane process.
What I ended up with is a kind of monstrous-masterpiece. In Fastlane I had the Slack command being called with some basic information about the build, such as the branch, project name, and whether it passed/failed. But to get the results of the Unit/UI tests, I thought I’d use grep to find the line in the junit file that had text like “tests=100 failures=0”, I then used sed to clean up the surrounding text, and had the final output as “Passed: 100, Failed: 0”. The code coverage was slightly harder. I used grep and sed again in the same way to find the total code coverage, but it was formatted like “1.00000000”, and I wanted a percentage. So I piped that through bc with a small calculation, and they’re not formatted as a percentage with two decimal spaces.
Then with some magic of environment variables, I added two build-specific URLs to the message payload. One for the build details, and the other which linked directly to the code coverage report.
I’m not sure if all of that is relevant for each build, or if I’ll have to include some other things I’ve forgotten about. But what I can say, is that it was really fun to come with all of these little scripts that come together with something so simple at the end. And it’s quite likely that no-one else seeing the messages will have any idea the lengths I went to to make everything appear so simple.
As you may have already seen on my Twitter, or in my journal entries, I’ve started to work on the second major version of Text Case, 2.0. The major changes will be to the user interface, so I want it to be slightly more colourful, fit more in what I see as the latest design language Apple has set out in the Shortcuts app, and also have the formats structured better.
The project started with me making a list of all the things that I will need to implement for it to be level with the functionality of the current version. Here’s that list:
Drag and Drop
Use Copied Text
Tap to Copy
Hold to Share
Siri Shortcuts Support
Add to Siri
Title Case Format
Custom App Icons
I started working on the most important section of the app, the formats list. Over the past few days I’ve been building up the style similar to the Shortcuts app, so instead of being simple white boxes that contain the formatted text, they’re more colourful and even have a slight gradient to add a bit of depth (I’m planning on experimenting with a small shadow as well).
So once the list was working, I added the core logic from the current version and made the formats work. I did adapt it slightly though, as it now groups similar formats together, which I think makes the app look a lot tidier. This change means that when I add the reordering feature, it will most likely me limited to reordering the groups rather than individual formats. You’ll still be able to hide any you don’t want to see though.
Then I added the input field. It’s also a bit cleaner, and fits with the new style. But it has essentially the same capabilities as before. I plan on investigating importing text from a file, and implementing drag and drop, but I think that’s supported automatically.
After I had the list displaying, input working, and the text being formatted, I worked on the interaction with the resulting formatted text. I’ve had a few bits of feedback in the past saying they would appreciate one-touch copying, and now I’ve added it! So you can simply tap any formatted text in the app, and you’ll get a nice alert at the bottom showing the exact text you’ve copied. Or alternatively, you can still tap and hold on formatted text to bring up the contextual actions, which are the same as before, copy and share.
The next step from here will be to start working on the settings section of the app, as that also allows me to test the rest of the app in different scenarios much easier. I’m already planning two changes to the settings in this new version. The first is changing the idea of an accent colour to a theme, as I want the format groups to control the colour. But I also appreciate that a light and dark theme is a minimum. The second change is custom app icons, they may be a basic selection, but the app no longer has a “main colour” so I’d like to give a few options.
Another update to Text Case has just hit the store!
Just a small one this time though, to tie up a few things, before anything big can be planned or worked on. In fact it can be boiled down to three things:
A new text format, this time it’s KebabCase. And as usual it was requested, so I added it! There’s no chance that I can come up with every format possible, so if you want one added then please just let me know.
About section added (website links, App Store link, app version…)
And I’ve fixed a bug in the Action Extension. As the UI used to inherit some of the styles from the encompassing app, but it wouldn’t always look correct. I’ve fixed this by keeping it matching with the rest of the app, along with the chosen accent colour.
It’s not an extravagant update, but then again, they can’t all be.
It’s been in my head for a while, but I’m finally making my decision about Slate official. If you weren’t already aware of what Slate actually is (was), it’s an iOS app for the Micro.blog platform. I’ve spent quite a lot of time working on it, and I used to use it quite a lot myself, as it was good enough for reading posts, and also publishing text-only posts.
I always knew the next steps for the app. The main things I planned to work on next were:
Markdown preview when composing posts
Faster timeline parsing/scrolling
A caching mechanism for timelines
Support for non-Micro.blog micro blogs
These are totally achievable features, and it’s what I classed as being necessary before being able to release it as a public app (It’s currently been in TestFlight beta for months).
But about two or three months ago, I basically stopped using Micro.blog. I transitioned my posts over here, but I still planned on using the service but have it tied to one blog. I’m not sure what really made me stop using it, but it sort of faded over a long period of time, and I didn’t feel like missing anything, so I didn’t go back.
This all tied in with me slowing down on the development of Slate. Although I was still doing occasional small updates, and it was in my head that I would soon spend some time on the bigger features that I wanted to implement. But the time never came. And I became less interested in building an app for a service that I wasn’t using anymore.
It also combined with me starting to focus on good UX in my apps, and trying to really create great experiences. And as a user of Tweetbot (Twitter client for iOS and macOS), I didn’t think I would realistically be bale to put the time and effort into making a great app for Micro.blog.
So after a huge chunk of time (probably just over two months), I’ve decided that I will no longer work on Slate. And at least for the foreseeable future, I don’t see myself touching the code at all.
It doesn’t mean I’m completely over with Micro.blog, the platform, though. I’ve listened to the Micro Monday podcast, where Jean MacDonald, the community manager, talks to members of the Micro.blog community), pretty regularly. Even since stopping using the service. And it still sounds like Micro.blog is a nice place to be, with loads of interesting people. So there’s a possibility of me returning as a normal user, but very unlikely that I’ll work on Slate again!
If you want to find me on Micro.blog, I am still under the username chrishannah. However, the only content that gets posted there currently is the RSS feed of this blog. But that’s where I’ll be if I return.
I’m very glad to announce that Text Case is now released, and is live on the App Store!
Text Case is a simple utility that allows you to convert any text into various different formats.
It comes packed with an action extension that lets you select text anywhere in iOS, tap the Share button, and then you’ll find the “Convert Text” action. This will show you a preview of all available formats, and a simple tap on one of those will copy it to your clipboard, and you’ll be returned to the original app.
After putting a task in Slate off for at least a few months, I’ve got a big chunk of work out of the way, which makes future development so much easier.
Basically, when I first started developing the different sections (Timeline, Mentions, Discover, and Favourites), the code was completely split, and usually badly copied across classes.
I’ve done some work with protocols and inheritance, and now the before mentioned 4 parts of the app are using 99% the same code, except from the slight change in context. For example Mentions is exactly the same, other than a title change, and a few letters in the API endpoint.
As with most other people, WWDC is taking up a lot of time for me. So I think after I do just a tiny bit more work on composing posts, I’ll send another build out. I have composing working in my current build, but my 2 minimum requirements for the next public beta is a minimal version of Markdown formatting, and also replying to posts.
Say you write an iOS app, and now you want to write the Mac version.
Assuming there’s a data model, maybe a database, some networking code, that kind of thing, then you can use that exact same code in your Mac app, quite likely without any changes whatsoever.
I agree with Brent here. I’ve never really understood the argument that AppKit is that difficult to understand, so that’s why people don’t port native apps over. Surely the underlying logic of the app is the hard part, and linking the functionality to the interface is the easier part?
I would say I’m more of an iOS developer, simply because I’ve spent more time on it. But I’ve also made a few Mac applications. Sure, a resizing window is a bit more complex than a relatively fixed screen size, and some the interface elements are names slightly differently.
It’s just different, for both sets of people. But not as difficult as it may seem.