Caret, a great Markdown editor

:  ~ 45 sec read

I guess it's that time of year again, when I change the editor I use to write. The last editor I was using, LightPaper, hasn't seen any updates in the past year and a half, which is a bummer, because I really think it has potential, and it's already a pretty good app; it just didn't fit my needs/desires. I know, I'm spoiled when it comes to editors, but I'm also a sucker for clean, dark themes.

Recently, I stumbled across Caret, which has everything I look for: in-line Markdown highlighting, syntax assistance, live and customizable (through CSS) preview, an easy-to-the-eyes dark theme and a gr […]

Continue reading →

The App Store and the state of pay to play

:  ~ 4 min read

Truth be told, I haven't installed a free game like this since ... as long as I can remember. I haven't played games like Candy Crush et al, so I don't really know if this is the standard or not, but I'd like to share my latest experience. You don't have to have experience with this genre, it's all generic stuff, or obvious enough.

I like tower defense games, and the other day I thought I'd give SurvivalArena a try. I saw it's a pay to play, but I thought it can't be that bad, I'll just progress slower; after all, it's a tower defense, what paywalls can there be?

Well ... after around 15, mayb […]

Continue reading →

Tips for consuming APIs

:  ~ 2 min read

Last time I wrote a few tips for writing APIs; this time I'd like to write a few for consuming them.

  1. The most important one I can give is to always have a layer between your app and the network; this will ensure you always have a single source of truth:
    • create models, no matter how few fields an object has, instead of reading from dictionaries/arrays all over the app. This will make adding/changing/removing fields a breeze if required, will ensure everything is type safe, and that you don't have to worry about typos every time you use a field; autocomplete is your friend;
    • have your own "manag
Continue reading →

Tips for writing APIs

:  ~ 2 min read

I'd like to leave a few tips that I think are adamant in writing good APIs. I've come across all of these mistakes, and they are a pain to deal with. Some more than others, but all decrease the enjoyability of working with them.

  1. First and foremost, be consistent. This might be the most important tip I would give, and will be the most detailed one:
    • some cases are more broadly used, but, ultimately, it doesn't matter if you use camelCase, PascalCase, or snake_case, just use the same kind everywhere;
    • the above point goes for naming endpoints too; don't have one endpoint reference-data and anoth
Continue reading →

Non-selectable UITextViews and URL interactions

:  ~ 1 min read

Say we have some HTML content we want to display in a UITextView:

if let stringData = .utf16),
	let attributedString = try? NSAttributedString(
		data: stringData,
		options: [.documentType: NSAttributedString.DocumentType.html],
		documentAttributes: nil) {
	attributedText = attributedString
else {
	attributedText = nil

For added complexity, let's assume the UITextView is inside a UIScrollView, meaning we'll most likely want the it to be non-editable, non-selectable and, for our case, non-scrollable as well. And here comes the tricky part: if we set its isSelectable p […]

Continue reading →

Naming init parameters

:  ~ 45 sec read

I used to name them by the type of the parameters passed in, for example:

let dictionary = ["name": "Sneakers", "price": "40"]
let product = Product(dictionary: dictionary)
let viewModel = ProductViewModel(product: product)

But lately, I've been using a more Swifty approach, by having an external name of from or with:

let dictionary = ["name": "Sneakers", "price": "40"]
let product = Product(from: dictionary)
let viewModel = ProductViewModel(with: product)

How do I pick between the two? I go with the following approach:

Continue reading →

[SSS] Creating a sitemap

:  ~ 2 min read

Sitemaps are used by search engines to know what pages to crawl; they're basically a list of all the URLs available on a website. Last time we saw how to manually create an RSS feed by manually creating an XML document, and a sitemap is also just an XML document.

First, let's add the route to our droplet:

func addRoutes() -> Droplet {
	get("/sitemap.xml", handler: SitemapController.create)
	// [...]

As we saw in the previous post, we need a controller that has a method with the same signature as the handler:

struct SitemapController {

	static func create(with request: Request) throws -> Respon […]

Continue reading →

[SSS] Creating an RSS feed

:  ~ 1 min read

Back when the blog was written in Ruby, I wrote that I eventually went ahead and implemented an RSS feed, and that it was much easier than expected. Turns out I didn't even need a library to do it, it's only a matter of creating an XML document.

Sure, it might be prettier to assign properties (e.g rss.item.content = "content here") versus creating the document manually (e.g xml += <content>content here</content>), but with proper formatting, the latter can look pretty great too. Besides, printing the document, or looking at the source in a browser will be easier to track / spot bugs.

Let's start wit […]

Continue reading →

[SSS] Displaying posts and extending Queries

:  ~ 5 min read

This is a bit tricky, since my routes for posts and pages are the same, and I differentiate between the two if I can create an Int out of the lastPathComponent. I know it's not the best approach, but since URLs should be permanent, I never moved to a /page/x structure. I also kind of dislike that structure ¯\_(ツ)_/¯.

In the first post in this series, I briefly presented the Droplet extension, with a very basic addRoutes method, just to present the methods in the extension itself. Let's give it a few routes:

extension Droplet {

	func addRoutes() -> Droplet {
		get("/feed", handler: FeedController […]

Continue reading →

[SSS] PostgreSQL models

:  ~ 3 min read

Let's start by defining our Post model:

struct Post {

	let title: String
	var rawBody: String { // The original, markdown body.
		didSet {
			// For updating body, truncatedBody and readingTime automatically.
			// didSet doesn't get called on init too, sadly.
	fileprivate(set) var body: String // The html body.
	var truncatedBody: String // The html body, truncated to x chars.
	fileprivate(set) var readingTime: String
	let datetime: String // The date, in yyyy-MM-dd-HHmm format.
	let link: String // The link, created from the title, in post-title format.
	let date: String // The short […]

Continue reading →