Chris Hannah Chris Hannah

Chris Hannah

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)] }

Slate Development Log #7

Just a small update.

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.

My New Swift Tips Blog

Regarding my ramblings yesterday about starting a new blog for swift development tips, I’ve decided I will host it on my main blog.

However, it is a separate category, that is excluded from the main feeds. There’s still a link in the navigation bar though.

The first post is super simple, and the actual tip is 1 line of code. It’s how to hide extra separators on a UITableView.

I may try and work out a schedule for regular posts, but it may just be slightly sporadic. It’s not going to be full of big tutorials though, I’d rather just share small tips for now.

Automate your financial life with Monzo and IFTTT

We believe that a truly smart bank should empower people to manage their money in a way that suits them. Today, we’re proud to announce that we’re the first bank to partner with the world’s largest automation platform — IFTTT!

In a nutshell, IFTTT lets you personalise how you manage your money. You can create your own rules, called Applets, to connect your Monzo account to the services you regularly use. For example, say you use the iOS Health app to log your calories. With IFTTT, you could enable our pre-made Applet that means every time you buy anything at Starbucks, you’ll automatically log 200 calories on iOS Health.

Yet nother reason why Monzo is the best bank in the world.

Read about Monzo’s IFTTT Integration.