<?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>b&#124;tw&#124;se &#187; software</title>
	<atom:link href="http://danwright.info/blog/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://danwright.info/blog</link>
	<description>by Dan Wright</description>
	<lastBuildDate>Tue, 29 Nov 2011 07:56:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Xcode project object UUIDs</title>
		<link>http://danwright.info/blog/2010/10/xcode-pbxproject-files-3/</link>
		<comments>http://danwright.info/blog/2010/10/xcode-pbxproject-files-3/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 20:09:14 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Xcode pbxproject]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=239</guid>
		<description><![CDATA[Continuing our discussion of the Xcode project file format&#8230; Unique Xcode object IDs using Ruby The &#8220;UUIDs&#8221; used in project files are shorter than true UUIDs (only 12 bytes/16 characters), and have no punctuation. We can&#8217;t just use system UUID services to generate new ones, then. In practice, our UUIDs usually do not need to [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing our <a href="xcode-pbxproject-files">discussion</a> of the <a href="xcode-pbxproject-files-2">Xcode project file format</a>&#8230;</p>
<h3>Unique Xcode object IDs using Ruby</h3>
<p>The &#8220;UUIDs&#8221; used in project files are shorter than true UUIDs (only 12 bytes/16 characters), and have no punctuation. We can&rsquo;t just use system UUID services to generate new ones, then. In practice, our UUIDs usually do not need to be <em>universally</em> unique; they must be unique within a project file, and ideally would be unique across all projects built or opened on a given machine. Here, nonetheless, is a quickie ruby class that generates Xcode project UUIDs:</p>
<pre><code class="code">
class XcodeUUIDGenerator

    def initialize
        @num = [Time.now.to_i, Process.pid, getMAC]
    end

    # Get the ethernet hardware address ("MAC"). This version
    # works on Mac OS X 10.6 (Snow Leopard); it has not been tested
    # on other versions.

    def getMAC(interface='en0')
        addrMAC = `ifconfig #{interface} ether`.split("\n")[1]
        addrMAC ? addrMAC.strip.split[1].gsub(':','').to_i(16) : 0
    end

    def generate
        @num[0] += 1
        self
    end

    def to_s
        "%08X%04X%012X" % @num
    end
end
</code></pre>
<p>Usage is simple:</p>
<pre><code class="code">    gen = XcodeUUIDGenerator.new
    id1 = gen.generate.to_s
    id2 = gen.generate.to_s
    id3 = gen.generate.to_s
</code></pre>
<h3>PBXFileReference</h3>
<p>A <code>PBXFileReference</code> is used to track every external file referenced by the project: source files, resource files, libraries, generated application files, and so on. A source file might look like this:</p>
<pre><code>
 29B97316FDCFA39411CA2CEA /* main.m */ = {
	isa = PBXFileReference;
	fileEncoding = 4;
	lastKnownFileType = sourcecode.c.objc;
	path = main.m;
	sourceTree = "<group>";
 };
</code></pre>
<p>The values for <code>lastKnownFileType</code> may be found within Xcode itself, by selecting the file and choosing &#8220;Get Info&#8221;. A sourceTree of &#8220;<group>&#8221; corresponds to &#8220;Relative to Enclosing Group&#8221;. A fileEncoding value of &#8220;4&#8243; is UTF-8. Here, the path is only a file name, however it can be a (longer) relative path or an absolute path (sourceTree = &#8220;<absolute>&#8220;). Relative paths may also be relative to the chosen SDK, the Xcode application (rare), the project file (that is, the .xcodeproj bundle), or the built product.</p>
<pre><code>
 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {
	isa = PBXFileReference;
	lastKnownFileType = wrapper.framework;
	name = Cocoa.framework;
	path = /System/Library/Frameworks/Cocoa.framework;
	sourceTree = "<absolute>";
 };
</code></pre>
<p>Some Xcode templates contain absolute paths to some frameworks (as in the above example), however this is, arguably, &#8220;wrong&#8221;&mdash;SDK files should always use SDK-relative paths (as, indeed, Xcode 3.2.x will do if you add a framework to a project manually):</p>
<pre><code>
 2D04AF89126B8A7A00073224 /* AppleScriptObjC.framework */ = {
	isa = PBXFileReference;
	lastKnownFileType = wrapper.framework;
	name = AppleScriptObjC.framework;
	path = System/Library/Frameworks/AppleScriptObjC.framework;
	sourceTree = SDKROOT;
 };
</code></pre>
<p>Finally, the final output of your target also has a PBXFileReference. It looks slightly different:</p>
<pre><code>
 8D1107320486CEB800E47090 /* MyProject.app */ = {
	isa = PBXFileReference;
	explicitFileType = wrapper.application;
	includeInIndex = 0;
	path = MyProject.app;
	sourceTree = BUILT_PRODUCTS_DIR;
 };
</code></pre>
<p>Instead of <code>lastKnownFileType</code>, it has an <code>explicitFileType</code>; it also has a property <code>includeInIndex</code>, set to 0 (FALSE).</p>
<p>You can add comment to files; these are stored as a <code>comments</code> property on the PBXFileReference.</p>
<h3>PBXBuildFile</h3>
<p>Files that need to be processed in the build (for example compiled, linked, or copied) also have a <code>PBXBuildFile</code>. These are <em>very</em> simple:</p>
<pre><code> 8D11072D0486CEB800E47090 /* main.m in Sources */ = {
	isa = PBXBuildFile;
	fileRef = 29B97316FDCFA39411CA2CEA /* main.m */;
	settings = {ATTRIBUTES = (); };
};
</code></pre>
<p>The fileRef is the id of the <code>PBXFileReference</code>. The <code>settings</code> property is usually omitted entirely. If you specify per-file compiler flags, they will be stored in the <code>COMPILER_FLAGS</code> property of the <code>settings</code> property.</p>
<h3>PBXSourcesBuildPhase</h3>
<p>Projects commonly have several build phases: compiling, linking, copying resources, copying other files, and perhaps running shell scripts. <code>PBXSourcesBuildPhase</code> describes the compiling phase for a target.</p>
<pre><code> 8D11072C0486CEB800E47090 /* Sources */ = {
    isa = PBXSourcesBuildPhase;
    buildActionMask = 2147483647;
    files = (
      8D11072D0486CEB800E47090 /* main.m in Sources */,
      256AC3DA0F4B6AC300CF3369 /* MyProjectAppDelegate.m in Sources */,
    );
    runOnlyForDeploymentPostprocessing = 0;
 };
</code></pre>
<p>The <code>files</code> property contains an array of <code>PBXBuildFile</code> references. <code>buildActionMask</code> is usually 2147483647 (that&rsquo;s 0x7FFFFFFF in hexadecimal). The <code>runOnlyForDeploymentPostprocessing</code> property is normally 0 (FALSE).</p>
<h3>Until next time&#8230;</h3>
<p>That&rsquo;s it for this week! Next time, we&rsquo;ll look at the other build phases.</p>
<p>¶</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2010/10/xcode-pbxproject-files-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More on the Xcode project format</title>
		<link>http://danwright.info/blog/2010/10/xcode-pbxproject-files-2/</link>
		<comments>http://danwright.info/blog/2010/10/xcode-pbxproject-files-2/#comments</comments>
		<pubDate>Mon, 11 Oct 2010 00:04:16 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[Xcode pbxproject]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=225</guid>
		<description><![CDATA[A 90-Second Project Parser in Ruby Last week we looked at the overall format of Xcode project files. Here&#8217;s an easy parser written in Ruby; this one will only run on Mac OS X, because it uses Foundation from Ruby: #!/usr/bin/ruby # http://danwright.info/blog/xcode-pbxproject-files-2 require 'osx/cocoa' xcodeproj = "/Users/danwr/Documents/MyProject/MyProject.xcodeproj" projectpbxproj = "#{xcodeproj}/project.pbxproj" data = OSX::NSData.dataWithContentsOfFile(projectpbxproj) plist [...]]]></description>
			<content:encoded><![CDATA[<h3>A 90-Second Project Parser in Ruby</h3>
<p><a href="xcode-pbxproject-files">Last week</a> we looked at the overall format of Xcode project files. Here&rsquo;s an easy parser written in Ruby; this one will only run on Mac OS X, because it uses Foundation from Ruby:
<pre><code class="code" style="font-size: 9px;">
#!/usr/bin/ruby
# http://danwright.info/blog/xcode-pbxproject-files-2

require 'osx/cocoa'

xcodeproj = "/Users/danwr/Documents/MyProject/MyProject.xcodeproj"

projectpbxproj = "#{xcodeproj}/project.pbxproj"
data = OSX::NSData.dataWithContentsOfFile(projectpbxproj)
plist = OSX::NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription(data, 0, nil, nil)

rootObject = plist['rootObject']
objects    = plist['objects']

if ARGV.length == 0
	puts "rootObject = #{objects[rootObject]}"
else
	what = ARGV.shift
	if /^[0-9a-fA-F]{24}$/ =~ what
		puts "object #{what} = #{objects[what]}"
	else
		results = objects.keys.find_all {|key| objects[key]['isa'] == what }
		puts "isa '#{what}': #{results}"
	end
end
</code></pre>
<p>If you run this command without any arguments, it will show you the root object (PBXProject). If you run it with a UUID, it will display the corresponding object; if you provide it with an object class (&#8216;isa&#8217;), it will display the UUIDs for all matching objects. For purposes of this article, I&rsquo;ve hard-coded the path to a project; you can edit that to point to your own project, or modify the script to allow a path to be specified as an argument.</p>
<p>Wow, that&rsquo;s silly-easy. If you want your script to run on another platform&mdash;Windows or Linux&mdash;you would need another solution (but it isn&rsquo;t exactly difficult to write a custom parser in a modern scripting language such as Ruby, Python, or even Old Man Perl.</p>
<h3>XCConfigurationList</h3>
<p>An <code>XCConfigurationList</code> is simply a list of configurations. A <em>configuration</em> refers to a group of settings, and commonly we have at least two: Debug and Release, the former for debugging the project, the latter optimized for customers.</p>
<pre><code class="code" style="font-size: 10px;">
C01FCF4E08A954540054247B = {
    buildConfigurations =     (
        C01FCF4F08A954540054247B,
        C01FCF5008A954540054247B
    );
    defaultConfigurationIsVisible = 0;
    defaultConfigurationName = Release;
    isa = XCConfigurationList;
}</code></pre>
<p>The <code>defaultConfigurationName</code> and <code>defaultConfigurationIsVisible</code> properties indicate which configuration is the default when building with the <code>xcodebuild</code> tool, as well as whether this information should be exposed in the Xcode user interface. The <code>buildConfigurations</code> array contains references to objects of type <code>XCBuildConfiguration</code>.</p>
<h3>XCBuildConfiguration</h3>
<p>An <code>XCBuildConfiguration</code> is a collection of build settings, like so:</p>
<pre><code class="code" style="font-size:10px;">
C01FCF4F08A954540054247B = {
    buildSettings =     {
        ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
        "GCC_C_LANGUAGE_STANDARD" = gnu99;
        "GCC_OPTIMIZATION_LEVEL" = 0;
        "GCC_WARN_ABOUT_RETURN_TYPE" = YES;
        "GCC_WARN_UNUSED_VARIABLE" = YES;
        "ONLY_ACTIVE_ARCH" = YES;
        PREBINDING = NO;
        SDKROOT = "macosx10.6";
    };
    isa = XCBuildConfiguration;
    name = Debug;
}</code></pre>
<p>The <code>buildSettings</code> property is the heart of an XCBuildConfiguration. Each build setting should look familiar: these are the same names and settings you would use in an <code>.xcconfig</code> file. Of course, <code>buildSettings</code> can be empty, as it often will be when you have an .xcconfig file specified instead.</p>
<h3>PBXVariantGroup</h3>
<p>A <code>PBXVariantGroup</code> describes a group of files that act like one; this is used to described localized files (strings and xibs).</p>
<pre><code class="code" style="font-size:10px;">
1DDD58140DA1D0A300B32029 = {
    children =     (
        1DDD58150DA1D0A300B32029
    );
    isa = PBXVariantGroup;
    name = "MainMenu.xib";
    sourceTree = "<group>";
}
</code></pre>
<p>This one describes the application&rsquo;s main xib (describing the menu bar and main window). The <strong>name</strong> is the name of the file. The <strong>children</strong> contains a list of localizations; here, there is just one, for the English version. Let&rsquo;s look at that child:</p>
<pre><code class="code" style="font-size:10px;">
1DDD58150DA1D0A300B32029 = {
    isa = PBXFileReference;
    lastKnownFileType = "file.xib";
    name = English;
    path = "English.lproj/MainMenu.xib";
    sourceTree = "<group>";
}
</code></pre>
<p>The path is the path of the actual .xib file (relative to the encoding group). <code>lastKnownFileType</code> indicates the file type.</p>
<h3>Next time&#8230;</h3>
<p>Next time, a look at <code>PBXFileReference</code>, <code>PBXBuildFile</code>, and <code>PBXSourcesBuildPhase</code>.</p>
<p>&para;</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2010/10/xcode-pbxproject-files-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A brief look at the Xcode project format</title>
		<link>http://danwright.info/blog/2010/10/xcode-pbxproject-files/</link>
		<comments>http://danwright.info/blog/2010/10/xcode-pbxproject-files/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 01:58:03 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=215</guid>
		<description><![CDATA[Let&#8217;s take a quick little tour of the Xcode project file format. Anyone doing Mac OS X or iOS development in a team environment (i.e. just about everybody) has had to deal with the joy of merging project changes in version control (subversion, cvs, git, you name it). An Xcode project, of course, is actually [...]]]></description>
			<content:encoded><![CDATA[<p>Let&rsquo;s take a quick little tour of the Xcode project file format. Anyone doing Mac OS X or iOS development in a team environment (i.e. just about everybody) has had to deal with the joy of merging project changes in version control (subversion, cvs, git, you name it).</p>
<p>An Xcode project, of course, is actually a <strong>package</strong>, a directory with bundled files within. A typical project might look like this:</p>
<pre><code>
MyProject.xcodeproj/
	danwr.mode1v3
	danwr.pbxuser
	project.pbxproj

</code></pre>
<p>The first two files have your username. If multiple users use the same project, you will have a set of <code>.mode1v3</code> and <code>.pbxuser</code> files for each user. These files contain various user settings (preferences, really) that are associated with the project, for example:</p>
<ul>
<li>the size and position of the project window</li>
<li>which groups are open and which are closed</li>
<li>which item in the project is selected</li>
<li>&#8230;and more</li>
</ul>
<p>This information is not normally shared among multiple users, so it is neither necessary nor desirable to add these (<code>.mode1v3</code> and <code>.pbxuser</code>) files to your repository. If you already have, go ahead and remove them (<code>svn remove</code> if you use subversion, for instance). I&rsquo;ll wait.</p>
<h3>Project.pbxproj</h3>
<p>This leaves us with the project file itself, <code>project.pbxproj</code>. Oh, look how smug it is, all undecipherable and all. Or&#8230; is it? Let&rsquo;s open up that bad boy in a text editor and see what it looks like. First, the overall layout:</p>
<pre><code>
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 45;
	objects = {
</code>            <em style="color:#003300;">[[ : snip! : ]]</em><code>
	};
	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}
</code></pre>
<p>We start with a comment indicating the text encoding used in the file, UTF-8. Presumably other encodings are possible, however in practice all project files use UTF-8. You will notice other comments (C-style: <code>/* ... */</code>) sprinkled throughout the project file. While presumably Xcode&rsquo;s lexer handles multi-line comments, Xcode itself does not generate multi-line comments. If one were attempting the read or write project.pbxproj files, the parser would need to be able to handle multi-line comments, while ideally avoiding writing them (unless preserving existing comments).</p>
<p>A set of brackets { } enclose a record of key-value pairs. The keys are:</p>
<ul>
<li><code>archiveVersion</code>; It is set to 1 in all versions of Xcode that use the file format described here.</li>
<li><code>classes</code>; A list of classes, usually empty.</li>
<li><code>objectVersion</code>; This relates to which object types are used in this project.pbxproj, and which keys are defined. This changes based on the version of Xcode that wrote the project; it is controlled by the â€œProject Formatâ€ popup menu in Xcode&rsquo;s &ldquo;Project Info&rdquo; window. The value 45 corresponds to &ldquo;Xcode 3.1-compatible&rdquo;.</li>
<li><code>objects</code>; This is a list (actually, a record, or hash) of objects in the project. This is the meat of the file format.</li>
<li><code>rootObject</code>; This identifies the root object, the object that represents the project itself.</li>
</ul>
<p>Now let&rsquo;s take a look at the objects in general. There is an object for every file, group, target, build phase, and so on. Each object is identified by a <a href="http://en.wikipedia.org/wiki/UUID">UUID</a>. If they are universally-unique, then any number of projects from any number of original machines can be opened at the same time by a single copy of Xcode without any problems. These UUIDs are 12 bytes&mdash;24 hexadecimal digits without any separating hyphens. Each object has a set of properties, one of which, &ldquo;<code>isa</code>&rdquo; specifies the class of the object. The other properties are determined by this class.</p>
<h3>Object classes</h3>
<p>The object classes supported depends upon the <code>objectVersion</code>. Here is a partial list:</p>
<ul>
<li><code>PBXBuildFile</code></li>
<li><code>PBXFileReference</code></li>
<li><code>PBXFrameworksBuildPhase</code></li>
<li><code>PBXGroup</code></li>
<li><code>PBXNativeTarget</code></li>
<li><code>PBXProject</code></li>
<li><code>PBXResourcesBuildPhase</code></li>
<li><code>PBXSourcesBuildPhase</code></li>
<li><code>PBXVariantGroup</code></li>
<li><code>XCBuildConfiguration</code></li>
<li><code>XCConfigurationList</code></li>
</ul>
<p>The most important one here is <code>PBXFileReference</code>; every file referenced by the project (source files, headers, libraries, frameworks, xcconfig files, other projects&#8230;)<sup>1</sup> is represented by a <code>PBXFileReference</code>.</p>
<pre><code>
	089C165DFE840E0CC02AAC07 /* English */ = {
		isa = PBXFileReference;
		fileEncoding = 4;
		lastKnownFileType = text.plist.strings;
		name = English;
		path = English.lproj/InfoPlist.strings;
		sourceTree = "<group>";
	};
</code></pre>
<p>There are two different types of files: input (e.g. source files) and output (e.g. the output application or library). <code>lastKnownFileType</code> is present and set for input files. The list of possible values can be found in Xcode in the file &ldquo;Get Info&rdquo; window. Additional values are, of course, possible.</p>
<pre><code>
	8D1107320486CEB800E47090 /* MyProject.app */ = {
		isa = PBXFileReference;
		explicitFileType = wrapper.application;
		includeInIndex = 0;
		path = MyProject.app;
		sourceTree = BUILT_PRODUCTS_DIR;
	};
</code></pre>
<p>Output files always have the <code>explicitFileType</code> key, <code>includeInIndex</code> (typically set to 0, or false, for binaries and packages). Both input and output files have a <code>path</code> and <code>sourceTree</code> specified. Path names are not normally quoted unless necessary (for example, if the pathname includes a semicolon, space, or other special character).</p>
<p>In part 2, I&rsquo;ll look at PBXVariantGroup, XCBuildConfiguration, and XCConfigurationList.</p>
<p>&para;</p>
<hr />
<sup>1</sup> There are exceptions; two of the most well-known are <code>Info.plist</code> files and precompiled header source (<code>.pch</code>) files. These two files are always identified either by absolute pathname, or by a path relative to the <code>.xcodeproj</code> project.</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2010/10/xcode-pbxproject-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode Run Script Build Phase error reporting</title>
		<link>http://danwright.info/blog/2010/03/xcode-run-script-build-phase-error-reporting/</link>
		<comments>http://danwright.info/blog/2010/03/xcode-run-script-build-phase-error-reporting/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 17:14:35 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=151</guid>
		<description><![CDATA[I thought about blogging about this several months ago, but never got around to it. And don&#8217;t skip reading the comments.]]></description>
			<content:encoded><![CDATA[<p>I thought about blogging about <a href="http://briksoftware.com/blog/?p=120" target="_blank">this</a> several months ago, but never got around to it. And don&rsquo;t skip reading the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2010/03/xcode-run-script-build-phase-error-reporting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Photoluna 1.1</title>
		<link>http://danwright.info/blog/2010/01/photoluna-1-1/</link>
		<comments>http://danwright.info/blog/2010/01/photoluna-1-1/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 05:14:34 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[banasmoo-news]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=141</guid>
		<description><![CDATA[Photoluna 1.1 was released a few weeks ago, and is now available on the iTunes App Store. If you purchased version 1.0, you&#8217;ll be happy to know that this upgrade is free, and many of you have already updated to the new version. Regrettably, I&#8217;ve been a bit behind the curve updating the Photoluna web [...]]]></description>
			<content:encoded><![CDATA[<p>Photoluna 1.1 was released a few weeks ago, and is now available on the iTunes App Store. If you purchased version 1.0, you&#8217;ll be happy to know that this upgrade is free, and many of you have already updated to the new version.</p>
<p>Regrettably, I&#8217;ve been a bit behind the curve updating the <a href="http://banasmoo.com/goto?photoluna">Photoluna web site</a>; most of the screen shots are from version 1.0. I was off on a two-week stint of jury duty just as 1.1 hit the store, followed by a bad cold that led straight into the holidays! The page should be updated soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2010/01/photoluna-1-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Photoluna 1.1 is (almost) here</title>
		<link>http://danwright.info/blog/2009/12/photoluna-1-1-is-almost-here/</link>
		<comments>http://danwright.info/blog/2009/12/photoluna-1-1-is-almost-here/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 00:46:01 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[banasmoo-news]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=139</guid>
		<description><![CDATA[Good news for those of you waiting for the next version of Photoluna! We finished and submitted version 1.1 last week, and it is currently under review by Apple. If all goes well it should be available within the next week. We have our fingers crossed. â€œBut how much will the upgrade cost,â€ you ask? [...]]]></description>
			<content:encoded><![CDATA[<p>Good news for those of you waiting for the next version of Photoluna! We finished and submitted version 1.1 last week, and it is currently under review by Apple. If all goes well it should be available within the next week. We have our fingers crossed.</p>
<p>â€œBut how much will the upgrade cost,â€ you ask? Nothing! This upgrade will be free to all current customers.</p>
<p>â€œWhatâ€™s <em>in</em> the upgrade?â€ Ah, for that, youâ€™ll have to wait a little longer&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2009/12/photoluna-1-1-is-almost-here/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>October &#8220;Blahs&#8221; Sale</title>
		<link>http://danwright.info/blog/2009/10/october-blahs-sale/</link>
		<comments>http://danwright.info/blog/2009/10/october-blahs-sale/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 21:45:15 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[banasmoo-news]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=137</guid>
		<description><![CDATA[Photoluna, for iPhone and iPod Touch, is on sale right now for 50% off (on top of the every-day 20% discount from its release price). This sale will only last a few days, so act quickly!]]></description>
			<content:encoded><![CDATA[<p><a href="http://banasmoo.com/goto?photoluna">Photoluna</a>, for iPhone and iPod Touch, is on sale right now for <strong>50% off</strong> (on top of the every-day 20% discount from its release price). This sale will only last a few days, so act quickly!</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2009/10/october-blahs-sale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Photoluna End-of-Summer Sale</title>
		<link>http://danwright.info/blog/2009/08/photoluna-end-of-summer-sale/</link>
		<comments>http://danwright.info/blog/2009/08/photoluna-end-of-summer-sale/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 21:31:36 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[banasmoo-news]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=135</guid>
		<description><![CDATA[Photoluna, for iPhone and iPod Touch, is on sale right now for 60% off. This sale will only last a few days, so act quickly!]]></description>
			<content:encoded><![CDATA[<p><a href="http://banasmoo.com/goto?photoluna">Photoluna</a>, for iPhone and iPod Touch, is on sale right now for <strong>60% off</strong>. This sale will only last a few days, so act quickly!</p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2009/08/photoluna-end-of-summer-sale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Breaking into the debugger on ARM</title>
		<link>http://danwright.info/blog/2009/08/breaking-into-the-debugger-on-arm/</link>
		<comments>http://danwright.info/blog/2009/08/breaking-into-the-debugger-on-arm/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 00:26:07 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=114</guid>
		<description><![CDATA[From time to time, itâ€™s useful to break into the debugger programmatically. The simplest way to accomplish this on Mac OS X and iPhone OS is with raise(SIGINT), to wit: #define DebugBreak() raise(SIGINT) There is one problem with this technique, however: the debugger (gdb) will break well inside the raise call (actually inside __kill called [...]]]></description>
			<content:encoded><![CDATA[<p>From time to time, itâ€™s useful to break into the debugger programmatically. The simplest way to accomplish this on Mac OS X and iPhone OS is with <code>raise(SIGINT)</code>, to wit:</p>
<pre class="code">
#define DebugBreak()    raise(SIGINT)
</pre>
<p>There is one problem with this technique, however: the debugger (gdb) will break well inside the raise call (actually inside <code>__kill</code> called by <code>kill</code> called by <code>raise</code>), and more often then not will be unable to display the contents of local variables in the function that called <code>raise(SIGINT)</code>.</p>
<p>The secret, of course, is to define an entirely <em>inline</em> version of <code>raise(SIGINT)</code>. The implementation for <code>raise</code> is simple enough; <code>kill</code> is an even simpler wrapper around <code>__kill</code>.</p>
<pre class="code">
int raise(int signo)
{
    return kill(getpid(), signo);
}
int kill(pid_t pid, int signo)
{
    return __kill(pid, signo, 1);
}
</pre>
<p>The final pieces, <code>getpid</code> and <code>__kill</code>, simply call system routines through the <code>syscall</code> mechanism.</p>
<p>So now we can update <a href="http://cocoawithlove.com/2008/03/break-into-debugger.html">Matt Gallagherâ€™s article</a> by adding support for ARM (iPhone and iPod Touch) like so:</p>
<pre class="code" style="font-size: 75%">
#if __ppc64__ || __ppc__
    #define BSDebugBreak() \
        do { \
            __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
              : : : "memory","r0","r3","r4" ); \
           } while (0)
#elif __i386__ || __x86_64__
    #define BSDebugBreak() \
        do {__asm__{"int $3\n" : : );} while (0)
#elif __arm__
    #define BSDebugBreak() \
        do { \
        __asm__("mov r0, #20\nmov ip, r0\nsvc 128\nmov r1, #37\nmov ip, r1\nmov r1, #2\nmov r2, #1\n svc 128\n" \
            : : : "memory","ip","r0","r1","r2"); \
        } while (0)
#else // unknown architecture
    #define BSDebugBreak() raise(SIGINT)
#endif
</pre>
<p>I have omitted Mattâ€™s references to <code>if(AmIBeingDebugged())</code> as I prefer to make that test optional and explicit in the client code rather than include it in the <code>BSDebugBreak</code> macro. Iâ€™ve also added a clause for unknown, future architectures (it is usually wise to assume another architecture is just over the horizon). My personal version of this macro definition has an <code>#error</code> directive in place of the <code>raise(SIGINT)</code> version.</p>
<p><a href="http://banasmoo.com/downloads/BSDebugBreak.h">Download BSDebugBreak.h</a></p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2009/08/breaking-into-the-debugger-on-arm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Photoluna updates</title>
		<link>http://danwright.info/blog/2009/08/photoluna-updates/</link>
		<comments>http://danwright.info/blog/2009/08/photoluna-updates/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 20:53:30 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[banasmoo-news]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[banasmoo]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[ipod]]></category>
		<category><![CDATA[Photoluna]]></category>

		<guid isPermaLink="false">http://danwright.info/blog/?p=112</guid>
		<description><![CDATA[In late June, we released Photoluna 1.0.1 to the iTunes App Store. Since then, we have been working hard on the next version (&#8220;1.1&#8221;). This upcoming release will likely require OS 3.0. The reason is fairly simple: We no longer have any devices available for testing that are running earlier versions, and it is not [...]]]></description>
			<content:encoded><![CDATA[<p>In late June, we released <a href="http://banasmoo.com/goto?photoluna">Photoluna 1.0.1</a> to the iTunes App Store. Since then, we have been working hard on the next version (&ldquo;1.1&rdquo;). This upcoming release will likely require OS 3.0. The reason is fairly simple: We no longer have any devices available for testing that are running earlier versions, and it is not possible to &ldquo;downgrade&rdquo; an iPhone or iPod Touch once it has been upgrade to 3.0.</p>
<p>Stay tuned for more information about version 1.1 in the coming weeks, or follow us on <a href="http://twitter.com/banasmoo">Twitter!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://danwright.info/blog/2009/08/photoluna-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

