Awesome LLDB Trick

Ever get tired of trying to inspect CGRect values in LLDB?

(lldb) po self.view.bounds
error: property 'bounds' not found on object of type 'UIView *'
error: 1 errors parsing expression

I know, so annoying, right? Fortunately Craig Hockenberry has found a great trick in Xcode to make inspecting UIKit structures easier.

(lldb) expr @import UIKit
(lldb) po self.view.bounds
(origin = (x = 0, y = 0), size = (width = 375, height = 667))
(origin = (x = 0, y = 0), size = (width = 375, height = 667))

Read his article for all the details.

CocoaPods > Git Submodules

I must take a moment to recant some comments I made over a year ago about CocoaPods in a post about OCMock.  The first time I came across CocoaPods I thought it was pretty awesome, but then reality set in.  I had problems getting my project configured.  It would sometimes crash with cryptic errors (and still does if you have syntax issues).  I had trouble getting it to work with our continuous integration system.  Then a developer I have much respect for told me to just use Git submodules–it does what CocoaPods tries to do the “right way” I was informed.

Fast forward a year and I have changed my tune.  Git submodules is a reasonable solution to the problem of integrating other projects–but that’s not the primary problem that CocoaPods solves.  The real power of CocoaPods is having a searchable repository of open source frameworks at your fingertips.  In addition, with Git submodules there is usually a messy bit of configuration to do in order to get the framework integrated–and if you decide you don’t want to use it, additionally messy work to remove it.

CocoaPods makes it simple to find and include thousands of open source frameworks into your project.  It does the heavy lifting of dealing with dependencies and integrating into your project.  It works with Xcode’s Bots and Jenkins.  You can even configure it to use a private repository which contains your own frameworks that are not to be distributed to the public.

What’s even cooler? It makes it drop-dead simple to create and distribute a framework for iOS or Mac.

The only thing you need to do is evaluate the quality of the code you’re using.  There’s a lot of stuff out there and not all of it is great.  Buyer beware (the linked article is about Ruby Gems, but applies to all open source code).

 

I <3 Xcode 5 and AppleDocs

If you are an Objective-C developer, rejoice!  You can now have AppleDoc-style documents built right in to your project with Xcode 5!  All you need to do is add special comments in your headers and Xcode will automagically suck those comments right into its docs!

For example, if I format my function declaration like so:

/**
 A cool method to do some nifty stuff!
 @param foo a useful parameter
 @param bar another useful parameter
 @return the result of mashing foo and bar together
*/
- (id)niftyMethodWithFoo: (Foo *) foo andBar: (Bar *) bar;

Then when I option-click on that method name from anywhere in my source code I get a quick view of the help:

quickdocs

Our friends at NSHipster have a great article on how to format your comments to generate awesome AppleDocs, so I won’t bore you with that here.  There is a lot more you can do that just document functions, so I encourage you to read all about it and start adding AppleDoc comments to your code!

Treat Compiler Warnings as Errors

I’m a big believer in the compiler option to treat warnings as errors.  Compiler warnings are our first line of defense against inadvertent screw-ups in our code.  It means you’re probably doing something wrong, or that goes against recommended practices.  ie: “Sure, technically you can do this but it might result in unexpected behavior, memory leaks or other problems if you’re not careful.”  So turn on “warnings as errors” to prevent accidents.

The warning may just be a “head’s up”–like an unused variable warning.  Maybe you forgot to use it somewhere in your code.  Maybe you did some refactoring and no longer needed it.  In this case just fix your code.

There may be cases where you understand better than the compiler what you’re trying to do, and you do want to exploit a capability of the compiler to do something you think is really clever.  (We programmers do like to be clever, don’t we?)   Chances are you’re wrong though and you should probably find a different way.  The next version of the compiler might be more strict–or worse, might behave in a different fashion in this case and cause a change in your code’s behavior, often for the worse.  If you want maintainable code, treat the compiler’s warnings seriously.

However, if you are absolutely certain you know what you need to do and there’s no alternate way to accomplish your code, then don’t turn off the “warnings as errors” build setting, and don’t turn off the warning globally.  Just turn it off for your one risky piece of code and document it.  eg:

#pragma clang diagnostic push
// Turn off the "undeclared selector" warning because we're
// checking to make sure that the target responds to that 
// selector before trying to perform it.
#pragma clang diagnostic ignored "-Wno-undeclared-selector"

if ([target respondsToSelector:@selector(doSomethingCool)]) {
    [target performSelector:@selector(doSomethingCool)];
}

#pragma clang diagnostic pop

Notice that while I’m exploiting this ambiguous compiler behavior I’m also being careful to avoid misusing it!

Finally, there may be a situation where third party code has some warnings. One option would be to fix the warnings and submit a pull request to the owner. This might not always be feasible though (or you simply don’t have time to fix someone else’s code). You can also turn the offending warning(s) off on a per-file basis. This is nice because the configuration change goes into your project settings, not the third party source. This could help avoid merge conflicts or having to re-apply your changes when updating the third party source to a newer version.

In Xcode select your target and go to the “build phases” tab. Search for the name of the offending file and double-click on the “compiler flags” field (to the right of the file name). Enter the flag to disable the offending warning, eg: -Wno-undeclared-selector.

Disabling a compiler warning on a per-file bases.

Disabling a compiler warning on a per-file bases.

Lastly, it’s not always easy to know what the name of the compiler flag is for the warning you disable. Your compiler should have documentation about this, as do the Internets. Try searching for the error message and “disable”. It’s very likely someone else has had this problem and already found the compiler flag for you. And if you don’t get any results it may be a sign that you’re doing something inadvisable.

xcode-select is your friend

If you’re an early adopter using Xcode 5 developer preview but need to use the Xcode 4 command line toolchain, xcode-select is your friend.  Use this command to switch the toolchain back to your Xcode 4 install:

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

WWDC 2013 Top Ten

I was one of the lucky ones who attended WWDC 2013 this year.  (Pro tip: copy your Apple ID password to the clipboard so you can sign in very quickly and order your ticket.)  As always there is a lot of information about new products, OS updates, innovations and APIs.  Below is a round up of some of the most important developments in iOS development from Apple.

  1. Bots.  Apple has finally made continuous integration a breeze.  In the past I have used Jenkins to set up a continuous integration system–but it was a lot of work which required a great deal of manual configuration.  With XCode 5 and OS X Server you can use Bots to easily build a continuous integration system and even have a “scoreboard” which shows stats on the state of your build.
  2. XCTest.  Apple has upgraded their unit test framework and made testing your code easier than ever.
  3. XCode 5.  Built on ARC the new XCode should take up less memory and run faster than before.  They’ve streamlined the interface and included some new built-in profiling tools to help catch memory leaks and performance issues while you’re developing.  Instruments is still there with its rich tools, but now XCode has an early warning system while you’re debugging.
  4. New Background Features.  Background transfer means that the OS will download (or upload) your data for you while your app is in the background.  This is huge for data-intensive apps!  Read up on NSURLSession to find out more.  Remote Notification allows you to send a push notification to your app and wake it up to perform a task.  Background Fetch tells the OS to periodically wake your app and give it a chance to update its data, so that whenever the user brings it to the foreground it has up-to-date information to present to the user.
  5. UIKit Dynamics.  iOS has always had rich animation support, but now it’s easier than ever to create dynamic and engaging interactions in your app.  And for gamers check out SpriteKit (Cocos2D watch out). It even has a particle effects editor!
  6. Inter-App Audio.  CoreAudio has some cool new features that allow audio-enabled apps to share audio between each other.  This is very similar to AudioBus–but works directly with the OS and doesn’t require a third party library (which makes me wonder what’s going to happen to the innovative AudioBus app and framework).
  7. Collection View Layout Transitions.  There is some really cool stuff you can do in iOS 7 with collection views and layout transitions.  Check out the iOS 7 photo app or calendar for examples!  This new feature will let you seamlessly transition from one layout to another within the same collection view.  Instead of pushing a new view onto a navigation controller the existing collection view can animate to a new layout and present a detail view within a larger context–giving users a better sense of place.
  8. Custom Navigation Transitions.  Have a great idea for a navigation controller transition?  Now you can build it.  There are a lot of details here, and it looks pretty complicated, but if you follow the rules it looks like it will work pretty smoothly and save you the trouble of building your own navigation UI.
  9. State Restoration.  This has existed since iOS 6 but there are some new features that make it more powerful and easier than ever to let iOS restore your app to its former state when it is re-launched.  Combined with snapshots this makes your app seem like its process never got killed.
  10. Game Controller Support. This looks awesome for the gaming crowd. Watch out console makers! Did I mention SpriteKit makes it easy to build awesome 2D games?

PS: be sure to check out the WWDC 2013 videos online!

 

Fix Your Xcode Project Index

I’m a fan of the new Xcode 4. However, sometimes the editor seems to “forget” my project’s symbols–preventing auto-completion and symbol lookup (including the quick-open feature, which I use a lot). Here’s a useful solution if you find yourself in this situation. Select your project in the Xcode Organizer and delete its “derived data.” It’s annoying but does the trick.