<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Hi. I’m Mike Swanson, technologist, owner of Juicy Bits, and former Microsoft employee of 11½ years. This is my blog.Have a comment or question? Contact me.</description><title>Mike Swanson's Blog</title><generator>Tumblr (3.0; @michaeldswanson)</generator><link>http://blog.mikeswanson.com/</link><item><title>This week, I’ve been working on a radial menu control for...</title><description>&lt;span id="video_player_20184275820"&gt;[&lt;a href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" target="_blank"&gt;Flash 10&lt;/a&gt; is required to watch video.]&lt;/span&gt;&lt;script type="text/javascript"&gt;renderVideo("video_player_20184275820",'http://blog.mikeswanson.com/video_file/20184275820/tumblr_m1prvyVXRN1r3cke2',400,300,'poster=http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_m1prvyVXRN1r3cke2_frame1.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_m1prvyVXRN1r3cke2_frame2.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_m1prvyVXRN1r3cke2_frame3.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_m1prvyVXRN1r3cke2_frame4.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_m1prvyVXRN1r3cke2_frame5.jpg')&lt;/script&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This week, I’ve been working on a radial menu control for an upcoming Juicy Bits app. I recorded a short video that illustrates the evolution of the project and shows the menu in action. The radial menu has proven to be a quick and convenient way to select context-sensitive options. Also, because the buttons are equidistant from the center, your finger doesn’t have to travel around the screen as much.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/20184275820</link><guid>http://blog.mikeswanson.com/post/20184275820</guid><pubDate>Fri, 30 Mar 2012 13:32:10 -0700</pubDate></item><item><title>Smaller Apps with Vector Images</title><description>&lt;p&gt;&lt;strong&gt;3/26/2012: Added an update at the end of the post.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For the past couple of weeks, I’ve been working on new vector processing code for a future update of my &lt;a href="http://click.linksynergy.com/fs-bin/click?id=q2YUtcu6v/A&amp;amp;offerid=146261.419957803&amp;amp;type=2&amp;amp;subid=0"&gt;Halftone&lt;/a&gt; app for iOS. As I’ve &lt;a href="http://blog.mikeswanson.com/post/17160200980/i-have-no-idea"&gt;mentioned before&lt;/a&gt;, Halftone draws a lot of its graphics using vectors, and as a result, it automatically takes advantage of the new iPad Retina display. These recent experiments have forced me to take a closer look at vector handling in iOS, and I thought I’d share what I’ve learned.&lt;/p&gt;
&lt;p&gt;By the end of this post, I hope to convince you that a vector version of your app may require only 14.8% of the space that a bitmap-based Retina version requires.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;Before I get going, it’s important to mention that—while I love vectors—I love bitmaps too! Halftone contains a lot of bitmap images, and I spend a lot more time in Photoshop than I do in Illustrator. So don’t walk away thinking that I’m recommending vectors for everything.&lt;/p&gt;
&lt;p&gt;That said, here’s how I generally break it down:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;For small images that aren’t photographic, I use PNG images. This includes icons, UI elements, and logos, to name a few. If every pixel and edge matters, a bitmap provides the most control.&lt;/li&gt;
&lt;li&gt;For photographic images, I use JPGs, no matter what the size.&lt;/li&gt;
&lt;li&gt;For large images that aren’t photographic, it depends…&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Though the iOS SDK has great support for bitmap image formats like JPG and PNG, it doesn’t include any support for vector image formats like SVG or EPS. To be fair, &lt;a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebView_Class/Reference/Reference.html"&gt;the UIWebView control&lt;/a&gt; can be used in a pinch, but it doesn’t provide access to the raw image data (including its alpha channel), and it’s often a much heavier solution than necessary.&lt;/p&gt;
&lt;p&gt;The current version of Halftone draws each vector with Objective-C code that’s been exported directly from Adobe Illustrator using a custom plug-in that I’ve built. This method works well, but it requires that the vector image code is compiled into the app itself before it’s submitted to the App Store. One downside of this method is that there’s no way to enable a Halftone user to add their own vector image files. Nor is there a way to include in-app purchase for vector images (apps are not allowed to download code after-the-fact). These limitations led me to consider a new workflow.&lt;/p&gt;
&lt;p&gt;Ever since the advent of HTML5, SVG files have enjoyed a bit of a resurgence (the format was invented in 1999), and they’re supported by all modern web browsers. The two dominant vector editing tools, &lt;a href="http://www.adobe.com/products/illustrator.html"&gt;Adobe Illustrator&lt;/a&gt; and the Open Source &lt;a href="http://inkscape.org/"&gt;Inkscape&lt;/a&gt;, have excellent support for creating and editing SVG documents. This means that any image that can be opened by those tools can easily be saved to an SVG file.&lt;/p&gt;
&lt;p&gt;My goal was clear: I needed to find a SVG parser and renderer for iOS!&lt;/p&gt;
&lt;p&gt;After some searching, I found a few projects that purported to handle simple SVG files but none that claimed robust support for the format (at least robust enough). So, I downloaded each project, and it only took a few quick tests to find the rough edges. The existing projects are good enough for basic support, and if that’s all you need, you’ll probably be fine with any of them.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/adamgit/SVGKit"&gt;Adamgit’s fork of Matt Rajca’s SVGKit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/splashdust/SVGQuartzRenderer"&gt;SVGQuartzRenderer by Splashdust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cmkilger/CKSVG"&gt;CKSVG by cmkilger&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Like any good developer, I have a healthy dose of naïveté. If I had realized what I was getting myself into, I probably wouldn’t have started. As it goes, I’ve spent the last couple of weeks nearly memorizing the &lt;a href="http://www.w3.org/TR/SVG/"&gt;SVG specification&lt;/a&gt;, and I’ve become more than familiar with the &lt;a href="http://www.w3.org/TR/CSS21/cascade.html"&gt;rules of the CSS cascade&lt;/a&gt;. Thankfully, I have no need for scripting, external style sheets, events, or any of the fancy text-based support, and I’ve been able to avoid those sections of the spec.&lt;/p&gt;
&lt;p&gt;I’ve built a test app that allows me to open an SVG file and display the UIWebView/WebKit-rendered version by holding down a “Show Reference” button. There’s also an “onion skin” mode that fades the UIWebView to 50% so that I can see both renderings simultaneously, though it’s not as useful as flipping back-and-forth with the button. As an aside, does anyone remember those advertisements (perhaps from National Geographic?) where they’d show an elephant, then flip between a normal version and a version that didn’t include its trunk? If memory serves, they’d say something like: “did you see that?” Well, that’s me testing my renders against WebKit; I’m constantly looking for pixels that appear or disappear.&lt;/p&gt;
&lt;p&gt;To test my parsing and rendering, I’ve used the &lt;a href="http://www.w3.org/Graphics/SVG/WG/wiki/Test_Suite_Overview"&gt;SVG test suite&lt;/a&gt;. The suite is incredibly useful, as there are many complex rules that—no matter how many times you read the spec—can be ambiguous. Many of the tests use crafty or clever techniques, and they’re quick to expose issues. I’ve also collected a set of common SVG files, and as acid tests, I’ve exported some extremely complex vector images from Adobe Illustrator. Here’s a file from the SVG test suite rendered by my test app on the left and by UIWebView/WebKit on the right:&lt;/p&gt;
&lt;p align="center" class="nolink"&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Path%20Example.png" title="Path Example"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f6o9H8Dr1r0hcti.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To test the extremes, here’s the &lt;a href="http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/showcase/illustrator/pdfs/risetogether-howto.pdf"&gt;Rise Together&lt;/a&gt; sample that ships with Adobe Illustrator CS5. The exported SVG file is a full 21MB (!), and it takes my non-optimized test app a full 30 seconds to parse and render it! As before, my version is on the left, and the UIWebView version is on the right. Not sure what UIWebView is up to here, but I’ll take the “win,” as I usually lose to WebKit.&lt;/p&gt;
&lt;p align="center" class="nolink"&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Rise%20Together.png" title="Rise Together"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f6oodyxk1r0hcti.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;Rise Together&lt;/em&gt; close-up from a Retina display:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f7a3YRKa1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Here’s another acid test that uses the &lt;em&gt;Yellowstone Map&lt;/em&gt; sample from Illustrator. It’s not as complex as &lt;em&gt;Rise Together&lt;/em&gt;, but it includes a lot of text. While my needs don’t require robust text support, it’s good to see that the test app can cover the basics. As a side note, I’ve noticed that UIWebView appears to ignore some font kerning and ligature information while rendering.&lt;/p&gt;
&lt;p align="center" class="nolink"&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Yellowstone%20Map.png" title="Yellowstone Map"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f6ozv7od1r0hcti.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;Yellowstone Map&lt;/em&gt; close-up from a Retina display:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f7b6nExQ1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Here’s a more reasonable example that illustrates a plant cell structure. It’s easy to imagine diagrams like this being featured in reference or magazine apps:&lt;/p&gt;
&lt;p align="center" class="nolink"&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Plant%20Cell%20Structure.png" title="Plant Cell Structure"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f6paw1ak1r0hcti.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;Plant Cell Structure&lt;/em&gt; close-up from a Retina display:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f7btTYsc1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Finally, here’s a popular lion sample that hits the sweet spot. It parses and renders quickly, and it’s easy to imagine the image (along with its alpha channel) being used as an element or character in an app:&lt;/p&gt;
&lt;p align="center" class="nolink"&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Lion.png" title="Lion"&gt;&lt;img src="http://media.tumblr.com/tumblr_m1f6pkEkUi1r0hcti.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Being vector-based, all of these images can be rendered at any size, and they can easily be transformed (positioned, scaled, rotated, skewed, etc.) without any loss of quality.&lt;/p&gt;
&lt;p&gt;Another major benefit of vector-based formats is file size. SVG documents are XML documents, and they’re very compressible. On average, my sample files ended up being around 33% of their original size when packaged in an &lt;a href="http://en.wikipedia.org/wiki/.ipa_%28file_extension%29"&gt;IPA file&lt;/a&gt; (the compressed format that’s used to package iOS apps).&lt;/p&gt;
&lt;p&gt;To compare format sizes, I used four versions of eight different SVG test files:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The original, untouched SVG file.&lt;/li&gt;
&lt;li&gt;A PNG export of the SVG file from Adobe Illustrator (including an alpha channel) that fills the 2,048 x 1,536 pixel dimensions of the new iPad Retina display and preserves its aspect ratio.&lt;/li&gt;
&lt;li&gt;A PNG that fills the 1,024 x 768 pixel dimensions of the standard display on an iPad/iPad 2.&lt;/li&gt;
&lt;li&gt;A compiled stream of Objective-C code that uses &lt;a href="http://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/drawingwithquartz2d/Introduction/Introduction.html"&gt;Quartz 2D&lt;/a&gt; commands to draw the SVG file. The code is exported by my test app after the parsing phase and it represents the steps that would be required by almost any SVG renderer. It’s not completely optimized, but it’s still useful for comparison. Other than loading a bitmap, it’s about as fast as you can get.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;To accurately measure the payload of each image as it would be distributed in an app, I started by creating an image-free reference IPA file. Then, one by laborious one, I built individual IPA files for each sample image using the four different data types (that’s a total of 1 + (8 x 4) = 33 IPA files!). Finally, I calculated the difference between the reference IPA file and each IPA + image file to get a measure of its payload in bytes.&lt;/p&gt;
&lt;p&gt;Here are the results for the eight sample files (in bytes):&lt;/p&gt;
&lt;table width="100%" cellspacing="5"&gt;&lt;thead&gt;&lt;tr valign="bottom"&gt;&lt;td&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;SVG&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;SVG&lt;br/&gt;in IPA&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;Retina&lt;br/&gt;PNG&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;Ret PNG&lt;br/&gt;in IPA&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;Standard&lt;br/&gt;PNG&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;Std PNG&lt;br/&gt;in IPA&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;Obj-C&lt;br/&gt;Code&lt;/strong&gt;&lt;/td&gt;
  &lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Butterfly.png" title="Butterfly"&gt;Butterfly&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;31,187&lt;/td&gt;
    &lt;td align="right"&gt;10,860&lt;/td&gt;
    &lt;td align="right"&gt;211,519&lt;/td&gt;
    &lt;td align="right"&gt;189,155&lt;/td&gt;
    &lt;td align="right"&gt;202,590&lt;/td&gt;
    &lt;td align="right"&gt;185,621&lt;/td&gt;
    &lt;td align="right"&gt;22,984&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Giza%20Pyramid.png" title="Giza Pyramid Complex"&gt;Giza Pyramid Complex&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;934,950&lt;/td&gt;
    &lt;td align="right"&gt;281,182&lt;/td&gt;
    &lt;td align="right"&gt;320,211&lt;/td&gt;
    &lt;td align="right"&gt;309,018&lt;/td&gt;
    &lt;td align="right"&gt;327,854&lt;/td&gt;
    &lt;td align="right"&gt;355,424&lt;/td&gt;
    &lt;td align="right"&gt;411,178&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Lion.png" title="Lion"&gt;Lion&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;18,324&lt;/td&gt;
    &lt;td align="right"&gt;6,917&lt;/td&gt;
    &lt;td align="right"&gt;291,593&lt;/td&gt;
    &lt;td align="right"&gt;281,530&lt;/td&gt;
    &lt;td align="right"&gt;260,699&lt;/td&gt;
    &lt;td align="right"&gt;264,833&lt;/td&gt;
    &lt;td align="right"&gt;36,704&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Metadata%20Example.png" title="Metadata Example"&gt;Metadata Example&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;21,675&lt;/td&gt;
    &lt;td align="right"&gt;8,876&lt;/td&gt;
    &lt;td align="right"&gt;143,347&lt;/td&gt;
    &lt;td align="right"&gt;129,291&lt;/td&gt;
    &lt;td align="right"&gt;97,823&lt;/td&gt;
    &lt;td align="right"&gt;99,179&lt;/td&gt;
    &lt;td align="right"&gt;18,310&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Plant%20Cell%20Structure.png" title="Plant Cell Structure"&gt;Plant Cell Structure&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;189,161&lt;/td&gt;
    &lt;td align="right"&gt;46,420&lt;/td&gt;
    &lt;td align="right"&gt;436,100&lt;/td&gt;
    &lt;td align="right"&gt;432,548&lt;/td&gt;
    &lt;td align="right"&gt;316,653&lt;/td&gt;
    &lt;td align="right"&gt;333,397&lt;/td&gt;
    &lt;td align="right"&gt;184,332&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Rise%20Together.png" title="Rise Together"&gt;Rise Together&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;21,550,150&lt;/td&gt;
    &lt;td align="right"&gt;8,212,273&lt;/td&gt;
    &lt;td align="right"&gt;1,425,383&lt;/td&gt;
    &lt;td align="right"&gt;1,399,053&lt;/td&gt;
    &lt;td align="right"&gt;969,032&lt;/td&gt;
    &lt;td align="right"&gt;986,736&lt;/td&gt;
    &lt;td align="right"&gt;359,420&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Tiger.png" title="Tiger"&gt;Tiger&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;96,719&lt;/td&gt;
    &lt;td align="right"&gt;31,780&lt;/td&gt;
    &lt;td align="right"&gt;402,998&lt;/td&gt;
    &lt;td align="right"&gt;397,482&lt;/td&gt;
    &lt;td align="right"&gt;308,423&lt;/td&gt;
    &lt;td align="right"&gt;302,995&lt;/td&gt;
    &lt;td align="right"&gt;79,902&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.mikeswanson.com/blog/images/vectorsvectorsvectors/Yellowstone%20Map.png" title="Yellowstone Map"&gt;Yellowstone Map&lt;/a&gt;&lt;/td&gt;
    &lt;td align="right"&gt;2,194,130&lt;/td&gt;
    &lt;td align="right"&gt;550,520&lt;/td&gt;
    &lt;td align="right"&gt;723,806&lt;/td&gt;
    &lt;td align="right"&gt;729,014&lt;/td&gt;
    &lt;td align="right"&gt;565,504&lt;/td&gt;
    &lt;td align="right"&gt;563,129&lt;/td&gt;
    &lt;td align="right"&gt;1,978,212&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;As you can see from the table, images that are comprised of strokes, fills, and gradients can be represented very efficiently as SVG files and compiled Objective-C. The more complex an image becomes (and therefore, the more instructions it takes to describe the image), the more PNG files start to show their strength. Sometimes, it’s just quicker and easier to store the result of a parse/render than it is to draw an image when you need it. If you’re wondering, yes, I double-checked the Giza PNG numbers.&lt;/p&gt;
&lt;p&gt;Remember that if you’re shipping an iPad Retina-capable app, you need to include at least two PNG files for each image: one at standard resolution, and one at Retina resolution. With vector images, you only ever have to store one, and it’ll never change in size. This can be a huge payload win. For apps that share artwork with desktop apps, using vectors could also help to future-proof assets in anticipation of &lt;a href="http://arstechnica.com/apple/news/2012/03/signs-in-mountain-lion-point-to-retina-display-coming-this-summer.ars"&gt;possible Retina support in Mountain Lion&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s a look at the relative payload sizes for each of the sample images:&lt;/p&gt;
&lt;table width="60%" cellspacing="5"&gt;&lt;thead&gt;&lt;tr valign="bottom"&gt;&lt;td&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;SVG&lt;br/&gt;App&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;PNG&lt;br/&gt;App&lt;/strong&gt;&lt;/td&gt;
    &lt;td align="right"&gt;&lt;strong&gt;SVG/PNG&lt;/strong&gt;&lt;/td&gt;
  &lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Butterfly&lt;/td&gt;
    &lt;td align="right"&gt;10,860&lt;/td&gt;
    &lt;td align="right"&gt;374,776&lt;/td&gt;
    &lt;td align="right"&gt;2.9%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Giza Pyramid Complex&lt;/td&gt;
    &lt;td align="right"&gt;281,182&lt;/td&gt;
    &lt;td align="right"&gt;664,442&lt;/td&gt;
    &lt;td align="right"&gt;42.3%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Lion&lt;/td&gt;
    &lt;td align="right"&gt;6,917&lt;/td&gt;
    &lt;td align="right"&gt;546,363&lt;/td&gt;
    &lt;td align="right"&gt;1.3%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Metadata Example&lt;/td&gt;
    &lt;td align="right"&gt;8,876&lt;/td&gt;
    &lt;td align="right"&gt;228,470&lt;/td&gt;
    &lt;td align="right"&gt;3.9%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Plant Cell Structure&lt;/td&gt;
    &lt;td align="right"&gt;46,420&lt;/td&gt;
    &lt;td align="right"&gt;765,945&lt;/td&gt;
    &lt;td align="right"&gt;6.1%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Rise Together&lt;/td&gt;
    &lt;td align="right"&gt;8,212,273&lt;/td&gt;
    &lt;td align="right"&gt;2,385,789&lt;/td&gt;
    &lt;td align="right"&gt;344.2%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tiger&lt;/td&gt;
    &lt;td align="right"&gt;31,780&lt;/td&gt;
    &lt;td align="right"&gt;700,477&lt;/td&gt;
    &lt;td align="right"&gt;4.5%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Yellowstone Map&lt;/td&gt;
    &lt;td align="right"&gt;550,520&lt;/td&gt;
    &lt;td align="right"&gt;1,292,143&lt;/td&gt;
    &lt;td align="right"&gt;42.6%&lt;/td&gt;
  &lt;/tr&gt;&lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The last big issue to consider is performance. Bitmap images are pre-baked and ready to go…just decompress the data and pump pixels to the screen. Vector images require additional parsing, computation, and drawing, and they often take much longer to render. For simple images that don’t need to be available instantly, this can be done in real-time (as examples, both the Butterfly and Lion sample images take about 0.28 seconds to load, parse, and render on a 3rd generation iPad using my non-optimized test app). For images that need to be available instantly, this processing overhead may be unacceptable. One strategy is to parse and render the SVG image the first time, then cache the final bitmap to disk. This way, you get the benefit of shipping a much smaller app, the quality of near-infinite-resolution vector images, and the raw performance of a bitmap.&lt;/p&gt;
&lt;p&gt;The compiled Objective-C code method saves the payload of the parser/renderer but is just a bit heavier than an embedded SVG file. However, as there is no parsing/cascading step to perform, the code is very fast. It’s an interesting compromise for images that can be baked-in to the app.&lt;/p&gt;
&lt;p&gt;Imagine the characters and backgrounds for a game like &lt;a href="http://www.rovio.com/"&gt;Angry Birds&lt;/a&gt;. These relatively simple line-art images could be drawn off-screen using vectors between levels, then sent to the screen as bitmaps (this is probably what they’re doing anyway, but with OpenGL). Or, they could be rendered and cached to disk the first time the app runs. There are lots of apps that use vector-based art but ship with PNG versions.&lt;/p&gt;
&lt;p&gt;To summarize, if we throw out the &lt;em&gt;Rise Together&lt;/em&gt; acid test where SVG clearly loses to PNG, on average, a vector-based app that embeds SVG files requires around 14.8% of the space that a Retina-capable app requires with its dual PNG files. Put another way, you can include more than six times the graphical content in the same payload size without losing any quality, all while future-proofing your assets.&lt;/p&gt;
&lt;p&gt;Just remember that the right format depends on the nature of your content and the appropriate balance of payload and performance. Only you can know what’s best based on your needs, and as always, test, test, test.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update on 3/26/2012&lt;/strong&gt;: I’ve received a lot  of questions about the technical nature of the SVG parser and what I intend to  do with it. The technical details could probably fill a whole article, but I’ll  try to summarize them here.&lt;/p&gt;
&lt;p&gt;It wasn’t clear in the original post, but  I’ve written a brand new SVG parser and renderer from scratch that isn’t based  on any of the referenced projects. It offers near full support for the  following SVG elements: &lt;em&gt;circle&lt;/em&gt;, &lt;em&gt;clipPath&lt;/em&gt;, &lt;em&gt;defs&lt;/em&gt;, &lt;em&gt;ellipse&lt;/em&gt;, &lt;em&gt;fill&lt;/em&gt;, &lt;em&gt;font-face&lt;/em&gt;, &lt;em&gt;g&lt;/em&gt;, &lt;em&gt;image&lt;/em&gt; (including embedded base64-encoded  images), &lt;em&gt;line&lt;/em&gt;, &lt;em&gt;linearGradient&lt;/em&gt;, &lt;em&gt;path&lt;/em&gt;, &lt;em&gt;pattern&lt;/em&gt;, &lt;em&gt;polygon&lt;/em&gt;, &lt;em&gt;polyline&lt;/em&gt;, &lt;em&gt;radialGradient&lt;/em&gt;, &lt;em&gt;rect&lt;/em&gt;, &lt;em&gt;stroke&lt;/em&gt;, &lt;em&gt;svg&lt;/em&gt;, &lt;em&gt;symbol&lt;/em&gt;, &lt;em&gt;text&lt;/em&gt;, &lt;em&gt;tspan&lt;/em&gt;, and &lt;em&gt;use&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The parser performs an abbreviated CSS  cascade that respects both style and presentation attributes (no support for  external style sheets, as I have no need for them). It supports all length  units and their associated computations, including percentages, ems, exs,  points, etc. It has full &lt;em&gt;viewBox&lt;/em&gt; support, including &lt;em&gt;preserveAspectRatio&lt;/em&gt; and &lt;em&gt;objectBoundingBox&lt;/em&gt; units, and support for an  arbitrary combination of transforms. IRI/xlink references are also correctly  resolved and used.&lt;/p&gt;
&lt;p&gt;Additionally, it supports fills and  strokes that use solid colors, gradients, and patterns.&lt;/p&gt;
&lt;p&gt;The Objective-C generation is based on a  “Quartz 2D emulator” that understands contexts and states and outputs the  minimum set of commands to render its output.&lt;/p&gt;
&lt;p&gt;As far as release plans, I hadn’t given  it much thought. My experiments and work are currently focused on Halftone and  future Juicy Bits apps, but if there’s enough interest, I’d consider releasing  it in some form.&lt;/p&gt;
&lt;p&gt;For what it’s worth, I’ve exchanged a few  e-mails with the SVGKit folks, and it sounds like they’re pushing for much more  robust support in future releases.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/19874621055</link><guid>http://blog.mikeswanson.com/post/19874621055</guid><pubDate>Sat, 24 Mar 2012 20:45:00 -0700</pubDate></item><item><title>Halftone and the iPad Retina Display</title><description>&lt;p&gt;Today is delivery day for the new iPad! So, I thought I&amp;#8217;d show some differences between the non-Retina display on the original iPad and iPad 2, and the new Retina display on the iPad (3rd generation) using &lt;a href="http://www.juicybitssoftware.com/halftone/" title="Halftone"&gt;Halftone&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, it seems common to miscalculate the math behind the new screen. While each dimension has been doubled, because it&amp;#8217;s been doubled in both dimensions, there are actually four times (2 x 2 = 4) as many pixels on the screen. This diagram illustrates the difference:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m0zn2vdiXY1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;That&amp;#8217;s a lot of pixels! If you do the math, you&amp;#8217;ll discover that the non-Retina display has 786,432 pixels, and the Retina display has 3,145,728! Not only does the Retina display have four times as many pixels, but those pixels are condensed into the same physical screen size of 9.7 inches (diagonal). Put another way, you could squeeze four iPad 2 screens into the same physical size as one Retina screen on the new iPad. Wow!&lt;/p&gt;
&lt;p&gt;So how does it look? As many people have mentioned, it&amp;#8217;s tough to show the difference without having an actual screen in front of you, but I&amp;#8217;ll do my best with what we have.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an actual screenshot from Halftone on a non-Retina display. So that it matches the same dimensions as the Retina example below, I&amp;#8217;ve used Photoshop&amp;#8217;s &lt;a href="http://en.wikipedia.org/wiki/Image_scaling" title="Nearest Neighbor"&gt;Nearest Neighbor&lt;/a&gt; algorithm to resample it at 200%.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m0zn3msbpC1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;This is how the same area looks on the new iPad Retina display:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m0zn3qZNel1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;If we zoom-in even closer (200%)—again using Nearest Neighbor—you can really start to appreciate the additional detail. Here&amp;#8217;s the non-Retina display:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m0zn3vyFG01r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;And the same image on a Retina display:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_m0zn3zVVuJ1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;The difference in quality is truly stunning.&lt;/p&gt;
&lt;p&gt;For those who are curious, it didn&amp;#8217;t take a lot of extra work to add full iPad Retina support to Halftone. Being a Universal app that also runs on iPhone and iPod touch, Halftone has long supported Retina resolution on the iPhone 4/4S. This meant that most of the icons and imagery in Halftone was already at Retina resolution.&lt;/p&gt;
&lt;p&gt;Also, &lt;a href="http://blog.mikeswanson.com/post/17160200980/i-have-no-idea" title="Halftone and Vector Graphics"&gt;Halftone relies heavily on vector graphics&lt;/a&gt; for its borders, speech balloons, and stamps. As a result, it required no additional work for these elements to take full advantage of the new display. Another side-effect is that the additional memory in the new iPad also means that larger images can be processed and exported at full quality.&lt;/p&gt;
&lt;p&gt;Finally, there&amp;#8217;s legitimate concern that Retina-enabled iPad apps will result in much larger app sizes (and therefore require more bandwidth to download and store them on the device). In Halftone&amp;#8217;s case, though, the increase is only around 1.5MB, and it&amp;#8217;s due to the default screenshots that display when the app launches in portrait or landscape orientation. Otherwise, the vector imagery requires no additional space at all. Aren&amp;#8217;t vectors great!?&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re a Halftone user, I hope you love how it looks on the new display.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/19404769380</link><guid>http://blog.mikeswanson.com/post/19404769380</guid><pubDate>Fri, 16 Mar 2012 11:19:00 -0700</pubDate></item><item><title>My wife and I visited Andy Keck today to see his amazing 1922...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_m0p42hPEjU1r3cke2o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;My wife and I visited &lt;a href="http://andykeck.com/" title="Andy Keck"&gt;Andy Keck&lt;/a&gt; today to see his amazing 1922 Intertype Model C machine (named Eloise). Andy and I met via Twitter because of our mutual interest in &lt;a href="http://linotypefilm.com/" title="Linotype: The Film"&gt;Linotype: The Film&lt;/a&gt;, and we ran into each other at the Seattle premiere this past Wednesday evening. The film is fantastic, and seeing the Intertype machine in-person made it even better (&lt;a href="http://photos.mikeswanson.com/intertype" title="Intertype Open House Photos"&gt;more photos&lt;/a&gt;). Thank you, Andy!&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/19089426947</link><guid>http://blog.mikeswanson.com/post/19089426947</guid><pubDate>Sat, 10 Mar 2012 17:00:02 -0800</pubDate><category>Intertype</category></item><item><title>Confusing iOS Location Services Prompt</title><description>&lt;p&gt;Two days ago, I released an &lt;a href="http://www.juicybitssoftware.com/2012/02/23/halftone-1-9-now-available/" title="Halftone 1.9 Released"&gt;update to my Halftone app&lt;/a&gt; for iOS that adds an oft-requested feature: the ability to open photos directly from Facebook, Flickr, and Instagram. The new image picker is the result of more than a month of design and development work, the same code base runs across all devices (with a tailored UI for each device), and it serves as a drop-in replacement for the native iOS image picker. I’m proud of the final product, so I was dismayed to read one of the first tweets about the new version:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One of my favorite apps (Halftone) just updated &amp;amp; added location services as a &amp;#8220;key&amp;#8221; to continue using the app &amp;#8230; WTF?? DELETED!!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Shortly thereafter from another customer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;@juicybits requiring using location services to use app?? 1 star rating&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But I’m getting ahead of myself.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;Prior to this update, Halftone used the native, built-in &lt;a href="https://developer.apple.com/library/ios/#documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html" title="UIImagePicker"&gt;UIImagePicker control&lt;/a&gt; that every iOS owner is familiar with. It’s the same control that you see when opening an image in most apps. From the app’s perspective, using the image picker is straightforward:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The app asks iOS to display the image picker&lt;/li&gt;
&lt;li&gt;You interact with your albums and photos and select an image (or choose to cancel)&lt;/li&gt;
&lt;li&gt;The selected image is handed to the app for its use&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Note that the app has no direct access to any of the images, and in fact, it doesn’t even know how many albums or images are on your device. All it knows about is the single image that you picked, and when that image is handed to the app, almost none of its &lt;em&gt;metadata &lt;/em&gt;is included (like the date and time the photo was taken, exposure information, and GPS coordinates).&lt;/p&gt;
&lt;p&gt;For apps that need access to a single image without metadata using the standard look-and-feel, the UIImagePicker control is a fantastic, familiar, and easy to use solution.&lt;/p&gt;
&lt;p&gt;However, if an app requires a customized version of this workflow, if it wants to provide a different presentation, or if it needs access to any image metadata, it has to use the ALAssetsLibrary functionality that Apple introduced in iOS 4.0. While ALAssetsLibrary does not provide any standard user interface elements, it does enable an app to access all of the albums and photos on a device.&lt;/p&gt;
&lt;p&gt;And—most importantly for this article—ALAssetsLibrary has access to all of the image metadata.&lt;/p&gt;
&lt;p&gt;For Halftone, I wanted to build an image picker that would take full advantage of the available screen space, work in all orientations, and have a single codebase for all devices. Not only did it need to pick photos from the device, but it also needed to allow users to just-as-easily pick photos from Facebook, Flickr, and Instagram in a consistent way. So that’s what I built, and as you can now surmise, the new image picker relies on ALAssetsLibrary. Here’s an iPhone screenshot of the new image picker on the Facebook tab:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lzyvn8MLLz1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Many modern cameras and most smartphones (including the iPhone) can automatically embed GPS coordinates that record where a photo was taken. These coordinates are stored in the image metadata, and if you’ve ever used an app that places photos on a map, it’s easy to understand how this location information can be used. It’s likely that you have photos on your iPhone right now that contain these coordinates.&lt;/p&gt;
&lt;p&gt;For apps that only use the built-in UIImagePicker to open images, none of the GPS metadata is handed to the app. Not even the date and time the photo was taken. Just the image itself.&lt;/p&gt;
&lt;p&gt;For apps that use ALAssetsLibrary, though, all of the image metadata is available, including the GPS location. So, what do you think happens the first time any app tries to use ALAssetsLibrary? Bingo! Because the app could access the location where an image was taken, iOS displays this prompt:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lzyvnyWVBH1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;If you’ve read this far, the prompt may not be surprising at all. In fact, if you’re not surprised, I’ll pat myself on the back for a job well done. Good job, Mike!&lt;/p&gt;
&lt;p&gt;Well, if you’re among the one million+ casual Halftone users who will never (and should never) read this post, I can tell you that it’s baffling. Especially the misleading initial text: &lt;em&gt;“Halftone” Would Like to Use Your Current Location&lt;/em&gt;. No it wouldn’t. It doesn’t do anything with your location. As a matter of fact, it doesn’t even want to see the location metadata in your photo!&lt;/p&gt;
&lt;p&gt;Let’s remind ourselves of one user’s response to this prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;@juicybits requiring using location services to use app?? 1 star rating&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Without any context, this unexpected prompt makes it sound like Halftone is trying to track your location. For users who have heard about the &lt;a href="http://www.theverge.com/2012/2/15/2800397/ios-apps-contacts-privacy-permission" title="Recent Misappropriation of Address Book Data"&gt;recent misappropriation of address book data&lt;/a&gt; by well-known apps, it’s no surprise that they choose “Don’t Allow.” I’d do the exact same thing.&lt;/p&gt;
&lt;p&gt;The problem is that by disallowing this permission, Halftone can no longer use ALAssetsLibrary to read photos from the device…at all. From a user’s perspective, Halftone used to be a trusted app that allowed me to open my photos, but this “new and improved” update not only wants to track my location, but it won’t show me the photos on my own device! #epicfail!&lt;/p&gt;
&lt;p&gt;To explain why Halftone is prompting for Location Services approval, the new version displays this pop-up just before the prompt:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lzyvoebz3G1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Normally, I’d never try to explain a complex topic like this to a user who only wants to access their photo library. But, in this situation, it’s important that the user understands why they’re being asked, because the new functionality is dependent on approval. I loathe having to display this text.&lt;/p&gt;
&lt;p&gt;Other well-known iOS apps that use ALAssetsLibrary have tried similar approaches. For example, here’s the screen that Dropbox shows just prior to the approval prompt:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lzyvoqeEif1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;For Dropbox users who notice the small little arrow after “Permission is needed to access your photos,” they are treated to a long explanation similar to the one that Halftone uses. They even go so far as to provide a link to the &lt;a href="https://developer.apple.com/library/ios/#documentation/AssetsLibrary/Reference/ALAssetsLibrary_Class/Reference/Reference.html" title="ALAssetsLibrary"&gt;Apple developer documentation for ALAssetsLibrary&lt;/a&gt;, which contains this small snippet of text:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Special Considerations&lt;/strong&gt;&lt;br/&gt;This method will fail with error ALAssetsLibraryAccessGloballyDeniedError if the user has not enabled Location Services (in Settings &amp;gt; General).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Of course, the Dropbox app doesn’t depend on photo access, so denying this permission has no significant impact.&lt;/p&gt;
&lt;p&gt;Another example is Mixel, an iPad app by Khoi Vinh that does depend on access to photos. It’s a very well-designed app that takes advantage of ALAssetsLibrary to provide an improved user experience. I envy the simplicity of Mixel’s approach in that there is no attempt to explain anything about Location Services. The permission prompt is displayed by iOS, and if the permission is denied, the following screen is displayed:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lzyvp9hn1K1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Basically, it instructs the user to go into the Settings app to enable Location Services. Until that happens, Mixel has no access to photos on the device.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://openradar.appspot.com/10511637" title="ALAssetsLibrary Bug Report"&gt;Here’s a bug report&lt;/a&gt; by Sean Heber of Iconfactory explaining similar challenges. In this case, Twitterific uses ALAssetsLibrary to get the most-recent photo from the camera roll so it can easily be attached to a tweet. Based on what you’ve read in this post, you now understand why it’s necessary for Twitterific to use ALAssetsLibrary: it needs access to photos and their dates. From his report:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…after being deployed for only one day, the support issues involving the location services question are flooding in.&lt;/p&gt;
&lt;p&gt;Many people reflexively deny location permissions…&lt;/p&gt;
&lt;p&gt;We could present the user with an alert if they deny permission explaining what just happened, but that seems annoying, too, and we&amp;#8217;re not sure it&amp;#8217;d really help since it&amp;#8217;d happen after they already denied it meaning that to undo the &amp;#8220;Don&amp;#8217;t Allow&amp;#8221; damage, they&amp;#8217;d have to told to leave the app and hunt through Settings to flip a switch back on!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I couldn’t agree more.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://discussions.apple.com/thread/3752545?start=0&amp;amp;tstart=0"&gt;Here’s a post&lt;/a&gt; by Andreas Lindahl expressing a similar frustration with his recent app. He needed to use ALAssetsLibrary because the standard UIImagePicker control doesn’t support landscape orientation. He’s also seeing negative reviews, and his app has no interest in location metadata.&lt;/p&gt;
&lt;p&gt;So, what can be done to improve this situation?&lt;/p&gt;
&lt;p&gt;To start, let’s agree that ALAssetsLibrary provides functionality that the majority of photo apps (and other apps like Dropbox) can use to provide an improved user experience. It’s good for users, and it’s good for apps.&lt;/p&gt;
&lt;p&gt;Let’s also agree that the current &lt;em&gt;“App” Would Like to Use Your Current Location&lt;/em&gt; prompt is at least confusing, more likely misleading, and in some cases, even alarming to users.&lt;/p&gt;
&lt;p&gt;For apps that have no interest or use for location metadata (and I would argue that this is the vast majority), there’s no need for this information to be passed to the app.&lt;/p&gt;
&lt;p&gt;Here are two solutions that Apple could implement in a future version of iOS that would make the use of ALAssetsLibrary much more appealing to app developers. Only one of them would need to be implemented.&lt;/p&gt;
&lt;p&gt;The first option would be to add a parameter to ALAssetsLibrary during initialization that allows the app to request access to location metadata. In Halftone’s case, it would never ask for this permission, and as a result, there would be no Location Services prompt from iOS, there would be no “why are we asking for Location Services approval” explanation, and the new functionality would just work.&lt;/p&gt;
&lt;p&gt;The second option would be to continue to prompt for permission for ALAssetsLibrary but with a more appropriate message (e.g. “Halftone would like to use the location information in your photos”). If a user denies this permission, ALAssetsLibrary would still allow access to images, but it would also strip away any location metadata before handing the images to the app.&lt;/p&gt;
&lt;p&gt;Of these two options, I personally prefer the first, because it more accurately reflects the intentions of the app. Based on my experience, accurately codifying an app’s intentions will provide Apple with more architectural flexibility as ALAssetsLibrary continues to evolve in future releases.&lt;/p&gt;
&lt;p&gt;In the end, either of these improvements will make life better for users, app developers, and Apple. I think we all agree that protecting sensitive and private user information is a requirement, and I support proposals like the &lt;a href="http://www.marco.org/2012/02/17/ios-permission-dialogs" title="iOS Permission Dialogs"&gt;iOS permission dialogs&lt;/a&gt; that Marco Arment of Instapaper has outlined in his post. However, in the case of ALAssetsLibrary, the current heavy-handed approach is not only confusing users, but it is also preventing developers from providing an improved user experience in their apps.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/18269837647</link><guid>http://blog.mikeswanson.com/post/18269837647</guid><pubDate>Sat, 25 Feb 2012 13:08:00 -0800</pubDate></item><item><title>I Have No Idea</title><description>&lt;p&gt;In early December, 2011, I was both surprised and flattered to discover that Apple had named &lt;a href="http://click.linksynergy.com/fs-bin/click?id=q2YUtcu6v/A&amp;amp;offerid=146261.419957803&amp;amp;type=2&amp;amp;subid=0" title="Halftone"&gt;Halftone&lt;/a&gt; as one of the best photo apps in its &lt;a href="http://www.itunes.com/AppStoreRewind" title="App Store Rewind 2011"&gt;App Store Rewind 2011&lt;/a&gt;. Since then, I’ve received a lot of e-mail asking me how I did it. That is, what did I do to “get” Apple to pick Halftone? I don’t know what kind of response they expect, but I’m sure that I disappoint them when I respond:&lt;/p&gt;
&lt;p&gt;I have no idea.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;I’ve certainly thought a lot about the question, but I have no special insight into the process or criteria that Apple uses to assemble its year-end list. That said, I’d guess that one criterion is &lt;em&gt;quality&lt;/em&gt; and another is likely &lt;em&gt;user experience&lt;/em&gt;. I invest a lot of time trying to craft an experience that delights and empowers users.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;stamp&lt;/em&gt; feature of Halftone serves as a good example.&lt;/p&gt;
&lt;p&gt;There are many apps that allow users to add graphic elements to a photo or a document, and in almost every case, the graphic element is a &lt;a href="http://en.wikipedia.org/wiki/Bitmap" title="Bitmap"&gt;bitmap&lt;/a&gt;. There’s nothing inherently wrong with bitmaps, of course, but for Halftone, I wanted to enable users to freely move, rotate, and scale stamps with no loss of quality. That meant that the stamp feature needed to use &lt;a href="http://en.wikipedia.org/wiki/Vector_graphics" title="Vector Graphics"&gt;vector-based&lt;/a&gt; elements.&lt;/p&gt;
&lt;p&gt;Unfortunately, the iOS SDK has no native support for vector graphics formats (like SVG, EPS, and AI), so I had to develop my own solution.&lt;/p&gt;
&lt;p&gt;If you’ve followed me for a while, you’ll know that I’ve written a couple of free plug-ins for Adobe Illustrator. The most recent, &lt;a href="http://visitmix.com/work/ai2canvas/" title="Ai-&amp;gt;Canvas"&gt;Ai-&amp;gt;Canvas&lt;/a&gt;, adds a new option to the File/Export menu in Illustrator that makes it easy to use vector shapes and basic animation with HTML5 canvas elements (watch this &lt;a href="http://visitmix.com/work/ai2canvas/introduction.html" title="Ai-&amp;gt;Canvas Introductory Video"&gt;short introductory video&lt;/a&gt; if you’re curious).&lt;/p&gt;
&lt;p&gt;Remembering that the canvas element was created by Apple for WebKit, and recognizing similar concepts in Quartz 2D, I decided to build a new plug-in that exports Illustrator artwork directly to Objective-C code. I’ve used the plug-in to create the code that draws all of the stamp shapes in Halftone.&lt;/p&gt;
&lt;p&gt;For example, this WHAM! artwork in Adobe Illustrator:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lyzgi7EhSw1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Exports to this Objective-C code that I paste into my Halftone Xcode project:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lyzgihTy7p1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;By drawing native vector shapes, Halftone can render its stamps at any resolution with very high quality. That’s why you can turn on the Full Size setting in Halftone and create stamps that look fantastic, even close-up:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lyzgjkiubj1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;I’m confident that most users don’t know (or care) that the stamp feature is based on vectors, but I do. Also, most users don’t zoom-in to full size Halftone images to examine the pixels, but for those who do, they’re going to see the finest output that I know how to create. Whether or not it’s consciously noticed, this attention to the smallest detail certainly contributes to an overall feeling of quality.&lt;/p&gt;
&lt;p&gt;I doubt that Apple knows anything about the effort that went into the stamp feature in Halftone, but I like to think that they did recognize its contribution to the overall quality of the app.&lt;/p&gt;
&lt;p&gt;A second example—also related to the stamp feature—is that I try to re-think interaction methods when designing for a touchscreen interface. One of the best things about a touchscreen device is that it feels like you’re interacting directly with objects that are just underneath your fingertips. That means that many of the common interactions that were developed for indirect input (like a mouse) should be reconsidered.&lt;/p&gt;
&lt;p&gt;In almost every graphics application, you know that you can click on an element to enter an editing mode and use “handles” to scale and rotate the element. These are such common interactions that you might not even think about it. Step back for a moment, though, and you’ll realize that these handles were created for your mouse, and over the years, you’ve been trained to adapt to the computer more than the computer has adapted to you.&lt;/p&gt;
&lt;p&gt;To discover a more natural interaction, I placed a sheet of paper on the desk and began to manipulate it with my fingertips…just like you would with a touchscreen device. The great thing about tests like this is how surprisingly obvious the interaction becomes. You’re interacting directly with a physical object, and you just “know” what to do. If there’s a way to duplicate this interaction with touch, it’s likely to seem just as natural to your users.&lt;/p&gt;
&lt;p&gt;So, to move a stamp in Halftone, you touch somewhere near the center of the stamp and drag it wherever you’d like. No editing mode. No interacting with artificial interface elements like handles. No visual indicators. Just direct interaction with the stamp itself.&lt;/p&gt;
&lt;p&gt;To rotate, you touch near an edge and start spinning the stamp around. Scaling works the same way…just touch and drag an edge away from the center. Even though you can’t scale a physical sheet of paper, it’s easy to imagine what you’d want to do. After you’ve tried these interactions just once, you quickly forget that they’re anything special, because they behave “as expected.” Plus, there are no special editing modes that the user has to learn, track, or maintain.&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://media.tumblr.com/tumblr_lyzgk2wSOq1r0hcti.png"/&gt;&lt;/p&gt;
&lt;p&gt;Out of curiosity, I built a test version that rotated and scaled around a second touch point. This method worked well, but it required two hands and added unnecessary complexity, so I removed it.&lt;/p&gt;
&lt;p&gt;Like the vector functionality, I have no idea if Apple noticed or considered these interaction methods in their deliberations, but I can tell you that with over one million users and all of the e-mail I receive, nobody has mentioned any difficulty with these methods. To the contrary, I very frequently hear how easy it is to use Halftone.&lt;/p&gt;
&lt;p&gt;I’m proud of the stamps in Halftone. Most people don’t know how much effort it took to make the feature work (nor do they need to know). I do believe, however, that the effort contributed to a more natural and delightful interaction with the app, and I trust that the high output quality is noticed, even if everyone isn’t a pixel peeper.&lt;/p&gt;
&lt;p&gt;It would have taken considerably less time to build a feature with standard bitmap images that could be rotated and scaled with typical bounding box handles. But I wanted to push what’s possible with touchscreen devices and to explore new interaction methods.&lt;/p&gt;
&lt;p&gt;Often, it’s difficult to know exactly what an app or a feature should or shouldn’t do. It’s difficult because—as developers—we have &lt;em&gt;the burden of professional knowledge&lt;/em&gt;: we know how much work it will take.&lt;/p&gt;
&lt;p&gt;My advice is to train yourself to recognize and note the small (but important) reactions that you have when you’re working with your own apps. Dismiss your professional knowledge about the effort it will take and consider the experience alone. Only when you’re willing and able to do what’s necessary to perfect a feature will you be accomplishing your best work. Your &lt;a href="http://en.wikipedia.org/wiki/Exit-criteria" title="Exit-Criteria"&gt;exit criteria&lt;/a&gt; should be when you’re delighted to use your own app or feature and surprised that you were able to pull it off.&lt;/p&gt;
&lt;p&gt;At the end of the day, I don’t know exactly why Apple picked Halftone, and I’ll probably never know. But, I like to think that it had something to do with providing users the best experience I knew how to provide.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/17160200980</link><guid>http://blog.mikeswanson.com/post/17160200980</guid><pubDate>Mon, 06 Feb 2012 10:03:00 -0800</pubDate></item><item><title>Ever since I’ve moved to my new blog, the most common...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_lvlgddYFVw1r3cke2o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Ever since I’ve moved to my new blog, the most common request I get (by far) is: “when are you going to post your wallpaper images again?” Well, the answer is: today!&lt;/p&gt;
&lt;p&gt;I’ve gone through the 160+ images that I’ve released over the years and culled them down to a set that represents some of the most popular along with some of my favorites. I hope you &lt;a href="http://blog.mikeswanson.com/wallpaper" title="Mike Swanson Wallpaper Images"&gt;enjoy them&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/13646099450</link><guid>http://blog.mikeswanson.com/post/13646099450</guid><pubDate>Fri, 02 Dec 2011 13:15:17 -0800</pubDate></item><item><title>Happy Thanksgiving! I was curious about heat transfer while...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_lv6t7tlrzC1r3cke2o1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Happy Thanksgiving! I was curious about heat transfer while cooking our turkey this year, so I logged the thigh temperature every five minutes. We cooked a 14lb turkey at 350⁰ F in a cooking bag, and it took almost exactly three hours (which includes a 15 minute resting period at the end). Note that I pulled the turkey out of the oven when it reached 180⁰ F, and it continued to warm to 189⁰ F.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://thermal-imaging-blog.com/index.php/2010/11/24/heat-transfer-is-for-turkeys/" title="Heat Transfer is for Turkeys"&gt;Thermal Imaging Blog&lt;/a&gt; has a nice post about cooking turkey, and &lt;a href="http://www.gfzing.com/2010/thanksgiving-turkey-why-does-it-seem-to-take-forever-to-cook/" title="Thanksgiving Turkey - Why Does it Seem to Take Forever to Cook"&gt;here’s a post&lt;/a&gt; by someone else who tried this last year. If you’re really interested, I found a paper titled &lt;a href="http://lib3.dss.go.th/fulltext/Journal/Journal%20of%20food%20science/1998%20v.63/no.2/jfsv63n2p0257-0261ms0307%5B1%5D.pdf" title="Modeling Heat Transfer During Oven Roasting of Unstuffed Turkeys"&gt;Modeling Heat Transfer During Oven Roasting of Unstuffed Turkeys&lt;/a&gt; that uses a 2D finite element model to calculate temperatures at different points in the turkey. Cool!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update on 11/25/2011&lt;/strong&gt;: I’ve had a few questions about the dotted line in my graph. It’s an exponential trendline that I used to predict when the turkey would reach 180⁰ F.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/13272740005</link><guid>http://blog.mikeswanson.com/post/13272740005</guid><pubDate>Thu, 24 Nov 2011 15:04:00 -0800</pubDate></item><item><title>We received our Nest Learning Thermostat yesterday. The unit and...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_luvlvdesqD1r3cke2o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;We received our &lt;a href="http://www.nest.com/" title="Nest Learning Thermostat"&gt;Nest Learning Thermostat&lt;/a&gt; yesterday. The unit and its packaging are exquisite, simple, and well-designed. Other than a drill, the Nest includes everything you need to install it yourself, including a small screwdriver with four interchangeable bits. It took me about an hour from start to finish, and as you can see in the photo, I used one of the optional mounting plates to cover up the bare wall that was behind our old thermostat. Yes, the screen has a slight red tint to it, because it was heating the house when I took the photo. The free iPhone app (and web site) makes it easy to remotely monitor and control the Nest. So far, so good.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/12981348017</link><guid>http://blog.mikeswanson.com/post/12981348017</guid><pubDate>Fri, 18 Nov 2011 13:59:10 -0800</pubDate></item><item><title>Juicy Bits</title><description>&lt;p&gt;Most of my friends know that I’m always working on side projects. And if you don’t know what side project I’m currently working on, that doesn’t mean that I’m taking a break. It just means that I’m being quiet. ;-)&lt;/p&gt;
&lt;p&gt;This side project began as an experiment in March, 2009, and over the past 2½ years, it’s become my new full-time job.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;In February, 2009, I bought a Mac Mini so that I could port my &lt;a href="http://www.mikeswanson.com/XAMLExport/" title="Adobe Illustrator to XAML plug-in"&gt;Adobe Illustrator to XAML plug-in&lt;/a&gt; to run on a Mac. As a technologist, I was aware of the Apple App Store and had followed its progress since it opened its doors in July, 2008. I was spending my time in Apple’s developer tools (Xcode) anyway, so I downloaded the iPhone SDK to see what mobile development was all about. I also picked up an iPhone 3G for testing.&lt;/p&gt;
&lt;p&gt;After some frustrating weeks learning Objective-C (thankfully, I already knew C/C++), I managed to build an app called &lt;a href="http://www.juicybitssoftware.com/3dcamera/" title="3D Camera"&gt;3D Camera&lt;/a&gt; that was released in May, 2009. I created a “novelty” app primarily because I didn’t have time to maintain servers or other back-end infrastructure, and I wanted a fun app that nobody would depend on. I also needed an app that the press wouldn’t find very interesting. After all, my day job was still as a Technical Evangelist at Microsoft, and nobody needed &lt;em&gt;that &lt;/em&gt;article.&lt;/p&gt;
&lt;p&gt;At the time, most of my decisions were based on experimentation, and I never expected that this side project would turn into anything real. I told one of my friends that I’d be happy if I could make enough money to pay for a new camera lens. My company name, &lt;a href="http://www.juicybitssoftware.com/" title="Juicy Bits"&gt;Juicy Bits&lt;/a&gt;, was concocted on short notice so I could release 3D Camera in the App Store. If I knew that it would eventually become my full-time job, I probably would have put more thought into the name!&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" alt="Juicy Bits" height="210" src="http://media.tumblr.com/tumblr_luud3dDHWy1r0hcti.png" width="313"/&gt;&lt;/p&gt;
&lt;p&gt;Since then, Juicy Bits has served as an after-hours technical playground. I didn’t need it to pay the bills, so I was free to experiment. I continued to build novelty apps, and I tried running sales, creating “lite” versions, altering pricing, using social media, and just about anything that could teach me more about this new marketplace. Not only was I hooked, but I was constantly learning new things, challenging myself, and having fun all at the same time!&lt;/p&gt;
&lt;p&gt;But I couldn’t tell anyone about it. Only my wife and one of my closest friends knew what I was doing.&lt;/p&gt;
&lt;p&gt;As my skills improved, I was able to create and release more apps. In June, 2009, I packaged-up some of my close-up nature photos and published a gallery of wallpaper images. Those gallery apps have gone through some revisions to become &lt;a href="http://www.juicybitssoftware.com/nature-images/" title="Nature Images"&gt;Nature Images&lt;/a&gt;, &lt;a href="http://www.juicybitssoftware.com/nature-images-hd/" title="Nature Images HD"&gt;Nature Images HD&lt;/a&gt;, and &lt;a href="http://www.juicybitssoftware.com/textures-hd/" title="Textures HD"&gt;Textures HD&lt;/a&gt;. While they’re not big sellers, each release has taught me just a little bit more about how the app marketplace works.&lt;/p&gt;
&lt;p&gt;In December, 2009, I released &lt;a href="http://www.juicybitssoftware.com/spypix/" title="Spy Pix"&gt;Spy Pix&lt;/a&gt;. It’s yet another novelty (and photography) app that uses a technique called &lt;a href="http://en.wikipedia.org/wiki/Steganography" title="steganography"&gt;steganography&lt;/a&gt; to hide one image inside of another. Imagine my surprise when I learned that it’s popular with college kids who like to send&amp;#8230;err…&lt;em&gt;special &lt;/em&gt;photos to each other. Who knew!?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.juicybitssoftware.com/3d-camera-studio/" title="3D Camera Studio"&gt;3D Camera Studio&lt;/a&gt;, a more fully-featured version of my first app, 3D Camera, was finally approved by Apple in May, 2010. The iPad had been released in January, and this was my first in-depth experiment with tablet development. It was liberating to have a larger screen and a chance to redesign my original app for this new form factor.&lt;/p&gt;
&lt;p&gt;In between the new apps, I was adding features to existing apps, fixing bugs, and starting to promote them more and more. As a result, the business side of Juicy Bits continued to generate more income. My apps were being reviewed in printed magazines, online, and frequently, they were featured by Apple in their &lt;em&gt;New and Noteworthy&lt;/em&gt; and &lt;em&gt;Staff Favorites&lt;/em&gt; lists.&lt;/p&gt;
&lt;p&gt;The more popular they became, the more that other companies would reach out to me with offers to collaborate on future apps and products. Because I needed to keep Juicy Bits under the radar, I had to pass up many exciting opportunities. It was frustrating.&lt;/p&gt;
&lt;p&gt;My most recent app, &lt;a href="http://www.juicybitssoftware.com/halftone/" title="Halftone"&gt;Halftone&lt;/a&gt;, was inspired by another technique that makes photos look like they came from old newspapers and comic books. You’d think I have a thing for photography apps, wouldn’t you? Halftone was released in February of this year, and it’s my first Universal app (meaning that the same app runs on iPhone, iPod touch, and iPad).&lt;/p&gt;
&lt;p&gt;It will come as no surprise that I like the most recent app the best. Over the summer, Halftone was selected by Apple as its iPhone and iPad &lt;a href="http://www.juicybitssoftware.com/2011/07/08/halftone-is-the-ipad-app-of-the-week-in-the-uk/" title="Halftone App of the Week"&gt;App of the Week&lt;/a&gt; in both Canada and the UK. It’s spent a lot of time in “top 10” lists, and it’s frequently among the top 100 photography apps in many of the worldwide app stores. It even spent some time above Angry Birds, if you can believe it! Within the next week or two, it’ll tick over the one million user mark. It’s stunning (to me) to think that Halftone has been used to create over 5½ million photos.&lt;/p&gt;
&lt;p&gt;So, in the summer of 2011, it hit me: I’m having so much fun writing mobile software for Juicy Bits, why don’t I make it my full time job? After discussing the idea with some trusted friends, I decided that I would leave my job at Microsoft after we completed our BUILD event in September, 2011. After 11½ wonderful years, September 30th, 2011 was my last day at Microsoft.&lt;/p&gt;
&lt;p&gt;October 1st, 2011 was the beginning of something new and exciting. While I miss the daily interaction with all of my Microsoft friends and internet followers, I’m having fun applying my full attention to Juicy Bits and what comes next.&lt;/p&gt;
&lt;p&gt;There’s another set of Halftone updates coming later this year, and I hope to release a new app that I’ve been working on sometime before Christmas.&lt;/p&gt;
&lt;p&gt;If you want a quick tour of Halftone, Adorama TV recently published a nice &lt;a href="http://www.juicybitssoftware.com/2011/11/04/adorama-tv-halftone-review/" title="Adorama TV Halftone Video Review"&gt;video review&lt;/a&gt; that’s worth watching. Also, crowdSPRING ran &lt;a href="http://blog.crowdspring.com/2011/11/small-business-spotlight-of-the-week-juicy-bits/" title="crowdSPRING Juicy Bits Interview"&gt;an interview&lt;/a&gt; that they did with me a few weeks back that contains a few more details.&lt;/p&gt;
&lt;p&gt;Welcome to &lt;a href="http://www.juicybitssoftware.com/" title="Juicy Bits"&gt;Juicy Bits&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/12959053940</link><guid>http://blog.mikeswanson.com/post/12959053940</guid><pubDate>Thu, 17 Nov 2011 21:48:53 -0800</pubDate></item><item><title>While I left Microsoft of my own accord, Lemonade is a short...</title><description>&lt;iframe src="http://player.vimeo.com/video/9677439" width="400" height="300" frameborder="0"&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;While I left Microsoft of my own accord, &lt;em&gt;Lemonade&lt;/em&gt; is a short documentary about 16 people in the advertising industry who lost their jobs and found their calling. It’s just as appropriate today as when I first saw it years ago. Definitely worth watching.&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/12006394936</link><guid>http://blog.mikeswanson.com/post/12006394936</guid><pubDate>Thu, 27 Oct 2011 15:24:00 -0700</pubDate></item><item><title>Keoni</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_lsvrv60vJ51r3cke2o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Keoni&lt;/p&gt;</description><link>http://blog.mikeswanson.com/post/11302945676</link><guid>http://blog.mikeswanson.com/post/11302945676</guid><pubDate>Mon, 10 Oct 2011 19:49:54 -0700</pubDate></item></channel></rss>

