Automatically Include Open Source Licenses into the Settings Bundle

There’s a good chance your iOS app includes a number of open source frameworks in its codebase, and Loose Leaf is no different. Many of these dependencies’ licenses require that you include a copy of the license in your final build. Some require other attribution or URLs. Even with just a few includes, it can quickly become difficult to manage.

Last week, we talked through how to automate our app’s version numbers, and this post will automate our bundled licenses.

The Goal: Include Licenses in our Settings

This walkthrough will help us create a custom sub-menu in our Settings.bundle to show all of our bundled licenses.

Licenses in Settings

Step 1: Prepare The Settings Bundle

First, we need to define where that section will appear in our settings bundle.

In your Settings bundle, create a new file Acknowledgements.plist:


Since the contents of this file will be auto-generated each time we compile, there’s no reason to add it into your git repo. I suggest adding the path to Acknowledgements.plist into your .gitignore file.

Next,you’ll need to add 2 items to your Root.plist – a Title and a Child Pane:

License Root.plist item

The first item creates the “LICENSE” title item, and the second creates the link to our sub-menu. It references the file “Acknowledgements.plist” to use as the child pane.

Step 2: Add License Files

Next, we need to define the licenses that we’ll be wanting to include in our Settings bundle. For each license, create a separate .license file in your project contents. No need to copy these into your built product, we only need them in our source tree – we’ll be using them to generate the contents of our Acknowledgements.plist file in the next step.

Each license file should be in the following format:

Name of the Licensed Object, eg. "JRSwizzle License" etc

contents of the license here - copy of the MPL or MIT License, etc

Step 3: The Build Script

I’m using the perl script from this Stack Overflow answer, and I’ve saved it as “”. This perl script will be modifying the Acknowledgements.plist file for us.

#!/usr/bin/perl -w

use strict;

my $out = "Settings.bundle/en.lproj/Acknowledgements.strings";
my $plistout =  "Settings.bundle/Acknowledgements.plist";

system("rm -f $out");

open(my $outfh, '>', $out) or die $!;
open(my $plistfh, '>', $plistout) or die $!;

print $plistfh <<'EOD';


for my $i (sort glob("*.license"))
    my $value=`cat $i`;
    $value =~ s/\r//g;
    $value =~ s/\n/\r/g;
    $value =~ s/[\t]+\r/\r/g;
    $value =~ s/\"/\\\"/g;
    my $key=$i;
    $key =~ s/\.license$//;
    my $fullstr = "";
    my $cnt = 1;
    my $keynum = $key;
    for my $str (split /\r\r/, $value)
        if ($cnt == 1){
            print $plistfh "\n";
            print $plistfh "Type\n";
            print $plistfh "PSGroupSpecifier\n";
            print $plistfh "Title\n";
            print $plistfh "$keynum\n";
            print $outfh "\"$keynum\" = \"$str\";\n";
            $fullstr .= "\n\n" . $str;
        $keynum = $key.(++$cnt);
    $fullstr =~ s/^\s+//;
    $fullstr =~ s/\s+$//;
    print $outfh "\"$keynum\" = \"$fullstr\";\n";
    print $plistfh "FooterText\n";
    print $plistfh "$keynum\n";
    print $plistfh "\n";

    print $plistfh "\n";
    print $plistfh "Type\n";
    print $plistfh "PSGroupSpecifier\n";
    print $plistfh "FooterText\n";
    print $plistfh "\n\n";
    print $plistfh "\n";

print $plistfh <<'EOD';



Make sure the Run Script is near the top of your Phases section. This script needs to be run before the Copy Resources item in your Build Phases.

Step 4: Build your project!

That’s it! Just build and run your project, and all of the licenses should be auto-included into your Settings bundle automatically. If you ever need to add or remove more licenses, just add or remove more .license files from your project’s directory and they’ll be automatically included in the next build. Easy!

This process has been incredibly helpful for Loose Leaf‘s build process. I include a number of different open source frameworks, and this has been incredibly helpful for organizing those licenses into the build. Of course, I also have a number of frameworks that I’ve open sourced as a part of Loose Leaf’s development, so maybe I’ll see one of those included in your project too!

Streaming Xcode and iPad Development with OBS

Developer Livestreams

Since January, I’ve occasionally live streamed Loose Leaf iOS development to YouTube. I even took some time in April to stream and open source a 2D physics game from scratch! It’s been a challenging and fun experience personally, and has more broadly grown into quite a subculture – sites like Watch People Code,, and even articles by CNN and Wired show the trend’s recent growth.

When I first started to stream, it was surprisingly difficult to get started. I wasn’t quite sure what software to use or how to set things up. This post aims to help new streamers and be a quick and easy way to get streaming quickly.

What do I need?

You only need a few tools to get started:

  1. Open Broadcast Software:
  2. Live Video Display: (optional)
  3. Your own Youtube channel

Step 1: Schedule a Live Event on YouTube

OBS is the key to your streaming puzzle – it’s the piece that streams your desktop to YouTube, so step one is to configure it with your personal YouTube settings. First, login to your YouTube channel and go to your “Creator Studio.”

Creator Studio

Next, expand the Video Manager and select “Live Events” from the sidebar. Then click to add a new Live Event – don’t worry, it won’t go live without your say-so later on.

Live Events

Fill out any title you’d like, pick a date far in the future, and click “Create Event”. Next, in the Ingestion Settings section, you’ll be telling YouTube how you’ll be sending it your stream. For this, I have it set to 500-2000Kb (480p).


Once you’ve selected your bitrate, YouTube will show you your personal stream settings. This is what we’ll use to configure OBS:

stream key

Step 2: Configure OBS

Open OBS and click on the Settings button. Then, select the Stream settings option and select YouTube as your stream type, and then copy your “Stream Name” from the above strep into the “Stream key” field in OBS.

stream settings

Next, we’ll need to make sure your stream bitrate etc are setup properly – click on the Output tab and set your bitrate to 1500.

bitrate settings

Last but not least, go to your Video settings and set your scaled resolution to 854 x 480. My internet plan only allows up to 3Mb/s upload speed, so 480p is as much as I can stream before maxing out my bandwidth.

resolution settings

Now OBS is configured properly, but we still need to tell it exactly which window / screen to stream! On to Step 3….

Step 3: Creating a Scene

OBS lets you easily switch between multiple independent “Scenes” while you stream – convenient for switching between a static “Setting up” image to your live video stream, etc. For now, we’ll just setup a single video stream source: create a new scene in OBS with the little green plus icon Screen Shot 2015-06-12 at 11.20.08 PM, and name it anything you like. With that scene selected, add a new Source to the list with its green plus icon Screen Shot 2015-06-12 at 11.20.08 PM and choose “Display Capture.” If you have multiple monitors, pick your display, then click “Ok”.

Step 4: Test the Stream!

Now you’re setup and ready to go! Switch back over to YouTube and click into your Live Control Room.

Live Control Room

You should see a red bar across the top saying that YouTube is not receiving any data. Switch over to OBS and click on the Start Streaming button. After a few seconds, you should see that red bar disappear and the Preview button will enable. Click that Preview button to see how your stream is doing, then go live when you’re ready!

Step 5: Setup your Webcam (optional)

OBS has support for adding your webcam as a video source, but I found that it lagged considerably behind the stream of the desktop. Instead, I suggest installing Live Video Display. After it’s launched, we’ll need to select your iSight as it’s camera source. Select the Video Settings button, choose your iSight camera from the list, and pick the smallest capture resolution:

Video Settings

We’re only using Live Video Display for the webcam, not for anything else, so turn off its audio settings:

Audio settings

Last but not least, set it to have zero frames of delay – this’ll force it to push your webcam to OBS as fast as it can capture it:

Screen Shot 2015-06-12 at 11.44.31 PM

Now that your webcam source is setup, we need to configure OBS to know about it. In OBS, click the green plus icon Screen Shot 2015-06-12 at 11.20.08 PM to add another source to your scene. Choose Game Capture (Syphon) and name it anything you like. When its properties window opens, check the Inject box and launch SyphonInject, then choose Live Video Display from the list – you should see your webcam pop into the preview window. Click OK to confirm, and that’s it! Now you should see your webcam on top of your desktop screen!

Step 6: Enjoy!

I’ve really enjoyed live streaming some of my iOS development – I’ve met new people, learned new things, and enjoyed it all from start to finish! If you’d like to follow along on any of my dev streams – either for Loose Leaf, Spare Parts, Remotely, or others – head on over to my YouTube or pages 🙂

Using Git to Specify the Version of Your App

It’s the simple things in life: One of the best workflow changes I made for Loose Leaf was to use git to manage the version number of my app. To release a new version, just add a tag in git, and the version in my app’s Info.plist would automatically update to match. There’s a number of different ways to set something like this up, and I’ve pieced my particular strategy together from various Stack Overflow posts, and I thought it’d be helpful to put an end-to-end post together to describes the how and why in 1 place.

Long and Short Versions

There are two version string’s you’ll need to specify in your Info.plist: the Bundle Version and the Short Bundle Version. Despite their similar name, these two version numbers can be used for different things. They let you specify two different version numbers for two different uses:

  1. Short Bundle Version: This is the version number your users see and care about. “1.0” or “2.0” etc
  2. Bundle Version: This is the version number for you as a developer to care about. It’ll tell you exactly which git commit it was built from.

This post is going to show you how to use git tags to automatically

Step 1: Defining the Bundle Version

To create a new version of the app, simply add a git tag with the appropriate version number:

$ git tag -a -m "a new release" 1.0.0

That’s it! Now that we’ve saved our version info into git, we need a way at build time to ask git which tag we’re currently working on. To retrieve our most recent tag info, we can simply use:

$ git describe

This gets us pretty close – If we’re currently on the exact commit of that tag, then we’ll see “1.0.0” printed to the command line, but if we’re on a subsequent commit, we’ll see something like “1.0.0-24-g89ea736”. Let’s parse out just the version prefix:

$ git describe --tags | awk '{split($0,a,"-"); print a[1]}'

Perfect! that command will ask git for the tagged description, then parse out the prefix before the first “-“. In our case, that’ll print out “1.0.0” for every commit after that 1.0.0 tag.

Step 2: Defining the Short Bundle Version

The short bundle version should be a monotonically increasing number that specifies exactly which commit was used for a particular build. The command to do that is:

$ git rev-list HEAD | wc -l | tr -d ' '

“git rev-list HEAD” lists out all of the commit hashes from the beginning of our repo until our current commit. “wc -l” counts those commits, and “tr -d ‘ ‘” trims the whitespace. Running this command will print out something like “2434”.

Step 3: Automating Your Build

At this point, we have:

  1. User-facing build number from Step 1
  2. Developer-facing build number from Step 2

And now we’re ready to automatically update our Info.plist with these two numbers every build.

Step 3.1: Open up Xcode and select your target’s Build Phases section

Select Target

Build Phases

Step 3.2: Add a new Run Script phase

Next, we’ll add in the script into our build process to automatically update our Info.plist. Select “Add Run Script Build Phase” from the Editor menu.

Add Run Script

Important: Make sure that your new Run Script phase is after the Copy Bundle Resources phase.

Step 3.3: The Custom Script

Now we’ll use the git commands we found above, and write in their output into the Info.plist. This script modifies the Info.plist in the build target instead of the src directory so that you’re not modifying your source files every time you build.

The script:

# Update the CFBundleShortVersionString in the generated Info.plist using the most recent Git tag.
# Idea taken from by Joachim Bondo.

# Get the current release description from Git.
GIT_RELEASE_SHORT_VERSION=`git describe --tags | awk '{split($0,a,"-"); print a[1]}'`
GIT_RELEASE_VERSION=`git rev-list HEAD | wc -l | tr -d ' '`

# Set the CFBundleShortVersionString in the generated Info.plist (stripping off the leading "v").
defaults write "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH%.*}" "CFBundleShortVersionString" "$GIT_RELEASE_SHORT_VERSION"
defaults write "${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH%.*}" "CFBundleVersion" "$GIT_RELEASE_VERSION"


That’s it! Now every time you build your app, the version information will be automatically pulled from your git tags. Easy!

Step 3.4: Rename the Script (optional)

I have a number of different build scripts – everything from this version modification to Crashlytics scripts – and it’s nice to be able to see at a glance which script does what. To change the name of the Build Phase, just double click on it’s title to select it, then type in a descriptive name.

Description Phase Name

Step 4: Bonus Step – Add Version to Settings.bundle

In Loose Leaf, I’ve also added the full version string to the Settings bundle. This helps particularly during QA; it’s much easier for testers to check the app settings to report bugs for a specific version. Even with just a few testers and a few bug-fix builds, it’s nice to be able to quickly verify that someone’s on a particular build when testing.

The end result of this step is a additional field in your Settings bundle that displays the full version string for that build.

Settings Version

To achieve this, first add in a title field into the Root.plist of your Settings bundle. After your done it should look like this:

Settings Root.plist

The default value can be anything (it’s set as “0.1” here), but our script will update it at build time. Also note in this example I’ve added it as Item 4. It maybe a different index in your plist, so make note of that number, we’ll use it again soon. For our example, I’ll be using “4”.

Next, add another Run Script Phase, and copy in the following script:

GIT_RELEASE_SHORT_VERSION=`git describe --tags | awk '{split($0,a,"-"); print a[1]}'`
GIT_RELEASE_VERSION=`git rev-list HEAD | wc -l | tr -d ' '`

/usr/libexec/PlistBuddy "$CONFIGURATION_BUILD_DIR/$CONTENTS_FOLDER_PATH/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:4:DefaultValue $VERSION_FOR_SETTINGS"

In the above script, it specifies “PreferenceSpecifiers:4:…”. If you’re item in the Root plist is a different index, make sure to use that number here too.

Step 5: Enjoy!

Now it’s easy to automatically manage your version numbers for every build. Don’t worry about forgetting to update your Info.plist – everything is taken care of automatically with this simple script!

Google Author link
Page 4 of 51« First...23456...102030...Last »