Categories
Explainer Projects Technical

Using Swift string literals to load bundle resources

My new iOS fiction project relies heavily on text.

That means I want to make it easy to create that content anywhere, and I want it to be frictionless to drop it into the project as needed.

My solution: Markdown files I can load from the bundle using string literals. Look how easy:

let markdown: MarkdownFile = "markdown.md"

Here’s how to do it.

String literals

In Swift, you use string literals all the time. Usually to initialize strings.

let string: String = "Hello, I am a string."

But Swift includes a protocol called ExpressibleByStringLiteral. Which means if your Swift type adopts it, that type can be initialized with nothing more than a string. While this is immediately convenient, it has real power for assets that need tedious boilerplate. Say, anything that needs to be loaded from a bundle.

Basic example

struct MarkdownFile: ExpressibleByStringLiteral {
    
    let bundleName: String
    let rawMarkdown: String?
    
    init(stringLiteral: String) {
        
        bundleName = stringLiteral
        
        var loadedMarkdown: String? = nil
                
        if let filepath = Bundle.main.path(forResource: bundleName, ofType: nil) {
        //By skipping the ofType argument above, we'll match to the first file whose name
        //exactly matches bundleName
            do {
                let loadedString = try String(contentsOfFile: filepath)
                loadedMarkdown = loadedString
            } catch {
                print("Could not load string: \(error)")
            }
        } else {
            print("Could not find file: \(bundleName)")
        }
        
        rawMarkdown = loadedMarkdown
    }
}

Here’s a basic example of a MarkdownFile struct. It knows two things about itself: the name of the file used to initialize it, and any string it was able to load from a file in the bundle with that name.

On init it goes looking for a bundle resource matching the name it was provided through the string literal. If it finds one, and it can load its contents as a string, those contents are stored to rawMarkdown. If not, rawMarkdown returns nil.

This is already pretty convenient. Again, to initialize, all you need is:

let markdown: MarkdownFile = "markdown.md"

But we can take it further.

Adding convenience

The MarkdownFile struct can be responsible for converting its contents into a display representation, as well. Let’s add a computed property to parse the Markdown into HTML. I’ll be using Ink for this, but you could use any project—or convert it into something else, like NSAttributedString.

var htmlRepresentation: String? {
    if let raw = rawMarkdown {
        return MarkdownParser().html(from: raw)
    } else {
        return nil
    }
}

Putting it all together

With our output property all set up, we have a small, convenient API for handling Markdown files in any way we want. Here’s how we use it:

let markdown: MarkdownFile = "markdown.md"

if let html = markdown.htmlRepresentation {
    webview.loadHTMLString(html, baseURL: nil)
}

self.title = markdown.bundleName

Behind the scenes, lots of stuff is happening to load and parse the file. But when you need Markdown across your project, you need only concern yourself with a filename. If you want to change any part of how this works later on, you have a single struct that’s responsible for all the Markdown behavior in your code.

Full example code here.

Categories
Explainer

Picard’s Uneasy Fandom

Captain Picard is back.

You’d think this would be cause for universal celebration. But not all the fans engaging with Michael Chabon’s instagram are thrilled with the new series. Their discontent reveals a science experiment being enacted upon tens of millions of people.

What happens to a piece of culture when its formative economics undergo a seismic shift?

Will its fans still recognize it?

Television economics

We have to start with how money shaped storytelling in the days of broadcast television. Here’s the quick, late 20th century version.

Classical

TV was expensive. The more credible your show, the more money you needed. You were shooting with film, editing wasn’t initially digital. This took work.

But! If you succeeded in making something that people fell in love with, you could sell it to them over and over and over again. So that initial, expensive investment? It gets paid back, many, many times over. If a new piece of IP really worked, it could pay you back for decades.

So how do you sell it to people? Back then, there’s no streaming platform to work this out for you. All you’ve got is broadcast television television stations. They’ll sell ads against your content to make money, they’ll use the money to pay you for rights to the content.

The golden ticket for your television IP was simple: reach 100 episodes. If you hit 100 episodes, you can sell the show for stations to air every afternoon. With 100 episodes, you can be on every weekday for five weeks without repeating. This was seen as the threshold for viable re-run revenue.

So that was the entire game.

Make 25 episodes every year. Stay on the air at least four years. Whatever your annual budget, you need to spread it out over a lot of shows.

These fucking people. 236 episodes of this playing multiple times a day in every single US market must have been a cash cow.

Not only that, every episode had to be self-contained. This model evolved at a time without streaming, and where recording shows was cumbersome. It wasn’t a guarantee that any given audience member had seen the episode played a week before. And if they felt lost, they’d tune out, along with your ad revenue.

So the economics conspired to make the average television series highly uniform, episodically self-contained and copious in volume.

Except where it didn’t.

Prestige

Over at HBO, economics worked differently. As cable and satellite penetration increased, HBO found a niche selling access to content. Pay cable was the original streaming service. Tack a few extra dollars onto your monthly cable bill, you get access to premium movies without leaving your house.

HBO’s The Larry Sanders Show. They said “fuck” a lot.

But you can get movies anywhere. So HBO added something unique: original TV shows. For HBO, money was coming directly from subscribers, rather than ads. They didn’t want to re-distribute to anyone else, either. It was their differentiator. No need to rush to 100 episodes.

So instead, seasons were short. 8-13 episodes. Quality over quantity.

But this was anomalous. An exception to the rule.

Until AMC was on the brink.

The Prestige Explosion

If you’re my age and grew up with cable, you remember flipping past the bizarre edifice of American Movie Classics. They were continually playing black and white movies in weird aspect ratios, completely irrelevant to our cultural frame of reference.

This was a problem because eventually people my age developed favorable advertising demographics. Cable operators didn’t want to continue paying fees to include AMC in the basic cable lineup if a big proportion of their viewers were skipping it. The loss of revenue for AMC in this case would have been lethal. They needed to create immediate relevance.

So they started funding shows on the HBO model. Quality over quantity. Compelling enough that you needed to see what happened next season.

The result: an army of loyal consumers who would arrive at their cable operator’s office with pitchforks if they didn’t get resolution on Don Draper or Walter White. At the same time, the penetration of DVD players made it possible to buy or rent entire seasons of a TV show. You no longer needed to sell 100 episodes to a TV station. You could sell 30 episodes to individuals.

Picard’s transformation

Today, a lot of TV gets made according to this model. Streaming services have proliferated and they have the same sticky subscriber goals of AMC or HBO. Give you something unique, keep you coming back.

While Jean-Luc Picard has changed in the 20 years since we last saw him, television has changed even more. Here is the science experiment:

What happens when a shared narrative framework born to the old economics of television is reanimated, with full continuity, into the modern style of TV production? The change has unnerved some folks who were used to the old way of making these stories.

People can say fuck sometimes

Shit you not, people are complaining that there’s cursing in this series. Star Trek: The Next Generation had to be sold into re-runs to play in the afternoons and evenings when kids were at home. If they’d tried to slip anything racy into the dialogue, the advertising prospects get complicated. Better to keep things clean and presentable for all hours. To say nothing about the prudish FCC.

Of course, when distributed through the internet, anything goes. You need to opt into a specific stream and it’s assumed that parents have some basic control over the situation.

So on Picard, there’s language sometimes. The medium permits it and it’s hard to believe we lost interest in cursing between now and the 24th century. Besides: thousands of gifs don’t lie. The body language of these characters always implied cursing.

Mood, production design and pacing are different

An episode of TNG races through a story. It has to be self-contained. Things happen, characters do things and resolutions are provided.

Picard has no such rush. It’s a single story, told with the understanding that you are fully capable of watching it in order.

With over 20 episodes to get through each season, it saved time and complexity to keep everyone’s clothing consistent. Same goes for lighting.

Meanwhile, because quantity of episodes isn’t paramount, episodes don’t need to be made on an assembly line of identical sets and costumes. The Next Generation often felt like a televised stage play. Compact scenes in familiar settings featuring a handful of actors, as they hashed through an ethical or philosophical conflict.

By contrast, Picard shows tremendous range of mood and setting. We have everything from action scenes to tender conversations to philosophical arguments. We’ve been to France, to Starfleet Headquarters, to space, to the borderlands, to a Borg cube. We see a variety of clothes on our characters. Uniforms exist at the periphery, in a professional world that’s no longer our focus.

Elite crisis

But perhaps most striking, Picard arrives in a cultural context that is exhausted and disappointed.

Star Trek was always a political animal. Gene Roddenberry discovered that science fiction gave him a cloak for discussing political issues that would be too controversial to broadcast in the late 1960’s. TNG continued this tradition, tackling subjects including civil rights, environmental crises, the nature of war, even technology ethics.

Picard knows it is walking into a messy moment in human history. A moment where many of us have lost faith in our leaders and institutions. A moment where we see millions of people fleeing their homes just to stay alive, while those who are safe look the other way. A moment where it feels our technology is out of our control, and perhaps betraying us to shadowy figures we don’t fully see.

So the story reflects this. To meet its duties in the tradition it’s continuing, Picard has no other option.

Star Trek was always an idea about our best selves

There’s plenty you can critique about Star Trek. Its heteronormativity hasn’t aged well. It’s hard to imagine a future that straight in a present that’s so cheerfully queer.

Its erasure of religion ends up an erasure of many cultures, so we lose some richness in the humans it can represent.

And I could go on. But even if it didn’t always meet its own high standards for creativity and diversity, the intention of Star Trek was clear: help us imagine a better version of ourselves. I would argue it was successful in this.

“There’s a black lady on TV and she ain’t no maid!” — A very young Whoopi Goldberg

If Star Trek is to return in a modern form, many things are subject to change in its style and presentation. But its core responsibility is immutable: show us how our best selves respond to difficult situations.

In this, Picard is meeting its obligations to us head-on. We’re only four episodes in. The quality of its final execution is an open question and certainly subject to critique. It is a truth accepted since the first season of TNG that we are not guaranteed good Star Trek.

What is clear is that Picard wants to address the most pressing issues facing us right now. It wants to fulfill its role as a social imagination stimulant. It wants to support us by showing our best selves dusting themselves off and responding to a crisis of confidence in our leadership and institutions. It wants to show us what it’s like to try again after failing to make a better world.

We could certainly use the help.

Read more

Thread: How “The Measure of a Man” offers modern lessons in technology ethics.

Categories
Explainer

Protect your digital identity from Google for $70 per year

I’ve never trusted Gmail. Google does too much creepy stuff, and they have zero customer accountability.

While there’s no escaping Google for some services, I think it’s reasonable to draw the line at email. It’s deeply personal content and the gateway to all of the rest of your internet accounts. If you used a Gmail account for your other account signups, and one day Google decided to take your account away, you could find yourself locked out of your entire digital identity.

Best of all, it’s entirely possible to assemble your own email service—if you can part with a few dollars each year.

Start with a domain

This part is essential. As long as you control your own domain, you can always decide where your email is routed.

If you do nothing else, register a domain. You can at least set up free mail forwarding from your domain to a Gmail address. If one day you need to leave Google in the middle of the night, you can redirect your mail forwarding to a new service.

I like Namecheap. Every registration comes with free whois masking, so no one can look up your address through your domain. Here’s a bit on how to set up email forwarding through Namecheap, but most registrars offer this option. Just search the web for [registrar name] email forwarding.

Once you’re using a custom domain for email, you have a lot more control over how you receive email. But there are limits to the free forwarding service that comes with your registration. It can be finicky to successfully send mail using your new address. For a fully-integrated experience where your address always works consistently for sending and receiving, you have to go further.

Add an email host

You can actually pay Google to be your email host. This is called Gsuite and it costs $5 per month. But the whole point of this is to get away from Google.

This is the beauty of holding your own domain, though: you can decide. If Google happens to be convenient for you, you can point your address there. If you’d rather keep your email private from a company like Google, you can use someone else. While it’s entirely possible to stand up your own server for email, dedicated entirely to you, with no other users, I’m not going to get into those details. Instead, there’s a nice middle ground between complete DIY and revealing all your data to a massive advertising company.

You can use a service like Fastmail, whose only ambition is to provide secure, reliable email for a reasonable price. Also for $5 a month, they’ll host your email and, if you want, completely configure your domain for you. Here are the details.

But Fastmail isn’t the only option. If you’re especially worried about privacy and security, you can use ProtonMail, which is headquartered and hosted in Switzerland. Mmm, Swiss privacy laws.

What’s important here is that, at any moment, you can point your domain to new service if the host you’re using doesn’t work out. Your emails won’t be trapped with one service.

Backing up your email

Web-based email is convenient but it means giving up a lot of power. When you use an email application on your local computer, you can be assured that all of your messages are stored to your hard drive. If you do automatic backups, your email will be safely backed up as well. If you host with Fastmail, they have complete documentation for setting this up on macOS, Windows and Linux. ProtonMail offers something similar, again with a privacy emphasis.

Coexisting with Google

After all of this is set up, you’ll probably still need Google for some things. You can sign up for a Google Account with your email address and not get Gmail. This is convenient for Google Calendar especially—most people seem to use Google/Gsuite for calendaring, so having your invitations automatically caught by Google Calendar is helpful.

Of course, for all non-email services provided by Google, you’re again at their mercy. But your email is safe.