All posts by Jeremy

IF Tracker: FAQ

Why aren’t more foods included in the IF Tracker?

We are working to add additional foods to the database. However, in order to calculate the IF Rating of a food, we need extremely detailed nutrient data about the food. For example, the formula takes into account the amounts of individual fatty acids such as arachidonic acid or docosahexaenoic acid—not just the amount of saturated or monounsaturated fat. For many commercially available (i.e., processed) foods, the manufacturers do not provide enough nutritional detail to allow us to calculate a rating.  Calculating a rating in the absence of these details could produce inaccurate or misleading ratings. Although we sympathize with your desire for a larger list of foods, we feel that it’s important to provide ratings only when we have enough nutrient data to calculate an accurate rating.

Why can’t I add new foods?

We’d love to include a tool that would allow you to calculate the IF Ratings for foods that are not in the database. However, in order to get an accurate rating, you’d have to enter extremely detailed nutrient data about the food. For example, the formula takes into account the amounts of individual fatty acids such as arachidonic acid or docosahexaenoic acid—not just the amount of saturated or monounsaturated fat.  Because this information is not generally available to consumers we determined that a custom entry tool would be of little use.

What is the IF Rating for baking powder or baking soda?

Baking powder and baking soda are both neutral (0).   The addition of these ingredients does not change the IF Rating of a recipe. Simply calculate your recipes without them.

Is there a way to substitute or create equivalent flours from millet, amaranth, or almonds?

To the extent that the flours are simply ground up grains or nuts, the rating for 1 ounce of flour would be approximately the same as the rating for 1 ounce of the corresponding grain.  For reference, a cup of flour is about 5 ounces.

Why do the IF Ratings in the app differ from “The Inflammation Free Diet”?

Since the book was originally published in 2006, additional research prompted the author, Monica Reinagel, to make some updates to the rating formula, particularly in the way that the glycemic load impacts the ratings.  The result was some minor changes in the IF Ratings for certain fruits, legumes, and dairy products, which are reflected in the ratings on NutritionData.com.

In addition, there have been some dramatic changes in the way salmon are farmed.  The latest data from the USDA indicates that changes in the food given to farmed salmon have resulted in a product that is now comparable to wild salmon in terms of the anti-inflammatory properties.

Unfortunately, the USDA only updated the data for raw salmon, not the cooked versions.  Because the listings on NutritionData.com are automatically generated based on the USDA database, they are only as up-to-date as the underlying data.  In the IF Tracker, Monica Reinagel was able to interpolate more accurate ratings for cooked salmon as well.

While it may be confusing to have multiple sources which don’t all line up, this is a dynamic area of research and the information doesn’t “stand still.”  Unfortunately, it’s not always possible to keep all the published instances perfectly synchronized with the latest information.

In those cases where there are discrepancies between the ratings in the book, NutritionData.com, and/or the IF Tracker app, the ratings used calculated in the IF Tracker represent the latest most up-to-date calculations.  But, with the exception of the dramatic change in farmed salmon, the changes are basically nuances on the original ratings.  Although it may seem that something changing from negative to positive or the reverse is a big deal, it usually represents a minor shift on a large continuum.  Assigning foods individual ratings inevitably encourages people to think of each food as being inflammatory or anti-inflammatory.  But as we hope you’ve learned from the book, it’s the sum of all foods eaten that really matters.

Updated Site

Just a quick note that we’ve updated our website. Sorry for any bookmarks or links that got confused in the process, but the new layout and organization is not only a lot cleaner, but allows for greater flexibility as we move forward.

Adding a TextField to an AlertView

Today, I was looking at how to add password protection to an app.  The basic design was the user could set a password via the options, then when they relaunched the app, would be asked to re-enter the numeric sequence.  If they got it right, the app would proceed as normal otherwise, terminate.

Ultimately, I went with the solution proposed by Jeff LaMarche on his blog.  But, many of the other solutions I found via Google appeared to use private APIs (such as addTextFieldWithValue:) which is a sure fire way to get rejected these days.

If you haven’t read the blog, or even better – his book, they are both great.  The book offers a very easy introduction to the iPhone SDK using practical examples.  It’s a great starting place for developers new to the SDK.

Managing Assets & Viewing Bundle Contents

Managing all of the assets that go into an iPhone app via Xcode can sometimes be tedious.  It seems somewhat counter intuitive to me to have the IDE manage these resources too.  Maybe I’m in the minority, but I’d prefer to just work with source code and NIBs in Xcode and keep track of the “other stuff” on my own.

The other day I was looking around for a solution to remove the non-Interface Builder assets from Xcode, organize these files into folders within my bundle, and remove the tons of Groups or Folder References from the IDE.  Happily, the answer wasn’t too bad.

Xcode Options

When you drag a resource into Xcode, it presents you with a dialog asking how to treat it:

asset_dialog

Starting from the top, the checkbox will copy the assets (and preserve the folder hierarchy, if present) while placing the resources at the root folder of the destination group.  The default radio box is to “Recursively create groups for any added folders” which is generally what you’ll want, especially if you’re using Interface Builder too.  In your bundle, these resources are placed at the “root” meaning to access them in your code, you’ll just need to specify a name.

The other radio option, “Create Folder References…”, creates a folder tree both inside Xcode and in your bundle.  However, the resources cannot be seen by Interface Builder and you’ll need to use a path if you load them at run-time.

Build Phase Copy

If you like the folder hierarchy in your bundle, or just want to move this management largely out of Xcode, it’s pretty easy to do it on your own by adding a new build phase, as shown below.  Right click on your Target and follow the cascading menus.

build_phase

In the build phase, add the following script

PBXCP=${DEVELOPER_DIR}/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp
BASE=${PROJECT_DIR}/assets
DST=${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}
${PBXCP} -exclude .svn ${BASE} "${DST}"

The script calls an iPhone tool to recreate your folder structure inside your build directory before the final bundle is created.  With the script, I can remove any links or asset associations within Xcode except those I want to use in IB.  I maintain a folder “assets” off my product directory where I place any files that I’d like bundled in my app.

Checking Bundle Contents

Perhaps a trick most folks know, but I thought it was worth mentioning, is you can inspect and check the contents of your app bundle by following either navigating there via the Terminal or right clicking the app and selecting “Show Package Contents”.

I had a question about the database format of iGive Blood that shipped in version 1.0 and managed to find an old build from Apple.  For products that you’ve shipped, it’s almost the same.

  1. In iTunes, right click the app and select “Show in Finder”
  2. Copy the IPA file to your desktop
  3. Rename the extension to ZIP
  4. Double click the ZIP to create an uncompressed folder.
  5. Open the Payload folder which has the app.

It’s actually a bit disappointing that it’s so easy to get to the package contents especially as the contents aren’t obscured.  Maybe that’s a subject for another post…

Sometimes It’s the Obvious

Between working on a couple updates for our existing apps, I’ve been working on learning some new stuff with the iPhone SDK.  Sometimes it’s great to just wipe the canvas and start fresh!  So, I’m playing around with which UI* framework elements support custom artwork and creating some custom controls.  It’s fun, especially now that I’ve got some solid footing on the default appearance and behaviors of the common controls.

I tossed together a UITabBar app template and started filling out the custom UIViewControllers.  The code to push the view controller is pretty standard:

   if (myView == nil)
   {
      myView = [[UIViewController alloc] initWithNibName:@"testView" bundle:nil];
   }

   [self.navigationController pushViewController:myView animated:YES];

 

I created a corresponding Objective-C UIViewController class, testView, and associated the class in Interface Builder, including the “view” connection. 

testView 

The test view controller had a couple IBOutlets which I also created in IB and associated too. 

Save all… recompile in Xcode, debug – and Boom!  “NSUnknownException”, reason: “[<UIView 0x47a3e1>  setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key testControl.”

Nothing like a helpful error message, eh?

So – a quick return to Interface Builder where I double check the connections, Class Identity, and assorted properties that might trigger the exception.  Save all… recompile in Xcode, debug, and Boom!  Crashed again. 

Okay… time to get more serious.  Since these were empty classes anyway, I blew them away and started fresh.  Recreated the classes, the controls, the connections, and tried again.  No difference.  Ugh.  I swear I’ve done this before – a lot!

Well, I decided to pull out all of the controls except a UITableView and toss breakpoints throughout the UIViewController class to try to trap and step through exactly where things might be going amiss.  Recompile, debug, and things worked great!  The view appeared, including the table, but none of my breakpoints caught.

This was very odd, as I had breaks in initWithNibName:bundle:, loadView, viewDidLoad, and – just to be thorough – viewWillAppear:.  A little head scratching and I came to the quick conclusion that my custom class, despite being set in Interface Builder, isn’t actually being used.  And, after a few more minutes of triple-checking my settings, I discovered the source of the problem – I’d created a UIViewController instead of a “testView” (see above).  Changing the code fixed the problem – big surprise.

While I overlooked my declaration initially (as perhaps you did too!) – it just goes to show that sometimes it’s the obvious and before nuking work that probably is okay – give a quick inspection all around.

Security Updates, Xcode & Subversion

In addition to my full time job as a developer, I get occasional opportunities to moonlight as a system administrator.  Recently, we updated our Macs to the latest security patch Apple pushed out – and lo, our subversion integration with Xcode broke.  Sigh.

Back when we were initially setting up boxes for development, I very dimly recall there was some “shell magic” via the Terminal that needed to happen to get all the parts working together.  I think this was largely because Xcode preferred to work with an earlier version of subversion, perhaps 1.4.x – and it was no longer readily available at the time.

None the less, it’s easy to forget all the configuration steps in setting up a developer box – especially stuff that takes only a couple hours to figure out a nearly a year ago.  We’re not yet to Snow Leopard, so our tools may be a little dated: Xcode is 3.1.4 and Subversion is 1.5.5.

Symptoms

After the security upgrade, we fired up Xcode and noticed that there were:

  • No modified files in the project.
  • Right clicking a source file showed only “Get Annotations” in the Groups & Files pane.
  • Viewing the SCM | Repositories dialog (from the main menu) gave an error: 180001 unable to connect to the repository.
  • Even more scary was the Terminal message: svn: Expected FS format ‘2’; found format ‘3’

Solutions

Unfortunately, determining the solution wasn’t particularly clear.  Doing some Google searches on the error messages produced limited results.  The initial reaction was that something went wrong with the repository, but it was just working!  Running, “svnadmin verify” against the repository produced the File System format error message which was ominous.

The first thought was that perhaps the security patch affected the PATH variable.  Mac OS X ships with an older version of the subversion binaries and maybe we were picking up the wrong one.  On the Mac, various shell variables including your path are set in the .profile file found in your home directory.  A quick in the Terminal showed that /usr/bin was first in the path and /usr/local/bin (home to our newer svn) was last.  No problem – a quick edit and all was better.  Well… not quite.

Adjusting the path restored subversion from the Terminal and even the svnX app.  But, Xcode still stoutly refused to acknowledge the existence of the repository.  Grrr!  But, a step in the right direction and at least our repository was okay.

The breakthrough was trying to “Get Annotations” on a file.  There was a much more descriptive error – “155021 (Unsupported working copy format) please get a newer Subversion client.”  This jogged something loose in my mind and I dimly recall having to change some of the system libraries to get Xcode working with the newer Subversion.

After another quick search I found two other folks reported the same thing (Paul Solt and Blind Genius).  I’ll restate the solution here, but effectively Xcode is dynamically linking with the older Subversion libraries found in /usr/lib.  To work with newer builds of Subversion, you’ll need to create symbolic links to the newer dynamic libraries as follows:

cd /usr/lib

sudo mkdir svn.orig

sudo mv libap*-1.dylib svn.orig

sudo mv libsvn*-1.dylib svn.orig

sudo mv libap*-1.0.dylib svn.orig

sudo mv libsvn*-1.0.dylib svn.orig

sudo ln –s /opt/subversion/lib/*-1.0.dylib .

sudo ln –s /opt/subversion/lib*-1.dylib .

After adding the symbolic links, restart Xcode and things should be back to normal.

Cautions

One thing worth reverting is the PATH change.  Modifying the search order for executables might be considered a security risk as often 3rd party binaries (particularly shell ones) traditionally reside in /usr/local/bin and you might end up running something unexpected.  Perhaps safer is to create symbolic links to the binaries in /usr/bin, or alternatively command aliases in your .profile to run the correct version.