Do we really want an iPad Xcode?


Would it really be useful?

When we develop with Xcode, we’re not just running Xcode. We’re also running Pixelmator and Sketch, or Photoshop, any of these possibly in combination with PaintCode, QuartzCode or Core Animator. We’re running Slack or HipChat. We’re running Paw and/or Charles. And speaking of the network we might be using BBEdit or SublimeText to edit some python or ruby, and Transmit for uploading to the server. We might be getting down & dirty with Hopper or Hex Edit Pro or Reveal. We’re running Dash. We’ll have Mail and either FantastiCal or BusyCal running, and you can bet that Safari will have several tabs open to various stackoverflow.com pages. The Simulator will probably be running too and let’s not forget that it isn’t exactly a light-weight process on its own, and of course we’re going to need to bring up Instruments on occasion. We’ll be running SourceTree or Tower because we’re good developers and we use version control. Since we’re good touch-typists we’ll probably be running Alfred for various shortcuts and workflows. And lastly there’s iTunes, because what’s a coder without some motivating music?

whew.

Benchmarks indicate that the A9X has the raw horsepower to run Xcode. But Xcode doesn’t exist in a vacuum, developers don’t run just Xcode. All of the ancillary tools are what really comprise the entire development suite.

I can run a pretty good set of apps along with Xcode on my creaky Mid-2009 MacBook Pro 8GB. Trying to do all of that on the iPad Pro with 4GB RAM1, I’m skeptical that it would be a productive workflow.

What is needed to make the iPad Pro an effective development machine? More RAM would obviously be beneficial and I presume that some future iPad Pro in the future will have that option.

Additionally, app switching and interoperability needs to improve. I don’t know how other developers handle app switching but I’m a heavy user of the Command-Tab shortcut. I use LiteSwitchX to improve the experience, but the basic Cmd-Tab functionality is de rigueur. If an external keyboard is paired with an iPad then iOS does provide a Command-Tab switcher. The issue in that case is how responsive the app is when you activate it. Even on my (relatively) ancient MacBook I don’t generally notice any hesitation, even when switching to an app that hasn’t been used in a while.

Application interoperability is another consideration.It would be interesting to see how source control works, would you send the entire project every time you want to do a git commit?

The final issue would be the low-level tools. Lets face it, I don’t expect Hopper or Hex Edit Pro to ever have iOS versions. But what about Xcode plugins? What about other tools e.g. Fastlane’s Snapshot? These tools aren’t necessary for everyone, but they do provide a definite benefit to some developers.

Some of the above issues are minor or may not apply to your work flow. The major issue I see is the sandboxing of apps, I doubt that’s going away any time soon, but it restricts a lot of tools.


1. I guess I could remove half the RAM in my MacBook and see how it goes, but I have better things to do with my time.

How to view assembly generated from Swift


Xcode currently does not provide any way to view the generated assembly code from Swift source files within Xcode itself1. You can manually generate the assembly using the xcrun command:

xcrun -sdk $(xcrun --show-sdk-path --sdk iphoneos9.0) swiftc -target arm64-apple-ios9.0 -emit-assembly source.swift > output.s

You will need to determine the values for the –sdk (note that this is the switch within the parentheses) and -target switches. To determine which value to use for –sdk use the xcodebuild command:

xcodebuild -showsdks

You determine the appropriate -target argument value using the <architecture>-<vendor>-<abi> triple e.g.:

armv7-apple-ios9.0

arm64-apple-ios9.0

You can determine this value by looking at the build output from the CompileSwift command’s -target argument. You do this by going to the Report Navigator in Xcode and looking at one of the build reports. You’ll need to click on the expand transcript button on the far right:

Xcode Report Navigator annotated

and then look for the -target argument:

CompileSwift  target

Note that this target is not the name of the target in Xcode.

You can also use xcrun to emit IR (bytecode):

xcrun -sdk $(xcrun --show-sdk-path --sdk iphoneos9.0) swiftc -target arm64-apple-ios9.0 -emit-ir source.swift > output.ir

1: rdar://23399706

The ARM64 (AARCH64) stack


I was doing some reading on ARM64 assembly and ran across the following code snippet:

 STP w3, w2, [sp, #-16]! // push first pair, create space for second
STP w1, w0, [sp, #8]

What exactly is going on? Why are these two instructions adjusting the stack pointer one way for the first instruction and the other way for the second? How are the arguments actually placed on the stack?

Let’s take a look. Here is the stack before the above instructions execute:

01

The iOS ABI Function Call Guide specifies that the stack grows downwards, and the Stack Pointer (SP) points to the bottom of the stack (in technical terms the iOS stack is full-descending, where full means that the SP points to the location in which the last item was stored). We also know that the SP may be set to address any byte in memory but according to the Procedure Call Standard for the ARM 64-bit Architecture it must be 16-byte aligned (that is, SP mod 16 = 0) whenever it will be used to access memory.

The Red Zone, a 128 byte area immediately below the SP, can potentially be used for local variables but is otherwise not relevant to this discussion.

Both of the subject instructions are Store Pair of Registers which store two 32-bit words or two 64-bit doublewords from two registers into an address. In this case, the first instruction will move the contents of W3 and W2 (note that the W designation means we are dealing with the lower word of the corresponding X register) into the memory location pointed to by the SP.

First, the SP is adjusted by -16 bytes (i.e. we add 16 bytes to the bottom of the stack) and since the addressing mode is pre-index the resulting address is written back to the SP. If we could set a breakpoint in this instruction after the address is calculated and the SP is updated, the stack would look now like this:

02

After the SP is adjusted, the first argument (W3) is moved to the address pointed to by [SP]. At this point the stack looks like this:

03

 

and then W2 is moved to the address SP + sizeof W3 resulting in this:

04

 

W3 and W2 are each 4 bytes, so they only fill the bottom 8 bytes of the newly created 16 bytes.

The second instruction then uses offset addressing mode and calculates the starting address by adding 8 to the SP (without modifying it this time) and then stores W1 and W0 there. First W1 is stored at the location pointed to by SP + 8:

05

 

And then W0 is written to the memory location calculated by SP + 8 + sizeof W1 and we wind up with:

06

References:

  • Procedure Call Standard for the ARM 64-bit Architecture
  • iOS ABI Function Call Guide

Storing paths


In HouseCat I store the full path to the image files (full-size and thumbnails) in a CoreData entity. An example would be:

/var/mobile/Containers/Data/Application/7DEFAD28-E1B8-4851-996C-355A6ED0C14F/Documents/img/4FBC04DA-AA9C-46DE-A4EF-B51EABF0F40B.png

That path is built via:

// all images (thumbs & full-size) will be stored in this dir:

NSString *imgDir = @”/img/”;

 

CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);

NSString *imgName = CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, theUUID));

CFRelease(theUUID);

NSString *imgSuffix =@”.png”;

 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDir = [paths objectAtIndex:0];

 

NSString *filePath = [NSString stringWithFormat:@”%@%@%@%@”, documentsDir, imgDir, imgName, imgSuffix];

 

I recently ran into a problem where the path became invalid resulting in, among other problems, empty grey boxes where there should be an image. Not good.

After a digging into the problem, I found what happens if the user deletes the app, then restores it from backup: a new Application/UID directory is generated. At that point, the paths in the db point to a non-existant directory.

Oh snap.

The solution is simple, in the CoreData entity just store the sub-dir under the application dir and then dynamically prepend the current app directory at run-time.

Now I need to figure out how to fix this for all existing customers that upgrade to the new version. I’m mulling several options but I think the optimal solution will be to check some user prefs flag on startup and if it indicates that the db is an older version then I’ll just iterate over all the records and fix them with a regex.

//   NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  

//   NSString *documentsDir = [paths objectAtIndex:0];

Mavericks and prefs caching


Good grief, what a pain in the ass.

I was trying to change the default font in Apple Mail 7.3. Changes wouldn’t stick, but I didn’t want to delete the entire prefs file and reset just  to change the display font. Finally worked the process out:

  1. Open Mail prefs
  2. In terminal: killall cfprefsd
  3. Make desired changes in Mail prefs
  4. Exit Mail
  5. Open Mail to verify changes

I found PrefsEditor by Thomas Templemann, looks like I simply need to stop thinking of editing prefs files and start interacting with the cached prefs.

 

Update 15 Jun 2014:

Looks like the changes don’t stick after a shutdown/startup cycle. Restart cycle is OK. Like I said at the beginning, what a pain in the ass.

 

Update 30 Jun 2014:

Made some progress. Finally got around to checking the console logs, saw the following:

6/30/14 10:45:04.406 AM cfprefsd[174]: CFPreferences: error renaming file /Users/asdf/Library/Containers/com.apple.mail/Data/Library/Preferences/com.apple.mail.plist.RtrsKda to /Users/asdf/Library/Containers/com.apple.mail/Data/Library/Preferences/com.apple.mail.plist.

I wasn’t even aware of the Containers directory, so I took a look. The permissions on the file itself looked like they had a stale UID from the old machine so I just reset permissions on the entire Container/com.apple.mail directory (using “Apply to enclosed items…”) and most of the problems seem to have cleared up.

The only remaining niggle is that the selected account always defaults to one that I don’t want. I’ll get back to that when I have some time to waste…

Finally on Mavericks


Yeah, I’m a late adopter… The reason for the delay is that 10.8 was working just fine pretty much until the last few weeks. Then between OS entropy and needing to upgrade the OS for some apps that required it, I decided to bite the bullet.

I use a MacBook Pro and decided to pull the optical drive and replace it with a 1TB 7200RPM, install the new OS on that, and then manually transfer over only the apps that I absolutely needed (not using Migration Assistant). It only took about 15 minutes to install the OWC Data Doubler and the new drive. I then installed Mavericks and copied over the apps and their preferences/support directories. I only really ran into difficulty with Mail (and Keychain), I just had to try a few times before everything got copied over and worked properly but that didn’t really hold me up for too long.

Considering the MBP is a Mid-2009 model, it’s just flying now, everything is snappy and responsive. It’s really like getting a new machine.

I’ll let the old (750MB) drive sit there for a while just to make sure I get everything off it that I need, then I’ll erase it and install the Yosemite beta on it. I’ve already got the Xcode 6 beta and I’m looking to start my next project entirely in Swift.

iTunes Connect Submission template


I keep a text file with the following fields in my project folder, it helps during iTunes Connect submission. As I’m working on the app I fill it out, then just copy & paste when I’m ready to submit:

Name: 
SKU:
Bundle ID:
Support URL:
Description:

Keywords:

Instructions for tester:
- step 1
- step ?
- step 3: profit!

Thank you!
 

(Yes, I thank the tester…)

App Store Pricing


One of the projects I have in the pipeline will be an OS X application. The market for this app supports pricing of several hundred dollars; in fact, $299 is considered a bargain. Will this app ever be ported to iOS? Not until Apple reduces its cut1.

Seriously Apple? I sell a $299 iOS app and you take 30%? There’s no way to justify that other than “it’s our app store and we’ll do whatever the hell we want.” Which, while that obviously is a successful business model for Apple, doesn’t do so much for my bottom line.

Granted, this reluctance is psychological: 30% of any amount is still… 30%. But psychologically, 30% of $1.99 is one thing while 30% of some price north of $299 is an entirely different matter.

Here’s a thought: Apple switches to a tiered model for their cut. For example:

Tier Level Apple’s cut
Tier 1 – Tier 50 30%
Tier 51 – Tier 72 25%
Tier 73 – Tier 78 20%
Tier 79 – Tier 80 15%
Tier 81 – Tier 82 10%
Tier 83 and up 5%

Maybe this scheme would help to reverse the downward pricing trend? Maybe not, since the change wouldn’t occur until tier 51 which would be a huge jump for a lot of apps. But at least it would be some incentive to raise prices. It would certainly provide an incentive for more productivity apps, maybe engineering and science apps too.

I don’t think that this scheme would cut into Apple’s profits too much since the vast majority of apps (i.e. games) are probably in the first few tiers, certainly not above tier 502.

Will Apple do this? Developers have zero pull with Apple barring a 100% boycott (which will never happen). We might see some change if Samsung/Android start eating Apple’s lunch, but:

  • That’s not going to happen in the immediate future
  • If it does we’ll have other worries

And frankly I don’t want Apple to suffer, I honestly don’t wish them ill. I love developing for OS X and iOS: I can’t stand all the Visual shit I have to put up with and if it wasn’t for Parallels Desktop, gah! I would like Apple to change though.

Interesting note: while doing research for this post, I ran across this from 2008: “The consensus seems to be that prices are too low, that people expect cheap apps, and that they won’t buy more expensive iPhone apps.” My, how things have changed… not.

 

(1) The OS X app will probably also have a plugin API, which is another reason that an iOS version is DOA. But let’s focus on one Sisyphean task at a time.

(2) I can not find any public data to support this statement. If anyone reading this knows of some, I’d love to see it.

Usability Testing


This evening at our local iOS Meetup I had an opportunity to present my upcoming app to unsuspecting users.

How it worked was, after introductions, people who had an app that they wanted to submit raised their hand and we all stood together. Everyone else just grouped up in twos or threes and away we went.

Everyone in our group of four introduced themselves, then I gave a very brief introduction to my new app. The idea was to provide the bare minimum necessary for the user to start using the app.

After that, I started the app on my iPhone and then handed it over to the first user. I can’t tell you how humbling and yet how helpful it is to have someone with new eyes use your app for the very first time. I thought I was 99% done but after tonight… Well, I have a page of notes that I still need to review but there’s definitely room for improvement.

The first-run experience really does seem to make a difference. The very first thing the user did was not what I expected a user to do, so I may need some sort of first-run popup or overlay.

They did have some good things to say about the app though, so I know I’m on the right track. But it can be difficult look at your own app objectively. A few other tricks that I’ve tried:

  • Start using the app or its prototype first thing in the morning
  • Every day, try to find something that sucks about your app

All in all, if you ever have a chance to get some new user experience, it’s worth it.

houseCat Home Inventory half-price sale


Starting April 10 2014 and running through April 15 2014 houseCat Home Inventory will be on sale for half-off.

Since April 15th has special financial meaning for most of us, this is a good time to review your assets. houseCat Home Inventory makes this easy for you:

  • Simple data entry
  • Unlimited photos of each item
  • Inventory report

So after you put the stamp on your return (or hit the submit button) head on over to the iTunes store and download houseCat Home Inventory.