<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BlackDog Foundry</title>
	<atom:link href="http://www.blackdogfoundry.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.blackdogfoundry.com/blog</link>
	<description>Mobile Development Platform</description>
	<lastBuildDate>Thu, 10 May 2012 04:26:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Hours, Minutes and Seconds in NSPredicateEditor</title>
		<link>http://www.blackdogfoundry.com/blog/?p=169</link>
		<comments>http://www.blackdogfoundry.com/blog/?p=169#comments</comments>
		<pubDate>Thu, 10 May 2012 04:19:49 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[nspredicate]]></category>
		<category><![CDATA[xcode4]]></category>

		<guid isPermaLink="false">http://www.blackdogfoundry.com/blog/?p=169</guid>
		<description><![CDATA[The NSPredicateEditor is an excellent control that can be used to quickly give your users the ability to build up an NSPredicate.  I recently added one to a Mac application I was developing, and was surprised to see that, by default, Xcode4 only supports filtering by date, not by time.



For my application, I needed [...]]]></description>
			<content:encoded><![CDATA[<p>The NSPredicateEditor is an excellent control that can be used to quickly give your users the ability to build up an <code>NSPredicate</code>.  I recently added one to a Mac application I was developing, and was surprised to see that, by default, Xcode4 only supports filtering by <em>date</em>, not by <em>time</em>.</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/05/nspred_default.png" alt="Default Look and Feel" title="nspred_default.png" border="0" width="376" height="87" /></p>

<p>For my application, I needed a much more accurate filtering capability, so I started to dig around to see what I could find.  I found <a href="http://funwithobjc.tumblr.com/post/1646098126/creating-a-simple-nspredicateeditorrowtemplate">an excellent starting blog post</a> followed up by another <a href="http://funwithobjc.tumblr.com/post/1677163679/creating-an-advanced-nspredicateeditorrowtemplate">more advanced post</a> that gave me some really good background information.</p>

<p>These two blog posts also sowed the seed that inspired this post.</p>

<h3>Back To Coding</h3>

<p>As far as I know, you cannot add time support to your <code>NSPredicateEditor</code> rows using Interface Builder in Xcode4.  You need to drop back into code… come on in, the water is fine <img src='http://www.blackdogfoundry.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>As outlined in the previously referenced posts, each <code>NSPredicateEditorRowTemplate</code> is responsible for providing the individual controls by overriding the <code>templateView</code> method.  As you can see from the above screenshot, this method normally returns an array containing the following controls: <code>NSPopupButton</code>, <code>NSPopupButton</code> and <code>NSDatePicker</code> respectively.</p>

<p>In order to facilitate time support, we are going to create a subclass of <code>NSPredicateEditorRowTemplate</code> and modify the third element to change the date components that are displayed.</p>

<h3>Creating our subclass</h3>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;Cocoa/Cocoa.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> BDTimestampRowTemplate <span style="color: #002200;">:</span> <span style="color: #400080;">NSPredicateEditorRowTemplate</span>
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithLeftExpressions<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>leftExpressions;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;BDTimestampRowTemplate.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> BDTimestampRowTemplate
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithLeftExpressions<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>leftExpressions <span style="color: #002200;">&#123;</span>
	NSAttributeType rightType <span style="color: #002200;">=</span> NSDateAttributeType;
	NSComparisonPredicateModifier modifier <span style="color: #002200;">=</span> NSDirectPredicateModifier;
	<span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>operators <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObjects<span style="color: #002200;">:</span>
	                       <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithUnsignedInteger<span style="color: #002200;">:</span>NSLessThanPredicateOperatorType<span style="color: #002200;">&#93;</span>,
	                       <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithUnsignedInteger<span style="color: #002200;">:</span>NSLessThanOrEqualToPredicateOperatorType<span style="color: #002200;">&#93;</span>,
	                       <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithUnsignedInteger<span style="color: #002200;">:</span>NSGreaterThanPredicateOperatorType<span style="color: #002200;">&#93;</span>,
	                       <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithUnsignedInteger<span style="color: #002200;">:</span>NSGreaterThanOrEqualToPredicateOperatorType<span style="color: #002200;">&#93;</span>,
	                       <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithUnsignedInteger<span style="color: #002200;">:</span>NSEqualToPredicateOperatorType<span style="color: #002200;">&#93;</span>,
	                       <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithUnsignedInteger<span style="color: #002200;">:</span>NSNotEqualToPredicateOperatorType<span style="color: #002200;">&#93;</span>,
	                       <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
	NSUInteger options <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>super initWithLeftExpressions<span style="color: #002200;">:</span>leftExpressions rightExpressionAttributeType<span style="color: #002200;">:</span>rightType modifier<span style="color: #002200;">:</span>modifier operators<span style="color: #002200;">:</span>operators options<span style="color: #002200;">:</span>options<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>templateViews <span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// get the list of views in the template </span>
	<span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>views <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super templateViews<span style="color: #002200;">&#93;</span>;
	<span style="color: #11740a; font-style: italic;">// get out the date picker control</span>
	<span style="color: #400080;">NSDatePicker</span> <span style="color: #002200;">*</span>datePicker <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>views objectAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #11740a; font-style: italic;">// change the flags so that it displays date AND time</span>
	NSDatePickerElementFlags flags <span style="color: #002200;">=</span> NSYearMonthDayDatePickerElementFlag | NSHourMinuteSecondDatePickerElementFlag;
	<span style="color: #11740a; font-style: italic;">// apply the flags</span>
	<span style="color: #002200;">&#91;</span>datePicker setDatePickerElements<span style="color: #002200;">:</span>flags<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> views;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>


<p>Note that I have hard-coded (in this class) the supported operators.  This is because a timestamp field really can only meaningfully support this subset.  It makes the <code>initWithLeftExpressions</code> method just a little cleaner.</p>

<p>Using the techniques described in Dave&#8217;s <a href="http://funwithobjc.tumblr.com/post/1646098126/creating-a-simple-nspredicateeditorrowtemplate">excellent blog post</a>, you can then use this new class to modify your timestamp row template.</p>

<p>It will result in a template row that looks like:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/05/nspred_modified.png" alt="Modified predicate row" title="nspred_modified.png" border="0" width="486" height="99" /></p>

<p>You will notice that it <em>still</em> doesn&#8217;t show seconds.  Through some trial and error, I have found that the time-only flag will use seconds, but if you use date and time flags, you can&#8217;t get seconds.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blackdogfoundry.com/blog/?feed=rss2&amp;p=169</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZBar bar code / QR code reader &#8211; Android</title>
		<link>http://www.blackdogfoundry.com/blog/?p=139</link>
		<comments>http://www.blackdogfoundry.com/blog/?p=139#comments</comments>
		<pubDate>Sat, 03 Mar 2012 15:44:03 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ndk]]></category>
		<category><![CDATA[QR Code]]></category>
		<category><![CDATA[ZBar]]></category>

		<guid isPermaLink="false">http://www.blackdogfoundry.com/blog/?p=139</guid>
		<description><![CDATA[This post describes the approach that I used to NDK compile the Zbar bar code / QR code source code into a native Android library.

Preparing the Workspace

Create 2 new folders in your eclipse workspace &#8211; jni and libs



Download the Zbar source tarball from SourceForge &#8211; http://zbar.sourceforge.net/download.html

Now open the tarball and locate the zbar folder.



Extract the [...]]]></description>
			<content:encoded><![CDATA[<p>This post describes the approach that I used to NDK compile the Zbar bar code / QR code source code into a native Android library.</p>

<h2>Preparing the Workspace</h2>

<p>Create 2 new folders in your eclipse workspace &#8211; <strong>jni</strong> and <strong>libs</strong></p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step1.png"><img class="alignnone size-full wp-image-140" title="step1" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step1.png" alt="" width="1550" height="810" /></a></p>

<p>Download the Zbar source tarball from SourceForge &#8211; <a href="http://zbar.sourceforge.net/download.html">http://zbar.sourceforge.net/download.html</a></p>

<p>Now open the tarball and locate the zbar folder.</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step2.png"><img class="alignnone size-full wp-image-141" title="step2" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step2.png" alt="" width="1200" height="625" /></a></p>

<p>Extract the contents of the <strong><em>zbar</em></strong> folder into the<strong> jni </strong>folder in your Eclipse workspace. You will also need to extract the <strong><em>zbar.h</em></strong> file from the include folder to the<strong> jni </strong><strong>folder in your Eclipse workspace</strong>. Then download the <a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/04/ZBarAndroidPatch.zip">ZBarAndroidPatch</a> and unzip into the <strong>jni</strong> folder. The directory structure should look something like this:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step3.png"><img class="alignnone size-full wp-image-143" title="step3" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step3.png" alt="" width="1551" height="818" /></a></p>

<p>You now need to code the JNI wrapper class that will be used to call the ZBar library. The following is an example of the source code for this class:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step42.png"><img class="alignnone size-full wp-image-152" title="step4" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step42.png" alt="" width="700" height="490" /></a></p>

<h2>Generate JNI header</h2>

<p>After the Eclipse workspace is setup you are ready to generate the JNI header for your wrapper class. To do this, you need to use the Java Header File Generator <strong>javah</strong> which can be found in the Java JDK. Go to the <strong>classes</strong> directory and run <strong>javah</strong> against your wrapper class:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step5.png"><img class="alignnone size-full wp-image-147" title="step5" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step5.png" alt="" width="1237" height="816" /></a></p>

<p>This will generate a C header file. Copy this header file into the <strong>jni </strong>directory and edit the <strong>android_zbar.c</strong> source file to align with the newly generated JNI header:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/yo.png"><img class="alignnone size-full wp-image-148" title="yo" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/yo.png" alt="" width="1001" height="761" /></a></p>

<h2>Build the Library</h2>

<p>You are now ready to NDK build the ZBar library. In the <strong>jni</strong> directory run the <strong>ndk-build</strong> command:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step7.png"><img class="alignnone size-full wp-image-155" title="step7" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step7.png" alt="" width="1237" height="816" /></a></p>

<p>All going well, this should build the <strong>libzbar.so</strong> library:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step81.png"><img class="alignnone size-full wp-image-156" title="step8" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step81.png" alt="" width="1237" height="816" /></a></p>

<h2>Copy ZBar Library Into Workspace</h2>

<p>The last step is to copy the ZBar library back into your eclipse workspace. Copy the <strong>armeabi </strong>directory<strong> </strong>(including the libzbar.so file) into the <strong>libs</strong> directory of your workspace:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step9.png"><img class="alignnone size-full wp-image-157" title="step9" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/step9.png" alt="" width="1551" height="818" /></a></p>

<h2>Using the Library</h2>

<p>To use the native ZBar library, simply call the method on your JNI wrapper class:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/usejni.png"><img class="alignnone size-full wp-image-159" title="usejni" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/03/usejni.png" alt="" width="421" height="135" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blackdogfoundry.com/blog/?feed=rss2&amp;p=139</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cloning third-party git repositories in Xcode4</title>
		<link>http://www.blackdogfoundry.com/blog/?p=131</link>
		<comments>http://www.blackdogfoundry.com/blog/?p=131#comments</comments>
		<pubDate>Mon, 27 Feb 2012 05:09:25 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[xcode4]]></category>

		<guid isPermaLink="false">http://www.blackdogfoundry.com/blog/?p=131</guid>
		<description><![CDATA[Ever been confused about how to effectively compile and link third-party libraries that you may have cloned from github, bitbucket, et al?  This post post describes the process of setting up your Xcode4 environment to clone, compile and link third-party libraries.

Third-party libraries that are hosted on github, bitbucket, etc typically offer varying degrees of [...]]]></description>
			<content:encoded><![CDATA[<p>Ever been confused about how to effectively compile and link third-party libraries that you may have cloned from github, bitbucket, et al?  This post post describes the process of setting up your Xcode4 environment to clone, compile and link third-party libraries.</p>

<p>Third-party libraries that are hosted on github, bitbucket, etc typically offer varying degrees of documentation as to how they should be linked in but, in general, they all follow the same basic sequence of steps.</p>

<p>This post describes the approach that I have been using to link third-party libraries that I have cloned from git.</p>

<h2>Overview</h2>

<p>I tend to make good use of the new workspace functionality of Xcode4.  For me, it allows me to group my related projects while still retaining the logical separation of each of the projects.</p>

<p>This post describes creating a new workspace and adding an out-of-the-box project from one of the Xcode4 templates.  It then clones an <a href="http://stig.github.com/json-framework/">arbitrary project</a> from github and links it into our application.</p>

<p>Sounds fairly easy… let&#8217;s get into it.</p>

<h2>Setting Up the Workspace</h2>

<p>Create a new workspace:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_workspace.png" alt="Creating workspace" title="linking_workspace.png" border="0" width="585" height="542" /></p>

<p>And add a project from the list of Xcode4-supplied iPhone templates:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_create_project1.png" alt="Create Master-Detail project" title="linking_create_project1.png" border="0" width="600" height="404" /></p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_create_project2.png" alt="Set project name" title="linking_create_project2.png" border="0" width="600" height="404" /></p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_create_project3.png" alt="Save project details" title="linking_create_project3.png" border="0" width="571" height="600" /></p>

<p>Now, you should be able to compile and run this project.  Nothing very exciting yet.</p>

<h2>Cloning Third-Party Project</h2>

<p>For this example, I chose to clone a JSON library (for no other reason than it was the first one to appear in google).</p>

<p>Open the Git Repositories view by using the <code>File/Source Control/Repositories…</code> menu item and add a new cloned repository:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_git_menu.png" alt="Cloning a repository" title="linking_git_menu.png" border="0" width="272" height="107" /></p>

<p>and enter the URL for your remote library:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_git_url.png" alt="Enter git url" title="linking_git_url.png" border="0" width="600" height="404" /></p>

<p>and the local name for it (I usually try to use the same name as the remote repository):</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_git_name.png" alt="Entering local name" title="linking_git_name.png" border="0" width="600" height="404" /></p>

<p>and clone:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_git_clone.png" alt="Cloning remote project" title="linking_git_clone.png" border="0" width="585" height="542" /></p>

<p>Note that cloning <em>does not</em> add the project to your workspace.  You have to manually add it.  After cloning you will be presented with the following dialog &#8211; choose <code>Show in Finder</code> and we will drag the project into our workspace.</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_git_done.png" alt="Showing project in Finder" title="linking_git_done.png" border="0" width="600" height="404" /></p>

<p>Drag the <code>xcodeproj</code> file into your Xcode4 workspace.  <em>Be careful here…</em> you want to drag the project so that it is a <em>peer</em> of your <code>TestApp</code> project, not a <em>subordinate</em>.</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_dragging.png" alt="Dragging project into workspace" title="linking_dragging.png" border="0" width="290" height="288" /></p>

<p>Your workspace should now look like the following:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_added.png" alt="Workspace with third-party library added" title="linking_added.png" border="0" width="258" height="424" /></p>

<p>If it looks like the following, delete it and drag it a little further left before dropping:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_added_wrong.png" alt="Dragged as a subordinate project" title="linking_added_wrong.png" border="0" width="258" height="318" /></p>

<h2>Verifying Cloned Library</h2>

<p>Now that we have successfully cloned the third-party library into our workspace, we should firstly make sure it compiles by itself.</p>

<p>Switch schemes to the newly added project and confirm that the library compiles OK (note that very occasionally Xcode4 doesn&#8217;t add the new schemes into the list &#8211; I have no idea why, but usually just closing Xcode4 and starting again seems to fix it.)</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_schemes.png" alt="Switching schemes" title="linking_schemes.png" border="0" width="162" height="128" /></p>

<h2>Adding Third-Party Library as a Dependency</h2>

<p>We have the third-party library in our workspace, but the <code>TestApp</code> project still doesn&#8217;t know about it yet.  Fortunately, Xcode4 supports the notion of dependent projects, which is what we are going to use next.</p>

<p>Drag the blue heading bar of the third-party library onto the blue heading bar of the <code>TestApp</code> application:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_dependency.png" alt="Setting up project dependencies" title="linking_dependency.png" border="0" width="258" height="121" /></p>

<p>and create a group for the added project:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_dependency2.png" alt="Saving dependency" title="linking_dependency2.png" border="0" width="600" height="404" /></p>

<p>Your workspace should now look like:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_dependency_workspace.png" alt="Workspace with dependencies" title="linking_dependency_workspace.png" border="0" width="258" height="442" /></p>

<p>You&#8217;ve added a project dependency within the workspace, but we still haven&#8217;t told your target that it is dependent on the third-party library.  Click on your app&#8217;s target, select the <code>Build Phases</code> tab, and add a <code>Target Dependency</code>:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_target_dependency.png" alt="Target dependency" title="linking_target_dependency.png" border="0" width="400" height="460" /></p>

<p>While you&#8217;re on this tab, add an entry to the <code>Link Binary With Libraries</code> section to make sure the library is linked in at build-time:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_link_dependency.png" alt="Linking dependency" title="linking_link_dependency.png" border="0" width="400" height="460" /></p>

<p>The nice thing about this dependency being set up is that if you make any changes to the sub-project, Xcode4 is smart enough to recompile the library and re-link it into your app.</p>

<h2>Using the Library</h2>

<p>Switch back to the <code>TestApp</code> scheme and perform a build.  You should find that everything compiles OK at this point.  Now it is time to add some code that uses the third-party library.</p>

<p>In this case, we are just going to add a single line of code (with an import).  Open up the <code>AppDelegate.m</code> file and add the following statement:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;SBJson/SBJson.h&gt;</span></pre></div></div>


<p>Now, add a line at the start of the <code>application:didFinishLaunchingWithOptions:</code> method:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;JSON Test: %@&quot;</span>, <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionary<span style="color: #002200;">&#93;</span> JSONRepresentation<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>If everything has been set up correctly, you should find that Xcode4&#8217;s content assist should be able to offer assistance for the library&#8217;s methods.</p>

<p>Compile and run.</p>

<p>Uh-oh… What will likely happen is that it will start up, but bomb out with an error message like:</p>

<pre>
2012-02-27 15:31:19.108 TestApp[95762:f803] -[__NSCFDictionary JSONRepresentation]: unrecognized selector sent to instance 0x6841c70
2012-02-27 15:31:19.132 TestApp[95762:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary JSONRepresentation]: unrecognized selector sent to instance 0x6841c70'
</pre>

<p>The reason for this is that we need to include one more linker setting to tell the compiler to pick up the newly added objective-c methods.  Apple has written an <a href="http://developer.apple.com/library/mac/#qa/qa1490/_index.html">article</a> that describes the reasoning behind this.  To resolve, open up the <code>Build Settings</code> for the <code>TestApp</code> target, search for <code>Other Linker Flags</code> and add the following values:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_linker_flags.png" alt="Other linker flags" title="linking_linker_flags.png" border="0" width="320" height="297" /></p>

<p>Compile and run again, and you should see output like:</p>

<pre>
2012-02-27 15:37:47.226 TestApp[96063:f803] JSON Test: {}
</pre>

<p>And that is it!  We&#8217;re done.</p>

<h2>Footnote: Header File Management</h2>

<p>You may be wondering how Xcode4 found the <code>SBJson.h</code> file that we imported.  I don&#8217;t claim to be an expert here, but my research (and some trial/error) indicates that there are several factors at play here:</p>

<ul>
<li>When using an Xcode4 workspace, the build artefacts all get built into a &#8216;Derived Data&#8217; directory.  This physical location for this directory is defined in the Location panel of the Xcode4 settings dialog.  On my machine, this is <code>~/Library/Developer/Xcode/DerivedData</code>. Underneath this directory, each workspace gets its own unique directory.  In my case, it is <code>LinkingThirdPartiesExample-bvzijybaagkayohgfmjlxcaezgck</code></li>
<li>Within this directory, there is a Build directory that contains the build-time artefacts for the various platforms (iPhone simulator, iPhone device, Mac, et al).</li>
<li>Xcode4 is pre-defined to look in the <code>include</code> directory for header files.  If they are there, they will automatically be picked up.</li>
<li>Any <code>.h</code> in your workspace that are marked as Public are published underneath the <code>Build</code> directory. </li>
<li><p>Well-structured libraries (such as <code>SBJson</code>) mark their headers as public and use the <code>Public Headers Folder Path</code> build setting in such a way so that consumers of their library don&#8217;t <em>have</em> to modify their include paths.</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/02/linking_derived_data.png" alt="Derived data directory" title="linking_derived_data.png" border="0" width="600" height="430" /></p></li>
<li>Not-so-well-structured libraries may not mark their headers as public, or have non-standard entries for their <code>Public Headers Folder Path</code>, which will force you to modify your app&#8217;s build path to include those files explicitly.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blackdogfoundry.com/blog/?feed=rss2&amp;p=131</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a library to be shared between iOS and Mac OS X</title>
		<link>http://www.blackdogfoundry.com/blog/?p=60</link>
		<comments>http://www.blackdogfoundry.com/blog/?p=60#comments</comments>
		<pubDate>Tue, 17 Jan 2012 09:53:32 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[xcode4]]></category>

		<guid isPermaLink="false">http://www.blackdogfoundry.com/blog/?p=60</guid>
		<description><![CDATA[One of the projects I am working on at the moment could possibly be deployed to the iPhone, iPad and Mac OS X.  There is quite a chunk of behaviour that I would like to extract into a common library, and then just develop the UI for the respective platforms in their own projects. [...]]]></description>
			<content:encoded><![CDATA[<p>One of the projects I am working on at the moment could possibly be deployed to the iPhone, iPad and Mac OS X.  There is quite a chunk of behaviour that I would like to extract into a common library, and then just develop the UI for the respective platforms in their own projects.  The project structure I have in mind is:</p>

<ul>
<li><code>BDCommon</code> &#8211; A shared library that contains logic that is common across all applications</li>
<li><code>MyMacApp</code> &#8211; A Lion-based Mac application that depends on the BDCommon project</li>
<li><code>MyPhoneApp</code> &#8211; A universal iOS application that depends on the BDCommon project</li>
</ul>

<p>As you probably know, when it comes to linking libraries, iOS apps can only link static libraries and the preferred approach for Mac OS X apps is to use a framework.  So, I decided to create a single project that has two targets:</p>

<ul>
<li><code>BDCommon.framework</code> (used when linking from a Mac OS X app)</li>
<li><code>libBDCommon.a</code> (used when linking from an iOS app)</li>
</ul>

<p>This post describes the steps I performed in Xcode4 to achieve this.</p>

<h2>Create Common Project</h2>

<p>What you are about to do is create a new MAC OS X Framework project called <code>BDCommon</code>.  This will be the containing shell for both targets.</p>

<h3>Create new Mac OS X Framework</h3>

<p>Create a new Mac OS X Framework:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_new_project1.png" alt="Create new project" title="shared_new_project1.png" border="0" width="600" height="404" /></p>

<p>Set the product name and company identifier:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_new_project2.png" alt="Setting project properties" title="shared_new_project2.png" border="0" width="600" height="404" /></p>

<p>And save the project:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_new_project3.png" alt="Save the project" title="shared_new_project3.png" border="0" width="571" height="600" /></p>

<h3>Configure BDCommon Project</h3>

<p>Now we need to configure our newly create <code>BDCommon</code> project to support having two targets (one for the framework and one for the static library). The default behaviour of Xcode4 is to use the target&#8217;s name as the product name. This is OK if you only have one target, but because we want to build two products that have the same &#8220;name&#8221; (ie. <code>BDCommon.framework</code> and <code>libBDCommon.a</code>) we have to have two targets, both with different names. Hence, we need to decouple the product&#8217;s name from the target&#8217;s name.</p>

<p>In build settings for the <code>BDCommon</code> target, change the <em>Packaging/Product Name</em> from <code>$(TARGET_NAME)</code> to <code>BDCommon</code>:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_product_name.png" alt="Change product name" title="shared_product_name.png" border="0" width="600" height="275" /></p>

<p>We will now rename the name of the target itself to <code>BDCommon.framework</code> so that we can easily recognise it in the list of targets:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_target_name.png" alt="Change target name" title="shared_target_name.png" border="0" width="171" height="58" /></p>

<p>One last thing is to rename the Scheme to <code>BDCommon.Framework</code> (like renaming the Target, this is mostly a cosmetic act that helps us distinguish between the framework&#8217;s scheme and the static library&#8217;s scheme:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_scheme_name.png" alt="Change scheme name" title="shared_scheme_name.png" border="0" width="600" height="48" /></p>

<p>Perform a build.  Confirm that the <code>BDCommon.framework</code> gets created:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_framework_built.png" alt="Check framework has been built" title="shared_framework_built.png" border="0" width="260" height="132" /></p>

<p>Now would probably be a good time to commit your changes to git.</p>

<h3>Adding the libBDCommon.a Static Library Target</h3>

<p>So, we now have a project that contains a target that will build a framework for our Mac OS X apps. Next, we want to add an additional target to build a static library for our iOS apps.</p>

<p>Choose the <em>File/New/New Target…</em> menu option and add a Cocoa Touch Static Library:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_static_new_target.png" alt="Create new target" title="shared_static_new_target.png" border="0" width="600" height="404" /></p>

<p>Set the name to <code>BDCommon</code> and add it to the <code>BDCommon</code> project:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_static_target_name.png" alt="Set static target name" title="shared_static_target_name.png" border="0" width="600" height="404" /></p>

<p>Again, because we want to be able to rename the target, we need to decouple the product&#8217;s name by hard-coding it to <code>BDCommon</code>:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_static_product_name1.png" alt="Change static product name" title="shared_static_product_name.png" border="0" width="600" height="259" /></p>

<p>Let&#8217;s rename the target to <code>libBDCommon.a</code> so that it is more obvious which target is which:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_static_target_rename.png" alt="Rename static target" title="shared_static_target_rename.png" border="0" width="176" height="71" /></p>

<p>And lastly, let&#8217;s rename the scheme to <code>libBDCommon.a</code> to match the target name (again, to make it easier to distinguish between the two targets&#8217; schemes):</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_static_scheme_rename.png" alt="Rename static library scheme" title="shared_static_scheme_rename.png" border="0" width="600" height="98" /></p>

<p>Perform a build for both schemes (<code>BDCommon.framework</code> and <code>libBDCommon.a</code>).  Here is where you will notice what I believe is a bug in Xcode4:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_lib_not_built.png" alt="Static library not built" title="shared_lib_not_built.png" border="0" width="261" height="138" /></p>

<p>Despite Xcode4 reporting that the build was successful, <code>libBDCommon.a</code> is depicted in red (indicating that it hasn&#8217;t built successfully).  If you choose <em>Open in Finder</em> for both products, you will notice that it can find where it built <code>BDCommon.framework</code>, but not where it built <code>libBDCommon.a</code>.</p>

<p>It turns that it has actually built <code>libBDCommon.a</code> &#8211; it just displays it in the wrong colour.  Using Finder, you can navigate manually to the common build directory and see that they do indeed get built successfully:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_libs_being_built.png" alt="Libraries being built" title="shared_libs_being_built.png" border="0" width="460" height="166" /></p>

<p>Almost done now. If you have a look at the files in your Project Navigator, you will notice that the <code>BDCommon</code> group is duplicated.  This is due to Xcode4 being &#8220;helpful&#8221; and generating code when you added the second target.  Note that it hasn&#8217;t actually generated two copies of the physical files… it has just created several references to the existing files.  If you expand both <code>BDCommon</code> groups, you can delete the one with the fewer entries:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_extra_group.png" alt="Extra BDCommon group" title="shared_extra_group.png" border="0" width="257" height="308" /></p>

<p>Make sure, though, that you choose <em>Remove References Only</em> though, otherwise, it will actually physically delete the files.</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_delete_extra_group.png" alt="Deleting extra groups" title="shared_delete_extra_group.png" border="0" width="541" height="153" /></p>

<p>When you deleted the references in the step above, you also would have removed the membership of those references for the physical files from the two targets.  You need to make sure that both <code>BDCommon.h</code> is in the membership list of both framework and static library targets.</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_target_membership.png" alt="Target membership" title="shared_target_membership.png" border="0" width="245" height="68" /></p>

<p>The convention for shared libraries (whether they be a static library or a framework) is to have a single monolithic header file (in our case, that will be <code>BDCommon.h</code>) that imports all the other <code>.h</code> files. At the moment, we don&#8217;t have any other .h files to include, so go ahead and remove all content from <code>BDCommon.h</code> so that it is an empty file.</p>

<p>Make sure that <code>BDCommon.h</code> is declared as a public header for both targets:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_public_headers.png" alt="Making headers public" title="shared_public_headers.png" border="0" width="245" height="82" /></p>

<p>You can safely remove <code>BDCommon.m</code> now, as it no longer serves any really purpose.  Note that this time, you will really delete the file (not just the reference).</p>

<p>Perform another build for both schemes and make sure your products get rebuilt correctly.</p>

<p>Again, this would be a good time to check your code into git.</p>

<h3>Adding Some Behaviour to the Common Project</h3>

<p>Over time, I expect that my common project will evolve to contain many different classes.  To illustrate the process for the purpose of this article, we&#8217;ll add a simple class called <code>BDLog</code> that has a single method that outputs <code>Hello world</code>.  Clearly, this is a contrived example, but it should give an indication on how to add new functionality to your common library.</p>

<p>Add a new Objective-C class:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_new_class.png" alt="Create new BDLog class" title="shared_new_class.png" border="0" width="600" height="404" /></p>

<p>Set the class name to be <code>BDLog</code>:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_new_class2.png" alt="Setting class name to BDLog" title="shared_new_class2.png" border="0" width="600" height="404" /></p>

<p>And save to your <code>BDCommon</code> group. Make sure you included it in both the <code>BDCommon.framework</code> and the <code>libBDCommon.a</code> targets:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_new_class3.png" alt="Saving new class dialog" title="shared_new_class3.png" border="0" width="571" height="600" /></p>

<p>Add a static method definition called <code>log</code> to <code>BDLog.h</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span><span style="color: #a61390;">log</span>;</pre></div></div>


<p>And a corresponding implementation in <code>BDLog.m</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span><span style="color: #a61390;">log</span> <span style="color: #002200;">&#123;</span>
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Hello world!&quot;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now you need to declare it as a public header for both your targets so that it is accessible from the application projects:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_public_headers.png" alt="Making headers public" title="shared_public_headers.png" border="0" width="245" height="82" /></p>

<p>Modify <code>BDCommon.h</code> to add the following line:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;BDCommon/BDLog.h&gt;</span></pre></div></div>


<p>When building your libraries, Xcode4 copies the public headers for your static library into a directory like <code>.../DerivedData-dflasdfiouknclskjdchvlawioiewhsk/Build/Products/Debug-iphonesimulator/usr/local/include</code>.  This is fine, but it means that you need to change the header search path for every project that wants to include it, which is a pain in the ass.  What we can do to make this easier is to rely on a little bit of knowledge about the list of directories that Xcode automatically uses when building.  As it turns out, it always adds a directory called <code>include</code> to the header search path.  To take advantage of this, we will change the <em>Packaging/Public Headers Folder Path</em> from <code>/usr/local/include</code> to <code>include/BDCommon</code> (per the screenshot below, you can also use <code>$(PRODUCT_NAME)</code> which will automatically substitute <code>BDCommon</code>).  Using this path, allows us to import our headers with a statement like <code>#import &lt;BDCommon/BDCommon.h&gt;</code>.  <strong>This step is only required for the <code>libBDCommon.a</code> target.</strong></p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_setting_public_header.png" alt="Setting public header" title="shared_setting_public_header.png" border="0" width="600" height="256" /></p>

<p>Perform a build and check that both the framework and static libraries still build correctly.</p>

<h2>Creating a Mac OS X Application</h2>

<p>Alright, we are now at the moment of truth.  We need to see whether all the hard work above (which should be a once-off setup) allows us to share common code.  To do this, we&#8217;re first going to create a Mac OS X application and link to our framework.</p>

<p>Create a new Mac OS X app:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_mac_app.png" alt="Create new Mac OS X app" title="shared_mac_app.png" border="0" width="600" height="404" /></p>

<p>Set the name to <code>MyMacApp</code> &#8211; although it doesn&#8217;t really matter… we are just verifying that the framework will link OK:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_mac_app2.png" alt="Setting Mac app name" title="shared_mac_app2.png" border="0" width="600" height="404" /></p>

<p>And save the application:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_mac_app3.png" alt="Saving Mac OS X app" title="shared_mac_app3.png" border="0" width="571" height="600" /></p>

<p>Open the <em>Build Phases</em> tab for your application, and expand the <em>Link Binary with Libraries</em> section:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_mac_link.png" alt="Linking libraries" title="shared_mac_link.png" border="0" width="275" height="109" /></p>

<p>Click on the <code>+</code>, and with a bit of luck, our newly created framework should appear in the list of frameworks in the workspace.  Select it, and choose Add:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_mac_link_framework.png" alt="Linking framework" title="shared_mac_link_framework.png" border="0" width="400" height="460" /></p>

<p>Open up your App Delegate class implementation and add the following statement at the top of the file:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;BDCommon/BDCommon.h&gt;</span></pre></div></div>


<p>Now add the following code to the <code>applicationDidFinishLaunching:</code> method (if all goes well, Xcode4 will even auto-complete the class and method names for you):</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>BDLog <span style="color: #a61390;">log</span><span style="color: #002200;">&#93;</span>;</pre></div></div>


<p>Build and run.  If everything goes to plan, you will see <code>Hello world!</code> appear in the console output.</p>

<h2>Creating an iPhone Application</h2>

<p>One down, one to go.  Same basic deal as before &#8211; we are going to create an iPhone application, but this time we will link in the static library, instead of the framework.</p>

<p>Create a new iPhone app:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_phone_app.png" alt="Creating iphone app" title="shared_phone_app.png" border="0" width="600" height="404" /></p>

<p>Set the name to MyPhoneApp:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_phone_app2.png" alt="Setting iphone app name" title="shared_phone_app2.png" border="0" width="600" height="404" /></p>

<p>And save the application:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_phone_app3.png" alt="Saving iphone app" title="shared_phone_app3.png" border="0" width="571" height="600" /></p>

<p>Open the <em>Build Phases</em> tab for your application, and expand the <em>Link Binary with Libraries</em> section:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_phone_link.png" alt="iphone library links" title="shared_phone_link.png" border="0" width="275" height="109" /></p>

<p>Click on the <code>+</code>, and our newly created static library should appear in the list of libraries in the workspace.  Select it, and choose Add:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_phone_link_library.png" alt="iphone link static library" title="shared_phone_link_library.png" border="0" width="400" height="460" /></p>

<p>Open up your App Delegate class implementation and add the following statement at the top of the file:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;BDCommon/BDCommon.h&gt;</span></pre></div></div>


<p>Now add the following code to the <code>application:didFinishLaunchingWithOptions:</code> method (if all goes well, Xcode4 will even auto-complete the class and method names for you):</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>BDLog <span style="color: #a61390;">log</span><span style="color: #002200;">&#93;</span>;</pre></div></div>


<p>Build and run.  If everything goes to plan, you will see <code>Hello world!</code> appear in the console output.</p>

<h2>Linking Static Libraries That Contain Categories</h2>

<p>If you use Objective-C categories in your common library, you will likely get an error when you link your static library against the iOS app.  Apple has written an [article](http://developer.apple.com/library/mac/#qa/qa1490/_index.html “Building Objective-C static libraries with categories”) that describes the process to resolve this problem.  In a nutshell, though, you can modify the *Other Linker Flags* in your iOS app to include the <code>-ObjC</code> and <code>-all_load</code> options:</p>

<p><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2012/01/shared_other_linker_flags.png" alt="Setting other linker flags" title="shared_other_linker_flags.png" border="0" width="600" height="256" /></p>

<h2>Wrapping Up</h2>

<p>There are a few things that I haven&#8217;t yet touched on that I may include in a future post:</p>

<ul>
<li>Bundling your library for distribution to other developers</li>
<li>Private header files</li>
</ul>

<p>As this was my first foray into this topic, I would be very interested in hearing feedback from you.  In particular, if there are pieces of the above that are incorrect or misleading, please let me know and I will correct ASAP.</p>

<p>Drop me a line at craig (at) blackdogfoundry (dot) com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blackdogfoundry.com/blog/?feed=rss2&amp;p=60</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using BlackDog Replication in your Application</title>
		<link>http://www.blackdogfoundry.com/blog/?p=3</link>
		<comments>http://www.blackdogfoundry.com/blog/?p=3#comments</comments>
		<pubDate>Thu, 27 May 2010 07:00:45 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://www.blackdogfoundry.com/blog/?p=3</guid>
		<description><![CDATA[Overview

This service is designed to assist you in keeping your application reference (or operational) data up-to-date.  For example, consider the case where you have developed an application that stores train timetable information in an sqlite database on your iphone.  This information would be correct at the time of application publication, however, over time [...]]]></description>
			<content:encoded><![CDATA[<h2>Overview</h2>

<p>This service is designed to assist you in keeping your application reference (or operational) data up-to-date.  For example, consider the case where you have developed an application that stores train timetable information in an sqlite database on your iphone.  This information would be correct at the time of application publication, however, over time it would quickly become out of date.  The replication service that BlackDog offers is to store a copy of the &#8220;master&#8221; data on the BlackDog server (which you can update at any time), and the devices connect to the BlackDog server and replicate down only the changed records.</p>

<p>Many developers write their own data replication behaviour, but it is complex and error-prone.  The BlackDog Replication service allows you to concentrate on developing your application’s behaviour and core functionality, not dealing with challenges like replication.</p>

<p>This tutorial describes the steps you will need to perform in order to integrate the sqlite replication behaviour into your application.  It assumes that you are have previously used XCode to develop iphone applications.</p>

<p>The overriding premise of the BlackDog replication behaviour is that you, as the application developer, can develop your application with only a small amount of consideration to the replication that occurs under the covers.  This means that you should be able to develop your application reading from the database with no BlackDog functionality, and then add in the BlackDog replication once your application is working.</p>

<p>Looking at a typical iphone development project, it would normally involve the following high-level sequence of steps:</p>

<ul>
<li>Create initial sqlite database that contains some data</li>
<li>Copy that database into your project&#8217;s resource folder</li>
<li>Build your application that reads from that database using sqlite APIs</li>
<li>Finalise the contents of the sqlite database</li>
<li>Perform final testing</li>
<li>Ship the application to Apple for approval</li>
</ul>

<p>Contrast that to the workflow when using the BlackDog replication libraries (new steps in bold):</p>

<ul>
<li>Create initial sqlite database that contains some data</li>
<li>Copy that database into your project&#8217;s resource folder</li>
<li>Build your application that reads from that database using sqlite APIs</li>
<li>Finalise the contents of the sqlite database</li>
<li><b>Upload the contents of the sqlite database to the BlackDog server</b></li>
<li><b>Add a few lines of code to invoke the BlackDog replication service</b></li>
<li>Perform final testing</li>
<li>Ship the application to Apple for approval</li>
</ul>

<h2>Downloading BlackDog Libraries</h2>

<p>The first thing you will need to download is the latest <a href="http://www.blackdogfoundry.com/downloads">BlackDog replication libraries</a>. The BlackDog libraries come in a ZIP file that contains a number of libraries, but the two that you will need to use the replication functionality are:</p>

<ul>
<li>bdcommon</li>
<li>bdrepl</li>
</ul>

<p>When you unzip that file, you will find the following file hierarchy:</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_libs.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_libs.png" alt="" title="BlackDog Libraries and Headers" width="753" height="437" class="alignnone size-full wp-image-44" /></a></p>

<p>You will note that there are libraries provided for both Release and Debug compilation options, as well as the device and simulator runtime engines.  The Headers directory contains the Objective-C header files that define the BlackDog functionality. Unzip this file into a directory of your choosing.  For the purposes of this tutorial, I assume that the zip file was unzipped into /Users/xxxx/BlackDog</p>

<h2>Setting up your XCode Environment</h2>

<p>As all developers like to manage their development environment settings, there is no single canonical way to set up your environment.  However, there are several key objectives that must be achieved to link in the BlackDog replication libraries.</p>

<ul>
<li>Include the Headers directory</li>
<li>Link the replication libraries</li>
<li>Add some pre-requisite frameworks</li>
</ul>

<p>One possible way of achieving each of these is described below.</p>

<h3>Include the Headers directory</h3>

<p>Right-click on your Target, and choose Get Info.  On the Build tab, type &#8220;header search&#8221; in the filter field and enter <b>/Users/xxxx/BlackDog/Headers</b> into the &#8220;Header Search Paths&#8221; setting.
<a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_headers.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_headers.png" alt="" title="Headers" width="582" height="221" class="alignnone size-full wp-image-42" /></a></p>

<h3>Link the replication libraries</h3>

<p>In the Target Info Build tab, filter for &#8220;other linker flags&#8221; and enter <b>-all_load -lbdcommon -lbdrepl</b> in the &#8220;Other Linker Flags&#8221; setting.
<a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_linker1.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_linker1.png" alt="" title="Adding Other Linker Flags to XCode" width="584" height="172" class="alignnone size-full wp-image-52" /></a></p>

<p>In the Target Info Build tab, filter for &#8220;library search&#8221; and add <b>/Users/xxxx/BlackDog/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)</b> in the &#8220;Library Search Paths&#8221; setting.
<a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_library.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_library.png" alt="" title="Adding Library Search Path to XCode" width="542" height="245" class="alignnone size-full wp-image-43" /></a></p>

<p>Note that the use of the $(CONFIGURATION) and $(EFFECTIVE_PLATFORM_NAME) variables are a clever technique that allows for dynamically picking up the correct BlackDog runtime library depending on whether you are running on the device or simulator, or in Debug/Release mode.</p>

<h3>Add some pre-requisite frameworks</h3>

<p>In the Target Info General tab, add the following frameworks/dynamic libraries:</p>

<ul>
<li>CFNetwork.framework</li>
<li>libxml2.dylib</li>
<li>libsqlite3.0.dylib</li>
</ul>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_frameworks.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/blackdog_frameworks.png" alt="" title="Adding Frameworks to XCode" width="568" height="181" class="alignnone size-full wp-image-41" /></a></p>

<h2>Calling the Libraries</h2>

<p>Once your XCode environment has been setup correctly, you can now start calling the Replication libraries.  The functionality that is available is defined in the BlackDogReplication.h file in the Headers folder.  The API is very simple:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> BlackDogReplication <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> <span style="color: #002200;">&#123;</span>	
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">/**
 * Launches a synchronous replication.  If you require an asynchronous
 * invocation, use a separate background thread to run this function.
 * 
 * Parameters:
 *   delegate - The delegate that provides the input parameters and responds
 *              to the callback functions as replication occurs
 *   fullReplication - Should we get a full replication, or a delta.  In nearly
 *                     all cases, this value will be false as you would normally
 *                     only want to replicate changes since your last update.
 *                     However, there may be cases where you want to completely
 *                     refresh the contents of the table.  In those rare cases,
 *                     pass true in this parameter.
 */</span>
<span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>replicate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>id&lt;BlackDogReplicationDelegate&gt;<span style="color: #002200;">&#41;</span>delegate fullReplication<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>fullReplication;
<span style="color: #a61390;">@end</span></pre></div></div>


<p>There is a single static method defined on the BlackDogReplication class that takes your delegate and a boolean indicating whether you want a full replication, or an incremental replication.  You will nearly always want an incremental so you should pass NO as the parameter. You will need to define a delegate class that can be used, and it will need to implement the methods that are defined in the BlackDogReplicationDelegate class and its parent class (BlackDogDelegate).  The simplest example of a delegate class looks like:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> DemoDelegate
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>appKey <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;cd79fbe3ae6d41ba9daad1acf45b5bff&quot;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>secretKey <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;3a1248037bc74fd2aa512f4e8feabf90&quot;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>sqliteDatabasePath <span style="color: #002200;">&#123;</span>
	<span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>docDirectory <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSSearchPathForDirectoriesInDomains<span style="color: #002200;">&#40;</span>NSDocumentDirectory, NSUserDomainMask, <span style="color: #a61390;">YES</span><span style="color: #002200;">&#41;</span> objectAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>docDirectory stringByAppendingPathComponent<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;database.sqlite&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableName <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;mytable&quot;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>initialChangeId <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #2400d9;">1</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>


<p>An example invocation of the API looks like:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">DemoDelegate <span style="color: #002200;">*</span>delegate <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DemoDelegate alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>BlackDogReplication replicate<span style="color: #002200;">:</span>delegate fullReplication<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>delegate release<span style="color: #002200;">&#93;</span>;</pre></div></div>


<p>The above code connects to the BlackDog server and replicates any changes since your device last replicated data from the master server.</p>

<h2>Updating your data</h2>

<p>There are two ways to update your master data:</p>

<ol>
<li>Uploading a complete sqlite database via the BlackDog website (non-incremental)</li>
<li>Invoking a web service (XML-based) APIs to send incremental updates to the BlackDog server</li>
</ol>

<h2>Some important notes</h2>

<ul>
<li>When you initially upload an sqlite database to the BlackDog website, it performs a number of validations, and creates a snapshot of the data with a changeID of 1. </li>
<li>Every time changes get made to the table and uploaded to the BlackDog website, the changed records (including deletions) are flagged with the next ChangeID. </li>
<li>The client libraries know what the latest ChangeID is for the data on the device, so when it performs a replication, it only fetches the rows that have been changed since that ChangeID. </li>
<li><b>If your replicated tables do not make use of a primary key column, the BlackDog replication service is unable to provide incremental replication.  That is, the whole table will be replicated even if only one row has changed.</b></li>
<li><b>If you delete a replicated table from the BlackDog server, the data is gone forever.  You can upload a fresh copy of the table, but it will be given a ChangeID of 1 and your devices are very likely to have a ChangeID of, say, 23.  In this case the client will download a complete set of the data again.</b></li>
</ul>

<h3>Caveats for uploading complete sqlite databases</h3>

<ul>
<li>If you upload a complete sqlite database via the website, it is treated as non-incremental.  That is, when devices replicate they will receive a complete data refresh.  If you need incremental changes to be incremented, you need to use the BlackDog web services which will be described in a later tutorial.</li>
<li>If the uploaded sqlite database contains multiple tables, all tables will be registered for replication (if there are tables in the database that you do not need for replication, you can delete the reference to them on the BlackDog website.)  Tables that already exist on the BlackDog server will be updated with a new ChangeID; new tables will be initialised with a ChangeID of 1.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blackdogfoundry.com/blog/?feed=rss2&amp;p=3</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BlackDog Features</title>
		<link>http://www.blackdogfoundry.com/blog/?p=7</link>
		<comments>http://www.blackdogfoundry.com/blog/?p=7#comments</comments>
		<pubDate>Thu, 27 May 2010 06:08:25 +0000</pubDate>
		<dc:creator>craig</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[notification]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[registration]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://www.blackdogfoundry.com/blog/?p=7</guid>
		<description><![CDATA[Registration

In order to use the BlackDog services, you first need to register for an account.  To do this, you will need to select an account name, password and provide your email address.



Once you have entered the required details, you will be sent a confirmation email with a URL for you to click on to [...]]]></description>
			<content:encoded><![CDATA[<h2>Registration</h2>

<p>In order to use the BlackDog services, you first need to register for an account.  To do this, you will need to select an account name, password and provide your email address.</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_register.png"><img class="alignnone size-full wp-image-16" title="Registration screen" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_register.png" alt="" width="583" height="214" /></a></p>

<p>Once you have entered the required details, you will be sent a confirmation email with a URL for you to click on to confirm your account.</p>

<h2>Applications</h2>

<p>Within your BlackDog account, you have the ability to define an application.  The application name can be whatever you like (it is purely informational to help you manage your applications within BlackDog), and would typically align to an application that you submit to the Apple Store/Android Marketplace.  If you have an application that runs on multiple devices (but still has the same underlying behaviour), you would only create one application in BlackDog.</p>

<p>Once you&#8217;ve created the application, it will be assigned an application key and a secret key.  These values are used on the mobile devices to create secure sessions with the BlackDog server.</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_appkey.png"><img class="alignnone size-full wp-image-20" title="Application/Secret Key Settings" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_appkey.png" alt="" width="441" height="90" /></a></p>

<p>You can define multiple applications that all have completely separate functionality and settings.</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_applist.png"><img class="alignnone size-full wp-image-21" title="Application List" src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_applist.png" alt="" width="726" height="124" /></a></p>

<h2>Using APIs</h2>

<p>The primary purpose of BlackDog is for you to take advantage of the iPhone and Android libraries and embed them in your mobile applications.  Currently, the following libraries are provided:</p>

<ul>
    <li>bdrepl</li>
    <li>bdnotify</li>
</ul>

<p>The above libraries also depend on the bdcommon library for some base functionality.  For example, if you are using the Replication API, you will need to include both bdcommon and bdrepl libraries.</p>

<p>The key input that you, as a developer, need to provide is defined by either the BlackDogReplicationDelegate or BlackDogNotificationDelegate protocol/interface.  Both of these interfaces extend from a parent interface called BlackDogDelegate that defines some common behaviour.</p>

<h3>iPhone</h3>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">/**
 * The BlackDogDelegate protocol is designed to represent a common set of functions
 * across all BlackDog Foundry services.  In particular, by abstracting the application 
 * key and secret key into this protocol, it gives the developers the freedom to share
 * an implementation of this protocol across multiple BlackDog services (such as 
 * replication and analytics), without having to duplicate information.
 *
 * As a stand-alone protocol, this isn't a particularly useful class.  Delegates should
 * not implement this protocol directly, but rather implement one or more specific
 * protocols such as BlackDogReplicatorDelegate.
 */</span>
<span style="color: #a61390;">@protocol</span> BlackDogDelegate &lt;NSObject&gt;
&nbsp;
<span style="color: #11740a; font-style: italic;">/**
 * Returns a string containing your application's 32-character application key.  
 * eg. &quot;2119cafdaa37402c9c0af77e8f701f58&quot;
 */</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>appKey;
&nbsp;
<span style="color: #11740a; font-style: italic;">/**
 * Returns a string containing your application's 32-character secret key.  
 * eg. &quot;f333759829f74d4faf07496aeac23604&quot;
 */</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>secretKey;
&nbsp;
@optional
&nbsp;
<span style="color: #11740a; font-style: italic;">/**
 * Called by the BlackDog libraries if a session with the BlackDog server is unable
 * to be established.   During typical operations, this should never be called, with 
 * the possible exception of when the BlackDog server is down (or for some reason 
 * temporarily not servicing requests), in which case, the code parameter will be 
 * STATUS_TEMPORARILY_UNAVAIL.  In this case, it may be meaningful to let end-users
 * know that there is a temporarily problem with replication (depending on how much
 * visibility the end-users have of replication).  In all other cases, though, the
 * code and reason parameters will be of little meaning to end-users - they are aimed
 * at the developer of the application.
 * 
 * Parameters:
 *   code   - Contains a integer code that gives a hint of what the problem may have been.   
 *   reason - Contains a (possibly) human-readable string with a little more info.
 */</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>didFailToEstablishSession<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>code reason<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>reason;
&nbsp;
<span style="color: #11740a; font-style: italic;">/**
 * Called by the BlackDog libraries if a a particular API call was not successful.
 * Usually this would occur if the call to the remote service was technically sucessful
 * (ie. the remote service was invoked), but suffered an error during execution.  This
 * might be due to you passing invalid data, or perhaps due to a BlackDog server error
 * condition.  There is also a chance that the client-side BlackDog libraries had some
 * problems performing an action (for example, if errors were experienced opening a local
 * sqlite database.  The code and reason parameters will almost certainly contain no 
 * meaningful information that would be able to be displayed to end-users - they are 
 * aimed at the developer of the application.
 * 
 * Parameters:
 *   code   - Contains a integer code that gives a hint of what the problem may have been.   
 *   reason - Contains a (possibly) human-readable string with a little more info.
 */</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>didFailToInvokeRemoteService<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>code reason<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>reason;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>


<p>If you are developing an application for the iPhone that is using the BlackDog replication services, you would define your delegate class like so (note that extremely minimal error handling methods have been implemented):</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;DemoDelegate.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> DemoDelegate
&nbsp;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>appKey <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;cd79fbe3ae6d41ba9daad1acf45b5bff&quot;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>secretKey <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;3a1248037bc74fd2aa512f4e8feabf90&quot;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>sqliteDatabasePath <span style="color: #002200;">&#123;</span>
	<span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>docDirectory <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>NSSearchPathForDirectoriesInDomains<span style="color: #002200;">&#40;</span>NSDocumentDirectory, NSUserDomainMask, <span style="color: #a61390;">YES</span><span style="color: #002200;">&#41;</span> objectAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>docDirectory stringByAppendingPathComponent<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;database.sqlite&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableName <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;mytable&quot;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>initialChangeId <span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #2400d9;">1</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>didFailToFetchChanges<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>code reason<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>reason <span style="color: #002200;">&#123;</span>
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@&quot;</span>, reason<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>didFailToEstablishSession<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>code reason<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>reason <span style="color: #002200;">&#123;</span>
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@&quot;</span>, reason<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>didFailToInvokeRemoteService<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>code reason<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>reason <span style="color: #002200;">&#123;</span>
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@&quot;</span>, reason<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>


<p>If you were using both replication and notification, you have three choices:</p>

<ol>
    <li>Define a single delegate class that implements both BlackDogReplicationDelegate and BlackDogNotificationDelegate.</li>
    <li>Define two separate delegate classes &#8211; one that implements BlackDogReplicationDelegate and one that implements BlackDogNotificationDelegate</li>
    <li>Define three delegate classes &#8211; one that implements BlackDogDelegate (eg. MyDelegate) and provides the common details (application and secret key), and two others that subclass MyDelegate that respectively implement the replication and notification delegates.</li>
</ol>

<h2>Reports</h2>

<p>BlackDog offers a number of reports that help you understand the usage of the BlackDog services.</p>

<h3>Device Type Report</h3>

<p>This report displays a pie chart with the percentage breakdown of the various device types.  The high level report displays a breakdown of the device types (iPhone, Android, etc), but the Include Sub-Types checkbox allows you to drill down into more specifics on the actual types (eg. iPhone 3GS, HTC Magic, etc).</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_devicetype.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_devicetype.png" alt="" title="Device Type Report" width="726" height="412" class="alignnone size-full wp-image-27" /></a></p>

<p>The start and end dates filter the time period that you would like the report over; for this report, the referenced date is date on which the device irst connected to the BlackDog services).  You can optionally run the report across all your applications, or just for a single application.  By default, the data in the BlackDog database is stored in UTC format, however, you can override this choose an offset to run the report for.</p>

<h3>Device Installation Report</h3>

<p>This report displays a line chart that shows the number of devices that connect to the BlackDog service for the first time during that period.  You can group the data points of report on an hourly, daily, monthly and yearly basis.</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_deviceinstall.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_deviceinstall.png" alt="" title="Device Installation Report" width="726" height="398" class="alignnone size-full wp-image-28" /></a></p>

<p>The start and end dates filter the time period that you would like the report over; for this report, the referenced date is the date on which the device first connected to the BlackDog services).  You can optionally run the report across all your applications, or just for a single application.  By default, the data in the BlackDog database is stored in UTC format, however, you can override this choose an offset to run the report for.</p>

<h3>API Usage Counts Report</h3>

<p>This report displays a line chart indicating the volume of the various BlackDog API calls. This report will give you an excellent view of the way that your application interacts with the BlackDog services.</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_apiusage.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_apiusage.png" alt="" title="API Usage Report" width="726" height="398" class="alignnone size-full wp-image-29" /></a></p>

<p>The start and end dates filter the time period that you would like the report over.  You can optionally run the report across all your applications, or just for a single application.  By default, the data in the BlackDog database is stored in UTC format, however, you can override this choose an offset to run the report for.</p>

<h3>Active Devices Report</h3>

<p>This report displays the list of active devices during the given period (where &#8220;active&#8221; is defined as having some interaction with the BlackDog services).</p>

<p><a href="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_activedevices.png"><img src="http://www.blackdogfoundry.com/blog/wp-content/uploads/2010/05/bd_report_activedevices.png" alt="" title="Active Devices Report" width="726" height="398" class="alignnone size-full wp-image-30" /></a></p>

<p>The start and end dates filter the time period that you would like the report over.  You can optionally run the report across all your applications, or just for a single application.  By default, the data in the BlackDog database is stored in UTC format, however, you can override this choose an offset to run the report for.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blackdogfoundry.com/blog/?feed=rss2&amp;p=7</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

