<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8370263200616041533</id><updated>2011-12-12T09:38:49.111-08:00</updated><category term='MacHeist'/><category term='IAccessor.ReleaseAccessor'/><category term='asp.net 3.5 extensions'/><category term='parse file'/><category term='AdWhirl'/><category term='asp.net SP1'/><category term='AJAX'/><category term='smart phone'/><category term='difference tool for mac'/><category term='Core Data'/><category term='CRE Loaded'/><category term='Navigation'/><category term='iPad app review'/><category term='stringWithContentsOfFile'/><category term='iPhone development blogs'/><category term='RamJet'/><category term='Cropper'/><category term='caching in asp.net'/><category term='sqlclient'/><category term='insert'/><category term='BCP'/><category term='FindIt'/><category term='browser detection'/><category term='iPhone development'/><category term='storefront'/><category term='sqlbulkcopy'/><category term='Mac'/><category term='RCW exception'/><category term='default image'/><category term='outsource'/><category term='.net'/><category term='iOS'/><category term='fast iPhone app development'/><category term='Android'/><category term='Mac HTML Editor'/><category term='Free HTML Editor'/><category term='Expected specifier-qualifier-list before &apos;NSManagedObjectModel&apos; error and how to fix it'/><category term='cocos2d'/><category term='MobClix'/><category term='appstore'/><category term='Mac memory'/><category term='system.web.caching.cache'/><category term='ads in iPhone app'/><category term='fill rate'/><category term='drawInRect'/><category term='Magic Mouse reconnect issue'/><category term='CGContextShowTextAtPoint'/><category term='load file'/><category term='componentsSeparatedByString'/><category term='sql server'/><category term='Default.png'/><category term='ADO.NET'/><category term='PHP'/><category term='iPhone'/><category term='Magic Mouse right-click issue'/><category term='access denied error'/><category term='QuattroWireless'/><category term='Windows screen capture'/><category term='dynamic data web site'/><category term='Squeeze for Mac'/><category term='asp.net'/><category term='UITableView'/><category term='iPad'/><category term='delegate'/><title type='text'>The Eclectic Techie</title><subtitle type='html'>A technical blog by John Tabernik spanning various Microsoft technologies (including .NET, SQL Server, and SharePoint), iPhone development on the Mac, and PHP scripting (including Joomla and CRE Loaded).</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>48</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-8195216615559506656</id><published>2011-12-12T09:38:00.000-08:00</published><updated>2011-12-12T09:38:13.862-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='appstore'/><category scheme='http://www.blogger.com/atom/ns#' term='iOS'/><category scheme='http://www.blogger.com/atom/ns#' term='outsource'/><title type='text'>The Magic Camera is Up on the App Store!</title><content type='html'>I outsourced my first iOS app, and it is now live &lt;a href="http://itunes.apple.com/us/app/the-magic-camera-free/id481940663?ls=1&amp;mt=8"&gt;here&lt;/a&gt;.  The Magic Camera lets you take a picture of someone, but instead of taking the picture, the app actually presents a picture from a set of images of people from around the world, animals, etc.&lt;br /&gt;&lt;br /&gt;I had a few goals in putting this together--first, I thought it would be a fun app, and it seems like the kids really enjoy it.  Second, I wanted to get something new in the App Store, but I did not have time to write it myself.  Finally, I wanted to develop a relationship with an outsourced team to develop more app in the future.&lt;br /&gt;&lt;br /&gt;The experience was a great one--the developer that I found on oDesk did a great job, and was extremely professional.  Compared to costs that I have seen others describe for app development, I got this developed for an outstanding rate.  And I think the quality of the final version is high.&lt;br /&gt;&lt;br /&gt;Anyway, it was a great first experience outsourcing the app.  And if you have kids, they would probably enjoy this app, like my kids do!  And it's free!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-8195216615559506656?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/8195216615559506656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2011/12/magic-camera-is-up-on-app-store.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8195216615559506656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8195216615559506656'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2011/12/magic-camera-is-up-on-app-store.html' title='The Magic Camera is Up on the App Store!'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-5607758041595644550</id><published>2011-05-14T08:12:00.000-07:00</published><updated>2011-05-14T08:12:13.330-07:00</updated><title type='text'>Dynamic WordPress content - getting content from another database</title><content type='html'>I am currently working on a research project to catalog a number of events from recent history.  The goal was to be able to create these events in one database and display them.  Due to the sophistication and layout capabilities of WordPress, this seemed like a great framework to put the presentation into.  But there are a few hurdles I needed to overcome--essentially, how could I create pages in WordPress in advance, and then, when they were requested, source events them from another database.&lt;br /&gt;&lt;br /&gt;The concept may or may not seem interesting, but my goal was to dig deeper into WordPress to understand some of the inner workings.  Thanks to tons of great web sites where people share their knowledge (most notably John Faulds code example &lt;a href="http://www.tyssendesign.com.au/articles/cms/connecting-to-external-database-from-within-wordpress/comment-page-1/#comment-2835"&gt;here&lt;/a&gt;), and WordPress's own &lt;a href="http://codex.wordpress.org/"&gt;outstanding documentation&lt;/a&gt;, it was easy to develop some simple code to perform the function.&lt;br /&gt;&lt;br /&gt;First off, let me explain my approach.  It was to create all the pages in WordPress first programmatically, placing an identifier into the content section.  My goal would be to read this content section later, be able to determine what content to get from my secondary database based on this information, and then retrieve and display my new information. &lt;br /&gt;&lt;br /&gt;All you need to do is go into your functions.php page and introduce code like the following (note John Faulds' runSQL function copied here almost verbatim):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function dynamic_content() {&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$content = get_the_content();&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;echo "&lt;br /&gt;&lt;br /&gt;";&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$sql = "select description from dates where date = '" . $content . "'";&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$results = runSQL($sql);&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//echo $sql;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;while ($row = mysql_fetch_array($results)) {&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;echo $row[0];&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;echo "&lt;br /&gt;&lt;br /&gt;";&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function runSQL($rsql) {&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$rootpasswd='&lt;password&gt;';&lt;/password&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$user='&lt;user&gt;';&lt;/user&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$db='&lt;databasename&gt;';&lt;/databasename&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$dbcnx = @mysql_connect('localhost',$user,$rootpasswd,true);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if (!$dbcnx) {&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;echo '&lt;br /&gt;Unable to connect to the database server at this time.&lt;br /&gt;';&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;exit();&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;mysql_select_db($db, $dbcnx);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$result = mysql_query($rsql) or die ('test');&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return $result;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;mysql_close($connect);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This requires some explanation first.  You will notice in your loop template pages that there are regular calls to "the_content".  This function actually outputs content--and since my goal was to read this and replace it, the_content() is not acceptable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-5607758041595644550?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/5607758041595644550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2011/05/dynamic-wordpress-content-getting.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5607758041595644550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5607758041595644550'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2011/05/dynamic-wordpress-content-getting.html' title='Dynamic WordPress content - getting content from another database'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6059522861178432627</id><published>2011-04-12T18:13:00.000-07:00</published><updated>2011-04-12T18:13:27.898-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smart phone'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Review: Android Blows</title><content type='html'>Understand a few things first.  I love competition.  I firmly believe that competition is what makes people and companies strive to be better.  More than anything, I wanted iPhone to have a strong competitor to keep it honest.  Anyone who lived through the glorious chip revolution of the 1990's and saw the birth of PowerPC (who?) and AMD challenge the supremacy of Intel and the resulting monumental gains in chip technologies knows the good that comes out of companies fighting for their lives.&lt;br /&gt;&lt;br /&gt;Second, understand that dollar or dollar, I own more Google stock than I own Apple stock.  Google is an amazing company, I genuinely believe they try to do all the right things, and I know if I was presented with some of the interview questions posed to potential Google employees, I would probably curl up, wimpering, into a fetal position.&lt;br /&gt;&lt;br /&gt;But I have to be honest.  After almost five months of desperately wanting to just *like* the Android phone, I have to conclude that it is frustrating on a par with my Windows machines at work.  Yes, it's that bad.&lt;br /&gt;&lt;br /&gt;Let's start with some specifics.  I am using the Samsung Fascinate from Verizon.  Specs appear to be about on par with most Android phones--1GHz Hummingbird processor, 384M of RAM.  I love the sleek design and slim size--it is very iPhone-esque.  A co-worker showed me, and between his positive review, my love of Google, general public praise for Android, and being able to get a smart phone with Verizon service, I could not pass it up.&lt;br /&gt;&lt;br /&gt;But it only took a few times of turning it on for me to be annoyed--the phone was about as responsive as a Pentium Pro circa 1998 running Windows Vista.&lt;br /&gt;&lt;br /&gt;So I went back to my co-worker, and he explained that you pretty much HAD to run a utility (he recommended the free version of Advanced Task Killer) that would aggressively kill applications in memory that were no longer needed.  With a lot of experience with iPhone and iPad development, I was immediately skeptical.  Does the operating system manage everything so poorly that third party apps need to be bolted on to make the experience bearable?  Has Google made the equivalent of Windows for the smart phone????&lt;br /&gt;&lt;br /&gt;Advanced Task Killer immediately created it own set of problems.  Since I installed it, I notice my keypad disappears at awkward times when I am using it mid-phone call--like when I am trying to enter my PIN to access my voicemail.  I tried disabling ATK for the obvious tasks--like the phone--but that did not fix the problem.  Turning down the aggressiveness of the task killing (I normally have it set to "Aggressive", not the top setting of "Crazy") does help, but then my phone is no longer responsive in any way again.  I would call it a catch-22, but my keypad would disappear after I type the first 2.&lt;br /&gt;&lt;br /&gt;Next comes the most common app I would use on the phone, Mail.  Strangely enough, the native mail app was so slow and sluggish, I switched over to the official Yahoo! mail app.  This, let me tell you, is a real piece of work.  Not only does it suffer from the absolutely embarrassing performance, it has weird quirks that you need to be aware of.  For example, there is an Outbox.  Once I sent an email, watched the message appear on the screen saying it was waiting to be sent, then waited until it disappeared.  No problem.  The next day, I found this not STUCK IN MY OUTBOX.  I had synched mail probably 50 times.  And of course I discovered this handy problem with an important email.  Today, I just figured out the work around.  When messages get stuck in your Outbox, start up the aforementioned Advanced Task Killer, kill Yahoo Mail, restart it, and hope for the best.  It only took me 15 minutes to send this email today.  Of course, in the future, I know I can just kill the application and restart it to actually send a note.  Does this sound more and more like Windows to you????  (OK, you are thinking, Google is not responsible for what Yahoo publishes, right?  I think I am within my rights to list this because (1) it is actually better than the native mail app, (2) I am sure the poor performance has something to do with the operating system since every Android app seems to suffer from it.)  Oh, and did I mention the performance?  If you are retrieving mail, don't even bother trying to scroll the display or even use the home button to get out of the app.  If an app does not want to give up control to the operating system, you might as well set the phone down and let it do its thing for the 7 minutes--because it will NOT respond.&lt;br /&gt;&lt;br /&gt;Oh, and then let's talk about browsing.  If I try to launch my My Yahoo! page in the native browser, the application crashes.  I guess that is good, because I don't have to load up ATK to do it for me.  In desperation, I switched to the Dolphin browser, which can be downloaded free.  It is pretty good, has not crashed on me, and seems to perform pretty well.  I recommend Google or Verizon (whoever is packaging the native browser on the Fascinate) switch to Dolphin.  It would have saved me hating something else about the Android.  And you would not have needed to read this paragraph.&lt;br /&gt;&lt;br /&gt;I had a lot of confidence in Android's overall approach.  Be open.  Run on all kinds of hardware.  Open source the code so it can be understood, and possibly improved.  But I would contend after 5 months of serious use that it is simply not finished.  Android, if it will ever be a contender, is going to need either a major overhaul, a significantly higher hardware requirement to offset the unacceptable performance of the apps, or some combination of the two.  The iPhone outshines it in so many ways, it is not even a contest.  But the biggest way--it is just plain usable.  Sure, bad connection speeds are a fact of life when you are not in wi-fi range.  The iPhone is cool with that--maybe you can't get your mail right then, but you can scroll through the mail you do have, even press the home button to go do something else if mail isn't getting retrieved fast enough for you.  Try doing this with an iPhone, then with your shiny new Android.  You will want to put your Android through the nearest window.&lt;br /&gt;&lt;br /&gt;So, if you are in the market for a smart phone, PLEASE think carefully before you get an Android.  If you are patient and like waiting on your devices, or if you are getting it for free and would have to pay for anything else, or you have never used a peripheral in your life that was not powered by Windows, you might be happy with it.  But if you do not fit into one of these three categories, you owe it to yourself to look at all the choices out there....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6059522861178432627?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6059522861178432627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2011/04/review-android-blows.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6059522861178432627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6059522861178432627'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2011/04/review-android-blows.html' title='Review: Android Blows'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-9222091223150687634</id><published>2010-11-08T20:08:00.000-08:00</published><updated>2010-11-08T20:14:29.818-08:00</updated><title type='text'>Building Web Sites with Microsoft Technologies</title><content type='html'>I just finished a continuing education class at Lakeland Community College in Kirtland, OH.  I am putting the slides for the class out here if they are useful to anyone.&lt;br /&gt;&lt;br /&gt;Here are the presentation and class materials for the 5 classes:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/fileview?id=0B2kHxfGtE6TUNzk2M2EyZjgtMzc2Mi00NTAwLWE3YjQtMTJlMzUxZWIxY2Fi&amp;hl=en"&gt;Part 1: ASP.NET&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B2kHxfGtE6TUYzc5YzNlOTYtODA5Zi00ODM1LWJkYWItNjc3YWNmMzMwMjA5&amp;hl=en"&gt;Part 1: ASP.NET project files&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/fileview?id=0B2kHxfGtE6TUZDg2MTQ0Y2YtZGVlMC00ZDY1LWFmYzEtNDI1YjE1YTBjZjQy&amp;hl=en"&gt;Part 2: .NET Framework&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B2kHxfGtE6TUMjA2YjI4ZjUtNWJhZC00OWE1LThhNTEtYTFkODQwZjFlNmM1&amp;hl=en"&gt;Part 2: .NET Framework project files&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/fileview?id=0B2kHxfGtE6TUMjc2NjRkYTAtNWVkYS00MTc2LWI5OTQtYTE0YThhNzk5MGYz&amp;hl=en"&gt;Part 3: Database concepts&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/fileview?id=0B2kHxfGtE6TUZDFkODEzOGUtZjE0YS00YjVjLWE0NjEtNTc4NTQ4NGVkNzJk&amp;hl=en"&gt;Part 4: ADO.NET&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B2kHxfGtE6TUMGIzMTRjZTctY2FjZS00Mjg1LTgxNzktMDQ5Mzk1MDFjMmYy&amp;hl=en"&gt;Part 4: ADO.NET project files&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/fileview?id=0B2kHxfGtE6TUMzQ0YTEzY2ItYzk1My00NjY4LThiODgtYWVmYmZhOTY2OTVl&amp;hl=en"&gt;Part 5: Putting It All Together&lt;/a&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B2kHxfGtE6TUZDRjNTJjN2QtNTljNS00NGJjLWIwOTctMDUxNDYxMTY2ZTg5&amp;hl=en"&gt;Part 5: Putting It All Together project files&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Questions?  Shoot me an email.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-9222091223150687634?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/9222091223150687634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/11/building-web-sites-with-microsoft.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/9222091223150687634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/9222091223150687634'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/11/building-web-sites-with-microsoft.html' title='Building Web Sites with Microsoft Technologies'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-2714473088274910363</id><published>2010-08-10T16:04:00.000-07:00</published><updated>2010-08-10T16:05:21.324-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='difference tool for mac'/><title type='text'>Great Free Differencing Tool for Mac</title><content type='html'>For some odd reason, searching in Google for a file differencing tool for Mac does not return anything promising.  The best I found easily was a blog post saying to use the FileMerge that gets installed with Xcode.  You can run it from the command line.&lt;br /&gt;&lt;br /&gt;Command line?  Look, I am a Microsoft developer most of the time.  That means I both expect and need things to be kinda easy.&lt;br /&gt;&lt;br /&gt;Luckily, I searched a little further and found &lt;a href="http://sourcegear.com/diffmerge/"&gt;Sourcegear's DiffMerge&lt;/a&gt;.  Just like you would expect, graphical, easy to use, and free.&lt;br /&gt;&lt;br /&gt;Thanks, Sourcegear!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-2714473088274910363?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/2714473088274910363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/08/great-free-differencing-tool-for-mac.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2714473088274910363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2714473088274910363'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/08/great-free-differencing-tool-for-mac.html' title='Great Free Differencing Tool for Mac'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-8174204992751383775</id><published>2010-07-09T19:27:00.000-07:00</published><updated>2010-07-09T19:27:31.200-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fast iPhone app development'/><title type='text'>Crank Out Some iPhone Apps - Outsource Them!</title><content type='html'>If you have been reading my blog, you know my story--I am a Microsoft developer by day, and an iPhone/iPad developer by night.  The problem--when you have a wife and kids and a house (or even a social life) this is not really sustainable for long.&lt;br /&gt;&lt;br /&gt;With iOS4 coming out, I have been doing a little less coding lately and a little more reading about iPhone development.  One of the things I have been reading is books by others promising ways to write apps quickly or make money on iPhone apps.  A lot of them I just laugh at.  So when I read an ad promising to let me write iPhone quickly without writing code--well, I had to read the book just to see what they were promising.&lt;br /&gt;&lt;br /&gt;To my surprise, it was a really good idea!  The book, &lt;a href="http://ed64ad8wj6wlp70926ilo5ecvi.hop.clickbank.net/"&gt;How To Create iPhone Apps with No Programming Experience&lt;/a&gt; is actually a great step-by-step methodology to get apps built the easy way--by explaining what you want and handing it off to someone else to code.  The book comes with a few extras, the most interesting on how to make money with free apps, which you probably already know.  But the book itself was a good read.  If you have any thoughts about trying to write an iPhone yourself but just don't have the time, this is a great solution.&lt;br /&gt;&lt;br /&gt;The best part of the book was the description of some of the completely ridiculous apps that have made big money.  The point being, of course, that marketing is every bit as important in the iPhone app gold rush as programming.  You can have a slick app, but if you have no marketing plan, it will disappear in the mountain of apps released daily.  Conversely, if you have an idea for an app that you can market, maybe a crazy simple app could make you rich.  And if you outsource them, you can crank out ten in the time you would have done one yourself.&lt;br /&gt;&lt;br /&gt;Anyway, check out &lt;a href="http://ed64ad8wj6wlp70926ilo5ecvi.hop.clickbank.net/"&gt;How To Create iPhone Apps with No Programming Experience&lt;/a&gt;.  It is a great no-nonsense approach to getting your app out there for people to download.&lt;br /&gt;&lt;br /&gt;BTW--I have unofficially crossed the 50,000 app download mark.  How exciting is that!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-8174204992751383775?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/8174204992751383775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/07/crank-out-some-iphone-apps-outsource.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8174204992751383775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8174204992751383775'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/07/crank-out-some-iphone-apps-outsource.html' title='Crank Out Some iPhone Apps - Outsource Them!'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-269667230074761194</id><published>2010-06-01T09:48:00.000-07:00</published><updated>2010-06-03T00:48:27.204-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPad'/><category scheme='http://www.blogger.com/atom/ns#' term='appstore'/><category scheme='http://www.blogger.com/atom/ns#' term='iPad app review'/><title type='text'>Review process for iPad apps--Yikes!</title><content type='html'>So I submitted my first iPad app almost 2 weeks ago.  After being lulled into a false sense of confidence following iPhone app reviews, I have had a bad experience with this review.&lt;br /&gt;&lt;br /&gt;iPhone app reviews had gotten down to a few days at the end of last year and earlier this year.  So I expected the iPad app review for my first app to be, I don't know, vaguely like that.&lt;br /&gt;&lt;br /&gt;When I saw my app go from "submitted" to "in review" so quickly, I was very optimistic.  But then came an extremely long delay.  And OK, I am fine with a delay--I am sure everyone is submitted iPad apps right now.&lt;br /&gt;&lt;br /&gt;But then came the frustration.  After 8 days (yes, 8 days) I get a notice that my app had been rejected.  The reason?  I had called it "FindIt for iPad" on the title screen, and this is a copyrighted term.  Fair enough--I probably should have thought of that.  But what required 8 days to figure out that "iPad" was prominently placed on the main page?????&lt;br /&gt;&lt;br /&gt;Then, of course, the process has to start over from scratch.  Again, I get it--a new binary, and anything can be in it.  So the new executable has to be completely tested.  So we are now a full 16 days from the initial submittal.  And I don't have much confidence that it is really being reviewed any more when it says "in review."  (See rant above about "how did it take 8 days to figure out 'iPad' was prominently placed on the main page.")&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_c2pE14ayF2g/TAU3lIiu3cI/AAAAAAAAACY/noSTlPFoRCs/s1600/FindIt-Review.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="113" src="http://2.bp.blogspot.com/_c2pE14ayF2g/TAU3lIiu3cI/AAAAAAAAACY/noSTlPFoRCs/s400/FindIt-Review.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Scary stuff.  Hopefully this helps someone out there avoid the same issue I had.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-269667230074761194?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/269667230074761194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/06/review-process-for-ipad-apps-yikes.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/269667230074761194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/269667230074761194'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/06/review-process-for-ipad-apps-yikes.html' title='Review process for iPad apps--Yikes!'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_c2pE14ayF2g/TAU3lIiu3cI/AAAAAAAAACY/noSTlPFoRCs/s72-c/FindIt-Review.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-333004149343355345</id><published>2010-05-17T17:43:00.000-07:00</published><updated>2010-05-17T17:43:07.891-07:00</updated><title type='text'>Anybody need $5/mo PHP hosting?</title><content type='html'>So it turns out I overbought my PHP hosting a bit....and I have a bunch of extra bandwidth.  It is great hosting from HostNine, including MySQL database, Control Panel, Fantastico Deluxe with Joomla and WordPress, etc etc.  I bought a reseller account because I needed to host for several of my clients.  This was a good deal, but I have a bunch of unneeded bandwidth that is going to waste.&lt;br /&gt;&lt;br /&gt;Anyway, let me know if you are interested.  We can work out how much throughput and space you need.  You can't get quality hosting like anywhere for $5/month!&lt;br /&gt;&lt;br /&gt;I think I can take on 4-5 new accounts, so I will offer this deal to the first 4 or 5 people to get in touch with me.  Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-333004149343355345?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/333004149343355345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/05/anybody-need-5mo-php-hosting.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/333004149343355345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/333004149343355345'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/05/anybody-need-5mo-php-hosting.html' title='Anybody need $5/mo PHP hosting?'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1297447176051691479</id><published>2010-05-17T16:53:00.000-07:00</published><updated>2010-05-17T16:53:18.783-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RamJet'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac memory'/><title type='text'>Best. Mac Memory. Ever.</title><content type='html'>I have really wanted for a while to upgrade my MacBook Pro from 4G to 8G, but I didn't want to fork over the $800 (recently dropped to $600) to get it from the Apple Store.  There are lots of sites out there that offer premium memory for discount prices--how do you know you will get good memory and good customer service?  You ask your other Mac friends where they get there memory!&lt;br /&gt;&lt;br /&gt;Luckily, my friend Dave Ferrell (a.k.a. XCodeGuy) has owned Macs for a long time and has a number of do's and don'ts when it comes to software, hardware, and peripherals.  He recommended &lt;a href="http://www.ramjet.com/index.html"&gt;RamJet.com&lt;/a&gt;, which he said has great prices and the memory has always worked for him.&lt;br /&gt;&lt;br /&gt;I have to say the customer experience with RamJet was above average.  Between the emails alerting me to the status of the order, the status of shipping, and the status of my refund, I was very impressed.  Yes, I said REFUND.  RamJet will buy back your existing memory for a nice price.  I was able to buy my new memory for $359 and get $50 back for my Apple memory.  So for almost 1/2 the price of the Apple memory, I got my 8G and I am loving it!&lt;br /&gt;&lt;br /&gt;So, if you need solid memory for less than you would pay for genuine Apple memory, you can't miss with RamJet.  Thanks guys!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1297447176051691479?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1297447176051691479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/05/best-mac-memory-ever.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1297447176051691479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1297447176051691479'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/05/best-mac-memory-ever.html' title='Best. Mac Memory. Ever.'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-4994122802912340276</id><published>2010-04-18T16:04:00.000-07:00</published><updated>2010-04-18T16:04:40.806-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Magic Mouse right-click issue'/><category scheme='http://www.blogger.com/atom/ns#' term='Magic Mouse reconnect issue'/><title type='text'>Pretty tired of Magic Mouse issues</title><content type='html'>As you are probably aware, I am huge fan of the Mac and of Apple products.  The are solid, well engineered, and I have had few issues with any Apply hardware.&lt;br /&gt;&lt;br /&gt;Except for the Magic Mouse, which has caused me a lot of frustration.  My first mouse I got at Christmas of 2009 for use with my early-2009 unibody 2.66Ghz MacBook Pro.  It worked great for a while--it was easy to make the transition to it, and I really like having the desktop even less cluttered because it is wireless.&lt;br /&gt;&lt;br /&gt;But then, after a few months, I started experiencing a strange issue.  A large percentage of the time, even if I clicked all the way over to the left of the mouse, it would act like I was doing a right-click.  After having my wife try it too (to make sure I wasn't doing something wrong) and confirm it was acting strangely, I took it back and had it replaced.&lt;br /&gt;&lt;br /&gt;Then, everything worked well for a few months.  Until I disconnected the MacBook Pro from everything and used it away from my mouse and keyboard.  Ever since I brought the MacBook Pro back and reconnected it, I have to manually disconnect and reconnect the mouse every time I start up my laptop.&lt;br /&gt;&lt;br /&gt;One of the things I love about Apple products is that they just work.  We pay a premium for them, and they are worth it, because they save us time.  But what about when they don't work?  Then we paid a premium for junk--and worse yet, with high expectations, because Apple stuff is supposed to *just work*.&lt;br /&gt;&lt;br /&gt;This is definitely the kind of thing that would have annoyed me on the PC.  On the Mac, I am just fed up.  I want my money back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-4994122802912340276?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/4994122802912340276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/04/pretty-tired-of-magic-mouse-issues.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/4994122802912340276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/4994122802912340276'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/04/pretty-tired-of-magic-mouse-issues.html' title='Pretty tired of Magic Mouse issues'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1654436890513744165</id><published>2010-03-28T18:48:00.000-07:00</published><updated>2010-03-28T18:48:04.256-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='CRE Loaded'/><category scheme='http://www.blogger.com/atom/ns#' term='browser detection'/><title type='text'>Detect IE6 and redirect to compatible site in CRE Loaded</title><content type='html'>There are tons are beautiful CRE Loaded sites--if you are ever in the market for one, I personally am a huge fan of &lt;a href="http://www.algozone.com/"&gt;AlgoZone&lt;/a&gt; and &lt;a href="http://www.rockettheme.com/"&gt;RocketTheme&lt;/a&gt; for CRE Loaded and Joomla themes.  But one of the downsides of the nicer themes is compatibility issues.  For those of you who have not jumped on the CSS bandwagon, or for others of you unaware of the "old days" of web development, there has been a huge shift over time in the way styles are applied to sites.&lt;br /&gt;&lt;br /&gt;In the old days, tables were your only tool.  Whatever you needed to do, you created tables, nested tables, and played with table attributes.  Tables could do a lot, but the final code for a complex page was all but incomprehensible, and forget trying to debug someone else's.  It could be a real mess to find and fix errors, or to try to add new elements into pages.&lt;br /&gt;&lt;br /&gt;The shift over time has been to use CSS styles applied to DIV tags.  This keeps a great deal of presentation details separate from the pages, allow for page content to be developed apart from really complex styles.  In addition to separating the actual code, this also provides great ways to take a page and render it completely differently based completely on the CSS applied.  Content management systems in particular make extensive use of this because their individual widgets can display simple content, and the CSS applied can really change the output.  This would have been a very difficult job in the old table days.&lt;br /&gt;&lt;br /&gt;So back to CRE Loaded styles.  I recently was working on putting a new template on a storefront, when one of my team members thought to look at the in IE6.  The results were horrific.  The site not only looked bad, elements such as the product menu just didn't show up.  We ran some stats and found to our surprise that nearly 10% of potential customers coming to the store use IE6.  So something had to be done.&lt;br /&gt;&lt;br /&gt;I decided the easiest solution was to set up another domain, check the browser type, and then redirect IE6 users to the other domain.  Connection information in CRE Loaded would stay the same, so both sets of users would share the same database, and the job would be trivial.&lt;br /&gt;&lt;br /&gt;So, I searched the code and found a good place to put the IE6.  The first step was the put the following in includes/application_top.php:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// first.....since IE6 performs very badly with our template....&lt;br /&gt;// detect the browser and send all those poor souls to the&lt;br /&gt;// old template&lt;br /&gt;include('includes/browser_detect.php');&lt;br /&gt;&lt;br /&gt;$a_browser_data = browser_detection('full');&lt;br /&gt;if ( $a_browser_data[0] == 'ie' )&lt;br /&gt;{&lt;br /&gt; if ( $a_browser_data[1] &lt;= 6 ) {  $url = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];  $url = str_replace("www.myDomain.com", "www2.myDomain.com", $url);  header('Location: ' . $url ) ; }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I found some great code to detect the browser type &lt;a href="http://TechPatterns.com"&gt;here&lt;/a&gt;.  I put that code in includes/browser_detect.php.&lt;br /&gt;&lt;br /&gt;Then I went to test, and discovered that half the time I clicked on things, I was being redirected to the old site.  After some seaching, I found that the domain is actually stored in a few pages of the php script.  I changed those, and then I was staying consistently in the new site.  Perfect.&lt;br /&gt;&lt;br /&gt;Next I went into the admin side of the new site, and changed the template.  Oh wait.  The default template is stored in the database!  The database that I am sharing between the sites!  Time for more analysis.&lt;br /&gt;&lt;br /&gt;I searched and searched through the code and discovered that DEFAULT_TEMPLATE was the variable that I needed to set, but DEFAULT_TEMPLATE was not set anywhere in the code.  I realized my lack of PHP knowledge was hurting me, so I started looking up constant definition in PHP.  It became clear that the value was being set somewhere, but searching the codebase had turned up nothing.  Then I realized there must be somewhere in the code that all the configuration variables were being pulled in from the database and constants were being created for them.&lt;br /&gt;&lt;br /&gt;After more searching, I discovered the code I expected was in includes/application_top.php, not far from where I had inserted the above lines:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// set application wide parameters&lt;br /&gt;$configuration_query = tep_db_query('select configuration_key as cfgKey, configuration_value as cfgValue from ' . TABLE_CONFIGURATION);&lt;br /&gt;while ($configuration = tep_db_fetch_array($configuration_query)) {&lt;br /&gt;  define($configuration['cfgKey'], $configuration['cfgValue']);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PHP does not allow you to redefine the constants either....so there was no way to let this loop occur and then redefine the value later.  Instead, you could either put an if clause in the code, look for DEFAULT_TEMPLATE, and set the value there, or instead set your override value first, then check as you are looping to see if the value is already defined, and only define it if it is not.  It was late at night, so I chose the first.  The more bulletproof way would really be to set up an include to define overrides and then put the conditional logic in this loop to skip any values that are currently defined.  When I have some free time I will definitely refactor this code.&lt;br /&gt;&lt;br /&gt;Anyone ever try to do anything like this?  Let me know if you had a better solution.  Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1654436890513744165?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1654436890513744165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/detect-ie6-and-redirect-to-compatible.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1654436890513744165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1654436890513744165'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/detect-ie6-and-redirect-to-compatible.html' title='Detect IE6 and redirect to compatible site in CRE Loaded'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-2226198251526251804</id><published>2010-03-16T09:52:00.000-07:00</published><updated>2010-03-16T09:52:56.163-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='access denied error'/><title type='text'>The Infamous "Access Denied" AJAX Error</title><content type='html'>A client of mine had a website issue--the red X in the lower left in IE saying an error had occurred.  I dug in a little and discovered the famous pop-up that you have probably seen if you have done any amount of AJAX development:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_c2pE14ayF2g/S5-1Z-x5mrI/AAAAAAAAACQ/SCuyFT3YieY/s1600-h/AJAXerror.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_c2pE14ayF2g/S5-1Z-x5mrI/AAAAAAAAACQ/SCuyFT3YieY/s320/AJAXerror.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The error message can change slightly depending on your browser, but you will get some variation of "This page is accessing information that is not under its control.  This poses a security risk.  Do you want to continue?" or "Access denied" or "Access is denied."&lt;br /&gt;&lt;br /&gt;Essentially, here is the problem.  It is not uncommon, especially in large corporate environments, for the web services being called to actually live in a different domain from the page that is rendered.  Browsers consider it a security hole to be displaying data from site X and be performing an XmlHttpRequest against site Y.  And this is probably for the best.&lt;br /&gt;&lt;br /&gt;To remedy this situation, you need to either (1) get your application and web services on the same domain or (2) provide some kind of proxy that allows for calling the web service on the other domain within your own domain.&lt;br /&gt;&lt;br /&gt;Sometimes this is easier said then done, but I was very lucky in my case.  My client actually was using a domain name that resolved to the same domain the page was being served up from.  They had created separation in case the web services and web sites were ever migrated to different machines.  So, it was a simple matter of using the same domain for the services used by the web site.&lt;br /&gt;&lt;br /&gt;The client is actually moving in the direction of making all their machines the same, at least for this collection of web apps and services.  It is not often a resolution to a problem is so easy.  Anyway, this is something to keep in mind when you get the "access denied" error on an AJAX-enabled site.&lt;br /&gt;&lt;br /&gt;Good luck out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-2226198251526251804?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/2226198251526251804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/infamous-access-denied-ajax-error.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2226198251526251804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2226198251526251804'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/infamous-access-denied-ajax-error.html' title='The Infamous &quot;Access Denied&quot; AJAX Error'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_c2pE14ayF2g/S5-1Z-x5mrI/AAAAAAAAACQ/SCuyFT3YieY/s72-c/AJAXerror.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1798137699833137915</id><published>2010-03-06T13:41:00.000-08:00</published><updated>2010-03-06T13:41:43.346-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='drawInRect'/><category scheme='http://www.blogger.com/atom/ns#' term='CGContextShowTextAtPoint'/><category scheme='http://www.blogger.com/atom/ns#' term='FindIt'/><title type='text'>Draw text faster with CGContextShowTextAtPoint</title><content type='html'>The FindIt puzzles have turned out pretty well, but there are still a few things I am not happy with.  The things that bother me most--slow load times on the puzzle selection page and on the puzzle screen.  The load time on the puzzle selection page is not horrible--usually 2 to 3 seconds.  But my goal is to release an update to FindIt Premium that will include all the puzzle packs to date.  If I am seeing 2-3 seconds for 10 puzzles, what will it be like at 30?  This clearly needs to be improved.&lt;br /&gt;&lt;br /&gt;Luckily, this part was easier to figure out.  To get the game out the door, I used text files for the data.  With some time to step back and get the game cleaned up, I changed the puzzle metadata over from flat files to SQLite and Core Data.  This has had a small impact on load time--around 2 seconds.  Not that significant for just 10 puzzles, but in my profiling, and I seeing a significant increase as the number of puzzles increases.  So my update for this should be coming out soon.&lt;br /&gt;&lt;br /&gt;But what about the main page load time?  Again, I performed some analysis to determine what was the bottleneck.  I had assumed loading the page data from files again was the problem.  So I started commenting out code and testing.  Sure enough, the puzzle data loaded very quickly from a single file.  That wasn't it.&lt;br /&gt;&lt;br /&gt;Next I tried changing my looping logic, changed from a dynamically allocated NSMutableArray to an array I preallocated to the correct size, and even changed my short-cutting logic to decide whether to write out a letter or not.  None of these were the culprit.&lt;br /&gt;&lt;br /&gt;But then I commented out my writing the letters to the screen with NSString drawInRect.  Immediately, even my largest puzzles (85x85) loaded in a second.  So I set out to find a more efficient way to write out text.  As I learned more, I saw that drawInRect is really trying to do a lot for you--like using the output area of the text for alignment and clipping.  I am just trying to write out a single letter, so this was all unnecessary overhead.&lt;br /&gt;&lt;br /&gt;If you are doing something like this, try CGContextShowTextAtPoint.  This is a much more high-performance function that is not trying to align the text or perform clipping--it is just writing out the letters the way you tell it to.  For me, this was perfect, and much more efficient.  I noticed load time on even the largest puzzles was much more efficient, around 2 seconds or so, down from as many as 5.&lt;br /&gt;&lt;br /&gt;This is also good news since I plan to release an iPad version of FindIt.  Sure, the processor is going to be faster, but I also plan to display a lot more on a page.  Considering that, I wanted to be sure to have the efficiency tweaked for optimal performance.&lt;br /&gt;&lt;br /&gt;Hopefully this helps you too!  Good luck with your iPhone and iPad development!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1798137699833137915?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1798137699833137915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/draw-text-faster-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1798137699833137915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1798137699833137915'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/draw-text-faster-with.html' title='Draw text faster with CGContextShowTextAtPoint'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-8539190190572795287</id><published>2010-03-03T20:20:00.000-08:00</published><updated>2010-03-03T20:20:13.416-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='system.web.caching.cache'/><category scheme='http://www.blogger.com/atom/ns#' term='caching in asp.net'/><title type='text'>Caveat on Caching in ASP.NET</title><content type='html'>If you are working with the System.Web.Caching.Cache component in ASP.NET, there is something you should probably know.  The cache is not a virtual location where data is being stored; instead, the cache is a collection, and as such, the objects being put into it are being put in by reference, not by value.&lt;br /&gt;&lt;br /&gt;I was working with a client today and they were experiencing an issue that no one could figure out.  I dug into it, and discovered that they were doing the following:&lt;br /&gt;&lt;br /&gt;1)  Creating an System.Xml.XmlDocument object and loading it with data&lt;br /&gt;2)  Inserting this object into the cache&lt;br /&gt;3)  Removing some nodes from the object&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Following a page transition, they were pulling the document back out of the cache, and they could not understand why nodes seemed to be disappearing.  This is when I explained how the cache works, and that is it not saving a representation of the object when it is inserted into the cache, but rather putting the object into the cache collection.&lt;br /&gt;&lt;br /&gt;Just a good thing to know if you plan to be caching and changing objects.  Good luck out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-8539190190572795287?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/8539190190572795287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/caveat-on-caching-in-aspnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8539190190572795287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8539190190572795287'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/03/caveat-on-caching-in-aspnet.html' title='Caveat on Caching in ASP.NET'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1491330540320241023</id><published>2010-02-28T20:04:00.000-08:00</published><updated>2010-02-28T20:04:43.269-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Expected specifier-qualifier-list before &apos;NSManagedObjectModel&apos; error and how to fix it'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='Core Data'/><title type='text'>Expected specifier-qualifier-list before 'NSManagedObjectModel' error and how to fix it</title><content type='html'>I was putting Core Data into an existing application.  I was cutting and pasting a lot from the excellent Apple example, iPhoneCoreDataRecipes.  No, this is not a bunch of code examples to show you how to get started with Core Data...but it is a working example of how to get an app up and running with Core Data using SQLite as a back-end persistent store.&lt;br /&gt;&lt;br /&gt;So, I was happily cutting and pasting code between iPhoneCoreDataRecipes and my iPhone app (the premium version of &lt;a href="http://itunes.apple.com/us/app/findit-premium-word-find-game/id343745362?mt=8"&gt;FindIt&lt;/a&gt;, if you must know) when I ran into the following error everywhere:&lt;br /&gt;&lt;br /&gt;Expected specifier-qualifier-list before 'NSManagedObjectModel'&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The object changed (i.e. it was not always 'NSManagedObjectModel') but the error was consistent.  And yet I was copying everything over from the .m and .h files in the Apple example.  Strange.&lt;br /&gt;&lt;br /&gt;My first thought was checking that I had included the Core Data framework in the app.  Yup.  That wasn't it.&lt;br /&gt;&lt;br /&gt;Then I realized--it was the global prefix file.  I went and checked out the Apple example, and sure enough, Core Data was there.  I just needed to through this into my &lt;appname&gt;_Prefix.pch file as well, and all the errors went away.&lt;br /&gt;&lt;br /&gt;Hope this helps you too!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1491330540320241023?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1491330540320241023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/02/expected-specifier-qualifier-list.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1491330540320241023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1491330540320241023'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/02/expected-specifier-qualifier-list.html' title='Expected specifier-qualifier-list before &apos;NSManagedObjectModel&apos; error and how to fix it'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1766270004041268769</id><published>2010-02-28T18:18:00.000-08:00</published><updated>2010-02-28T18:19:32.401-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac'/><category scheme='http://www.blogger.com/atom/ns#' term='Squeeze for Mac'/><category scheme='http://www.blogger.com/atom/ns#' term='MacHeist'/><title type='text'>This year's MacHeist is coming soon / Is Squeeze worth it?</title><content type='html'>If you are a Mac user, don't miss this year's &lt;a href="http://www.macheist.com/"&gt;MacHeist software bundle&lt;/a&gt;, due to arrive March 2nd.  MacHeist offers great niche software for free or nearly free.  I usually find at least one piece of software in the bundle that I end up using regularly.  Whatever else, it is cool to get your hands on new, high-quality, low-cost Mac software and take if for a spin.&lt;br /&gt;&lt;br /&gt;Right now, MacHeist is offering a free license for LateNiteSoft's &lt;a href="http://www.latenitesoft.com/squeeze/"&gt;Squeeze for Mac&lt;/a&gt;.  The idea sounds awesome--just like compressing directories on the PC.  If you are not aware of the process, file compressors sit in between the OS's file access methods and the file system, and make the files work exactly as they did before, but compressing them on writes and decompressing them on reads on the fly.  The amazing part--since physical file access is typically the slowest part of the read or write, compression reduces disk access but increases CPU time.  Since CPU is very cheap compared to the physical access, you usually *improve* performance while you are decreasing disk usage.  This makes disk compression under most circumstances a no-brainer.&lt;br /&gt;&lt;br /&gt;But I had interesting results in using Squeeze.  I had a directory of wave files that I tried to compress.  The directory was around 200MB.  Here is a screen capture of directory information from Path Finder:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_c2pE14ayF2g/S4siVNZDg9I/AAAAAAAAABY/mDlE4tczbbE/s1600-h/Squeeze+-+Path+Finder+results.png" imageanchor="1"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_c2pE14ayF2g/S4siVNZDg9I/AAAAAAAAABY/mDlE4tczbbE/s320/Squeeze+-+Path+Finder+results.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here is what I saw in Squeeze:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_c2pE14ayF2g/S4sidWdYtxI/AAAAAAAAABg/cnx8tzq45gE/s1600-h/Squeeze+results.png" imageanchor="1"&gt;&lt;img border="0" height="46" src="http://3.bp.blogspot.com/_c2pE14ayF2g/S4sidWdYtxI/AAAAAAAAABg/cnx8tzq45gE/s400/Squeeze+results.png" width="400" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_c2pE14ayF2g/S4sidWdYtxI/AAAAAAAAABg/cnx8tzq45gE/s1600-h/Squeeze+results.png" imageanchor="1"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_c2pE14ayF2g/S4sidWdYtxI/AAAAAAAAABg/cnx8tzq45gE/s1600-h/Squeeze+results.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Hmmmmm.  22GB saved on a 200MB directory?  For some reason, I am skeptical.  I am a developer, so I know fairly minor things like this happen--it is no reason to dismiss a piece of software.  But this was in addition to the fact that is kept running, and I was not seeing significant compression on any directories.  Anybody else have any good or bad stories to relate on Squeeze for Mac?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1766270004041268769?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1766270004041268769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/02/this-years-macheist-is-coming-soon-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1766270004041268769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1766270004041268769'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/02/this-years-macheist-is-coming-soon-is.html' title='This year&apos;s MacHeist is coming soon / Is Squeeze worth it?'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_c2pE14ayF2g/S4siVNZDg9I/AAAAAAAAABY/mDlE4tczbbE/s72-c/Squeeze+-+Path+Finder+results.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-5588270158577117228</id><published>2010-02-02T09:41:00.000-08:00</published><updated>2010-02-02T09:41:33.857-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows screen capture'/><category scheme='http://www.blogger.com/atom/ns#' term='Cropper'/><title type='text'>Windows screen capture utility</title><content type='html'>You probably run into this situation--you need to take a snapshot of a section of the screen for a million different reasons, either to show someone or document something or include in an email.  I probably reach for a tool ten times a day to do this.  The Mac and Windows Vista and 7 have this functionality built in; but what about those of us still working on XP at work?&lt;br /&gt;&lt;br /&gt;Enter Brian Scott's &lt;a href="http://blogs.geekdojo.net/brian/articles/Cropper.aspx"&gt;Cropper&lt;/a&gt;.  Cropper is a simple, lightweight, and free solution to this problem.  Install the app from the download at the like above and launch it.  It will place the Cropper icon in your system tray.  Then, when needed, you can double click this icon, and pop up a sliding control on the screen to select an area for copying.&lt;br /&gt;&lt;br /&gt;I used SnagIt for years and disliked several things--it seemed very bloated and slow to do simple screen captures.  Plus, how many times did you highlight the upper left corner and start clicking and dragging only to see you had not gone up high enough or the left far enough?  Then, you are pulled into the next screen, to exit out and try again.  Painful.&lt;br /&gt;&lt;br /&gt;Cropper instead is very cool in that you can use the mouse or keyboard to move the selected area--even performing a "nudge" with the arroe keys.  All around great piece of software.  Thanks so much, Brian!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-5588270158577117228?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/5588270158577117228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/02/windows-screen-capture-utility.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5588270158577117228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5588270158577117228'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/02/windows-screen-capture-utility.html' title='Windows screen capture utility'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-3970807558645102606</id><published>2010-01-10T21:38:00.000-08:00</published><updated>2010-01-10T21:38:38.541-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='QuattroWireless'/><category scheme='http://www.blogger.com/atom/ns#' term='MobClix'/><category scheme='http://www.blogger.com/atom/ns#' term='ads in iPhone app'/><category scheme='http://www.blogger.com/atom/ns#' term='fill rate'/><title type='text'>My concerns with Quattro Wireless</title><content type='html'>I have several iPhone apps that are using Quattro Wireless as a major part of my ad serving.  Quattro is a pretty good provider in that they seem to offer very competitive rates and typically have offered a pretty strong fill ratio.&lt;br /&gt;&lt;br /&gt;That is, until lately.  I have noticed my fill ratio drop significantly, reaching between 20-30% in recent weeks, and hitting an abysmal 10% average for the last 3 days.  I am sure Quattro has a lot of requests, with the huge growth in iPhone apps lately, and the unprecedented downloading that has been going on.  But 10%??!?!?  These guys are paid to provide a service, and I was not very happy with the previous 20-30% range.&lt;br /&gt;&lt;br /&gt;I really hope Apple buying Quattro can turn this kind of marked decline around.  But I am not waiting to see what happens.  Over the weekend, I converted my apps over to use the MobClix provider, which promises 100% fill rate--presumably caching ads and presenting them when a new one is not available from the provider.&lt;br /&gt;&lt;br /&gt;I am actually pretty impressed with MobClix.  I used them for one of my apps, and I am slowly starting to convert over to them for other apps as well.  Their framework is small, integration was simple, and I have noticed a significant reduction in application errors from users that are running MobClix over other providers.  If you get a chance, check them out.  If nothing else, the promise of 100% fill rate has really caught my attention!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-3970807558645102606?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/3970807558645102606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2010/01/my-concerns-with-quattro-wireless.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3970807558645102606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3970807558645102606'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2010/01/my-concerns-with-quattro-wireless.html' title='My concerns with Quattro Wireless'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-664603439535115740</id><published>2009-12-18T19:00:00.000-08:00</published><updated>2009-12-18T19:00:23.689-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Free HTML Editor'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac HTML Editor'/><title type='text'>Great Free HTML Editor for the Mac</title><content type='html'>Although I have searched several times with no luck for a good HTML editor for the Mac, today I decided I was done using TextEdit.&lt;br /&gt;&lt;br /&gt;Here is my criteria for a "good" HTML editor.&lt;br /&gt;&lt;br /&gt;1)  The editor must provide some semblance of context highlighting.  Just displaying the text is not good enough.&lt;br /&gt;&lt;br /&gt;2)  The editor gets extra points for some of the features I have come to expect from using the Microsoft toolset--automatic completion of closing tags when I type the opening tag, outlining and the ability to collapse sections, and syntactical popups of available tags.  Auto-identing would also get high marks.&lt;br /&gt;&lt;br /&gt;3)  Support for CSS.&lt;br /&gt;&lt;br /&gt;4)  Also, a huge bonus if there is some easy way to preview the output.&lt;br /&gt;&lt;br /&gt;5)  The tool MUST be free.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This all seems like a tall order, doesn't it?  Especially when you add in #5.&lt;br /&gt;&lt;br /&gt;Well, friends, there is a tool that provides all the above and then some.  Navigate your browser over to &lt;a href="http://www.aptana.org/"&gt;Aptana&lt;/a&gt; and download Studio.  You can either download the standalone tool (around 85M) or the Eclipse plug-in if you have already downloaded Eclipse to build apps for the Android phone.&lt;br /&gt;&lt;br /&gt;Don't wait!  Download it now.  This is an unbelievable tool.  And did I mention it's free?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-664603439535115740?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/664603439535115740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/12/great-free-html-editor-for-mac.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/664603439535115740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/664603439535115740'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/12/great-free-html-editor-for-mac.html' title='Great Free HTML Editor for the Mac'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-3349355165670562253</id><published>2009-12-04T09:47:00.000-08:00</published><updated>2009-12-04T09:47:59.846-08:00</updated><title type='text'>Using DateTime.ParseExact to load a DB2 timestamp to .NET</title><content type='html'>It would be nice if the only database you ever needed to access from .NET was SQL Server, or something similar to it, that .NET understood and worked with easily.  One of my clients makes extensive use of DB2, though, and not a recent version--a version old enough that there is no LINQ provider.  So, part of my job is working around some of the oddities of pulling out of DB2 and sometimes writing the result into .NET.&lt;br /&gt;&lt;br /&gt;Recently I had to pull a DB2 timestamp and save out something like a timestamp in SQL Server.  As you probably know, the SQL Server timestamp is not a timestamp as all, at least not like DB2's.  So when I needed to pull the timestamp from DB2 and get some semblance of a timestamp in SQL Server, I needed to convert to a DateTime in .NET.&lt;br /&gt;&lt;br /&gt;Luckily, DateTime.ParseExact was there to save the day.  DateTime.ParseExact provides methods to allow you to describe in detail the format of the value you will be passing in, and have the resulting DateTime parse out the string exactly as you describe it.&lt;br /&gt;&lt;br /&gt;The solution is pretty simple (assuming dateField is the input string with the DB2 timestamp):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;        Dim cultureInfo As New CultureInfo("en-US")&lt;br /&gt;        Dim dateTime As DateTime = DateTime.ParseExact(dateField, "yyyy-MM-dd-HH.mm.ss.ffffff", cultureInfo)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note the ".ffffff" at the end of the format string.  This allows you to specify fractions of a second, which will be coming in on the input string.  Unfortunately, this information will be stripped off, and you will lose the fraction part.  But at least you now have a DateTime you can save successfully into SQL Server!&lt;br /&gt;&lt;br /&gt;Good luck out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-3349355165670562253?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/3349355165670562253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/12/using-datetimeparseexact-to-load-db2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3349355165670562253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3349355165670562253'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/12/using-datetimeparseexact-to-load-db2.html' title='Using DateTime.ParseExact to load a DB2 timestamp to .NET'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6756994718968797388</id><published>2009-12-02T20:52:00.000-08:00</published><updated>2009-12-02T20:52:43.552-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='storefront'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='CRE Loaded'/><title type='text'>Zero to e-commerce in 2 days with CRE Loaded</title><content type='html'>If you have done any amount of freelance web development, you have probably been asked at some point to put together an e-commerce store front for someone.  Most likely, the request also contained some caveats--like, the customer was just getting started, and wanted a store front for cheap, and they wanted it to be up pretty quickly (i.e. no long development cycle, with a minimum to the requirements gathering process), and they wanted some kind of admin tools so they did not have to contact you any time they wanted something simple like a price change.&lt;br /&gt;&lt;br /&gt;As a custom build, this would be nothing short of impossible.  Hopefully your next thought is to use an existing framework and customize it, to accomplish the goals and get something up quickly and cheaply.  Next, you are also thinking about hosting, which can be expensive too, depending the requirements of the tool you buy.&lt;br /&gt;&lt;br /&gt;I was presented with a similar request lately, so I started looking at some existing frameworks.  My research took to through such disparate tools as DotNetNuke (of course the Microsoft guy would look at DNN) and MamboCharge, but I landed on CRE Loaded.  CRE Loaded is a PHP script that has been developed on the popular OSCommerce framework.  And the results are amazing.&lt;br /&gt;&lt;br /&gt;Some of the best parts of CRE Loaded are the multitude of plug-ins available (including secure credit card processing), the availability of resources (both people and web content that can assist), and the easy and speed of getting a store up and running.  CRE Loaded brags about how quickly you can get a Payment Card Industry (PCI) compliant store up and running, which promises secure processing in an industry standard framework.  And it is every bit as easy as they say.&lt;br /&gt;&lt;br /&gt;I recently got a store up in just a few days.  I spent additional time tweaking the product, and learned a lot of the ins and outs.  Let me tell you that if you plan to do any serious customization, or even maintain an inventory of even 100 items, you owe it to yourself to learn how to make changes in the SQL tables directly.  I am sure CRE Loaded would rather you would either use their front end, or their custom load process--but if you know what you are doing, you can turn a difficult update across your entire inventory into a few minutes work.&lt;br /&gt;&lt;br /&gt;Case in point, I was setting up shipping for the store, and discovered that shipping requires product weights.  The inventory list that I had gotten from the customer's POS system was missing a lot of things, not the least of which was shipping weights.  So I had 3 options--go through the admin screens and add a weight to every item (probably close to an hour's work); extract the database to a spreadsheet, update the spreadsheet, and then reload the spreadsheet, praying that the only thing that would be changed would be the product weight (probably 15 minutes work, plus an undetermined amount of time to fix anything that might have been broken due to a typo, etc); or, write a SQL query to set every product weight to 1 pound (1 minute's work).&lt;br /&gt;&lt;br /&gt;If you are PHP person, you can also dig into the entire source, and tweak the application.  This is not for those lacking caution, though, because it is a somewhat complex script, so I would not advise hacking into to it to make changes--spend some time first and figure out what it is doing.  Another example, I had to make some changes to the shipping module to allow various flat rate shipping types, selectable by the customer.  Currently, CRE Loaded expects that you will either use one flat rate, or chose from a number of different available shipping options.  The moral of the story, though, is that will a little analysis, even this was a fairly easy change, and I could customize the app to meet the business' requirements.&lt;br /&gt;&lt;br /&gt;CRE Loaded offers a free version that is a bit limited, but the pro version does a lot and only costs the equivalent of a few hours' work.  In am impressed with the speed, ease, and flexibility.  If you need to get a storefront up, make sure you include it in the list of products you research.  It is worth every penny!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6756994718968797388?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6756994718968797388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/12/zero-to-e-commerce-in-2-days-with-cre.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6756994718968797388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6756994718968797388'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/12/zero-to-e-commerce-in-2-days-with-cre.html' title='Zero to e-commerce in 2 days with CRE Loaded'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-924236263405090406</id><published>2009-11-11T09:39:00.000-08:00</published><updated>2009-11-11T09:39:34.603-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='storefront'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='CRE Loaded'/><title type='text'>CRE Loaded Automated Load</title><content type='html'>I am working on a project right now that is quite a challenge--making CRE Loaded work with an automated load from a separate POS system.  CRE Loaded is a tremendous tool, but I don't think it was intended to provide automated capabilities to tie into an existing POS system.&lt;br /&gt;&lt;br /&gt;For those of you unfamiliar with it, CRE Loaded is a free, PHP-based storefront.  You can find out more &lt;a href="http://www.creloaded.org/"&gt;here&lt;/a&gt;.  CRE Loaded is based on the popular OSCommerce platform, and is a great way to get an appealing and flexible storefront up on the web quickly.  In addition to the free version, there is a paid Pro version that provides additional capabilities and features.&lt;br /&gt;&lt;br /&gt;Generally, I have been very happy with CRE Loaded, but the loading process, called Easy Populate, is lacking.  A few of the things you would expect to be there (automated loads, additional fields for the loads, and complete refresh of your entire store inventory) require stepping up to the Pro version, or are not available at all outside custom development.  I believe the automated load of the store inventory is going to require hand coding of a CRON job to script out backing up the database, clearing it, and loading from a new import file.&lt;br /&gt;&lt;br /&gt;This is a bit of surprise because CRE Loaded seems to handle the vast majority of the desired functionality simply and easily, right out of the box.  Personally, it seems like a pretty common feature to require handling a load from a POS system or other external system.  Because of that, I am surprised at what seems like anemic capabilities to support load imports.&lt;br /&gt;&lt;br /&gt;That said, CRE Loaded is generally a great product, and the ability to write custom code as needed will even mitigate this issue.  If you need to set up a storefront, I would put this at the top of your list to review.  Just be sure you either don't need to handle external inventory, or can invest in custom code to fulfill this requirement.&lt;br /&gt;&lt;br /&gt;Good luck out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-924236263405090406?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/924236263405090406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/11/cre-loaded-automated-load.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/924236263405090406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/924236263405090406'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/11/cre-loaded-automated-load.html' title='CRE Loaded Automated Load'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-4888308537436662909</id><published>2009-10-13T09:48:00.000-07:00</published><updated>2009-10-13T09:48:20.890-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Default.png'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='default image'/><title type='text'>Default image not showing up for iPhone app</title><content type='html'>I ran into an issue last night trying to set up the default image for the app I am about to submit to the AppStore.  I have learned the first thing to look at is the capitalization when adding files to an XCode project.  But there were a few other things I needed to do to get this working.&lt;br /&gt;&lt;br /&gt;So if you don't see your Default.png image showing up, try these steps:&lt;br /&gt;&lt;br /&gt;1)  First, make sure your "Default.png" is named exactly that ("default.png" will not work).&lt;br /&gt;&lt;br /&gt;2)  Second, make sure Default.png is in the root directory of your project.&lt;br /&gt;&lt;br /&gt;3)  Do a clean of your target.&lt;br /&gt;&lt;br /&gt;4)  Then build and your default image should show up.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I also noticed that running this in the simulator was not helpful because my app started very quickly and the default image only displayed for a second.  So, make sure you give this a try on the device to see how long the default image really displays.&lt;br /&gt;&lt;br /&gt;Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-4888308537436662909?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/4888308537436662909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/default-image-not-showing-up-for-iphone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/4888308537436662909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/4888308537436662909'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/default-image-not-showing-up-for-iphone.html' title='Default image not showing up for iPhone app'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-3918294847336329206</id><published>2009-10-07T17:46:00.000-07:00</published><updated>2009-10-07T17:49:57.258-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><title type='text'>iPhone / Objective-C Code Examples (and .NET equivalents)</title><content type='html'>I have found myself reusing a lot of the same code throughout my apps.  I thought I would publish some tips and code snippets to hopefully get you going on your next project.  Here they are, in no particular order.  I also tried to put a .NET equivalent for those of you who, like me, are coming from a long .NET background.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1)  Use NSLog liberally to debug as you write your code.  You can really do a lot with it.  A few standard statements are for printing strings or numbers, and you can also print an Objective-C object.  Here are the three I use most often:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;NSLog(@"%@", aString);     // prints any NSString, for example&lt;br /&gt;NSLog(@"%d", anInt);       // prints a signed int&lt;br /&gt;NSLog(@"%f", aFloat);      // prints a float&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2)  If you have a UITableView that you need to have updated, you can reload it with this command (assuming it is named "tableView"):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[self.tableView reloadData];&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3)  Need to iterate through a collection?  Try this handy code snippet, which is similar to For Each in .NET languages:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;for (id currentObject in allObjects) {&lt;br /&gt;// do something here with currentObject&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4)  Here is how you can check to see if an object is certain type.  This is a bit like using gettype or typeof in .NET to find a specific type:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if ([myObject isKindOfClass:[TheClassIAmLookingFor class]]) {&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5)  Here is how you cast an object in Objective-C, like using CType or DirectCast in .NET:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;TypeToCastTo typeCastObject = (TypeToCastTo *)myObject;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6)  I show alert pop-ups a lot in my apps.  Here is a simple example for an alert launched when a button is clicked, and responded to to perform some action.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;-(void)resetClicked:(id)sender withEvent: (UIEvent *) event {&lt;br /&gt;&lt;br /&gt;UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Reset" message:@"Are you sure you want to reset this puzzle?\nAll of your work will be lost!" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];&lt;br /&gt;[alert show];&lt;br /&gt;[alert release];&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {&lt;br /&gt;// the user clicked the OK button&lt;br /&gt;if (buttonIndex == 1)&lt;br /&gt;{&lt;br /&gt;// reset logic goes here&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;7)  Split is a great function in .NET.  Here is the Objective-C equivalent:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;NSArray *arrayOfValues = [commaDelimitedListOfValues componentsSeparatedByString:@","];&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;More code snippets next time!  Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-3918294847336329206?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/3918294847336329206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/iphone-objective-c-code-examples-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3918294847336329206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3918294847336329206'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/iphone-objective-c-code-examples-and.html' title='iPhone / Objective-C Code Examples (and .NET equivalents)'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-7127169079908778644</id><published>2009-10-07T09:20:00.000-07:00</published><updated>2009-10-07T09:36:24.438-07:00</updated><title type='text'>Update your AdWhirl SDK to 1.2.7 (and Include the AddressBook Framework)</title><content type='html'>If you have not recently updated you AdWhirl SDK to 1.2.7, you may notice some big benefits if you do.  I was seeing leaks before the upgrade, and a few random crashes.  Both of these seem to be much improved, but also there seems to be a speed improvement as well.&lt;br /&gt;&lt;br /&gt;There is one caveat--when I replaced my 1.2.5 SDK with the 1.2.7 SDK, I started getting all kinds of compiler errors.  I sent a note to AdWhirl support (which responded really quickly--thanks!) and they said you need to include the AddressBook framework into your app because it is by AdMob.  I did not see this anywhere in the documentation, and of course, I did not expect it simply going from 1.2.5 to the more recent version.  It is a 10 second fix, but I wanted everyone to be aware.&lt;br /&gt;&lt;br /&gt;Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-7127169079908778644?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/7127169079908778644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/update-your-adwhirl-sdk-to-127-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/7127169079908778644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/7127169079908778644'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/update-your-adwhirl-sdk-to-127-and.html' title='Update your AdWhirl SDK to 1.2.7 (and Include the AddressBook Framework)'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6494826204686076857</id><published>2009-10-05T20:50:00.000-07:00</published><updated>2009-10-06T16:08:48.185-07:00</updated><title type='text'>My Favorite iPhone Development Books</title><content type='html'>OK, so the next most common question I am asked after blogs that I follow: what are good books that I can recommend.  Here are some really popular ones right now.  Books are a great way to get up to speed quickly.  If you are getting started with iPhone development, this can shave weeks off your time to deliver a project.&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.amazon.com/gp/product/1430224592?ie=UTF8&amp;amp;tag=eclectictechi-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1430224592"&gt;&lt;img src="http://ecx.images-amazon.com/images/I/417ie4OlWAL._SL160_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=eclectictechi-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1430224592" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.amazon.com/gp/product/1430224592?ie=UTF8&amp;amp;tag=eclectictechi-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1430224592"&gt;&lt;h3&gt;Beginning iPhone 3 Development: Exploring the iPhone SDK&lt;/h3&gt;&lt;/a&gt;&lt;br /&gt;Are you a programmer looking for a new challenge?  Does the thought of building your very own iPhone app make your heart race and your pulse quicken?  If so, Beginning iPhone 3 Development: Exploring the iPhone SDK is just the book for you. Updated and revised for iPhone SDK 3, many of the discussions in the original book have been clarified to make some of the more complex topics easier to understand. In addition, all of the projects have been rebuilt from scratch using the SDK 3 templates.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/0321566157?ie=UTF8&amp;tag=eclectictechi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321566157"&gt;&lt;img border="0" src="http://ecx.images-amazon.com/images/I/510GGdmW7QL._SL160_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=eclectictechi-20&amp;l=as2&amp;o=1&amp;a=0321566157" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.amazon.com/gp/product/0321566157?ie=UTF8&amp;tag=eclectictechi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321566157"&gt;&lt;h3&gt;Programming in Objective-C 2.0 (2nd Edition)&lt;/h3&gt;&lt;/a&gt;&lt;br /&gt;From the author of Programming in C, Programming in Objective-C 2.0 provides the new programmer a complete, step-by-step introduction to the Objective-C language. The book does not assume previous experience with either C or object-oriented programming languages, and it includes many detailed, practical examples of how to put Objective-C to use in your everyday programming needs.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.amazon.com/gp/product/0470683988?ie=UTF8&amp;tag=eclectictechi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0470683988"&gt;&lt;img border="0" src="http://ecx.images-amazon.com/images/I/510W02ek7hL._SL160_.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=eclectictechi-20&amp;l=as2&amp;o=1&amp;a=0470683988" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.amazon.com/gp/product/0470683988?ie=UTF8&amp;tag=eclectictechi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0470683988"&gt;&lt;h3&gt;iPhone SDK 3 Programming: Advanced Mobile Development for Apple iPhone and iPod touch (Wiley)&lt;/h3&gt;&lt;/a&gt;&lt;br /&gt;Apples iPhone is the hottest mobile device on the planet. More than one million iPhone 3G phones were sold in the first three days of release and millions more are sure to be in the hands of iPhone fans each year. Apples iPhone SDK has been updated and includes more than one thousand new APIs that developers will want to get their hands on.&lt;br&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;a href="http://74341fuxf32bo5372mvdpjakdp.hop.clickbank.net/"&gt;&lt;img width="75%" height="75%" src="http://www.mattjdrake.com/wp-content/uploads/ebook-ad-image-150px.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://74341fuxf32bo5372mvdpjakdp.hop.clickbank.net/"&gt;&lt;h3&gt;How To Make An iPhone App&lt;/h3&gt;&lt;/a&gt;&lt;br /&gt;Do you want to start developing iPhone apps, but find the technology confusing?  Here is the ALL-IN-ONE iPhone development resource that will give you everything to need to make an iPhone App!&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://jtabernik.prodlock.hop.clickbank.net/"&gt;&lt;br /&gt;&lt;img height="75%" width="75%" src="http://www.myphoneriches.com/images/200box.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://jtabernik.prodlock.hop.clickbank.net/"&gt;&lt;h3&gt;iPhone App Secrets - Making Money With iPhone Apps&lt;/h3&gt;&lt;/a&gt;The mobile phone application market has exploded recently. Never before in history has it been so easy for you to tap into a ready made army of cash rich customers!  Right now, there are around 20 million iPhone owners.  These iPhone owners spend upwards of $50 million dollars every single month on new iPhone applications.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6494826204686076857?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6494826204686076857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/my-favorite-iphone-development-books.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6494826204686076857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6494826204686076857'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/my-favorite-iphone-development-books.html' title='My Favorite iPhone Development Books'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-846941544157446620</id><published>2009-10-03T21:38:00.000-07:00</published><updated>2009-10-03T21:41:52.395-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development blogs'/><title type='text'>iPhone Blogs That I Follow</title><content type='html'>I get the question now and then about the blogs that I follow to keep up with what goes on in iPhone development.  It seemed like a nice thing to provide links to this since all of these resources have been helpful to me.  So, in no particular order, here are some great iPhone development resources.  Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.travisdunn.com/iphone-developer-development-blogs" target="_blank"&gt;iPhone Developer/Development Blogs | Travis Dunn&lt;/a&gt; - Imagine my surprise when the internet failed to produce a select list of iPhone development blogs more than 10 links wide. Well, I've beaten the internet at its own game and collected the links myself, like a neurotic SERP.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://maniacdev.com/2009/10/a-more-in-depth-look-at-the-how-to-make-an-iphone-app-book/" target="_blank"&gt;A More In Depth Look At The How To Make An iPhone App Book&lt;/a&gt; - ... where you should have no trouble figuring out how to use those libraries on your own. You can get more information on the How To Make An iPhone App homepage by clicking here. ©2009 iPhone Development Tutorials and Programming Tips. ...&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.iphonedevsdk.com/forum/iphone-sdk-development/30152-creating-calander.html" target="_blank"&gt;creating a calander - iPhone Dev SDK Forum&lt;/a&gt; - I want to create a calendar. which is can be scrolled vertically and contains dates of the next seven weeks. I am new to iphone development therefore.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://maniacdev.com/2009/09/iphone-game-development-with-core-animation/" target="_blank"&gt;iPhone Game Development With Core Animation | iPhone Development ...&lt;/a&gt; - I've made quite a few posts about OpenGL ES, and the available game engines on the iPhone, and I'd like to iterate that you do not need to use OpenGL ES or.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://msl1.mit.edu/furdlog/?p=7065" target="_blank"&gt;FurdLog » Messing With Developer Infrastructure Conventions&lt;/a&gt; - By creating games and other programs for the iPhone, software developers hoped to find millions of new customers. But they didn't expect to feel muzzled. The software development kit that Apple Inc. distributed to programmers bound them ...&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://foolswisdom.com/wordpress-for-iphone-source-code-available/" target="_blank"&gt;WordPress for iPhone + Source Code Available! &lt; A Fool's Wisdom&lt;/a&gt; - Earlier this week my Automattic colleagues and Effigent released WordPress for iPhone and iPod Touch. Now, the source is also available and Trac is set up for reporting bugs and participating in development! ...&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.rottenbananas.com/blog/2008/11/the-iphone-app-store-is-pure-genius/" target="_blank"&gt;The iPhone App Store is Pure Genius&lt;/a&gt; - Apple's iPhone App Store allows third-parties to release software for the iPhone (built with an API provided by Apple) to all iPhone users. They can charge what they want for the app, and delivery and payment is managed beautifully within the iPhone interface through your iTunes account. By providing the medium (iPhone) and the delivery service (App Store), Apple has created a completely self-sustaining business model that generates passive income for them and increases demand for the product with each awesome release on the App Store. &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://juixe.com/techknow/index.php/2007/07/06/top-15-iphone-web-development-resources/" target="_blank"&gt;Top 15 iPhone Web Development Resources&lt;/a&gt; - Here is a list of links to the best available iPhone development resources such as simulators, development plugins, wikis, and other JavaScript/HTML/Safari documentation. iPhoney – A free iPhone web simulator for designers. ...&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.webomatica.com/wordpress/2009/05/02/how-much-is-too-much-for-an-iphone-app/" target="_blank"&gt;How Much Is Too Much For An iPhone App? » Webomatica ...&lt;/a&gt; - Just tossing this out there, since I have come down with a case of iPhone app price sensitivity.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-846941544157446620?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/846941544157446620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/iphone-blogs-that-i-follow.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/846941544157446620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/846941544157446620'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/10/iphone-blogs-that-i-follow.html' title='iPhone Blogs That I Follow'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-2115136608923219390</id><published>2009-09-29T09:35:00.000-07:00</published><updated>2009-09-29T09:46:58.479-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IAccessor.ReleaseAccessor'/><category scheme='http://www.blogger.com/atom/ns#' term='ADO.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='RCW exception'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><title type='text'>Object disposal order in .NET</title><content type='html'>I got a crazy error yesterday while refactoring my data access layer for a client.  I wanted to provide a mechanism to get the output parameters from a stored procedure call.  I typically use delegates or events to give the developer the option to get the output parameters if they want them.&lt;br /&gt;&lt;br /&gt;So I made a change to the order of events to dispose of the connection earlier (rather than hold onto it longer than necessary--"acquire resources late and release them early," as Microsoft says).  My pseudocode looked something like this:&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;Close and dispose of connection&lt;br /&gt;Call output parameter access callback&lt;br /&gt;Dispose of command object&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I was getting back my data, but I started getting an unusual error:&lt;br /&gt;&lt;br /&gt;System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The error referenced the following:&lt;br /&gt;&lt;br /&gt;System.Data.Common.UnsafeNativeMethods.IAccessor.ReleaseAccessor(IntPtr hAccessor, Int32&amp; pcRefCount)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you might guess, I did not suspect the order of object disposal causing this, so I spent a lot of time looking at other potential issues before nailing this down.  I believe there is probably a solution via closing the command's underlying connection rather than destroying it without it realizing.  Unfortunately, I have not had time to tinker with this yet.&lt;br /&gt;&lt;br /&gt;If you run across this error, try the simple solution.  Try closing and disposing of your connection after the command object is closed.&lt;br /&gt;&lt;br /&gt;Good luck out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-2115136608923219390?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/2115136608923219390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/object-disposal-order-in-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2115136608923219390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2115136608923219390'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/object-disposal-order-in-net.html' title='Object disposal order in .NET'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6411363655114185651</id><published>2009-09-18T09:19:00.000-07:00</published><updated>2009-09-18T09:52:50.604-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dynamic data web site'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net 3.5 extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net SP1'/><title type='text'>Use a Dynamic Data Web Site for simple database table administration</title><content type='html'>Since its release last year as part of the ASP.NET Extensions (and its subsequent inclusion in the 3.5 framework with SP1), the Dynamic Data Web Site has been a fantastic way to simply and easily develop administrative pages for database tables literally without writing a line of code.  But recently, I had a client who wanted to take one of these sites that I generated, and change it.  They wanted the look and feel more like their standard apps--I assumed this would be pretty easy.  But they also wanted to limit and modify some functionality--take away the edit and delete function, for example, unless the user explicitly had access to maintain data.  I was reticent to commit to the cost on this because I had no idea how hard or easy this would be.&lt;br /&gt;&lt;br /&gt;To my surprise, the site generated by the Dynamic Data Web Site is amazingly flexible, clear, and easy to configure.  There is a master page and css class included with the site.  As you would imagine, but replacing the master page in the site with the client's standard master page, and by changing the colors and styles in the css, I had the dynamic site matching the client's standard look and feel in minutes.  To do this, look at the DynamicData/PageTemplates folder.  There are 5 aspx pages that you will need to modify.  Change the master page to point to the standard one.  Then rename the content section to the master page's content body, and maybe (as I did) move some content into new content sections to rearrange the page a bit.  It was that easy.&lt;br /&gt;&lt;br /&gt;But what about the security functionality?  My client uses a well-designed page inheritance hierarchy that exposes security information.  I was able to go into the code behind for the aspx pages I mentioned above and change them to inherit from the client's standard base page.  This allowed me to use logic in the aspx pages to filter out functionality I didn't always want to display.  For example, I would wrap the Edit buttons on the list page in an if block like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; If CanPerformAdminFunctions() Then &lt;br /&gt;   ...&lt;br /&gt; End If &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In short, I was able to filter out any and all functionality from users that I wanted to be able to see the data but not edit it.&lt;br /&gt;&lt;br /&gt;On a more detailed note, we also had an issue with bit fields in the database--sometimes we had nullable bit fields.  This means the standard Yes/No check box display for a bit is not sufficient; you need a tristate control.  The easiest solution is either a drop down or radio button list.  Either way, this change was easy to manage--just swap out the control in FieldTemplates/BooleanEdit for a new control and add in some logic to set the field value to nothing if it is not set.&lt;br /&gt;&lt;br /&gt;All in all, I have been extremely impressed with the ability to change, edit, and extend the functionality of the Dynamic Data Web Site.  This is a great tool to have in your tool box, whether you need a quick and dirty admin site, or you want to start with a simple site and extend it to meet your needs.&lt;br /&gt;&lt;br /&gt;Good luck out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6411363655114185651?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6411363655114185651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/use-dynamic-data-web-site-for-simple.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6411363655114185651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6411363655114185651'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/use-dynamic-data-web-site-for-simple.html' title='Use a Dynamic Data Web Site for simple database table administration'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-3179351801831246655</id><published>2009-09-09T09:24:00.000-07:00</published><updated>2009-09-09T09:50:29.535-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Navigation'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='UITableView'/><category scheme='http://www.blogger.com/atom/ns#' term='delegate'/><title type='text'>Using the UITableView, Part 1</title><content type='html'>I approached the UITableView for iPhone development with some trepidation.  It looked pretty complicated to get up and running--I assumed I would be spending a significant amount of time getting it working.  To my surprise, I found adding this to my app, configuring it, and adding functionality to it have been remarkably easy.&lt;br /&gt;&lt;br /&gt;If you are a novice, you may still be learning to get a view transition to occur when a UITableItem is clicked.  Here is code that you need in the tableView:didSelectRowAtIndexPath: method.  This assumes you have a NIB named "PageTwo" and that its class is named pageTwo.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {&lt;br /&gt;&lt;br /&gt; pageTwo *anotherViewController = [[pageTwo alloc] initWithNibName:@"PageTwo" bundle:nil];&lt;br /&gt; [self.navigationController pushViewController:anotherViewController animated:YES];&lt;br /&gt; [anotherViewController release];&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now you can transition to a new page, any new page, when a record in the UITableView is selected.  Note that this can be animated, so you immediately get the great sliding animation effects standard in all iPhone apps.&lt;br /&gt;&lt;br /&gt;Consider adding buttons to the Navigation bar at the top.  I found some complicated examples of this, but Apple provided some good direction to keep this simple.  This is all I needed to do to provide a button on the right side of a Navigation bar.  I put this code in my viewDidLoad method:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:@"Button"                 style:UIBarButtonItemStyleBordered                 target:self                  action:@selector(myFunction:)];&lt;br /&gt;    self.navigationItem.rightBarButtonItem = addButton;&lt;br /&gt;    [addButton release];&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For my next trick, I will demonstrate how to use your controller class as a delegate for the UITableView, so your class can respond to calls from the UITableView, allowing you to populate the class on the fly.  See you next time!&lt;br /&gt;&lt;br /&gt;John&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-3179351801831246655?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/3179351801831246655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/using-uitableview-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3179351801831246655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3179351801831246655'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/using-uitableview-part-1.html' title='Using the UITableView, Part 1'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-4562291615850099162</id><published>2009-09-03T20:50:00.000-07:00</published><updated>2009-09-03T21:08:51.678-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='parse file'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='load file'/><category scheme='http://www.blogger.com/atom/ns#' term='stringWithContentsOfFile'/><category scheme='http://www.blogger.com/atom/ns#' term='componentsSeparatedByString'/><title type='text'>Load and Parse a File on the iPhone</title><content type='html'>Right now, I am hard at work on my next game.  It is a puzzle style game, and I am using a variety of different tricks to pull it together.  One of which is using my .NET skills to generate the actual puzzles on the Windows platform, then transfer them and use them on the Mac.  I had to do some computations that I knew how to do easily on the PC, so I decided to use those skills (read: take a shortcut).&lt;br /&gt;&lt;br /&gt;Anyway, this means that I had to be able to read in the file once I got it over to XCode.  Luckily, like most things, there are an impressive amount of examples to do the load....assuming you don't need to parse the results and pass them into a custom object.&lt;br /&gt;&lt;br /&gt;The format of my file is pretty simple: I am using an identifier for a node which is a string, then I am using 3 floating point values for the x-, y-, and z-coordinates of a point in 3-dimensional space.  So I need to be able to read in the rows from the file, and parse out the results that I can use to create these custom nodes.&lt;br /&gt;&lt;br /&gt;It was pretty tedious getting there, because the main method to parse out delimited strings, &lt;code&gt;componentsSeparatedByString&lt;/code&gt;, returns types that you might not expect.  Coming from a non-C background, I was slowed down by having to convert each node to something to be able to use it.  I am a .NET guy...I expect some implicit conversion!!&lt;br /&gt;&lt;br /&gt;Hopefully this bit of code helps you.  This will load in all the lines in your string, parse out the values, then create a custom object for each one.  Some of the supporting code is left out, so you can see the meat of the example; I also converted this to loading ints instead of floats because it made the code a little simpler.  Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"nodeOutputFile" ofType:@"txt"];  &lt;br /&gt; NSString *fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSASCIIStringEncoding error:NULL];  &lt;br /&gt; if (fileContents) {  &lt;br /&gt; &lt;br /&gt;  NSArray *lines = [fileContents componentsSeparatedByString:@"\n"];&lt;br /&gt;  for (int i = 0; i &lt; [lines count]; i++) {&lt;br /&gt;&lt;br /&gt;   JTNode *newNode = [JTNode alloc];&lt;br /&gt;     &lt;br /&gt;   NSArray *tokens = [[lines objectAtIndex:i] componentsSeparatedByString:@","];&lt;br /&gt;&lt;br /&gt;   NSString *identifier = [tokens objectAtIndex:0];&lt;br /&gt;&lt;br /&gt;   NSNumber *x = [NSNumber numberWithInt:[[tokens objectAtIndex:1] integerValue]];&lt;br /&gt;   NSNumber *y = [NSNumber numberWithInt:[[tokens objectAtIndex:2] integerValue]];&lt;br /&gt;          NSNumber *z = [NSNumber numberWithInt:[[tokens objectAtIndex:3] integerValue]];&lt;br /&gt;&lt;br /&gt;   [newNode createWithX:[x integerValue]&lt;br /&gt;        Y:[y integerValue]&lt;br /&gt;        Z:[z integerValue]&lt;br /&gt;      Identifier:identifier];&lt;br /&gt;      &lt;br /&gt;  &lt;br /&gt;   // do something here with newNode   &lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Good luck to you!&lt;br /&gt;John Tabernik&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-4562291615850099162?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/4562291615850099162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/load-and-parse-file-on-iphone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/4562291615850099162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/4562291615850099162'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/load-and-parse-file-on-iphone.html' title='Load and Parse a File on the iPhone'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1976165271391675956</id><published>2009-09-01T20:31:00.000-07:00</published><updated>2009-09-01T20:59:47.555-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BCP'/><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlclient'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlbulkcopy'/><category scheme='http://www.blogger.com/atom/ns#' term='insert'/><title type='text'>Load SQL Server from .NET Much Faster Than With Insert Statements</title><content type='html'>SQL Server is a developer's friend--it is everywhere, it is easy to use, there are tons of resources available for it, and you can distribute a free version with your apps.  Odds are SQL Server is either your primary database platform, or you have some data in it and work with it fairly regularly.&lt;br /&gt;&lt;br /&gt;One of the most common questions I hear is: "How can I get data into SQL Server?"&lt;br /&gt;&lt;br /&gt;Most of the time the answer lines somewhere between creating insert statements for a few records or developing a DTS package to handle a file import.  But every client has different needs, and sometimes you run across a situation where you need a different tool in the toolbox.&lt;br /&gt;&lt;br /&gt;A client I work for needed a robust solution to get a lot of data into SQL Server while providing detailed reporting on the process, high availability of the database, and a good deal of fault tolerance.  Due to some environmental issues, DTS was not feasible.  As a result, I needed a fast way to get a lot of data (hundreds of thousands of rows per load) into the database with essentially just .NET.&lt;br /&gt;&lt;br /&gt;Luckily, I happened on the SqlBulkCopy class in System.Data.SqlClient.  SqlBulkCopy abstracts the BCP utility that has been around in SQL since version 7.  The best part--this class, via BCP can bypass standard SQL overhead like logging, triggers, etc.  When loading the data without executing any constraints is acceptable--i.e. when you really just want to bulk load the table--SqlBulkCopy is unbeatable.&lt;br /&gt;&lt;br /&gt;The process couldn't be simpler.  You just need to load a datatable with data, create a SqlBulkCopy class, set up the column mappings, and execute the copy.  Loading up the datatable is a great method because there are many, many ways in .NET to get data into a datatable natively, and you can get data there by hand if necessary (manually adding rows).&lt;br /&gt;&lt;br /&gt;Here is some example code.  Pass this method a datatable, set up the connection string, and you will get great performance!&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    Private Sub BcpRecordsToSqlServer(ByRef MyTable As DataTable)&lt;br /&gt;&lt;br /&gt;        Dim s As New SqlBulkCopy(SQLConnectionString, SqlBulkCopyOptions.Default)&lt;br /&gt;&lt;br /&gt;        s.DestinationTableName = "MyDestinationTableName"&lt;br /&gt;        s.BulkCopyTimeout = 36000&lt;br /&gt;&lt;br /&gt;        For Each field As DataColumn In MyTable.Columns&lt;br /&gt;            s.ColumnMappings.Add(field.ColumnName, field.ColumnName)&lt;br /&gt;        Next&lt;br /&gt;&lt;br /&gt;        s.WriteToServer(MyTable)&lt;br /&gt;        s.Close()&lt;br /&gt;&lt;br /&gt;    End Sub &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A few notes about this code.  First, you can set a property on the class initialization to determine if triggers will fire or not, etc.  Second, you can set a time-out on the copy.  Third, I am simply looping through the column in the datatable and setting them to output to the same column in the target table--assuming that you set up the input columns to be named whatever the target table's columns are.  This is nice because you only have to populate the fields you want in the destination table.&lt;br /&gt;&lt;br /&gt;This process is great for reading chunks of data and uploading them to SQL Server.  I originally ran a process pulling data and uploading via individual insert statements.  I stopped this process after 6 hours.  In contrast, using BCP I was able to upload 100,000 rows in under 10 minutes!&lt;br /&gt;&lt;br /&gt;Clearly insert statements versus BCP is an apples to oranges comparision--if data integrity is not certain from your data source, you may find BCP if the wrong choice because constraints are bypassed.  These statements are not logged, so you cannot recover them in a partial back-up or log shipping situation.  Also, you cannot run the BCP load in a transaction.&lt;br /&gt;&lt;br /&gt;But, if you are able to scrub the data first, or even scrub the data as you load the datatable, or if you are certain the data is acceptable, you cannot beat the raw speed of using this process to insert into SQL Server from .NET.&lt;br /&gt;&lt;br /&gt;Under certain circumstances, this is an invaluable tool to have in the toolbox!&lt;br /&gt;&lt;br /&gt;Good luck!&lt;br /&gt;John Tabernik&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1976165271391675956?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1976165271391675956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/load-sql-server-from-net-much-faster.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1976165271391675956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1976165271391675956'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/09/load-sql-server-from-net-much-faster.html' title='Load SQL Server from .NET Much Faster Than With Insert Statements'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6964617785288894490</id><published>2009-08-31T17:38:00.000-07:00</published><updated>2009-09-01T21:01:56.320-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocos2d'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone development'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='AdWhirl'/><category scheme='http://www.blogger.com/atom/ns#' term='QuattroWireless'/><category scheme='http://www.blogger.com/atom/ns#' term='ads in iPhone app'/><title type='text'>Put AdWhirl Ads into Your iPhone App</title><content type='html'>Monetizing an iPhone app comes in many flavors these days--you don't just need to charge for your app.  Today I want to give you a step-by-step guide to getting ads into your application.  You will be shocked how easy it is!&lt;br /&gt;&lt;br /&gt;When I decided to release a lite ad-supported version of my app, I searched around to find out about ad providers.  Luckily, in my search, I happened upon &lt;a href="http://www.adwhirl.com/"&gt;AdWhirl&lt;/a&gt;.  AdWhirl is not actually an ad provider--instead, they provide an interface to other ad provider networks, allowing you to add one ad API into your app, and get 8 ad providers instantly (including the ability to put in your own ads).&lt;br /&gt;&lt;br /&gt;AdWhirl has outstanding step-by-step instructions on their site &lt;a href="http://www.adwhirl.com/instructions"&gt;here&lt;/a&gt;.  I was trying to incorporate &lt;a href="http://www.quattrowireless.com/"&gt;Quattro Wireless&lt;/a&gt; into my app and was having some issues, not the least of which was the lack of cut-and-paste of example code.  I was searching on example code when I found AdWhirl, which includes Quattro Wireless as a provider.  And AdWhirl made it easy for me to set up my ads, so it was a no brainer.  [Update--I have received word from Quattro Wireless that they do provide cut and paste code in their developer wiki.  My mistake--I guess I did not look in the right place.]&lt;br /&gt;&lt;br /&gt;But now, let's look at some code.  For my &lt;a href="http://www.youtube.com/watch?v=4OKNsXuOljo"&gt;sliding tile game&lt;/a&gt;, I used the cocos2d framework.  I was worried this would make it hard to incorporate in AdWhirl, but it was no problem at all!  Take the steps in the instructions document above, then do a few simple steps to incorporate AdWhirl into your app:&lt;br /&gt;&lt;br /&gt;First, I recommend adding a few constants into a common header file:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#define PUBLISHER_ID @"12345678901234567890"&lt;br /&gt;#define SITE_ID @"MyApplication"&lt;br /&gt;#define ADWHIRLAPPKEY @"1234567890abcdef1234567890"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;These are the constants needed by the AdWhirl interface.&lt;br /&gt;&lt;br /&gt;Include these variables in your scene header file:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; ARRollerView *rollerView;&lt;br /&gt; BOOL isPaused;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next, I went into my main Scene file and put the following at the end of the init method:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  rollerView = [ARRollerView requestRollerViewWithDelegate:self];&lt;br /&gt;  [ARRollerView startPreFetchingConfigurationDataWithDelegate:self];&lt;br /&gt;  &lt;br /&gt;  rollerView.center = CGPointMake(160, 454); &lt;br /&gt;  UIView *myView = [[Director sharedDirector] openGLView];&lt;br /&gt;  [myView addSubview:rollerView];&lt;br /&gt;&lt;br /&gt;  isPaused = FALSE;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This code will begin prefetching data for ads.  Also, you will notice I specifically placed the ads at the bottom of the view--that took some trial and error to get it to line up perfectly.  isPaused is going to be the notifier to pause the game timer while an ad would be displayed if the user clicks on one during game play.&lt;br /&gt;&lt;br /&gt;Now, your scene will need to provide a method to return your app key:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;- (NSString*)adWhirlApplicationKey&lt;br /&gt;{&lt;br /&gt;    return ADWHIRLAPPKEY;  //Return your AdWhirl application key here&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also, add these two methods to pause and unpause the game if you have a game timer:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;- (void)willDisplayWebViewCanvas {&lt;br /&gt; isPaused = TRUE;&lt;br /&gt;}&lt;br /&gt;- (void)didDismissWebViewCanvas {&lt;br /&gt; isPaused = FALSE;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You will also need to add some code in your timer method to pause timing if isPaused is true.  For example, I have a tick event, which I bail out of immediately if isPaused is true.&lt;br /&gt;&lt;br /&gt;I was also getting bunch of errors until I added a special line in the dealloc, to set the ad delegate to nil before you release it.  So don't forget this part!!&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;-(void)dealloc{&lt;br /&gt; &lt;br /&gt; if (rollerView) {&lt;br /&gt;  [rollerView setDelegateToNil];&lt;br /&gt;  [rollerView release];&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And that's it!  Hopefully using these few code snippets, you can avoid some of the learning I went through and get ads into your apps in less than an hour.&lt;br /&gt;&lt;br /&gt;Obviously, you also need to go through the process on the AdWhirl web site to set up the ad providers, etc, but this is pretty simple.  There can be some lag time for some of the providers waiting for codes and things to be emailed to you, but it does not take much of your time to submit the requests.&lt;br /&gt;&lt;br /&gt;I hope this is a pretty complete overview.  If you have questions, please feel free to send me a note.  Good luck!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6964617785288894490?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6964617785288894490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/08/put-adwhirl-ads-into-your-iphone-app.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6964617785288894490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6964617785288894490'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/08/put-adwhirl-ads-into-your-iphone-app.html' title='Put AdWhirl Ads into Your iPhone App'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6121404281128176475</id><published>2009-08-25T16:42:00.000-07:00</published><updated>2009-08-25T16:57:57.344-07:00</updated><title type='text'>Get Quality Backlinks Today</title><content type='html'>In addition to standard PPC, I have spent a lot of time trying to build quality backlinks to my marketing sites.  This is a very difficult and time consuming process.  Anyone who has tried to drive more traffic to their sites knows...you can spend an hour a day for months before you get any valuable traffic.&lt;br /&gt;&lt;br /&gt;But what if you don't want to wait?  Well, I have discovered a great resource in &lt;a href="http://www.automaticbacklinks.com"&gt;AutomaticBacklinks.com&lt;/a&gt;.  They are easy to use, easy to set up, and deliver high-quality traffic to your site quickly.&lt;br /&gt;&lt;br /&gt;AutomaticBacklinks.com is like most of the back link services in that it offers backlinks in trade for either cash or other links.  However it differs in terms of its great pricing and the speed with which you will get traffic.  I have tried several of these services and tracked the impact to my volume in Google Analytics.  Two things that impressed me...that both the volume was higher, but more importantly, that the quality of the traffic seemed much better.  The traffic I got from AutomaticBacklinks really seemed to be *reading* my content, not just finding it.  That is testament to the fact that these guys have built a better process than their competitors.&lt;br /&gt;&lt;br /&gt;If like me you have some sites you want to get into the limelight--there is no faster way to get it that AutomaticBacklinks.com.  Give it a try and see if you don't agree!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6121404281128176475?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6121404281128176475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/08/get-quality-backlinks-today.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6121404281128176475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6121404281128176475'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/08/get-quality-backlinks-today.html' title='Get Quality Backlinks Today'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6837992429877709978</id><published>2009-08-07T18:20:00.000-07:00</published><updated>2009-08-07T18:26:56.760-07:00</updated><title type='text'>Ask Uncle Boris, Live in the AppStore</title><content type='html'>iPhone/iPod Touch application #3, Ask Uncle Boris is live in the AppStore.  This app is not very technically challenging, but it was fun to make and helped me learn a few more things about iPhone development.  This was my first app using xib files and standard views.  No cocos2d was needed for this one.  I am however working on a new app that makes extensive use of TileMapAtlas--it is really easy to use and I cannot believe how quickly the app is coming together. &lt;br /&gt;&lt;br /&gt;Here is a demo video I made about the app.  You can also look at my marketing page for the app, &lt;a href="http://AskUncleBoris.com"&gt;AskUncleBoris.com&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;object width="336" height="204"&gt;&lt;param name="movie" value="http://www.youtube.com/v/-KqtxbWsRlU&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/-KqtxbWsRlU&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="336" height="204"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6837992429877709978?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6837992429877709978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/08/ask-uncle-boris-live-in-appstore.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6837992429877709978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6837992429877709978'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/08/ask-uncle-boris-live-in-appstore.html' title='Ask Uncle Boris, Live in the AppStore'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-2368098185703898085</id><published>2009-07-26T17:25:00.000-07:00</published><updated>2009-07-29T19:09:40.667-07:00</updated><title type='text'>The Wild World of AppStore Applications</title><content type='html'>It is really an emotional rollercoaster--waiting and refreshing your email constantly looking for a reply.  Sometimes you get rejected.  But it is all worth it for those golden moments of approval.&lt;br /&gt;&lt;br /&gt;I am of course talking about submitting apps to the Apple AppStore.  A quick process for me so far, getting your code ready, submitting, and waiting for approval is both exciting and nerve-wracking.  I have had two apps approved, one taking five business days, the other taking ten.  Neither were rejected, so I count myself in the lucky category.  I have friends who have had apps waiting months for approval.  A scary thought!&lt;br /&gt;&lt;br /&gt;I currently have two other apps waiting for approval.  One got rejected this morning, but it was criteria around a free "Lite Version" of one of my paid apps (apparently you are not allowed to upsell in your Lite Version).  It took about 15 minutes to modify and resubmit.  We will see what happens!&lt;br /&gt;&lt;br /&gt;A word of caution if you have never submitted an app before--the first one takes time!  And I am not even talking about the approval process.  I spent a few days getting my app compiled and signed, getting my icons the right size for the AppStore guidelines, blah blah blah....   The second one took a few days as well, but since then, I have been submitting in minutes.  If you have issues you can't get around, feel free to shoot me a response to this post--I may well have stumbled on the same issue.&lt;br /&gt;&lt;br /&gt;If you are interested, I have a &lt;a href="http://www.youtube.com/watch?v=4OKNsXuOljo"&gt;demo of one of my apps&lt;/a&gt; on YouTube.  Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/4OKNsXuOljo&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/4OKNsXuOljo&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-2368098185703898085?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/2368098185703898085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/07/blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2368098185703898085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/2368098185703898085'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/07/blog-post.html' title='The Wild World of AppStore Applications'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-266868601392683650</id><published>2009-06-15T09:28:00.000-07:00</published><updated>2009-06-15T09:41:54.974-07:00</updated><title type='text'>My Foray into iPhone Development</title><content type='html'>OK, not many posts lately.  I have been very busy with my new Mac.  My goal was to learn enough Objective-C / Cocoa Touch / etc. to be able to build some iPhone apps.  Shockingly, I was able to get an app up and into the AppStore very quickly thanks to the strong developer community with tons of examples and great documentation.  Check out Spin the Bottle '09 on the AppStore &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=317159982&amp;mt=8"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Apple also deserves a big hand I think for having built a solid platform and great development tools.  I have been a PC guy since 1984 (I started developing when I was 13 years old), and I never expected to turn away from PCs.  But I have to tell you, the Mac is astonishing in terms of performance, stability, and usability.  The best part--no anti-virus software!!  If you have ever thought about trying a Mac, I would highly recommend it.  The best part--you get to right cool stuff for the iPhone and iPod Touch.&lt;br /&gt;&lt;br /&gt;I also want to quickly thank a colleage, &lt;a href="http://www.xcodeguy.com/"&gt;Dave Ferrell&lt;/a&gt;.  Dave showed me around OS X at the Apple Store at the end of last year and his enthusiasm was contagious.  I had been intrigued by Macs since they first came out in 1983, but after that day, I had to get one!&lt;br /&gt;&lt;br /&gt;I will post more over the coming months about iPhone development on the Mac, but unlike my PC work, I am going to be primary focused on game development for the iPhone.  If you haven't heard, killer apps in the AppStore can hit hundreds of thousands of downloads a month.  This could bring me closer to my goal of having a few million people give me $1....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-266868601392683650?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/266868601392683650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/06/my-foray-into-iphone-development.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/266868601392683650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/266868601392683650'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/06/my-foray-into-iphone-development.html' title='My Foray into iPhone Development'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-5536903767099027998</id><published>2009-04-03T09:07:00.000-07:00</published><updated>2009-04-03T15:49:34.170-07:00</updated><title type='text'>File-Based Caching, Part 1</title><content type='html'>There are a variety of caching methods available to you when writing a web app.  I am sure you have used session and the intrinsic .NET caching component to cache data.  But there are times when neither of these solutions is the right solution.&lt;br /&gt;&lt;br /&gt;Let's consider when session and caching are most valuable.  Session is extremely useful for user-specific data that is needed across a variety of applications.  (I will assume that you are in a web farm environment, and therefore storing your data in the native SQL-Server session store.  Even if you are not, this discussion applies to a lesser degree.)  Since it is retrieved and stored on every page transition, it is typically good to keep values stored in it small.  Sometimes I store large data elements there, but I try to keep that to a minimum, and only to data that must be access all the time.&lt;br /&gt;&lt;br /&gt;Caching is also a great mechanism, highly efficient and proven to work well.  But think about the usage of it--if your all of individual users will have their data cached there, you will be eating up a lot of precious web server memory.  Compound this by the fact that each web server will need to cache the data, meaning that whatever process is needed to create the data, it may execute once for each web server you have.  If this process is expensive, you haven't gained a whole lot when different servers all need to process the same request.  Finally, however much memory is used per user, you are eating up with memory on every web server.  The result is a large expense.&lt;br /&gt;&lt;br /&gt;Caching is very valuable when the data is not user specific.  If you have configuration settings, for example, or lookup values or whatever that can shared across all users, caching is a great approach.  Not only will you significantly reduce the time to fetch the data, but your load on the infrastructure (for example if the data is being retrieved from a database) will be reduced as well.&lt;br /&gt;&lt;br /&gt;Now let's consider a common situation that is not a good fit for session or caching.  Often, data for an application that a user would retrieve is specific to the user.  Maybe some other users would get the same data, but it is not enterprise-wide.  Let's also suppose that it is expensive to materialize this data initially--a common example is executing a SQL query that might require several seconds to run.  You know you should cache this, rather recreate it each time.  Session is not a good candidate because the results coming back are large--it would be too inefficient to save and retrieve on every page transition, and it is specific to one app anyway (i.e. you don't want this data following the user around for the rest of their session).&lt;br /&gt;&lt;br /&gt;.NET caching is not a good option because (1) we don't want to re-execute the expensive query potentially for each web server, and (2) the data is large and each user's data will be different, meaning you will be eating up a lot of memory every machine.&lt;br /&gt;&lt;br /&gt;I recently wrote a file-based caching component to deal with this exact problem.  I created a shared directory that can be accessed by every web server, and I write a file there with anything I want to store and retrieve.  The process uses a BinaryFormatter to take any object is input, and be able to serialize it and deserialize it.  Plus, I compress the BinaryFormatter results to shrink the size of the file written and reloaded.&lt;br /&gt;&lt;br /&gt;Results have been impressive.  Expensive requests can now be cached, and the repeated calls to the pages that use them are lightning-fast.  Best of all, the solution is completely generic, so I can easily cache results from a web service call, a database call, or custom objects with no additional work on my part, thanks the BinaryFormatter.&lt;br /&gt;&lt;br /&gt;Next time, I will provide some code and walk through usage of the component.  I will also explain the use of expiration, which is a critical requirement to any caching mechanism.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-5536903767099027998?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/5536903767099027998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/04/file-based-caching-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5536903767099027998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5536903767099027998'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/04/file-based-caching-part-1.html' title='File-Based Caching, Part 1'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-8639940658762693333</id><published>2009-03-20T09:06:00.000-07:00</published><updated>2009-03-20T09:55:56.955-07:00</updated><title type='text'>Create a Custom Trace Listener, Part 1</title><content type='html'>Visibility into components can be a real challenge in a web application.  Often, there is functionality in a low level component that we need to trace because it is misbehaving or throwing a new error that it didn't before.  Typically some kind of scaffolding needs to be created to put output somewhere so we can see it.  This require work to be done in every component.&lt;br /&gt;&lt;br /&gt;A better solution would be to have a lightweight tracing process that can be incorporated into a solution easily, preferably with minimal coding.  Since this is such a universal need, Microsoft has provided a great means to do exactly this through built-in functionality in .NET.&lt;br /&gt;&lt;br /&gt;.NET includes tracing capability out of the box in every component through the Debug.Trace function, which can write output into the Visual Studio IDE.  This is nice for local development, but not much value when your component is running on a remote machine.  Thankfully, .NET allows us to hijack the output of Debug.Trace and do anything we want with it.&lt;br /&gt;&lt;br /&gt;Often in a framework, I will have many levels of components, and have a need to debug one small part of one component.  Using a custom trace listener, I am able to put tracing informaion into a component, recompile it, and place it in the GAC on the server in question.  Immediately, I get the trace output, regardless of where in the many layers of the framework it may live.  This is a huge time savings--there is no need to develop custom functions to write or respond to the tracing output, and I have complete control over where the messages go.&lt;br /&gt;&lt;br /&gt;Developing a custom trace listener will require the following:&lt;br /&gt;&lt;br /&gt;1)  Building a self-contained .dll that can be GACed which will consume the trace messages&lt;br /&gt;2)  Changing the web.config file of the application to tell it to use custom tracing&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I take this a step further, and output the trace messages to a database, and check to see if a component's tracing setting is turned on or off.  This allows for turning tracing on or off in an environment with no coding changes.  But this requires a few more steps:&lt;br /&gt;&lt;br /&gt;3)  Set up a database to receive the test messages&lt;br /&gt;4)  Set up a mechanism to determine if an application's trace setting is on or off&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next time, I will discuss how to develop a custom trace listener and allow an application to use it.  Then I will discuss the steps to turn this on and off in an environment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-8639940658762693333?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/8639940658762693333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/create-custom-trace-listener-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8639940658762693333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/8639940658762693333'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/create-custom-trace-listener-part-1.html' title='Create a Custom Trace Listener, Part 1'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6522700447176692180</id><published>2009-03-18T09:30:00.000-07:00</published><updated>2009-03-18T09:47:51.275-07:00</updated><title type='text'>Data Access Using Delegates, Part 2</title><content type='html'>Before jumping into the code for the data access, I want to post a quick overview of delegates for those of you not familiar with them.&lt;br /&gt;&lt;br /&gt;Delegates are essentially function pointers that you can pass into a method like a parameter.  This delegate is a function the called method can call back to, to perform work, to provide updates, etc.&lt;br /&gt;&lt;br /&gt;Consider this example.  Suppose I have a method that is a long-running process, and I have a status bar that I want to update.  The method could take as a parameter a delegate that will get status updates that could be displayed.  The code could look like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Delegate Sub ProcessUpdates(ByRef UpdateMessage As String)&lt;br /&gt;&lt;br /&gt;Public Function LongRunningProcess(ByRef ProcessUpdatesDelegate As ProcessUpdates)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProcessUpdatesDelegate.Invoke("Starting...")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' do something&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProcessUpdatesDelegate.Invoke("Step 1 Completed")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' do something&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProcessUpdatesDelegate.Invoke("Step 2 Completed")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;' do something&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProcessUpdatesDelegate.Invoke("Process Completed")&lt;br /&gt;&lt;br /&gt;End Function&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Next, we would make a call into LongRunningProcess to kick it off, providing the function to call back to to process the update messages.  We would do that this way:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Public Sub ProcessUpdates(ByRef UpdateMessage As String)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;txtStatus.Text = UpdateMessage&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;' do this somewhere in the main line code:&lt;br /&gt;LongRunningProcess(AddressOf ProcessUpdates)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's all there is to it!  Notice that the signature of the ProcessUpdates method has to match the delegate signature exactly.  By following this straightforward process, we can make a delegate, pass it to a method, and have the called method make calls back to the delegate as needed.&lt;br /&gt;&lt;br /&gt;This is exactly the method we will use next time in our data access layer!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6522700447176692180?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6522700447176692180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/data-access-using-delegates-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6522700447176692180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6522700447176692180'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/data-access-using-delegates-part-2.html' title='Data Access Using Delegates, Part 2'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-5082206019050263611</id><published>2009-03-17T09:03:00.000-07:00</published><updated>2009-03-17T09:34:24.013-07:00</updated><title type='text'>Clean Up Your Session Access With Session-Backed Classes</title><content type='html'>One of my favorite techniques to refactor ugly web code into cleaner, OO code is creating session-backed classes.  Often, developers go directly after session values, setting and getting them throughout their web pages.  I hate this for a number of reasons--the biggest two are (1) it is very difficult to deal with decentralized session access, i.e. if you need to change a variable name, or manage everywhere a variable is called, it can be spread out all over your site; and (2) if you misspell the variable name somewhere (clearly session variable names bypass compile-time checking), your code will not behave the way you expected.&lt;br /&gt;&lt;br /&gt;Session-backed classes free you from this problem, give you a nice quasi-OO wrapper over the session, centralize access to the variables, and even provide intellisense when you are developing against them.  Additionally, since creating a session-backed class is a trivial process, you can spend about an hour and create a session-backed class generator to take out the grunt work.&lt;br /&gt;&lt;br /&gt;Let's look at the fundamentals you need for a session-backed class:&lt;br /&gt;&lt;br /&gt;1)  You need a new class that will represent a logic unit (a user, an employee, a sale)&lt;br /&gt;2)  You need a constructor to take a reference to your session management; this is optional if you want to assume you can use the current HTTP context&lt;br /&gt;3)  You need a list of properties that will be made available by this class&lt;br /&gt;4)  A best practice is to use a prefix for the variables to allow the values to be easily grouped, and to clearly show what class created the variables&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, let's take a look at some session-backed class code.  Here is a simple class with one property, making use of the current HTTP context for session management:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Public Class Employee&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Public Property Name() As String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Get&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return HttpContext.Current.Session(Prefix &amp;amp; &amp;quot;Name&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End Get&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set(ByVal value As String)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HttpContext.Current.Session(Prefix &amp;amp; &amp;quot;Name&amp;quot;) = value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End Set&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End Property&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Private Function Prefix() As String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return &amp;quot;Classes.Employee.&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End Function&lt;br /&gt;&lt;br /&gt;End Class&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That's really all there is to it.  Referencing this variable from anywhere else in your application will give you a great OO-style interface into the session:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SessionValue = Employee.Name&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Meanwhile, you are not responsible for any additional code behind the scenes to serialize and deserialize the object, which is perfect for classes that are working with values used by legacy apps that call directly into session (i.e. apps that you can't easily change).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-5082206019050263611?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/5082206019050263611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/clean-up-your-session-access-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5082206019050263611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5082206019050263611'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/clean-up-your-session-access-with.html' title='Clean Up Your Session Access With Session-Backed Classes'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-5561600624668499946</id><published>2009-03-16T19:00:00.000-07:00</published><updated>2009-10-07T17:52:21.703-07:00</updated><title type='text'>Service Unavailable In IIS 6.0</title><content type='html'>If you are not aware, IIS 6.0 has a special feature that monitors failures on your web site.  If enough errors occur in a certain period of time, your app pool is shut down.  The default is 5 errors in 5 minutes.&lt;br /&gt;&lt;br /&gt;I have not seen a whole lot of errors that have registered in this category, i.e. enough of an issue for the app pool to shut itself down.  Our dev box gets beaten up pretty well with our apps in progress, and today was the first time I noticed the app pool being down.&lt;br /&gt;&lt;br /&gt;This is an important thing to know if you notice a "Service Unavailable" error when your page is being served up.  It is also a good thing to be aware of, since it is probably the setting on your production and test boxes, if it has not been modified by your admins.&lt;br /&gt;&lt;br /&gt;You can adjust this setting or turn it off in IIS.&lt;br /&gt;&lt;br /&gt;A special thanks to Elliot Swan for making my job easier today.  I just discovered his tool, &lt;a href="http://www.elliotswan.com/postable/"&gt;Postable&lt;/a&gt;.  Thanks, Elliot!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-5561600624668499946?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/5561600624668499946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/service-unavailable-in-iis-60.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5561600624668499946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/5561600624668499946'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/service-unavailable-in-iis-60.html' title='Service Unavailable In IIS 6.0'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1867385888813527859</id><published>2009-03-16T10:14:00.000-07:00</published><updated>2009-03-16T10:34:25.857-07:00</updated><title type='text'>Reflection and Data Output, Part 1</title><content type='html'>Reflection is extremely beneficial for outputting data dynamically.  Often, we need to be able to change column order or even what displays quickly.  Reflection gives us the mechanism to perform late-binding on columns that will be output.&lt;br /&gt;&lt;br /&gt;Let's consider an example.  Suppose you want to output a table with a few columns--a user's name, country, and ID.  My data access layer is going to provide me a list of objects with properties of the same names.  I can hardcode my output process to use these names.  But what if I expect them to change a lot?  Or what if users are going to be able change them themselves?  Hardcoding is not an option.&lt;br /&gt;&lt;br /&gt;Reflection allows us to solve this problem by reading configuration information and outputting our data columns based on this data.&lt;br /&gt;&lt;br /&gt;You will need to add the following declaration:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Private pInfo() As System.Reflection.PropertyInfo&lt;br /&gt;Private PropertyIndexes() As Integer&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then populate this array:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Dim t As Type = MyObjectCollection(0).GetType&lt;br /&gt;pInfo = t.GetProperties&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then set the indexes of the fields to display:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ReDim PropertyIndexes(TotalColumns - 1)&lt;br /&gt;' loop through your array of property names to display&lt;br /&gt;PropertyIndexes(i) = FindPropertyName(PropertyNameToDisplay(i))&lt;br /&gt;' next&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Finally, for each of your objects, you will loop through the list of fields to display, using this code to pull the correct fields out of the data access object:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Dim output As Object&lt;br /&gt;output = pInfo(PropertyIndexes(i)).GetValue(MyObjectCollection, Nothing)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Yes, I am throwing a lot at you, and this may not make sense right now.  If you are an expert with reflection, you probably see exactly what I am doing.  If not, I will dive more deeply in the details next time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1867385888813527859?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1867385888813527859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/reflection-and-data-output-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1867385888813527859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1867385888813527859'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/reflection-and-data-output-part-1.html' title='Reflection and Data Output, Part 1'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-7414976299117301993</id><published>2009-03-16T09:47:00.000-07:00</published><updated>2009-03-16T10:05:32.762-07:00</updated><title type='text'>Data Access Using Delegates, Part 1</title><content type='html'>Data access layer code is almost universally the same--you get a connection string, you open a connection, you execute your query, you turn your data into objects, you do some clean up of objects you created.  You have probably written hundreds of components to do this.&lt;br /&gt;&lt;br /&gt;One of my biggest annoyances with data access code is that it is usually decentralized, with each DAL opening and closing the connection, creating and destroying objects, etc.  Maybe I want to go back and add in logging to each component and be able to turn it on and off.  I can't really do that if I have hundreds of tiny DALs.  Also, how do I know that all the developers on the project have been diligent about closing and disposing of all their objects?  I don't want to have to verify this is true across everyone's components.&lt;br /&gt;&lt;br /&gt;These exact concerns led me to a different design approach--one that would centralize the tedious, repetitive pieces into a component that could be easily managed, while providing all the necessary functionality and efficiency to the developers.  This is not an easy task because the simplest approach to solve a data problem (datatables, for example) are typically not the fastest.&lt;br /&gt;&lt;br /&gt;My requirements were to design a solution that would:&lt;br /&gt;1)  Centralize connection string management, so connection strings existed in exactly one place&lt;br /&gt;2)  Centralize object creation, and closing and disposing of objects, to ensure this always occurs&lt;br /&gt;3)  Centralize significant events, such as opening a connection or executing a command, to allow capturing of information for troubleshooting or profiling&lt;br /&gt;4)  Decentralize necessary functions, such as adding parameters to a stored procedure call&lt;br /&gt;5)  Allow for efficient data retrieval, rather than require an expensive retrieval method to meet the above criteria&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Looking at these requirements, it didn't take long to realize that delegates were the best solution.  Delegates allow efficient calls to be made to functions outside the centralized code, while providing a means to keep all the important code within a main data access component.&lt;br /&gt;&lt;br /&gt;I will discuss delegates briefly, then jump into how you can use this approach to simplify and enhance your data access components.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-7414976299117301993?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/7414976299117301993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/data-access-using-delegates-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/7414976299117301993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/7414976299117301993'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/data-access-using-delegates-part-1.html' title='Data Access Using Delegates, Part 1'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-3649579751338270304</id><published>2009-03-11T09:34:00.000-07:00</published><updated>2009-03-11T09:45:57.255-07:00</updated><title type='text'>Hint - Use String.Format</title><content type='html'>If you are not currently using String.Format, you owe to yourself (and your co-workers) to start.&lt;br /&gt;&lt;br /&gt;String.Format changes code from looking like this (in VB.NET):&lt;br /&gt;&lt;font size="3"&gt;&lt;pre&gt;Dim MyString as String = _&lt;br /&gt;     "Value of " &amp; MyVariableName &amp; " equals " &amp; _&lt;br /&gt;     MyVariableValue &amp; "."&lt;/pre&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;To looking like this:&lt;br /&gt;&lt;font size="3"&gt;&lt;pre&gt;Dim MyString as String = _&lt;br /&gt;     String.Format("Value of {0} equals {1}.", _&lt;br /&gt;     MyVariableName, MyVariableValue)&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;Let's look at the differences.  First, the String.Format route is much more readable.  It is pretty clear what the result of the concatenation will be without needing to understand the code.  Second, the String.Format approach is significantly less error prone--no more have to recompile because you missed an ampersand, quote, etc.&lt;br /&gt;&lt;br /&gt;Plus, your coworkers will thank you.  Whoever needs to read or maintain your code after you will save time and be able to make changes more easily.  Plus, they may pick up the important skill of using String.Format....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-3649579751338270304?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/3649579751338270304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/hint-use-stringformat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3649579751338270304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/3649579751338270304'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/hint-use-stringformat.html' title='Hint - Use String.Format'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-283033337884388694</id><published>2009-03-09T07:20:00.000-07:00</published><updated>2009-03-09T07:24:03.352-07:00</updated><title type='text'>Date Validation in ASP.NET</title><content type='html'>I don't think ASP.NET uses the most intiative validator for data type validation. I find every time I need to add date validation to a form, I have to go back and look up which validator I need to use (compare validator? range validator?) and what fields to set.&lt;br /&gt;&lt;br /&gt;So, for reference, here is what you need to do:&lt;br /&gt;&lt;list&gt;&lt;br /&gt;&lt;li&gt;Use a Compare validator&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Set the ControlToValidate to point to the date textbox&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Set the Type to "Date"&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Set the Operator to "DataTypeCheck"&lt;/li&gt;&lt;br /&gt;&lt;/list&gt;&lt;br /&gt;That's all there is to it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-283033337884388694?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/283033337884388694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/date-validation-in-aspnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/283033337884388694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/283033337884388694'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/date-validation-in-aspnet.html' title='Date Validation in ASP.NET'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-6019164976835401992</id><published>2009-03-06T09:42:00.000-08:00</published><updated>2009-03-10T10:22:19.431-07:00</updated><title type='text'>Using Web Service for Legacy Data</title><content type='html'>Web Services are a tremendous way to encapsulate data access. If I think my data access layer may be hit from multiple types of clients, I create a web service to deliver the data. This ensures easy access, no matter who may want to consume the data.&lt;br /&gt;&lt;br /&gt;One of my current clients has an existing classic ASP site. This site handles the majority of their sales traffic. It has been in place for some time, and with plenty of initiatives for new systems, they have no desire to rewrite it in .NET. In addition to classic ASP, their site contains a number of COM components for data access. So, my goal was to use .NET to develop data access that could be used by the classic ASP and COM components, but allow a transition to new technologies when it made sense.&lt;br /&gt;&lt;br /&gt;Note first that threading can be a big issue when it comes to connecting legacy technologies to .NET. Per Microsoft, you should not have a COM component calling a .NET component directly. This is another way that the Web Service protects you.&lt;br /&gt;&lt;br /&gt;Architecturally, Web Services also give you a great means of load balancing. My client, like any large company, had a good-sized web farm that was handling requests. By exposing the data access layer on HTTP, the server that is most able to handle the request will do so--even if it is not the server that is processing the COM component or ASP page. In other words, a server may actually hand of this request to a more idle server, and both machines have a hand in processing the web page.&lt;br /&gt;&lt;br /&gt;As I mentioned above, Web Services are my tool of choice when it comes to providing data to a myriad of types of clients, so this is the perfect choice in this case. Next, the problem is how to make the connection between the old technologies and a web service.&lt;br /&gt;&lt;br /&gt;Long ago, the SOAP toolkit was the way to solve this problem. But with this technology deprecated by Microsoft, it is clearly not the solution.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So when I need to connect classic ASP or COM components to a web service, I use a direct XMLHTTP request using the MSXML component. This is a very straightforward process, and setting up the configuration information is largely a matter of copying and pasting information from the .asmx page into your program.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;First, you need to set up a few functions that you will use to make the call. I put the following code in a include file for classic ASP:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; strWSUrl = "http:&amp;#47;&amp;#47;server&amp;#47;webservices&amp;#47;MaterialRelease&amp;#47;service.asmx" &lt;br /&gt; strAction = "http:&amp;#47;&amp;#47;tempuri.org&amp;#47;GetAvailableForecasts"&lt;br /&gt; strXml = _&lt;br /&gt;  "&amp;lt;?xml version=""1.0"" encoding=""utf-8""?&amp;gt;" &amp; _&lt;br /&gt;  "&amp;lt;soap:Envelope xmlns:xsi=""http:&amp;#47;&amp;#47;www.w3.org&amp;#47;2001&amp;#47;XMLSchema-instance"" xmlns:xsd=""http:&amp;#47;&amp;#47;www.w3.org&amp;#47;2001&amp;#47;XMLSchema"" xmlns:soap=""http:&amp;#47;&amp;#47;schemas.xmlsoap.org&amp;#47;soap&amp;#47;envelope&amp;#47;""&amp;gt;" &amp; _&lt;br /&gt;  "  &amp;lt;soap:Body&amp;gt;" &amp; _&lt;br /&gt;  "    &amp;lt;GetAvailableForecasts xmlns=""http:&amp;#47;&amp;#47;tempuri.org&amp;#47;""&amp;gt;" &amp; _&lt;br /&gt;  "      &amp;lt;SupplierId&amp;gt;" &amp; SupplierID &amp; "&amp;lt;&amp;#47;SupplierId&amp;gt;" &amp; _&lt;br /&gt;  "    &amp;lt;&amp;#47;GetAvailableForecasts&amp;gt;" &amp; _&lt;br /&gt;  "  &amp;lt;&amp;#47;soap:Body&amp;gt;" &amp; _&lt;br /&gt;  "&amp;lt;&amp;#47;soap:Envelope&amp;gt;"&lt;br /&gt;&lt;br /&gt; result = PostWebService(strWSUrl, strAction, strXml)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-6019164976835401992?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/6019164976835401992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/using-web-service-for-legacy-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6019164976835401992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/6019164976835401992'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/using-web-service-for-legacy-data.html' title='Using Web Service for Legacy Data'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8370263200616041533.post-1314435869201452654</id><published>2009-03-04T20:22:00.000-08:00</published><updated>2009-03-05T09:41:43.370-08:00</updated><title type='text'>Hide a SharePoint Field</title><content type='html'>Often for workflows, or to manage documents, it is useful to have a hidden field. I have seen a lot of tricks to do this (programatically add the field as hidden, set up a UI to be able to edit a list's hidden attributes, even changing the javascript on the edit page), but is there a way to do this out of the box, without needing to program?&lt;br /&gt;&lt;br /&gt;Fortunately, the answer is yes, and it is pretty easy.  You just need to do the following:&lt;br /&gt;&lt;br /&gt;1)  You need to allow management of content types.  This option is in the List advanced settings.  Make sure this is set to "Yes."  Making this change will present additional configuration options in the List settings pages.&lt;br /&gt;&lt;br /&gt;2)  Now, find the column you want to hide in the List settings page.  When you click on the column, you are presented with options for the column, including the ability to hide the column.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's that simple!  Now you can create a column for many purposes--I frequently use this feature to hold a status to facilitate workflows.  The status can even be displayed in a view if needed, without it being editable in a New or Edit item page.&lt;br /&gt;&lt;br /&gt;Good luck out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8370263200616041533-1314435869201452654?l=eclectictechie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eclectictechie.blogspot.com/feeds/1314435869201452654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/hide-sharepoint-field.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1314435869201452654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8370263200616041533/posts/default/1314435869201452654'/><link rel='alternate' type='text/html' href='http://eclectictechie.blogspot.com/2009/03/hide-sharepoint-field.html' title='Hide a SharePoint Field'/><author><name>jtabernik</name><uri>http://www.blogger.com/profile/13434823401391118690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
