Moving From Parse to OneSignal for Push Notifications

Parse is shutting down, and if you want your app to keep working, you’ll need to move to something else. I’d recommend doing it sooner than later. Thankfully our app isn’t out for another few weeks, and since the only thing we were using Parse for was push notifications, it wasn’t more than a couple hours of work to switch over to something new. The thing we found to handle our push notifications was One Signal.

Aside from Parse I’ve also used Urban Airship, Push IO, and a custom push server. Custom was definitely the worst. If I were writing the backend myself, custom might not have been so bad, but since I was always working with other developers, it was always a pain because it required involving someone else to test the thing and there was always something wrong with the certificate setup on the server. Out of all of those OneSignal has been the easiest, followed by Parse. I like OneSignal better than Parse though because it’s just push instead of one part of a larger thing that sort of expects me to be using their whole platform.

Email Validation String Extension

I’ve been using this extension on on String to make checking if a string is a valid email easy. If you know a better place this could live, let me know, but an extension on String felt as good a place as any. I didn’t write the original regex (although I did need to tweak it to make addresses with + in them work), but I’ve tested it and it works well as far as I can tell.

extension String {
    func isValidEmail() -> Bool  {
        if self.isEmpty {
            return false
        }

        guard let regex = try? NSRegularExpression(pattern: "^([a-zA-Z0-9_\\-\\.\\+]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", options: []) else {
            return false
        }
        return regex.numberOfMatchesInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == 1
    }
}

Less Gross Storyboard Segue to a Navigation Controller

This is a really ugly piece of code I’ve found myself writing in Swift whenever I’m preparing a storyboard segue where the destinationViewController is a UINavigationController whose root view controller is the thing I actually need to set properties on:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let viewController = (segue as? UINavigationController)?.topViewController {
        // Set up the view controller
    }
}

And so I decided to make this slightly less terrible by adding this category to my app:

extension UIStoryboardSegue {
    var navigationController: UINavigationController? {
        get {
            return destinationViewController as? UINavigationController
        }
    }
}

So now that ugly line becomes this:

if let viewController = segue.navigationController?.topViewController {
        // Set up the view controller
}

In Praise of Non-Magical Pointing Devices

Last week I tried playing a game on my Mac for the first time in a long time. About a minute in I realized that a trackpad or Magic Mouse was not going to cut it. I needed something with actual separate buttons that click. The one I landed on, after reading a few positive reviews, was the Razer DeathAdder Chroma. Yes, I agree the name is ridiculous. I choose not to focus on that.

I like it for a few reasons:

  • It’s the number one gaming mouse on Amazon, but doesn’t look too much like a gaming mouse, which is good, because I couldn’t look at one of those and take myself seriously.
  • It only has two side buttons, which is just the right amount for me. I bound them to back and forward in Safari, Xcode, etc.
  • The driver software is fantastic for the tiny bit of tweakiness I want (assigning those side buttons), and also totally Mac compatible. You can even easily set different button configurations for different apps, and it will switch automatically.
  • It feels pretty good in my hand. The buttons feel nice and clicky, too. The Magic Mouse gives me hand cramps.
  • It was only $50.

The things I miss are interial scrolling and gestures. But those suck on the Magic Mouse anyway, and are easily fixed by placing my trackpad on the other side of my keyboard for gestures.

The Myth of Gentrification

This Slate article makes a case, based on a bunch of data, that the problems talked about with gentrification are overwhelmingly incorrect, and that focusing on them has been at the expense of awareness and addressing real problems.

That gentrification displaces poor people of color by well-off white people is a claim so commonplace that most people accept it as a widespread fact of urban life. It’s not. Gentrification of this sort is actually exceedingly rare. The socio-economic status of most neighborhoods is strikingly stable over time.

The “Why Am I Anxious?” Checklist

I’ve come up with a list of things I should ask myself and do if I’m feeling anxious or antsy. Here it is:

  1. Did I not have any coffee today? Have some.
  2. Have I had too much coffee? Drink some water. Take a walk.
  3. Did I sleep not enough or too much? Keep working on that.
  4. Am I worried what someone is thinking of me? Talk to them.
  5. Am I worried about something I’m not doing? Stop worrying and do some of it.

No matter what:

  1. Remember you’re not stupid and people like you.
  2. Drink some water and take a walk.

Brent Harping on Swift Limitations

Brent is harping on limitations you hit when trying to use protocol oriented programming in Swift:

But these days we’re smarter: we use protocols. There’s no reason Folder and File should descend from the same class — they’re almost entirely different, and inheritance is a pain to deal with, so we use protocols instead.

And we’re happy. It works great.

Until you realize that, in Swift, you can’t do this.

I hit something like this yesterday. So no, it’s not just him.

How John Zeratsky Became a Morning Person

This post on Medium by John Zeratsky echoes a lot of what I’ve felt, and what I’m trying to get to. This part describes how I’ve been my entire life:

It didn’t come naturally to me. When I had to wake up early—for a meeting, an event, or class—it was like the vignette above. I struggled to get out of bed. Often I barely made it to my engagement on time. And that rushed, zombie-like morning loomed over my day like a hangover.

John also was motivated by the same thing I am though; the promise of how much more you can get done by being a morning person. Whether I like it or not, the world isn’t likely to adjust to my natural schedule, so if I want to get by in it, I need to figure out a way to change this about myself. Missing mornings — or being awake but useless for them — means I’m missing a couple hours every day I could be participating in the world, or doing something good for myself. The best part is that it worked for John, and he’s kept it up:

It worked. I traded a typical night-owl schedule—up ’til midnight or later, staring at a screen, writing, doing design work, coding—for an uncommon routine where I go to sleep early, wake up early, and get a lot of work done in those quiet morning hours.

If he did it, maybe I’m not hopeless.