A Quick Look At AppCode 2.0

JetBrains recently released version 2.0 of their fantastic Objective-C IDE, AppCode. If you aren’t using it, you should go grab a copy – you won’t regret it. Let’s have a quick look at some of the cool new stuff, and how it compares to AppCode 1.x as well as Xcode.

First Launch

Let’s get to know AppCode! It’s a little bit slow to launch, but Xcode itself is no speed demon here, so it’s hard to fault AppCode too much.

AppCode

Unfortunately, opening a project for the first time still takes a while, thanks to the index building process.

Loading Project

Fortunately, the index building process only seems to happen once per project. Subsequent opens only take a few seconds of ‘Reading Index’. Additionally, there’s no longer a long delay when switching between configurations (iPhone simulator to iOS Device, for example). Thanks, JetBrains! That was a pretty big annoyance.

Look And Feel

AppCode looks a bit different than your typical Mac app. This is understandable, as it’s built on JetBrains’ cross-platform IDE framework – the same Java-based framework that powers products like IntelliJ IDEA and RubyMine.

AppCode

Version 2.0 adds an attractive new dark theme. It’s easy on the eyes, but it’s even more of a contrast from the rest of your system.

AppCode Dark

Keyboard Shortcuts

One of the best things about AppCode is it’s keyboard shortcut support. It includes a built-in Visual Studio keybinding scheme. If you are a developer coming from the Windows world, a nearly-complete set of Visual Studio keybindings is almost worth the price of admission by itself.

AppCode Keybindings

In addition, AppCode supports chorded hotkeys – hotkeys with multiple steps. Instead of having to use hand-contorting shortcuts like Cmd-Shift-Option-Space-R-7, you can use much nicer multi-step hotkeys like Ctrl-R, Ctrl-V to launch the Extract Variable refactoring.

You also get a few other niceties like proper (from a Visual Studio perspective) Ctrl-Tab document switching.

Unit Testing

When you run unit tests in Xcode (and by run unit tests, I mean run all the unit tests in your project, because that’s about all Xcode lets you do by default), an instance of the iOS Simulator gets launched, and your tests are run inside of it. Want to run something other than all the tests in your project? You can either create separate targets for each set of tests you want to run, or find a third party test runner.

When you run unit tests (or a single test, or a file’s worth of tests – it’s nice to have options!) in AppCode, the simulator isn’t used at all. Whatever AppCode is doing, it’s doing it a whole lot more efficiently than Xcode.

Refactoring

Here’s a quick look at some of the refactorings offered by Xcode.

Xcode Refactorings

… and here’s what AppCode has to offer. Quite a difference. I won’t go into the details of all the different refactorings here, but suffice it to say, if you want to do any serious refactoring you should be using AppCode.

AppCode Refactorings

What’s Missing?

In general, AppCode 2.0 is a fantastic IDE. However, there are a couple of important functionality gaps to be aware of.

AppCode does not include a UI designer or storyboard editor. If you try to open up a storyboard in AppCode, it will be launched in Xcode instead. Likewise, AppCode does not include a Core Data model editor, and opening an xcdatamodel will also launch it in Xcode.

AppCode also doesn’t have the ability to submit apps to the App Store. Given the secure, proprietary nature of the App Store submission process, I’m not holding my breath for this feature to appear anytime soon.

On the bright side, the integration between the two IDEs is fairly seamless, and changes made in Xcode are picked up right away in AppCode. I look forward to the day that I no longer have to launch Xcode at all (aside from app submission), but until then, the AppCode/Xcode combo works pretty well.

In Summary

AppCode 2.0 is a great update to an already great product. If you aren’t already using it, you should definitely give it a shot. The raw editing, navigation, and refactoring capabilities are almost guaranteed to increase your productivity, especially if you aren’t a heavy user of storyboards or Core Data.

I honestly wish I had started using AppCode a long time ago; I would probably have a few more apps in the App Store by now. It’s a particularly fantastic tool for UI-less libraries like ios-queryable.

As you can tell, I’m a huge fan of AppCode. But what do you think? Are you more productive in Xcode?

Announcing Surveylitics.com – Create Surveys via Email

Some of you may have noticed that the flow of posts (and apps) has slowed down a bit. That’s because, among other things, I’ve been busy working on a little side project.

I am extremely happy to announce that that side project is now ready for public consumption, so go check it out at http://surveylitics.com!

surveylitics

Surveylitics is a SaaS app for creating online surveys. It’s main selling point is the ability to create surveys via email. Feel free to try it out and send along your thoughts – feedback is always appreciated.

Now that the Surveylitics launch is out of the way, I’ll hopefully be able to spend a bit more time on the iOS side of things. I’ve already got a nifty new app in the works, and a few other ideas in the pipeline.

Nested push animation can result in corrupted navigation bar

While updating one of my apps a while back, I suddenly started receiving a bizzare error message:

nested push animation can result in corrupted navigation bar

Like most iOS error messages, this one doesn’t really tell you anything about what the problem is or how to fix it. Nested push animation? Huh? Am I somehow calling push from within a call to push? Does ‘can result in’ really mean ‘results in’? Why should I care?

It turns out that the problem was quite simple, and was indeed my own fault. I had a segue hooked up in my storyboard… but I happened to have added some code that was manually calling pushViewController. Removing the old segue from the storyboard solved the problem.

Whoops!

A git workflow for the app store submission process

When you submit an app to the app store for review, what do you do?

Do you simply stop development on the app until the review comes back? Do you keep working on new features? If your app is denied, do you try to resubmit it with the new features you added since the first submission? Do you try to undo everything you did, fix the issues found in the review, and resubmit? Do you switch over to another app?

The app store review process causes some interesting workflow challenges, but git makes them easy to deal with.

Let’s assume that you’re already using Git and Dropbox (or some other DVCS such as mercurial, and some other form of backup or a networked repository). If you aren’t, you should be, so stop reading this article and go read this one instead.

Let’s also assume that you are familiar with basic DVCS concepts such as branching, merging, and tagging. If you aren’t, the git book is a great place to learn.

So, we are ready to start working on some cool new features. We’ll start by creating a branch for our next version – in this case, version 1.3.

Martys-Mac:WhichEpisode marty$ git checkout -b 1.3
M	Which Episode.xcodeproj/project.xcworkspace/xcuserdata/marty.xcuserdatad/UserInterfaceState.xcuserstate
Switched to a new branch '1.3'

Now we’re ready to make our changes. We’ll fix a few bugs, add some features, tweak some views, and so on. This might take a few commits – that’s totally fine.

...make changes...
git commit -am ...

...make changes...
git commit -am ...

...make changes...
git commit -am ...

Ok, we’re now done version 1.3, and we’ve uploaded the binary to the app store for review. Time to end our work on the 1.3 branch by merging it back in to master, and then pushing our changes to our repo in DropBox. You can also push to your remote repo for safekeeping at any point during development of 1.3, of course.

Martys-Mac:WhichEpisode marty$ git checkout master
Switched to branch 'master'
Martys-Mac:WhichEpisode marty$ git merge 1.3
Updating 41988bd..90adff4
Fast-forward
 Default-Portrait@2x~ipad.png                       | Bin 0 -> 18121 bytes
 Default-Portrait~ipad.png                          | Bin 0 -> 5949 bytes

Martys-Mac:WhichEpisode marty$ git push
Total 0 (delta 0), reused 0 (delta 0)
To /Users/marty/Dropbox/Projects/WhichEpisode.git/
   41988bd..90adff4  master -> master

At this point, the branch for 1.3 is still there, but we won’t need to touch it again unless something goes wrong with our submission. However, we are ready to work on our next release, 1.4, so let’s create another branch for it:

Martys-Mac:WhichEpisode marty$ git checkout -b 1.4
Switched to a new branch '1.4'

You can now start working on all the cool new features for your next release.
If 1.3 gets rejected, and you need to apply a fix to it, just switch to the 1.3 branch, make the change, and commit it.

Martys-Mac:WhichEpisode marty$ git checkout 1.3
Switched to branch '1.3'

...fix bug...
git commit -am ....

Re-submit the binary, then switch back to the 1.4 branch and merge in the change, to make sure it stays up to date with any important fixes.

Martys-Mac:WhichEpisode marty$ git checkout 1.4
Switched to branch '1.4'
Martys-Mac:WhichEpisode marty$ git merge 1.3
Updating 90adff4..3152f6d
Fast-forward
 0 files changed
 create mode 100644 test.txt

Astute readers may notice that at this point, we have a change in the 1.3 branch that’s not in master. I can live with that, because I know the change will find its way to master once the 1.4 branch is merged, but if you are really worried you can always merge 1.3 to master again.

Martys-Mac:WhichEpisode marty$ git checkout master
Switched to branch 'master'
Martys-Mac:WhichEpisode marty$ git merge 1.3
Updating 90adff4..3152f6d
Fast-forward
 0 files changed
 create mode 100644 test.txt

So, that’s pretty much how I use git to work with the app store release process. It lets me submit releases to the app store for review, and then continue development in another branch, without worrying about what to do if my app gets rejected.

This has been working quite well for me, but I am curious as to what everyone else does. Thoughts? Ideas? Ways to improve the process? Do something completely different? Use git-flow? I would love to hear your stories!

2012 In Review: A Year Of iOS Apps And Blogging

Now that it’s 2013, I thought it would be a good time to look back at the past year. It was my first year of blogging and iOS app development, and it was full of successes, failures, and surprises.

The Goals

A year ago, I came up with a number of goals I wanted to achieve for the year. Time to see how I did!

  • Sign up for the iOS Developer Program
    Success!
  • Release my first app to the app store by the end of January
    Success! Well, technically I was slightly late, but close enough!
  • Release some open-source Objective-C code
    Success! I have released the virtually unnoticed ReallyRandom class for grabbing truly random numbers from http://random.org, and the reasonably popular ios-queryable, which makes writing Core Data queries far easier.
  • Start answering Objective-C or iOS questions on Stack Overflow
    Success – although I would’ve liked to have answered a few more.
  • Blog at least twice per week
    Failed. It looks like I am averaging about 1 post per week.
  • Come up with 10 legitimate ideas for App Store apps
    Failed. I am currently at 9 ideas.
  • Implement and release one of those 10 ideas every month or so
    Failed. I currently have 8 apps in the app store, with another one inches away from being submitted for review.

The Apps

As mentioned above, I currently have 8 apps in the App Store, and another one almost out the door.

My most successful apps have been Which Episode? and 20 Rep Squats. Which Episode? has sold the highest number of copies, and 20 Rep Squats has generated the most revenue (despite being a niche app for an incredibly small niche) thanks to it’s $2.99 price tag.

My least successful or most disappointing app has been Photo Todo. Despite being what I think is a nifty take on the typical todo list app, it has sold an amazingly low number of copies.

I think that my biggest weaknesses on the app side of things are a lack of marketing and a lack of UI design skills. Combined, these two things make it harder for my apps to stand out from the crowd.

The Website

Traffic has been steadily increasing every month (aside from a minor hiccup at Christmas), and I am now averaging roughly 250 visits per day. All website-related metrics are trending upwards, as this chart shows.

2012-stats

Looking Ahead…

Here are my goals for 2013.

  • Release at least 8 more apps
  • Double my average monthly website traffic
  • Double my average monthly app revenue
  • Step up my marketing efforts to increase sales of existing apps
  • Try to blog a bit more often
  • Keep better stats on downloads and sales (since the Apple-provided tools are woefully inept, and using third party app analytics services violates Apple’s developer agreement)

So, how did you do in 2012? What are your goals for next year?