<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><description>I enjoy mobile &amp; connected devices, DIY computing (Raspberry Pi, Arduino), video games, and brewing beer. My company Mobile Distortion has a number of apps for sale on the App Store.


    
        
            I have a non-spam mailing list I use to notify when cool stuff is finished. Sign up?
        
            
</description><title>James Jennings - Mobile Software Architect</title><generator>Tumblr (3.0; @jamesjennings)</generator><link>http://jamesjennin.gs/</link><item><title>MDHeartRateMonitor</title><description>&lt;p&gt;If you&amp;rsquo;re an iOS dev and are interested in health apps, I&amp;rsquo;ve just posted some code for working with BLE heart rate monitors. If you&amp;rsquo;re interested in helping out, I could really use some people with more devices, as I only have one that I&amp;rsquo;ve tested with.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/mobiledistortion/MDHeartRateMonitor"&gt;https://github.com/mobiledistortion/MDHeartRateMonitor&lt;/a&gt;&lt;/p&gt;</description><link>http://jamesjennin.gs/post/93228786624</link><guid>http://jamesjennin.gs/post/93228786624</guid><pubDate>Tue, 29 Jul 2014 11:27:35 -0700</pubDate></item><item><title>New Stuff</title><description>&lt;p&gt;Well, I guess at this point, anything I post is new. Does the previous post really reference something called &amp;ldquo;Hudson&amp;rdquo;? Wow.&lt;/p&gt;
&lt;p&gt;Anyway, I&amp;rsquo;m in the middle of revamping my flash card app, cardGRIND. Check out the new marketing site here: &lt;a href="http://cardgrind.com/"&gt;http://cardgrind.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also doing the mailing list thing if you&amp;rsquo;re inclined, see the form in the header.&lt;/p&gt;
&lt;p&gt;JJ&lt;/p&gt;</description><link>http://jamesjennin.gs/post/75086653840</link><guid>http://jamesjennin.gs/post/75086653840</guid><pubDate>Thu, 30 Jan 2014 14:33:00 -0800</pubDate></item><item><title>Saving Time &amp; Money Through Build Automation: Intro to Hudson</title><description>&lt;p&gt;Just gave a quick talk yesterday at &lt;a target="_blank" href="http://www.barcampsd.org/"&gt;BarCamp San Diego 8&lt;/a&gt; about using Hudson for build automation.  You can check out the slide deck &lt;a target="_blank" href="http://www.slideshare.net/jamesjennings1/saving-time-money-through-build-automation-intro-to-hudson"&gt;here on Slideshare&lt;/a&gt;.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;To give credit where credit is due, there were a couple blog posts describing a few tips and tricks that coalesced into my final build system.  They are:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;George Sealy&amp;rsquo;s series of posts on using Hudson for iOS development &lt;a target="_blank" href="http://acornheroes.com/2010/08/setting-up-an-automated-build-in-an-ios-environment/"&gt;here&lt;/a&gt;, &lt;a target="_blank" href="http://acornheroes.com/2010/08/setting-up-an-automated-build-in-an-ios-environment-part-2/"&gt;here&lt;/a&gt;, &lt;a target="_blank" href="http://acornheroes.com/2010/09/setting-up-an-automated-build-in-an-ios-environment-part-3/"&gt;here&lt;/a&gt; and &lt;a target="_blank" href="http://acornheroes.com/2010/10/setting-up-an-automated-build-in-an-ios-environment-part-4/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Jeffrey Sambells has a neat system for the OTA distribution of apps &lt;a target="_self" href="http://jeffreysambells.com/posts/2010/06/22/ios-wireless-app-distribution/"&gt;here&lt;/a&gt;, including an awesome-looking dynamic PHP file implementation I&amp;rsquo;d love to take a stab at recreating someday.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Here&amp;rsquo;s a quick overview of the bash scripts referenced in the talk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;updateProvisioning.sh&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="brush: bash;"&gt;rm -Rf ~/Library/MobileDevice/Provisioning\ Profiles/*
cp "$1"/*.* ~/Library/MobileDevice/Provisioning\ Profiles/
&lt;/pre&gt;
&lt;p&gt;What we&amp;rsquo;re doing here is wiping out all previously installed provisioning profiles on the computer, and replacing them with the contents of the folder passed in as the sole argument. When coupled with the use of the automatic profile selectors in each target&amp;rsquo;s build settings, what you get is a system that allows you to update provisioning profiles independently of the developer. This allows me to empower the clients to update their own provisioning profiles (for example, when they have a new device to test on), which, due to the folder changed trigger set up in hudson, also kicks off new builds.&lt;/p&gt;
&lt;p&gt;Note that using wildcard provisioning profiles probably won&amp;rsquo;t work if a single Hudson project needs to build multiple configuration. This is because the automatic profile selector may not pick the profile you expect when using a wildcard profile.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;packageIPA.sh&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="brush: bash;"&gt;mkdir Payload
cp -rp build/"$1"-iphoneos/"$2" Payload/
zip -r "$3" Payload
rm -rf Payload

TMP_BUILD_NAME="$4"

if [ ! -e "$5"$TMP_BUILD_NAME ]; then
    mkdir "$5"$TMP_BUILD_NAME
fi

cp "$3" "$5"$TMP_BUILD_NAME/
&lt;/pre&gt;
&lt;p&gt;This script simply takes the built .app file and turns it into a .ipa, saved at the specified location. The resulting folder is eventually uploaded via FTP/Dropbox later in the Hudson process.&lt;/p&gt;
&lt;p&gt;Takes 5 arguments:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Name of build configuration&lt;/li&gt;
&lt;li&gt;Name of built .app file&lt;/li&gt;
&lt;li&gt;Name of resultant .ipa file&lt;/li&gt;
&lt;li&gt;Folder name for final output (usually passed in as a combo of project name and build number)&lt;/li&gt;
&lt;li&gt;Path to save final output (for example, final .ipa file is saved to &amp;lt;argument 5&amp;gt;/&amp;lt;argument 4&amp;gt;/&amp;lt;argument3&amp;gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Finally, the HTML and PLIST files referenced, both of which will need to be customized for your needs:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Project1.html&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="brush: html;"&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta name="viewport" content="width=200; initial-scale=1.5;user-scalable=no" /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;a href="itms-services://?action=download-manifest&amp;amp;url=http://builds.mobiledistortion.com/##BUILDNAME##/Project1.plist"&amp;gt;Tap here to install&amp;lt;/a&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Project1.plist&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&amp;gt;
&amp;lt;plist version="1.0"&amp;gt;
&amp;lt;dict&amp;gt;
	&amp;lt;key&amp;gt;items&amp;lt;/key&amp;gt;
	&amp;lt;array&amp;gt;
		&amp;lt;dict&amp;gt;
			&amp;lt;key&amp;gt;assets&amp;lt;/key&amp;gt;
			&amp;lt;array&amp;gt;
				&amp;lt;dict&amp;gt;
					&amp;lt;key&amp;gt;kind&amp;lt;/key&amp;gt;
					&amp;lt;string&amp;gt;software-package&amp;lt;/string&amp;gt;
					&amp;lt;key&amp;gt;url&amp;lt;/key&amp;gt;
					&amp;lt;string&amp;gt;http://builds.mobiledistortion.com/##BUILDNAME##/Project1.ipa&amp;lt;/string&amp;gt;
				&amp;lt;/dict&amp;gt;
			&amp;lt;/array&amp;gt;
			&amp;lt;key&amp;gt;metadata&amp;lt;/key&amp;gt;
			&amp;lt;dict&amp;gt;
				&amp;lt;key&amp;gt;bundle-identifier&amp;lt;/key&amp;gt;
				&amp;lt;string&amp;gt;com.mobiledistortion.Project1&amp;lt;/string&amp;gt;
				&amp;lt;key&amp;gt;bundle-version&amp;lt;/key&amp;gt;
				&amp;lt;string&amp;gt;1.0&amp;lt;/string&amp;gt;
				&amp;lt;key&amp;gt;kind&amp;lt;/key&amp;gt;
				&amp;lt;string&amp;gt;software&amp;lt;/string&amp;gt;
				&amp;lt;key&amp;gt;title&amp;lt;/key&amp;gt;
				&amp;lt;string&amp;gt;Project1&amp;lt;/string&amp;gt;
			&amp;lt;/dict&amp;gt;
		&amp;lt;/dict&amp;gt;
	&amp;lt;/array&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&lt;/pre&gt;
&lt;p&gt;As always, if you have questions feel free to hit me here or on twitter - @jamesjennings.&lt;/p&gt;</description><link>http://jamesjennin.gs/post/2788994074</link><guid>http://jamesjennin.gs/post/2788994074</guid><pubDate>Sun, 16 Jan 2011 19:50:00 -0800</pubDate></item><item><title>Fun with CGRect</title><description>&lt;p&gt;I saw &lt;a target="_blank" href="http://www.drobnik.com/touch/2010/07/cgrect-tricks/"&gt;this post&lt;/a&gt; on Dr. Touch today on CGRect tricks. Very good stuff, as he mentions, CGRect is probably one of the most used structures in iPhone programming, especially when doing UI work, since the frame property of UIView is the basis for determining how things are laid out on screen.&lt;/p&gt;
&lt;p&gt;Dr. Touch&amp;rsquo;s article goes over the following, read &lt;a target="_blank" href="http://www.drobnik.com/touch/2010/07/cgrect-tricks/"&gt;his article&lt;/a&gt; for more on these subjects:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Creating with CGRectMake() &lt;/li&gt;
&lt;li&gt;Transforming with CGRectInset() and UIEdgeInsetsInsetRect()&lt;/li&gt;
&lt;li&gt;Intersection tests with CGRectContainsPoint() and CGRectIntersectsRect()&lt;/li&gt;
&lt;li&gt;Creating and loading from a dictionary representation with CGRectCreateDictionaryRepresentation() and CGRectMakeWithDictionaryRepresentation()&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The topic of CGRect is on my list of blog post ideas, so I&amp;rsquo;ll go ahead and add a couple of my own CGRect tricks I&amp;rsquo;ve found useful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Null, Empty/Zero, and Infinite rectangles&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are three CGRect constants that can come in useful: CGRectNull, CGRectZero and CGRectInfinite.  These are matched by three comparison functions, CGRectIsNull(), CGRectIsEmpty(), CGRectIsInfinite().&lt;/p&gt;
&lt;p&gt;CGRectNull and CGRectIsNull() deal with the concept of the null set, i.e. the result of unioning two disjoint rectangles.  CGRectInfinite and CGRectIsInfinite() are all about a rectangle with no bounds.&lt;/p&gt;
&lt;p&gt;There is a subtle difference between the functionality of CGRectZero and CGRectIsEmpty(). CGRectZero is simply a rect with an origin of 0,0 and a size of 0. CGRectIsEmpty(), however, returns true for either CGRectZero &lt;strong&gt;or &lt;/strong&gt;CGRectNull, which is an important distinction to make.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comparing CGRects&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Since CGRect is a structure, comparing for equality isn&amp;rsquo;t as simple as &lt;/p&gt;
&lt;pre class="brush: objc;"&gt;if(rectA == rectB)&lt;/pre&gt;
&lt;p&gt;But never fear, CGRectEqualToRect() is here! CGRectEqualToRect() compares to CGRects, and returns a bool letting you know if they are equivalent (equivalent in this context meaning the two rectangles have the same origin, and the same size).  &lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a snippet of example code:&lt;/p&gt;
&lt;pre class="brush: objc;"&gt;//is the tab bar controller's frame the same as when we initialized?
if(!CGRectEqualToRect(tabBarController.view.frame,tabBarFrame))
{
    //then we whip it into shape.
    tabBarController.view.frame = tabBarFrame;
}&lt;/pre&gt;
&lt;p&gt;The problem being solved here was that the frame of a UITabBarController was being mysteriously being reset by &amp;ldquo;mysterious forces&amp;rdquo; (which turned out to be presentModalViewController:animated:). The above snipped of code is called when a change in the frame is observed, forcing the frame back to a state I specified during initialization.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CGRectUnion is UIScrollView&amp;rsquo;s best friend&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So here&amp;rsquo;s the scenario: you have a UIScrollView with a bunch of subviews, which can dynamically resize and lay themselves out. That&amp;rsquo;s all well and good, but how do you set the contentSize of the scroll view so that the user can see all the subviews?&lt;/p&gt;
&lt;p&gt;If you know the top-left most and bottom-right most view, the answer is simple, use those points to define a rectangle, then add some padding.  Which in Core Graphics terms, means CGRectUnion() and CGRectInset():&lt;/p&gt;
&lt;pre class="brush: objc;"&gt;// get the rectangle that encompasses all of the dynamic content
CGRect theUnion = CGRectUnion(topLeftView.frame, bottomRightView.frame);
// add some padding to top and bottom (negative value adds padding, positive is an inset)
CGRect paddedUnion = CGRectInset(theUnion, 0, -20);
// in the end, we really only need the size of the rect
contentScroller.contentSize = paddedUnion.size;&lt;/pre&gt;
&lt;p&gt;Easy enough!&lt;/p&gt;</description><link>http://jamesjennin.gs/post/880892611</link><guid>http://jamesjennin.gs/post/880892611</guid><pubDate>Fri, 30 Jul 2010 12:39:53 -0700</pubDate><category>iphone</category></item><item><title>We interrupt our regularly-scheduled substantive discourse to...</title><description>&lt;iframe width="400" height="225"  id="youtube_iframe" src="https://www.youtube.com/embed/C_E83GfWM-A?feature=oembed&amp;enablejsapi=1&amp;origin=http://safe.txmblr.com&amp;wmode=opaque" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;We interrupt our regularly-scheduled substantive discourse to bring you 2 ½ minutes of nerding out.&lt;/p&gt;</description><link>http://jamesjennin.gs/post/847581844</link><guid>http://jamesjennin.gs/post/847581844</guid><pubDate>Thu, 22 Jul 2010 19:04:43 -0700</pubDate><category>random</category></item><item><title>How To: Quickly Organize Groups in Xcode</title><description>&lt;p&gt;I must have missed the bus on this one. So, one of my biggest hang-ups with Xcode is the weird disconnect between what it calls &amp;ldquo;Groups&amp;rdquo; and folders on the file system. I do my bestest to keep my code organized in Xcode as well as on the disk, which sometimes requires removing and re-adding files in the IDE. This can lead to really disorganized and cluttered groups, which makes it hard to find files.&lt;/p&gt;
&lt;p&gt;Anyway, I was struggling to keep a 200+ file group sorted in Xcode one day, and stumbled upon, completely by accident, a really, really simple way of doing it.&lt;/p&gt;
&lt;p&gt;Say you have a group like the following, which you&amp;rsquo;d like to get into alphabetical order:&lt;/p&gt;
&lt;p&gt;&lt;img height="300" src="http://68.media.tumblr.com/tumblr_l5w4sl4dp21qaevfy.png"/&gt;&lt;/p&gt;
&lt;p&gt;Now, in the left panel, click on the name of the group (here, &amp;ldquo;Pill Images&amp;rdquo;), and make sure the top right files panel is pulled down. Click on a file in the top right, and hit Command-A to select all.&lt;/p&gt;
&lt;p&gt;&lt;img height="300" src="http://68.media.tumblr.com/tumblr_l5w4uvpwjx1qaevfy.png"/&gt;&lt;/p&gt;
&lt;p&gt;Now just drag that set of files back into the group in the left panel, and boom, ordered group:&lt;/p&gt;
&lt;p&gt;&lt;img height="300" src="http://68.media.tumblr.com/tumblr_l5w4wf804l1qaevfy.png"/&gt;&lt;/p&gt;
&lt;p&gt;Easy enough, right?&lt;/p&gt;</description><link>http://jamesjennin.gs/post/845226020</link><guid>http://jamesjennin.gs/post/845226020</guid><pubDate>Thu, 22 Jul 2010 07:03:42 -0700</pubDate><category>iphone</category><category>how to</category></item><item><title>Looking for iPhone, Android and Blackberry developers!</title><description>&lt;p&gt;Hey everybody - looking for some developers (especially iPhone) for some big projects coming up. Drop me a line if you know somebody, or even better, &lt;strong&gt;are&lt;/strong&gt; somebody!&lt;/p&gt;</description><link>http://jamesjennin.gs/post/842773339</link><guid>http://jamesjennin.gs/post/842773339</guid><pubDate>Wed, 21 Jul 2010 17:39:48 -0700</pubDate><category>random</category><category>random</category></item><item><title>How Xbox Achievements Work</title><description>&lt;p&gt;Xbox.com&amp;rsquo;s Engineering Blog has &lt;a href="http://www.xbox.com/en-US/live/engineeringblog/achievements-unlocked.htm"&gt;an interesting piece&lt;/a&gt; on how the Achievements system was implemented. Very interesting read, even as a non-Xbox developer.  I&amp;rsquo;ve always been curious how console development worked, and how that software has to integrate with services such as Xbox Live.&lt;/p&gt;
&lt;p&gt;Seeing as how the iOS platform is due to get its own social gaming platform, &lt;a href="http://www.xbox.com/en-US/live/engineeringblog/achievements-unlocked.htm"&gt;Game Center&lt;/a&gt;, it will be interesting to see how the two systems compare.&lt;/p&gt;</description><link>http://jamesjennin.gs/post/842724735</link><guid>http://jamesjennin.gs/post/842724735</guid><pubDate>Wed, 21 Jul 2010 17:25:45 -0700</pubDate><category>non-mobile</category></item><item><title>Dear Future James: The iPhone Simulator is Case Insensitive, iPhones are Case Sensitive</title><description>&lt;p&gt;July 20, 2010&lt;/p&gt;
&lt;p&gt;Dear Future James,&lt;/p&gt;
&lt;p&gt;If you are reading this, you have probably forgotten (again) that the iPhone Simulator is for some reason case insensitive.  As you might recall (probably not), all iOS devices are case sensitive, and are, in fact, very picky about case.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m writing to remind you of this, so that you don&amp;rsquo;t spend another hour tracking down a &amp;ldquo;but it works in the simulator!&amp;rdquo; type bug.  We did it today, we did it a couple months ago, and we really need to stop doing it.&lt;/p&gt;
&lt;p&gt;Today&amp;rsquo;s bug involved a lack of a launch image, but only on the device.  This is &amp;ldquo;First Day on the Job&amp;rdquo; type stuff, Jim.  A monkey with Xcode has a good chance of getting this right. Anyway, you were clever enough to remember that the launch image needed to be a PNG file, but named it &amp;ldquo;default.png&amp;rdquo; instead of &amp;ldquo;Default.png.&amp;rdquo;  This, of course, works in the simulator, but not on the device.&lt;/p&gt;
&lt;p&gt;So next time, be sure to engage that amazing attention-to-detail you have, and name the damn file correctly. Or even better, just set the UILaunchImageFile in the info.plist. Then you can name the file whatever you&amp;rsquo;d like!&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;br/&gt;Past James &lt;/p&gt;</description><link>http://jamesjennin.gs/post/838164365</link><guid>http://jamesjennin.gs/post/838164365</guid><pubDate>Tue, 20 Jul 2010 16:00:00 -0700</pubDate><category>dear future james</category><category>iphone</category></item><item><title>Quick Thoughts on the iPhone 4 "Antennagate"</title><description>&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=FL7yD-0pqZg"&gt;I don&amp;rsquo;t care.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;People will still buy iPhone 4s, and all of the other iOS devices.&lt;/li&gt;
&lt;li&gt;a = The number of people who own iPhone 4s and complain about the antenna&lt;br/&gt;b = The number of people who don&amp;rsquo;t own iPhone 4s and complain about the antenna&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;a &amp;lt; b&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;</description><link>http://jamesjennin.gs/post/837473537</link><guid>http://jamesjennin.gs/post/837473537</guid><pubDate>Tue, 20 Jul 2010 12:00:00 -0700</pubDate></item><item><title>I think the Tesla is laughing at everybody…</title><description>&lt;img src="http://68.media.tumblr.com/tumblr_l5uek4PbdE1qamxu8o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I think the Tesla is laughing at everybody…&lt;/p&gt;</description><link>http://jamesjennin.gs/post/835208862</link><guid>http://jamesjennin.gs/post/835208862</guid><pubDate>Mon, 19 Jul 2010 23:12:00 -0700</pubDate><category>random</category></item><item><title>Droid X Sabotages Itself If You Mod It?</title><description>&lt;p&gt;I do &lt;strong&gt;try&lt;/strong&gt; to stay neutral in the whole iPhone vs. Android debate, but &lt;a href="http://www.mobilecrunch.com/2010/07/14/droid-x-actually-self-destructs-if-you-try-to-mod-it/"&gt;this here article from MobileCrunch&lt;/a&gt; is pretty depressingly hilarious.&lt;/p&gt;
&lt;p&gt;On the eFuse tampering system built into the Droid X:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;If the eFuse failes to verify this information then the eFuse receives a command to “blow the fuse” or “trip the fuse”. This results in the booting process becoming corrupted and resulting in a permanent bricking of the Phone. This FailSafe is activated anytime the bootloader is tampered with or any of the above three parts of the phone has been tampered with.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;I got to see a Droid X for the first time yesterday, and like many Android devices before it, I said to myself &amp;ldquo;that there is a beautiful phone.&amp;rdquo; It&amp;rsquo;s sad to hear about these countermeasures; the phone seems like it&amp;rsquo;d be a hackers dream to play around with.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As the article points out, can you imagine if your new MacBook Pro intentionally fried its own processor if you attempted to install Windows on it?&lt;/p&gt;</description><link>http://jamesjennin.gs/post/834001340</link><guid>http://jamesjennin.gs/post/834001340</guid><pubDate>Mon, 19 Jul 2010 17:00:00 -0700</pubDate><category>android</category></item><item><title>25-Minute Crash Course in iOS Multitasking (It's a lie!)</title><description>&lt;p&gt;Check out the deck I used for my presentation at &lt;a target="_blank" href="http://www.barcampsd.org/"&gt;BarCampSD&lt;/a&gt;, entitled &amp;ldquo;iOS Multitasking is a lie. And that&amp;rsquo;s totally fine.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mobiledistortion.com/files/iOS%20Multitasking.pdf"&gt;Get it here.&lt;/a&gt;&lt;/p&gt;</description><link>http://jamesjennin.gs/post/795432069</link><guid>http://jamesjennin.gs/post/795432069</guid><pubDate>Sat, 10 Jul 2010 16:46:00 -0700</pubDate><category>barcamp7</category><category>iOS</category></item><item><title>The 5-Minute Guide to Implementing iAd (Correctly)</title><description>&lt;p&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Today has involved me launching &lt;a target="_blank" href="http://click.linksynergy.com/fs-bin/stat?id=HhDfmk85ej4&amp;amp;offerid=146261&amp;amp;type=3&amp;amp;subid=0&amp;amp;tmpid=1826&amp;amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fus%252Fapp%252Fprivacy-for-facebook%252Fid374187406%253Fmt%253D8%2526uo%253D6%2526partnerId%253D30"&gt;Privacy for Facebook&lt;/a&gt; every 10 minutes, checking to see if iAd has rolled out to the app. Never in my life have I been so excited to see advertising before.&lt;/p&gt;
&lt;p&gt;Anyway, &amp;ldquo;in honor&amp;rdquo; of iAd rolling out live today, I thought I&amp;rsquo;d give a quick walkthrough on how to implement iAd correctly.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;But James,&amp;rdquo; my lone reader asks themselves, &amp;ldquo;is it even possible in implement iAd incorrectly?&amp;rdquo; Certainly, dear reader. In fact, Apple made it very easy to do so. See, the iAd banner class (ADBannerView) is right there in the Interface Builder library, so a naive programmer (like me) might just drag that into the interface, rebuild, code sign, deploy.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://68.media.tumblr.com/tumblr_l4wikuZKhg1qaevfy.png"/&gt;&lt;/p&gt;
&lt;p&gt;Well, if you went that route, you’d very likely receive a nice little email from appreview, that, in part, says the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“We noticed that your app, Privacy for Facebook, is displaying an empty iAd banner when ad content is not available. The banner within the app should be hidden whenever ad content is not being served by iAd.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Basically, displaying a blank banner is a no-no. There are a couple reasons why banners may not be displayed: they haven’t rolled out or aren’t available in a particular locale, there is no ad inventory available for your specific app, or there could just be a network issue. Apple wants you to make sure you never show blank banners.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://68.media.tumblr.com/tumblr_l4wim9PUPw1qaevfy.png"/&gt;&lt;/p&gt;
&lt;p&gt;So here’s a quick and dirty way of doing it correctly (assuming a portrait orientation, landscape is left as an exercise for the reader):&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Add an ADBannerView to your interface, but just off screen. In this example, the ad should be at the bottom of the interface, so the origin of the ADBannerView is 0,460.&lt;img src="http://68.media.tumblr.com/tumblr_l4wimjNHsx1qaevfy.png"/&gt;&lt;/li&gt;
&lt;li&gt;Set the view controller as the ADBannerView’s delegate.&lt;/li&gt;
&lt;li&gt;Make sure you’ve included the iAd framework in the view controller’s .h file:
&lt;pre class="brush: objc;"&gt;#import &amp;lt;iAd/iAd.h&amp;gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Have the view controller implement ADBannerViewDelegate, and add a bool bannerIsVisible; to the interface&lt;/li&gt;
&lt;li&gt;Add methods like the following to the view controller’s implementation. Note these methods animate the banner up from the bottom, while at the same time resizing my other views (buttonFrame and web).
&lt;pre class="brush: objc;"&gt;- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    if (!bannerIsVisible)
    {
		NSLog(@"bannerViewDidLoadAd");
        [UIView beginAnimations:@"animateAdBannerOn" context:NULL];
        banner.frame = CGRectOffset(banner.frame, 0, -50);
        buttonFrame.frame = CGRectOffset(buttonFrame.frame, 0, -50);
		web.frame = CGRectMake(web.frame.origin.x,
							   web.frame.origin.y,
							   web.frame.size.width,
							   web.frame.size.height-50);
        [UIView commitAnimations];
        bannerIsVisible = YES;
    }
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
	if (bannerIsVisible)
	{
		NSLog(@"bannerView:didFailToReceiveAdWithError:");
		[UIView beginAnimations:@"animateAdBannerOff" context:NULL];
		// assumes the banner view is at the top of the screen.
		banner.frame = CGRectOffset(banner.frame, 0, 50);
        buttonFrame.frame = CGRectOffset(buttonFrame.frame, 0, 50);
		web.frame = CGRectMake(web.frame.origin.x,
							   web.frame.origin.y,
							   web.frame.size.width,
							   web.frame.size.height+50);
		[UIView commitAnimations];
		bannerIsVisible = NO;
	}

}&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Test it. Note that in testing mode, Apple will occasionally return an error instead of the Test Ad, so you can make sure your logic is working correctly.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;!--EndFragment--&gt;</description><link>http://jamesjennin.gs/post/759225411</link><guid>http://jamesjennin.gs/post/759225411</guid><pubDate>Thu, 01 Jul 2010 15:56:00 -0700</pubDate><category>iOS</category></item><item><title>Slide to unlock/view</title><description>&lt;p&gt;Can&amp;rsquo;t tell if this should be filed under &amp;ldquo;how-come-I-never-noticed-that&amp;rdquo; or under &amp;ldquo;that-is-way-too-subtle&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Anyway, when a locked iPhone gets a Push Notification from an app, unlocking it will sometimes open the app that sent the notification, depending on if the device went back to sleep after receiving it. This behavior is pretty obvious after a while.&lt;/p&gt;
&lt;p&gt;What &lt;strong&gt;&lt;em&gt;isn&amp;rsquo;t&lt;/em&gt;&lt;/strong&gt; obvious, however, is that receiving the notification changes the text in the slider section of the lock screen. This text can even be customized by the app.&lt;/p&gt;
&lt;p&gt;Check it:&lt;/p&gt;
&lt;p&gt;Normal, locked phone. &amp;ldquo;Slide to Unlock&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://68.media.tumblr.com/tumblr_l4t3ilDvNr1qaevfy.png" height="200"/&gt;&lt;/p&gt;
&lt;p&gt;Got a notification. &amp;ldquo;Slide to View&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://68.media.tumblr.com/tumblr_l4t3isBxNE1qaevfy.png" height="200"/&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the fun part. I customized the notification:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://68.media.tumblr.com/tumblr_l4t3tnl7xz1qaevfy.png" height="200"/&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a snippet of the push notification payload that shows how that&amp;rsquo;s done:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;alert&amp;rdquo; : { &amp;ldquo;action-loc-key&amp;rdquo; : &amp;ldquo;Freak Out&amp;rdquo;, &amp;ldquo;body&amp;rdquo; : &amp;ldquo;Ooh, cool!&amp;rdquo;}&lt;/p&gt;
&lt;p&gt;Very subtle, right?&lt;/p&gt;</description><link>http://jamesjennin.gs/post/752054709</link><guid>http://jamesjennin.gs/post/752054709</guid><pubDate>Tue, 29 Jun 2010 19:54:00 -0700</pubDate><category>iOS</category></item></channel></rss>
