<?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/"
	>

<channel>
	<title>The Air Source</title>
	<atom:link href="http://blog.airsource.co.uk/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.airsource.co.uk</link>
	<description>Code and cogitation on BREW and all things mobile from the folks at Airsource.</description>
	<pubDate>Fri, 13 Aug 2010 09:53:54 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>UI Automation on the iPhone</title>
		<link>http://blog.airsource.co.uk/index.php/2010/08/13/ui-automation-on-the-iphone/</link>
		<comments>http://blog.airsource.co.uk/index.php/2010/08/13/ui-automation-on-the-iphone/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 09:48:19 +0000</pubDate>
		<dc:creator>Iestyn</dc:creator>
		
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.airsource.co.uk/?p=1542</guid>
		<description><![CDATA[As a summer intern I could have worried about just being given tasks such as making the tea, but here at Airsource, among other challenges, I was given the chance to work on improving some the QA infrastructure via automated testing. I study Engineering and have learnt some theory regarding testing practices in software development, [...]]]></description>
			<content:encoded><![CDATA[<p>As a summer intern I could have worried about just being given tasks such as making the tea, but here at <a href="http://www.airsource.co.uk">Airsource</a>, among other challenges, I was given the chance to work on improving some the QA infrastructure via automated testing. I study Engineering and have learnt some theory regarding testing practices in software development, so it was great to put that to a practical use!</p>
<p>Apple announced with iOS4 the ability to do <a href="http://developer.apple.com/iphone/library/documentation/DeveloperTools/Reference/UIAutomationRef/index.html">automated UI testing</a> on the iPhone as a part of the Instruments development tool. Such testing is done with the help of a number of JavaScript libraries which allow you to access an application on a device and tap buttons, scroll views and varify text as if it were a human interacting with the hardware, and not a script.</p>
<p>Why is this &ndash; other than the fact it&#8217;s something from Apple &ndash; cool?  It essentially means that it is possible for us as app developers and testers to automate some of the tests we always do to ensure we have not broken anything in our latest development cycle. There is nothing worse than working hard on adding a new feature to an app, testing it and releasing it only to discover that your testing missed a regression in your previous functionality. This forces you to make a brown paper bag release to fix it, for which you have to test everything again in addition to the things not fully tested the first time. This takes up time and effort which could be used to add more features, and more importantly can lead to your users having a broken app.</p>
<p>Automating the tests does not mean that they are better tests than if they were done manually. What it does mean is that tester time is saved on doing the mundane day to day tests so that they can spend more of their time on testing edge cases and new features, where the harder to find bugs are more likely to be and less likely to be found by the developers as they write code.</p>
<h3>What Airsource is doing with it</h3>
<p>At Airsource we&#8217;ve been busy automating tests for our app, <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=304099767&#038;mt=8">Optiscan</a>. Doing this we have found that, despite what Apple have tried to do with using timeouts, it is sometimes necessary to have delays in the tests. The main shortcoming in this area is the fact UI Automation swallows taps on elements which are not visible; meaning that your tests script may expect a changed state and fail because the tap to change the state was never registered. The reason that timeouts do not work on this is that the element you are attempting to tap exists and valid, so it can be tapped, but it may not be visible (due to an animation sequence for example) thus the tap is never registered by the app. This is a big shortcoming in the system of timeouts, it would be great if Apple fixed this by attempting taps until the tap occurs on a visible element or the timeout is reached. </p>
<p>When you are writing a test you do not want to have to worry if the button is ready to be tapped or not, you just want to tap the button! So as a part of the testing effort we have written a bunch of useful little functions which encapsulate all the delay logic and mean than we don&#8217;t worry about delays when we&#8217;re writing the tests.</p>
<p>The code below allows us to scroll to an element with a particular name in a scroll view, before waiting for it to become visible and then tapping it. This simple encapsulation of a common task means that there is no need for the test writer to worry about the button becoming visible to tap before tapping it, just worry about how to actually test the app.</p>
<pre>
// Allows you to scroll to an element with a particular name and tap it.
function scrollToElementWithNameAndTap(scrollView,name)
{
	if (! (elementArray instanceof UIAScrollView))
	{
		throw ("Expected a UIAScrollView");
	}

	var e = elementArray.scrollToElementWithName(name);
	waitForVisible(e,5,0.25);
	e.tap();
}

// Poll till the item becomes visible, up to a specified timeout
function waitForVisible(element, timeout, step)
{
        if (step == null)
        {
                step = 0.5;
        }

        var stop = timeout/step;

        for (var i = 0; i < stop; i++)
        {
                target.delay(step); // for the animation
                if (element.isVisible())
                {
                        return;
                }
        }
        element.logElement();
        throw("Not visible");
}
</pre>
<p>Using JavaScript objects&#8217; <code>prototype</code> property it is even possible to make <code>scrollToElementWithNameAndTap(name)</code> a method of each instance of <code>UIAScrollView</code>. Hence if you have a constructor for your tests you can use</p>
<pre>
UIAScrollView.prototype.scrollToElementWithNameAndTap = function(name){
                        scrollToElementWithNameAndTap(this,name)
                        };
</pre>
<p>and now you can call the method on all your UIAScrollViews just as if it were a native UI Automation method.</p>
<h3>Doing more than it says on the tin</h3>
<p>An unfortunate aspect of the UI Automation kit is that there is no reset button or method.   The result of this is that if a test fails, then your app is in an unknown state, thus it is very likely that all subsiquent tests will also fail. Ideally you do not want it to appear as if 20 tests have failed when in fact only one has failed. Having the ability to <code>target.reset()</code> to reset the app to a known state would be very useful, and it is a pain that Apple have not implemented it in some form. </p>
<p>To remedy this we&#8217;ve had to add a small amount of code to our apps which makes it possible for us to interact with them on the level of the program, not just the UI level. UI Automation allows us to change the volume on the device using methods in <a href="http://developer.apple.com/iphone/library/documentation/ToolsLanguages/Reference/UIATargetClassReference/UIATargetClass/UIATargetClass.html#//apple_ref/doc/uid/TP40009924">UIATarget</a>, so we&#8217;ve added a listener for the device volume to our app, which means we can run code when we detect a volume change. Code for a volume listener is shown below.</p>
<pre>
// Set up a listener to act on volume changes
AudioSessionInitialize(nil, nil, nil, nil);
AudioSessionSetActive(true);
AudioSessionAddPropertyListener(
                         kAudioSessionProperty_CurrentHardwareOutputVolume,
                         applicationVolumeDidChange,
                         self);

// Note that this callback will only be called if the mute button is off.
void applicationVolumeDidChange(void *inClientData,
                         AudioSessionPropertyID inID,
                         UInt32 inDataSize, const void *inData)
{
        NSLog(@"Volume changed");

        // Do something like reset the system
}
</pre>
<p>This way calling <code>target.clickVolumeUp();</code> just after <code>UIALogger.logFail(...)</code> in your testing script will mean that you can reset the app before the next test is run. Note that it is important that the hardware mute button is off when you are testing otherwise no signals will be sent that the volume has changed!</p>
<h3>Shortcomings</h3>
<p>Other than the swallowed taps and lack of reset method mentioned above, there are a couple of other shortcomings with UI Automation. The most obvious being the lack of screenshots when running the tests on the simulator; this makes it hard to verify UI and record what the app&#8217;s state was when a test failed. To be honest it feels rather bizarre that you can take remote screenshots on the actual hardware iPhone, but not in the simulator. I hope that Apple fix this in future releases. </p>
<p>The less obvious, but rather annoying shortcoming (especially if you are building a large library of testing scripts) is the lack of a decent preprocessor. JavaScript does not have native support for preprocessing or any kind of #import structure, so it is good that UI Automation scripts support #import, but the lack of define statements and logic such as #define and #ifdef is a pain when you want only to run a certain initialisation script once, but it is called by each test you run. Emulation of this behaviour using JavaScript variables is not helped by the fact that variables can remain defined between different runs in Instruments.</p>
<h3>Conclusions</h3>
<p>Automated UI testing does not mean bug free code. No testing on any non-trivial piece of software can guarantee bug free code, and the testing is only as good as the tests themselves. Using automated testing means that it is easier to stop regressions by having a test in place for each previous bug which has cropped up, it also means that the tester&#8217;s time can be utilised more effectively. Apple&#8217;s UI Automation ticks many boxes for good automated testing despite its shortcommings, and we hope will prove an invaluable tool in our development cycle.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.airsource.co.uk/index.php/2010/08/13/ui-automation-on-the-iphone/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Quelle heure est-il? or &#8220;What&#8217;s the time, Mr Jobs?&#8221;</title>
		<link>http://blog.airsource.co.uk/index.php/2010/03/15/quelle-heure-est-il/</link>
		<comments>http://blog.airsource.co.uk/index.php/2010/03/15/quelle-heure-est-il/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 15:41:02 +0000</pubDate>
		<dc:creator>TC</dc:creator>
		
		<category><![CDATA[Technical]]></category>

		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.airsource.co.uk/?p=1474</guid>
		<description><![CDATA[A while ago, I was tracking down some NaNs in accelerometer-based code (smoothing device orientation for an OpenGL AR view). It turns out it wasn&#8217;t my bug — UIAcceleration.timestamp was going backwards approximately every 12 minutes! Naturally, the documentation doesn&#8217;t mention anything about this:
This value indicates the time relative to the device CPU time base [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago, I was tracking down some NaNs in accelerometer-based code (smoothing device orientation for an OpenGL AR view). It turns out it wasn&#8217;t my bug — <code>UIAcceleration.timestamp</code> was going backwards approximately every 12 minutes! Naturally, the documentation doesn&#8217;t mention anything about this:</p>
<blockquote><p>This value indicates the time relative to the device CPU time base register. Compare acceleration event timestamps to determine the elapsed time between them.</p></blockquote>
<p>Assuming iPhone OS is similar enough to Mac OS X, it <a href="http://lists.apple.com/archives/mac-games-dev/2004/Feb/msg00126.html">must</a> be using mach_absolute_time():<a href="#post1474-refA" style="line-height:0;vertical-align:super;font-size:65%">[1]</a><br />
<span id="more-1474"></span></p>
<blockquote><p>Uptime is the highest resolution (64-bits) timer on any PowerPC processor. It counts bus cycles (usually 1/4 the CPU speed) since the last reset (or (re?)boot). All other system timers and clocks are based off of this counter (including gettimeofday).</p></blockquote>
<p><a href="http://developer.apple.com/mac/library/qa/qa2004/qa1398.html">QA1398</a> appears to be the earliest<a href="#post1474-refF" style="line-height:0;vertical-align:super;font-size:65%">[2]</a> official documentation of mach_absolute_time() and gives two definitions of <tt>GetPIDTimeInNanoseconds()</tt>. The first relies on CoreServices&#8217; <tt>AbsoluteToNanoseconds()</tt> which isn&#8217;t in iPhone OS; we&#8217;re interested in the second (casts added for a little extra clarity):</p>
<pre>// Do the maths.  We hope that the multiplication doesn't
// overflow; the price you pay for working in fixed point.

elapsedNano = (uint64_t)elapsed * (uint32_t)sTimebaseInfo.numer
             / (uint32_t)sTimebaseInfo.denom;</pre>
<p>On OS X/i386, it&#8217;s fine — the <a href="http://fxr.watson.org/fxr/source/osfmk/i386/hpet.c?v=xnu-1456.1.26#L263">several</a> <a href="http://fxr.watson.org/fxr/source/osfmk/i386/rtclock.c?v=xnu-1456.1.26#L102">timers</a> <a href="http://fxr.watson.org/fxr/source/osfmk/i386/tsc.c?v=xnu-1456.1.26#L206">are</a> <a href="http://fxr.watson.org/fxr/source/osfmk/i386/rtclock.c?v=xnu-1456.1.26#L568">all</a> <a href="http://fxr.watson.org/fxr/source/osfmk/i386/rtclock.c?v=xnu-1456.1.26#L283">converted</a>  <a href="http://fxr.watson.org/fxr/source/osfmk/i386/machine_routines_asm.s?v=xnu-1456.1.26#L184">to</a> <a href="http://www.google.com/search?q=site%3Ahttp%3A%2F%2Ffxr.watson.org%2Ffxr%2Fsource%2Fosfmk%2Fi386%2F%3Fv%3Dxnu-1456.1.26+nanoseconds&#038;filter=0">nanoseconds</a> (this seems to miss the point entirely), so <tt>numer = denom = 1</tt> and there&#8217;s no overflow.</p>
<p>On an iPhone 3G S, it ticks at 24 MHz and (on OS 3) mach_timebase_info() returns 1000000000/24000000.<a href="post1474-refD" style="line-height:0;vertical-align:super;font-size:65%">[3]</a> The multiply overflows after 2<sup>64</sup>/10<sup>9</sup> &#8776; 1.84e10 ticks — about 768.6 seconds or 12.8 minutes. Bingo.<a href="post1474-refC" style="line-height:0;vertical-align:super;font-size:65%">[5]</a></p>
<p>But <code>UIAcceleration.timestamp</code> is a double — so it&#8217;s converting timestamps to nanoseconds, overflowing, and dividing by a billion (or multiplying by 1.0e-9) to get the timestamp in seconds. I&#8217;m not sure why they do all this; I&#8217;d just calculate <code>numer/(denom*1.0e9)</code> at startup and multiply timestamps by it. It&#8217;s also pretty easy to convert to nanoseconds without unnecessary<a href="post1474-refB" style="line-height:0;vertical-align:super;font-size:65%">[6]</a> overflow:</p>
<pre>nanos = elapsed/denom*numer + elapsed%denom*numer/denom;</pre>
<p>I ended up fixing the bug by throwing away accelerometer updates (but storing the new timestamp) when time has gone backwards. Who cares if you skip an accelerometer update every 12 minutes?</p>
<h4>Afterword</h4>
<p>I&#8217;m pretty sure that mach_absolute_time() is still the &#8220;best&#8221; way to measure timestamps — it&#8217;s existed since Mac OS 10.0 and seems to be a highly stable API. <a href="http://www.google.com/search?q=site:developer.apple.com/iphone/+mach_absolute_time">CoreAnimation and GCD</a> mention it, along with <a href="http://developer.apple.com/iphone/library/qa/qa2009/qa1643.html">QA1643</a> which suggests either using it directly or inlining it. Since iOS 4, there&#8217;s also CVGetCurrentHostTime() which the docs say is equivalent to the CoreAudio timebase (and thus mach_absolute_time). There&#8217;s a <a href="http://www.macresearch.org/tutorial_performance_and_time">reasonably accurate article</a> with more details (but I&#8217;d  divide by 10<sup>9</sup> instead of multiplying by 10<sup>&minus;9</sup>). </p>
<p>For completeness, there&#8217;s also <code>AudioQueueDeviceGetCurrentTime()</code> which requires an audio queue and returns a lot of extra things you probably don&#8217;t care about. In Snow Leopard/iOS 4 there&#8217;s <code>[[NSProcessInfo processInfo] systemUptime]</code>. <code>AudioGetCurrentHostTime()</code> exists  but is &#8220;private&#8221; due to the lack of an iPhone OS header (the Mac OS X header says since iPhone OS 2).</p>
<p>I used to be lazy and use <code>CFAbsoluteTimeGetCurrent()</code>, but since iOS 4 it can change arbitrarily (due to app backgrounding, NTP/cell network updates, or leap seconds). <code>[NSDate timeIntervalSinceReferenceDate]</code> is equivalent, <code>[NSDate date]</code> is much slower (~4000 CPU clocks!). Moreover, both seem to round to the microsecond (presumably they&#8217;re based on <code>gettimeofday()</code>).</p>
<ol style="font-size:smaller">
<li><a name="post1474-refA"></a>UpTime() is the Mac OS 8 name for mach_absolute_time(). On a PowerPC, it retrieves the value of the timebase register using the <code>mftb</code> and <code>mftbu</code> instructions. It&#8217;s not always the &#8220;bus clock&#8221;; my iBook G4 says it runs at 18431630 Hz, which doesn&#8217;t correspond to any bus unless the CPU has a 57.5&times; multiplier (<a href="http://en.wikipedia.org/w/index.php?title=Crystal_oscillator_frequencies&#038;oldid=373999844">apparently</a> it&#8217;ll be a 18.432 MHz UART clock, despite the lack of a serial port). As far as I know, ARMs don&#8217;t usually have a time base register; mach_timebase_info() on a 3GS takes over 700 CPU clocks, consistent with using an external device.</a></li>
<li><a name="post1474-refF"></a><a href="http://developer.apple.com/mac/library/documentation/Performance/Conceptual/LaunchTime/Articles/MeasuringLaunch.html#//apple_ref/doc/uid/20001856-100475">Launch Time Performance Guidelines: Measuring Launch Speed: Using Explicit Timestamps</a> has been around for longer and says <cite>mach_absolute_time reads the CPU time base register and is the basis for other time measurement functions</cite>, but it&#8217;s unclear which revision it was added in and is more of a brief mention than documentation. Interestingly, it&#8217;s the only other document mentioning <a href="http://www.google.com/search?q=site:developer.apple.com+%22CPU+time+base+register%22&#038;filter=0">&#8220;CPU time base register&#8221;</a>.</li>
<li><a name="post1474-refD"></a>The iPhone and iPhone 3G use 6 MHz. The iPhone 3G S, iPhone 4, and iPad use 24 MHz. The iPod Touches presumably are the same as the corresponding iPhone. On OS 4, mach_timebase_info() reduces the fraction, returning 125/3 on a 3G S, postponing overflow for 195 years, and making it difficult to tell whether UIAcceleration has been fixed.<a href="#post1474-refE" style="line-height:0;vertical-align:super;font-size:65%">[4]</a></li>
<li><a name="post1474-refE"></a><code>UIAcceleration.timestamp</code> values are still all close to a nanosecond boundary, so it still seems to convert to nanoseconds first. Presumably it&#8217;ll break noticeably on devices with an odd clock frequency (33.333333 MHz?). It&#8217;s also odd that it&#8217;s not fixed given the existence of <code style="white-space: nowrap">-[NSProcessInfo systemUptime]</code> which returns a double without nanosecond-rounding.</li>
<li><a name="post1474-refC"></a>It shouldn&#8217;t be difficult to figure out how many times it&#8217;s overflowed and thus get the corresponding mach_absolute_time() value, but that just seems like too much effort and is likely to break across releases.
<li><a name="post1474-refB"></a>If the interval is more than 2<sup>64</sup> ticks, the input has overflowed. If the interval is more than 2<sup>64</sup> nanoseconds, the output must overflow (or be clipped, or something). Otherwise, it&#8217;ll work; the &#8220;price you pay&#8221; for integer arithmetic is just that you need a little more care to prevent intermediate overflow. It&#8217;s &#8220;fixed point&#8221; either.</li>
<li>Interestingly, <code>CMSampleBufferGetSampleTimingInfo()</code> says that frames from <code>AVCaptureVideoDataOutput</code> use a nanosecond timescale, despite the lack of a nanosecond clock.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.airsource.co.uk/index.php/2010/03/15/quelle-heure-est-il/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Optiscan update teething troubles</title>
		<link>http://blog.airsource.co.uk/index.php/2010/03/12/optiscan-update-teething-troubles/</link>
		<comments>http://blog.airsource.co.uk/index.php/2010/03/12/optiscan-update-teething-troubles/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 22:51:42 +0000</pubDate>
		<dc:creator>John</dc:creator>
		
		<category><![CDATA[News]]></category>

		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.airsource.co.uk/?p=1481</guid>
		<description><![CDATA[ We&#8217;ve been making continual minor improvements to Optiscan, fixing some issues with cut and paste and handling of certain types of addresses. Unfortunately a serious bug slipped into release 1.8.2, which hit the App Store yesterday. Apple helped us immensely by fast-tracking approval of version 1.8.3. If you are seeing crashes in Optiscan today, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=304099767&amp;mt=8"><img class="attachment wp-att-1285 alignleft" src="http://blog.airsource.co.uk/wp-content/uploads/2009/03/optiscantransbak.png" alt="optiscantransbak" width="57" height="57" /></a> We&#8217;ve been making continual minor improvements to Optiscan, fixing some issues with cut and paste and handling of certain types of addresses. Unfortunately a serious bug slipped into release 1.8.2, which hit the App Store yesterday. Apple helped us immensely by fast-tracking approval of version 1.8.3. If you are seeing crashes in Optiscan today, check if you are still running 1.8.2. If so, check the App Store for an update! (It may take up to another couple of hours till it&#8217;s fully propagated through their distribution network.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.airsource.co.uk/index.php/2010/03/12/optiscan-update-teething-troubles/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Optiscan developments</title>
		<link>http://blog.airsource.co.uk/index.php/2010/02/08/optiscan-developments/</link>
		<comments>http://blog.airsource.co.uk/index.php/2010/02/08/optiscan-developments/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 12:03:33 +0000</pubDate>
		<dc:creator>John</dc:creator>
		
		<category><![CDATA[News]]></category>

		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.airsource.co.uk/?p=1465</guid>
		<description><![CDATA[ Several news items on Optiscan! Last week we sent version 1.8.0 to Apple (hopefully it will make the App Store this week). Together with some other cool stuff, this version adds support for structured append, which has been widely requested by users of the King Jim Pomera DM-20. An update to the Optiscan library [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=304099767&amp;mt=8"><img class="attachment wp-att-1285 alignleft" src="http://blog.airsource.co.uk/wp-content/uploads/2009/03/optiscantransbak.png" alt="optiscantransbak" width="57" height="57" /></a> Several news items on Optiscan! Last week we sent version 1.8.0 to Apple (hopefully it will make the App Store this week). Together with some other cool stuff, this version adds support for structured append, which has been widely requested by users of the <a href="http://www.kingjim.co.jp/pomera/dm20/index.html">King Jim Pomera DM-20</a>. An update to the Optiscan library for our <a href="http://blog.airsource.co.uk/index.php/2010/01/08/optiscan-licensing/">commercial licensees</a> will follow shortly.</p>
<p>We&#8217;ve had a note from Greg at <a href="http://www.setjapan.com/">SET Japan</a>: their latest designer QR code promotional video features Optiscan, which seems to scan it better than the competition. Check it out: <a href="http://youtube.com/watch?v=M5lAT3gVzFc">http://youtube.com/watch?v=M5lAT3gVzFc</a>.
</p>
<p>Also Optiscan is now featured on the <a href="http://www.sparqcode.com/sparqreader/">readers page</a> by <a href="http://www.mskynet.com/">MSKYNET</a>, which has a rather nice <a href="http://www.mskynet.com/static/maestro">online QR code generator</a>. They &#8220;rebrand&#8221; QR codes as sparqcodes in the US.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.airsource.co.uk/index.php/2010/02/08/optiscan-developments/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Optiscan licensing</title>
		<link>http://blog.airsource.co.uk/index.php/2010/01/08/optiscan-licensing/</link>
		<comments>http://blog.airsource.co.uk/index.php/2010/01/08/optiscan-licensing/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 18:32:53 +0000</pubDate>
		<dc:creator>John</dc:creator>
		
		<category><![CDATA[News]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[iphone license software library optiscan optishare]]></category>

		<guid isPermaLink="false">http://blog.airsource.co.uk/?p=1452</guid>
		<description><![CDATA[ Optiscan has been successful with consumers on the Apple App Store, but it has also piqued the interest of businesses. If you are interested in licensing the image processing library of Optiscan for your own application, or in developing a white-label version of Optiscan for use on devices specific to your company, we want [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=304099767&amp;mt=8"><img class="attachment wp-att-1285 alignleft" src="http://blog.airsource.co.uk/wp-content/uploads/2009/03/optiscantransbak.png" alt="optiscantransbak" width="57" height="57" /></a> Optiscan has been successful with consumers on the Apple App Store, but it has also piqued the interest of businesses. If you are interested in licensing the image processing library of Optiscan for your own application, or in developing a white-label version of Optiscan for use on devices specific to your company, we want to hear from you.</p>
<p>We will only license the library for use on the App Store if the intended use does not directly compete with Optiscan. To request additional details or an evaluation package, send details of your intended use to <a href="mailto:optiscan-licensing@airsource.co.uk">optiscan-licensing@airsource.co.uk</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.airsource.co.uk/index.php/2010/01/08/optiscan-licensing/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
