Archive for the ‘Various Frustrations’ Category

Bad things: Extension Access Control

Swift extends the courtesy of an access control annotated extension to its top level members. I’m going to call this “inheritance”, but I know there’s a better name for this but I just don’t know what it is.

Consider the following:

// Base type is public
public struct MyStruct {}

// Here, the extension is declared public, so each top level member
// "inherits" that access level.
public extension MyStruct {
  // This is public even if it is not annotated
  static var firstValue: String { return "public" }

  // This is also public but the compiler will warn.
  public static var secondValue: String { return "public but warned" }

  // This class is also public via "inheritance" 
  class PublicSubclass {
    // However, its members must be annotated. This is public
    public static let publicValue = "public"
    // This defaults to internal
    static let internalValue = "internal"
  }
}

In this example, firstValue inherits the public access level from the MyStruct extension. The explicit annotation for secondValue is warned by the compiler as unnecessary.  If you treat warnings as errors, that’s a problem.

Each of the static properties are accessible outside the module except for internalValue, as even in a public class declaration, its members do not inherit its control level:

Before I start putting some preliminary style guidance out there, I’d like to point out a few more things about this. Here’s a second example:

internal class InternalType {}

extension InternalType {
  public static var value: String { return "value" }
}

Swift compiles this code without error. It is clearly a developer-sourced issue. The intent to make the member public is fundamentally flawed. as it exceeds the type’s access control level. This issue also exists outside of extensions, where the compiler will not warn on too-high levels for direct type members:

internal class AnotherInternalType {
  public var value = "value" // no warning
}

You’d imagine this is a place where the compiler should up its game, no? This is a point of code that is technically functional and compilable but whose specification undercuts the documenting nature of using access control. Shouldn’t the annotation be limited and warned here?

The compiler will find mismatches between the extension ACL and the type ACL:

And that’s where the problem comes in because the guidance I’m working on says: “Do not annotate extensions with access control levels except when working with trivial utilities”. Skipping extension ACL ensures that you can meaningfully and intentionally add access control to each member declared within that extension. Each access level is co-located with the declaration it decorates. This makes your code more easily audited and its access levels will be immediately apparent as to intent and implementation.

What are your thoughts? Can you think of any reasons why extensions should ever be ACL’ed in production code? And is this just a bug/language enhancement thing or is there something I’m missing. Thanks in advance for your feedback.

Fleeing Bluehost: It’s crunch time

I have under 30 days to move from Bluehost or I’ll be locked into another year. If you don’t recall, Bluehost is infuriating. It shuts down whenever I have a traffic spike. Its SSL certificates are not automatically renewed, so every 90 days or so things fail.

My email is associated with unifiedlayer, one of the worst spam providers, which means that a lot of my outgoing email never arrives. Every time I need tech support, they try to upsell me to yet another paid service. The fees have increased and increased over time.

While I’d really love to have a statically generated site, I’m not willing to give up comments. I’m sticking with WordPress as the least turbulent solution unless someone has a better idea.

I need email. I need a wordpress site. I’d like to keep a listserv going but I can probably transfer that to slack if needed. I can’t really think of any other features that I need at this time.

  • Diogene recommended SiteGround. It offers well reviewed WordPress hosting. This sounds scary though: “For migration just use IMAP for your email and synchronize all mail locally then when you move you host sync back again with IMAP”
  • Dave DeLong says FastMail is a great solution for the mail-only axis. Hank Gay, Christopher Frederick, and Dewey concur. Christopher mentions that I can set up “SPF and DKIM records” to provide more secure ownership, whatever these things are.
  • Despite the general love for FastMail, Michael Weaver says iRedMail is a good alternative as well.
  • Matt mentioned nosupportlinuxhosting.com
  • Will suggests A2Hosting. Chris likes ASPnix.com.
  • John Woolsey pitches GreenGeeks.com.
  • Nate H suggests dreamhost (also recced by Tim as a site for “people who don’t know what they’re doing”, which is pretty much me) and siteground.
  • Mark Nichols uses WebFaction, but also supports Digital Ocean.
  • Brian Anderson suggests hostagor.com.
  • Kevin likes the roll-your own AWS solution: S3 for web, EC2 for wordpress, WorkMail for mail. Any thoughts on these?
  • Simon Davies agrees on AWS but suggests hosting email with zoho.com.
  • Dan Messing and Mark Bernstein like pair.com.

I’m looking for the simplest migration with the longest shelf life and the least worries. It should remain reasonably budget affordable as well.

I want to get this done quickly and easily and it scares me to pieces. This is, admittedly, way out of my comfort zone, which explains why I’m still with Bluehost even years after identifying the problems.

Any advice and support will be greatly appreciated.

UX fail: Logging into Apple TV

My son brought a new (which is to say, an old) Apple TV into our lives yesterday. He picked up a 2nd gen unit from Goodwill for under ten bucks in excellent condition. We were delighted.

Even older Apple TVs, a couple of generations before the app store hit, allow you to share music from the family library, watch shows and movies, project from hand-held devices, and use TVs as wireless extra displays.

We immediately began setting it up. The first issue at hand was to log into my Apple ID, so the unit could see my account, purchases, and home share.

I use long passwords. I recommend long passwords. Entering long passwords on a 2nd generation Apple TV using a remote is…well, it’s pretty horrible. Even though I’m a bit proud of my remote skills (for example, press-and-hold to access upper case letters from the lower case screen, or using hold-to-slide for quick letter navigation), it still takes a significant amount of time to enter my password.

And, when I had done so, and counted off the number of dots and confirmed they matched the right number of password characters, I expect that I was done with setup once I clicked the continue button.

Nope, not so quick.

It wasn’t until after Apple TV asked me whether to store my password for purchases (no thank you), and had moved onto yet another screen, that it stated I could not log in at this time. Something something about verification.

I assumed I entered the password wrong but I was a bit befuddled that it didn’t tell me that right away. I had already moved a couple of screens forward before it rejected my entry. What was going on?

After a few times through the process, I knuckled down and hit the web to search for “Apple TV verification”. That’s when I discovered that I needed to generate a verification code and add it to my password (one after the other, all in text in a single privacy-protected box) to log into my iTunes account.

This design shocked me. There was exactly no information listed on the enter password screen suggesting you need to not only enter your password but also append a six digit two-factor code to your password. There was no information guiding users through the steps to generate that code. There was no support for automatically sending a two-factor request to other registered devices, the way it normally works with my browser. Instead, you must generate a verification code on an another device using the same Apple ID.

I use two primary Apple IDs: one is for iTunes purchases and is shared with my family. The other is for my development work. All my mobile devices are signed into both, but you can only generate a verification code for your iCloud ID. You cannot for your iTunes ID.

I had to go through the hassle of picking a victim iDevice, logging out of iCloud, including disabling Find My iDevice and deleting all local iCloud data, just so I could log in using my iTunes account to generate my 6 digit time sensitive verification code. (Settings > iCloud > username > Passwords & Security > Get Verification Code)

It took me quite a bit of time to get a device to the point where I could do that. Wisely (but really just luckily), I left the device logged in to the iTunes iCloud account. I had not realized I’d need to authenticate in several places on Apple TV. The first time accessed my purchased content. The second time enabled home sharing. Again, without any hints about extended passwords and 2FA.

Fortunately, I targeted an aging iPod touch as my sacrificial victim, which, while running the latest iOS release, is not a heavily used dev system. I have not yet moved it back to my main iCloud account  just in case I have to go through this nonsense again.

Once I had my six digits, I had to add them to my password entry. Since timing is critical, I had to type out the password first, fetch the code, and then enter the verification code on my  Apple TV, which had gone into screen saver mode due to the delay. I added the digits to the end of the password (none of which are readable, it’s all dots), and hoped that it took.

All of this took place without any textual or visual indication to set user expectations that the password needed extra characters at the end to begin with.

This is probably the worst design for 2FA anyone could have come up with and I’m baffled at how this got past any level of management to be presented in Apple deployment. It feels like the first iteration of a solution offered by a summer intern before anyone with sense got involved.

I’d imagine that the second you enter an Apple ID, the device is fully capable of determining whether 2FA is needed. If so, it should guide the user how to obtain that information. Add some text, show a video, do whatever is needed, but contextualize!

Assuming that people know how to create the code and then append the code to the password is asinine. It’s also bad design. Make the 2FA code a second screen, for heaven’s sake. Lead users through the process. And for all that is good and holy, don’t make the user pass through one or more screens after the failed password before informing them that (1) the password didn’t take and (2) a validation step is needed and should have been done several screens earlier.

In the best of all worlds, just allow the 2FA code to auto generate and notify the way it does with Safari. Manual generation should be the fallback position only if associated devices are not available.

Every week or two, I have to re-enter a code to access Apple’s developer site. My office rings with the various beeps and whistles of 2FA. Every device helpfully shouts out its association with the iCloud account and provides a six digit key for me to use right away.

Having to laboriously set up a device and then manually generate a code is nonsense. Differentiating the main iCloud account and the iTunes account, both of which have been authenticated, is also nonsense. If a device is signed into both, it should produce 2FA codes for both.

The screen that most offended me was the one interspersed between the “enter your password” and “you need a verification code”. Who gave the okay to continue on with the “use this password to authorize purchases” screen before confirming 2FA? It’s just insane.

In the end, a process that should have taken 5 minutes max stretched to nearly 90. If someone comfortable with problem solving and web searches was this put off by the anti-intuitive UX design, imagine how Apple’s core customer base will react.

This is the furthest I’ve ever gotten from “it just works” in Apple’s ecosystem and a user experience that gives me great pause.

ISO-8601, YYYY, yyyy, and why your year may be wrong

The end of the year is rolling around and it’s time to remind everyone about that yyyy works the way you think it does and YYYY does not. Here’s a quick example to start:

Just because you test a format quickly with the current date and get back the result you expect, does not mean you’ve constructed your date format correctly.

Speaking of which, BJ Homer points out that you can just use “y”, as “yyyy” pads to 4 digits which doesn’t usually matter but isn’t always needed. Olivier Halligon adds, further, that not all calendars use 4 digit years. “For example the Japanese start a new era every time the emperor changes, resetting to year 1 in that era; we’re currently in year Heisei 30.”

To quote The Dave™: “Nooooooo…. Please use “y”, not “yyyy”. “yyyy” zero-pads years that aren’t four digits, and there are multiple calendars w/ 2 or 3-digits years (Japanese, Chinese, Republic of China). “y” is the natural length of the year: “30” for Japanese cal, “2018” for Gregorian, etc”

What you’re actually seeing with “Dec 24, 2017” is the first day of the last full week of the preceding year. It doesn’t matter what numbers you plug into the month (“MM”) or day (“dd”). The presence of YYYY in the date format without its expected supporting information reduces to “start of year, go back one week, report the first day”. (I’ll explain this more in just a little bit.)

Here are some examples, which you can check from the command line using the cal utility:

As Apple’s 2014-era date formatting guide points out:

A common mistake is to use YYYY. yyyy specifies the calendar year whereas YYYY specifies the year (of “Week of Year”), used in the ISO year-week calendar. In most cases, yyyy and YYYY yield the same number, however they may be different. Typically you should use the calendar year.

Unicode.org’s Unicode Technical Standard #35, Date Format Patterns goes into a little more depth:

[“Y” is] Year (in “Week of Year” based calendars). This year designation is used in ISO year-week calendar as defined by ISO 8601, but can be used in non-Gregorian based calendar systems where week date processing is desired. May not always be the same value as calendar year.

ISO 8601 uses a 4-digit year (YYYY) for “week of year” calendars from 0000 to 9999. If you’re into trivia, the years before 1583 are technically excluded except by special agreement between sending and receiving parties.

Anyway, if you’re going to use YYYY formats, you’ll want to use additional format elements that support “week of year” date construction. For example, consider the calendar for this upcoming January, which starts on Tuesday the 1st:

    January 2019      
Su Mo Tu We Th Fr Sa  
       1  2  3  4  5  
 6  7  8  9 10 11 12  
13 14 15 16 17 18 19  
20 21 22 23 24 25 26  
27 28 29 30 31

This year, January first can be considered as the first week of 2019 or the 53rd week of 2018, as the weeks overlap in the middle. Using e (the numeric day of the week) and ww (the ordinal week to count from), you can represent both dates correctly using the oddball YYYY formatting token.

Here are examples that use the week-of-year approach counting from both 2018 and 2019:

As you can see from this, when you use YYYY and do not supply an ordinal week or day, they both default to zero, which is why you get the behavior of the zeroth week (that is, the week before the first week) on the zeroth day (also, the first day of that week) for that calendar year, which is the week before the first week that overlaps the stated year. This explains the results of all those otherwise random late-December dates from earlier.

ISO 8601 should be updated in a few months, with a release somewhere around February.

From what I can tell, the first part revises the current standard and the second expands it. The only freely accessible human-viewable material I could find were the five-page TOC previews for 8601-1 and 8601-2.

(Hat tip: Thanks, Robin Malhotra)

Prototyping CoreGraphics in the Playground

No matter how flaky, I love using playgrounds to prototype Core Graphics, SpriteKit, and many other see-as-you-go technologies. They’re fantastic for building out specific custom content with a bare minimum of coding investment. You get a lot of win for very little time.

I was helping someone out the other day, explaining the strokeEnd keypath (versus the path keypath) and building a playground showed it off to perfection.

Admittedly, it helps to have quick helper code on-hand for quick starts. I have playground-specific setup code, handing me a view controller (called vc) and a centered view, ready to start demo-ing in this one.

I also have a couple of pages of code (like the layer(path:) constructor, the animateStrokemethods, and the schedule() utility off page, in the support module. They’re all highly reusable. It’s a pity in-playground debugging is so dreadful. It would be an ideal module-building tool if not for that: build and explore (and ideally build tests) in a single place, without having to be in a fixed workspace lacking the exploration feature. Adding “convert this exploration into a test” would be icing on top.

I’m disappointed that playground-specific visualizations built for teaching and demos don’t transfer to the debugger for real-world production support. I don’t see any reason why a CGPoint instance should get a pretty graphic representation but a CGAffineTransform, for which I have quite a full presentation, does not.

I can use custom mirroring to produce valuable output for dump, and therefore for printing objects in the debugger but not for debug quicklooks. Plus as far as I can tell the custom NSObject-only quicklooks haven’t been updated in years and there’s no hint of extending this to structs and enums.

By the way, what’s the deal with all the API audits? How long are these going to go on? If you thought updating the app delegate was a minor nuisance, you haven’t seen what’s happened to all the constants and Core Graphics APIs. This update is huge and disruptive…

Return to Sender: My first dive into watchOS

Just wrote my first two watchOS apps. The first, intended to provide voice coaching for physical therapy exercises, was a failure. Timing just wasn’t reliable and the errors built up more and more over a session of repeated counts, holds, and “almost there”/”two more”/”last one” prompts.

The second was a simple D&D dice set and much more successful. (Barring, of course, my miserable sense of interface design.)

It consists of an iOS app paired with a watchOS extension, which runs as its own watchOS app, allowing anyone with an arm and a need for d20 to roll at will.

The WatchOS APIs were disappointing at first glance. For one thing watch buttons use target-action but provide no sense of sender. A single iOS call must be split into 7 calls on the watch:

// iOS. I used tags. Sue me.
@IBAction func roll(_ button: UIButton) {
    let value = Int.random(in: 1 ... button.tag)
    let percent = button.tag == 100 ? "%" : ""
    label.text = "\(value)\(percent)"
}

// watchOS
@IBAction func d4()  { label.setText("\(Int.random(in: 1...4))")  }
@IBAction func d6()  { label.setText("\(Int.random(in: 1...6))")  }
@IBAction func d8()  { label.setText("\(Int.random(in: 1...8))")  }
@IBAction func d10() { label.setText("\(Int.random(in: 1...10))") }
@IBAction func d12() { label.setText("\(Int.random(in: 1...12))") }
@IBAction func d20() { label.setText("\(Int.random(in: 1...20))") }
@IBAction func dPercent() { label.setText("\(Int.random(in: 1...100))%") }

There’s no auto-layout so far as I can tell, so you either “fill” things or you give them fixed sizes. I couldn’t figure out a way to split my buttons into thirds of the available screen space.

Setting a label’s text is a matter of a function call not a property assignment. That was surprising to me. I’m not sure what advantage was gained here beyond violating the principle of least astonishment.

I had to design my app’s interface in the WatchKitApp target but implement it in the extension target. This may be perfectly normal and in-line with other extensions on iOS but I haven’t spent much time there so it raised my eyebrows a bit. You add your app assets in the app, your complications (which I did not build) in the extension.

Right now on my priority list, I’d like to build something similar to the “breathe” app. I don’t entirely know where to start. I need to use a notification system to launch the app at set intervals, n times a day, preferably during the work day, and then use some kind of coached interaction with haptic feedback. My immediate goal is one that has me regularly exercise my sitting back muscles to build up strength.

I’m a bit sad about the timing issues I encountered with my first jab at the coaching app. I may approach that again with a new design as having my wrist count and prompt would be a lot better than having to do all the work myself (I always lose my place) or having to keep my phone nearby.

My need for reps, holds, and rest periods are simple. And while I don’t particularly like the scrolling wheel that seems to take the place of segmented controls, I can live with them.

If you’d like to see my first project (either to be inspired or to offer critiques), I’ve left a copy at github.

That darn Maps app

Dear Maps team,

Please don’t route me onto a dirt road again. It was super un-fun. I ended up going back up to I-80 and heading over to Wyoming from Nebraska, adding another state and about 5 hours to my trip including the not-joy of I-25 rush hour traffic instead of the much quieter I-76 through Fort Morgan.

It was impossible to get any live data from said dirt road so I just went with my gut until I could get directions again, which took about 2 hours, placing me just outside Cheyenne.

Navigation through Nebraska is always horrible horrible horrible, usually just blank tiles until I hit either Colorado or South Dakota. When going state to state, I’d like to cache tiles along several possible routes because with so much highway construction, I don’t want to be caught with blank tiles in the middle of Nebraska when I have to go twenty or forty miles off to the left or right to avoid a road that isn’t roading at the moment.

Caching tiles and directions along many possible routes would have helped the whole dirt road fiasco. The no-data-no-tiles-no-rerouting trap is both unsafe and unpleasant. Plus it made me miss Sidney, NE, with the only truck stop I’ve ever encountered in the United States that offered bidets (!) in their bathrooms. A true tourist’s experience.

While I’m venting, please respect my wishes about “No tolls” or “No highways” for my entire trip, even if I take a slight detour to avoid traffic. Forgetting “Show me how to get to [Someplace] avoiding tolls” when I reroute cost me  unnecessary funds recently by putting me onto 470, aka the hell road. I was properly billed (thankfully!) and paid immediately but no one voluntarily drives on E470.

Maps folk, please let me say “Show me how to get to Colombia, MO avoiding tolls and dirt roads” and remember that request until I’m safely at my destination. And let me add those requests as I’m driving. During rush hour, let me say “Hey, let’s get off the highways until I’m close to 225”. That’s totally doable from a programming point of view.

Speaking of slight detours, I generally know better than Maps how to tweak directions within the first few miles of my home. For example, I prefer to take the relatively quiet 13th and 14th streets from downtown instead of Colfax or 6th. There’s an incredibly unsafe left turn near our house that Maps always recommends. I drive a little further and make a safe U-turn at a light with a dedicated left turn signal.

I do these tweaks near my home all the time and Maps shouldn’t be fighting me on this, announcing updated directions every single block. I’d like a setting that limits any directions at all (after the initial announcement) for the first, say, mile or two or three away from my home or other “known” starting points that I could add to a list.

In fact, I know how to get to many major milestones within the greater Denver metropolitan area like 225 and Vasquez, and Hampden and 25, and Colorado and 70. I’d like to be able to have navigation kick off once  I’m near a known point or I’m close to the highway or fairly far along towards my destination. That shouldn’t be too hard to develop and customize, requiring no in-car interaction so it’s safe.

In many cases, I only need last mile assistance when driving in-city, including other cities I’m familiar with like Colorado Springs and Fort Collins. I wish I could ask for a “guide me when I’m close to” setting for these kinds of navigation requests.

Thank you all. You know I appreciate everything you do!

Converting projects by hand to Swift 4.2

If Xcode is acting up for you the way it is for me, you may want to step back from automated migration and just do it by hand. I spent far too much time this morning trying to get Xcode to finish migrating for what were extremely trivial changes.

If you’re going by hand, make sure to change your “didFinishLaunching” launch options (in your App delegate) from [UIApplicationLaunchOptionsKey: Any] to use UIApplication.LaunchOptionsKey. (Notice the period in the name.)

To set the compiler from Swift 4 to Swift 4.2, open Target > Build Settings. Navigate to Swift Language Version and use the pop-up to select the proper compiler:

For some projects (especially small sample code) this alone may be sufficient to get you back and working.

Are you red-green color blind? How do you handle git color coding?

Git version control, whether at the GitHub site or at the command line is ostentatiously color-coded. How do red-green color blind users (a common issue for Engineers) deal with this? Any suggestions for discussing how to use the alerts and coding as in the following screenshots aimed at a potentially color blind audience? Thanks in advance!

Untracked and tracked files are color coded

Additions and deletions are color coded

Using TextEdit as your git editor

For a little while, I’ve been using emacs as my git editor because I strongly feel that vi is something that should happen to other people. It’s been fine but not everyone loves emacs or likes the debris it leaves in its wake. So I thought I’d try out TextEdit instead.

After a little testing of approaches, I first tried out this:

git config --global core.editor /Applications/TextEdit.app/Contents/MacOS/TextEdit

I picked this rather than some of the other approaches because it’s straightforward in launching the app. There’s one problem though, which is that git doesn’t pick up on the fact that a file has been edited and closed when the application remains active:

% git commit --amend 
hint: Waiting for your editor to close the file... 
(...waits forever...)

The commit completes and works when I quit TextEdit but I don’t like  to quit the app each time I update a commit, especially if I have other files open. The amended commit does complete on quit:

% git commit --amend [master 59a0934] Testing TextEdit!
Author: erica <erica@ericasadun.com>
Date: Thu Jul 12 08:02:26 2018 -0600
1 file changed, 3 insertions(+), 1 deletion(-)

So I changed my approach. I turned to open instead:

git config --global core.editor "open -W -n"

TextEdit is open‘s natural environmental editor for text. You don’t have to specify more than open for git to work with the right editor.

This approach uses two tweaks. When you launch an app with open, the -n flag instructs open to launch a new instance of the application even if one is already running. You may see two “TextEdit” icons open in your dock, for example.

Combine -n with -W and you have a slightly better solution.  The -W “wait” flag tells open to keep waiting until the launched application has finished running. This allows git to to wait “for your editor to close the file”, which you do by quitting TextEdit. Sure, I’d much prefer that TextEdit run using a “single file” mode, but this isn’t a bad solution.

Sadly, I couldn’t find any undocumented launch flags to make TextEdit run in single file mode and while it’s easy enough to write a Mac app that edits a single file at a time and quits on closing, it’s not a practical solution for everyone.

Is there a way to automatically propagate “done” back to git without ending a TextEdit process? I couldn’t find one. If you have a better idea, please let me know.