• Podcast List - November 2018

    A November edition of some podcasts that I’ve been listening to recently.

    Podcasts

    Dirty John

    An interesting short series that best falls into the ‘true crime’ category. I don’t want to say too much about it but would recommend for people who like anything like “They Walk Among Us” or “Up and Vanished”.

    The Sourdough Podcast

    I first heard about this podcast when I Maurizio of The Perfect Loaf was on it. I wouldn’t say you learn a tonne from it but it’s pretty interesting for those who are into baking.

    Tools They Use

    A podcast that interviews people about their daily tech and daily workflows. I’m a sucker for any tech podcasts so this has become another to add to the pile.

    West Cork

    One of the best true crime podcast series I’ve heard. Sadly only available on Audible, however if you haven’t signed up before, you can get a free trial and cancel it after you’ve heard the podcast.

    Planet Money’s The Indicator

    A spin off show from my previously listed ‘Planet Money’, this is a podcast served in ~10 minute episodes that have short investigations of different parts of the economy - far more interesting than it sounds.

    Up and Vanished

    I had Up and Vanished in my first podcast list, however there is a second season available now that focuses on the disappearance of a woman from a hippie cult in Colorado. I don’t think it’s nearly as good as the first season, there’s far more fluff and filler, but it’s interesting nonetheless.

  • New Favicon

    Last week I sold my laptop and received delivery of the new iPad Pro. I’ve a bunch of posts I want to make about the iPad, but here’s a short one for now.

    I’ve been meaning to add a favicon for this blog for a while, but just never got round to it. So, this morning, whilst playing around in Procreate, I decided to draw one up. I wanted some depiction of a pizza, however all the references that I could find online were certainly not Neapolitan (the undisputed best form of pizza), so, I made my own. Here is the process as exported from Procreate - a really cool feature that lets you export a time lapse of your drawing.

    Yeah

  • Presenting a series of UIAlertControllers with RxSwift

    I was recently writing a helper application for work that would store a bunch of URL paths that we support as Deeplinks. The user can pick from one of these paths and will be prompted to input a value for any parameters (any part of the path that matched a specific regex). However, the app got pretty complex when having to deal with multiple capture groups in that regular expression.

    The problem was this - given an array of strings (capture groups from my regular expression), show an alert one after the other requesting a value that the user wishes to input for that ‘key’.

    Traditionally, I would have probably made some UIAlertController-controller that might look something like this.

    protocol AlertPresenting: class {
        func present(alert: UIViewController)
    }
    
    protocol MultipleAlertControllerOutput: class {
        func didFinishDisplayingAlerts(withChoices choices: [(String, AlertViewModel)])
    }
    
    class MultipleAlertController {
        
        private var iterations = 0
        private var viewModels = [AlertViewModel]()
        private var results = [(String, AlertViewModel)]()
        private weak var alertPresenter: AlertPresenting?
        weak var output: MultipleAlertControllerOutput?
        
        func display(alerts alertViewModels: [AlertViewModel]) {
            self.iterations = 0
            self.results = []
            self.viewModels = alertViewModels
            self.showNextAlert()
        }
        
        private func showNextAlert() {
            guard viewModels.indices.contains(self.iterations) else {
                self.output?.didFinishDisplayingAlerts(withChoices: self.results)
                return
            }
            self.display(alert: viewModels[self.iterations])
        }
        
        private func display(alert: AlertViewModel) {
            // some stuff here showing alert, invoking show next alert after completion
            iterations += 1
        }
        
    }
    

    Now this isn’t necessarily bad, but having to keep track of or reset state can always lead to bugs - particularly in asynchronous situations. Instead I had an idea for doing this using RxSwift.

    import RxSwift
    
    func populateParameters(for alertViewModels: [AlertViewModel], presentingAlertFrom viewController: ViewControllerPresenting?) -> Observable<[RegexReplacement]> {
        
        return Observable
            .from(alertViewModels)
            .concatMap { alertViewModel -> Observable<(String, AlertViewModel)> in
                guard let vc = viewController else { return Observable.empty() }
                
                let textFieldResponse: Observable<String> = vc.show(textFieldAlertViewModel: alertViewModel)
                return textFieldResponse
                    .map { textInputValue in (textInputValue, alertViewModel) }
            }
            .toArray()
    }
    
    // Helper method for Rx UIAlertControllers
    protocol ViewControllerPresenting: class {
        func present(viewController: UIViewController)
    }
    
    extension ViewControllerPresenting {
        
        func show(textFieldAlertViewModel: AlertViewModel) -> Observable<String> {
            return Observable.create { [weak self] observer in
                let alert = UIAlertController(title: textFieldAlertViewModel.title,
                                              message: textFieldAlertViewModel.message,
                                              preferredStyle: .alert)
                
                alert.addAction(.init(title: "Cancel",
                                      style: .cancel,
                                      handler: { _ in
                                        observer.onCompleted() }))
                
                alert.addAction(.init(title: "Submit",
                                      style: .default,
                                      handler: { _ in
                                        observer.onNext(alert.textFields?.first?.text ?? "")
                                        observer.onCompleted() }))
                
                alert.addTextField(configurationHandler: { _ in })
                
                self?.present(viewController: alert)
                
                return Disposables.create {
                    alert.dismiss(animated: true, completion: nil)
                }
            }
        }
        
    }
    

    Now, this looks like a lot of code, but the lower part is simply a wrapping on UIAlertController with Rx. Something that can be re-used for any UIAlertController with a text field.

    Let’s break down the main bits.

    Observable.from(alertViewModels)
    

    This little snippet takes an array an gives you an observable that emits each element of the array. In this example that will be an event for event match in the regular expression.

    .concatMap { alertViewModel -> Observable<(String, AlertViewModel)> in
                guard let vc = viewController else { return Observable.empty() }
                
                let textFieldResponse: Observable<String> = vc.show(textFieldAlertViewModel: alertViewModel)
                return textFieldResponse
                    .map { textInputValue in (textInputValue, alertViewModel) }
            }
    
    

    Here we take the stream of matches for the regular expression and we compactMap an observable of the String that the user typed into a UIAlertController alongside the original AlertViewModel instance. The RxSwift method doing the heavy lifting is the compactMap. It waits for a completed event to be sent by the observable text field responses before invoking the next alert.

    The result of the compactMap is an Observable tuple of (String, AlertViewModel), which can be used by the consumer to populate the matches of the regex with the String values.

    We pipe this tuple Observable into a toArray which waits for a completed event - which happens automatically for us once every item in the array has had an alert shown.

    I’ve cut a bunch of corners in these examples in order to simplify flow and make these two approaches more comparable. You can see the full example in my deeplinking helper app here.

  • Rab Microlight Alpine

    I recently purchased the Rab Microlight Alpine down jacket. Like with my Arcteryx jacket, I thought it might be helpful to others if I shared my opinions and some pictures as there’s limited info or pictures outside of those by the manufacturer online.

    I chose this garment to replace a North Face Thermo Ball jacket that my brother has adopted to be his own. The Rab number uses real down and is noticeably warmer than the synthetic insulation of the North Face. That being said, the Rab fits slimmer which certainly helps to keep the warm in.

    Rab Microlight

    The jacket comes branded with a small Nikwax - the waterproofing company - logo printed at the back. The down used in the jacket is claimed to be ‘hydrophobic’, but I’m convinced this is just marketing chat. I don’t how the material /inside/ the jacket can really keep you dry, but I guess it’s better than nothing?

    Like the Arcteryx, this jacket has both a good hood and a soft microfibre-like material on the inside of the zip. There’s even a small sleeping bag like case that Rab provide for you to pack the jacket away into. Some jackets I have tried have the ability to pack away into their own pockets which defeats the need to keep track of a little bag that I will inevitably lose.

    The jacket doesn’t pack away /that/ small but it’s so light that you don’t notice on your person that much.

    I went for size Medium and I’m happy with the fit. I’m just shy of 6’2. Feel free to send me any questions, I’ll try and remember to add more pictures when I get some.

    Rab Microlight

  • Arcteryx Beta SL

    A few weeks ago coming down Ben Ledi, soaked to the bone for what felt like the hundredth time that year, I decided it was time to invest in a solid waterproof jacket. As soon as I was home I did a bunch of online reading (notably Outdoor Gear Lab and The Wirecutter) and over the next few weeks I took every opportunity to run into an outdoors shop in order to try out brands and sizes. Eventually I settled on the Arcteryx. Had I not gone for this jacket, the Mountain Equipment Rupal was next on my list. Both were highly waterproof, not crazily expensive and, in my opinion, looked pretty good.

    In my looking I couldn’t find many great photos of the jackets online and any good quality ones I found did not do the fits of the jackets justice. I thought I’d share some pictures of mine for anyone else who isn’t sold by the styling you see online.

    In each of these photos I’m wearing the Arcteryx with a Rab Microlight Alpine down jacket underneath - both in size UK medium.

    Arcteryx Beta SL with Rab Microlight

    Arcteryx Beta SL with Rab Microlight

    The hood on the jacket is great, it fits large so that it can fit over a helmet, but it can also be cinched down for normal wearing just fine. I’ll often wear over-ear headphones to work and it’s nice that they fit easily under this hood, something I couldn’t say about my previous North Face Triclimate.

    Arcteryx Beta SL with Rab Microlight

  • Photo Storage Workflow

    When I first started this blog I wrote a post about how much I love using my Fujifilm X-T20. Around the time I wrote that post I made a decision to stop paying for a Creative Cloud subscription and began using my phone as a hub for all my photos. Now, several months later, I can’t see myself ever going back.

    Previously 💾

    To provide some context, it’s worth noting my old workflow. I previously used a Canon 6D and shot exclusively in raw, meaning that each picture was around 10-25mb in size. Whenever I had taken a set of photos I would plug my SD card and an external hard drive into my laptop, open up Lightroom and transfer everything. I would then do some batch edits to the set and would often spend some more time on my favourites. Then I would export a subset of the photos and add them to Photos for Mac to be uploaded to iCloud where I could share them with others. Finally, I had Backblaze cloud set up in use so I would usually end up leaving my laptop sitting on overnight plugged full of external drives to allow time for backups to complete.

    Going full iCloud ☁️

    Back in March I was getting pretty fed up with how long it took to get my photos anywhere. I was enjoying the portability of my Fujifilm but was still restricted by either WiFi transfer speeds to my phone or the hard drive workflow described above. At that point I had stopped using raw as I was happy with the JPEGs I got straight out of the camera. I decided, on a whim, to cancel both my Backblaze and my Creative Cloud subscriptions. I moved every photo from my hard drives into Photos.app and left it for weeks (yes, plural) to upload everything. As of today I have ‘37,611’ photos and ‘1,744’ videos stored in iCloud. I’ve also got the free tier of Google Photos so I have lower quality backups on the other side too.

    This has been great for so many reasons.

    • Access to all my photos on virtually any device - including my phone, laptop, work laptop and the increasingly good iCloud.com
    • Great utilisation of machine learning for photos. I’ve tagged friends and family and can now make full use of search in Photos. This has only been made better by iOS 12 where you can combine search terms. I can instantly find photos of all sorts. For example ‘Rory Bain’, ‘Snowboarding’ in ‘France’.
    • Vastly improved “Memories”. When adding my photos from my hard drives, I also added photos from my Mum’s old hard drives. I’ve still many more to add, but even now it’s made the Memories feature far more enjoyable. On a persons birthdays for example, it automatically creates an album with my photos of that person over the years. Most people only get these albums since the start of their social media presence in the last 10 years and are photos are limited to ones that they’ve selectively kept online. This gives me photos going back decades.
    • Less scraping through sets of photos. Another benefit of machine learning and image recognition techniques in is that Photos automatically only adds distinct photos to auto-created albums. There aren’t 10 takes of the same family photo where I accidentally left continuous shutter on.
    • iOS photo editing apps are great. I personally use Darkroom 90% of the time and can do 80% of what I did in Lightroom without any importing faff.

    And much more…

    The final (for now 😬) piece of the iCloud set up that I received last week was a Lightning SD card adapter. Until now I have been using my laptop to upload my photos, having given up on WiFi transfer for being too slow. I got the Apple SD adapter, which I would highly recommend despite its high price. I tried to cheap out at first and was left with an adapter that hardly worked. Plus, the Apple one transfers at USB-3 speeds on the iPad Pro. I now leave this adapter in my bag alongside my camera and I can transfer photos in an instant. I love this setup. Its only problem is that it has me eyeing the upcoming 2018 iPad Pro… 🙄