Checking in CocoaPods files

I’ve gone back and forth on the debate with whether or not we should be checking in the dependencies for a project supplied by CocoaPods.  In the past I felt it was best to only check in the Podfile and maybe the lock file.  I believe I’ve finally made a decision with recent experiences and my development practices with Git.

I’m checking in the whole effing workspace.

Why?

  • Every branch, especially master, should be compilable and archivable up to a point.
    • Caveat 1: Xcode is a piece of shit sometimes and will break things because it can between versions.
    • Caveat 2: Provisioning Profiles.
  • CocoaPods is a well-maintained tool, however, Specs are a crap-shoot.
    • Specs can disappear.
    • Specs can be unofficially maintained.
    • Specs can be wrong.
  • Checking in your Pods directory ensures the best possible snapshot of the pre-binary code.
    • Forcing a pod install every time someone checks out code doesn’t ensure the same state of code is maintained for testing bugs in previous versions.
    • You may decide to drop Pods support and forget how to use it.
    • Wouldn’t it be nice to do diffs on your dependency classes?
  • Xcode Bots doesn’t work well enough yet with CocoaPods for me to want to install Pods every build
    • I’m also not sold on Xcode Bots itself – it’s quite unreliable and likes to smoke my server’s CPU.
    • CocoaPods needs to not be a hinderance – its pretty innocuous when the risky work (installing Pods) is done and checked in.

That sums up my thoughts.  I primarily work on WordPress for iOS which is a heavily forked and contributed to repository.  I don’t think the project could be a success with the amount of branching and pull requests performed if we didn’t check in the Pods directory.

iOS Background Refresh & Force Killing

If you’ve done any work with background refresh (application:didReceiveRemoteNotification:fetchCompletionHandler:) on iOS 7 you know that it can be a pain to debug your code with.  Some things I’ve discovered:

  1. Background refresh will start your app if it’s not running.
  2. If you force-quit an application, it’s not eligible to be started by a push notification.  Restarting the app or rebooting is the only way to again receive background push wakes.
  3. You can’t really debug wake by push other than with logging.
  4. Touching UI code in application:willFinishLaunchingWithOptions: is risky with background push since it fires but didFinishLaunchingWithOptions won’t if it’s immediately backgrounded.  If you’re using UIStateRestoration, make sure you’re limiting UI code in willFinishLaunchingWithOptions to setting up the root view controller.
  5. Don’t arbitrarily reset the badge count when your app is presented – you should really reset the badge count when the notification is viewed/considered no longer relevant.
  6. Update your push service to send “all clear” or zero count badges when things are read via other instances of your app (web, other iOS device, Android too).  Your users will thank you that they’re cleared everywhere.

Take a look at Apple’s documentation on app lifecycle – there is an excellent set of graphics to demonstrate where things hook in.