<?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>Nomad Planet</title>
	<atom:link href="http://www.nomadplanet.fr/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nomadplanet.fr</link>
	<description>Romain Vincens - Développements iOS, formations et conseils</description>
	<lastBuildDate>Thu, 14 Jul 2011 14:05:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Efficient and streamlined forms</title>
		<link>http://www.nomadplanet.fr/2011/05/efficient-and-streamlined-forms/</link>
		<comments>http://www.nomadplanet.fr/2011/05/efficient-and-streamlined-forms/#comments</comments>
		<pubDate>Thu, 19 May 2011 21:14:24 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[change]]></category>
		<category><![CDATA[cycle]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[returnKeyType]]></category>
		<category><![CDATA[textfield]]></category>
		<category><![CDATA[uitextfield]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.nomadplanet.fr/?p=300</guid>
		<description><![CDATA[In many projects I had to implement a login screen, containing two text fields: one for the username, and one for the password. It&#8217;s as easy as dropping two textfields [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-full wp-image-308 aligncenter" title="iOS keyboard" src="http://www.nomadplanet.fr/wp-content/uploads/2011/05/Screen-shot-2011-05-19-at-23.13.01.png" alt="" width="426" height="337" /></p>
<p>In many projects I had to implement a login screen, containing two text fields: one for the username, and one for the password. It&#8217;s as easy as dropping two textfields on a view, creating the outlets and writing a few lines of code. But when it comes to make your interaction between the form and your user as smooth, efficient and streamlined as possible, you need to write some additional lines of code.</p>
<h2>1. Cycle through fields</h2>
<p>The user has entered his username, he now needs to edit the password. It&#8217;s as easy as tapping the second textfield. But power-users want to go fast, they want to continue tapping without moving too much the fingers on screen. So you decide to set the returnKeyType of your textfields to UIReturnKeyNext. And once both fields are filled (and possibly validation passed), you can launch the authentication process.</p>
<p>Here&#8217;s a example for such code:</p>
<pre class="brush: objc; title: ;">
- (BOOL) textFieldShouldReturn:(UITextField *)textField {

	BOOL loginEntered = !(self.loginField.text == nil || [self.loginField.text isEqualToString:@&quot;&quot;]);
	BOOL passwordEntered = !(self.passwordField.text == nil || [self.passwordField.text isEqualToString:@&quot;&quot;]);

	if(textField == self.loginField) {
		if(!passwordEntered) {
			[self.loginField resignFirstResponder];
			[self.passwordField becomeFirstResponder];
			return YES;
		}
		else if(!loginEntered) {
			return NO;
		}
	}

	if(textField == self.passwordField) {
		if(!loginEntered) {
			[self.passwordField resignFirstResponder];
			[self.loginField becomeFirstResponder];
			return YES;
		} else if(!passwordEntered) {
			return NO;
		}
	}

    // Start your authentication process
    .....

	return YES;
}
</pre>
<p>Of cours both text fields have their delegate set to your view controller. You can also auto-enable the return key on fields.<br />
However no matter what the user has entered in the textfields, the keyboard always shows &#8216;Next&#8217; as the return key.</p>
<h2>2. On-the-fly keyboard return key type change</h2>
<p>We&#8217;d like to have the &#8216;Go&#8217; return key in the keyboard instead of &#8216;Next&#8217; when both fields are validated and the user can start the authentication process. But the SDK comes with a limitation: changing the returnKeyType in the textFieldShouldReturn: method does not update the UI. Here&#8217;s the trick: use reloadInputViews.</p>
<p>Listen for textfields updates, for instance in your viewDidLoad: method in your controller:</p>
<pre class="brush: objc; title: ;">
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:)
												 name:UITextFieldTextDidChangeNotification object:self.loginField];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:)
												 name:UITextFieldTextDidChangeNotification object:self.passwordField];
</pre>
<p>Implement the textFieldDidChange: method</p>
<pre class="brush: objc; title: ;">
- (void) textFieldDidChange:(NSNotification*)notif {
	BOOL loginEntered = !(self.loginField.text == nil || [self.loginField.text isEqualToString:@&quot;&quot;]);
	BOOL passwordEntered = !(self.passwordField.text == nil || [self.passwordField.text isEqualToString:@&quot;&quot;]);

    UIReturnKeyType keyType = loginEntered &amp;&amp; passwordEntered ? UIReturnKeyGo : UIReturnKeyNext;

    BOOL loginReturnTypeChanged = self.loginField.returnKeyType != keyType;
    BOOL passwordReturnTypeChanged = self.passwordField.returnKeyType != keyType;

    self.loginField.returnKeyType = keyType;
    self.passwordField.returnKeyType = keyType;

    if(loginReturnTypeChanged)
        [self.loginField reloadInputViews];

    if(passwordReturnTypeChanged)
        [self.passwordField reloadInputViews];
}
</pre>
<p>Do not forget to remove your notification observer, in viewDidUnload:</p>
<pre class="brush: objc; light: true; title: ;">
	[[NSNotificationCenter defaultCenter] removeObserver:self];
</pre>
<p>Et voilà, you now have a login form that do not require the user to tap anywhere outside of the keyboard. If you have other kind of tips, for making forms more efficient, please share!</p>
<p>(You can <a href="http://www.nomadplanet.fr/wp-content/uploads/2011/05/LoginForm.zip">get a demo project here</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2011/05/efficient-and-streamlined-forms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Slides et démo de la présentation CoreAnimation aux Cocoaheads</title>
		<link>http://www.nomadplanet.fr/2011/03/slides-et-demo-de-la-presentation-coreanimation-aux-cocoaheads/</link>
		<comments>http://www.nomadplanet.fr/2011/03/slides-et-demo-de-la-presentation-coreanimation-aux-cocoaheads/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 09:33:28 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.nomadplanet.fr/?p=292</guid>
		<description><![CDATA[Le 10 mars, j&#8217;ai fait une présentation aux Cocoaheads Paris sur CoreAnimation. La présentation couvrait l&#8217;utilisation que l&#8217;on pouvait en faire au niveau UIKit jusqu&#8217;au niveau CALayer, et se terminait [...]]]></description>
			<content:encoded><![CDATA[<p><img alt="Cocoaheads" src="http://www.fruitstandsoftware.com/CocoaHeads/Welcome_files/CocoaHeads.png" title="Cocoaheads" class="alignleft" width="219" height="199" /></p>
<div>
Le 10 mars, j&#8217;ai fait une présentation aux Cocoaheads Paris sur CoreAnimation. La présentation couvrait l&#8217;utilisation que l&#8217;on pouvait en faire au niveau UIKit jusqu&#8217;au niveau CALayer, et se terminait par l&#8217;animation de properties custom.<br />
Si vous cherchez un projet démo pour mon précédent article <a href="http://www.nomadplanet.fr/2010/11/animate-calayer-custom-properties-with-coreanimation/">«Animate CALayer custom properties with CoreAnimation»</a>, vous trouverez votre bonheur sur ce blog post:<br />
<a href="http://cocoaheads.fr/2011/03/slides-et-sources-du-cocoaheads-de-mars-a-paris">http://cocoaheads.fr/2011/03/slides-et-sources-du-cocoaheads-de-mars-a-paris</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2011/03/slides-et-demo-de-la-presentation-coreanimation-aux-cocoaheads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom UITableViewCells loaded from XIB, howto &amp; debug</title>
		<link>http://www.nomadplanet.fr/2011/01/custom-uitableviewcells-loaded-from-xib-howto-debug/</link>
		<comments>http://www.nomadplanet.fr/2011/01/custom-uitableviewcells-loaded-from-xib-howto-debug/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 15:13:57 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[blank]]></category>
		<category><![CDATA[cell]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[load]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[uitableview]]></category>
		<category><![CDATA[uitableviewcell]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[xib]]></category>

		<guid isPermaLink="false">http://www.nomadplanet.fr/?p=251</guid>
		<description><![CDATA[There is a lot of literature which can be found on the net about how to load UITableViewCells from XIB files, for a use in UITableViews. You can find at [...]]]></description>
			<content:encoded><![CDATA[<p>There is a lot of literature which can be found on the net about how to load UITableViewCells from XIB files, for a use in UITableViews. You can find at least 3 or 4 different methods to achieve it, and everyone is convince their method is better than other&#8217;s. </p>
<h2>The Apple way</h2>
<p>While I&#8217;m not interested now in debating which is best, it looks to me there&#8217;s a lot of confusion about how to achieve it right and quickly, so I am going to detail the one that Apple present as the <em>official</em> way.<br />
An example is worth a thousand words, this one is taken from the Recipes example in Apple documentation:</p>
<pre class="brush: objc; title: ;">
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *IngredientsCellIdentifier = @&quot;IngredientsCell&quot;;

    EditingTableViewCell *cell = (EditingTableViewCell *)[tableView dequeueReusableCellWithIdentifier:IngredientsCellIdentifier];
    if (cell == nil) {
		[[NSBundle mainBundle] loadNibNamed:@&quot;EditingTableViewCell&quot; owner:self options:nil];
        cell = editingTableViewCell;
		self.editingTableViewCell = nil;
    }

    ....

}
</pre>
<p>The three interesting lines are located inside the if block. While they look strange at first, you get all the meaning once you open EditingTableViewCell.xib and see how things got laid down:</p>
<p><img src="http://www.nomadplanet.fr/wp-content/uploads/2011/01/Screen-shot-2011-01-04-at-10.33.56.png" alt="" title="EditingTableViewCell XIB file" width="543" height="347" class="aligncenter size-full wp-image-263" /></p>
<p>The type of the view (the class) is EditingTableViewCell. IBOutlets are mapped to that file. However, the File&#8217;s Owner is IngredientDetailViewController, which is the view controller managing the UITableView displaying the EditingTableViewCell.</p>
<p>Right-clicking the File&#8217;s Owner shows that EditingTableViewCell is mapped to an IBOutlet called <em>editingTableViewCell</em> in the controller.</p>
<p><img src="http://www.nomadplanet.fr/wp-content/uploads/2011/01/Screen-shot-2011-01-04-at-15.57.49.png" alt="" title="IngredientDetailViewController outlets" width="654" height="296" class="aligncenter size-full wp-image-268" /></p>
<p>Giving a quick look at IngredientDetailViewController.h shows the outlet:</p>
<pre class="brush: objc; light: true; title: ;">
@property (nonatomic, assign) IBOutlet EditingTableViewCell *editingTableViewCell;
</pre>
<p>That means that when the code calls</p>
<pre class="brush: objc; light: true; title: ;">
[[NSBundle mainBundle] loadNibNamed:@&quot;EditingTableViewCell&quot; owner:self options:nil];
</pre>
<p>the EditingTableViewCell XIB file is going to be loaded and attached to the self (the owner), in the editingTableViewCell ivar.</p>
<pre class="brush: objc; light: true; title: ;">
cell = editingTableViewCell;
</pre>
<p>keeps a reference to that loaded XIB, which is a EditingTableViewCell object, and then</p>
<pre class="brush: objc; light: true; title: ;">
self.editingTableViewCell = nil;
</pre>
<p>resets the outlet, so that it frees up unneeded memory. The cells will be queued and reused in the UITableView, and in case the view controller needs a new reference, it can load it again from the XIB.</p>
<p>Smart. Efficient.</p>
<h2>Reusing in other view controllers</h2>
<p>The downside is that the EditingTableViewCell XIB is associated to IngredientDetailViewController which is not nice if you want to reuse your XIB for a UITableView in another controller.</p>
<p>Duplicating the file is not a solution. In fact, you can load the XIB from another controller, <strong>as long as the outlet is named exactly the same</strong>. Even if it&#8217;s the original controller which is mentioned as the File&#8217;s Owner in the XIB, it works.</p>
<h2>Debugging a blank view controller</h2>
<p>There&#8217;s a common mistake in the class/xib setup that can lead to hours of debugging while all was going smooth a few seconds before. When creating your custom UITableViewCell XIB file, you enter the view controller&#8217;s name in the File&#8217;s Owner (4th tab in the Inspector).<br />
Then you link the outlet to your view, but <strong>you should not</strong> link the view controller&#8217;s view to your view in that XIB. Instead it must remain blank (it will be mapped by the XIB of the view controller).</p>
<div id="attachment_267" class="wp-caption aligncenter" style="width: 732px"><img src="http://www.nomadplanet.fr/wp-content/uploads/2011/01/Wrong-link.png" alt="" title="Do not link your controller&#039;s view outlet in a custom UITableViewCell&#039;s XIB file" width="722" height="302" class="size-full wp-image-267" /><p class="wp-caption-text">Do not link your controller's view outlet in a custom UITableViewCell's XIB file, or you will likely get bugs</p></div>
<p>Linking the view as well in the cell&#8217;s XIB will cause your view controller to appear blank when running the application. This is due to the conflict that the view controller&#8217;s view is linked in two different XIBs, and XCode doesn&#8217;t show any warning for this. You&#8217;re now warned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2011/01/custom-uitableviewcells-loaded-from-xib-howto-debug/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Animate CALayer custom properties with CoreAnimation</title>
		<link>http://www.nomadplanet.fr/2010/11/animate-calayer-custom-properties-with-coreanimation/</link>
		<comments>http://www.nomadplanet.fr/2010/11/animate-calayer-custom-properties-with-coreanimation/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 14:37:32 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[CAAnimation]]></category>
		<category><![CDATA[CALayer]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[properties]]></category>

		<guid isPermaLink="false">http://www.nomadplanet.fr/?p=175</guid>
		<description><![CDATA[Apple&#8217;s Core Animation framework is a powerful way for developpers to produce animated content in their graphical interfaces. It is simple enough so that the developer only needs to specify [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-full wp-image-179   aligncenter" title="Core Animation logo" src="http://www.nomadplanet.fr/wp-content/uploads/2010/11/Core-Animation-logo.png" alt="" width="137" height="137" /></p>
<p>Apple&#8217;s Core Animation framework is a powerful way for developpers to produce animated content in their graphical interfaces. It is simple enough so that the developer only needs to specify the initial and final states of an object in order to make it animate. <strong>Core Animation handles interpolation of intermediate values</strong> and executes the animation in different thread than the main run loop, the developper doesn&#8217;t need to write specific code for the animations. And CoreAnimations can be automagically accelerated by the GPU.</p>
<p>CoreAnimation can be used in several ways, from the high-level UIView animation syntax down to implicit and explicit CAAnimations.<br />
All animations finally end up being animations of CALayers properties. There are a number of CALayer properties that can be animated, they are called the <strong>animatable-properties</strong> by Apple (opacity, bounds, content, cornerRadius etc&#8230;)</p>
<p>However in some cases, the developper may need to implement its own CALayer subclass. The main purpose of doing such a thing is <strong>to let the developer draw custom content in the drawInContext: method</strong> (a bit like the drawRect: UIView method).</p>
<p>Let&#8217;s say you have a custom CALayer, which basically draws a circle with a given radius. The circle have a border on which you can control the thickness. Let&#8217;s name that class CircleLayer.</p>
<p>Basically its interface would look like this:</p>
<pre class="brush: objc; title: CircleLayer.h;">
#import &lt;Foundation/Foundation.h&gt;
#import &lt;QuartzCore/QuartzCore.h&gt;

@interface CircleLayer : CALayer {
	CGFloat		radius;
	CGFloat		strokeWidth;
}

@property (nonatomic, assign) CGFloat	radius;
@property (nonatomic, assign) CGFloat	strokeWidth;

@end
</pre>
<p>and in CircleLayer.m</p>
<pre class="brush: objc; title: ;">
- (void)drawInContext:(CGContextRef)ctx {
    NSLog(@&quot;Drawing layer, strokeWidth is %f, radius is %f&quot;, self.strokeWidth, self.radius);

    CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);

	/* Path the circle */
    CGContextAddArc(ctx, centerPoint.x, centerPoint.y, self.radius, 0.0, 2*M_PI, 0);
    CGContextClosePath(ctx);

    /* And fill it */
    CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextFillPath(ctx);

	/* Path the circle again */
    CGContextAddArc(ctx, centerPoint.x, centerPoint.y, self.radius, 0.0, 2*M_PI, 0);
    CGContextClosePath(ctx);

	/* Stroke the path */
	CGContextSetStrokeColorWithColor(ctx, [UIColor lightGrayColor].CGColor);
	CGContextSetLineWidth(ctx, self.strokeWidth);
	CGContextStrokePath(ctx);
}
</pre>
<p>If the developper want to make the radius and/or the stroke width of the circle to animate, he would implement a CAAnimation with a fromValue and toValue:</p>
<pre class="brush: objc; title: ;">
- (void) animateRadius {
	CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@&quot;radius&quot;];
	anim.duration = 3.0;
	anim.fromValue = [NSNumber numberWithDouble:50.0];
	anim.toValue = [NSNumber numberWithDouble:150.0];
	anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

	[circleLayer addAnimation:anim forKey:@&quot;animateRadius&quot;];

	circleLayer.radius = 150.0;
}

- (void) animateStrokeWidth {
	CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@&quot;strokeWidth&quot;];
	anim.duration = 4.0;
	anim.fromValue = [NSNumber numberWithDouble:25.0];
	anim.toValue = [NSNumber numberWithDouble:1.0];
	anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

	[circleLayer addAnimation:anim forKey:@&quot;animateStrokeWidth&quot;];

	circleLayer.strokeWidth = 1.0;
}
</pre>
<p>However these two methods (which would be placed for instance in the UIView hosting the circleLayer) attempt to animate radius and strokeWidth which are not part of CoreAnimation&#8217;s animatable properties. So they wont animate.</p>
<p>But there is a solution, which is not really clear to me in Apple&#8217;s documentation. CircleLayer.m needs to implement two other methods:</p>
<p>The first, <strong>needsDisplayForKey: tells CoreAnimation which properties of the layer causes the layer to be marked as &#8216;dirty&#8217;</strong> (i.e: needs to be redrawn by drawInContext: method).</p>
<pre class="brush: objc; title: ;">
+ (BOOL)needsDisplayForKey:(NSString *)key {
	if ([key isEqualToString:@&quot;radius&quot;]
		|| [key isEqualToString:@&quot;strokeWidth&quot;]) {
        return YES;
    }
	else {
        return [super needsDisplayForKey:key];
    }
}
</pre>
<p>So here we tell that an update on <em>radius</em> or on <em>strokeWidth</em> should cause the layer to be redrawn (other properties cause the redraw too, with the help of [super needsDisplayForKey:key]).</p>
<p>The second, <strong>initWithLayer: will ensure that custom properties will be copied for presentation layers</strong>. When you animate a CALayer, it creates presentation copies of the layer (using initWithLayer:) for each and every frame of the animation. Each presentation layer contains an intermediate value of the animated properties. The original layer contains the final state of the properties.</p>
<pre class="brush: objc; title: ;">
- (id) initWithLayer:(id)layer {
	if(self = [super initWithLayer:layer]) {
		if([layer isKindOfClass:[CircleLayer class]]) {
			CircleLayer *other = (CircleLayer*)layer;
			self.radius = other.radius;
			self.strokeWidth = other.strokeWidth;
		}
	}
	return self;
}
</pre>
<p>Since our custom properties are not copied automatically by CALayer, not implementing initWithLayer: would result in <em>radius</em> and <em>strokeWidth</em> to be zeroed for each intermediate frame, and then finally jumping to their last value when the last frame is displayed.</p>
<div id="attachment_184" class="wp-caption aligncenter" style="width: 456px"><img class="size-full wp-image-184 " title="Animating custom properties in a CALayer" src="http://www.nomadplanet.fr/wp-content/uploads/2010/11/Screen-shot-2010-11-26-at-15.32.58.png" alt="" width="520" height="277" /><p class="wp-caption-text">The radius and border thickness currently being animated</p></div>
<p>Now you have a simple solution to animate whatever kind of properties on your custom CALayer as long as they represent numbers (which can be interpolated). And yes it works with NSNumbers too.</p>
<p><strong>[UPDATE]:</strong> You can find a demo project in <a href="http://www.nomadplanet.fr/2011/03/slides-et-demo-de-la-presentation-coreanimation-aux-cocoaheads/">this article</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2010/11/animate-calayer-custom-properties-with-coreanimation/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>iDact, où comment la technologie aide les malvoyants à se repérer dans les lieux publics</title>
		<link>http://www.nomadplanet.fr/2010/11/idact-ou-comment-la-technologie-aide-les-malvoyants-a-se-reperer-dans-les-lieux-publics/</link>
		<comments>http://www.nomadplanet.fr/2010/11/idact-ou-comment-la-technologie-aide-les-malvoyants-a-se-reperer-dans-les-lieux-publics/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 20:00:23 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.nomadplanet.fr/?p=141</guid>
		<description><![CDATA[Le projet iDact (des idées aux actes) a pour but d&#8217;aider les personnes malvoyantes à se déplacer dans les lieux publics au moyen de plans adaptés à leur handicap. Ce [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-large wp-image-161" title="iDact" src="http://www.nomadplanet.fr/wp-content/uploads/2010/11/iDact1-1024x800.png" alt="" width="614" height="480" /></p>
<div>Le projet iDact (des idées aux actes) a pour but d&#8217;aider les personnes malvoyantes à se déplacer dans les lieux publics au moyen de plans adaptés à leur handicap.<strong> Ce problème de mobilité et d&#8217;autonomie touche un grand nombre de personnes</strong> : 1,2 million en France et 15 millions en Europe.</div>
<h2>Genèse du projet</h2>
<div>Laurent Notarianni et son équipe travaillent depuis 20 ans à rendre les lieux publics accessibles aux personnes handicapées. Les études menées sur la déficience visuelle ont mis en avant la nécessité de plans adaptés pour l&#8217;utilisation des transports en commun. Après une élaboration au format papier en étroite collaboration avec des déficients visuels, le succès de l&#8217;iPad est l&#8217;occasion d&#8217;introduire l&#8217;interactivité tactile.</div>
<h2>Le principe</h2>
<div>L&#8217;application présente une liste de stations de métro parisien, que le malvoyant peut sélectionner simplement par le toucher. En effet les menus et principales informations sont lues quand l&#8217;utilisateur passe son doigt dessus. Une fois une station sélectionnée, son plan est affiché et l&#8217;utilisateur peut <strong>tracer avec son doigt</strong> un chemin sur le plan. <strong>Une voix signale les obstacles et les zones d&#8217;intérêts.</strong></div>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-164" title="idact_moi_ipad_4_web" src="http://www.nomadplanet.fr/wp-content/uploads/2010/11/idact_moi_ipad_4_web.jpeg" alt="" width="300" height="253" /></p>
<div>L&#8217;application permet à un déficient visuel de préparer son itinéraire à l&#8217;avance. En effet, elle n&#8217;a pas été conçue pour être utilisée sur place, mais elle aide grandement l&#8217;utilisateur à se faire une représentation spatiale de l&#8217;itinéraire qu&#8217;il va parcourir dans les lieux publics.</div>
<h2>L&#8217;application iPad</h2>
<div>Le premier prototype de l&#8217;application a été réalisé pendant le week-end BeMyApp au mois de juin 2010. Le principe? Des porteurs de projets tentent de réunir une équipe de développeurs et graphistes pour produire un prototype fonctionnelle d&#8217;une application pendant le week-end. Et pour Laurent, cela a été un franc succès car l&#8217;application a remporté le concours.</div>
<div>Depuis, Nomad Planet a pris le relais dans les développements iPad. Le moteur a été généralisé de sorte à pouvoir rajouter de nouvelles stations facilement, et de nouvelles fonctionnalités ont été ajoutées.</div>
<h2>La suite</h2>
<div>Laurent Notarianni et Nomad Planet souhaitent transformer l&#8217;essai en généralisant l&#8217;application de sorte qu&#8217;elle puisse s&#8217;adapter à n&#8217;importe quel lieu public. Les développements et la conception des plans nécessitent toutefois des ressources. Pour aller plus loin, et si vous êtes intéressés, <strong>nous avons besoin de l&#8217;aide de chacun d&#8217;entre vous</strong>. Il vous est possible de financer librement et à hauteur de vos moyens le projet sur le site <a href="http://www.kisskissbankbank.com/projects/idact">KissKissBankBank</a>. Vous pouvez aussi nous contacter si vous souhaitez proposer votre aide, aussi bien pour la réalisation de l&#8217;application que pour ses tests.</div>
<div id="_mcePaste">En attendant, vous pourrez retrouver Laurent et Nomad Planet lors du Téléthon du 3 au 5 décembre 2010, pour une grande épreuve consistant à produire un maximum de plans pendant le week-end.</div>
<h2>Pour en savoir plus</h2>
<div>Le site officiel d&#8217;iDact: <a href="http://idact.eu">http://idact.eu</a></div>
<div>Le projet sur le site KissKissBankBank: <a href="http://www.kisskissbankbank.com/projects/idact">http://www.kisskissbankbank.com/projects/idact</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2010/11/idact-ou-comment-la-technologie-aide-les-malvoyants-a-se-reperer-dans-les-lieux-publics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The incomplete implementation of Push Notifications</title>
		<link>http://www.nomadplanet.fr/2010/09/the-incomplete-implementation-of-push-notifications/</link>
		<comments>http://www.nomadplanet.fr/2010/09/the-incomplete-implementation-of-push-notifications/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 14:30:51 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[APNS]]></category>
		<category><![CDATA[implementation]]></category>
		<category><![CDATA[incomplete]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[push]]></category>

		<guid isPermaLink="false">http://www.nomadplanet.fr/?p=91</guid>
		<description><![CDATA[With the release of the iPhone OS 3.0 in June &#8217;09, Apple introduced their Apple Push Notification Service (APNS), which gives the ability to developpers to push notifications to mobile [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_93" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-93" title="APNS" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/APNS-300x169.jpg" alt="Apple Push Notifications Service" width="300" height="169" /><p class="wp-caption-text">Apple Push Notifications Service presentation</p></div>
<p>With the release of the iPhone OS 3.0 in June &#8217;09, Apple introduced their Apple Push Notification Service (APNS), which gives the ability to developpers to push notifications to mobile devices (iPhone / iPod Touch and iPad). The notifications are bound to their respective application and may include badges, sounds or custom text in an alert popup. It works by keeping constantly opened an IP connection between the APNS and the device, allowing third-party application servers to route notifications via the APNS. Their main purpose was to give a workaround for developpers for the lack of multitasking in the OS (there was no multitasking to preserve battery life of the devices).<br />
The push notifications service received a warm welcome, although a part of the tech world was criticizing the solution which seemed to be more like a better-than-nothing solution.</p>
<p>Recently, in June &#8217;10, Apple released iOS4, which brought multitasking to their newest devices. Multitasking is a big word, because Apple is still not offering true multitasking (several apps running concurrently), instead they implemented a solution consisting in suspending/resuming apps and let them perform a limited number of tasks while in the background. This elegant solution solves most of the problems that the lack of multitasking caused: ability to play music in the background, ability to make VoIP calls in the background, ability to complete an upload to a server etc&#8230;</p>
<p>However Apple did not update their implementation of the push notifications APIs in the iOS4 (although they introduced local notifications as well).</p>
<p>Before iOS4, an app could be (roughly) in two states: running or stopped.</p>
<ul>
<li>If the app was stopped, and the user taps the &#8216;View&#8217; button in the notification alert, then the app is launched with the
<pre class="brush: objc; light: true; title: ;">
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
</pre>
<p>selector, where the launchOptions contains the notification which caused the app to be launched.</li>
<li>If the app is running at the time the notification is received, the
<pre class="brush: objc; light: true; title: ;">
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
</pre>
<p>selector is fired and no alert is displayed. Their, the developper can chose to act consequently, and even reproduce the alert dialog if he wants to.</li>
</ul>
<p>But in iOS4.x, an app can (still roughly) be in 3 states: not launched, suspended (in the background), or running (in the foreground). And the APIs for push notification haven&#8217;t changed:</p>
<ul>
<li>If the app is not launched: it is launched with the application:didFinishLaunchingWithOptions: selector</li>
<li>If the app is running, its didReceiveRemoteNotification: selector is fired</li>
<li>If the app was in the background, the notification alert is displayed, and if the user taps &#8216;View&#8217;, the app is brought to the foreground and then didReceiveRemoteNotification: is fired.</li>
</ul>
<p><strong>So whether the app is running in the foreground or in the background, there is no way to know which state the app was in before receiving the notification.</strong></p>
<p>Suppose you want the following behavior in your app:</p>
<ul>
<li>if notification received while app is not running: launch app, and show a specific screen</li>
<li>if notification received while app is running: only update the badge value for a tab item in your tabbar</li>
<li>if notification received while app is in background: app returns to foreground and then shows up a specific screen</li>
</ul>
<p>It&#8217;s impossible to implement because there is no way to differentiate the last two scenarios. Some would say it&#8217;s easy to make a distinction because the <em>applicationWillEnterForeground:</em> selector is fired prior to the didReceiveRemoteNotification: selector. It is true, we can set a boolean to some value and check the boolean within the <em>didReceiveRemoteNotification:</em> . However in the following scenario: app running -&gt; user hits &#8216;Home&#8217; button, does some stuff -&gt; app resumed by user -&gt; notification received, the app would behave like if it was brought to the foreground by the notification, while it&#8217;s the user who did it.</p>
<p>Apart from trying to compare dates when <em>applicationWillEnterForeground:</em> and <em>didReceiveRemoteNotification:</em> are fired and try to make a guess, there is no real solution to the problem (or if you have one, please drop a comment).</p>
<div>
<div id="attachment_95" class="wp-caption aligncenter" style="width: 210px"><img class="size-medium wp-image-95" title="Push Notification" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/IMG_0658-200x300.png" alt="" width="200" height="300" /><p class="wp-caption-text">Gowalla receiving a notification while running in the background</p></div>
<div id="attachment_96" class="wp-caption aligncenter" style="width: 210px"><img class="size-medium wp-image-96" title="Notification in Gowalla" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/IMG_0659-2-200x300.png" alt="" width="200" height="300" /><p class="wp-caption-text">Gowalla shows another popup in the app once it&#39;s resumed after the user tapped &#39;View&#39;</p></div>
</div>
<div>Most of the apps I&#8217;ve tested so far behave like this: they display another popup when <em>didReceiveRemoteNotification:</em> is fired, causing the device to display to popups when a push notification is received when the app is in the background (one by the system while in background, one by the app when app brought to foreground). This also causes an app to show the popup if a remote notification is received while using the application.</div>
<div>[<strong>EDIT:</strong> Thanks to Yann's answer, this is not totally true as you can check the applicationState of the app. However this may cause other troubles if you're app is inactive while receiving a notification. See comments]</div>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2010/09/the-incomplete-implementation-of-push-notifications/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Custom HTTP headers for every request made in UIWebViews</title>
		<link>http://www.nomadplanet.fr/2010/09/custom-http-headers-for-every-request-made-in-uiwebviews/</link>
		<comments>http://www.nomadplanet.fr/2010/09/custom-http-headers-for-every-request-made-in-uiwebviews/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 21:19:57 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[HTTP headers]]></category>
		<category><![CDATA[request]]></category>
		<category><![CDATA[UIWebView]]></category>
		<category><![CDATA[webview]]></category>

		<guid isPermaLink="false">http://wordpress.nomadplanet.fr/?p=44</guid>
		<description><![CDATA[NSMutableURLRequest are handy classes for making HTTP requests. They allow you to add custom HTTP headers before sending a request. And it works fine. However in a project, I have [...]]]></description>
			<content:encoded><![CDATA[<p>NSMutableURLRequest are handy classes for making HTTP requests. They allow you to <strong>add custom HTTP headers</strong> before sending a request. And it works fine.<br />
However in a project, I have a webview displaying a webpage hosted on a server (I know it sucks but that&#8217;s not the point). The content of the webpage had to be slightly different depending on the version of the iPhone app displaying the page.<br />
Until today the version of the page was always the same, whatever the application version. But today, to differentiate older version of the app with newer, we decided to add a custom HTTP header to the initial webview request, something like &#8220;app-version:1.1&#8243;.<br />
However it turned out that <strong>every single link tapped in the webpage is handled by the UIWebView</strong> itself and obviously the UIWebView is not adding the new HTTP header furthermore. And we needed the HTTP header to be present in every request made by the webview to the webserver.</p>
<p>So the solution I brought to the problem was to override the default UIWebView. My new NPWebView class  inherits UIWebView AND is delegate of the UIWebView. So that it implements the webView:shouldStartLoadWithRequest:navigationType: delegate selector.</p>
<p>First version of the NPWebView class asserted that the passed NSURLRequest was a NSMutableURLRequest and then added a HTTP header to it. And it worked fine!<br />
Until I moved the project to OS4.0, where the trick didn&#8217;t work anymore. It seems Apple has modified their implementation of the UIWebview, making any change to the NSURLRequest within the webView:shouldStartLoadWithRequest:navigationType: selector inoperant. So I implemented a new workaround, that works pretty well and should now work for whatever version of the OS exists or will exist in the future.</p>
<p>The new solution is less efficient, I admit it. If you have a better solution, don&#8217;t hesitate to drop a comment!<br />
In the webView:shouldStartLoadWithRequest:navigationType: selector, we&#8217;re looking in the given request for the HTTP header we want to add, see if it&#8217;s there.</p>
<ul>
<li>If not, then we copy the request, discard the given one (return NO), add the custom HTTP headers to the copied request and then ask self to load that request.</li>
<p>If present, then we let load the request (return YES).</ul>
<pre class="brush: objc; title: ;">
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)aRequest navigationType:(UIWebViewNavigationType)navigationType {

	NSDictionary *headers = [aRequest allHTTPHeaderFields];
	BOOL hasWhateverAddedHeader = NO;
	for(NSString *key in [headers allKeys]) {
		if([[key lowercaseString] isEqualToString:@&quot;my-added-header&quot;]) {
			hasWhateverAddedHeader = YES;
			break;
		}
	}
	if(!hasWhateverAddedHeader) {
		NSMutableURLRequest *newRequest = [aRequest mutableCopy];
		[newRequest addValue:@&quot;whatever&quot; forHTTPHeaderField:@&quot;My-Added-Header&quot;];
		[self addAppVersionHTTPHeader:newRequest];
		[self loadRequest:newRequest];
		[newRequest release];
		return NO;
	}
	return YES;
}
</pre>
<p>But one can argue that my NPWebView class is already the delegate of the UIWebView, thus not allowing any other class to be delegate of the original webview. The answer I brought was to reimplement the setDelegate: selector which will retain another delegate while keeping the true delegate as being the NPWebView class.</p>
<p><strong>The NPWebView class I wrote has more features, like the ability to set a NSDictionary for custom headers and solves the delegate issue.</strong></p>
<p><a href="http://www.nomadplanet.fr/wp-content/uploads/2010/09/CustomHTTPHeaders.zip">Hit the link to download</a> a sample project with the <strong>NPWebView class (work under Apache License version 2.0). </strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2010/09/custom-http-headers-for-every-request-made-in-uiwebviews/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Carefully name your image resource files, it will help blind people!</title>
		<link>http://www.nomadplanet.fr/2010/08/carefully-name-your-image-resource-files-it-will-help-blind-people/</link>
		<comments>http://www.nomadplanet.fr/2010/08/carefully-name-your-image-resource-files-it-will-help-blind-people/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 19:59:36 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[blind]]></category>
		<category><![CDATA[button]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[VoiceOver]]></category>

		<guid isPermaLink="false">http://wordpress.nomadplanet.fr/?p=35</guid>
		<description><![CDATA[A few days ago, while working on a project for partially sighted people, I tried to run on my iPhone the apps I&#8217;ve been working on in the past with [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, while working on a project for partially sighted people, I tried to run on my iPhone the apps I&#8217;ve been working on in the past with Voice Over turned on (Settings / General / Accessibility / Voice Over). While I was testing the apps, something came to me as a surprise. <strong>Voice Over was able to speach something on a button with no text</strong>, only an icon on it. While I would have understood it if there was a title or an &#8216;alt&#8217; text attached to the button (like those on img tags in HTML), actually it had not.</p>
<p>So I decided to create a project from scratch, drop a few buttons on a view, all with different configurations applied to them and see how VoiceOver behaves with them on the iPhone. And then I realised that <strong>VoiceOver was saying the name of the picture file that was used in the button</strong>. Pretty, elegant solution by Apple for untitled buttons. And then I felt happy because in my work I&#8217;ve always been meticulous at naming the images I use in my project. Just so that it&#8217;s easy to understand their purpose. But now it has a functional purpose too <img src='http://www.nomadplanet.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Apple has always taken care of disabled people within their operating systems and apps. Of course it doesn&#8217;t do miracles in iPhoto for blind people but it helps in many situations, like writing a mail or browsing the web, even on an iPhone.<br />
Their implementation of the VoiceOver technology is great. It&#8217;s build right in the system and as long as you use Apple&#8217;s standard APIs, your application will be VoiceOver compatible (that means do not put text inside images!). Their technology is much more efficient than other third-party technologies you can find on Windows for instance (thinking of jaws).</p>
<div id="attachment_36" class="wp-caption aligncenter" style="width: 394px"><img class="size-full wp-image-36 " title="VoiceOver in action" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/IMG_0503.png" alt="VoiceOver in action" width="384" height="576" /><p class="wp-caption-text">The bottom-left &#39;position&#39; button selected by VoiceOver. It synthesizes &quot;Start tracking, button&quot;, probably because the image file is named startTracking.png</p></div>
<div>To sum up, when the VoiceOver UI selects a button, it will try to synthethize, in this order:</p>
<ul>
<li>the text set in the button title, if any</li>
<li>the name of the image used in the button (setImage:forState:)</li>
<li>the name of the background image used in the button (setBackgroundImage:forState:)</li>
<li>otherwise a default &#8216;Button&#8217; will be spoken</li>
</ul>
<p>So next time you code an application, just think that targetting disabled people may be as easy as finding an appropriate name to your image files!</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2010/08/carefully-name-your-image-resource-files-it-will-help-blind-people/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Conditional compiling benefits to tracing and debugging your application</title>
		<link>http://www.nomadplanet.fr/2010/08/conditional-compiling-benefits-to-tracing-and-debugging-your-application/</link>
		<comments>http://www.nomadplanet.fr/2010/08/conditional-compiling-benefits-to-tracing-and-debugging-your-application/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 10:29:51 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[conditionnal]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[nslog]]></category>
		<category><![CDATA[preprocessor]]></category>
		<category><![CDATA[traces]]></category>

		<guid isPermaLink="false">http://wordpress.nomadplanet.fr/?p=28</guid>
		<description><![CDATA[Printing logs (traces) in the console is a common way for us -developpers- to track and debug our code. You always find yourself adding a NSLog(@&#8221;I&#8217;m in this block&#8221;); at [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Printing logs</strong> (traces) in the console is a common way for us -developpers- to track and debug our code. You always find yourself adding a NSLog(@&#8221;I&#8217;m in this block&#8221;); at some point just so you understand what&#8217;s happening in your code when you face a bug or when you want to track what&#8217;s going on in your app. These traces generally have little interest for your end users, that&#8217;s why they&#8217;re printed in the console. While this practice is not bad, it <strong>adds a little overload to your application</strong>, and the little overload multiplied by dozens or hundreds of traces may finally end up as a significant amount of compute time, especially when you&#8217;re working on large projects and printing large amount of data. This is because <strong>I/O operations are among the most time-consuming operations</strong> a device can perform.</p>
<p>While you may think it&#8217;s not really important to optimize your code down at the logging  level, you should consider that any optimization, as little as it can be, is important. It is important because you know you can do better, but also because at the end, the user will be the one judging your app. By adding little optimizations to little optimizations you finally endup with a code running better, which <strong>will somehow be seen or felt by the user at some point</strong>.<br />
The good news is that it is not necessary for you to rush on your project right now to remove all your NSLogs because there&#8217;s a great feature your compiler come with named the conditional compilation.</p>
<p>With conditional compilation you have a great tool to define which piece of code should appear or not in your target when you compile the code. <strong>Conditional compilation is part of the compiler instructions</strong> (the ones starting with a #, like #import). In this case we&#8217;ll use #ifdef, #ifndef, #endif, along with #define and #undef.</p>
<pre class="brush: objc; title: ;">
#define DEBUG

#ifdef DEBUG
	NSLog(@&quot;Print a trace&quot;);
#endif
</pre>
<p>This small code says that if the DEBUG variable is defined (which is the case), the precompiler will include the NSLog() instruction in the final code to be compiled by the compiler. Otherwise it won&#8217;t.<br />
Here we&#8217;re defining the DEBUG variable with the #define instruction. For it to have effect, you have to place it somewhere in your code before the #ifdef is executed. Later on in your code you can undefine the variable with a simple #undef DEBUG. See? It&#8217;s easy! You can have your #define instruction placed in a separate constant file and comment/uncomment the instruction at your will.</p>
<p>But it&#8217;s not ideal. First you have to wrap every single NSLog() instruction around a #ifdef #endif block and then you have to comment/uncomment your #define instruction depending on which type of build you want to make.</p>
<ul>
<li> To solve the first problem, it&#8217;s easy, you just have to put your NSLog in a separate method or C function.
<pre class="brush: objc; title: ;">
- (void) log:(NSString*)message {
#ifdef DEBUG
	NSLog(@&quot;%@&quot;, message);
#endif
}
</pre>
<p>Now you just have to call [self log:@"Print a trace"] elsewhere in your class. This is not perfect as your method takes only one argument, a NSString, and is callable only in the class which contains the log: selector. There are solutions to this particular defect, it will be covered in another article.</li>
<li> For the second optimization, it is possible to define your precompiler variable using the compiler command line (the -D<em>variable_name</em> options). And for this XCode comes with <em>configurations</em> in which it&#8217;s easy to define these variables. In XCode, you can create different configurations for different release types, and you can create as many configurations as you wish. The menu available on the top left of your main XCode window allows you to specify which configuration you want to use for your build. By default there are the Debug and Release configurations.<img class="aligncenter size-full wp-image-201" title="Configuration Menu in XCode 3.x" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/Screen-shot-2010-08-17-at-13.59.14.png" alt="Configuration Menu in XCode 3.x" width="364" height="309" />To edit a configuration, just hit Cmd+I on your project. On the property window, there&#8217;s the <em>Configurations</em> tab which allows you to create, delete, duplicate configurations. In the <em>Build</em> tab, you have access to a lot of options in relation to building your project.<br />
In the <em>Build</em> tab, make sure to select the <em>Debug</em> configuration and not <em>All configurations</em>, then in the search field, enter «Other C Flags».  At this point, the field is empty, just add the -DDEBUG value (the field «Other C++ Flags» will be automatically populated). And now you&#8217;re done!<br />
<img class="aligncenter size-full wp-image-202" title="Adding debug flags to compiler" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/Screen-shot-2010-08-17-at-14.21.14.png" alt="Adding debug flags to compiler" width="594" height="673" />When writing and debugging your project, select your Debug configuration. When preparing an adhoc build or building the binary for submission to the appstore, just select a different configuration and the NSLogs won&#8217;t appear in the console, they even won&#8217;t be compiled in your code!</li>
</ul>
<p><strong>Defining variables for conditional compilations, used along with configurations in XCode, is a convenient way for creating slightly  different builds of the same code</strong>: you can have debug traces and blocks of codes in your debug configuration while having a clean code for your releases, all within the same project. All one-click away!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2010/08/conditional-compiling-benefits-to-tracing-and-debugging-your-application/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>L&#8217;immobilier en réalité augmentée</title>
		<link>http://www.nomadplanet.fr/2010/07/limmobilier-en-realite-augmentee/</link>
		<comments>http://www.nomadplanet.fr/2010/07/limmobilier-en-realite-augmentee/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 10:02:30 +0000</pubDate>
		<dc:creator>Romain Vincens</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[carte]]></category>
		<category><![CDATA[immobilier]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[meilleursagents.com]]></category>
		<category><![CDATA[prix]]></category>
		<category><![CDATA[réalité augmentée]]></category>

		<guid isPermaLink="false">http://wordpress.nomadplanet.fr/?p=19</guid>
		<description><![CDATA[L&#8217;application MeilleursAgents.com, sortie début juin, est une application gratuite destinée à tous ceux qui souhaitent avoir une estimation de biens immobiliers. Elle vous permet de connaître la valeur du marché [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">L&#8217;application MeilleursAgents.com, sortie début juin, est une application gratuite destinée à tous ceux qui souhaitent avoir une estimation de biens immobiliers. Elle vous permet de <strong>connaître la valeur du marché immobilier</strong> (exprimée en €/m²) d&#8217;un département, d&#8217;une ville, d&#8217;un quartier ou même d&#8217;un immeuble (dans Paris et sa proche banlieue).</p>
<p style="text-align: center;"><img class="size-full wp-image-22  aligncenter" title="Carte des prix MeilleursAgents.com" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/Carte-290.png" alt="Price map MeilleursAgents.com" width="290" height="632" /></p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">A l&#8217;ouverture de l&#8217;application, celle-ci  demande à vous localiser et affiche la <strong>carte de France des prix immobiliers</strong> en superposant une couche de couleurs sur une vue satellite Google Maps. Une légende est disponible dans la barre d&#8217;outils se situant en bas de l&#8217;écran, elle permet de connaître la fourchette de prix associée à chacune des couleurs (de vert, le moins cher, à rouge, le plus cher). D&#8217;un simple appui sur une zone colorée, l&#8217;application affiche une bulle d&#8217;information qui indique le prix estimé au m² de la zone en question. Il est possible d&#8217;avoir plus de détails sur l&#8217;adresse en question (fourchette haute et basse, prix pour un appartement ou une maison, ainsi qu&#8217;une photo de la facade de l&#8217;immeuble si disponible) et même d&#8217;<strong>estimer le prix d&#8217;un bien à cette adresse</strong>, en fonction de paramètres supplémentaires rentrés par l&#8217;utilisateur (nombre de pièces, surface, présence d&#8217;une cave, d&#8217;une terrasse &#8230;).<br />
Il est également possible d&#8217;effectuer une recherche directement sur une ville ou une adresse grâce à une barre de recherche, ou bien de se  déplacer de département en département avec la fonction dédiée sur la barre d&#8217;outil du bas.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-21" title="Réalité augmentée MeilleursAgents.com" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/AR-330.png" alt="Augmented reality MeilleursAgents.com" width="563" height="330" /></p>
<p style="text-align: left;">
<p style="text-align: left;">Mais <strong>le plus fun et impressionnant est sans doute la réalité augmentée</strong> (disponible uniquement sur iPhone 3Gs et 4). Celle-ci superpose à la caméra de votre téléphone directement le prix du mètre carré sur l&#8217;immeuble que vous aurez pointé. On se prend d&#8217;envie à n&#8217;importe quel endroit de la capitale de connaître le prix au mètre carré. Evidemment la précision du GPS étant ce qu&#8217;elle est, les informations affichées ne se superpose pas forcément exactement à l&#8217;immeuble pointé. Mais l&#8217;application dispose d&#8217;un écran de configuration permettant de régler manuellement sa position sur la carte ainsi que la distance de recherche. Pratique!</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-23" title="Configuration MeilleursAgents.com" src="http://www.nomadplanet.fr/wp-content/uploads/2010/09/Config-330.png" alt="Settings MeilleursAgents.com" width="563" height="330" /></p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">L&#8217;application MeilleursAgents.com est indéniablement ludique et fun à utiliser. Le service proposé par MeilleursAgents.com permet à un vendeur de réaliser la meilleure vente possible de son bien immobilier et dans les meilleurs délais grâce à leurs agences partenaires. L&#8217;application sera d&#8217;autant plus utile à tous ceux qui veulent mettre en vente leur bien immobilier.</p>
<p style="text-align: left;">[EDIT: Cette application est réalisée par Clicmobile]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomadplanet.fr/2010/07/limmobilier-en-realite-augmentee/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
