Archive for the ‘Xcode’ Category

Running Python in Xcode: Step by Step

As I’m preparing for a project that will involve Python programming, I need to get up to speed with at least a basic level of Python mastery. However, I’m not a big fan of using the interactive Python REPL, or whatever it is actually called:

screen-shot-2016-12-04-at-11-37-21-am

I decided to use Xcode instead, and I’m finding it a much better solution for my needs:

screen-shot-2016-12-03-at-8-31-15-pm

Here’s the steps I took to set up this project:

Step 1: Install Python 3.5

If you run python -V at the command line, macOS reports “Python 2.7.10”, or at least it does on my system. Bzzt. I want 3.5.2, which is the most recent non-beta release, and dates to June of this year.

I grabbed my installer from the Python.org downloads page: https://www.python.org/downloads/release/python-352/

Step 2: Locate python3

I use tcsh, so where python3 reports /usr/local/bin/python3. The location is surely the same for you, but I don’t know what the equivalent for where is in bash.

Step 3: Create an Xcode project

File > New > Project > Cross-platform > External Build System > Next.

screen-shot-2016-12-04-at-11-44-06-am

Enter a name (e.g. Python), and enter the path from Step 2 into the “Build Tool” line. Click Next.

screen-shot-2016-12-04-at-11-44-43-am

Navigate to whatever location you like, and click Create.

Step 4. Create a Python file

Choose File > New,  select macOS > Other > Empty. Click  Next.

screen-shot-2016-12-04-at-11-48-04-am

You should already be in your project’s top level folder. If not, go there. Name your file Whatever.py, choosing whatever name you like. I went with Work.py. Make sure the “add to target Python” box is checked. Click Create.

screen-shot-2016-12-04-at-11-49-43-am

Step 5. Edit your Run Scheme

The Xcode default should have the Run scheme selected:

cap

Click and hold on the Python target in the jump bar. Select Edit Scheme…

screen-shot-2016-12-04-at-11-50-56-am-2

The Run scheme displays, with the Info tab selected.

Step 6. Choose the Executable

I warn you now that this step is going to be delicate, fragile, and stupid. That’s because Xcode, for whatever reason, will not let you use the symbolic link at /usr/local/bin/python3. I don’t know why.

In the Info tab. Select “Other” from the Executable pop-up list. A file selection dialog appears.

cap

 

Return to the terminal. Type: open /usr/local/bin. Select python3 and control-click/right-click. Select Show Original. This will probably be named python3.5. It’s not a symbolic link but unfortunately Xcode continues to be fussy about allowing you to select it as your executable because of the period in its name. Sigh.

Drag python3.5 onto the file dialog and click Choose, if you’re allowed to. If so, great. If not, you need to work around Xcode: create a hard link and then drag the link onto the dialog.

% ln python3.5 python35

I know, I know. Ew. But it’s better than copying, or worse, renaming the file. And no, symbolic links don’t seem to work here. Better solution? Let me know.

Finally, uncheck “Debug executable”. You don’t want to debug the Python language itself.

screen-shot-2016-12-04-at-12-05-26-pm

Step 7. Add Launch Arguments

Now, click the Arguments tab. Click + under “Arguments Passed On Launch” and type $(SRCROOT)/ followed by the name of the Python file you created in Step 4.

screen-shot-2016-12-04-at-12-07-02-pm

Step 8. Test it out.

Click Close to dismiss the scheme editor. Enter a program (don’t forget all those colons and tabs) and run it:

screen-shot-2016-12-04-at-12-38-05-pm

It’s a very odd thing to be jumping into Python with a Swift background. Clearly Swift has inherited a lot of Python genes. It also feels sinful to use such lax typing without compiler oversight. That said, my first experiences in Python can wait for another day and another post. More to follow.

PaintCode releases new update and leaves App Store

screen-shot-2016-11-02-at-8-54-38-am

I’ve been a fan of PaintCode for a long time. PaintCode is a drawing and programming app that lets you move between code and rendered pictures. With it, you can create paths and fills, and then paint that information right into your app code using a variety of development languages.

Mike A at PixelCut dropped me a note last night letting me know that PaintCode 3 is now ready for release. The new version adds Android code generation, JavaScript, Telekinesis and more, in addition to Objective C and (now) Swift 3 support.

You can now use parameterized methods to draw into target rectangles. The app supports destination behaviors like aspect fit, stretch, center, etc. Although I’ve long since developed similar code for my own use, this is a great feature to add without relying on the end-coder’s expertise.

PixelCut has also made the choice to leave the Mac App Store. I’ve reached out to them to find out more about their decision.

PaintCode isn’t cheap but it’s a good tool for anyone who uses a lot of vector art, drawing, and paths in their code and they’ve been dedicated to keeping the tool current and updated. Existing customers get a 20% discount off the $99 app price.

Xcode 8 Document Coding Enhancements

Now that I’ve gotten Swift 2 to 3 ready and out, I’ve turned my attention to Swift Documentation Markup. I’m updating the book with both Swift 3 examples and markup enhancements. Xcode has added some great new features although as you’ll see there’s still work left to be done.

Xcode’s automatic doc-comment skeleton command is super handy. Move the cursor to any symbol and select Editor > Structure > Add Documentation (Command-Option-/). Xcode scans the symbol you’ve chosen and adds a doc-comment outline including named parameters and return types if they exist.

screen-shot-2016-09-16-at-10-46-30-am

You may want to add further comment features like notes, warnings, authorship, dates, and complexity details, but the basics provided by Xcode form a great place to get started.

One Xcode feature that’s just launching is support for treating closure parameters as first-class documentation elements. Xcode’s default documentation doesn’t include closure parameters, as you see in the screenshot that follows.

screen-shot-2016-09-16-at-11-06-41-am

Swift’s new “no  labels for function types” means that many developers will not include the internal declaration arguments that I use in this example for the action parameter.

By adding internal arguments like (_ line: String), you can extend your documentation. Xcode picks up and formats that information into a special closure parameter box, subordinate to the closure that uses that parameter. Here’s an example that extends the code documentation you just saw:

screen-shot-2016-09-16-at-11-09-13-am

Swift’s native comment schema suggests that Xcode could potentially add further support. The schema includes nesting parameters, return values, and throws document comments, as promised in this commit:

screen-shot-2016-09-16-at-11-15-05-am

As far as I can tell, the only feature that is currently supported by Xcode is the named closure parameters, demonstrated above. Here’s what the schema looks like from Swift’s point of view:

<!-- In general, template parameters with whitespace 
   discussion should not be emitted, unless direction 
   is explicitly specified. Schema might be more strict here. -->
  <choice>
    <element name="ClosureParameter">
      <optional>
        <ref name="Abstract" />
      </optional>
      <optional>
        <ref name="Parameters" />
      </optional>
      <optional>
        <ref name="ResultDiscussion" />
      </optional>
      <optional>
        <ref name="ThrowsDiscussion" />
      </optional>
      <optional>
        <ref name="Discussion" />
      </optional>
    </element>
    <element name="Discussion">
      <ref name="BlockContent" />
    </element>
  </choice>

Unadopted Swift enhancements don’t end there. There’s further work to be done to support changes provided by Swift but not picked up on by Xcode. Here are examples from the Swift language change log and from Swift proposal SE-0111:

  • Three new doc comment fields, namely - keyword:- recommended: and - recommendedover:, allow Swift users to cooperate with code completion engine to deliver more effective code completion results. The - keyword: field specifies concepts that are not fully manifested in declaration names. - recommended: indicates other declarations are preferred to the one decorated; to the contrary, - recommendedover: indicates the decorated declaration is preferred to those declarations whose names are specified.
  • This proposal introduces two new document comment fields, MutatingCounterpart and NonmutatingCounterpart. These replace the roles of the former mutable_variant and message arguments. Under this scheme, @discardableResultwill not use arguments. Documentation comment fields will, instead, supply usage recommendations in both directions.

iOS Playgrounds: Where is my print output?

Nate writes: “I can’t figure out how to show console output/print in the Swift Playgrounds app for iOS.”

All print output appears in the “sidebar” to the right of the code as little pop-ups:

Screen Shot 2016-06-22 at 1.11.56 PM

Embed the viewer by tapping “Add viewer” so you don’t have to keep popping up the quick view.

The hint box shown (for example “123”, or “?”, or “abc”, etc) depends on the type of item produced. The tiny cube represents an class instance.

Screen Shot 2016-06-27 at 11.40.51 AM

Like desktop playgrounds, you can view a single value at a time or tap the embedded display to select other views like List view:

Screen Shot 2016-06-24 at 12.15.27 PM

Compilation errors appear in-line for main playground code:

http://ericasadun.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-21-at-11.51.25-AM.png

Sources-based errors (which  you cannot yet fix in the app) are shown as popups. When these issues occur, debug back on  your Mac before trying again on iOS.

http://ericasadun.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-21-at-11.29.05-AM-535x401.png

It’s important to remember that the iOS Playgrounds app almost never is running the same version of Swift as you are on the desktop and won’t be until both Swift 3 and iOS 10 go gold.

Want to learn more about iOS Playgrounds? Read Playground Secrets and Power Tips.

Messing with Extensions: Describing color literals for the color blind

As the latest nightly build of Swift refuses to link on my system, I put together a new source editor extension. Developing these is still about as fun as having wisdom teeth pulled (actually the dental surgery would be more fun) but I’ve learned to keep a terminal window open so I can repeatedly delete derived data between builds:

Screen Shot 2016-08-03 at 11.41.33 AM

The new extension looks for a color literal on the cursor line and uses the XKCD color library to describe it.

Devolving your projects

So you moved to 3 and now are suffering from regretsies. Or you’re using Xcode 8 and you want to build a new 2.3 project. Fear not. Here are some tips for all your legacification needs.

Downgrading a Swift 3.0 Project

If you’re feeling especially regretful about moving a project to 3.0, you can downgrade it back to 2.3, but expect work unless you can regress to an appropriate commit. Adjust your build settings to use Legacy Swift (aka Taylor Lautner):

Screen Shot 2016-07-22 at 10.24.46 AM

Building a New 2.3 Project in Xcode 8

Since Xcode 8 doesn’t let you build 2.3 projects, you need to create a 3.0 project. Use build settings to regress to Legacy Swift.

After, make sure to convert all the code back to 2.3. Xcode offers most of the fixits you need for skeleton projects. Be aware that using “Fix all in scope” tends to crash Xcode 8. (27486260).

Screen Shot 2016-07-22 at 10.26.50 AM

Once converted, throw in a for-loop. This ensures that you’re actually running and compiling Swift 2.3 and not Swift 3:

Screen Shot 2016-07-21 at 9.31.42 PM

Importing 2.2 to Xcode 8 as Swift 2.3

If you’re working with an existing 2.2 codebase and are not ready to migrate to a language that has not, as yet, finished its design, you can choose the Swift 2.3 compiler.

First convert the project.

Screen Shot 2016-07-21 at 9.24.41 PM

Next, choose 2.3. The dialog defaults to Use Swift 3, so don’t hit Next until you mentally confirm your choice.

Screen Shot 2016-07-21 at 9.24.47 PM

For many 2.2 projects, you’re ready to rumble.

Screen Shot 2016-07-21 at 9.25.00 PM

Projects that use deprecated APIs and target iOS 10, may need upgrading:

Screen Shot 2016-07-22 at 10.36.19 AM

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.

https://gist.github.com/erica/2e6cecf5fae2a206faed440539c514c4

Accessing complete stdlib module declarations

Have you noticed that Command-clicking symbols doesn’t get you the whole stdlib module any more? Instead, you get all these individual submodules:

Screen Shot 2016-07-05 at 11.01.19 AM

Thanks to Mike Ash, I have a workaround.

Step 1: Type `import Swift`

Step 2: Command-click Swift.  *bam*

Step 3. Copy paste the entire thing into a reference file on your desktop. Handy beyond handy.

NOTE: Command-clicking Swift at the top level jump bar (circled) doesn’t work. Radar 27174641

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.