Archive for the ‘iOS’ Category

Beta 3 iPad Control Center Updates

The screenshot facility is still broken, retaining the orientation (including sideways and upside down, or blank if launching) of the last application use. However, those tiny “x” buttons for closing an app are gone. It’s slide-up again. Thank you, Apple.

Incidentally, battery life has been good (it was good in Beta 2 for me but I hear that iPhone users weren’t as lucky as iPad installs). And responsiveness is pretty good.

Lessons Learned: iOS Extensions and Keychain Accessibility

Today’s lesson is courtesy of Rizwan Sattar, who writes:

If you’re building a notification service or content extension, keep in mind that these extensions will run even after a device restart, before the first unlock. Normally Apple recommends to set your Keychain items as kSecAttrAccessibleAfterFirstUnlock for “items that need to be accessed by background applications”. When you’re accessing the keychain for things in your notification extensions, you’ll want to set it to kSecAttrAccessibleAlways or kSecAttrAccessibleAlwaysThisDeviceOnly, etc instead.

Thanks Rizwan!

Dropbox’s very bad not okay UX on iOS

Consider this question for a second: why do people own Dropbox? So they can put stuff into it and grab stuff out. Sure, there are other features but that mission statement pretty much the bottom line for iOS use. So why is Dropbox’s iOS client so horrible?

Start with the main menu bar. After selecting an item that you want to open in another app, which of these icons do you tap? The garbage one is clearly wrong, but the ellipsis is a very muddy choice. This should obviously use the (user-facing) share/(developer-facing) actions icon instead.

Apple’s design team agrees.

Once tapped, what’s the next step for “Open in”? Move and copy make sense but you have to tap “Export”, which finally uses the actions icon to give the hint that you want to open the selected file in another application. Bad naming, although it does appear properly as the first action.

Once tapped, you next have to find “Open In”. I have a couple of blockers installed (which shouldn’t even appear in this action sheet), so you have to scroll right to find the right icon.

It’s only after I scroll right that I finally locate “Open In” and can start the progress of opening my file in an appropriate application.

To summarize:

  • The ellipsis is a bad choice. It should be the Action/Share icon and it should directly open the Action Sheet.
  • Rename and Move should be placed into a separate “File actions” menu, along with discard (the trash can). They don’t belong grouped with the Action/Share sheet, which has a specific and conventional meaning in iOS.
  • The app should use care, especially with known file extensions, to limit the options presented in the sheet. “Open In” should be about the only choice for an epub extension file, and the other actions should be constrained to the invoked context.
  • Dropbox made me sad.

iOS 11 Screenshots

The new iOS 11 screenshot / edit feature has got to be my very favorite thing of the upcoming firmware update. Saving a screenshot creates a thumbnail in the bottom corner of the screen. Tap it to enter an edit mode that lets you crop and mark up the image.

  • Scroll left and right to move between screenshots if you’ve snapped more than one.
  • Use the blue handles on the sides and corners of the screenshot to crop the shot.
  • Select an editing tool (pen, highlight, pencil, eraser, lasso, and an assortment colors) then draw with your finger.
  • You undo-and-redo using buttons at the bottom left of the editor window (not shown here, because I hadn’t made any edits yet).
  • Tap Done at the top left to leave. You can save your shot to the photos album.
  • Otherwise, tap the action button (top right), to print, air drop, email, or otherwise work with your now-edited image.  I love the air drop option, which lets me snap, edit, and then throw the image into a blog post or a slack channel.

No wires, no fuss, just great convenience.

Holy War: Why I utterly loathe the new app switcher in iOS 11

Beta 3 Update: iOS 11 Beta 3 now supports swipe-up-to-close instead of the tiny little “x” buttons.

Under iOS 10, you could switch between apps or remove an app from the “recent list” by following these simple steps:

  1. Double-click the Home button to see recently used apps.
  2. Swipe left or right to find the app that you want to use.
  3. Tap the app or swipe upwards to quit/remove it from the list.

  • Each page was  clear and easy to identify. The app name and icon appeared on top.
  • The nearly full size rolodex presentation ensured that users with poor eyesight could easily identify each app.
  • The swipe area to select or remove an app was large, supporting users with a wide range of dexterity skills and motor limitations.

It was a great system that worked well.

In iOS 11, Apple redesigned. It decided to combine this recently used apps list with the control center, so that you could put as much information on-screen at once as possible. This produced an interface with teeny tiny images, and lots of user confusion overload.

In other words, in the current beta and the presentation at WWDC, they espoused a system that is best used by nimble millenials who unlike most every fidget-spinner-ing millenial I have ever met, would not be overwhelmed by sensory overload when presented with far too much information on a single screen.

In my opinion, this new design doesn’t work for the young, the old, the millenial, the seasoned pro, the able, the dis, the hawkeyed, or the near blind. Apple basically disregarded every rule of human usability and thrown it all together into a jumbled disorganized mess:

Compare this screen, with its dock, its windows, and its nearly two dozen control affordances to the iOS 10 version.  It’s a big jumbled insane mishmash of a UI design mess.

The controls in particular are unlabeled. Consider the timer, alarm, and stopwatch icons. They’re nearly identical and randomly scattered. And I can’t for the life of me remember what the dot is to the right of the camera.

As I constantly harp on about, a key factor in enhancing usability is to prioritize recognition over recall. As much as the Apple engineers have aimed to make all the buttons recognizable, they really aren’t.

You have to remember what a lot of these items do: the man in a circle, the magnifying glass, the three different clock faces, etc. You must further remember what happens when you tap and hold these as several of these items have secondary panels with embedded controls beneath them.

This 3-in-1 design breaks George A. Miller’s basic rule of working memory. Miller’s rule argues that you should not present the user with an overwhelming number of interactive items at once. The user cannot effectively remember and strategize interactions when shown more than seven or nine items at a single time. It’s as if Apple didn’t bother passing this screen through a usability evaluation process.

Working memory is not all that’s wrong with this design. In iOS 10, you just tapped or swiped up to manage apps. Those are both relatively large motor functions that require little fine control. That makes them an excellent match for a wide range of user ages and abilities. (Plus the pictures are all big and easy to recognize!)

Compare with iOS 11. To remove an app from the recents list, here’s what you have to do:

  1. Enter the control center. (In an improvement over iOS 10, this can be done with double tap, even if you’ve disabled swipe-up for the control center.)
  2. Swipe left and right to locate the app of interest.
  3. Tap and hold any app screen until the “X” buttons appear (and, maddeningly, the icons and app names disappear). This wait is short but frustrating.
  4. Tap exactly on the “X” to dismiss any app. This usually takes me upwards of three or four tries because the “X” is so small, my coordination is bad, and apparently I may need to re-align my touches with the OS.

In the end, the new control center a big giant mess trying to do too much in a massive design mishmash. I wish Apple would go back to its original design, although I wouldn’t mind some way to access the control center from the App Switcher.

Update: Oh you have to be kidding me:

If you like my posts and you want to say thanks for helping to prevent the meltdown of global civilization (“But if I’m right, and we can swap out that screen shot… Lenny, you will have saved the lives of millions of registered voters”), consider buying a book.  Save the Turtle, save the World. Choose the form of your Constructor. Thanks, all!

The Unexpected Joy of Vector Images in iOS 11

A few years ago, I griped about That Vector Thing, which was the way that Xcode 6 handled PDF vector assets and could not extend them to arbitrary use in UIImages.

Enter WWDC 2017. In Session 201 “What’s New in Cocoa Touch”, Apple described Asset Catalogs with PDF-backed vector images. All you have to do is tick the “Preserve Vector Data” checkbox.

After chatting with some colleagues about whether this would actually work as promised, I dragged up a 29×29 vector PDF image.

And I added it as a 1x image in an asset catalog. Notice the Resizing checkbox to the right. It is normally unchecked by default.

I then built a super-simple single view testbed to test things out.

override func viewDidLoad() {
    let imageView = UIImageView()
        .translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFit
    ["H:|[v]|", "V:|[v]|"].forEach { format in
            .constraints(withVisualFormat: format, 
                options: .init(rawValue:0), metrics: nil, 
                views: ["v": imageView]).forEach { 
            $0.isActive = true 
    let image = UIImage(named: "Biff")
    imageView.image = image

Here’s what that 29×29 image looks like running on an iPhone 7+ in the simulator. The 1x image is being rendered on a 3x destination, at a greatly magnified size. Its vector data ensures the image renders without losing detail or clarity. Compare it to the same asset that does not preserve vector data and my original test from 2014:


Click above to see full size screenshot originals. Below is a comparison shot from the simulator at the largest size.

I expect there are minor performance hits in scaling and rendering the vector image compared to loading a standard PNG or JPEG, but I didn’t get around to measuring the costs.

If you like my write-ups, please consider buying a book.

Solving Mathieu’s Phone: The mystery of disappearing gigs

The other day, Mathieu’s 16 GB phone suddenly had no space. Even after rebooting, even after reformatting (and not restoring from backup), all his spare bytes were being sucked into a black hole.

He had no songs, few apps, a modest number of photos, and under a gigabyte of space available, making him unable to compile, load, and tests his apps.


Each time he deleted one of his apps, the space would mysteriously fill up within a few minutes, adding to the ever increasing “other” bar in iTunes:


This delete-then-lose-space behavior made me think that iCloud was trying to store files locally on his phone to reduce cloud access. I suggested that he disable iCloud and sync just the bare essentials like contacts, calendars, and notes. (Mathieu has a paid 300GB iCloud plan.) Sure enough once he logged out and rebooted, over 7GB of space was freed up and he was able to use his phone again.

I’m not super-familiar with iCloud so if anyone can further explain how this works, and how to set up the phone to limit it from glomming space, I’d sure appreciate being able to pass that along. Thanks!

Playgrounds Part III

Screen Shot 2016-06-14 at 2.49.47 PM

I have to call it a day, but I’m really happy with what I’ve learned about authoring Playground Books for iOS today. (I’m less happy learning about how to completely reset Xcode — either reboot your system or hop into terminal, do a ps -ax and grep for Xcode and then kill anything with the name in it.) I thought I’d share a few lessons.

If you are going to author for iOS, start with a new playground created from scratch in Xcode 8 rather than modifying an existing one. If you cannot import PlaygroundSupport, reboot your computer. If it doesn’t show up and you’re still using XCPlayground (now deprecated), you’re doing it wrong.

Understand that the Swift snapshot on iOS 10 is older than the Swift snapshot in Xcode so don’t expect to use really recent evolution implementations:

Screen Shot 2016-06-14 at 2.37.05 PM

I ended up implementing my own sequence functions to make my code work.

The easiest way to get started is just to AirDrop a normal playground.

Screen Shot 2016-06-14 at 3.09.40 PM

It will open automagically in Playgrounds for you. When you transfer books, you have to choose “open in Playgrounds” from the AirDrop menu.

If you want to author a Playgrounds Book before tomorrow’s session, just customize a blank document (download at your own risk). My blank book is a one-pager, and you can tweak the Contents.swift file in Blank.playgroundbook/Contents/Chapters/Document1.playgroundchapter/Pages/Blank.playgroundpage. There are manifests at every point along the way, try not to mess them up otherwise the book won’t open.

When authoring pages, either in a normal playground or playground book, you can annotate them to omit details that would otherwise clutter the interaction space or should not be visible to the reader. In my Spirograph playground (download at your own risk), I use special mix of normal playground markup (I have a couple of books that cover this markup format: my Doc Markup book and my Playgrounds book) and these new keywords:

  • Use #-hidden-code and #-end-hidden-code to exclude code from the reader’s view.
  • Mark editable areas with #-editable-code and #-end-editable-code, and if you like you can add a note to the opening tag.
  • To simplify code completion, you can globally omit code completion #-code-completion(everything, hide) and then choose which selectors to present, as I do in the following sample. You see this in the above screenshot, which offers one-tap access to just three customization points for my spirograph.
 **Spirograph:** Play around.
 - Note: The default values are:
 * minor: -3.0
 * offset: 130.0
 * color: .black()
import UIKit
import PlaygroundSupport

public var color =
public var minor = -2.0
public var offset = 130.0

public func setMinor(_ value: Double) { minor = value }
public func setColor(_ value: UIColor) { color = value }
public func setOffset(_ value: Double) { offset = value }
//#-code-completion(everything, hide)
//#-code-completion(identifier, show, setColor(_:), setMinor(_:), setOffset(_:))
//#-editable-code Tap to enter code

let liveView = UIImageView(600, 600, backgroundColor: .white())
PlaygroundPage.current.liveView = liveView
liveView.image = spiroImage(
 size: CGSize(width: 600.0, height: 600.0),
 samples: 4096, minor: minor, offset: offset, color: color)

Parse to shut down on 28 Jan 2017

Kevin Lacker writes on the Parse blog,

We have a difficult announcement to make. Beginning today we’re winding down the Parse service, and Parse will be fully retired after a year-long period ending on January 28, 2017. We’re proud that we’ve been able to help so many of you build great mobile apps, but we need to focus our resources elsewhere.

We understand that this won’t be an easy transition, and we’re working hard to make this process as easy as possible. We are committed to maintaining the backend service during the sunset period, and are providing several tools to help migrate applications to other services.

Parse will release a database migration tool and will open source ParseServer. Regardless, this is going to come as a blow to a large segment of the iOS developer community.

More details at the New York Times.

Weekend Posts