<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>White Peak Software Blog &#187; Software Development</title>
	<atom:link href="http://blog.whitepeaksoftware.com/category/software-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.whitepeaksoftware.com</link>
	<description>Latest word on White Peak Software and our products.</description>
	<lastBuildDate>Wed, 29 Jun 2011 04:04:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>Adding Placeholder Text to UITextView</title>
		<link>http://blog.whitepeaksoftware.com/2010/12/08/adding-placeholder-text-to-uitextview/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/12/08/adding-placeholder-text-to-uitextview/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 15:19:19 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=370</guid>
		<description><![CDATA[I decided one of my apps should display placeholder text in a text view. Unfortunately UITextView does not have a placeholder property. I&#8217;ve always thought this is odd especially given the fact that UITextField has a placeholder property. I googled to see what others have done. I found some good approaches but no one solution [...]]]></description>
			<content:encoded><![CDATA[<p>I decided one of my apps should display placeholder text in a text view. Unfortunately UITextView does not have a placeholder property. I&#8217;ve always thought this is odd especially given the fact that UITextField has a placeholder property. </p>
<p>I googled to see what others have done. I found <a href="http://stackoverflow.com/questions/1328638/placeholder-in-uitextview">some good approaches</a> but no one solution that I liked. So I decided to write my own borrowing from the various ideas of others. The end result is KTTextView.</p>
<p><a href="https://github.com/kirbyt/KTTextView">KTTextView</a> derives from UITextView and enhances it with new features. At the moment the only new feature is the placeholder text. The <strong>placeholderText</strong> property works same as UITextField&#8217;s placeholder property. I also added the property <strong>placeholderColor</strong> in case an app has the need to use a color different then the default placeholder color.</p>
<p>KTTextView is hosted on <a href="https://github.com/kirbyt/KTTextView">github</a>. The project includes a sample app showing how to use KTTextView. I plan to add more features as time allows. One feature I want to add is an option to display the text view in a rounded rectangle giving it a similar look to UITextField. In the meantime, I hope you find the KTTextView&#8217;s current implementation useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/12/08/adding-placeholder-text-to-uitextview/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Turbo Pascal on iPad</title>
		<link>http://blog.whitepeaksoftware.com/2010/10/26/turbo-pascal-on-ipad/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/10/26/turbo-pascal-on-ipad/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 19:19:39 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[White Peak Software]]></category>
		<category><![CDATA[iPad]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=353</guid>
		<description><![CDATA[Isn&#8217;t not like I need a distraction from work, but I couldn&#8217;t resist this one. I saw a tweet about iDOS, a DOS emulator app just released for iPad and iPhone. For fear the app will be pulled from the App Store, I bought it right away. Besides, it&#8217;s only 99 cent. I read a [...]]]></description>
			<content:encoded><![CDATA[<p>Isn&#8217;t not like I need a distraction from work, but I couldn&#8217;t resist this one. I saw a tweet about iDOS, a DOS emulator app just released for iPad and iPhone. For fear the app will be pulled from the App Store, I bought it right away. Besides, it&#8217;s only 99 cent.</p>
<p>I read a story about someone <a href="http://toucharcade.com/2010/10/26/idos/">installing Windows 3.0 inside of iDOS</a>. Sounds cool but I&#8217;m not interested in Windows 3.0. Instead, I decided to install Turbo Pascal. Embarcadero recently posted <a href="http://edn.embarcadero.com/article/20803">Turbo Pascal v5.5 as a free download</a> so the first thing I did was to grab a copy of it. Next, I grabbed an <a href="http://www.info-zip.org/UnZip.html#Downloads">unzip program</a> so I can unzip TP55.zip in iDOS. (Save time and <a href="ftp://ftp.info-zip.org/pub/infozip/msdos/">go here</a> to download unz552x3.exe.)</p>
<p>Here are the remaining steps I followed to get Turbo Pascal up and running on my iPad.</p>
<ul>
<li>Connect the iPad to iTunes.</li>
<li>In iTunes, go to the Apps tab for the connected iPad and scroll down to the file sharing section.</li>
<li>Drag and drop TP55.zip and unz552x3.exe to iDOS.</li>
<li>Sync the device.</li>
<li>Once sync is complete, launch iDOS on the iPad. You&#8217;ll find the two files in the root directory.</li>
<li>Copy unz552x3.exe to a new directory, or just run it in the root directory. This will uncompress the unzip utility files. I prefer running it in a separate directory to keep the root clean.</li>
<li>Unzip TP55.zip. This will create two directories, DISK1 and DISK2. Again, I copied TP55.zip to a temp directory before unzip.</li>
<li>Run install.exe found in the DISK1 directory. If your experience is similar to mine, you will get a message saying to insert the oop/demos/bgi/doc diskette. I&#8217;m guessing the installer can&#8217;t find the directory DISK2.</li>
<li>At this point, I aborted the install. Not to worry. Turbo Pascal&#8217;s IDE, compiler, etc have been installed.</li>
<li>By default, the IDE can be found in c:\TP. The program file to run is turbo.exe.</li>
</ul>
<p>That&#8217;s it. Happy coding!</p>
<p>Update: If those not lucky enough to grab a copy of iDOS from the App Store, you can <a href="http://code.google.com/p/dospad/">download the source code for DOSPad</a> and build your own version. </p>
<p><img src="http://blog.whitepeaksoftware.com/wp-content/uploads/2010/10/photo-41.PNG" alt="photo-4.PNG" border="0" width="450" height="600" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/10/26/turbo-pascal-on-ipad/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>My Initial Thoughts on the Mac App Store</title>
		<link>http://blog.whitepeaksoftware.com/2010/10/21/my-initial-thoughts-of-the-mac-app-store/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/10/21/my-initial-thoughts-of-the-mac-app-store/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 14:19:08 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[White Peak Software]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=347</guid>
		<description><![CDATA[Yesterday Apple announced the Mac App Store, which will be available in 90 days. The Mac App Store is modeled after the iOS App Store. The store provides customers a trusted way to buy and download safe, quality software for the Mac OS X desktop. As with the iOS App Store, software developers must submit [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday Apple announced the Mac App Store, which will be available in 90 days. The Mac App Store is modeled after the iOS App Store. The store provides customers a trusted way to buy and download safe, quality software for the Mac OS X desktop. As with the iOS App Store, software developers must submit their apps to Apple for review, <a href="http://developer.apple.com/appstore/mac/resources/approval/guidelines.html">apps must adhere to a list of rules</a>, and Apple gets 30% of the app price for each unit sold.</p>
<p>My first impression when reading about the announcement was 30% is too high. E-commerce providers such as Fastspring and eSellerate charge a much lower percentage. But the Mac App Store does do a few things that other e-commerce providers do not. The Mac App Store has the potential to reach many more users given that the app will be available on the desktop. Also, the Mac App Store will host the download file. But when I think about it, none of this is new. The only thing new is Apple.</p>
<p>Download sites have existed for years. The <a href="http://pad.asp-software.org/spec/spec.php">PAD specification</a>, which has been available for years, provides a mechanism for software vendors to publish app metadata and be discovered by download sites, and ultimately by customers. And many download sites and e-commerce providers provide hosting of the app. Even Microsoft gave it a try with its web-based app store concept called <a href="http://www.windowsmarketplace.com/">Microsoft Marketplace</a>, which after many years is no more. So it seems to me, the only thing new and different about the Mac App Store is the review process. </p>
<p>Downloading desktop software from download sites can be risky. You never know if the software you download contains a virus or malware. Attempts such as pre-scanning software for viruses by download sites have been made to instill trust but at the end of the day it&#8217;s hard to trust software downloaded from these sites. The <a href="http://www.asp-software.org/">Association of Software Professionals</a> have attempted tackling the trust issue for years and has had some success. Still, at the end of the day, gaining customer trust with an online business is challenging.</p>
<p>Personally, I never download software from download sites but I buy a lot of software online. I only buy and download software from the vendor&#8217;s own web site, and I&#8217;ll only do it when I feel I can trust the vendor. The vendor earns my trust by having a professional online presence, provides contact information with bonus points for having a physical address and phone number, offers a money back guarantee, and most importantly digitally signing the software with a certificate from a trusted CA. If you browse the <a href="http://www.whitepeaksoftware.com/" class="kblinker" title="More about White Peak Software &raquo;">White Peak Software</a> web site, you&#8217;ll see I follow these trust rules myself.</p>
<p>Trust is important when doing business in the online world, and the Mac App Store will help gain customer trust. This should, in turn, help encourage customers who have never bought desktop software online to final do so. The added level of trust and the potential reach to new customers makes the 30% cut to Apple worth while in my opinion. But I still have concerns, from a developer&#8217;s point of view, about the Mac App Store.</p>
<p>Many existing, and popular, apps sold today including some from Apple will be rejected from the store based on the list of <a href="http://developer.apple.com/appstore/mac/resources/approval/guidelines.html">review rules</a>. But a bigger concern for me is that software vendors wishing to sell through the Mac App Store as well as through their own company web site will be required to maintain two different versions of the same app. Mac App Store apps cannot be self updating, cannot be trial version, and cannot use its own licensing scheme. These three things are key components to selling desktop software on the Internet today. This means a software vendor wishing to sell an app through the Mac App Store as well as through its own company store must have two separate builds of the app, one build without the self updating, trial version, and licensing scheme for the Mac App Store, and one build containing these features for sell through one&#8217;s own online store.</p>
<p>Another concern I have with the Mac App Store is the lack of pricing and licensing options. For example, <a href="http://whitepeaksoftware.com/main/killink-csv-editor/index" class="kblinker" title="More about Killink CSV &raquo;">Killink CSV</a> is a business app bought by individuals and large companies alike. By selling directly to the customer, I can offer various pricing and licensing options. I offer a volume discount on purchases. The more single user licenses you buy, the lower the per unit cost. I offer a site license option too, which allows customers to pay a lower price while being able to install the software on a greater number of computers. Then there are coupons. I use coupons to offer discount pricing for a variety of reasons. It&#8217;s doubtful the Mac App Store will support coupons in the next 90 days. Then there are affiliates. While sells from affiliates represents only a small portion of my product revenue, affiliates do bring in additional customers. Come to think of it, in a way, one could think of the Mac App Store as an affiliate with review process.</p>
<p>I can&#8217;t help but wonder&#8230;giving the fact that I have more control over pricing, can offer discounts, and run sales using coupons&#8230;will customers become annoyed when they pay one price for my app in the Mac App Store only to find out they could have saved money by buying directly? And how will customer support change with the introduction of the Mac App Store? I&#8217;m assuming Apple will not provide any customer information after a purchase to the software vendor. What happens when a customer calls or emails me about re-installing the app on a new computer? I&#8217;ll have to first find out how they purchased the app, through the Mac App Store or through my web site. I can see it now, a customer responds with, &#8220;I don&#8217;t remember.&#8221; And what about refunds? Direct purchases can be refunded, Mac App Store purchases, well, &#8220;You&#8217;ll have to talk with Apple.&#8221; </p>
<p>Overall, I can see the Mac App Store leading to confusion and delay.</p>
<p>Oh, and then there is the concern of paid upgrades. Many, if not most, desktop software vendors count on revenue earned by paid upgrades. Paid upgrades are currently not supported in the iOS App Store, so I have to think the same will be true of the Mac App Store.</p>
<p>And let&#8217;s not forget the trial versions of the app. A customer can come to my web site and download a free 30-day trial of my software. This gives the user time to evaluate the app before making a purchasing decision. This is not going to happen, at least not initially, with the Mac App Store. Will this lead to users demanding lower prices and if so will software vendors given in starting a new race to the bottom. I certainly hope not. Software vendors need to stay their ground and price their products based on the value of the app.</p>
<p>Will my app be rejected from the Mac App Store if I include in the app description, &#8220;Come to my web site to download a free 30-day trial&#8221;? And what of cross-platform apps? Say I write a version of Killink CSV for the Mac. According to the list of review rules, I cannot mention the availability of the Windows version in the app&#8217;s metadata. If I do, it will be rejected even if this is a key selling point of the app.</p>
<p>I welcome the Mac App Store. It has great potential for tapping into a customer base that otherwise would be un-tappable. But I worry the Mac App Store is not the right place for many desktop app and by not being in the Mac App Store sells will suffer. Only time will tell if the Mac App Store will help software vendors, especially the indie shops like White Peak Software, to succeed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/10/21/my-initial-thoughts-of-the-mac-app-store/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Customizing the Look of UINavigationBar and UINavigationController</title>
		<link>http://blog.whitepeaksoftware.com/2010/09/11/customizing-the-look-of-uinavigationbar-and-uinavigationcontroller/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/09/11/customizing-the-look-of-uinavigationbar-and-uinavigationcontroller/#comments</comments>
		<pubDate>Sat, 11 Sep 2010 09:57:39 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=335</guid>
		<description><![CDATA[I&#8217;ve recently worked on a number of iOS projects that require a custom background for the UINavigationBar including the navigation bar used by the UINavigationController. Customizing the look of a UINavigationBar is actually pretty simple. You can set the tintColor property to the color of your choice. But sometimes you need to do more. For [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.whitepeaksoftware.com/wp-content/uploads/2010/09/CustomNavBar.png" alt="CustomNavBar.png" border="0" width="200" align="left" vspace="6" hspace="6" /> I&#8217;ve recently worked on a number of iOS projects that require a custom background for the UINavigationBar including the navigation bar used by the UINavigationController. Customizing the look of a UINavigationBar is actually pretty simple. You can set the tintColor property to the color of your choice. But sometimes you need to do more. For example, say you want to have a title in your navigation bar that uses a font not available on iPad and iPhone. For this you will need to use an image to customize the navigation bar. </p>
<p>Let&#8217;s take a look at the various ways to customize the navigation bar.</p>
<p>The UINavigationBar has a style property called barStyle. barStyle can be set to UIBarStyleDefault or UIBarStyleBlack. The default uses a blue gradient background. When using UIBarStyleBlack you can also set the translucent property to YES to give the navigation bar a partially opaque look.  If you are using Interface Builder, then you will set the Style property in the Inspector window. Here you have the option to style the navigation bar as Default, Black Opaque, and Black Translucent. </p>
<p>What if you want a color other than blue and black? You can set the tintColor property (aka Tint in IB) to any color you like. This changes the navigation bar&#8217;s color. Best of all, setting the tintColor will also change the background color used by the bar button items displayed within the navigation bar. </p>
<p>Sometimes, however, just changing the tint of the UINavigationBar isn&#8217;t enough. Sometimes you want to have a fancier background. Maybe the background you want has a different gradient style or lighting effect, or maybe you want a title displayed in the center of the navigation bar to use a font not available in iOS. How would you change the look of the navigation bar for these scenarios? Simple. You use an image that is drawn on the navigation bar.</p>
<p>There are two approaches you can use to draw an image on the navigation bar. You can create a new class that inherits from UINavigationBar and override the drawRect method. For example:</p>
<pre class="brush: objc;">
@interface KTNavigationBar : UINavigationBar {

}
@end

@implementation KTNavigationBar

- (void) drawRect:(CGRect)rect
{
   [super drawRect:rect];

   UIImage *image = [UIImage imageNamed: @&amp;amp;amp;quot;navbar.png&amp;amp;amp;quot;];
   [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

@end
</pre>
<p>In this example, the image navbar.png is used to customize, or skin, the UINavigationBar. This is a nice, clean, object orientated way to customize the look of your navigation bar. The only thing you must remember to do is to use your custom UINavigationBar class within your application. This means changing the class type for those of us using IB.</p>
<p>Another trick you can use that doesn&#8217;t require changing the class type is to use a category. For example:</p>
<pre class="brush: objc;">
@interface UINavigationBar (KTCustomLook)

- (void) drawRect:(CGRect)rect;

@end

@implementation UINavigationBar (KTCustomLook)

- (void) drawRect:(CGRect)rect
{
   UIImage *image = [UIImage imageNamed: @&amp;amp;amp;quot;navbar.png&amp;amp;amp;quot;];
   [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

@end
</pre>
<p>I admit I have used this approach in more than one project, but doesn&#8217;t feel right to me. It feels more like using voodoo or black magic then following good OO design. But this approach does work and it does save you time by eliminating the need to change the class type for each instance of UINavigationBar within your app. [Update: This approach doesn't feel right because it overrides a method in a category. You should know this is a bad, bad thing, and I don't encourage others to do it. That said, it does work.]</p>
<p>One thing to note when using an image to customize the UINavigationBar, you still want to set the tintColor for the navigation bar. As I mentioned, setting this property will also change the background color used by the bar button items. So you want to set the tintColor to the appropriate color making the button color fit in with the navigation bar color style.</p>
<p>For those of you who want to see these concepts in action, I posted a <a href="http://github.com/kirbyt/CustomNavBar">sample project, called CustomNavBar</a>, on github. Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/09/11/customizing-the-look-of-uinavigationbar-and-uinavigationcontroller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My App Store Pricing Experiment: The Final Chapter</title>
		<link>http://blog.whitepeaksoftware.com/2010/09/01/my-app-store-pricing-experiment-the-final-chapter/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/09/01/my-app-store-pricing-experiment-the-final-chapter/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 14:52:27 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Labor Mate]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=329</guid>
		<description><![CDATA[Today is my final update on the pricing experiment I started back in May. You can read the previous posts here and here. The goal of the experiment was to see if the sales trend for Labor Mate would continue at the higher price of $1.99. After three full months, I can say the higher [...]]]></description>
			<content:encoded><![CDATA[<p>Today is my final update on the pricing experiment I started back in May. You can read the previous posts <a href="http://blog.whitepeaksoftware.com/2010/06/01/sales-are-down-but-revenue-is-up/">here</a> and <a href="http://blog.whitepeaksoftware.com/2010/07/02/sale-numbers-are-in-an-update-on-my-app-store-pricing-experiment/">here</a>. The goal of the experiment was to see if the sales trend for <a href="http://www.whitepeaksoftware.com/labormate" class="kblinker" title="More about Labor Mate &raquo;">Labor Mate</a> would continue at the higher price of $1.99. After three full months, I can say the higher price has done more harm than good.</p>
<p>Labor Mate continues to bring in over $1K per month despite the higher price, but the trend doesn&#8217;t look good. Over the last few weeks, the number of sales has decreased everywhere except in Japan. For some reason, sales are up in Japan and if not for Japanese sales in August, Labor Mate would have posted it&#8217;s worse sales month in 6 months.</p>
<p>Since it&#8217;s inception date, revenue for Labor Mate has been on a slow but steady rise. The higher price has reversed that trend. Labor Mate now appears to be on a slow but steady fall. Not only that, Labor Mate, which at one time was in the Health and Fitness Top 100 category in App Stores throughout the world, is not longer visible on any Top 100 chart, anywhere. This three month pricing experiment maybe the start of a slow death for Labor Mate, but it&#8217;s not done for yet.</p>
<p>I have big plans in the works, and a new update is just around the corner. I was planning a big release in a few weeks that would hopefully justify the $1.99 price tag in the eyes of consumers but I&#8217;m changing my strategy.  Starting today, Labor Mate is back down to 99 cents, and instead of a big update in a few weeks, I&#8217;m going to release 3 or 4 updates over the next 1 to 2 months. My goal here is to get Labor Mate back on track and return to the trend I was seeing before the price increase.</p>
<p>Update: One thing I should point out is Labor Mate has a lot of competition. The other similar apps cost between free and 99 cents. This maybe a key reason why a $1.99 Labor Mate cannot sustain the slow but steady growth seen by the 99 cent Labor Mate.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/09/01/my-app-store-pricing-experiment-the-final-chapter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Rely on UIDevice orientation for Rotation</title>
		<link>http://blog.whitepeaksoftware.com/2010/08/23/dont-rely-on-uidevice-orientation-for-rotation/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/08/23/dont-rely-on-uidevice-orientation-for-rotation/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 14:01:31 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=314</guid>
		<description><![CDATA[Last week I tweeted about having rotation issues with an iPad app I&#8217;m working on. This is the second time in recent weeks I&#8217;ve encountered rotation issues in an app. In both instances I was using a UIScrollView so I started thinking the UIScrollView was source of my problems. In the most recent instance the [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I tweeted about having rotation issues with an iPad app I&#8217;m working on. This is the second time in recent weeks I&#8217;ve encountered rotation issues in an app. In both instances I was using a <em>UIScrollView</em> so I started thinking the <em>UIScrollView</em> was source of my problems. In the most recent instance the <em>UIScrollView</em> contains a <em>UIView</em> that uses a number of <em>CALayer</em> instances for content display.</p>
<p>For those who don&#8217;t know, in Mac OS X 10.5 and greater, <em>CALayer</em> has the <em>autoresizingMask</em> property. Unfortunately this property does not exists under iOS, so it&#8217;s up to my code to do the resizing CALayers as needed. This is where the rotation issue revealed itself.</p>
<p>As the device is rotated from portrait to landscape, or vice versa, my view must resize and adjust the layout of the CALayers. Because <em>UIView</em> does not receive the rotation notifications I decided to be smart and use the <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIDevice_Class/Reference/UIDevice.html#//apple_ref/doc/uid/TP40006902-CH3-SW3">orientation property</a> from <em>UIDevice</em>. So in my view I had code similar to this:</p>
<pre class="brush: objc;">
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
if (UIInterfaceOrientationIsLandscape(interfaceOrientation) == YES) {
  // Adjust for landscape.
} else {
  // Adjust for portrait.
}
</pre>
<p>What I failed to realize, however, is that the property <em>orientation</em> will <strong>always</strong> return 0 unless orientation notifications are enabled. Here is a quote directly from the Developer Documentation:</p>
<p><cite>&#8220;The value of this property always returns 0 unless orientation notifications have been enabled by calling beginGeneratingDeviceOrientationNotifications.&#8221;</cite></p>
<p>Doh! Guess I should have RTFM sooner.</p>
<p>Because the <em>orientation</em> property will return 0, sometimes the view in my app would not rotate. But I didn&#8217;t know this was the source of the problem at the time.</p>
<p>After banging my head over and over on the wall, I decided to investigate exactly what was happening. I never suspected [[UIDevice currentDevice] orientation] but eventually I noticed it was returning 0. This seemed odd so I checked the Developer Documentation. I wasn&#8217;t expecting to learn anything new. Boy, was I wrong. I was surprised when I read the property always returns 0 when orientation notifications are not enabled.</p>
<p>I now knew the source of my rotation problems, and a likely quick fix to the problem would have been to call beginGeneratingDeviceOrientationNotifications, get the device orientation, then call endGeneratingDeviceOrientationNotifications. But this just seemed wrong to me. The better fix, in my opinion, is to rely on the rotation notifications received by the view controller, so that&#8217;s exactly what I did.</p>
<p>Now in my particular situation, there are two times I want to resize and layout the CALayers in the <em>UIView</em>. One of those times is when the device is rotated, which is when the view controller receives the <em>willRotateToInterfaceOrientation:duration:</em> message. This was easy to solve. I added an <em>adjustLayoutToInterfaceOrientation:</em> method to my <em>UIView</em> and I call the method inside the UIViewController&#8217;s <em>willRotateToInterfaceOrientation:duration:</em> method. For example:</p>
<pre class="brush: objc;">
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                duration:(NSTimeInterval)duration
{
   [view_ adjustLayoutToInterfaceOrientation:toInterfaceOrientation];
}
</pre>
<p>The other time my <em>UIView</em> needs to adjust the layout of the CALayers is when the <em>UIScrollView</em> scrolls. I&#8217;m using a modified version of Matt Gallagher&#8217;s <a href="http://cocoawithlove.com/2009/01/multiple-virtual-pages-in-uiscrollview.html">virtual pages in a UIScrollView</a> approach, so the contents of my view changes as the user scrolls. This is where, previously, I was trying to be smart and use the <em>orientation</em> property from <em>UIDevice</em>. But what I really need is the current orientation as received in the most recent call to <em>willRotateToInterfaceOrientation:duration:</em>.</p>
<p>My solution was to add the ivar currentOrientation to my view controller. My view already has a reference to the view controller. I exposed currentOrientation so my view can retrieve the property value. This allowed me to replace the <em>[[UIDevice currentDevice] orientation]</em> code with <em>[controller currentOrientation]</em>. Now the view always knows the current orientation and the app does not need to enable orientation notification in code.</p>
<p>As a result, the first code snippet in this posting changes to:</p>
<pre class="brush: objc; highlight: [1];">
UIInterfaceOrientation interfaceOrientation = [controller_ currentOrientation];
if (UIInterfaceOrientationIsLandscape(interfaceOrientation) == YES) {
  // Adjust for landscape.
} else {
  // Adjust for portrait.
}
</pre>
<p>And the <em>willRotateToInterfaceOrientation:duration:</em> implementation changes to:</p>
<pre class="brush: objc; highlight: [4];">
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                duration:(NSTimeInterval)duration
{
   currentOrientation_ = toInterfaceOrientation;
   [view_ adjustLayoutToInterfaceOrientation:toInterfaceOrientation];
}
</pre>
<p>This has been an eye opener for me, and I now have a new rule of thumb. Never use <em>UIDevice orientation</em> in code that is responsible for the resizing and layouts of subviews and CALayers.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/08/23/dont-rely-on-uidevice-orientation-for-rotation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some Useful Books for iOS Developers</title>
		<link>http://blog.whitepeaksoftware.com/2010/07/26/some-useful-books-for-ios-developers/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/07/26/some-useful-books-for-ios-developers/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 21:13:44 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=303</guid>
		<description><![CDATA[Last week I had the opportunity to teach a one-day class on learning iPad programming. One of the students asked what books I recommend. A friend asked the same question over the weekend, so I thought I might as well post the list of books on iOS and Objective-C programming I have found helpful. Beginning [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I had the opportunity to teach a one-day class on learning iPad programming. One of the students asked what books I recommend. A friend asked the same question over the weekend, so I thought I might as well post the list of books on iOS and Objective-C programming I have found helpful.</p>
<ul>
<li><a href="http://www.amazon.com/Beginning-iPhone-Development-Exploring-SDK/dp/1430224592/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1280028038&#038;sr=8-1">Beginning iPhone 3 Development</a>, Dave Mark and Jeff LaMarche
<li><a href="http://www.amazon.com/More-iPhone-Development-Tackling-Beginning/dp/143022505X/ref=sr_1_2?ie=UTF8&#038;s=books&#038;qid=1280028038&#038;sr=8-2">More iPhone 3 Development</a>, Dave Mark and Jeff LaMarche
<li><a href="http://appdevmanual.com/">iPhone App Development</a>, the missing manual, Craig Hockenberry
<li><a href="http://www.pragprog.com/titles/mzcd/core-data">Core Data</a>, Marcus Zarra
<li><a href="http://www.pragprog.com/titles/amiphd/iphone-sdk-development">iPhone SDK Development</a>, Bill Dudney and Chris Adamson
<li><a href="http://www.pragprog.com/titles/sfipad/ipad-programming">iPad Programming</a>, Daniel Steinberg and Eric Freeman
<li><a href="http://www.amazon.com/iPhone-Developers-Cookbook-Building-Applications/dp/0321659570/ref=sr_1_3?ie=UTF8&#038;s=books&#038;qid=1280028038&#038;sr=8-3">The iPhone Developer&#8217;s Cookbook</a>, Erica Sadun
<li><a href="http://www.amazon.com/gp/product/0321566157/ref=s9_simh_gw_p14_i2?pf_rd_m=ATVPDKIKX0DER&#038;pf_rd_s=center-2&#038;pf_rd_r=003RBYM22CW9Q5D1EJNN&#038;pf_rd_t=101&#038;pf_rd_p=470938631&#038;pf_rd_i=507846">Programming in Objective-C</a>, Stephen Kochan
<li><a href="http://www.amazon.com/gp/product/1449381650/ref=s9_newr_gw_ir02?pf_rd_m=ATVPDKIKX0DER&#038;pf_rd_s=center-3&#038;pf_rd_r=003RBYM22CW9Q5D1EJNN&#038;pf_rd_t=101&#038;pf_rd_p=470938811&#038;pf_rd_i=507846">Tapworthy, Designing Great iPhone Apps</a>, Josh Clark
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/07/26/some-useful-books-for-ios-developers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Really Simply Timer</title>
		<link>http://blog.whitepeaksoftware.com/2010/07/19/a-really-simply-timer/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/07/19/a-really-simply-timer/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 03:11:17 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=301</guid>
		<description><![CDATA[A friend asked if I would put together a sample iOS app that shows how to display a stopwatch timer like the one used in Labor Mate. It seemed like a fun exercise to break up the night, so I said, &#8220;Sure, why not.&#8221; I decided others might find the sample source code useful so [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.whitepeaksoftware.com/wp-content/uploads/2010/07/SimpleTimer.png" alt="SimpleTimer.png" border="0" width="207" height="385" align="left" vspace="6" hspace="6" />A friend asked if I would put together a sample iOS app that shows how to display a stopwatch timer like the one used in <a href="http://www.whitepeaksoftware.com/labormate" class="kblinker" title="More about Labor Mate &raquo;">Labor Mate</a>. It seemed like a fun exercise to break up the night, so I said, &#8220;Sure, why not.&#8221; </p>
<p>I decided others might find the sample source code useful so I posted the project to <a href="http://github.com/kirbyt/SimpleTimer">github</a> for all to enjoy. The piece devs might find interesting is the KTStopwatch class. This is a simplified version of the class I use in Labor Mate. It supports wall clock and elapsed time.</p>
<p>The source code is licensed using The MIT License, so do with it what you like. Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/07/19/a-really-simply-timer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sale Numbers are In: An Update on My App Store Pricing Experiment</title>
		<link>http://blog.whitepeaksoftware.com/2010/07/02/sale-numbers-are-in-an-update-on-my-app-store-pricing-experiment/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/07/02/sale-numbers-are-in-an-update-on-my-app-store-pricing-experiment/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 13:15:06 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Labor Mate]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[White Peak Software]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[app store]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=291</guid>
		<description><![CDATA[Last month I mentioned my experiment with the pricing for Labor Mate to see what effects, if any, a price increase will have. The initial results were interesting. The number of units sold went down, but revenue had gone up. On the surface it seems the price increase was a success, but I needed more [...]]]></description>
			<content:encoded><![CDATA[<p>Last month I mentioned my <a href="http://blog.whitepeaksoftware.com/2010/06/01/sales-are-down-but-revenue-is-up/">experiment with the pricing</a> for <a href="http://www.whitepeaksoftware.com/labormate" class="kblinker" title="More about Labor Mate &raquo;">Labor Mate</a> to see what effects, if any, a price increase will have. The initial results were interesting. The number of units sold went down, but revenue had gone up. On the surface it seems the price increase was a success, but I needed more data.</p>
<p>I increased the price of Labor Mate by $1 on May 15, going from $0.99 to $1.99. By increasing the price on May 15, I was able to compare the first half of the month with the second half. And as I mentioned in the previous <a href="http://blog.whitepeaksoftware.com/2010/06/01/sales-are-down-but-revenue-is-up/">post</a> revenue had indeed gone up. But I was curious to see if this would continue and what might be the long term effects, so I left Labor Mate at $1.99. After all, I made more money in May as a result of the price increase.</p>
<p>June is over and the sales numbers are in. I&#8217;m now able to compare a full month of sales (for June) at the higher $1.99 price to a full month of sales (for April) at the lower $0.99 price. And I can compare these numbers to May&#8217;s numbers. The results might be surprising to some, but are inline with what I secretly thought would happen.</p>
<p>In June, Labor Mate earned a whooping $31.94 more money than in April, and it earned $30.90 <strong>less</strong> compared to May. In April, Labor Mate averaged $35 per day. The average was $37 per day in May, and only $36 per day in June. </p>
<p>Revenue from Labor Mate has been on a slow but steady increase since it was first released back in 2008. Though I cannot prove it, based on past trends, my gut tells me Labor Mate would have likely hit June&#8217;s revenue number in May without the price increase. And my gut, again based on the trend, says June would have probably hit May&#8217;s number without the price increase. In other words, while the price increase did improve Labor Mate&#8217;s revenue, the amount of additional revenue resulting from the price increase is actually no different from the slow and steady increase in revenue I was already seeing at the lower, 99 cent price point. As a matter of fact, I saw a bigger jump in revenue between March and April, with April bringing in a whooping $175.71 more than March.</p>
<p>I&#8217;m now convinced the price increase did little to improve revenue, and actually the price increase likely did more harm than good. Prior to the price increase Labor Mate was ranked in the Top 100 in the Health and Fitness category for a number of different countries including the U.S. Today Labor Mate is no were near ranking in the Top 100 in most stores.</p>
<p>Another negative effect caused by the price increase is that fewer people are now using Labor Mate. As I noted in the previous <a href="http://blog.whitepeaksoftware.com/2010/06/01/sales-are-down-but-revenue-is-up/">post</a>, the number of daily downloads dropped. This means fewer people are buying Labor Mate, which in turns means fewer people are using it. I believe Labor Mate&#8217;s slow but steady raise was due in part to word of mouth advertising. Now that there are fewer new moms and dads buying and using Labor Mate, there are fewer people recommending Labor Mate to other new moms and dads. And I admit, ignoring price for a moment, I&#8217;m a little disappointed that fewer people are using the app. A part of me prefers selling at a lower price point so more mom and pops to be will use it. (Hmm, maybe I should release a free, iAd supported version.)</p>
<p>So what&#8217;s next? I&#8217;ve thought about dropping the price back down to 99 cents, but this could lead to a backlash from the folks who purchased Labor Mate over the last 6 weeks. Plus, $1.99 is still cheaper than a large cup of Starbucks coffee. The better idea, and the one I have been planning all along, is to continue improving Labor Mate and make it stand out above the other 99 cent copy cats. This includes leaving the price at $1.99 for now. After all, as one recent new user said to me in email, &#8220;it is a very practical and intuitive app and certainly justified at $1.99.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/07/02/sale-numbers-are-in-an-update-on-my-app-store-pricing-experiment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using UIPopoverController with iOS 4</title>
		<link>http://blog.whitepeaksoftware.com/2010/06/10/using-uipopovercontroller-with-ios-4/</link>
		<comments>http://blog.whitepeaksoftware.com/2010/06/10/using-uipopovercontroller-with-ios-4/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 23:37:25 +0000</pubDate>
		<dc:creator>kirbyt</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.whitepeaksoftware.com/?p=271</guid>
		<description><![CDATA[I ran into an interesting bug today while testing Hey Peanut on iOS 4. For those who don&#8217;t know, Hey Peanut is a universal binary, which means it runs on both the iPhone and iPad. My iPhone has the GM version of iOS 4 installed on it, which I&#8217;m using to test my apps under [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into an interesting bug today while testing <a href="http://whitepeaksoftware.com/main/hey-peanut/index" class="kblinker" title="More about Hey Peanut &raquo;">Hey Peanut</a> on iOS 4. For those who don&#8217;t know, Hey Peanut is a universal binary, which means it runs on both the iPhone and iPad. My iPhone has the GM version of iOS 4 installed on it, which I&#8217;m using to test my apps under iOS 4. </p>
<p>Because Hey Peanut can run on both the iPhone and iPad, my code must include certain checks to avoid crashes. One check the code makes is to determine if the class UIPopoverController is available or not. Prior to iOS 4, this class was only available in iOS 3.2. The current release of iOS on the iPhone is version 3.1.3, and it does not include this class. To make use of the popover I use code such as the following:</p>
<pre class="code">
   Class popoverControllerClass = NSClassFromString(@"UIPopoverController");
   if (popoverControllerClass) {
      popoverController_ = [[UIPopoverController alloc] initWithContentViewController:[self imagePicker]];
   }
</pre>
<p>Turns out there is a big problem with this code under iOS 4 causing Hey Peanut to crash each time. It wasn&#8217;t obvious to me at first why this code was failing but as I thought it more, and as I talked through the issue with an Apple engineer, I realized, &#8220;Duh! iOS 4 is running on the iPhone, not the iPad.&#8221; Simply checking for the existence of the class isn&#8217;t good enough any more. Instead, I need to also check the device type. So with a quick change to the code, shown below, I was able to fix the crash in Hey Peanut. The code now checks that the class is available and is running on a iPad.</p>
<pre class="code">
   Class popoverControllerClass = NSClassFromString(@"UIPopoverController");
   if (popoverControllerClass <b>&#038;&#038; UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad</b>) {
      popoverController_ = [[UIPopoverController alloc] initWithContentViewController:[self imagePicker]];
   }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.whitepeaksoftware.com/2010/06/10/using-uipopovercontroller-with-ios-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

