iOS and macOS Performance – Reading Files – Strings vs. Bytes

I can’t quite remember how I stumbled across this book, “iOS and macOS Performance Tuning”, a couple of weeks ago (Twitter, basically). But regardless, it is awesome. Written by Marcel Weiher, it has a couple of simple premises, well explained, that really provides a great roadmap for thinking about performance in iOS.

I will actually write up a couple of blogposts out of this book, because I like it so much and want the lessons to take root. This post will focus on something that I had never really explored carefully, which is working with NSData rather than just initializing Foundation objects with NSData and working with the resulting objects. The two places where this is a natural thing to do is with strings and with images.

I am going to do a very basic demonstration of his principles at work in reading and parsing a large text file, complete with benchmarks!

One of the primary lessons from this book is that regardless of the continuing speedup of devices and storage, the cost of using objects and their associated methods to process data does add up.1 If you are doing relatively complex transformations on a small number of objects, then using the most abstracted models and methods completely makes sense. But, for operations on large numbers of objects, there are opportunities to achieve profound speedup.

A second lesson is that for most operations and code, Objective-C still is faster than the equivalent Swift code. This is an important point that can get lost. Swift is incredibly powerful, and absolutely lends itself to modern programming practices that can lead to a better, safer, more stable codebase. But when it comes to raw performance, it is still difficult to optimize Swift as thoroughly as Objective-C

Read More »

Advertisements

Apple Watch Tips and Thoughts After 2 Years and 2 Months

I have been using my Apple Watch Series 1 for over two years, ever since I was lucky enough to get an early release watch through the Apple developers program. When a friend recently purchased a used one, I sent him a few tips. I figured it has most of the things I would want to pass on to any new user, so without further ado.

For me the series 1 watch has been entirely waterproof. Inspired by Craig Hockenberry. I have gone swimming vigorously in the pool, hot tub, ocean, shower, etc. This is not a guarantee or even recommendation and not what apple warrantees, but >2 years in, it’s been fine for me.

Since the WatchOS 3 updates, texting on the phone watch app is actually pretty decent. Quick replies and emoji actually cover a lot of situations. Siri works quite well. The ability to scribble text for short custom messages when I can’t speak is pretty great and reliable.

Possibly my favorite feature is being able to tap “find phone” in the watch’s control center from watch, which makes my phone beep loudly.

The watch’s integration with Apple maps is fairly slick when driving. looking at my wrist shows the upcoming step quite reliably, and as I am approaching a turn, it taps either left or right patterns to both remind me that the turn is coming and indicate which way to go.

Best workout app for me so far has been workouts . Very customizable, plus it uses the crown to end or pause a workout.

Best sleep app: Autosleep. I have a couple quibbles, but overall, it’s great. Totally automagical. I don’t have to turn on an app when I start sleeping, it just looks at my watches internal motion and heart rate information.

It’s a niche use case, but using the watch with wireless headphones alone without phone does actually work fairly well. Getting content onto the Watch is a little bit of a PITA. You can have one synced playlist with iTunes, and now Overcast app allows you to sync a couple of podcasts to be on the watch itself. The interface for this is simple and great. It is ok from a reliability standpoint, but when I have wanted to go for runs without my phone it has worked ~ 75% of the time. Hopefully, Apple makes this increasingly easier for developers.

Using the complications as a place to launch apps from is really helpful. I have a couple of different watch faces set up with my most used apps for just this purpose.

Timer and Alarm complications are probably my most used functions.

Having the timer as a complication is something I use all the time because of my failing memory to remind me to do something in a fixed period of time. Simple, but effective.

The alarm app on the watch is 10 times better than on the phone. First of all, setting alarms on my watch is more pleasant than on the phone due to the crown. But most of all, for my sleeping alarm, being woken up with some taps on my wrist is less jarring and I don’t have to worry about waking up my bride if we are getting up at different times.

Lastly, since I clearly use watch functions while I sleep, I need it to have enough charge for the night. I find that ~20% is the minimum for a full night of sleep, but that is cutting it close. So I try to make sure it’s at least 35%, especially if I will be relying on the alarm. Likewise, an hour of working out requires ~20-25% as a minimum.

I typically charge it while I shower, and when I flop on the bed before sleep, if I remember, but because it’s important to have a charge while I sleep for my alarms particularly, I did break down and get a second charger that I keep in my office. I added the office charging to my routines, since I use it for workouts, which makes the margin for error slimmer at night, especially if I forget to end a workout and it is running the heart rate monitor all that time.

Overall, I still love it and after over two years, it is running strong. I’ll be curious to see how long the battery will be able to keep up. I’m pretty sure that I will be tempted to get a (currently non-existent) series 3/4 before it has become unable to hold a charge.

Documenting Specific F%&cking Syntax For The Examples On f%&ckingBlockSyntax.com

While I am enjoying Swift more and more, I still love Objective-C, and continue to work in it professionally. One of the biggest syntactic pain points in Objective-C is definitely blocks (closures for the non Objc).

When trying to write an Objective-C block from scratch, the majority of iOS developers turn immediately to fuckingBlockSyntax.com. (This is not a secret) Due to the slightly off-putting syntax that is different in different contexts.

But I often find myself slowed down for a couple minutes trying to turn the generalized syntax (below) into specific syntax:

As a local variable:

returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};

Read More »

Swift Sugar: Ternary Operators – Optional Extension

In my previous post, I wrote some custom operators to function like the Objective-C version of ? : when checking for nil. It worked great, but custom operators ˘\_(ツ)_/˘.

Another approach occurred to me that takes care of the visual clutter that bothered me about this line:

let dependentParameter = optionalParameter != nil ? valueIfNotNil : valueIfNil

I realized that I could simply write an extension to the Optional class:

Read More »

Swift Sugar For Optional Ternary Operators

It is a common situation that an optional parameter is being passed into a function and that some other parameter needs to be set based on whether or not the optional parameter is nil or contains a value.

A typical way of handling this in Swift might be to use the if-let syntax as so:

func aFunction(optionalParameter: String?) {

    var dependentParameter = ""

    if let _ = optionalParameter {
        dependentParameter = valueIfNotNil
    } else {
        dependentParameter = valueIfNil
    }
    //do something with dependentParameter
}

Read More »