Tips (25)


Automating iOS + Watchkit build numbers, with Git, for iTunes Connect

This wasn’t especially difficult, but it was a little tedious to track down.

I’ve relied on a handy little build phase script (I wish I remember where I found it) for automating build numbers from git commits for iOS apps since Apple gave us access to TestFlight via iTunes Connect. This same script didn’t work for my Apple Watch app as I anticipated, so it took a little bit to work out the kinks for AppStore submission.

It boils down to this

  1. Set the build number = the number of git commits on the branch.
  2. Change the Info.plist build numbers for the iOS app target, the Watch App target, and the Watch Extension target. This is done in a script build phase before the “Copy Bundle Resources” phase.
  3. Reset the Info.plist build numbers after all the build phases have run (another script build phase)

See the gist I posted for the complete script. Make sure to check the directory paths for the correct app name.

Happy building!




Unit Testing CoreData Tip: The Singleton

It’s been a while since I was deep into CoreData, but here I am again. And this time, I’m writing proper unit tests.

Things were going pretty well – I had about 50 test cases with a few related asserts in each – until I started messing with saving, and fetching tests. I ran into some odd behavior where sometimes a particular test would pass, other times fail with different results in one assertion. All I was doing was creating a managed object, setting a relationship, saving, and reading back to check for proper order. Pretty trivial stuff.

I looked deeper.

If I ran just that one test case by itself, it would always pass. If I ran “All Tests”, it would always fail. Sometimes I would get several fetched objects when only one was expected. Sometimes those would be in different orders.

As I dug deeper, I attempted to reset my context on each test case

No luck.

To this point, my managedObjectContext has been a singleton – to follow the pattern of the rest of the appellation. I had a hunch the problem might be there – especially if multiple tests are running (concurrently, even?).

I tried creating a separate for-testing-only manager that creates a new stack each time so I could hopefully avoid these apparent concurrency issues.

That seems to do the trick, though I would have preferred sticking with the singleton. Don’t use CoreData stack singletons. Turns out @orta suggests the same [tweet] [blog post].




iOS TDD (Test Driven Development) – Convincing Myself

By no means is TDD (Test Driven Development) a new concept; I’ve known about it for years. I had sone some unit testing on projects prior, they became an integral part of routine when I started consulting for HP’s Software R&D lab. We’ve been very good about testing out all the important logic of the application, save automated functional testing of the UI (more on that in another post).

This post is really about TDD, not convincing you to unit test your code (something you should be doing). Actually, I’m not a diehard TDD fanatic. Rather I use principles of testing first before writing application logic. I don’t want to get stuck the pedantics of true TDD development.

My journey, if you will, started as I had a turning point in two projects for Pivotal Action that convinced me. The first project involved a bit of interplay between iBeacons (CLBeacon) and networking, which would be impractical to manually test with physical hardware. The second project involves a lot of transformations being applied to objects, and some networking. In both cases, relying on rather extensive unit tests could ensure I wasn’t breaking functionality with new features.

My general approach involves a few simple practices:

  1. Create a mock data set for input. I often use JSON files because it’s easily readable, and you can use the same data on multiple tests if you need. Also helpful if you’re testing mock network response data
  2. Create a test data set, or scenario. First pass, go with the “golden path” – the best case scenario
  3. Determine what your desired outcomes are in a best-case scenario
  4. Create separate test cases for each kind of data you may have to deal with. Again – start with the best case scenario
  5. Write some logic code to either transform data, or respond to it
  6. Go back to step 1 and create a new set of data representing one type of problem, or family of very similar problems. This could be malformed data, error codes from API services, etc. as well as common problems : out-of-bounds errors, off by one, nil, and others.
  7. Keep repeating 2-5 until you’ve exhausted just about every scenario you can reasonably think of.

This may seem boring and repetitive, but I assure you that thoroughly testing your logic will uncover holes in your implementation before you even start writing application and UI code. You’re also more likely to survive refactoring unscathed if you have extensive unit tests covering the changing code. I recently benefitted from this when I converted a set of model classes over to a CoreData stack. It wasn’t a perfect 1:1 refactor, but it uncovered some places where I had to adapt my expectations and logic so that the transformations would be the same in the end.

I’m not perfect at this, but I can say that doing unit testing before really getting into the guts of an application has saved me a lot of work farther down the road. I also have more confidence that changes I make aren’t breaking existing functionality. Give it a shot.




Focus Follow Mouse and other *nix wonders

Back in the days at the UCSD Center for fMRI, I had the opportunity to get my hands dirty with a few types of *nix systems that most people have never heard of, much less use. My boss was also pretty keen on very specific configurations that he insisted his employees put on their computers for those infrequent times he’d be on our workstations. For the record, they were:

  • Always use Emacs
  • Make sure that key to the left of the “A” key was your control key, map it to control if it wasn’t already
  • Make sure focus follows mouse set to enabled.
These are no big deal on various *nix systems, but to most Mac people, completely novel ideas

Caps Lock to Ctrl

Briefly, that control key thing. I hated it at first. Then I started using Emacs quite a bit and it made sense. It much better on your poor little pinky finger to press down without having to contort your hand. Old Solaris systems actually made that the hardware control key. Any other keyboard has to be remapped via software so “caps lock” wasn’t really caps lock. I highly recommend it, but people are soooo confused when they’re using my machine and the caps lock doesn’t work. Or control doesn’t work and makes all their text in capitals.

Focus Follows Mouse

I don’t know why I forget to do this one. The idea is that window focus (the act of becoming active) can be controlled by simply moving your mouse over the window rather than having to physically click on it and bring the window to the foreground. FFM is particularly handy because the window isn’t brought to the foreground, but is still takes input from the keyboard. I use this most often when working with the terminal – where often I only care most about the last several lines of output, and not all the clutter of text and OS UI above it. It leaves the main window that might be referencing right where it is.

On your Mac, open Terminal, and do this:

Quit terminal. Re-open, and open a second terminal window (not tab). Hover your mouse over one of them and start typing. Now, hover your mouse over the other one and type. See what happens? If everything worked properly, the typing occurs in the window your mouse is hovered over. The only caveat is that it acts a little funny if the terminal is in the background to another app, but it still works. I found that sometimes you have to hover out & over another app then back to the other term window. Not a huge deal, I guess. Try it out. If you don’t like it, change the above command from … YES to … NO

It’s a time saver and convenience – especially useful on constrained displays. You might just fall in love. Now if only the whole OS would let me do that.

 




Quiet NSLog() in Release Builds

On the heels of the previous post, here’s a little snippit I picked up from Marek Bell to quiet NSLog() output in release builds.

Add this to your {MyApp}-prefix.pch file

#ifndef __OPTIMIZE__
#    define NSLog(…) NSLog(__VA_ARGS__)
#else
#    define NSLog(…) {}
#endif

The reasoning behind using __OPTIMIZE__ is that it’s set only on release builds of your app, not in debug versions. It’s very simple and allows you to use NSLog() instead of having to come up with your own version.




Quiet the Console – PhoneGap / iOS

I have a confession – I’m a console logging junkie. I just like to see what’s going on. While that may be great for development, at some point you’ll have to quiet the logging down for production. Really – doing enough logging will slow everything down each time you’ve inserted a console.log() into your code.

Silencing the output to XCode’s debugging console wasn’t immediately obvious. Overriding console.log() in JS by setting it to an empty function worked in the browser for development, but as soon as I loaded the app onto the actual simulator, we were back to square one. Enter the PhoneGap DebugConsole prototype. Override it.

Insert this anywhere after your phonegap.js file loads. It’ll keep things quiet as long as DEBUG = true…

There you have it




If your site goes down, does it make a noise?

I don’t go to my brochure site very often. It’s there for the curious client who needs the reassurance that I know what I’m doing. Considering I haven’t made any significant changes in quite some time, I had no reason to go back, but apparently I should have. At some point my .htaccess file went missing, which was pretty good to foil even the best attempts to view pages other than the home page. I have two questions: 1) How long were all these links broken – that I didn’t even notice it, and 2) Nobody said anything – why?

Regardless, everything is fixed now. Typing my name into Google or Bing will fetch either this blog or the brochure site in the top 2-3 positions. If you haven’t been yet, check out mistercameron.com .

Cue deriding comments.




Cocoa Zombies – NSZombie

Found this great little debugging tip over at MarkJ.net. The short of it: You can use NSZombie tracking to debug memory crashes in your code. Great find – this whole time I was kinda under the impression that there was a lot of educated guessing involved based on where your fingers last touched code. I’m so naïve.




Compiling PHP5.3.x on Snow Leopard

I like to wait quite a while before upgrading Mac OS X to the newest release because, for me, it often requires quite a bit of work. I had hopes that Snow Leopard would be different because Apple finally installed current versions of the whole LAMP stack, but I wanted to wait regardless… just in case.

Why the wait?

I do dev work that require custom libraries in my PHP installation – vanilla PHP from Apple doesn’t have what I need. To do that I’ve relied pretty heavily on the Fink package manager. Too many times I’ve upgraded to the new OS and some of the libraries haven’t yet been updated to work properly on the new system. Usually after a couple months either the libraries get fixed or Google will give me enough results and clues that I can fix the issue myself.

First things first

I went ahead and compiled  Apache from scratch. It’s easy enough and you’ll need the 64bit support for PHP. MySQL was much easier – download the intel x86_64 installer for Mac OS X 10.5 (yes, even for Snow Leopard). Side note – MySQL finally got around to recompiling the System Prefs Pane to 64bit.

Installing Fink

I’ll save you some time. First, compile fink from source. When you set up the app, do the 64bit-only packages (you’ll know – it’ll prompt you to pick 32bit or 64bit). I tried the 64bit and PHP wouldn’t install. You can always do a separate mixed architecture install later (see here for details on mixed fink arch installs).

Compiling PHP (with GD)

I need GD. This tutorial did the trick – once I had figured out the 64bit fink issue(s). Follow it and the companion standard PHP / Snow Leopard compile tutorial, linked in that article. Take a look at my compile flags, if you’re interested:
export MACOSX_DEPLOYMENT_TARGET=10.6
CFLAGS="-arch x86_64"
CXXFLAGS="-arch x86_64"


./configure --prefix=/Library/PHP5
--mandir=/usr/share/man
--infodir=/usr/share/info
--sysconfdir=/etc
--with-config-file-path=/etc/php.ini
--with-zlib
--with-zlib-dir=/usr
--with-openssl
--enable-zip
--enable-exif
--enable-ftp
--enable-mbstring
--enable-mbregex
--enable-soap
--enable-sockets
--with-curl
--with-curlwrappers
--disable-cgi
--with-iconv=/sw
--with-gd
--with-jpeg-dir=/usr/local/lib
--with-png-dir=/usr/X11R6
--with-freetype-dir=/usr/X11R6
--with-xpm-dir=/usr/X11R6
--with-apxs2=/Library/Apache2/bin/apxs
--with-mysql=/usr/local/mysql
--with-mysqli=/usr/local/mysql/bin/mysql_config
--with-pdo-mysql=/usr/local/mysql

Two things: First, my PHP is installed into /Library/PHP5/. Second, my Apache is located at /Library/Apache2/. Nothin to it. Too bad it took me all day to figure this out. At least now I can move on with my life!




Installing PEAR Libraries Locally

[I started this post quite a while ago and forgot about it. Here it is finished. Hopefully you find something useful here]

I’ve had a few projects already where I could really use some PEAR libraries but not sufficient enough access to the server so I could install them in the system-wide PEAR include directory. I went searching for an easy to manage way to package specific PEAR libs along with apps I was building and installing for clients – something that would work without access to system-wide PHP/PEAR setup, and even in rare cases where I couldn’t write outside the document root.

First place to at least read through is the documentation. I’m going to assume you already know the basics of PEAR.

This summary will discuss the FTP method, as it seems applicable to more situations. For me – I keep my sites under version control so I need to be able to perform a local install that I can commit to the repository and either export or update on my various server environments.

Tools:
* Terminal or command-line (CLI)
* CLI version of PHP
* CLI version of PEAR

Steps (code follows)

  1. Create a directory where you want the PEAR libs installed. Note: PEAR will create a directory named pear in the location you specify.
  2. CD into that directory.
  3. Create your config file for your local environment (probably won’t be needed on external servers unless you plan on installing from there, in which case you should create a separate config file for each site).
  4. Install and update packages.
  5. Update your app’s include paths.

The Code:

  1. Create your config file in the PEAR directory from step 1, above. Absolute paths, absolutely!

    The first path is the location where you want the files. The second path is the location where the pearrc file is located. I usually put the PEAR files in an includes directory within the site’s document root, just in case a host or client I’m dealing with doesn’t have write access in higher-level directories. It’s best to keep the pearrc file outside of the webroot, or deny access to the file via Apache’s Allow/Deny directives.
  2. To run PEAR commands on your local install, you will need to use the following format

    (otherwise you’re likely working on system-wide changes – doesn’t help you when it’s time to deploy to the server). An example,
    %> pear -c /path/to/setup/pearrc install File_CSV_DataSource
  3. Set your app’s includes path to search in the PEAR directory:

    Change as needed.

That should do it. It’s a basic introduction, but if you already know how to use PEAR, you’re already 95% of the way there.