Archive for the ‘WWDC’ Category

Happy WWDC: Watch the keynote live

Apple’s keynote (aka it’s Special Event) will be streamed live at 10AM PDT (11 Mountain, 12 Central, 1 East coast, etc etc). If you didn’t score a golden ticket, you can watch along on the Apple event web page or on your Apple TV.

I’ll update this post with thoughts and reactions as the event unfolds.

  • iOS 12 announced as a free update. New measurement app for supporting devices will allow you to measure and scan physical scale using an AR experience. Lego’s demo shows that multiplayer AR can be a fun and exciting experience. Sample code going home with developers today.
  • Enhancements to photo search and sharing put the focus on the user-product experience. Today’s keynote, more than ever, seems to be focused on selling their existing products.
  • I love extensible Siri (aka “Siri Shortcuts”, with a dedicated drag-and-drop Shortcuts app), with custom end-user phrases to perform app integration and tasks. Siri will suggest these custom items. Create a macro for common tasks you group together and launch with a custom phrase. A great way to perform everything you need to get to work, hit your commute, or head off to lunch.
  • Several redesigned apps: News, Stocks (with integrated Apple News’s business section, adding iPad support), Voice Memos (also with iPad support), iBooks which is renamed to Apple Books.
  • CarPlay will now support third party navigation apps, so you can Waze your way home.
  • Lifestyle improvements continue with “Goodnight Moon, Goodnight Watch” do-not-disturb mode for bedtime and other naturally concluding cycles. Enhanced notification control, including grouped notifications, diminishes notification burnout.
  • Screentime lets you analyze how addicted you are to your devices, with full activity reports that summarize how often you pick up your device and what apps you spend the most time in. App Limits provide an alternative to 12-step Appholic programs.
  • Animoji enhancements adds tongue detection to improve language and emotional expressiveness. Memoji adds an iOS “mii” customization to animoji.
  • Group Facetime now supports up to 32 participants. With Animoji and special effects support, it’s like you’re doing drugs while sober.
  • Apple Watch gets some enhancements for health and fitness, including group competitions to motivate participants. Apple has added Clippy for automatic workout detection: “It looks like you’re starting an exercise routine”. New watch-to-watch walkie-talkie feature adds a little fun for kids and anyone who wants to harass the cook in the kitchen. “Whaaaaats for diiiiiiinnnner?”
  • Gymkit sounds like fun.
  • Apple TV adds Dolby Atmos sound and is Dolby Vision certified. Better integration with cable TV partners including Charter Spectrum in the US. “Zero Sign-on” means that all the channels you pay for are automatically configured on your behalf. Beautiful new whole-Earth aerial joins the lineup.
  • macOS Mojave: Inspired by the desert at night. Desktop stacks allow you to group material together to save space. Preview markup moves to the Finder! Markup augments screenshots. You can also capture video demos from your screen using a built-in video recorder. Integration between your Mac and your phone allow you to use the phone camera to capture pictures for use in iWork. (Apple Work?) Voice Memos, Home, News, and Stocks are now on macOS.
  • New privacy measures are in place. Today I learned: you can be tracked by a “fingerprint” including the fonts you have installed and other “public” customizations. Scary.
  • Redesigned App Store is redesigned. Pretty.
  • CreateML lets you develop assets and train models for Machine Learning. CoreML 2 is 30% faster and quantization reduces model size by up to 75%.
  • 2019: iOS Apps come to the Mac. A multi-year roadmap converges design and a whole new generation of developers flood the platform for the benefit of the Mac as well as iOS.

Happy WWDC: Time to unenroll your devices

It’s that special time of year: new announcements, new APIs, and new betas. If you’ve got a device you depend on, don’t forget: it’s a great time right now to unenroll your beta profile so you don’t accidentally upgrade to beta 1. A big thank you goes out this morning to Jeff Forbes, who reminded me about the timing!

Unfortunately, all the developer support docs are currently offline before the event. I’ve reconstructed the following from memory and web searches as I deleted my iOS beta profiles about a month or so ago. If I’ve gotten anything wrong, please let me know and I’ll correct.

If you’re on macOS, open System Preferences > App Store, and click the “Change” button next to Your computer is set to receive beta software updates. Confirm “Do Not Show Beta Software Updates”. I chickened out from actually clicking the button this morning on my dedicated primary beta system so I don’t know the steps from there.

On iOS, hop into Settings > General > Profile to delete the iOS Beta Software Profile. I believe you tap “Delete Profile”, enter your passcode, and then tap Delete. Once deleted, the device should longer subscribe to the iOS public betas.

The problem with Swift Playground localization

Starting in Swift Playgrounds 2, you can now use localized strings to guide the narration of your interactive lessons. As the screenshot above demonstrates, you can used localizable markup to provide the most appropriate text for titles, introductory text, and feedback.

However, what you can’t do is localize Swift members. Your French and Chinese consumers must tell Byte to moveForward(), not avancer() or 向前移动().

One of the guiding principles of the Swift language is demonstrated in its embrace of unicode for identifier symbols. This approach accommodates programmers and programming styles from many languages and cultures.

Xcode 9 has introduced major advances in code refactoring. It seems an obvious win to allow that technology to be applied to Swift Playgrounds 2, enabling identifier localization.

That’s because identifiers play such a key role in Swift Playgrounds. Unlike standard development tasks, where it’s unnecessary to create idiomatic APIs like IUContrôleurDeNavigation, the point of Swift Playgrounds is to teach and instruct. It uses small, limited, controlled API exposure, nearly all custom and supporting of the teaching story.

The anthropomorphized Byte character acts as a stand-in for the learner coder. And in doing so, it should communicate with commands that this coder identifies with, turnLeft and moveForward, not incomprehensibleForeignPhrase1 and evenMoreConfusingForeignPhrase2.

I think this is an opportunity waiting to happen, and I can’t imagine it would be all that hard to implement given the expansive identifier suite and the limited API visibility presented in a typical playgroundBook.

What do you think? Is it too much to ask for a localizable.Members.plist?

Bug reporter complaints

I wasn’t part of the bug reporter preview but having used it today, I’ve got to say that I am not a huge fan of the updated interface. It may be pretty, but for me it’s harder to use. I’d rather see icons and names at the start of the entry screen than scroll through three pages of iconless text (and their subtables) as I try to recognize the phrase that best matches my issue.

It’s funny because this design is a clearly cognitive mismatch between how I used to find the right items, which was just a matter of a single-screen scan, and trying to construct or detect the right verbal phrase that now matches the target issue. The new system is hitting the wrong part of my brain.

If you look at it, it’s laid out very nicely, with big clear areas to enter text and the “drop a screenshot” system is vastly improved over the old system. (Nice job there!) I like the font choices, can live with the sickly purple, and a lot of thought has gone into streamlining issue entry.

That said, the whitespace feels like there’s too much there, the left-to-right range of field width is too hard to scan to review the information you’ve entered, and as I mentioned before, the ‘What are you seeing an issue with?” tables are a little too much for me to process.

If I were to redesign it, I’d:

  • Change the wording to be more business-like: “Classify this issue:”, not “How would you classify this issue?”. “Affected Product or Area”, not “What are you seeing an issue with?”. “Bug or Suggestion”, not “What kind of issue are you reporting” (with the bias being towards ‘bug’, since that’s the primary purpose of the tool.) “Reproducing the issue”, not “What steps can we take to reproduce this issue”, and so forth.
  • In the prompt text, I’d eliminate weasel words. “Step-by-step instructions to reproduce this problem”, not “Please provide a step-by-step set of instructions to reproduce the problem (if possible).”
  • I’d cut back massively on the vertical whitespace, allowing more of the report to be seen at once. There’s just too much floaty gray for my taste.
  • I’d apply one of the “optimal line length” studies, which suggests anywhere between 50 and 75 characters per line for text (which is most of what this tool provides) and 80-160 characters for code entry. (I’d also consider a code-specific “related code” field.) The current width is about 98 characters if I counted correctly. It is very hard to track from the right back to the left while maintaining vertical positioning.
  • I’d explicitly mention Markdown/Common Mark support for bullets and numbering, as well as other markup.
  • I’d change the Suggestion/Bug toggle into either a radio control or a visual toggle with Bug, which should be to the left, pre-selected.
  • I’d massively increase the size of the “Cancel/Save/Submit” buttons and move them from the bottom bar to the main field under attachments.
  • Finally, I’d add a specific call out on completion. Thank the developer for taking time from their busy workday and express appreciation for participating in the radar process. Enroll them either in a rewards-for-radars program or a random giftcard giveaway for the month. It’s a small price to sweeten that “Radar or GTFO” message and it lowers frustration of typing into a big, faceless, low-feedback system.

Those are my thoughts. What are yours?

Apple open sources key file-level transformation Xcode components

Ted Kremenek writes on the swift-dev list:

This afternoon at WWDC we announced a new refactoring feature in Xcode 9 that supports Swift, C, Objective-C, and C++.  We also announced we will be open sourcing the key parts of the engine that support file-level transformations, as well as the compiler pieces for the new index-while-building feature in Xcode.

We will be releasing the sources in stages, likely over the next few weeks:

– For the refactoring support for Swift, there are some cleanups we’d like to do as well as some documentation we’d like to author before we push these sources back.  Argyrios Kyrtzidis and his team from Apple will be handling that effort.

– For the refactoring support for C/C++/Objective-C, these are changes we’d like to work with the LLVM community to upstream to the LLVM project.  These will likely be first staged to the swift-clang repository on GitHub, but that is not their intended final destination.  Duncan Exon Smith and his team from Apple will be handling that effort.

– We’ll also be open sourcing the compiler support for indexing-while-building, which include changes to both Clang and Swift.   Argyrios and his team will be driving that effort.  For the clang changes they will likely be first staged to swift-clang, and then discussed with the LLVM community to upstream them to mainline Clang.

– Finally, we will be open sourcing the remaining pieces of the Swift migrator.  Argyrios and his team will be handling the push back of changes there, and those changes will only be impacting the swift repository.

As usually, we’ll also be pushing back changes to have Swift work with the latest Apple SDKs.  We’re expecting that push back to happen early next week.  When that happens we will temporarily lock commit access to the repositories.  Details about that will be sent out later in a later email.  Until then, the downloadable toolchains from Swift.org will continue to work with Xcode 8.3.2.  After we do the push back the downloadable toolchains will be moved to be baselined on the Xcode 9.0 betas.  This shift is necessary as changes to the overlays depend on the latest SDKs.

Dear Erica: Playground Support Folder

“N” asks: “Hey, is the “shared playground folder” long gone, or does it still exist?”

Still there, still useful.

The big difference for long-time playground users is that it moved into the PlaygroundSupport module from the XCPlayground module. The latter was deprecated in Xcode 7. It’s a tiny module that supports playground-specific features. This constant (playgroundSharedDataDirectory) gives you a well-defined sandboxed folder that’s shared between all playgrounds.

This is, by the way, a terrible symbol name (take note!), as it returns a URL. It used to return a string but the name never got updated:

public let playgroundSharedDataDirectory: URL

I often build playground-specific subfolders so my directory doesn’t get all messy.

Another valuable feature is indefinite execution support (needsIndefiniteExecution) for playground pages that have to perform asynchronous work before completion. You can use this support to build little playground-based utilities instead of writing shell scripts.

I have some pages that work with Imgur, Google search, Wolfram queries, etc. A nice thing about building in playgrounds vs shell is that you can integrate audio and visual elements rather than having to save them to files and open them in helper applications.

If you’re writing API utilities, enable manual execution. Constant reloads can almost immediately deplete, for example, your Gist API query count for the day. Oops.

In Xcode, the shared data folder is available for iOS, macOS, and tvOS playgrounds. The shared data folder is not available on iOS’s Swift Playgrounds. This policy discourages custom local storage and access beyond standard media library locations.

There are some further protocols and types under the PlaygroundSupport umbrella in Swift Playgrounds. These aren’t available for Xcode playgrounds because they’re meant for use in Playground Books.

The extra functionality is part of Playground Book support, which underlies the tech in “Learn to Code”, etc. These additional APIs include items like a key-value data store, message passing between the live view and the primary playground page, and more.

If you want to learn more about Playgrounds, I have a book.  It discusses the features you use in Xcode and an overview of how to use iOS Playgrounds. I quite deliberately did not include much about Playground Book authoring as the topics are somewhat orthogonal.

I’ll probably be revising both Playground Secrets and Power Tips and my Swift Documentation Markup after WWDC. There’s also a three-book bundle available with Swift from Two to Three.

Explorations into the Xcode Source Editor Extensions underbelly: Part 1

Xcode source extensions are wildly exciting, surprisingly limited, and infuriatingly frustrating to work with. So I thought I’d share some experiences so you don’t have to suffer through some of my issues.

There are bunches of posts around the web on how to create extensions and I really don’t want to dupe their effort. In a nutshell, create a new Cocoa app. Then create a new macOS > Application Extension > Xcode Source Editor Extension target in that app. You’re ready to code.

If you watched the WWDC video, you’ll have seen the whole process of “run the target in Xcode and a new version of Xcode pops up with a darkened label and then you can test your extension”. I’m here to tell you that this approach is a huge steaming pile of crap doesn’t work as well as I’d hoped. What you really want to do is this:

In AppDelegate.swift of your extension/app project, add the following method. It lets you launch the app, install the latest extension and get the hell out of Dodge without using the “Xcode with the darkened label”.

func applicationDidFinishLaunching(_ aNotification: Notification) {
    let alert = NSAlert(); alert.messageText = "Extension installed! Click OK to quit."
    alert.beginSheetModal(for: window) { _ in
        exit(0)
    }
}

In your main extension Swift file (the class defined for XCSourceEditorExtensionPrincipalClass), add this. It lets you watch the OS X console and ensure that your extensions loaded the way you expected them to. Notice that I use NSLog and not print. Always use NSLog, so your output and debug info goes to the system console.

func extensionDidFinishLaunching() {
    NSLog("NAMEOFMYTARGET extensions did finish launching")
}

Set up your Info.plist in a separate editor pane or even a separate window. If you intend to create a multi-part extension (and most people will), you’ll want to build that extension incrementally and slowly add items to your XCSourceEditorCommandDefinitions dictionary. A typical entry looks like this:

Screen Shot 2016-07-21 at 10.20.38 AM

Also, don’t do what I did here. I used “sadun.ExtensionTestbed” because I know this is a throwaway. Assume you may write multiple extension groups and reverse namespace them properly, e.g. “org.sadun.ExtensionName.CommandName”.

Each time you want to test do this:

  1. Build your target.
  2. Open Products, right-click the .app file and show in Finder.
  3. Quit Xcode and run the app.
  4. Launch Xcode.
  5. Open any project that isn’t a playground because Xcode hates me and doesn’t want to properly load extensions for playgrounds. Always start with a non-playground project and *then* open a playground if you want to work with playgrounds.
  6. If the extension is greyed out (and if you follow these instructions they usually aren’t because this is the sequence for El Capitan that appears to be super reliable), check the OS X console. Look for assertion failures, XPC connection failures, and invalidated connections. If you see these, quit Xcode and relaunch. What you want to see there is the “did finish launching” log line.

I know this workflow is a super pain, especially given Apple’s promotion about in-Xcode testing without quitting and relaunching (let alone running the standalone app), but it’s transformed my source editor extension duty cycle from impossible to annoying. A huge win.

Notes:

  • Don’t “clean” your Xcode extension project while running the extension. Ooops.
  • Once the extension crashes, you need to re-run the installer app.
  • I can’t seem to grab a single cursor position, there has to be an actual selection, so my extensions for adding and removing “/// ” for doc comment markup mean you have to select a line, not just move the cursor there. Or maybe there’s a bug that’s screwing this up. I haven’t quite figured this out yet.
  • A lot of my code is super redundant: operate on all lines, operate on all selection lines, operate on selected text. I really need to re-architect a common subclassable system because the actual logic for most plugins is only a few lines or a call-out to another class.
  • Any extension that works on all lines rather than individual selections seems to be more stable in my experience.
  • My experiments trying to create interactive UI elements with extensions hasn’t been going very well, they run in the original application and not in Xcode, the window is behind xcode, they can’t be interacted with while Xcode is running, and you inevitably have to force quit something.

Screen Shot 2016-07-21 at 10.39.39 AM

Here are some things I’ve been messing with. Let me know how your extensions are going for you.

Playgrounds 6: Focusing Interaction

Screen Shot 2016-06-24 at 9.37.20 AM

In this screenshot, I’ve circled a bit of directed interaction. There’s a highlight around “0.5” and a pop-up editor that allows the user to change the value. This new feature is made possible by Swift Playground markup.

Like all Swift playgrounds, this page uses live code, some of which you see and other parts of which are hidden, either by placement in Sources or by using playground markup. The code is marked up to disable edits except in this one place. Here’s what the key part of the underlying code looks like:

filter.setValue(/*#-editable-code*/1.0/*#-end-editable-code*/, forKey: "inputAmount")
imageView.image = UIImage(ciImage: filter.outputImage!)

Yes, those are in-line comments adding markup in the  setValue call. It’s kind of ugly and it relies on the old-style C /* */ comment delimiters that allow the markup to be inserted in-place.

From a coding viewpoint, it’s ugly as sin. From a user experience viewpoint, it ensures that users can explore exactly one setting to better understand the Core Image vibrancy filter.

This is no way, at least at this time, to use markup to limit values to legal parameters. For example, Core Image may not like negative numbers or numbers above 1.0. You could work around that by using a separate variable and adding clamping code, e.g.

var inputAmount = make this editable
inputAmount = clamp(inputAmount, 0.0, 1.0)
filter.setValue(inputAmount, forKey: "inputAmount")

But if you do that, you’re drawing attention away from the CI code you’re demonstrating and focusing it on user interaction instead. No one’s going to use this pattern in real code, while they may very well use the pattern in the screenshot. (Which, if you think about it is the real point of this.)

I’ve gone ahead and filed a radar (26996963) about the issue, asking for enhanced markup that allows input qualities for editable playground sections.

I probably should file another one asking for “Auto Run” markup, so these kind of examples will re-execute on each edit, just like they do on OS X.

iOS Playgrounds Part 5: Editing real code

While stuck at the Dr’s office, with my daughter being attended to, I decided to try editing a Swift 2.2 playground in iOS Playgrounds, to see if I could upgrade it to Swift 3.0.

The tl;dr is that the tools, while not fully baked, are just as amazing as they were in the WWDC demos. With a few (notable) exceptions, editing source code, invoking fixits, etc. are beautifully realized to the point that I was able to perform non-trivial edits while sitting in a waiting room and using an iPad:

Screen Shot 2016-06-21 at 11.19.54 AM

I was able to fully update this playground page to run and render.

The Good

Built-in fixits are glorious. As in normal Xcode, they update code by inserting missing labels or replacing code:

Screen Shot 2016-06-21 at 11.24.44 AM

Multiple errors are paged (as you can see with the two dots at the top of the complaint), and there’s amazing cross referencing with related items, such as when a protocol is not properly implemented or partially implemented. You just tap away to the error point for the candidate issue.

Number and color edits are fantastic: I didn’t realize you could use the number tweaker to just “dial” your way up and down numbers by continuing to twirl into the number pad:

Screen Shot 2016-06-21 at 11.21.21 AM    Screen Shot 2016-06-21 at 11.21.29 AM

Pages I didn’t expect to work did work! Like this one:  It’s really short. Give it a try. Screen Shot 2016-06-21 at 11.36.42 AM

The Not So Good

You can’t fixit many errors:

Screen Shot 2016-06-21 at 11.30.49 AM

But you can select things and start to type and Playgrounds picks up the context for you:

Screen Shot 2016-06-21 at 11.31.37 AM

The Ugly

Screenshots are for live views, not playground views. And for some reason, I’m having a lot of difficulty today doing screenshots the old way (hold down sleep/wake, then click home). All of these screenshots are from Xcode’s device window instead.

A lot of confusion comes from inappropriate or missing tool tips. Sometimes it leads you down the garden path:

Screen Shot 2016-06-21 at 11.51.25 AM

Screen Shot 2016-06-21 at 11.53.11 AM

What was actually needed looks more like this:

Screen Shot 2016-06-21 at 12.09.44 PM

Trying to edit “advancedBy” to “advanced” by moving the cursor to the end of By and backspacing was simply a no-go. Playgrounds will remove the entire call at once.

You get a lot of problems with 2.2 items needing to be lowercased for 3, or using old CG constructors like CGRectMake not auto-fixing to CGRect(x:y:width:height). Playgrounds just don’t quite get the “fixit” needed for these simple switches.

Screen Shot 2016-06-21 at 12.16.05 PM

Even when you’re typing things in, Playgrounds doesn’t always offer you the right choices. In this example, all this needed was to lowercase CGAffineTransform to cgAffineTransform. No fixit and no syntax match:

Screen Shot 2016-06-21 at 12.12.39 PM

The really cool “drag parenthesis pairs into place” shown in the demos don’t seem to work in the app yet. Instead all I could drag was the letter “j”. (Update: Drag down and left or down and right and then use a second finger to tap or drag the updated key. It is hard but doable. If you’re not coordinated, use two hands. Thanks Seán Labastille)

Screen Shot 2016-06-21 at 11.44.59 AM

You can’t look up module definitions in-place.

No access to Sources that I can find so I can fix errors:

Screen Shot 2016-06-21 at 11.29.05 AM

The live views are distorted:

Screen Shot 2016-06-21 at 12.18.46 PM

Screen Shot 2016-06-21 at 12.19.23 PM

But other than that, wow, what a cool tool. I’m really enjoying it a lot.

Xcode Woes and Noes

Update: I did finally get stuff working after re-installing Xcode about a dozen times. And then it started acting up again. And then a few installs later it worked, etc. etc. Anyway, the gist at the bottom of this post works and I think it’s much more Swifty.

Screen Shot 2016-06-20 at 1.36.29 PM

So I’m watching 414. And I look at that code and I’m all “I could totally improve on that”. So I start, and once again, Xcode 8 blows up. I get the dreaded “Unable to determine compiler to use – the abstract compiler specification is missing from this Xcode installation” error, just like I do every time I try to create a new extension project or do anything particularly stressing to Xcode 8.

Screen Shot 2016-06-20 at 12.44.00 PM

Reinstalling Xcode 8 fixes everything until I attempt to open or create a project with an extension or I look at it wrong, because this issue isn’t limited to extensions.

You’d think this would be a really easy fix — edit a file somewhere or create a link or something — but I can’t figure out what to fix.  It’s particularly annoying because There’s so much in this original code that ticks me off (and no, that’s not my final code at the top of the list, that was just my first go at it, freehand).

Screen Shot 2016-06-20 at 1.40.47 PM

I can’t specify line numbers because the demonstrator didn’t enable them in Xcode (Preferences > Text Editing > Editing > Show > Line numbers). But here are a few key irritations:

  • Using an integer line index instead of enumerating and using key-value
  • Not guarding a conditional cast versus forced casting
  • Creating an array with () instead of a literal (: [Int] = [])
  • Building an Int-ish array instead of a [XCSourceTextRange] one from the start.
  • The newline update thing surely could have been done better.
  • Rule of Lily violation with “map”.
  • I hate “in” on the same line in closures.
  • The dictionary is ugly. And it’s declared in every run of the loop.

In any case, it’s unlikely I’ll get to play around with this because Xcode hates me. I thought I’d share and hope someone knows how to fix the dependency issue, and also it’s a kind of fun bad Swift snippet to fix, even if you can’t run the code and test it.

Let me know what you’d fix and if you get it running, share some code!

p.s. Update: Still no idea if this will work, but if you try it do let me know how it goes: