<?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>Indigo &#187; English</title>
	<atom:link href="http://i.ndigo.com.br/category/english/feed/" rel="self" type="application/rss+xml" />
	<link>http://i.ndigo.com.br</link>
	<description>I.ndigo Website</description>
	<lastBuildDate>Fri, 03 Feb 2012 19:01:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>Mobile Year in Review</title>
		<link>http://i.ndigo.com.br/2012/01/mobile-year-in-review-2/</link>
		<comments>http://i.ndigo.com.br/2012/01/mobile-year-in-review-2/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 20:49:41 +0000</pubDate>
		<dc:creator>felipe.sabino</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[Brazil]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[I.ndigo]]></category>
		<category><![CDATA[indigo]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile device]]></category>
		<category><![CDATA[mobile internet]]></category>
		<category><![CDATA[São Paulo]]></category>

		<guid isPermaLink="false">http://i.ndigo.com.br/?p=667</guid>
		<description><![CDATA[2011 was a really intense year here at I.ndigo. More rewarding than launching 29 apps, was being able to witness the Brazilian market maturation and successfully accomplish worldwide recognized cases. We would like to thank all partners, agencies, clients, employees and our families for believing in our potential and helping us build this result that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://i.ndigo.com.br/wp-content/uploads/2012/01/infografico-aplicativos-indigo-eng.png"><img src="http://i.ndigo.com.br/wp-content/uploads/2012/01/infografico-aplicativos-indigo-eng-708x1024.png" alt="" title="infografico-aplicativos-indigo-eng" width="660" height="954" class="aligncenter size-large wp-image-673" /></a></p>
<p>2011 was a really intense year here at I.ndigo. More rewarding than launching 29 apps, was being able to witness the Brazilian market maturation and successfully accomplish worldwide recognized cases.</p>
<p>We would like to thank all partners, agencies, clients, employees and our families for believing in our potential and helping us build this result that we are pleased to share with you.</p>
<p>Bring on 2012!</p>
]]></content:encoded>
			<wfw:commentRss>http://i.ndigo.com.br/2012/01/mobile-year-in-review-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS Facial Recognition</title>
		<link>http://i.ndigo.com.br/2012/01/ios-facial-recognition/</link>
		<comments>http://i.ndigo.com.br/2012/01/ios-facial-recognition/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 23:54:20 +0000</pubDate>
		<dc:creator>Raphael Petegrosso</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[core image]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[facial recognition]]></category>
		<category><![CDATA[iOS 5 Tech Talk World Tour]]></category>
		<category><![CDATA[ios5]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://i.ndigo.com.br/?p=636</guid>
		<description><![CDATA[Core Image was one of the many interesting topics discussed at iOS Tech Talk Tour that took place in São Paulo on january 9th. It is a framework that was already available at the MacOS and now can also be used by iOS developers. It is important to notice that this framework is available only [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://i.ndigo.com.br/wp-content/uploads/2012/01/big-bang.jpeg" alt="iOS Facial Recognition Test" title="iOS Facial Recognition Test" width="660" height="371" class="aligncenter size-full wp-image-643" /></p>
<p>Core Image was one of the many interesting topics discussed at iOS Tech Talk Tour that took place in São Paulo on january 9th. It is a framework that was already available at the MacOS and now can also be used by iOS developers.</p>
<p>It is important to notice that this framework is available only after iOS 5.0, resulting in a use limited to the application requirements. However, according to <a href="http://news.cnet.com/8301-13579_3-57321295-37/ios-5-on-almost-40-percent-of-iphones/" target="_blank">CNET</a> the percentage of devices using iOS 5 in November, 2011 was already 40%, showing that apps developed to this version will shortly be available to the majority of users</p>
<p>Facial recognition is, by far, the most interesting of Core Image&#8217;s features, which will be detailed in this article. This new technique allow developers to think about new apps using this concept with a very low implementation cost.</p>
<p>We will show you how to implement the facial recognition straight from the device&#8217;s camera data stream. The source code is based on Apple&#8217;s SquareCam <a href="http://developer.apple.com/library/ios/#samplecode/SquareCam/Introduction/Intro.html" target="_blank">example project</a>.</p>
<div><span><br />
</span></div>
<div><strong>Camera Configuration</strong></div>
<div>
<p><span id="internal-source-marker_0.11296257469803095"> </span></p>
<p>The first step is to configure the camera using the AVFoundation Framework, available since iOS 4 release in a way we can directly read the device stream.</p>
<p>This configuration is made in order to use the following objects:</p>
<ul>
<li><strong><a href="http://developer.apple.com/library/IOs/#documentation/AVFoundation/Reference/AVCaptureSession_Class/Reference/Reference.html" target="_blank">AVCaptureSession</a></strong> &#8211; This object represents a session that coordinates the data flow from AV input devices to the output. In order to accomplish that, We add the input and output devices to this session object and start data flow using the startRunning messages (and stop it by using stopRunning).</li>
</ul>
</div>
<div>
<p><span id="internal-source-marker_0.11296257469803095"> </span></p>
<ul>
<li><strong><a href="http://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVCaptureDevice_Class/Reference/Reference.html" target="_blank">AVCaptureDevice</a></strong> &#8211; It is a physical device abstraction which provides an input for a AVCapureSession object. There is an object available for every input device type, for instance: there is one video input for iPhone 3G, but there are two of them for iPhone 4.</li>
</ul>
</div>
<div>
<p><span id="internal-source-marker_0.11296257469803095"> </span></p>
<ul>
<li><strong><a href="http://developer.apple.com/library/IOs/#documentation/AVFoundation/Reference/AVCaptureDeviceInput_Class/Reference/Reference.html" target="_blank">AVCaptureDeviceInput</a></strong> &#8211; It is an AVCaptureInput subclass used to add and input device into a session (AVCaptureSession).</li>
</ul>
</div>
<div>
<p><span id="internal-source-marker_0.11296257469803095"> </span></p>
<ul>
<li><strong><a href="http://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVCaptureOutput_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40009543" target="_blank">AVCaptureOutput</a></strong> &#8211; It is an abstract class used to find a session output (AVCaptureSession).</li>
</ul>
</div>
<div><span id="internal-source-marker_0.11296257469803095">The image below, from Apple&#8217;s <a href="http://developer.apple.com/library/IOs/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html#//apple_ref/doc/uid/TP40010188-CH5-SW2" target="_blank">AV Foundation Programming Guide</a> shows the interaction between the instances and their data flow:</span></div>
<div><span><br />
</span></div>
<div style="text-align: center;"><img class="aligncenter size-full wp-image-584" src="http://i.ndigo.com.br/wp-content/uploads/2012/01/captureDetail.jpg" alt="" width="553" height="330" /></div>
<div>
<p><span> </span></p>
<div><span id="internal-source-marker_0.11296257469803095">The folowing chunk of code was taken from SquareCam project. It shows how to configure the camera:</span></div>
<div><span><br />
</span></div>
</div>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #49f;">-</span> <span style="color: #49f;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #49f;">&#41;</span>setupAVCapture
<span style="color: #49f;">&#123;</span>
    AVCaptureSession <span style="color: #49f;">*</span>session <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>AVCaptureSession new<span style="color: #49f;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #49f;">&#40;</span><span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>UIDevice currentDevice<span style="color: #49f;">&#93;</span> userInterfaceIdiom<span style="color: #49f;">&#93;</span> <span style="color: #49f;">==</span> UIUserInterfaceIdiomPhone<span style="color: #49f;">&#41;</span>
        <span style="color: #49f;">&#91;</span>session setSessionPreset<span style="color: #49f;">:</span>AVCaptureSessionPreset640x480<span style="color: #49f;">&#93;</span>;
    <span style="color: #a61390;">else</span>
        <span style="color: #49f;">&#91;</span>session setSessionPreset<span style="color: #49f;">:</span>AVCaptureSessionPresetPhoto<span style="color: #49f;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Select a video device, make an input</span>
    AVCaptureDevice <span style="color: #49f;">*</span>device <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>AVCaptureDevice defaultDeviceWithMediaType<span style="color: #49f;">:</span>AVMediaTypeVideo<span style="color: #49f;">&#93;</span>;
    AVCaptureDeviceInput <span style="color: #49f;">*</span>deviceInput <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>AVCaptureDeviceInput deviceInputWithDevice<span style="color: #49f;">:</span>device error<span style="color: #49f;">:</span><span style="color: #a61390;">nil</span><span style="color: #49f;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #49f;">&#40;</span> <span style="color: #49f;">&#91;</span>session canAddInput<span style="color: #49f;">:</span>deviceInput<span style="color: #49f;">&#93;</span> <span style="color: #49f;">&#41;</span>
        <span style="color: #49f;">&#91;</span>session addInput<span style="color: #49f;">:</span>deviceInput<span style="color: #49f;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Make a video data output</span>
    videoDataOutput <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>AVCaptureVideoDataOutput alloc<span style="color: #49f;">&#93;</span> init<span style="color: #49f;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// we want BGRA, both CoreGraphics and OpenGL work well with 'BGRA'</span>
    <span style="color: #8844FF;">NSDictionary</span> <span style="color: #49f;">*</span>rgbOutputSettings <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #8844FF;">NSDictionary</span> dictionaryWithObject<span style="color: #49f;">:</span>
    <span style="color: #49f;">&#91;</span><span style="color: #8844FF;">NSNumber</span> numberWithInt<span style="color: #49f;">:</span>kCMPixelFormat_32BGRA<span style="color: #49f;">&#93;</span> forKey<span style="color: #49f;">:</span><span style="color: #49f;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #49f;">&#41;</span>kCVPixelBufferPixelFormatTypeKey<span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>videoDataOutput setVideoSettings<span style="color: #49f;">:</span>rgbOutputSettings<span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>videoDataOutput setAlwaysDiscardsLateVideoFrames<span style="color: #49f;">:</span><span style="color: #a61390;">YES</span><span style="color: #49f;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// discard if the data output queue is blocked (as we process the still image)</span>
&nbsp;
    videoDataOutputQueue <span style="color: #49f;">=</span> dispatch_queue_create<span style="color: #49f;">&#40;</span><span style="color: #bf1d1a;">&quot;VideoDataOutputQueue&quot;</span>, <span style="color: #a61390;">NULL</span><span style="color: #49f;">&#41;</span>;
    <span style="color: #49f;">&#91;</span>videoDataOutput setSampleBufferDelegate<span style="color: #49f;">:</span>self queue<span style="color: #49f;">:</span>videoDataOutputQueue<span style="color: #49f;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">if</span> <span style="color: #49f;">&#40;</span> <span style="color: #49f;">&#91;</span>session canAddOutput<span style="color: #49f;">:</span>videoDataOutput<span style="color: #49f;">&#93;</span> <span style="color: #49f;">&#41;</span>
        <span style="color: #49f;">&#91;</span>session addOutput<span style="color: #49f;">:</span>videoDataOutput<span style="color: #49f;">&#93;</span>;
&nbsp;
    previewLayer <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>AVCaptureVideoPreviewLayer alloc<span style="color: #49f;">&#93;</span> initWithSession<span style="color: #49f;">:</span>session<span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>previewLayer setBackgroundColor<span style="color: #49f;">:</span><span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>UIColor blackColor<span style="color: #49f;">&#93;</span> CGColor<span style="color: #49f;">&#93;</span><span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>previewLayer setVideoGravity<span style="color: #49f;">:</span>AVLayerVideoGravityResizeAspect<span style="color: #49f;">&#93;</span>;
    CALayer <span style="color: #49f;">*</span>rootLayer <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>previewView layer<span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>rootLayer setMasksToBounds<span style="color: #49f;">:</span><span style="color: #a61390;">YES</span><span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>previewLayer setFrame<span style="color: #49f;">:</span><span style="color: #49f;">&#91;</span>rootLayer bounds<span style="color: #49f;">&#93;</span><span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>rootLayer addSublayer<span style="color: #49f;">:</span>previewLayer<span style="color: #49f;">&#93;</span>;
    <span style="color: #49f;">&#91;</span>session startRunning<span style="color: #49f;">&#93;</span>;
&nbsp;
<span style="color: #49f;">&#125;</span></pre></div></div>

<div><span><br />
</span></div>
<p><strong>Identifying a face with a CIDetector</strong></p>
<p>According to <a href="http://developer.apple.com/library/ios/#documentation/CoreImage/Reference/CIDetector_Ref/Reference/Reference.html" target="_blank">CIDetector&#8217;s Class Reference</a> the CIDetector object (available since iOS 5 inside CoreImage.framework) uses image processing to find &#8220;features&#8221; inside an image.</p>
<p>So, the next step is to identify the face in our video data stream is to configure a CIDetector. We can create an instance of the object by instantiating:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #8844FF;">NSDictionary</span> <span style="color: #49f;">*</span>detectorOptions <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span><span style="color: #8844FF;">NSDictionary</span> alloc<span style="color: #49f;">&#93;</span> initWithObjectsAndKeys<span style="color: #49f;">:</span>CIDetectorAccuracyLow, CIDetectorAccuracy, <span style="color: #a61390;">nil</span><span style="color: #49f;">&#93;</span>;
&nbsp;
faceDetector <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>CIDetector detectorOfType<span style="color: #49f;">:</span>CIDetectorTypeFace context<span style="color: #49f;">:</span><span style="color: #a61390;">nil</span> options<span style="color: #49f;">:</span>detectorOptions<span style="color: #49f;">&#93;</span> retain<span style="color: #49f;">&#93;</span>;</pre></div></div>

<p>When we previously initialized the camera, we configured our controller to act as a the video output stream&#8217;s delegate (<em>videoDataOutput</em>) at the line:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #49f;">&#91;</span>videoDataOutput setSampleBufferDelegate<span style="color: #49f;">:</span>self queue<span style="color: #49f;">:</span>videoDataOutputQueue<span style="color: #49f;">&#93;</span>;</pre></div></div>

<p>We can now implement the following method to read the video data stream:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #49f;">-</span> <span style="color: #49f;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #49f;">&#41;</span>captureOutput<span style="color: #49f;">:</span><span style="color: #49f;">&#40;</span>AVCaptureOutput <span style="color: #49f;">*</span><span style="color: #49f;">&#41;</span>captureOutput didOutputSampleBuffer<span style="color: #49f;">:</span><span style="color: #49f;">&#40;</span>CMSampleBufferRef<span style="color: #49f;">&#41;</span>sampleBuffer fromConnection<span style="color: #49f;">:</span><span style="color: #49f;">&#40;</span>AVCaptureConnection <span style="color: #49f;">*</span><span style="color: #49f;">&#41;</span>connection
<span style="color: #49f;">&#123;</span>
…
<span style="color: #49f;">&#125;</span></pre></div></div>

<p>Finally, with a CIDetector&#8217;s instance and the video data stream, We can identify our face.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// got an image</span>
CVPixelBufferRef pixelBuffer <span style="color: #49f;">=</span> CMSampleBufferGetImageBuffer<span style="color: #49f;">&#40;</span>sampleBuffer<span style="color: #49f;">&#41;</span>;
CFDictionaryRef attachments <span style="color: #49f;">=</span> CMCopyDictionaryOfAttachments<span style="color: #49f;">&#40;</span>kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate<span style="color: #49f;">&#41;</span>;
CIImage <span style="color: #49f;">*</span>ciImage <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>CIImage alloc<span style="color: #49f;">&#93;</span> initWithCVPixelBuffer<span style="color: #49f;">:</span>pixelBuffer options<span style="color: #49f;">:</span><span style="color: #49f;">&#40;</span><span style="color: #8844FF;">NSDictionary</span> <span style="color: #49f;">*</span><span style="color: #49f;">&#41;</span>attachments<span style="color: #49f;">&#93;</span>;
<span style="color: #a61390;">if</span> <span style="color: #49f;">&#40;</span>attachments<span style="color: #49f;">&#41;</span>
    CFRelease<span style="color: #49f;">&#40;</span>attachments<span style="color: #49f;">&#41;</span>;
<span style="color: #8844FF;">NSDictionary</span> <span style="color: #49f;">*</span>imageOptions <span style="color: #49f;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// '6' identifies device on vertical position</span>
imageOptions <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #8844FF;">NSDictionary</span> dictionaryWithObject<span style="color: #49f;">:</span><span style="color: #49f;">&#91;</span><span style="color: #8844FF;">NSNumber</span> numberWithInt<span style="color: #49f;">:</span><span style="color: #2400d9;">6</span><span style="color: #49f;">&#93;</span> forKey<span style="color: #49f;">:</span>CIDetectorImageOrientation<span style="color: #49f;">&#93;</span>;
<span style="color: #8844FF;">NSArray</span> <span style="color: #49f;">*</span>features <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>faceDetector featuresInImage<span style="color: #49f;">:</span>ciImage options<span style="color: #49f;">:</span>imageOptions<span style="color: #49f;">&#93;</span>;
<span style="color: #49f;">&#91;</span>ciImage release<span style="color: #49f;">&#93;</span>;</pre></div></div>

<p>The array features have each element as an instance of a CIFaceFeature, which identify a new face found in the video and allow us to retrieve several information from it.</p>
<div><span><br />
</span></div>
<p><strong>Image&#8217;s CIFaceFeature</strong></p>
<p>A <a href="http://developer.apple.com/library/mac/#documentation/CoreImage/Reference/CIFaceFeature/Reference/Reference.html" target="_blank">CIFaceFeature</a> object properties describes the face found in a image. These properties are:</p>
<p><strong>hasLeftEyePosition</strong><br />
<strong>hasRightEyePosition</strong><br />
<strong>hasMouthPosition</strong><br />
<strong>leftEyePosition</strong><br />
<strong>rightEyePosition</strong><br />
<strong>mouthPosition</strong></p>
<p>Besides that, due to its <a href="http://developer.apple.com/library/mac/#documentation/CoreImage/Reference/CIFeature_Ref/Reference/Reference.html#//apple_ref/occ/cl/CIFeature" target="_blank">CIFeature</a> inheritance, it also has the following properties:</p>
<p><strong>bounds</strong> &#8211; The rectangle that the feature was found inside<br />
<strong>type</strong> &#8211; The feature type</p>
<p>By using this information several actions can be taken, such as adding new visual elements on top of the face which was found in the image.</p>
<div><span><br />
</span></div>
<p><strong>CIDetectorAccuracyLow Vs CIDetectorAccuracyHigh</strong></p>
<p>When we created our CIDetector, we provided the CIDetectorAccuracyLow parameter:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #8844FF;">NSDictionary</span> <span style="color: #49f;">*</span>detectorOptions <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span><span style="color: #8844FF;">NSDictionary</span> alloc<span style="color: #49f;">&#93;</span> initWithObjectsAndKeys<span style="color: #49f;">:</span>CIDetectorAccuracyLow, CIDetectorAccuracy, <span style="color: #a61390;">nil</span><span style="color: #49f;">&#93;</span>;</pre></div></div>

<p>The reason we did that is because we are trying to read from a video stream, and using this option results in a faster analysis for each video frame, however, with a higher chance of not detecting any face at all.</p>
<p>In general, the CIDetectorAccuracyHigh option is used to analyse a single picture, resulting in a slower processing time, but with a higher face detection rate.</p>
<p>As you can notice, iOS 5 made it extremely easy to integrate facial recognition, which allows us to think again in several features that would be impracticable to implement in a project before. That said, we still have to be aware of the project requirements, since not all the users updates their operating system to the latest iOS version.</p>
<p>This post is also available in portuguese <a href="http://i.ndigo.com.br/2012/01/reconhecimento-de-faces-no-ios/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://i.ndigo.com.br/2012/01/ios-facial-recognition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Core Data over SQLite Performance Tests &#8211; Part 3</title>
		<link>http://i.ndigo.com.br/2010/08/core-data-over-sqlite-performance-tests-part-3/</link>
		<comments>http://i.ndigo.com.br/2010/08/core-data-over-sqlite-performance-tests-part-3/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 15:26:40 +0000</pubDate>
		<dc:creator>Raphael Petegrosso</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://i.ndigo.com.br/?p=228</guid>
		<description><![CDATA[Following the last post, Core Data over SQLite Performance Tests &#8211; Part 2, when we began performance tests with Core Data, now we continue with the results of this analysis. As we defined before, this test will show the performance of 4 situations (see details on the previous post): Insert without join tables; Inserts with [...]]]></description>
			<content:encoded><![CDATA[<p>Following the last post, <a title="Core Data over SQLite Performance Tests - Part 2" href="http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-2">Core Data over SQLite Performance Tests &#8211; Part 2</a>, when we began performance tests with Core Data, now we continue with the results of this analysis.</p>
<p>As we defined before, this test will show the performance of 4 situations (see details on the previous post):</p>
<ol style="margin-left: 25px;">
<li>Insert without join  tables;</li>
<li>Inserts with tables;</li>
<li>Select without join tables;</li>
<li>Select with join tables.</li>
</ol>
<p>The previous post showed the first 2 situations. This time we will cover the last 2 (selects).</p>
<h3><strong>1. Select without join tables</strong></h3>
<p>This test tries to execute selects without joins in 2 ways:</p>
<ul>
<li>Fetch by object&#8217;s attributes;</li>
<li>Fetch by identifier.</li>
</ul>
<p>In each case, we see how the time to execute the select varies with the number of registries of the table (from 1 to 10000):</p>
<p><strong>a) Fetch by object&#8217;s attributes</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/08/image8.png" alt="" title="" width="618" class="alignnone size-full wp-image-242" /></p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.007469 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.259504 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.049227 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">492.3 s</td>
</tr>
</tbody>
</table>
<p>As we can see on the chart, when fetching by an attribute that is not indexed the time needed to execute the select varies almost linearly with the number of registries of the table. So, it is easy to think on how the performance of your table is getting worst with the time.</p>
<p><strong>b) Fetch by identifier</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/08/image1.png" alt="" title="" width="618" class="alignnone size-full wp-image-237" /></p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.000070 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.004420 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.000086 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">0.8597 s</td>
</tr>
</tbody>
</table>
<p>This case shown us that fetching by the identifier (indexed), the time to fetch almost do not change with the number of registries, once the average time to fetch was almost equal the min time.</p>
<p><strong>Conclusion</strong></p>
<p>This tests resulted on the following table:</p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;"><strong>Test</strong></td>
<td style="width: 120px; text-align: center;"><strong>Average Time per Select</strong></td>
<td style="width: 120px; text-align: center;"><strong>Total Time</strong></td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">Fetch by object&#8217;s attributes</td>
<td style="width: 120px; text-align: center;">t1 or 0.049227 s</td>
<td style="width: 120px; text-align: center;">t2 or 492.3 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">Fetch by identifier</td>
<td style="width: 120px; text-align: center;">0.0017 x t1 or 0.000086 s</td>
<td style="width: 120px; text-align: center;">0.0017 x t2 or 0.8597 s</td>
</tr>
</tbody>
</table>
<p>As we can see, for simple selects (without joins) when possible we should use identifiers to fetch, but, if we need to fetch by an attribute, it&#8217;s not hard to think about the performance, once it increases linearly with the size of the table.</p>
<h3><strong>2. Selects with join tables</strong></h3>
<p>This test shows how the time to execute a select increases as the number of join tables (in each select) and number of rows increases. The number of joins varies from 0 to 4.</p>
<p><strong>a) Joins quantity: 0</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/08/image3.png" alt="" title="" width="618" class="alignnone size-full wp-image-239" /></p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.010763 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.405039 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.071537 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">7.15 s</td>
</tr>
</tbody>
</table>
<p>This test has no joins, so the results is the same from the previous test when fetching by an attribute.</p>
<p><strong>b) Joins quantity: 1</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/08/image2.png" alt="" title="" width="618" class="alignnone size-full wp-image-238" /></p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.012153 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.632435 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.299673 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">29.98 s</td>
</tr>
</tbody>
</table>
<p>As might be expected, with 1 join the average time to a insert was much worst, about 4.27 times greater than with 0 joins.</p>
<p><strong>c) Joins quantity: 2</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/08/image4.png" alt="" title="" width="618" class="alignnone size-full wp-image-240" /></p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.021038 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.633293 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.29986 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">29.96 s</td>
</tr>
</tbody>
</table>
<p>With 2 joins we needed almost the same time to process the select, as expected, once the fetching engine has already entered on the process&#8217; join step, what is not needed with 0 joins.</p>
<p><strong>d) Joins quantity: 3</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/08/image0.png" alt="" title="" width="618" class="alignnone size-full wp-image-236" /></p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.025723 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.621014 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.303619 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">30.36 s</td>
</tr>
</tbody>
</table>
<p>With 3 joins the average time was slightly worst again, as we might expect.</p>
<p><strong>e) Joins quantity: 4</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/08/image6.png" alt="" title="" width="618" class="alignnone size-full wp-image-241" /></p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.027883 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.64675 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.316077 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">31.61 s</td>
</tr>
</tbody>
</table>
<p>Again, with 4 joins the average time was slightly worst, as we might expect.</p>
<p><strong>Conclusion</strong></p>
<p>The following table results from the tests:</p>
<table style="margin-left: auto; margin-right: auto; margin-top: 50px; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;"><strong>Test</strong></td>
<td style="width: 120px; text-align: center;"><strong>Average Time</strong></td>
<td style="width: 120px; text-align: center;"><strong>Total Time</strong></td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">0 joins</td>
<td style="width: 120px; text-align: center;">0.071537 s</td>
<td style="width: 120px; text-align: center;">7.15 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">1 join</td>
<td style="width: 120px; text-align: center;">0.299673 s</td>
<td style="width: 120px; text-align: center;">29.98 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">2 joins</td>
<td style="width: 120px; text-align: center;">0.29986 s</td>
<td style="width: 120px; text-align: center;">29.96 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">3 joins</td>
<td style="width: 120px; text-align: center;">0.303619 s</td>
<td style="width: 120px; text-align: center;">30.36 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">4 joins</td>
<td style="width: 120px; text-align: center;">0.316077 s</td>
<td style="width: 120px; text-align: center;">31.61 s</td>
</tr>
</tbody>
</table>
<p>As we can see, we have a great variance from 0 to 1 join, but a small variance as the number of joins increases, due the way the select engine works.</p>
<p>This post, and the previous one, showed performance tests for Core Data that bring us information to analyse when use it in a project and what impact we would have when using it.</p>
<p>The next posts will present our analysis over the <a href="http://bitbucket.org/magicalpanda/activerecord-for-core-data">Magical Panda Active Record</a> framework. We expect you are anxious as we are. Stay tuned!</p>
<p>This post is also available in Portuguese: <a href="http://i.ndigo.com.br/2010/08/testes-de-performance-do-core-data-sobre-sqlite-parte-3">Testes de performance do Core Data sobre SQLite – Parte 3</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://i.ndigo.com.br/2010/08/core-data-over-sqlite-performance-tests-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocos2d for iPhone 0.99.4 &#8211; OpenGL ES Transparent Layer</title>
		<link>http://i.ndigo.com.br/2010/07/cocos2d-for-iphone-0-99-4-opengl-es-transparent-layer/</link>
		<comments>http://i.ndigo.com.br/2010/07/cocos2d-for-iphone-0-99-4-opengl-es-transparent-layer/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 18:07:25 +0000</pubDate>
		<dc:creator>Raphael Petegrosso</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Cocos2d for iPhone]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[transparency]]></category>

		<guid isPermaLink="false">http://i.ndigo.com.br/?p=173</guid>
		<description><![CDATA[Overview According to Cocos2d website, Cocos2d for iPhone is a framework for building 2D games, demos, and other graphical/interactive applications. It is based on the cocos2d design: it uses the same concepts, but instead of using Python it uses Objective-C. Their website says that Cocos2d for iPhone is: Easy to use: it uses a familiar [...]]]></description>
			<content:encoded><![CDATA[<h3><strong>Overview</strong></h3>
<p>According to <a href="http://www.cocos2d-iphone.org/about">Cocos2d website</a>,  <strong>Cocos2d for iPhone</strong> is a framework for building 2D games, demos, and other graphical/interactive applications. It is based on the cocos2d design: it uses the same concepts, but instead of using Python it uses Objective-C.</p>
<p>Their website says that <strong>Cocos2d for iPhone</strong> is:</p>
<ul>
<li style="list-style: disc; margin-left: 30px;">Easy to use: it uses a familiar API, and comes with lots of examples</li>
<li style="list-style: disc; margin-left: 30px;">Fast: it uses the OpenGL ES best practices and optimized data structures</li>
<li style="list-style: disc; margin-left: 30px;">Flexible: it is easy to extend, easy to integrate with 3rd party libraries</li>
<li style="list-style: disc; margin-left: 30px;">Free: is open source, compatible both with closed and open source games</li>
<li style="list-style: disc; margin-left: 30px;">Community supported: cocos2d has an active, big and friendly community (<a href="http://www.cocos2d-iphone.org/forum">forum</a>, IRC)</li>
<li style="list-style: disc; margin-left: 30px;">AppStore approved: More than 550 AppStore games already use it, including many best seller games.</li>
</ul>
<p>Cocos2d comes with an API that makes it simple to create an OpenGL ES based project, even if you are not an expert with OpenGL programming, once it has a nice encapsulation of some functionalities that are mostly used.</p>
<p>One negative point of using this kind of tool is that sometimes you get lost when it automates something that you didn&#8217;t want to be done for you. When trying to create a transparent OpenGL ES Layer with Cocos2d we saw that lot of people had this problem so we resolved to post about it.</p>
<h3><strong>Creating a Transparent OpenGL ES Layer with Cocos2d</strong></h3>
<p>Creating a transparent OpenGL ES Layer with Cocos2d v 0.99.4 was not an easy job, once its template code use a Macro to initialize a set of variables.</p>
<p>If you see the <em>CC_DIRECTOR_INIT()</em> macro, located on the <em>ccMacros.h file</em>, we have the following:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define CC_DIRECTOR_INIT()                                                        \</span>
<span style="color: #a61390;">do</span> <span style="color: #49f;">&#123;</span>                                                                              \
                                                                                  \
    window <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>UIWindow alloc<span style="color: #49f;">&#93;</span> initWithFrame<span style="color: #49f;">:</span><span style="color: #49f;">&#91;</span><span style="color: #49f;">&#91;</span>UIScreen mainScreen<span style="color: #49f;">&#93;</span> bounds<span style="color: #49f;">&#93;</span><span style="color: #49f;">&#93;</span>;     \
                                                                                  \
    <span style="color: #a61390;">if</span><span style="color: #49f;">&#40;</span> <span style="color: #49f;">!</span> <span style="color: #49f;">&#91;</span>CCDirector setDirectorType<span style="color: #49f;">:</span>kCCDirectorTypeDisplayLink<span style="color: #49f;">&#93;</span> <span style="color: #49f;">&#41;</span>               \
        <span style="color: #49f;">&#91;</span>CCDirector setDirectorType<span style="color: #49f;">:</span>kCCDirectorTypeNSTimer<span style="color: #49f;">&#93;</span>;                      \
                                                                                  \
     CCDirector <span style="color: #49f;">*</span>__director <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>CCDirector sharedDirector<span style="color: #49f;">&#93;</span>;                        \
     <span style="color: #49f;">&#91;</span>__director setDeviceOrientation<span style="color: #49f;">:</span>kCCDeviceOrientationPortrait<span style="color: #49f;">&#93;</span>;              \
     <span style="color: #49f;">&#91;</span>__director setDisplayFPS<span style="color: #49f;">:</span><span style="color: #a61390;">NO</span><span style="color: #49f;">&#93;</span>;                                               \
     <span style="color: #49f;">&#91;</span>__director setAnimationInterval<span style="color: #49f;">:</span><span style="color: #2400d9;">1.0</span><span style="color: #49f;">/</span><span style="color: #2400d9;">60</span><span style="color: #49f;">&#93;</span>;                                    \
                                                                                  \
     EAGLView <span style="color: #49f;">*</span>__glView <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>EAGLView viewWithFrame<span style="color: #49f;">:</span><span style="color: #49f;">&#91;</span>window bounds<span style="color: #49f;">&#93;</span>                 \
                                      pixelFormat<span style="color: #49f;">:</span>kEAGLColorFormatRGB565          \
                                      depthFormat<span style="color: #49f;">:</span><span style="color: #2400d9;">0</span>                               \
                               preserveBackbuffer<span style="color: #49f;">:</span><span style="color: #a61390;">NO</span><span style="color: #49f;">&#93;</span>;                            \
                                                                                  \
     <span style="color: #49f;">&#91;</span>__director setOpenGLView<span style="color: #49f;">:</span>__glView<span style="color: #49f;">&#93;</span>;                                         \
                                                                                  \
     <span style="color: #49f;">&#91;</span>window addSubview<span style="color: #49f;">:</span>__glView<span style="color: #49f;">&#93;</span>;                                                \
     <span style="color: #49f;">&#91;</span>window makeKeyAndVisible<span style="color: #49f;">&#93;</span>;                                                  \
                                                                                  \
 <span style="color: #49f;">&#125;</span> <span style="color: #a61390;">while</span><span style="color: #49f;">&#40;</span><span style="color: #2400d9;">0</span><span style="color: #49f;">&#41;</span>;                                                                      \</pre></div></div>

<p>As we can see, this macro creates an <em>EAGLView</em> that has <em>pixelFormat</em> of type <em>kEAGLColorFormatRGB565</em>, which is 16 bits. In order to have transparency enabled in our <em>EAGLView</em> we need to create it using <em>kEAGLColorFormatRGBA8</em> format, which is 32 bits.</p>
<p>We have lot of ways to solve it, such as changing that macro or initializing everything by ourselves. The important thing is to make sure to change the line:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">EAGLView <span style="color: #49f;">*</span>__glView <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>EAGLView viewWithFrame<span style="color: #49f;">:</span><span style="color: #49f;">&#91;</span>window bounds<span style="color: #49f;">&#93;</span>                      \
                                 pixelFormat<span style="color: #49f;">:</span>kEAGLColorFormatRGB565               \
                                 depthFormat<span style="color: #49f;">:</span><span style="color: #2400d9;">0</span>                                    \
                          preserveBackbuffer<span style="color: #49f;">:</span><span style="color: #a61390;">NO</span><span style="color: #49f;">&#93;</span>;                                 \</pre></div></div>

<p>to</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">EAGLView <span style="color: #49f;">*</span>__glView <span style="color: #49f;">=</span> <span style="color: #49f;">&#91;</span>EAGLView viewWithFrame<span style="color: #49f;">:</span><span style="color: #49f;">&#91;</span>window bounds<span style="color: #49f;">&#93;</span>                      \
                                 pixelFormat<span style="color: #49f;">:</span>kEAGLColorFormatRGBA8                \
                                 depthFormat<span style="color: #49f;">:</span><span style="color: #2400d9;">0</span>                                    \
                          preserveBackbuffer<span style="color: #49f;">:</span><span style="color: #a61390;">NO</span><span style="color: #49f;">&#93;</span>;                                 \</pre></div></div>

<p>So, we will have a transparent layer when using:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">glClearColor<span style="color: #49f;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span><span style="color: #49f;">&#41;</span>;</pre></div></div>

<p>In the above line, the last parameter indicates the opacity.<br />
(<a href="http://www.khronos.org/opengles/sdk/1.1/docs/man/">http://www.khronos.org/opengles/sdk/1.1/docs/man/</a>).</p>
<p>So that&#8217;s it! We hope you enjoy <strong>Cocos2d for iPhone</strong> and this tip helps you!</p>
<p>This post is also available in Portuguese: <a title="Cocos2d for iPhone 0.99.4 - Camada Transparente com OpenGL ES" href="http://i.ndigo.com.br/2010/07/cocos2d-for-iphone-0-99-4-camada-transparente-com-opengl-es">Cocos2d for iPhone 0.99.4 &#8211; Camada Transparente com OpenGL ES</a></p>
]]></content:encoded>
			<wfw:commentRss>http://i.ndigo.com.br/2010/07/cocos2d-for-iphone-0-99-4-opengl-es-transparent-layer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Core Data over SQLite Performance Tests &#8211; Part 2</title>
		<link>http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-2/</link>
		<comments>http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-2/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 22:59:40 +0000</pubDate>
		<dc:creator>Raphael Petegrosso</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://i.ndigo.com.br/?p=119</guid>
		<description><![CDATA[Following the last post, Core Data over SQLite Performance Tests &#8211; Part 1, when we introduced Core Data and defined the environment in which tests will run on, now we are going to start presenting you the results of this analysis. As we defined before, this test will show the performance of 4 situations (see [...]]]></description>
			<content:encoded><![CDATA[<p>Following the last post, <a title="Core Data over SQLite Performance Tests - Part 1" href="http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-1">Core Data over SQLite Performance Tests &#8211; Part 1</a>, when we introduced Core Data and defined the environment in which tests will run on, now we are going to start presenting you the results of this analysis.</p>
<p>As we defined before, this test will show the performance of 4 situations (see details on the previous post):</p>
<ol style="margin-left: 25px;">
<li>Insert without join  tables;</li>
<li>Inserts with tables;</li>
<li>Select without join tables;</li>
<li>Select with join tables.</li>
</ol>
<p>This post will cover the first 2 situations (inserts).</p>
<h3><strong>1. Inserts without join tables</strong></h3>
<p>This test tries to execute 10000 inserts on 5 different ways:</p>
<ul>
<li>Batch size: 1; Times: 10000;</li>
<li>Batch size: 10; Times: 1000;</li>
<li>Batch size: 100; Times: 100;</li>
<li>Batch size: 1000; Times: 10;</li>
<li>Batch size: 10000; Times: 1.</li>
</ul>
<p>The results were the following:</p>
<p><strong>a) Batch size: 1; Times: 10000</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.001.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.037017 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.571604 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.047213 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">417.3 s</td>
</tr>
</tbody>
</table>
<p>As we can see on the chart, we have a slight variance between the inserts. Although the maximum chart value was 0.57 seconds, the average (0.047s) was much more close to the minimum value (0.037s). Also, we can see that the time needed to a insert does not changes significantly while the table increases.</p>
<p><strong>b) Batch size: 10; Times: 1000</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.002.png" alt="" title="" width="620" height="179" class="alignnone size-full wp-image-139" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.051545 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">1.592167 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.077328 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">77.3 s</td>
</tr>
</tbody>
</table>
<p>This case shown us that, increasing the batch size to 10 we need, on average, about 1.64x more time to execute this batch. So, we can imagine that is much better to execute a big batch than lot of small batches. The test shown that to insert 10000 registries with batch size of 10 we needed 77.3 s, while with batch size of 1, to insert 10000 registries we needed 417.3 s.</p>
<p><strong>c) Batch size: 100; Times: 100</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.003.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.221817 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.733436 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.276504 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">27.7 s</td>
</tr>
</tbody>
</table>
<p>This case shown that increasing again the batch size, now to 100, we needed about 3.6x more time per batch than we needed with batch size of 10. So, we can deduce that the time per batch does not increases linearly as the batch size increases. But again, the total time to execute 10000 inserts was lower (27 s against 77 s).</p>
<p><strong>d) Batch size: 1000; Times: 10</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.004.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">2.341496 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">2.895445 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">2.522845 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">25.2 s</td>
</tr>
</tbody>
</table>
<p>Again, the same happened. As we increases the batch size to 1000 we needed 9.1x more time than we needed with batch size of 100. The total time was better than the previous, but is almost the same (25 s against 27 s).</p>
<p><strong>e) Batch size: 10000; Times: 1 (10 repetitions with empty database)</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.005.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">19.171194 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">24.020913 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">22.2 s</td>
</tr>
</tbody>
</table>
<p>This time, increasing the batch size to 10000 we needed 8x more time than we needed with batch size of 1000, while we could imagine we would need more than 9.1. So, we needed only 22 s to execute 10000 inserts.</p>
<p><strong>Conclusion</strong></p>
<p>This tests resulted on the following table:</p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;"><strong>Test</strong></td>
<td style="width: 120px; text-align: center;"><strong>Average Time per Batch</strong></td>
<td style="width: 120px; text-align: center;"><strong>Total Time</strong></td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">a</td>
<td style="width: 120px; text-align: center;">t1 or 0.047213 s</td>
<td style="width: 120px; text-align: center;">t2 or 417.3 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">b</td>
<td style="width: 120px; text-align: center;">1.83 x t1 or 0.077328 s</td>
<td style="width: 120px; text-align: center;">t2/5.40 or 77.3 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">c</td>
<td style="width: 120px; text-align: center;">5.86 x t1 or 0.276504 s</td>
<td style="width: 120px; text-align: center;">t2/0.066 or 27.7 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">d</td>
<td style="width: 120px; text-align: center;">53.68 x t1 or 2.523 s</td>
<td style="width: 120px; text-align: center;">t2/0.060 or 25.2 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">e</td>
<td style="width: 120px; text-align: center;">470.34 x t1 or 22.2 s</td>
<td style="width: 120px; text-align: center;">t2/0.053 or 22.2 s</td>
</tr>
</tbody>
</table>
<p>As we can see, for simple inserts (without joins) as we increases the batch size, the time needed to to execute that batch is greater, but, the total time is lower. So, with Core Data, when possible we should save data to database using batches.</p>
<h3><strong>2. Inserts with join tables</strong></h3>
<p>This test shows how the time to execute a insert increases as the number of join tables (in each insert) and number of rows increases. The number of joins varies from 0 to 3.</p>
<p><strong>a) Joins quantity: 0</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.006.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.053622 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.626013 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.068631 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">137.3 s</td>
</tr>
</tbody>
</table>
<p>This test has no joins, so the results is the same from the previous test.</p>
<p><strong>b) Joins quantity: 1</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.007.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.617910 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.353416 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.080156 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">160.3 s</td>
</tr>
</tbody>
</table>
<p>As might be expected, with 1 join the average time to a insert was 1.17 times greater than with 0 joins.</p>
<p><strong>c) Joins quantity: 2</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.008.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.078214 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.559592 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.109143 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">218.3 s</td>
</tr>
</tbody>
</table>
<p>With 2 joins we needed even more time to process an insert: 1.37 times more than with 1 join. Also, we can see that it seems that, as the database increases, we need more time to do inserts that was join tables.</p>
<p><strong>d) Joins quantity: 3</strong></p>
<p><img src="http://i.ndigo.com.br/wp-content/uploads/2010/07/index.009.png" alt="" title="" width="618" height="194" class="alignnone size-full wp-image-124" /></p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">min</td>
<td style="width: 120px; text-align: center;">0.093524 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">max</td>
<td style="width: 120px; text-align: center;">0.650233 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">average</td>
<td style="width: 120px; text-align: center;">0.135843 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">total</td>
<td style="width: 120px; text-align: center;">271.7 s</td>
</tr>
</tbody>
</table>
<p>With 3 joins the average time was worst again: 1.244 times more than with 2 joins.</p>
<p><strong>Conclusion</strong></p>
<p>The following table results from the tests:</p>
<table style="margin-left: auto; margin-right: auto; height: 47px; margin-top: 50px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;"><strong>Test</strong></td>
<td style="width: 120px; text-align: center;"><strong>Average Time</strong></td>
<td style="width: 120px; text-align: center;"><strong>Total Time</strong></td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">a</td>
<td style="width: 120px; text-align: center;">t1 or 0.068631 s</td>
<td style="width: 120px; text-align: center;">t2 or 137.3 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">b</td>
<td style="width: 120px; text-align: center;">1.17 x t1 or 0.080156 s</td>
<td style="width: 120px; text-align: center;">1.17 x t2 or 160.3 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">c</td>
<td style="width: 120px; text-align: center;">1.59 x t1 or 0.109143 s</td>
<td style="width: 120px; text-align: center;">1.59 x t2 or 218.3 s</td>
</tr>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">d</td>
<td style="width: 120px; text-align: center;">1.99 x t1 or 0.135843 s</td>
<td style="width: 120px; text-align: center;">1.99 x t2 or 271.7 s</td>
</tr>
</tbody>
</table>
<p>As we can see, as the number of joins increases in a insert the time required to process it also increases. This increasing number is not linear. </p>
<p>The next post will present our results and conclusions for selects on Core Data, stay tuned!</p>
<p>This post is also available in Portuguese: <a title="Testes de performance do Core Data sobre SQLite - Parte 2" href="http://i.ndigo.com.br/2010/07/testes-de-performance-do-core-data-sobre-sqlite-parte-2">Testes de performance do Core Data sobre SQLite &#8211; Parte 2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Core Data over SQLite Performance Tests &#8211; Part 1</title>
		<link>http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-1/</link>
		<comments>http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-1/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 21:45:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://i.ndigo.com.br/?p=77</guid>
		<description><![CDATA[Following the last post, iPhone Persistent Store Overview, I.ndigo begins the performance experiments series, on iPhone persistent store alternatives, with Core Data, Apple&#8217;s official framework for this purpose. Introduction Core Data for iPhone was introduced in the 3.0 version of the SDK, although it was previously available for Mac OSX. The framework implements an Object [...]]]></description>
			<content:encoded><![CDATA[<p>Following the last post, <a title="iPhone Persistent Store Overview" href="http://i.ndigo.com.br/2010/07/iphone-persistent-store-overview/">iPhone Persistent Store Overview</a>, I.ndigo begins the performance   experiments series, on iPhone persistent store alternatives, with Core   Data, Apple&#8217;s official framework for this purpose.</p>
<h3><strong>Introduction</strong></h3>
<p>Core Data for iPhone was  introduced in the 3.0 version of the SDK,  although it was previously  available for Mac OSX. The framework  implements an Object Graph Manager,  giving applications the ability to  manage data, including inserting new  records, applying changes, undoing  and redoing them and also the  ability persist them.<br />
It provides a  high level API that abstracts  all data management rules, as unique  identifiers, model consistency and  data validation, insertion, update  and deletion, as well as data store  creation and operation.</p>
<p>Data  modeling  abstraction is achieved by Xcode&#8217;s integrated graphical data  modeling  tool, where  the developer must describe an  entity-relationship diagram  representing and the system’s data. Xcode  then generates all the classes  and files needed to manage and  optionally persist the data.</p>
<p>The persistent store  layer  abstracts the database and file store to the developer. The iPhone  SDK  provides SQLite and a binary format and the Mac OSX SDK also  provides  XML persistence. Either way, the implementation details stay  apart from  the developer, who should only care about objects and its  properties.</p>
<h3><strong>Core  Data Architecture</strong></h3>
<p>To implement the  previously described  functionality, a flexible and solid architecture  was created, as seen  in the following diagram:</p>
<div id="attachment_78" class="wp-caption aligncenter" style="width: 497px"><a href="http://i.ndigo.com.br/wp-content/uploads/2010/07/core_data_architecture.png"><img class="size-full wp-image-78" title="core_data_architecture" src="http://i.ndigo.com.br/wp-content/uploads/2010/07/core_data_architecture.png" alt="" width="487" height="506" /></a><p class="wp-caption-text">Core Data Architecture</p></div>
<ul>
<li><em>NSManagedObjectModel:</em> Created on run-time,  based on the project&#8217;s data model, which is designed by the developer in  the integrated graphical tool, represents the hole system&#8217;s data;</li>
</ul>
<ul>
<li><em>NSManagedObject:</em> Represents each  entity and its properties, modeled by the developer. Those properties  includes attributes and relationships;</li>
</ul>
<ul>
<li><em>NSManagedObjectContext:</em> Provides all the  mentioned functionality to the Managed Objects, as fetching and  deletion; It is aware of and has access to the Persistent Store  Coordinator;</li>
</ul>
<ul>
<li><em>NSPersistentStoreCoordinator:</em> Provides an interface  to the data persistence layer.</li>
</ul>
<p>As mentioned before, Core  Data is not limited to data persistence. All aspects of data management  are separated from the persistence layer and can be used without it.</p>
<h3><strong>Testing Methodology</strong></h3>
<p><strong>Environment</strong></p>
<table style="margin-left: auto; margin-right: auto; height: 47px;" width="500">
<tbody>
<tr style="border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;">
<td style="width: 120px; text-align: center;">iPhone  3G 8GB</td>
<td style="width: 120px; text-align: center;">Xcode 3.2.3</td>
<td style="width: 120px; text-align: center;">iPhone SDK 4.0</td>
<td style="width: 120px; text-align: center;">iOS 4.0</td>
<td style="width: 120px; text-align: center;">Release Configuration</td>
</tr>
</tbody>
</table>
<p><strong>Data Model</strong></p>
<p><strong> </strong></p>
<div id="attachment_80" class="wp-caption aligncenter" style="width: 518px"><strong><strong><a href="http://i.ndigo.com.br/wp-content/uploads/2010/07/datamodel.png"><img class="size-full wp-image-80" title="Data Model" src="http://i.ndigo.com.br/wp-content/uploads/2010/07/datamodel.png" alt="" width="508" height="299" /></a></strong></strong><p class="wp-caption-text">Data Model</p></div>
<p><strong> </strong></p>
<p><strong>Testing Scenario<br />
</strong></p>
<p>SQLite was chosen over  binary format because it is the only type that is capable of partial  object graph loading, making use of the lazy fetching feature, what is  very important for the powerful, though limited iPhone hardware  capabilities.</p>
<p>Also,  a 10000 lines database, or 10000 persistent objects, was considered  enough for performance testing purpose. Core Data persists its objects  by saving all the NSManagedObjects present in the NSManagedObjectContext  by once. Therefore, the testing methodology for the insertion tests  included batch operations, with different of objects quantity per save,  as the following table describes:</p>
<table style="height: 124px; margin-left: auto; margin-right: auto;" width="273">
<tbody>
<tr style="text-align: center; border-top: solid 1px #aaa;">
<td><strong>Batch size</strong></td>
<td><strong>Times</strong></td>
</tr>
<tr style="text-align: center; border-top: solid 1px #aaa;">
<td>1</td>
<td>10000</td>
</tr>
<tr style="text-align: center; border-top: solid 1px #ccc;">
<td>10</td>
<td>1000</td>
</tr>
<tr style="text-align: center; border-top: solid 1px #ccc;">
<td>100</td>
<td>100</td>
</tr>
<tr style="text-align: center; border-top: solid 1px #ccc;">
<td>1000</td>
<td>10</td>
</tr>
<tr style="text-align: center; border-top: solid 1px #ccc; border-bottom: solid 1px #aaa;">
<td>10000</td>
<td>1</td>
</tr>
</tbody>
</table>
<p>The following testes  will be performed:</p>
<ol style="margin-left: 25px;">
<li style="margin-bottom: 10px;"><em>Insert without join  tables</em><br />
The main objective of  this test is to determine the insertion performance degradation,  according to the database size. Therefore, following the previous ta ble,  10000 objects will be persisted.</li>
<li style="margin-bottom: 10px;"><em>Insert with join  tables</em><br />
This test purpose is  to decide how much the number of table joins affect the performance.  Therefore, a smaller database will be used (2000 lines) with join  quantity from none to four.</li>
<li style="margin-bottom: 10px;"><em>Select without join  tables</em><br />
In this test two  approaches will be considered: fetching objects by its attributes and  getting them by their identifier. The performance is going to be  measured, until the persisted object&#8217;s count reaches 10000.</li>
<li style="margin-bottom: 10px;"><em>Select with join  tables</em><br />
This tests aims to  identify the selection performance degradation, according to the number  of object relationships (table joins). Since this is the heaviest test,  once the data must be inserted and then selected accordingly, data will  be selected after each 100 objects are inserted (atomically).</li>
</ol>
<p>All tests have as main  objective to determine the performance degradation of Core Data in  relation to the amount of persisted data and the number of relationships  between the data entities.</p>
<p>The next post will present our results and  conclusions, stay tuned!</p>
<p>This post is also available in Portuguese: <a href="http://i.ndigo.com.br/2010/07/testes-de-performance-do-core-data-sobre-sqlite-parte-1">Testes de performance do Core Data sobre SQLite &#8211; Parte 1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://i.ndigo.com.br/2010/07/core-data-over-sqlite-performance-tests-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone Persistent Store Overview</title>
		<link>http://i.ndigo.com.br/2010/07/iphone-persistent-store-overview/</link>
		<comments>http://i.ndigo.com.br/2010/07/iphone-persistent-store-overview/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 23:24:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://i.ndigo.com.br/?p=62</guid>
		<description><![CDATA[Storing information over iPhone apps is a task that needs to be carefully taken and analyzed. We know an iPhone has limited resources that need to be used and released, properly. The problem is: what happens when you have an app that stores and load large amount of data (e.g, a Sales Force Automation Applications)? [...]]]></description>
			<content:encoded><![CDATA[<p>Storing information over iPhone apps is a task that needs to be carefully taken and analyzed. We know an iPhone has limited resources that need to be used and released, properly. The problem is: what happens when you have an app that stores and load large amount of data (e.g, a Sales Force Automation Applications)?</p>
<p>We don&#8217;t know how the application will respond to these data access with the time (as the database size increases). Moreover, we have lot of third-party options of persistence layer, or layers responsible to manage data access and data mapping to objects.</p>
<p>These third-party options may have other problems that could resulting in performance loss with the time. So, choosing the best for each situation isn&#8217;t an easy job.</p>
<p>Thus, I.ndigo has decided to begin a series   of performance experiments on the most known options of Persistent Store, and obviously, the Core Data purely implemented.</p>
<p>Searching on the web for options resulted on the following list of technologies:</p>
<div style="overflow-x: scroll;">
<table id="h-.j" style="border: 1px solid #ccc;" border="1" width="1000" align="center">
<tbody>
<tr>
<td width="11.11111111111111%"></td>
<td width="11.11111111111111%"><strong>Core Data</strong></td>
<td width="11.11111111111111%"><strong>FMDB</strong></td>
<td width="11.11111111111111%"><strong>Magical Panda</strong></td>
<td width="11.11111111111111%"><strong>Mogenerator</strong></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;"><strong>OmniDataObjects</strong></span></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;"><strong>iphone-rsdb</strong></span></td>
<td width="11.11111111111111%"><strong>SQLite</strong></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;"><strong>SQLitePersistentObjects</strong></span></td>
</tr>
<tr>
<td width="11.11111111111111%">Abstraction level</td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;">object graph manager</span></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;">SQLite wrapper</span></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;">ActiveRecord (over Core Data)</span></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;">object graph manager</span></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;">Core Data API implementation (over SQLite)</span></td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;">SQLite wrapper (based on fmdb)</span></td>
<td width="11.11111111111111%">-</td>
<td width="11.11111111111111%"><span style="font-family: arial,sans,sans-serif;">ActiveRecord over SQLite</span></td>
</tr>
<tr>
<td width="11.11111111111111%">belongs_to implementation</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
</tr>
<tr>
<td width="11.11111111111111%">has_many implementation</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
</tr>
<tr>
<td width="11.11111111111111%">many_to_many implementation</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">N/A</td>
<td width="11.11111111111111%">no</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">no</td>
</tr>
<tr>
<td width="11.11111111111111%">SQL</td>
<td width="11.11111111111111%">no</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">no</td>
<td width="11.11111111111111%">no</td>
<td width="11.11111111111111%">no</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
</tr>
<tr>
<td width="11.11111111111111%">Lazy Loading</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">no</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">no</td>
<td width="11.11111111111111%">yes</td>
<td width="11.11111111111111%">no</td>
</tr>
<tr>
<td width="11.11111111111111%">License</td>
<td width="11.11111111111111%">iPhone Program</td>
<td width="11.11111111111111%">MIT</td>
<td width="11.11111111111111%">MIT</td>
<td width="11.11111111111111%">N/A</td>
<td width="11.11111111111111%">MIT</td>
<td width="11.11111111111111%">Apache 2.0</td>
<td width="11.11111111111111%">Public Domain</td>
<td width="11.11111111111111%">New BSD License</td>
</tr>
</tbody>
</table>
</div>
<div>This table also shows information about these technologies, which helped us to choose different options to test and compare one another. This table also shows whether there is any license limitation or need for a specific tool, such as SQL implementation.</p>
<p>Next posts will cover a serie of tests executed on some of these technologies and comparisons between them in several scenarios.</p>
<p>Stay tuned!</p>
<p>This post is also available in Portuguese: <a title="Visão Geral de iPhone Persistent Store" href="http://i.ndigo.com.br/2010/07/visao-geral-de-iphone-persistent-store/" target="_self">Visão Geral de iPhone Persistent Store</a></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://i.ndigo.com.br/2010/07/iphone-persistent-store-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

