Text Case Has Been Released!

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.

The available formats are currently:

  • Title Case
  • URL Encoded
  • Uppercase
  • Lowercase
  • Capitalise
  • Reversed
  • Mocking Spongebob (This one is for fun)

More formats will be added in the future!

Download Text Case on the App Store!

I’ve Decided to “Just Ship” Text Case

I’ve been working on a small project called Text Case for a while now. It’s had my attention in small bursts, and I think it’s finally ready to be classified as a 1.0.

I won’t write a whole essay about it just yet, but it’s a utility app that converts raw text into various different formats. The main one being title case, which is very handy for me personally.

Along with the base app, it comes with an Action Extension, which you can access by selecting a portion of text, and then accessing the Share sheet. You then get to preview the possible formatted versions, and just one tap will copy it to the clipboard, and it’s dismissed.

I can already think about different ways the app can be expanded, but I don’t want this to become a habit of mine, where I never ship something because I always want to add one extra thing. There’s definitely going to be edge cases where formatting won’t be perfect, I’m thinking the title case will be 100% of these, but I can fix these quite fast.

But for once, I’m just going to ship an app, and see how it’s goes.

Here’s a preview:

Nancy Pearl's Rule of 50 for dropping a bad book

Nancy Pearl, writing for The Globe and Mail:

It wasn’t until I became an adult, and a librarian, that I began to question my commitment to finishing each and every book that I began. Now that I really was living a major portion of my life in the library, I literally found myself surrounded by books, tempting me, calling to me from the shelves. How could I – in one lifetime – ever get through everything I wanted to read if I had to finish those books that I discovered to be (at least to me) boring, badly written or just plain bad?

It dawned on me that maybe, just maybe, I didn’t have to finish every book I started. Gradually my attitude changed, but not without a struggle. I felt bad for the authors whose books I gave up on. Didn’t they deserve a full chance to entice me into the world they’d created? I could hear their voices in my head, like the voice of my conscience, saying, “Wait, wait, it gets better! You haven’t gotten to the good part yet.” Oh the guilt, the guilt!

This is a very good tip if you want to read more books. I noticed myself that I would become stuck on a boring book, and I wouldn’t allow myself to read anything else. And that really messes things up.



So now, I just put a book down whenever I’m bored of it, and then pick it back up when I am. It certainly makes my “Reading” section in GoodReads look rather packed, but it’s a good problem to have.

Read the full post.

‘My daring grandfather took a bit of East Berlin for himself’

Photo (Top): KALIN

One of the most extraordinary stories I’ve ever read. It’s about a man that decided his land wasn’t for taking, how he interacted with the government, and how the community respected him.

Elaine Chong, writing for BBC News:

In 1982, a Turkish immigrant started a garden near the Berlin wall on a patch of East German land. Osman Kalin fiercely defended his small domain from any authorities who tried to take it away. Though he died this year, his family are still looking after the plot and the tree house he built there.

Read the full story.

Read It Later

After reading Allen Pike’s piece “372 Easy Steps to Expanding Your Mind” on his experiences with Instapaper, the popular read it later service, I decided to finally give Instapaper a go again. It’s been a good number of years since I used it, and I was immediately presented with this lovely message:

Instapaper is temporarily unavailable for users in Europe

Great.

Luckily, I remembered I have an old Pocket account, and I used to like that, so I’ve now downloaded the app again. To be pretty honest, I don’t notice any difference to the app to when I used to use it. Maybe that’s a win for consistency, but it looks a bit outdated.

After logging in, I noticed there was still four articles that I’d saved for later. It’s a good overview of the articles I usually read. Although I must admit these are from a very long time ago:

I’m pretty sure this type of service, is the missing piece of my reading puzzle. I already use Twitter for “news”, and I’m a big fan of RSS feeds, so I have a lot of content already. Along with that, I can find more content on Micro.blog, which is a great place to write your own content, read others, and find interesting conversations and communities.

However, whenever I have just a single article I want to read, but just not that second, it somehow finds a way to escape me.

It’s not that I’ve been completely without a service like this, instead I’ve been ”using” Pinboard. I’m a big fan of Pinboard, with its simple appearance, great functionality, and good API (I was messing around with automation before). But I haven’t found a great app for it yet, so it doesn’t really get used that much. I tend to just send links there to die.

So I’m going to try out Pocket for a while, I hope I can get around the old design of the iOS app. Luckily for me it has a dark mode, and also a Mac app. I think I’ll be fine.

Find me on Pocket

Endangered Tiger Cubs Born at ZSL Whipsnade Zoo

My local zoo Whispnade, has some incredible news about some of their recent additions:

The as-yet unsexed cubs were born to seven year-old Amur tigress Naya, on Saturday 23 June, after 108 days of pregnancy, and only 121 days (four months) after meeting dad Botzman.

Keepers at the UK’s largest Zoo were anxiously monitoring second-time mum Naya using remote camera technology as she gave birth to the first tiger cub at 7.25pm, and were then elated to see her give birth to three further cubs over the subsequent five hours.

It is pretty impressive to say that there about 500 Amur tigers left in the wild, and Whipsnade have now managed to add 4 to the overall population.

Here’s a small video of the cubs:

Read the Full Article.

Loading Images From the Web Into a UIImageView

This is more of a recommendation than a tip, but it totally helped me out, so I thought I’d share.

If you find yourself needing to load quite a substantial about of images form the web, handle caching, and then add them to image views, then I think Kingfisher is a library you should check out.

I use it in my Micro.blog client, Slate, where I’m loading profile pictures, and countless images inside the post content. I simply pass the URL of the image to the UIImageView, and Kingfisher will take care of the downloading, caching, applying, and also apply a placeholder while it’s doing this if you so choose.

Straight from the README on GitHub, the easiest implementation of this is as follows:

let url = URL(string: "url_of_your_image")
imageView.kf.setImage(with: url)

But there is a more complex function you can call to have a whole load more control:

func setImage(with resource: Resource?,
                         placeholder: Placeholder? = nil,
                         options: KingfisherOptionsInfo? = nil,
                         progressBlock: DownloadProgressBlock? = nil,
                         completionHandler: CompletionHandler? = nil) -> RetrieveImageTask
    {

Which you can use like this:

let imageURL = URL(string: "here is the image url")
        let placeholderImage = UIImage(named: "placeholder")

imageView.kf.setImage(with: imageURL, placeholder: placeholderImage, options: nil, progressBlock: { (receivedSize, totalSize) in // Do something with the progress amount, like update a progress bar }) { (image, error, cacheType, url) in // After completion, do whatever you want with the image, any errors, cacheType, and the URL }

I’m a big fan of the library, and if you’re ever in a situation where you need to simply load a few images from the web, or a more image heavy app, then this is my suggestion. It’s certainly a lot easier than writing your own image downloader, and cache system. I spent a while making one myself, but it was never as good as Kingfisher.

Kingfisher on GitHub

My World Cup Predictions 🌍 🏆 ⚽️ 🏟

Group Stages

Group A

  • Winners: Uruguay 🇺🇾
  • Runners up: Egypt 🇪🇬

Group B

  • Winners: Spain 🇪🇸
  • Runners up: Portugal 🇵🇹

Group C

  • Winners: France 🇫🇷
  • Runners up: Australia 🇦🇺

Group D

  • Winners: Argentina 🇦🇷
  • Runners up: Nigeria 🇳🇬

Group E

  • Winners: Brazil 🇧🇷
  • Runners up: Switzerland 🇨🇭

Group F

  • Winners: Germany 🇩🇪
  • Runners up: Sweden 🇸🇪

Group H

  • Winners: England 🏴󠁧󠁢󠁥󠁮󠁧󠁿
  • Runners up: Belgium 🇧🇪

Group G

  • Winners: Colombia 🇨🇴
  • Runners up: Poland 🇵🇱

Semi-Finals

  • Germany 🇩🇪
  • France 🇫🇷
  • Brazil 🇧🇷
  • Spain 🇪🇸

Final

  • Winners: Germany 🇩🇪 🏆
  • Runners up: Brazil 🇧🇷 🥈

Formatting Improvement in Slate

A massive improvement has just been made to Slate! I’ve found a new way to convert the html content of a post into a format the app can read.

It’s so much faster, actually supports things like bold and italics, lists appear how you’d expect them to, and also doesn’t mess around with extra line breaks!

The speed increase is what about shocked me though, because the old method took about the same time it took to request the actual data from the Micro blog api. It was only ever a temporary solution, but this works near instantly.

Counting Enum Cases in Swift 4.2

Previous to Swift 4.2, the way you (or at least, I) count the number of cases in an Enum, would be to create an extra case called lastValue, or count. This, of course, was only useful if the raw type was an Int.

enum Option: Int {
    case one
    case two
    case count
}

Option.count.rawValue

Well now, if you make it conform to the CaseIterable protocol, you can use the allCases array. Which is generated automatically, and contains all the cases in the order they were defined.

enum Option: CaseIterable {
    case one
    case two
}

Option.allCases.count

This also means you can not only use it to count the amount of cases, but iterate over all of them much easier.

The allCases value is only generated when the Enum doesn’t use associated values, in which case you will have to do this manually.

enum Option: CaseIterable {
    case one
    case two(Bool)

static var allCases: [Option] = [.one, .two(true)] }