<?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>Vincent Gable's Blog &#187; Announcement</title>
	<atom:link href="http://vgable.com/blog/category/announcement/feed/" rel="self" type="application/rss+xml" />
	<link>http://vgable.com/blog</link>
	<description>my weblog.</description>
	<lastBuildDate>Tue, 29 Nov 2011 22:20:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The Most Useful Objective-C Code I&#8217;ve Ever Written</title>
		<link>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/</link>
		<comments>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 10:01:01 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Bug Bite]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[LOG_EXPR]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[NSLog]]></category>
		<category><![CDATA[Preprocessor]]></category>
		<category><![CDATA[printf]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=670</guid>
		<description><![CDATA[Actually, it&#8217;s the most useful code I&#8217;ve extended; credit for the core idea goes to Dave Dribin with his Handy NSString Conversion Macro. LOG_EXPR(x) is a macro that prints out x, no matter what type x is, without having to worry about format-strings (and related crashes from eg. printing a C-string the same way as [...]]]></description>
			<content:encoded><![CDATA[<p>Actually, it&#8217;s the most useful code I&#8217;ve <em>extended</em>; credit for the core idea goes to <a href="http://www.dribin.org/dave/">Dave Dribin</a> with his <a href="http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/"><cite>Handy NSString Conversion Macro</cite></a>.</p>
<p><strong><code><a href="">LOG_EXPR</a>(x)</code> is a macro that prints out <code>x</code>, no matter what type <code>x</code> is</strong>, without having to worry about format-strings (and related crashes from eg. printing a C-string the same way as an <code>NSString</code>). It works on Mac OS X and iOS. Here are some examples,</p>
<p><code>LOG_EXPR(self.window.screen);</code></p>
<blockquote><p>self.window.screen = &lt;UIScreen: 0x6d20780; bounds = {{0, 0}, {320, 480}}; mode = &lt;UIScreenMode: 0x6d20c50; size = 320.000000 x 480.000000&gt;&gt;
</p></blockquote>
<p><code>LOG_EXPR(self.tabBarController.viewControllers);</code></p>
<blockquote><p>self.tabBarController.viewControllers = (<br />
    &#8220;&lt;UINavigationController: 0xcd02e00&gt;&#8221;,<br />
    &#8220;&lt;SavingsViewController: 0xcd05c40&gt;&#8221;,<br />
    &#8220;&lt;SettingsViewController: 0xcd05e90&gt;&#8221;<br />
)</p></blockquote>
<p>Pretty straightforward, really. The biggest convenience so far is having the expression printed out, so you don&#8217;t have to write out a name redundantly in the format string (eg. <code> NSLog(@"actionURL = %@", actionURL)</code>). But <code>LOG_EXPR</code> really shows it&#8217;s worth when you start using scalar or <code>struct</code> expressions:</p>
<p><code>LOG_EXPR(self.window.windowLevel);</code></p>
<blockquote><p>self.window.windowLevel = 0.000000</p></blockquote>
<p><code>LOG_EXPR(self.window.frame.size);</code></p>
<blockquote><p>self.window.frame.size = {320, 480}</p></blockquote>
<p>Yes, there are expressions that won&#8217;t work, but they&#8217;re pretty rare for me. I use <code>LOG_EXPR</code> every day. Several times. It&#8217;s not quite as good as having <a href="http://vgable.com/blog/2010/06/14/ask-f-script/">a REPL for Cocoa</a>, but it&#8217;s handy.</p>
<p><a href="#Get_LOG_EXPR">Give it a try</a>.</p>
<h3>How It Works</h3>
<p>The problem is how to pick a function or format string to print <code>x</code>, based on the type of <code>x</code>. C++&#8217;s type-based dispatch would be a good fit here, but it&#8217;s verbose (a full function-definition per type) and I wanted to use pure Objective-C if possible. Fortunately, <strong>Objective-C has an <a href="http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html"><code>@encode()</code></a>  compiler directive that returns a string describing any type it&#8217;s given.</strong> Unfortunately it works on <em>types</em>, not variables, but with C99 <strong>the <code><a href="http://gcc.gnu.org/onlinedocs/gcc/Typeof.html">typeof()</a></code> compiler directive lets us get the type of any variable</strong>, which we can pass to <code>@encode()</code>.  The final bit of compiler magic is using <a href="http://gcc.gnu.org/onlinedocs/cpp/Stringification.html">stringification (<code>#</code>)</a> to print out the literal string inside <code>LOG_EXPR()</code>&#8216;s parenthesis.</p>
<h3>The Macro, Line By Line</h3>
<div class="code-box">
<pre>
1 #define LOG_EXPR(_X_) do{\
2 	__typeof__(_X_) _Y_ = (_X_);\
3 	const char * _TYPE_CODE_ = @encode(__typeof__(_X_));\
4 	NSString *_STR_ = VTPG_DDToStringFromTypeAndValue(_TYPE_CODE_, &#038;_Y_);\
5 	if(_STR_)\
6 		NSLog(@"%s = %@", #_X_, _STR_);\
7 	else\
8 		NSLog(@"Unknown _TYPE_CODE_: %s for expression %s in function %s, file %s, line %d", _TYPE_CODE_, #_X_, __func__, __FILE__, __LINE__);\
9 }while(0)
</pre>
</div>
<ol>
<li>The first and last lines are a way to put <code>{}</code>&#8216;s around the macro to prevent <a href="http://en.wikipedia.org/wiki/C_preprocessor#Multiple_statements">unintended effects</a>. The <code>do{}while(0);</code> &#8220;loop&#8221; does nothing else.</li>
<li>First evaluate the expression, <code>_X_</code>, given to <code>LOG_EXPR</code> <em>once</em>, and store the result in a <code>_Y_</code>. We need to use <code><a href="http://gcc.gnu.org/onlinedocs/gcc/Typeof.html">typeof()</a></code> (which had to be written <code>__typeof__()</code> to appease some versions of GCC) to figure out the type of <code>_Y_</code>.</li>
<li><code>_TYPE_CODE_</code> is c-string that <a href="http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html">describes the type</a> of the expression we want to print out.</li>
<li>Now we have enough information to call a function, <code>VTPG_DDToStringFromTypeAndValue()</code> to convert the expression&#8217;s value to a string. We pass it the <code>_TYPE_CODE_</code> string, and <em>the address of </em> <code>_Y_</code>, which is a pointer, and has a known size. We can&#8217;t pass <code>_Y_</code> directly, because depending on what <code>_X_</code> is, it will have different types and could be of any size.</li>
<li><code>VTPG_DDToStringFromTypeAndValue()</code> returns <code>nil</code> if it can&#8217;t figure out how to convert a value to a string.</li>
<li>Everything went well, print the <a href="http://gcc.gnu.org/onlinedocs/cpp/Stringification.html">stringified</a> expression, <code>#_X_</code>, and  the string representing it&#8217;s value, <code>_STR_</code>.</li>
<li>otherwise…</li>
<li>The expression had a type we can&#8217;t handle, print out a verbose diagnostic message.</li>
<li>See line 1.</li>
</ol>
<h3>The <code>VTPG_DDToStringFromTypeAndValue()</code> Function</h3>
<p>See the source in <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m">VTPG_Common.m</a>:</p>
<p><iframe src ="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m" width="100%" height="300">(Your browser does not support iframes.)</iframe></p>
<p>It&#8217;s derived from  <a href="http://www.dribin.org/dave/">Dave Dribin</a>&#8216;s function <a href="http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/"> <code>DDToStringFromTypeAndValue()</code></a>, and is pretty straightforward: <code>strcmp()</code> the type-string, and if it matches a known type call a function, or use <code>+[NSString stringWithFormat]:</code>, to turn the value into a string.</p>
<h3>The First Step Twords Fixing Your Macro Problem is Admitting it&#8230;</h3>
<p>So yeah, maybe I went a little wild with macros here…</p>
<p>But it took out some <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">WET</a>-ness of the original code, and prevents me from accidentally mixing up types in a long wall of <code>if</code>s, eg.</p>
<div class="code-box">
<pre>
else if (strcmp(typeCode, @encode(NSRect)) == 0)
{
    return NSStringFromRect(*(NSRange *)value);
}
else if (strcmp(typeCode, @encode(NSRange)) == 0)
{
    return NSStringFromRect(*(NSRange *)value);
}
</pre>
</div>
<p>If I were cool, I&#8217;d use <code>NSDictionary</code>s to map from the <code>@encode</code>-string to an appropriate format string or function pointer.  This is conceptually cleaner; less error-prone than using macros; and almost certainly faster. Unfortunately, it gets a little tricky with functions, since I need to deference <code>value</code> into the proper type.</p>
<p>One final note from my testing, I could do away with the <code>strcmp()</code>s, because directly comparing <code>@encode</code> string pointers (eg <code>if(typeCode == @encode(NSString*))</code> works. I don&#8217;t know if it will <em>always</em> work though, so relying on it strikes me as a profoundly Bad Idea. But maybe that bad idea will give someone a good idea.</p>
<h3>Limitations</h3>
<h4>Arrays</h4>
<p>C arrays generally muck things up. Casting to a pointer works around this:</p>
<div class="code-box">
<pre>
char x[14] = "Hello, world!";
//LOG_EXPR(x); //error: invalid initializer
LOG_EXPR((char*)x); //prints fine
</pre>
</div>
<h4><code>__func__</code></h4>
<p>Because it is a <code>static const char []</code>, <code><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1642.html">__func__</a></code> (and <code>__FUNCTION__</code> or <code>__PRETTY_FUNCTION__</code>) need casting to <code>char*</code> to work with <code>LOG_EXPR</code>. Because logging out a function/method call is something I do frequently, I use the macro:</p>
<div class="code-box">
<pre>
#define LOG_FUNCTION()	NSLog(@"%s", __func__)</pre>
</div>
<h4><code>long double</code> (Leopard and older)</h4>
<p>On older systems, <code>LOG_EXPR</code> won&#8217;t work with a <code>long double</code> value, because <code>@encode(long double)</code> gives the same result as <code>@encode(double)</code>. This is a <a href="http://openradar.appspot.com/6468314">known issue</a> with the runtime. The top-level <code>LOG_EXPR</code> macro could detect a <code>long double</code> with <code>if((sizeof(_X_) == sizeof(long double)) &#038;&#038; (_TYPE_CODE_ == @encode(double)))</code>. But I doubt this will ever be necessary.</p>
<p>I haven&#8217;t actually written any code that uses <code>long double</code>, because I <strong>use <code><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/doc/uid/20000055-BCIHCEFJ">NSDecimal</a></code>, or another base-10 number format, for situations that require more precision than a <code>double</code>.</strong></p>
<h3>Scaling and Frameworks </h3>
<p>Growing <code>LOG_EXPR</code> to handle <em>every</em> type is a lot of work. I&#8217;ve only added types that I&#8217;ve actually needed to print. This has kept the code manageable, and seems to be working so far.</p>
<p>The biggest problem I have is <strong>how to deal with types that are in frameworks that not every project includes</strong>. Projects that use CoreLocation.framework need to be able to use <code>LOG_EXPR</code> to print out CoreLocation specific <code>struct</code>s, like <code> CLLocationCoordinate2D</code>. But projects that <em>don&#8217;t</em> use CoreLocation.framework don&#8217;t have a definition of the <code>CLLocationCoordinate2D</code> type, so code to convert it to a string won&#8217;t compile. There are two ways I&#8217;ve tried to solve the problem</p>
<h4>Comment-out framework-specific code</h4>
<p>This is pretty self-explanatory, I&#8217;ll fork VTPG_Common.m and un-comment-out code for types that my project needs to print. It works, but it&#8217;s drudgery. Programmers hate that.</p>
<h4>Hardcode type info</h4>
<p>The idea is to hard-code the string that <code>@encode(SomeType)</code> would evaluate to, and then (since we know how <code>SomeType</code> is laid out in memory) use casting and pointer-arithmetic to get at the fields.</p>
<p>For example:</p>
<div class="code-box">
<pre>
//This is a hack to print out CLLocationCoordinate2D, without needing to #import &lt;CoreLocation/CoreLocation.h&gt;
//A CLLocationCoordinate2D is a struct made up of 2 doubles.
//We detect it by hard-coding the result of @encode(CLLocationCoordinate2D).
//We get at the fields by treating it like an array of doubles, which it is identical to in memory.
if(strcmp(typeCode, "{?=dd}")==0)//@encode(CLLocationCoordinate2D)
	return [NSString stringWithFormat:@"{latitude=%g,longitude=%g}",((double*)value)[0],((double*)value)[1]];
</pre>
</div>
<p>This Just Works in a project that includes CoreLocation, and doesn&#8217;t mess up projects that don&#8217;t. Unfortunately it&#8217;s <em>horribly brittle</em>. Any Xcode or system update could break it. It&#8217;s not a tenable fix.</p>
<h3>Areas for Improvement</h3>
<p>If there&#8217;s some type <code>LOG_EXPR</code> can&#8217;t handle that you need, please <a href="http://github.com/VTPG/CommonCode">jump right in and improve it</a>!</p>
<p>When I have time, I plan to write a general parser for <code>@encode()</code>-strings. This will let me print out <em>any</em> <code>struct</code>, which mostly solves the type-defined-in-missing-framework problem, and would let <code>LOG_EXPR</code> Just Work with types from all kinds of POSIX/C libraries.</p>
<h3><a name="Get_LOG_EXPR"></a>Using <code>LOG_EXPR()</code> in Your Project </h3>
<p>Download <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m">VTPG_Common.m</a> and <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.h">VTPG_Common.h</a> from <a href="http://github.com/VTPG/CommonCode">my github repository</a>, and add them to your Xcode project.</p>
<p>Now just add the line <code>#import "VTPG_Common.h"</code> to your prefix file (named <code>&lt;ProjectName&gt;_Prefix.pch</code> by default), after the <code>#ifdef __OBJC__</code>, for example:</p>
<div class="code-box">
<pre>
#ifdef __OBJC__
    #import &lt;Foundation/Foundation.h&gt;
    // maybe other files, depending on project  template...
    #import "VTPG_Common.h"
#endif</pre>
</div>
<p>Now <code>LOG_EXPR()</code> will work everywhere in your project.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Sneaking Malware Into the  App Store</title>
		<link>http://vgable.com/blog/2010/07/21/sneaking-malware-into-the-app-store/</link>
		<comments>http://vgable.com/blog/2010/07/21/sneaking-malware-into-the-app-store/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 08:38:45 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iTunes]]></category>
		<category><![CDATA[Malware]]></category>
		<category><![CDATA[Review Process]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=664</guid>
		<description><![CDATA[It&#8217;s happened. An app that grossly violated Apple&#8217;s terms of service (by enabling free tethering) made it through Apple&#8217;s review process, onto the App Store, and into the #2 most-popular spot before being taken down. Although this app wasn&#8217;t malicious to users, it&#8217;s absolutely malicious to Apple&#8217;s agreements with AT&#038;T and other phone-companies. It is [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s happened. An app that grossly violated Apple&#8217;s terms of service (by <a href="http://appshopper.com/blog/2010/07/20/handy-light-tethering-app-camouflaged-as-flashlight/">enabling <em>free</em> tethering</a>) made it through Apple&#8217;s review process, onto the App Store, and into the #2 most-popular spot before being taken down. Although this app wasn&#8217;t malicious to users, it&#8217;s absolutely malicious to Apple&#8217;s agreements with AT&#038;T and other phone-companies. It is a real demonstration that <strong>Apple can&#8217;t keep malware off the App Store</strong>.</p>
<h3>A Few Sneaky Ideas</h3>
<p>It&#8217;s not hard to come up with ways to fool App-Store reviewers.</p>
<p>You might just <strong>get lucky</strong>. With <a href="http://148apps.biz/app-store-metrics/">over 230,000</a> Apps in the store, reviewers are swamped. They&#8217;re only human and they might not notice some subtle evil &#8212; especially if it&#8217;s not on <a href="http://appreview.tumblr.com/">their naughty-behavior list</a>.</p>
<p><strong>Time-Bombs</strong>, apps that hide their bad-behavior for a few days, are undetectable without periodic audits, since they act normally during the pre-release review period.</p>
<p><strong>Phoning home</strong> to a server that let&#8217;s an app know it&#8217;s passed review and can begin it&#8217;s life of crime, would let an app be even more precise.</p>
<p>With just a few minutes thought, I&#8217;m sure you can think of even more clever tricks, or combination of tricks.</p>
<h3>Not a Fully Open Vulnerability</h3>
<p>That&#8217;s not to say your iPhone is in as much danger as your PC. iOS apps don&#8217;t have the same free-reign that traditional computer programs have. That <a href="http://www.mikeash.com/pyblog/iphone-apps-i-cant-have.html">limits their usefulness</a>, but it also limits the damage they can cause. An iOS App can&#8217;t stop you from killing it, and it can&#8217;t mess with other apps, so it can&#8217;t &#8220;take over&#8221; your phone. But it can do anything it likes with your Contacts, and secretly abuse the phone&#8217;s always-on network connection, and get up to other sorts of minor mischief.</p>
<p>I don&#8217;t have room here to fully analyze the risks of a rogue iPhone&#8217;s program. But generally, the danger isn&#8217;t too great: a little more than a what website can do, a <em>lot</em> less than what a PC program with administrator access can do.</p>
<p>Ultimately, Apple&#8217;s best defense against malware isn&#8217;t control of the App Store review process or iTunes payments (although they help), but control over iOS. A well-designed operating system limits what kinds of malware are possible. The review process can screen for egregious mistakes. But it can&#8217;t catch everything, and it&#8217;s least-able to catch the most clever malware, which ultimately, are the programs we should be most worried about. Apple&#8217;s review process doesn&#8217;t provide real security against modern malware.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/07/21/sneaking-malware-into-the-app-store/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Retina Ready</title>
		<link>http://vgable.com/blog/2010/06/24/retina-ready/</link>
		<comments>http://vgable.com/blog/2010/06/24/retina-ready/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 07:18:41 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Displays]]></category>
		<category><![CDATA[Ed Tufte]]></category>
		<category><![CDATA[iPhone 4]]></category>
		<category><![CDATA[PPI]]></category>
		<category><![CDATA[Resolution]]></category>
		<category><![CDATA[Retina Display]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=628</guid>
		<description><![CDATA[The iPhone 4&#8242;s ultra-sharp &#8220;Retina Display&#8221; really is a game changer. Until now, popular computer screens have been so low resolution, they could only display crude, low density, designs. It will take a few years for such high resolution screens to filter up into the personal computer space. But if you start writing an application [...]]]></description>
			<content:encoded><![CDATA[<p>The iPhone 4&#8242;s ultra-sharp &#8220;<a href="http://www.apple.com/iphone/features/retina-display.html">Retina Display</a>&#8221; really is a game changer. Until now, popular computer screens have been so low resolution, they could only display crude, low density, designs. It will take a few years for such high resolution screens to filter up into the personal computer space. But if you start writing an application that takes advantage of the iPhone 4&#8242;s display now, there will be millions of people who can use it by the time you&#8217;re done.</p>
<p>The best source I can recommend for understanding the kinds of designs that take full advantage of high PPI displays are <a href="http://www.edwardtufte.com">Edward Tufte</a>&#8216;s classic design books:</p>
<p><iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=vincgabl-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0961392142" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe> <iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=vincgabl-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0961392126" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe> <iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=vincgabl-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0961392118" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe> <iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=vincgabl-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0961392177" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<p>If you just get one, make it <a href="http://www.amazon.com/dp/0961392142?tag=vincgabl-20&#038;camp=213381&#038;creative=390973&#038;linkCode=as4&#038;creativeASIN=0961392142&#038;adid=1J3BGS86B6S6D1T92B5Y&#038;"><cite>The Visual Display of Quantitative Information</cite></a>.</p>
<p>PS: Tufte&#8217;s books are themselves examples of beautiful, complex, high density design, and as such really only make sense printed. At least for the next few years. Even if you can find an electronic version, I wouldn&#8217;t recommend reading it, because it won&#8217;t convey the power of a 1600 PPI display (printer).</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/06/24/retina-ready/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simulator Advertising?</title>
		<link>http://vgable.com/blog/2010/06/11/simulator-advertising/</link>
		<comments>http://vgable.com/blog/2010/06/11/simulator-advertising/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 22:38:35 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Advertising]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone Simulator]]></category>
		<category><![CDATA[Simulator]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=620</guid>
		<description><![CDATA[I wish I could take credit for this idea, but it&#8217;s from someone else, will Apple sell iAds that only show up in the iPhone simulator? Probably not, but it would be a hell of a targeted demographic. For those of you who aren&#8217;t familiar with how building iPhone software works, we developers spend thousands [...]]]></description>
			<content:encoded><![CDATA[<p>I wish I could take credit for this idea, but it&#8217;s from <a href="http://twitter.com/rlwimi">someone else</a>, <strong>will Apple sell iAds that only show up <em>in the iPhone simulator</em>?</strong> Probably not, but it would be a hell of a targeted demographic.</p>
<p>For those of you who aren&#8217;t familiar with how building iPhone software works, we developers spend thousands of hours testing and debugging our programs in an <a href="http://developer.apple.com/iphone/library/documentation/xcode/conceptual/iphone_development/125-Using_iPhone_Simulator/iphone_simulator_application.html">iPhone Simulator</a> application that runs on our Macs. The simulator can&#8217;t run Apps from the App Store, only programs compiled from source code with Xcode. So the only people using the simulator are programers, or otherwise deeply involved with building iOS apps. Apple could make it so that any iAds in the simulator would show special ads targeted to developers.</p>
<p>Better still, iAds in the simulator could show something <em>useful</em> like rules from the <a href="http://developer.apple.com/iphone/library/documentation/userexperience/conceptual/mobilehig/Introduction/Introduction.html"><cite>Human Interface Guidelines</cite></a> (that too few read), <a href="http://www.mikeash.com/pyblog/friday-qa-2010-05-14-what-every-apple-programmer-should-know.html">good tips</a> or even <a href="http://en.wikiquote.org/wiki/Category:Computer_scientists">inspiring quotations</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/06/11/simulator-advertising/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NSHomeDirectory() is a Bad Thing</title>
		<link>http://vgable.com/blog/2010/06/02/nshomedirectory-is-a-bad-thing/</link>
		<comments>http://vgable.com/blog/2010/06/02/nshomedirectory-is-a-bad-thing/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 08:08:54 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[NSHomeDirectory]]></category>
		<category><![CDATA[Paths]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=611</guid>
		<description><![CDATA[Code that uses NSHomeDirectory() is probably doing The Wrong Thing. It&#8217;s not appropriate to clutter up the user&#8217;s home directory &#8212; internal application-data should be stored in the Application Support directory (or a temporary file if it&#8217;s transient). So I can&#8217;t think of a good reason to get the path to the user&#8217;s home directory. [...]]]></description>
			<content:encoded><![CDATA[<p>Code that uses <code>NSHomeDirectory()</code> is probably doing The Wrong Thing. It&#8217;s not appropriate to clutter up the user&#8217;s home directory &#8212; internal application-data should be stored in the <a href="http://cocoawithlove.com/2010/05/finding-or-creating-application-support.html"><code>Application Support</code> directory</a> (or a <a href="http://stackoverflow.com/questions/215820/how-do-i-create-a-temporary-file-with-cocoa">temporary file</a> if it&#8217;s transient). So I can&#8217;t think of a good reason to get the path to the user&#8217;s home directory. <strong>Every use of <code>NSHomeDirectory()</code> I&#8217;ve seen is spamming the home directory, or getting a subdirectory in a brittle way.</strong></p>
<p>For sample code that gets a directory robustly, using <code> NSSearchPathForDirectoriesInDomains()</code>, see <a href="http://cocoawithlove.com/2010/05/finding-or-creating-application-support.html"><cite>Finding or creating the application support directory</cite></a>.</p>
<p>Because <code>NSHomeDirectory()</code> encourages so many bad practices, it should be deprecated.</p>
<h3>Disabling <code> NSHomeDirectory()</code> in Your Projects</h3>
<p>Add the following macro to your prefix file:</p>
<div class="codebox" style="overflow:scroll">
<pre>#define NSHomeDirectory() NSHomeDirectory_IS_DISCOURAGED_USE_NSSearchPathForDirectoriesInDomains_TO_GET_A_SUBDIRECTORY_OF_HOME</pre>
</div>
<p>Then any use of <code>NSHomeDirectory()</code> will give the compiler error:</p>
<div style="overflow:scroll">
<blockquote><p>error:<br />
&#8216;NSHomeDirectory_IS_DISCOURAGED_USE_NSSearchPathForDirectoriesInDomains_TO_GET_A_SUBDIRECTORY_OF_HOME&#8217; undeclared (first use in this function)
</p></blockquote>
</div>
<h3>Tell Me I&#8217;m Wrong</h3>
<p><strong>If you&#8217;ve seen a legitimate use of <code>NSHomeDirectory()</code> please leave a comment!</strong> Just because I can&#8217;t think of one doesn&#8217;t mean they don&#8217;t exist.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/06/02/nshomedirectory-is-a-bad-thing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>&#8220;Otherwise there’d be no sense to it&#8221;</title>
		<link>http://vgable.com/blog/2010/03/25/otherwise-there%e2%80%99d-be-no-sense-to-it/</link>
		<comments>http://vgable.com/blog/2010/03/25/otherwise-there%e2%80%99d-be-no-sense-to-it/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 09:56:44 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Quotes]]></category>
		<category><![CDATA[Dashiell Hammett]]></category>
		<category><![CDATA[Ethics]]></category>
		<category><![CDATA[Hardboiled]]></category>
		<category><![CDATA[Motivation]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=583</guid>
		<description><![CDATA[…She bent forward to put a white hand on my knee. &#8220;There is wealth in that cellar beneath the garage. You may have whatever you ask&#8221;. I shook my head. &#8220;You aren&#8217;t a fool!&#8221; she protested. &#8220;You know-&#8221; Let me straighten this out for you,” I interrupted. “We’ll disregard whatever honesty I happen to have, [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
…She bent forward to put a white hand on my knee. &#8220;There is wealth in that cellar beneath the garage. You may have whatever you ask&#8221;.</p>
<p>I shook my head.</p>
<p>&#8220;You aren&#8217;t a fool!&#8221; she protested. &#8220;You know-&#8221;</p>
<p>Let me straighten this out for you,” I interrupted. “We’ll disregard whatever honesty I happen to have, sense of loyalty to employers, and so on. You might doubt them, so we’ll throw them out. Now I’m a detective because I happen to like the work. It pays me a fair salary, but I could find other jobs that would pay more. Even a hundred dollars more a month would be twelve hundred a year. Say twenty-five or thirty thousand dollars in the years between now and my sixtieth birthday.</p>
<p>“Now I pass up about twenty-five or thirty thousand of honest gain because I like being a detective, like the work. And liking work makes you want to do it as well as you can. Otherwise there’d be no sense to it. That’s the fix I am in. I don’t know anything else, don’t enjoy anything else, don’t want to know or enjoy anything else. You can’t weight that against any sum of money. Money’s good stuff. I haven’t anything against it. But in the past eighteen years I’ve been getting my fun out of chasing crooks and solving riddles. It’s the only kind of sport I know anything about, and I can’t imagine a pleasanter future than twenty-some years more of it. I’m not going to blow that up.</p></blockquote>
<p>Excerpt from <cite>The Gutting of Couffignal</cite> by Dashiell Hammett. All monies are in 1927 US Dollars. It&#8217;d buy me a couple of nice houses today.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/03/25/otherwise-there%e2%80%99d-be-no-sense-to-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>This Usually Makes Me Feel Better</title>
		<link>http://vgable.com/blog/2010/02/09/this-usually-makes-me-feel-better/</link>
		<comments>http://vgable.com/blog/2010/02/09/this-usually-makes-me-feel-better/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 23:55:53 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Bug Bite]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Quotes]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[Ira Glass]]></category>
		<category><![CDATA[Motivation]]></category>
		<category><![CDATA[Practice]]></category>
		<category><![CDATA[Taste]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=569</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/-hidvElQ0xE&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/-hidvElQ0xE&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/02/09/this-usually-makes-me-feel-better/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>All Your Facebook Friend&#8217;s Phone Numbers</title>
		<link>http://vgable.com/blog/2010/02/06/all-your-facebook-friends-phone-numbers/</link>
		<comments>http://vgable.com/blog/2010/02/06/all-your-facebook-friends-phone-numbers/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 23:20:55 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Contact]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[Phone Numbers]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=567</guid>
		<description><![CDATA[http://www.facebook.com/friends/?filter=pfp That&#8217;s the link to all your facebook-friend&#8217;s phone numbers. Every time I see one of those &#8220;I need ya phone numbers&#8221; things on facebook I post that link. Please do the same. At least until the phone companies fix the real problem by automatically backing up contacts from the phone &#8220;in the cloud]]></description>
			<content:encoded><![CDATA[<p><span style="font-size:200%"><strong><a href="http://www.facebook.com/friends/?filter=pfp">http://www.facebook.com/friends/?filter=pfp</a></strong></span></p>
<p>That&#8217;s the link to <a href="http://www.facebook.com/friends/?filter=pfp">all your facebook-friend&#8217;s phone numbers</a>.</p>
<p>Every time I see one of those &#8220;I need ya phone numbers&#8221; things on facebook I post that link. Please do the same. At least until <a href="http://vgable.com/blog/2008/09/24/i-lost-my-phone-and-need-ur-numbers/">the phone companies fix the real problem</a> by automatically backing up contacts from the phone &#8220;in the cloud</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/02/06/all-your-facebook-friends-phone-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EULA Today Fail</title>
		<link>http://vgable.com/blog/2010/01/15/eula-today-fail/</link>
		<comments>http://vgable.com/blog/2010/01/15/eula-today-fail/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 09:16:54 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[EULA]]></category>
		<category><![CDATA[Failure]]></category>
		<category><![CDATA[Legal]]></category>
		<category><![CDATA[License]]></category>
		<category><![CDATA[USA TODAY]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=557</guid>
		<description><![CDATA[The EULA1 for the USA TODAY iPhone App starts off General These Terms of Service govern your use of the USATODAY.com website (the &#8220;Site&#8221;) only and do not govern your use of other USA TODAY services, such as services offered by the USA TODAY print newspaper. Clearly this invalidates the agreement on the iPhone, since [...]]]></description>
			<content:encoded><![CDATA[<p>The EULA<sup>1</sup> for the <a href="http://www.usatoday.com/iphone/">USA TODAY iPhone App</a> starts off</p>
<blockquote>
<h3>General</h3>
<p>These Terms of Service govern your use of the USATODAY.com website (the &#8220;Site&#8221;) only and do not govern your use of other USA TODAY services, such as services offered by the USA TODAY print newspaper.
</p></blockquote>
<p>Clearly this <b>invalidates the agreement on the iPhone</b>, since the iPhone App is <em>not</em> &#8220;the USATODAY.com website&#8221;.</p>
<p>This is mildly embarrassing for USA TODAY, and even more of a fumble for <a href="http://mercuryintermedia.com/">Mercury Intermedia</a>, who built the app. But I can&#8217;t think of any way this actually <em>hurts</em> anyone, even in theory. Users are already bound by the <a href="http://www.apple.com/legal/itunes/appstore/us/terms.html">App Store Terms and Conditions</a>, so why bother putting your own EULA (that nobody&#8217;s ever going to read much less care about) in your app?</p>
<p><sup>1</sup><small>To see the EULA, tap that little <em>i</em> near the bottom left of the homescreen, then tap <strong>Terms of Service</strong>. The text above was copied from version 1.5 of the <a href="http://www.usatoday.com/iphone/">USA TODAY iPhone App</a>.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/01/15/eula-today-fail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A C &amp;Puzzler[]</title>
		<link>http://vgable.com/blog/2009/12/25/a-c-puzzler/</link>
		<comments>http://vgable.com/blog/2009/12/25/a-c-puzzler/#comments</comments>
		<pubDate>Fri, 25 Dec 2009 20:35:54 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Bug Bite]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Arrays]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[Pointers]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=547</guid>
		<description><![CDATA[Here&#8217;s a C-puzzler for you! given this function, void foo(char* s){ printf("s is at: %p\n s is: '%s'\n", s, s); } and that char s[] = "Joy!"; foo(s); prints out s is at: 0xbffff46b s is: &#8216;Joy!&#8217; what will this next line print? foo(&#038;s); //WHAT WILL THIS DO? Pick all that apply: Print &#8220;Joy!&#8221; Print [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a C-puzzler for you!</p>
<p>given this function,</p>
<pre>void foo(char* s){
	printf("s is at: %p\n s is: '%s'\n", s, s);
}</pre>
<p>and that</p>
<pre>
char s[] = "Joy!";
foo(s);
</pre>
<p>prints out</p>
<blockquote><p>
s is at: <code>0xbffff46b</code><br />
s is: &#8216;Joy!&#8217;
</p></blockquote>
<p>what will this next line print?</p>
<pre><strong>foo(&#038;s); //WHAT WILL THIS DO?</strong>
</pre>
<p>Pick all that apply:</p>
<ol>
<li>Print &#8220;Joy!&#8221;</li>
<li>Print garbage</li>
<li>Print the same address for <code>s</code></li>
<li>Print the a different address for <code>s</code></li>
<li>Crash</li>
<li>Go into an Infinite loop</li>
</ol>
<h3>Answer</h3>
<p><small>Answer: one and three</small></p>
<p>Yeah, it&#8217;s not what I expected either, especially since:</p>
<pre>@encode(__typeof__(s)) = [5c]
@encode(__typeof__(&#038;s)) = ^[5c]</pre>
<p>In fact, all of these are equvalent (modulo type warnings):</p>
<pre>
foo(s);
foo(&#038;s[0]);
foo(&#038;(*s));
foo(&#038;s);
</pre>
<p><a href="http://www.reddit.com/r/programming/comments/i6k5/jeez_after_all_these_years_a_c_array_vs_pointer">Explanation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2009/12/25/a-c-puzzler/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

