<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>Tal Bereznitskey</title><generator>Tumblr (3.0; @berzniz)</generator><link>http://berzniz.com/</link><item><title>iOS Apps: Keeping data over re-installs</title><description>&lt;p&gt;I took &lt;a href="http://berzniz.com/post/49507932158/i-suck-at-marketing"&gt;my own advice&lt;/a&gt; and decided to create a Freemium version of &lt;a href="https://bitly.com/DriveModeEng"&gt;Drive Mode&lt;/a&gt; and call it &lt;em&gt;Speak and Drive&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The app will allow users to dictate 20 destinations to their favorie navigation app. After these 20 free uses, the user has the option to unlock the app for unlimited use with an In-App Purchase.&lt;/p&gt;
&lt;h3&gt;Where should I store this &amp;#8220;uses&amp;#8221; counter?&lt;/h3&gt;
&lt;p&gt;The easiest place to store this data is the &lt;em&gt;NSUserDefaults&lt;/em&gt; dictionary. This is a &lt;strong&gt;big mistake&lt;/strong&gt; since the user can trick the counter. All he has to do is uninstall the app and then re-install this. This will delete the &lt;em&gt;NSUserDefaults&lt;/em&gt; entry and return the counter to 0.&lt;/p&gt;
&lt;h3&gt;Hello Keychain&lt;/h3&gt;
&lt;p&gt;The only place to store data that never gets deleted is the &lt;em&gt;Keychain. &lt;/em&gt;The purpose of the keychain is to store sensitive data like usernames, passwords, etc. I&amp;#8217;ll use it here since it doesn&amp;#8217;t get deleted when the app is deleted.&lt;/p&gt;
&lt;p&gt;Reading and writing to the Keychain isn&amp;#8217;t as straight forward as writing to the &lt;em&gt;NSUserDefaults&lt;/em&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dictionary. There is a lot of boilerplate and you got to deal with a lot of C code (the iOS SDK doesn&amp;#8217;t provide a neat Objective-C interface for it).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Fortunately, the open source community is always there to save me. I found this amazing &lt;a href="https://github.com/carlbrown/PDKeychainBindingsController"&gt;Keychain wrapper&lt;/a&gt; and it makes the Keychain work similar to &lt;/span&gt;&lt;em&gt;NSUserDefaults&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Except for one small detail. It will only allow you to store NSStrings in the Keychain. I quickly created my own counter wrapper class:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/5604924"&gt;https://gist.github.com/5604924&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Now I can track the number of uses easily without letting people trick the counting system.&lt;/p&gt;</description><link>http://berzniz.com/post/50737500849</link><guid>http://berzniz.com/post/50737500849</guid><pubDate>Sat, 18 May 2013 12:27:52 -0400</pubDate></item><item><title>I suck at marketing</title><description>&lt;p&gt;I have a lot of ideas for products. Some are really bad, others are quite good.&lt;/p&gt;
&lt;p&gt;Once in a while a really good idea comes along. This is the product I build.&lt;/p&gt;
&lt;p&gt;The last good idea turned into &lt;a href="https://bitly.com/DriveModeEng"&gt;Drive Mode&lt;/a&gt;. A good product that solves a real pain for users. I also know that people are actively looking to solve this pain.&lt;/p&gt;
&lt;p&gt;I created two versions of the app:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;span&gt;A localized version for my own country (Israel&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;A multi-language version&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;h3&gt;Marketing is so easy&lt;/h3&gt;
&lt;p&gt;The localized version was so easy to market. I just sent a few emails to relevant blogs, they picked it up and so did the users. A national newspaper wrote about it and I was even interviewed for a popular TV show about it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="http://media.tumblr.com/f095b41388ccbb83c9dee6235c2ac434/tumblr_inline_mm82ml12Zf1qz4rgp.jpg"/&gt;&lt;/p&gt;

&lt;p&gt;(I do have eyes in real life, just not in this photo)&lt;/p&gt;
&lt;p&gt;The app is still a regular Top 10 ranked app in the Israeli App Store and it has a great rating score from a lot of users. Not my-friends-users, but real users who use the app every day (And I have the analytics to prove it).&lt;/p&gt;
&lt;h3&gt;Marketing is so hard&lt;/h3&gt;
&lt;p&gt;After conquering the Israeli market, I was sure I could repeat the same success in other markets.&lt;/p&gt;
&lt;p&gt;So I took the &amp;#8220;Marketing Recipe&amp;#8221; from the localized version and applied it again: I sent the information about the app to as many blogs and review sites as I could. Not only to English blogs, but to French, Dutch, Italian and you-name-it language blogs as well.&lt;/p&gt;
&lt;p&gt;It got a few reviews on those blogs, but it didn&amp;#8217;t drive many users to download and use the app.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Those who did use it liked it.&lt;/strong&gt; I know, they said so on the App Store: &amp;#8220;Ottima&amp;#8221;, &amp;#8220;WELL DONE&amp;#160;!!!&amp;#8221;, &amp;#8220;Perfect&amp;#8221;, &amp;#8220;Fantasticaaaaaaaa!!!!!!!!!!&amp;#8221;, &amp;#8220;Realmente práctica&amp;#8221;, &amp;#8220;Life saver&amp;#8221;, &amp;#8220;Handige app!&amp;#8221;. (To be fair, there were some users who weren&amp;#8217;t impressed by it, but they are the minority).&lt;/p&gt;
&lt;p&gt;So here&amp;#8217;s a useful product that people like. &lt;strong&gt;Why doesn&amp;#8217;t it take off by itself?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I knew I had to do something about it. I started reading every blog post ever about marketing apps and marketing in general and took some actions. Still, I couldn&amp;#8217;t reach the result I aimed for and that is suitable for the app.&lt;/p&gt;
&lt;p&gt;What should I do next?&lt;/p&gt;
&lt;h3&gt;&amp;#8220;What have you tried?&amp;#8221;&lt;/h3&gt;
&lt;p&gt;Matt wrote a long time ago that after asking a question you might face with the &lt;a href="http://mattgemmell.com/2008/12/08/what-have-you-tried/"&gt;&amp;#8220;What have you tried?&amp;#8221;&lt;/a&gt; question. I&amp;#8217;m all up for that.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what I&amp;#8217;ve tried:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;I used Applaunch.us services to help me reach bigger review sites. &lt;a href="http://berzniz.com/post/47785056309/my-disappointing-experience-with-applaunch-us"&gt;It didn&amp;#8217;t work&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I wrote on car/driving forums about the app. I don&amp;#8217;t regularly visit these communities, so my posts were not welcomed there (I asked for permission before posting about the app. Most told me &amp;#8220;Thanks for being honest and asking for permission, but please don&amp;#8217;t advertise on our forums&amp;#8221;).&lt;/li&gt;
&lt;li&gt;I dropped the app price to attract more downloads. It didn&amp;#8217;t work. People were either willing to pay or not. It wasn&amp;#8217;t about the price.&lt;/li&gt;
&lt;li&gt;I posted a few posts on &lt;a href="https://news.ycombinator.com/item?id=5646645"&gt;hacker&lt;/a&gt; &lt;a href="https://bitly.com/DriveModeEng"&gt;news&lt;/a&gt; &lt;a href="http://berzniz.com/post/49031590163/remote-control-your-ios-app"&gt;about&lt;/a&gt; it.&lt;/li&gt;
&lt;li&gt;I updated the app to support more navigation apps. That didn&amp;#8217;t change much (Most users did upgrade to it).&lt;/li&gt;
&lt;li&gt;I&amp;#8217;ve tried using Google Adwords to attract traffic to the app landing page. Unfortunately, Google did not approve the keywords I was targeting (They didn&amp;#8217;t like &amp;#8220;Siri&amp;#8221; nor &amp;#8220;Google Maps&amp;#8221;).&lt;/li&gt;
&lt;li&gt;I&amp;#8217;m currently looking at Twitter ads as well. I love Twitter and I hope this might actually work.&lt;/li&gt;
&lt;/ol&gt;&lt;h3&gt;What&amp;#8217;s next?&lt;/h3&gt;
&lt;p&gt;I have a few ideas for my next steps.&lt;/p&gt;
&lt;p&gt;People like the app once they download it, but not many are willing to give it a spin. I could create a new lite version of the app and give it away for free. It will support X operations and users can unlock it with an In-App Purchase.&lt;/p&gt;
&lt;p&gt;Friends told me that &lt;strong&gt;the app name should be better &lt;/strong&gt;and that it should say clearly what the app does. The current name is &amp;#8220;Drive Mode&amp;#8221;. The idea was that when you get on an Airplane you use &amp;#8220;Airplane Mode&amp;#8221; and when you start Driving you use &amp;#8220;Drive Mode&amp;#8221;. I might change the app name to something like &amp;#8220;Speak and Navigate&amp;#8221;, &amp;#8220;Speak and Drive&amp;#8221; or similar.&lt;/p&gt;
&lt;p&gt;Other than that I&amp;#8217;m quite lost. &lt;strong&gt;I suck at marketing.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Do you have an idea?&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;I would really&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;strong&gt;love to hear your ideas&lt;/strong&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;about what can/should be done. &lt;/span&gt;&lt;span&gt;Please leave a comment below, I read and answer every single one, always.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;You can &lt;strong&gt;download it for free&lt;/strong&gt; with one of these app promo codes:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;(&lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/5kx46ajj"&gt;1&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/m6aa2ace"&gt;2&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/3qvqbe5r"&gt;3&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;a href="http://tokn.co/e23btznf"&gt;4&lt;/a&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/nz6fkd88"&gt;5&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/hbys5wyw"&gt;6&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/ttqrdt7v"&gt;7&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/g3c59w6k"&gt;8&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/4c9nrzkg"&gt;9&lt;/a&gt;&lt;/strike&gt;&lt;span&gt; &lt;/span&gt;&lt;strike&gt;&lt;a href="http://tokn.co/pjuwnspm"&gt;10&lt;/a&gt;&lt;/strike&gt;&lt;span&gt;)&lt;/span&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/49507932158</link><guid>http://berzniz.com/post/49507932158</guid><pubDate>Fri, 03 May 2013 08:35:00 -0400</pubDate></item><item><title>Remote control your iOS app</title><description>&lt;p&gt;If you&amp;#8217;re in the business of developing iPhone apps, you probably already  know that app version upgrades are a pain. Each app upgrade must go through Apple&amp;#8217;s app review process which takes 5-14 days.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;That&amp;#8217;s the reason why I always add remote configuration to my Apps. I call it a &amp;#8220;Remote control&amp;#8221; for apps.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Remote Control for apps&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;What I do is include a JSON file as my configuration. It controls everything that can be configured: supported languages, number of items to show per page, colors to use, etc.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Once a day, the app connects to my servers and pulls a new version of that configuration JSON file. This way, I control the configuration from my server. I can change my app behavior whenever I want.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is how it saved me with &lt;a href="https://bitly.com/DriveModeEng"&gt;Drive Mode&lt;/a&gt;, my latest iPhone app:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Drive Mode is an app that let&amp;#8217;s you speak and control navigation apps with your voice. It supports various navigation apps. The integration with one of the apps, Navigon, was buggy and didn&amp;#8217;t work. My super nice users sent me feedback about it and asked me to fix it.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Since it is all remotely-configured, I just had to change a string in my JSON file and upload it to my server and BOOM! Every user gets this update instantly.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I managed to fix the issue in one hour instead of 5-14 days.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I can also add support for new apps without having to submit a new app to the App Store. Now that&amp;#8217;s a competitive advantage.&lt;/p&gt;
&lt;h3&gt;Do you want something like this for your app?&lt;/h3&gt;
&lt;p&gt;This is so simple to implement, so I wonder why it isn&amp;#8217;t part of the iOS SDK (something like &lt;em&gt;NS&lt;/em&gt;&lt;em&gt;Remote&lt;/em&gt;&lt;em&gt;UserDefaults&lt;/em&gt;&lt;span&gt;). I&amp;#8217;m thinking about open sourcing this or maybe making a small (free) hosted service to handle this for everyone.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let me know if you&amp;#8217;re interested.&lt;/p&gt;</description><link>http://berzniz.com/post/49031590163</link><guid>http://berzniz.com/post/49031590163</guid><pubDate>Sat, 27 Apr 2013 16:14:28 -0400</pubDate></item><item><title>My [disappointing] experience with AppLaunch.us</title><description>&lt;p&gt;I used the services of &lt;a href="https://applaunch.us/"&gt;AppLaunch.us&lt;/a&gt; exactly twice: &lt;strong&gt;for the first time and the last time.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I first heard about AppLaunch from the popular weekly newsletter curated by Dave Verwer (@daveverwer), the &lt;a href="http://iosdevweekly.com/"&gt;iOS Dev Weekly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It was a &lt;a href="http://iosdevweekly.com/issues/80/"&gt;sponsored item&lt;/a&gt; and as I truly respect Dave&amp;#8217;s work, I concluded that AppLaunch.us could help me market &lt;a href="http://bitly.com/DriveModeEng"&gt;Drive Mode&lt;/a&gt;, my latest iPhone app.&lt;/p&gt;
&lt;p&gt;AppLaunch.us is a tool for easily getting your app to the press. I decided to try their most basic package costing $55 and see how it works.&lt;/p&gt;
&lt;p&gt;I filled all the information about my app, payed and got a confirmation email telling me that my submission arrived successfully. They also said I can contact them with what ever questions I had.&lt;/p&gt;
&lt;p&gt;After 4 days of hearing nothing, I contacted them to ask what is the roadmap for the campaign. I was never answered. Three days later I got a generic email stating that my campaign started. On that day I got 7 more identical emails saying that my press-kit was downloaded by a review site.&lt;/p&gt;
&lt;p&gt;I waited a few days to see if a review site will contact me, or post anything about the app, but nothing happened. It&amp;#8217;s okay, maybe the app wasn&amp;#8217;t interesting enough.&lt;/p&gt;
&lt;p&gt;I tried contacting AppLaunch.us asking about the state of the campaign and exploring what else could I do. It was never answered.&lt;/p&gt;
&lt;p&gt;I logged in to their website, but there was no info for my account, just stating that the campaign is in &amp;#8220;Preparing campaign&amp;#8221; state.&lt;/p&gt;
&lt;p&gt;After a few more days, I tried contacting them again. Guess what? They never answered it as well.&lt;/p&gt;
&lt;p&gt;It was now 3 contact attempts and 0 answers.&lt;/p&gt;
&lt;p&gt;After about two weeks, AppLaunch.us website had been redesigned and now the account page shows statistics about the campaign. Here it is:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;140 Reviewers have read the launch email&lt;/li&gt;
&lt;li&gt;6 Reviewers have viewed the press release&lt;/li&gt;
&lt;li&gt;13 Reviewers have downloaded your Press Kit&lt;/li&gt;
&lt;li&gt;0 Reviewers have requested a promo code&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Pretty much a campaign failure, but this is not their fault.&lt;/p&gt;
&lt;p&gt;I did however try to find one developer saying AppLaunch.us did work for him, but I couldn&amp;#8217;t find anyone. Finding people saying it didn&amp;#8217;t work for them was much easier.&lt;/p&gt;
&lt;p&gt;As Apple would say it: &lt;strong&gt;It just doesn&amp;#8217;t work.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;On my own&lt;/h3&gt;
&lt;p&gt;Okay. Anyone can send an email pitching an app to the press, right? That&amp;#8217;s exactly what I did.&lt;/p&gt;
&lt;p&gt;The results:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;21 email sent&lt;/li&gt;
&lt;li&gt;4 reviews posted&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So without &amp;#8220;press connections&amp;#8221; and reputation I got more reviews than a service that &amp;#8220;specializes&amp;#8221; in this operation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My suggestion: Do not use AppLaunch.us! Do it on your own.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/47785056309</link><guid>http://berzniz.com/post/47785056309</guid><pubDate>Fri, 12 Apr 2013 11:31:00 -0400</pubDate></item><item><title>The part-time indie developer</title><description>&lt;p&gt;&lt;span&gt;I&amp;#8217;m a &lt;/span&gt;&lt;strong&gt;&amp;#8220;Full-time software developer&amp;#8221;&lt;/strong&gt;&lt;span&gt; for a startup company. I wake up everyday and drive to work where they pay me to work on my hobby. I develop iOS and web applications that lots of people use everyday. It&amp;#8217;s a great job and I consider myself to be very fortunate.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;When my work day ends, I go home and become a &lt;strong&gt;&lt;span&gt;&amp;#8220;Part-time indie developer&amp;#8221;.&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So what is a &amp;#8220;Part-time indie developer&amp;#8221;? I&amp;#8217;m not totally sure myself as I just came up with this title a few minutes ago. Basically, if you&amp;#8217;re &lt;strong&gt;working alone on &lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;$0 budget &lt;/strong&gt;&lt;span&gt;&lt;strong&gt;side-projects in your free time&lt;/strong&gt; then you are one. &lt;/span&gt;&lt;span&gt;I am one.&lt;/span&gt;&lt;strong&gt;&lt;!-- more --&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Why do I keep working on my free time? That&amp;#8217;s a great question. The truth is &lt;strong&gt;I get the urge to create new and useful stuff&lt;/strong&gt; that are out of the scope of my workplace. I can work on whatever I want without thinking if it&amp;#8217;s a waste of time or not.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Creating apps is not a one-man&amp;#8217;s mission. The process includes coming up with an idea, validating the idea, designing the app, developing the app, QA testing the app, marketing the app and providing support for the users. As an indie developer, I love doing all of these myself.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Why? Because&lt;strong&gt; I love acquiring new skills.&lt;/strong&gt; &lt;/span&gt;&lt;span&gt;Validating an idea is an important skill to have at any level. Designing an app from scratch is a great UX/UI school. &lt;/span&gt;&lt;span&gt;Marketing an app is a great way to learn marketing.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Being a one-man-army is not the only challenge. &lt;strong&gt;The real challenge is transforming your idea into a working product&lt;/strong&gt; you can tweet about. And for this to happen, you have to play your cards right. The most important card you have is time.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Time is scarce and this leads to choosing certain kind of projects to work on. &lt;/span&gt;&lt;span&gt;This is the single most important thing I learned: &lt;/span&gt;&lt;strong&gt;Small ideas win&lt;/strong&gt;&lt;span&gt;. Small ideas can be translated into small projects. Small projects can be completed in a short time. Completed projects are a success for a part-time indie developer.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Yes, the part-time indie developer must be a passionate, versatile and effective creature.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Challenge accepted!&lt;/p&gt;</description><link>http://berzniz.com/post/45493776200</link><guid>http://berzniz.com/post/45493776200</guid><pubDate>Sat, 16 Mar 2013 08:55:40 -0400</pubDate></item><item><title>New iPhone app - Drive Mode</title><description>&lt;p&gt;Here&amp;#8217;s a peek at my newest iPhone app:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/c0b8a51ba9c3f83faf50aa97b40d16f5/tumblr_inline_miso5dQDn31qz4rgp.png"/&gt;&lt;/p&gt;

&lt;p&gt;The iPhone app I use the most is &lt;a href="https://itunes.apple.com/us/app/waze-social-gps-traffic-gas/id323229106?mt=8" target="_blank"&gt;Waze&lt;/a&gt;, a turn-by-turn navigation app. Without it, I would probably never get anywhere.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Google Maps is great when I travel abroad, it really is becoming a great navigation app with tons of cool features.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;There&amp;#8217;s one problem both these navigation apps have, they lack the ability to enter a new destination during driving.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I always have to lie and say &amp;#8220;I&amp;#8217;m not the driver&amp;#8221; while trying to tap the correct letters of my desired destination. It never works.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;Drive Mode&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Meet &lt;a href="http://bit.ly/DriveModeEng"&gt;Drive Mode&lt;/a&gt;, the app that lets you speak and tell your iPhone where you want to go.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It listens and understands where you asked it to go and automatically starts navigating using your favorite navigation app with the destination you spoke.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It currently supports Waze, Google Maps and Apple Maps. It does not rely on Siri so you can use it on iPhone 4 and older devices.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Other than the coolness of talking to your iPhone, you can also keep your eyes on the road and drive more safely.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;Download&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The app is now available on the App Store.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bit.ly/DriveModeEng" target="itunes_store"&gt;&lt;img alt="Drive Mode" src="http://r.mzstatic.com/images/web/linkmaker/badge_appstore-lrg.gif"/&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/44005808058</link><guid>http://berzniz.com/post/44005808058</guid><pubDate>Mon, 25 Feb 2013 16:18:55 -0500</pubDate></item><item><title>NSBackbone - Porting Backbone.js concepts to native iOS Apps</title><description>&lt;p&gt;&lt;strong&gt;We all want to write better code.&lt;/strong&gt; One that is easy to read, understand and extend. Finding the path to good code might not be trivial and is sometime achieved by searching out side of the box.&lt;/p&gt;
&lt;p&gt;This is the case with &lt;a href="https://github.com/berzniz/NSBackbone"&gt;NSBackbone&lt;/a&gt;. It&amp;#8217;s a sample project that takes inspiration from the successful javascript library &lt;a href="http://backbonejs.org/"&gt;Backbone.js&lt;/a&gt;. Building web apps with javascript and backbone.js can teach us a lot about keeping our code short, clean and simple.&lt;/p&gt;
&lt;p&gt;One of the best things about Backbone is how predictable its code is. Each Backbone.View has the same structure. This makes the code dead simple to understand, no matter which view you&amp;#8217;re looking at.&lt;/p&gt;
&lt;p&gt;UIViewControllers however, are a different story. &lt;strong&gt;UIViewControllers are unpredictable.&lt;/strong&gt; Some will refresh the UI on viewWillAppear where others will do so on viewDidAppear. Some will only update the UI once on viewDidLoad. We must hunt down all of the viewDid/viewWill methods and figure out what&amp;#8217;s going on.&lt;/p&gt;
&lt;p&gt;Although Backbone is not a 100% MVC (Model-View-Controller) framework, it still makes handling data and UI easy. Backbone makes it easy to observe changes to a model (an object holding data) and act upon them. We use this feature to ensure the UI is always showing the most updated data.&lt;/p&gt;
&lt;p&gt;Backbone.Views are predictable. Take a look at the following typical view:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/4361743"&gt;https://gist.github.com/4361743&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s very short, but accomplishes a very common and important task in apps. The task of keeping the UI updated to reflect the changes in the model&amp;#8217;s data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The rules I follow with Backbone:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1. A view renders the UI when it loads.&lt;/p&gt;
&lt;p&gt;2. A view observes changes to the model&amp;#8217;s data and re-render the UI.&lt;/p&gt;
&lt;p&gt;3. User actions change the model&amp;#8217;s data and not the UI. The UI will be updated by observing the model&amp;#8217;s changes.&lt;/p&gt;
&lt;p&gt;With these rules in mind, let&amp;#8217;s rewrite the code with Objective-C:&lt;/p&gt;
&lt;p&gt;(This amazing &lt;a href="https://github.com/rayh/kvo-block-binding"&gt;library&lt;/a&gt; is used to simplify the model observation code)&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/4361749"&gt;https://gist.github.com/4361749&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Take a good look at this code. The view is always updated no matter what changed the model. The model could changed due to action taken by the user or by an async network request, but &lt;strong&gt;no matter what - the view will reflect the changes&lt;/strong&gt;. The user will see the changes as they happen.&lt;/p&gt;
&lt;p&gt;It just works.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/berzniz/NSBackbone"&gt;NSBackbone&lt;/a&gt; project on github shows this concept in action. &lt;strong&gt;You&amp;#8217;ll love it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Please share your ideas about bringing concepts from different programming languages to iOS development.&lt;/p&gt;</description><link>http://berzniz.com/post/38579016628</link><guid>http://berzniz.com/post/38579016628</guid><pubDate>Sat, 22 Dec 2012 18:20:00 -0500</pubDate><category>iOS</category><category>backbone</category></item><item><title>4 Changes in Backbone.Events you should know about</title><description>&lt;p&gt;I really liked the latest update of Backbone to version 0.9.9 which will probably be the last one before 1.0.&lt;/p&gt;
&lt;p&gt;There are a lot of changes and tweaks, but what I really like are the changes/additions made to the &lt;strong&gt;Backbone.Events&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Global Notifications&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Backbone now supports a global Pub/Sub notification system. The implementation is very similar to what I&amp;#8217;ve suggest at a previous blog post (&lt;a href="http://berzniz.com/post/19351578959/backbone-js-global-notifications"&gt;Backbone global notifications&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Backbone&lt;/strong&gt; object now extends &lt;strong&gt;Backbone.Events&lt;/strong&gt; instead of adding another object onto it. Smart and simple.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Defeat memory leaks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re new to Backbone then you probably don&amp;#8217;t even know about the problem of memory leaks when binding to objects.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;ve been using Backbone for a project or two, you already know that for each &lt;strong&gt;.on&lt;/strong&gt; you call on an object, you must also call &lt;strong&gt;.off&lt;/strong&gt; in order to let the Garbage collector do its job. We always seem to forget this especially when Views are binding to Models.&lt;/p&gt;
&lt;p&gt;Backbone now allows you to bind the other way around. A view can bind to a few model notifications and then unbind from all of them with a single call.&lt;/p&gt;
&lt;p&gt;This is done with the &lt;strong&gt;view.listenTo(model, &amp;#8216;event-name&amp;#8217;, func)&lt;/strong&gt; an&lt;span&gt;d &lt;strong&gt;view.stopListening()&lt;/strong&gt;. The default &lt;strong&gt;remove()&lt;/strong&gt; function of views will call &lt;strong&gt;stopListening()&lt;/strong&gt; for you so you won&amp;#8217;t forget.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Bind only once&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Another cool new feature is binding to a notification only once. A call to &lt;strong&gt;once()&lt;/strong&gt; ensures that the callback only fire once when a notification arrives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Alternative syntax&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Binding now supports a map syntax:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;p&gt;model.on({&lt;/p&gt;
&lt;p&gt;    &amp;#8216;change:name&amp;#8217;&amp;#160;: this.nameChanged,&lt;/p&gt;
&lt;p&gt;    &amp;#8216;change:age&amp;#8217;&amp;#160;: this.timeMachine,&lt;/p&gt;
&lt;p&gt;    &amp;#8216;change:height&amp;#8217;&amp;#160;: this.newShoes&lt;/p&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is much cleaner than having three separate calls to &lt;strong&gt;.on&lt;/strong&gt; and aligns well with the events hash used for Views.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/37971289563</link><guid>http://berzniz.com/post/37971289563</guid><pubDate>Sat, 15 Dec 2012 03:48:29 -0500</pubDate><category>backbone</category></item><item><title>8 Reasons why real men DO use Interface Builder</title><description>&lt;p&gt;I remember when my team leader asked me if I think it&amp;#8217;s possible to compile our C libraries for a new platform called &amp;#8220;iPhone OS&amp;#8221;. I said yes and my programming career took a 180 degree turn that day.&lt;/p&gt;
&lt;p&gt;A new platform was born for learning, hacking and building cool stuff that could run on my super sleek new phone. When the iPhone SDK came out, I sat to write the first iPhone app of my company. I love working on new platforms and learning all I can about it. &lt;/p&gt;
&lt;p&gt;I read about every single article about iPhone development and found out that &amp;#8220;Interface Builder&amp;#8221; (IB) is not to be used by real men. I used to hand-code HTML and I knew how crappy those WYSIWYG editors were so I didn&amp;#8217;t think this IB will be any different. &lt;strong&gt;Also, a builder tool is for newbies, right?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;!-- more --&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So the entire iPhone app was hand coded with beautiful segments of code to alloc views, init them, set their frame, color, alignment, alpha value, text when they are normal and text when they are highlighted, connected buttons to actions and let scrollview know if they should be paging or not. Very fun.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Seriously, I think 70 percent of the code was doing UI work.&lt;/strong&gt; 90 percent of my time was shuffling pixels from one line of code to the other. I had so many #defines and static variables so the code would be&amp;#8230; neat&amp;#8230; and of course it wasn&amp;#8217;t. Should I use the Interface Builder? Hell no, I&amp;#8217;m a real man.&lt;/p&gt;
&lt;p&gt;One day I decided to use the IB for our next upcoming feature. Just to try it out&amp;#8230; it wouldn&amp;#8217;t make me less of a man. That was a good decision. I found out that the IB is a time saver, a clutter saver and a pixel-nazi&amp;#8217;s best friend.&lt;/p&gt;
&lt;p&gt;From then on I I set a goal: &lt;strong&gt;&amp;#8220;Always use the Interface Builder, unless impossible&amp;#8221;.&lt;/strong&gt; And so I did. I had my chance at working on some crazy, customisable, non-standard UI so believe me when I say that almost everything can be done using the IB.&lt;/p&gt;
&lt;p&gt;Interface Builder is not a crappy WYSIWYG HTML editor. It will not make your code worse. It will not break when you upgrade to the next version of Xcode. It&amp;#8217;s the suggested way to build the app UI, and real men DO use it.&lt;/p&gt;
&lt;p&gt;Not convinced yet? Here&amp;#8217;s the full list of reasons (IB &amp;gt; code) when it comes to UI:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Easy prototyping&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you just want to play around with an idea, you can use IB to drag and drop views and get an overall feel of your next feature.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Easy changing stuff&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Oh, that view is a few pixels off? Let&amp;#8217;s move it a bit to the left. IB is much faster at this then the usual loop of changing-values-in-your-code, running it on the simulator, rinse and repeat&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Less code&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How many lines does it take to configure a label? At least 6: One for alloc&amp;#8217;ing it, another for sizing it, another for an alignment mask, add one to choose a color, another for choosing the correct font, oh and don&amp;#8217;t forget a line for setting the actual text on the label. Yes. you can throw this entire code away.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Easier to maintain&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Once everything is configured, you can let your grandma play with the IB to change stuff. I don&amp;#8217;t let my grandma touch my UI, but if my product manager asks for it, he can open the UI in the interface builder and have a kick at it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. All options are revealed&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Do you know everything a view has to offer? When coding, you&amp;#8217;ll have to lookup the header file or documentation of each and every parent-class of the view you&amp;#8217;re creating. With IB all options are in front of you, so you can&amp;#8217;t miss a feature like auto-sizing, text-shadow, content-offsets and others.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. One for iPhone and one for iPad.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Creating a universal app? You can use a dedicated XIB for each device that uses the same class. Some people even use this feature to design one UI for portrait mode and a different for landscape.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. Educate your designer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I showed my designer the IB and let him play with it a little. Once he figured out how I&amp;#8217;m going to &amp;#8220;build his PSDs&amp;#8221;, he understood how to cut them into beautiful PNGs, all ready to use.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8. What can&amp;#8217;t be done with it, can be done without it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yes, some things are impossible to achieve with the IB. For example, reusing a UI control from a different Xib is not yet possible. So what do I do? I create everything in the IB and connect them in code.&lt;/p&gt;
&lt;p&gt;Today I added code so my button will use a stretched UIImage as its background. So the UIButton was all configured in the IB expect for this tiny unsupported feature. The point is it all plays along well.&lt;/p&gt;
&lt;p&gt;Some people would suggest dropping the IB completely over this. They are plain wrong! It&amp;#8217;s okay to turn to code when things are not possible. Maybe the next version of Xcode will allow it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IB &amp;gt; Code&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To sum it up: use IB whenever possible, but do know how to build the same UI using code. You&amp;#8217;ll need both skills to create a killer, easy-to-maintain app.&lt;/p&gt;</description><link>http://berzniz.com/post/32597579083</link><guid>http://berzniz.com/post/32597579083</guid><pubDate>Sun, 30 Sep 2012 11:37:00 -0400</pubDate></item><item><title>Handling handlebars.js like a pro</title><description>&lt;p&gt;When I was looking for a javascript templating engine, I initially wanted to pick &lt;a href="http://mustache.github.com/"&gt;mustache.js&lt;/a&gt; for all templating needs. The syntax is ridiculously simple and it takes less than 5 minutes to integrate it.&lt;/p&gt;
&lt;p&gt;Then I heard about &lt;a href="http://handlebarsjs.com/"&gt;handlebars.js&lt;/a&gt; and the precompilation feature won me over. This should speed loading times for the end users.&lt;/p&gt;
&lt;p&gt;After playing with handlebars for a while, I wondered &lt;strong&gt;what&amp;#8217;s the best way to integrate it into our web app development cycle.&lt;/strong&gt; I googled, stackoverflowed, etc&amp;#8230; but surprisingly, I couldn&amp;#8217;t find decent information about the subject.&lt;/p&gt;
&lt;p&gt;I opened my sketch-book and wrote a few goals for integrating handlebars:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;No build/compile step for development.&lt;/li&gt;
&lt;li&gt;Production code will use precompiled templates.&lt;/li&gt;
&lt;li&gt;No code changes required when switching from development to production.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Now that I knew what I was looking for, It was time to analyze handlebars behavior and write some code.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Compiling templates at runtime&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The usage of handlebars consists of three steps: (1) reading a raw-template, (2) compiling it into a javascript function and (3) running the compiled-template with the desired arguments:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2900899"&gt;https://gist.github.com/2900899&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;This is suited for development, where raw templates are edited all the time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Precompiling templates&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The idea of precompiling templates is to eliminate step 2 from runtime. We do this by performing step 2 in an earlier build step called &lt;em&gt;precompilation&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When you precompile a template, the raw template must reside in its own file with the &lt;em&gt;.handlebars&lt;/em&gt; extension.&lt;/p&gt;
&lt;p&gt;For this example, I created a file named &lt;em&gt;hello.handlebars&lt;/em&gt; with the following conent:&lt;/p&gt;
&lt;p&gt;&amp;lt;p&amp;gt;Hello {{name}}&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;Running the handlebars compiler from the terminal is easy:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;handlebars hello.handlebars -f templates.js&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Include the output script (&lt;em&gt;templates.js&lt;/em&gt;) in the html file to get access to the templates. The templates are attached to the &lt;em&gt;handlebars.templates&lt;/em&gt; object. Since my file was named &lt;em&gt;&lt;strong&gt;hello&lt;/strong&gt;.handlebars&lt;/em&gt;, it will set the compiled template as the value of the &amp;#8216;hello&amp;#8217; key.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s how to use it:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2900902"&gt;https://gist.github.com/2900902&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;This is great for production code where templates aren&amp;#8217;t changing at all.&lt;/p&gt;
&lt;p&gt;The handlebars compiler can be used to compile multiple raw-template files into one &lt;em&gt;templates.js&lt;/em&gt; file. Place all your .handlebars files in one folder (let&amp;#8217;s name it &lt;em&gt;templatesfolder&lt;/em&gt;) and issue the following command:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;handlebars templatesfolder/ &amp;gt; &lt;/em&gt;&lt;em&gt;templatesfolder/&lt;/em&gt;&lt;em&gt;templates.js&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So if you have &lt;em&gt;hello.handlebars&lt;/em&gt;, &lt;em&gt;goodbye.handlebars&lt;/em&gt; and &lt;em&gt;you.handlebars&lt;/em&gt; in that folder, the output will be &lt;em&gt;Handlebars.templates[&amp;#8216;goodbye&amp;#8217;]&lt;/em&gt;, &lt;em&gt;Handlebars.templates[&amp;#8216;hello&amp;#8217;]&lt;/em&gt; and &lt;em&gt;Handlebars.templates[&amp;#8216;you&amp;#8217;]&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mixing it together&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How do we mix the development code with the production code?&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll create a wrapping method that returns the compiled version if it&amp;#8217;s available. otherwise, it will fetch it (read the input of the raw template file), compile it and return it to the caller.&lt;/p&gt;
&lt;p&gt;I call this function &lt;em&gt;getTemplate&lt;/em&gt; and It&amp;#8217;s going to be attached to the &lt;em&gt;Handlebars&lt;/em&gt; object. Let&amp;#8217;s see how the final code will use this function:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2900942"&gt;https://gist.github.com/2900942&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s implement the &lt;em&gt;getTemplate&lt;/em&gt; method in an &lt;strong&gt;empty&lt;/strong&gt; &lt;em&gt;templates.js&lt;/em&gt; file:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2900905"&gt;https://gist.github.com/2900905&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;There are a few things to note here:&lt;/p&gt;
&lt;p&gt;1. I used JQuery&amp;#8217;s GET method in a synchronized way since the caller is expecting the template as the return value. This will somewhat degrade performance, but only in development mode. Since most developers use their own localhost for development, you should not feel any difference.&lt;/p&gt;
&lt;p&gt;2. The use of jQuery&amp;#8217;s GET requires that you host your site on a local server and not from disc (meaning: http:// is good, but file:// isn&amp;#8217;t).&lt;/p&gt;
&lt;p&gt;3. Once a template has been compiled at runtime, it will be added to the &lt;em&gt;Handlebars.templates&lt;/em&gt; object (same way as the precompiled templates). The next time the template will be asked, the function will return it immediately.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wrapping it up&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So now that we have our &lt;em&gt;getTemplate&lt;/em&gt; method residing in the &lt;em&gt;templatesfolder/templates.js file&lt;/em&gt;, we need to precompile our templates and add them to the end of the &lt;em&gt;templates.js&lt;/em&gt; file:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;handlebars templatesfolder/&amp;#160;&amp;#187; templatesfolder/templates.js&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;templates.js&lt;/em&gt; file now contains both the &lt;em&gt;getTemplate&lt;/em&gt; method and all the compiled templates. When &lt;em&gt;getTemplate&lt;/em&gt; is called, it will already have all templates compiled under &lt;em&gt;Handlebars.templates&lt;/em&gt; and will not have to fetch/compile anything at runtime.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are four steps in order to get handlebars working:&lt;/p&gt;
&lt;p&gt;1. Include &lt;em&gt;templates.js&lt;/em&gt; in your html after the &lt;em&gt;handlebars.js&lt;/em&gt; script&lt;/p&gt;
&lt;p&gt;2. Use &lt;em&gt;getTemplate&lt;/em&gt; to get a compiled template.&lt;/p&gt;
&lt;p&gt;3. Run the handlebars precompiler before delivering build to production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A few more tips&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1. You can optimize the templates with the compiler options:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;handlebars &amp;lt;input&amp;gt; -f &amp;lt;output&amp;gt; -k each -k if -k unless&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;2. Since your templates are already precompiled, you can use the slimmer version of Handlebars (&lt;em&gt;handlebars.runtime.js&lt;/em&gt;) on your production. It has a smaller footprint and will load faster.&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;</description><link>http://berzniz.com/post/24743062344</link><guid>http://berzniz.com/post/24743062344</guid><pubDate>Sat, 09 Jun 2012 09:24:00 -0400</pubDate></item><item><title>The Android developer who made me a better iOS developer</title><description>&lt;p&gt;The iOS app I&amp;#8217;ve been working on lately was given a hugh feature redesign, making it beautiful but a bit more complex. I was happy with the result and how I overcame all the hurdles along the way.&lt;/p&gt;
&lt;p&gt;A few days later, right when the entire team was about to leave the office and head home for a long weekend break, the Android developer showed off the same redesign on his Android device.&lt;/p&gt;
&lt;p&gt;It all looked great and was blazingly fast and smooth. Much smoother than the experience on the iPhone. &lt;strong&gt;How did he do it?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I felt really bad. How didn&amp;#8217;t I notice the iPhone was lagging and non-smooth? How did I let this happen?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[One geeky paragraph ahead, skip it if you hate nerds]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So I sat down and started debugging the hell out of it. Am I using too many subviews? Are the table cells not cached? Are the text labels not opaque? Is the scroll-spying code slowing everything? After a bit of digging, I found out it was Core Data. Database reads were taking place while scrolling, and that&amp;#8217;s&amp;#8230; bad (and slow).&lt;/p&gt;
&lt;p&gt;I found the problem and fixed it. I now know there&amp;#8217;s plenty of other areas were I must ask myself if there&amp;#8217;s a better way to do it. Now&amp;#8217;s the time to fix myself.&lt;/p&gt;
&lt;p&gt;So thank you Mr. Android developer for making me sweat and work a little bit harder.&lt;/p&gt;</description><link>http://berzniz.com/post/23891196707</link><guid>http://berzniz.com/post/23891196707</guid><pubDate>Sun, 27 May 2012 18:47:50 -0400</pubDate></item><item><title>Booleans are free. Use them.</title><description>&lt;p&gt;Last week a co-worker asked me how I implemented a certain feature in our product. I couldn&amp;#8217;t really remember all the fine details of the implementation so I loaded the file into the editor and we sat to read it together.&lt;/p&gt;
&lt;p&gt;The code was actually good and I didn&amp;#8217;t feel I had to &amp;#8220;protect&amp;#8221; it by saying it was done under pressure and other excuses I use often. He read the code and said &amp;#8220;Oh, I see what you&amp;#8217;re doing here. Thanks!&amp;#8221;.&lt;/p&gt;
&lt;p&gt;The one thing that made the code super readable can be summarized by this programming tip:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Booleans are free. Use them.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an example:&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;Look at the following code:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2594221"&gt;https://gist.github.com/2594221&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Your brain has to concentrate on unimportant things like expressions, math and pixels in order to figure out (=guess) what the if statement is trying to do.&lt;/p&gt;
&lt;p&gt;This is much easier on the brain:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2594243"&gt;https://gist.github.com/2594243&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;This code is easier to read as the intention is &amp;#8220;injected&amp;#8221; into the code explicitly by naming the if statement with a boolean.&lt;/p&gt;
&lt;p&gt;An added bonus is making the surrounding comments obsolete (=delete them). The code is practically documenting itself.&lt;/p&gt;</description><link>http://berzniz.com/post/22378147919</link><guid>http://berzniz.com/post/22378147919</guid><pubDate>Fri, 04 May 2012 07:42:05 -0400</pubDate></item><item><title>Backbone.js global notifications</title><description>&lt;p&gt;I was looking for a way to allow two &lt;strong&gt;Backbone.Views&lt;/strong&gt; to exchange information between them.&lt;/p&gt;
&lt;p&gt;Here are some solutions to this problem:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. The bad idea&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We could just let them reference each other. Then &lt;strong&gt;view1&lt;/strong&gt; could say this.view2.doSomething() and it&amp;#8217;s the easiest way to solve this.&lt;/p&gt;
&lt;p&gt;However simple it may be, this will lead to a very tight &lt;a href="http://en.wikipedia.org/wiki/Coupling_(computer_programming)"&gt;coupling&lt;/a&gt; and a very bad design for our web app. If we have a circular dependency, we should probably rethink our design.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. The good idea (that doesn&amp;#8217;t always work)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;We could have a model and share it to both views. One view will bind to an event on the model, and when the other view does something important, the model can trigger the event.&lt;/p&gt;
&lt;p&gt;This is great except that a Backbone.View can only hold one Backbone.Model at a time. In many cases the two views will need to reference different models.&lt;/p&gt;
&lt;p&gt;(Yes. I know that a View can hold extra models by &amp;#8216;&lt;strong&gt;view.model2 = new Model()&lt;/strong&gt;&amp;#8217; but this seems to stray from the convention)&lt;/p&gt;
&lt;p&gt;Another weak point of this solution is that someone (probably the router, or a custom controller object) will have to create the model and hand it off to the two views. And if one of these views has subviews, we will have to pass it on to them and the chaos takes over.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. The better idea&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We could create a &lt;strong&gt;global notifications system&lt;/strong&gt; where any object can bind to global events and any object can trigger a global event.&lt;/p&gt;
&lt;p&gt;So instead of the first view registering for events triggered by the second view, it can register for global notifications.&lt;/p&gt;
&lt;p&gt;This can be easily done by adding a &lt;strong&gt;Backbone.Notifications&lt;/strong&gt; object:&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2045615"&gt;https://gist.github.com/2045615&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Now we can let the first view bind to a global event (in this example: &lt;strong&gt;SomeViewRendered&lt;/strong&gt;) and the second view can trigger it.&lt;/p&gt;
&lt;div class="gist"&gt;&lt;a href="https://gist.github.com/2025061"&gt;https://gist.github.com/2025061&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Seems to work, it&amp;#8217;s easy and it creates a very decoupled interface between the different Backbone objects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More uses&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We can also use this to ask the Backbone.Router object to navigate somewhere else without direct calling it. Something like this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Backbone.Notifications.trigger(&amp;#8216;navigateRequest&amp;#8217;, &amp;#8216;/task/50&amp;#8217;);&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A router can bind to this notification and act upon it. This allows any object to request anything from the system and if another object can provide it, it will magically happen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is this Neat or what? What do you think?&lt;/strong&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/19351578959</link><guid>http://berzniz.com/post/19351578959</guid><pubDate>Thu, 15 Mar 2012 14:23:00 -0400</pubDate><category>backbone</category></item><item><title>Adding custom Getters and Setters to Backbone models</title><description>&lt;p&gt;I started using &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt; for web development. It&amp;#8217;s a really great framework for structuring your javascript code.&lt;/p&gt;
&lt;p&gt;After digging in further, I figured out &lt;strong&gt;Backbone models are missing one important feature: custom Setters and Getters.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;Sure, you can add functions like &amp;#8220;getFullName&amp;#8221;, but Backbone internal functions (like .sync and the defaults hash) will never know about it.&lt;/p&gt;
&lt;p&gt;Fortunately, Backbone can be easily extended by writing plug-ins.&lt;/p&gt;
&lt;p&gt;So here&amp;#8217;s a &lt;strong&gt;plug-in that adds Getters and Setters to your Backbone.Model&lt;/strong&gt;(s), hosted by github:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/berzniz/backbone.getters.setters"&gt;&lt;a href="https://github.com/berzniz/backbone.getters.setters"&gt;https://github.com/berzniz/backbone.getters.setters&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This will allow you to define a function for each attribute&amp;#8217;s getter and setter.&lt;/p&gt;</description><link>http://berzniz.com/post/18143965960</link><guid>http://berzniz.com/post/18143965960</guid><pubDate>Thu, 23 Feb 2012 15:37:00 -0500</pubDate><category>backbone</category><category>getters</category><category>setters</category></item><item><title>Export your AppAnnie data</title><description>&lt;p&gt;I love &lt;a href="http://www.appannie.com"&gt;AppAnnie&lt;/a&gt;. If you don&amp;#8217;t know them, you should.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what AppAnnie say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;p&gt;More than 75,000 Apple App Store apps trust App Annie Analytics to track their downloads, sales and reviews completely for free. &lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;I am one of those 75,000 App owners who trust them with &lt;strong&gt;my data&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And if it is in fact &lt;strong&gt;my data&lt;/strong&gt;, then I should have the ability to export it to my computer, right?&lt;/p&gt;
&lt;p&gt;Well, not really. App Annie doesn&amp;#8217;t have this option. It doesn&amp;#8217;t even have an API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So let&amp;#8217;s hack together an &amp;#8220;Export API&amp;#8221; for them, shall we?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;!-- more --&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(&lt;strong&gt;Updated: &lt;/strong&gt;Thanks Nick for providing the new method in the comments.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;. Login to your AppAnnie account:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="https://www.appannie.com/account/login/" target="_blank"&gt;&lt;a href="https://www.appannie.com/account/login/"&gt;https://www.appannie.com/account/login/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;. After login, navigate to&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.appannie.com/care" title="https://www.appannie.com/care" target="_blank"&gt;&lt;a href="https://www.appannie.com/care"&gt;https://www.appannie.com/care&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;3. Choose an account and go to &amp;#8220;All Apps&amp;#8221; page.&lt;/p&gt;
&lt;p&gt;4. Take a look at the address, it should be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.appannie.com/sales/YOUR_ACCOUNT_ID"&gt;https://www.appannie.com/sales/YOUR_ACCOUNT_ID&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;5. You can get your revenue data by navigating to (replace YOUR_ACCOUNT_ID with your actual account ID from the previous step):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.appannie.com/sales/revenue_data/YOUR_ACCOUNT_ID/?type=revenue&amp;amp;s=2010-01-01&amp;amp;e=2013-01-01"&gt;https://www.appannie.com/sales/revenue_data/YOUR_ACCOUNT_ID/?type=revenue&amp;amp;s=2010-01-01&amp;amp;e=2013-01-01&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can get your units data by browsing to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.appannie.com/sales/units_data/YOUR_ACCOUNT_ID/?type=units&amp;amp;s=2010-01-01&amp;amp;e=2013-01-01"&gt;https://www.appannie.com/sales/units_data/YOUR_ACCOUNT_ID/?type=units&amp;amp;s=2010-01-01&amp;amp;e=2013-01-01&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As you can see, the time frame is set in the URL. I set it from 2010 to 2013 so I get some extra unimportant data, but you can change the dates to fit your needs.&lt;/p&gt;
&lt;p&gt;The result will be a &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON &lt;/a&gt;string. To be more precise, it is a JSON string followed by more data. Just look for a &lt;em&gt;&amp;#8220; &amp;#8212;end-data&amp;#8212;&amp;#8221; &lt;/em&gt;text and copy everything before it (excluding it) and you will have a valid JSON data.&lt;/p&gt;
&lt;p&gt;You can now paste it into a &lt;a href="http://jsonviewer.stack.hu/"&gt;JSON viewer&lt;/a&gt; to nicely view the reports.&lt;/p&gt;
&lt;p&gt;A few notes:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;You will need some coding skills to turn this JSON to an excel sheet. Not rocket science.&lt;/li&gt;
&lt;li&gt;If there is a demand, I can hook up a script to do all this for you (get the reports and turn them to an excel file with a single click).&lt;/li&gt;
&lt;li&gt;All the information in this post is current to the day of the posting, AppAnnie might change their URL or data structure at any time and this blog post will be obsolete.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Get your data while it&amp;#8217;s hot!&lt;/strong&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/15975242632</link><guid>http://berzniz.com/post/15975242632</guid><pubDate>Mon, 16 Jan 2012 18:35:00 -0500</pubDate></item><item><title>Don't be a liar! and 4 other tips for iOS graphic designers</title><description>&lt;p&gt;As an iOS developer I had the pleasure of teaming up with awesome graphic designers to create iPhone and iPad apps.&lt;/p&gt;
&lt;p&gt;I try not waste their time, and make sure they don&amp;#8217;t waste mine. So &lt;strong&gt;I came up with a list of tips that will keep us productive and happy&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re a designing for iOS, the following tips I shared with them will probably save you hours of work as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. &lt;/strong&gt;&lt;strong&gt;Don&amp;#8217;t be a liar!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;Nicholas Felton, the infographics guru who was behind the Facebook timeline design, &lt;a href="http://www.fastcodesign.com/1665414/designers-behind-facebook-timeline-5-lessons-for-creating-a-ui-with-soul"&gt;suggests&lt;/a&gt; to be honest with your mockups:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“As a designer, you have your baby that you want to try and sell. To make it saleable, you might pick someone who has really nice photos in their profile and use that to make your mockups, but you’re ultimately just lying to yourself and the rest of the group if you think everyone’s page is going to look like that.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the most important tip you must remember. When creating a screen mockup, imagine how it would look like when not all the information you wish to display is available.&lt;/p&gt;
&lt;p&gt;Why? Because real life data is mostly incomplete, too short or too long and will mess up your pretty designs. Research how the real life data looks like before(!) you launch photoshop and make designs that flatter the real life data.&lt;/p&gt;
&lt;p&gt;Once you stop being a liar we can progress to some specific iOS related tips&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Sit with an iPhone developer at least once&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;After designing the first screen of the app, ask me to sit down with you and show you how I turn your static graphics into a living app. Ask me to open up XCode interface builder (the tool for creating iOS user interfaces) and see how your graphics are applied in real time.&lt;/p&gt;
&lt;p&gt;Your graphics will have to be turned into buttons, labels, text-area and other controls. It will be a good idea to get familiar with the work needed to be done in order to turn your graphics into a living app.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;ll sit with me, I&amp;#8217;ll show you that buttons have 3 states (normal, highlighted and selected) each needing a different graphic, that every text on screen must be defined with font/color/decoration/size and many other helpful information.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Generalize your art&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If your design includes a few buttons with the same style, but different labels (&amp;#8220;Done&amp;#8221;, &amp;#8220;Go&amp;#8221;, &amp;#8220;Cancel&amp;#8221;, etc.) you can just drop the label and deliver one blank button.&lt;/p&gt;
&lt;p&gt;As a developer, I prefer using a blank button and attaching the label to it myself. This allows me to create a &amp;#8220;Search&amp;#8221; button without emailing you and asking for a new &amp;#8220;Search&amp;#8221; button. &lt;strong&gt;Less work for you.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t forget to tell me which font should be used for the label of the button, or I&amp;#8217;ll have to use Comic Sans just to piss you off&amp;#8230;&lt;/p&gt;
&lt;p&gt;Go with this concept further, if you have the same graphics repeating with a small change in each one, you should generalize it. I will add the finishing touch myself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Fonts and placement&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m an idiot, I need to be told exactly what to do. If I get a graphic design from you with a title on the top, I must know a few things: what font is used? is it bold? what RGB color is this? and some more.&lt;/p&gt;
&lt;p&gt;To answer my questions, please add an accompanying text file that looks like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The title on the top is Helvetica Bold, 17.0px in size, the RGB color is #FFBBGG and it&amp;#8217;s placed 15px from the top and should be centered horizontally.&lt;/p&gt;
&lt;p&gt;The name of the song is Helvetica, 12.0px in size, the RGB color is #FFFAAA and it&amp;#8217;s placed 5px from the top and 25px from the left.&lt;/p&gt;
&lt;p&gt;And so on&amp;#8230;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;5. Delivering your files&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m lazy. All I really want to do is take your files and add them to the project. In order to do that, here are my demands:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Organize.&lt;/strong&gt;&lt;br/&gt;Each screen should have it&amp;#8217;s own folder with the screen&amp;#8217;s name. Each folder should have a screenshot of the whole screen so I will understand how the final result should look like. The rest of the files in this folder are the elements cut into pieces: buttons, cells, borders, whatever, each separately in its own file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be consistent.&lt;/strong&gt;&lt;br/&gt;All graphic files must be PNGs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Understand iOS graphics.&lt;br/&gt;&lt;/strong&gt;Each graphic file must have two versions: an high-res version and a low-res version. The first version will be used for iPhones with retina display (iPhone 4 and later) and the second version for non-retina display devices (older iPhones and iPads).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name Clearly&lt;/strong&gt;.&lt;br/&gt;The low-res version should have a good descriptive name such as BigBlueButtonNormalState.PNG and the high-res version should have the same name with a @2x suffix: BigBlueButtonNormalState@2x.PNG - The @2x suffix is read by the iPhone and used if retina display is available.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Size correctly.&lt;/strong&gt;&lt;br/&gt;The high-res version must be double the size of the low-res version. If the low-res version is 100x150 pixels then the high-res must be 200x300 pixels. Now I know you create the high-res version first and then downscale it, so just make sure your high-res version is even (width has even number of pixels and so does the height).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;These demands are tough, but &lt;strong&gt;will earn you the &amp;#8220;Best designer ever&amp;#8221; badge&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thank You for being awesome!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Designers are always awesome when applying these tips. &lt;strong&gt;Be awesome!&lt;/strong&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/14669116083</link><guid>http://berzniz.com/post/14669116083</guid><pubDate>Fri, 23 Dec 2011 08:58:00 -0500</pubDate></item><item><title>Don't call yourself an iOS developer if you don't know these tools</title><description>&lt;p&gt;Here are 4 tools out of my iOS development toolbox. They&amp;#8217;re all free and great!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unretiner&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Are you developing retina aware software? If so, you probably know that you should use two versions of each image resource in your app. An high-resolution version with a name of &lt;em&gt;image@2x.png&lt;/em&gt; and a low-resolution with a name of &lt;em&gt;image.png&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://itunes.apple.com/us/app/unretina/id411277085?mt=12"&gt;Unretiner&lt;/a&gt; will take an high-resolution image and create the low-resolution image for you automatically. Just drag the images (click the + button if you&amp;#8217;re developing on Lion, dragging has a bug) and get the resources already renamed for you. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;!-- more --&gt;MOGenerator&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Core Data can sometimes be hard to manage, especially creating and updating Obj-C objects for your custom entities. &lt;a href="http://rentzsch.github.com/mogenerator/"&gt;MOGenerator &lt;/a&gt;will change all that by creating the objects for you.&lt;/p&gt;
&lt;p&gt;The best part is the separation of machine-objects and human-objects. Let MOGenerator manage the machine object and focus on the logic of your app in the human readable objects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OCMock&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re into testing your code (good for you!) then you&amp;#8217;ll probably like &lt;a href="http://ocmock.org/"&gt;OCMock&lt;/a&gt; very much. With a few lines of added code you can take your regular class and replace methods with test-methods, verify that specific methods are getting called and much more.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MadRuby&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This app has nothing to do with iOS development directly, but it is very helpful. &lt;a href="http://www.wingsforpigs.com/MadRuby/MadRuby.html"&gt;MadRuby&lt;/a&gt; is a keyboard macro recorder. You can use it to record your keyboard clicks and then play them back multiple times.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Know other tools?&lt;/strong&gt; Let me know.&lt;/p&gt;</description><link>http://berzniz.com/post/14082452670</link><guid>http://berzniz.com/post/14082452670</guid><pubDate>Sun, 11 Dec 2011 16:19:00 -0500</pubDate></item><item><title>Learning is not (just) reading blogs</title><description>&lt;p&gt;I spend a lot of time on the web reading great blogs. I like to read anything about technology, from founder&amp;#8217;s stories for inspiration to low-level technical articles.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s a good way to learn about new trends and get new ideas, but the only way to learn a new skill is by doing.&lt;/p&gt;
&lt;p&gt;I also believe that the best way to learn anything is to actually create something useful and not just an &amp;#8220;Hello world&amp;#8221; half functioning program. Creating a small product will push you to dive deeper and the end result is you&amp;#8217;ll learn more.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s why I love spending some of my free time to hack small side-projects. About six months ago I set my goal at creating an iPad app that will be &lt;strong&gt;super-fun&lt;/strong&gt; to use. I decided to create a web browser that would suck less than Mobile Safari.&lt;/p&gt;
&lt;p&gt;The idea was to load webpages blazingly fast by throwing away unneeded content like, let&amp;#8217;s say, images and advertisements. The end result was &lt;a href="http://browseBear" title="BrowseBear" target="_self"&gt;BrowseBear&lt;/a&gt; and it was released for free.&lt;/p&gt;
&lt;p&gt;It wasn&amp;#8217;t very successful since it doesn&amp;#8217;t, well, render webpages, but it still got some kick-ass reviews on the App Store.&lt;/p&gt;
&lt;blockquote&gt;&amp;#8220;&lt;strong&gt;Great!&lt;/strong&gt; - Only app I have found which truly does speed up browsing times, it has replaced safari&amp;#8217;s place in my iPad :) (sorry safari!)&amp;#8221;&lt;/blockquote&gt;
&lt;blockquote&gt;&amp;#8220;&lt;strong&gt;UnBEARable not to have&lt;/strong&gt; - DOWNLOAD THIS APP. IT&amp;#8217;S COMPLETELY WORTH THE $0.00 I PAID&amp;#8221;&lt;/blockquote&gt;
&lt;p&gt;The most important thing was that I had fun making it and it helped me learn new iPhone development skills. I use these skills on a daily basis at the start-up I work for.&lt;/p&gt;
&lt;p&gt;One thing I need to do more is push myself to languages and platforms I&amp;#8217;m not familiar with. The next time I take a shower and have an idea, I&amp;#8217;ll sit down and implement it with a technology I don&amp;#8217;t know.&lt;/p&gt;
&lt;p&gt;Take the time to read the web, but leave some time for real learning by doing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Go Do!&lt;/strong&gt;&lt;/p&gt;</description><link>http://berzniz.com/post/12565738668</link><guid>http://berzniz.com/post/12565738668</guid><pubDate>Tue, 06 Dec 2011 16:37:28 -0500</pubDate></item><item><title>Breaking the rules is allowed</title><description>&lt;p&gt;If you&amp;#8217;re not into programming, stop reading this post now.&lt;/p&gt;
&lt;p&gt;A few weeks ago I showed my code to a colleague and as always, I knew exactly where my code was great and when it was a complete mess. My friend shared some programming tips and I enjoyed the code-review and learned from it.&lt;/p&gt;
&lt;p&gt;However, we got into one disagreement: every method in my code tries to &amp;#8220;Fail fast&amp;#8221; and exit as quickly as possible. Just as I was failing non programmers on the first line of this blog post above.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;Failing fast means you&amp;#8217;ll see many &lt;em&gt;return&lt;/em&gt; statements in any function I write. He claimed that it&amp;#8217;s a convention and a known coding standard to use one and only &lt;em&gt;return&lt;/em&gt; statement in each method. &amp;#8220;Just ask anybody.&amp;#8221; he said.&lt;/p&gt;
&lt;p&gt;I couldn&amp;#8217;t disagree more, but I thought it would be a good idea to ask the community over at &lt;a href="http://www.stackoverflow.com"&gt;stackoverflow&lt;/a&gt;. As always somebody already &lt;a href="http://stackoverflow.com/questions/1701686/why-should-methods-have-a-single-entry-and-exit-points"&gt;asked that&lt;/a&gt;, &lt;a href="http://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement"&gt;more&lt;/a&gt; &lt;a href="http://stackoverflow.com/questions/4838828/why-should-a-function-have-only-one-exit-point"&gt;than&lt;/a&gt; &lt;a href="http://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement"&gt;once&lt;/a&gt;. There isn&amp;#8217;t a definite answer there, but the general idea is that this rule was correct for older programming languages.&lt;/p&gt;
&lt;p&gt;The goal of coding rules is to make programming easier. And by that I mean reading and maintaining the code should be as simple as possible. If a rule tells me to do the opposite, I break it.&lt;/p&gt;
&lt;p&gt;Rules get old as programming languages evolve. Evolve with them and break the old rules.&lt;/p&gt;</description><link>http://berzniz.com/post/13700524051</link><guid>http://berzniz.com/post/13700524051</guid><pubDate>Sat, 03 Dec 2011 18:39:00 -0500</pubDate></item><item><title>Not having fun? You probably need a new job</title><description>&lt;p&gt;I remember creating my first computer game at the age of 11.&lt;/p&gt;
&lt;p&gt;The game was an *amazing* simulated football game, programmed in &lt;a href="http://en.wikipedia.org/wiki/Atari_BASIC"&gt;Basic&lt;/a&gt; on my beloved Atari. Essentially, it was a black screen with a timer running up to 90 (simulated) minutes. Footy events like goals, free kicks and red cards were randomly plotted to the screen.&lt;/p&gt;
&lt;p&gt;I was the only one to ever play it, but even so, I was very excited. I actually had an idea for something, I convinced myself I could pull it off and so I did. Above all, I had fun programming it. About &lt;a href="http://www.youtube.com/watch?v=EbVKWCpNFhY"&gt;11&lt;/a&gt; in a scale of 1 to 10.&lt;/p&gt;
&lt;p&gt;Soon later I found out about &lt;a href="http://en.wikipedia.org/wiki/Championship_Manager"&gt;Championship Manager&lt;/a&gt;, a game with the same basic idea, which quickly became my favorite computer game.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m now a grown-up myself (and act as one most of the time), finished university and spent a few years working for a big software company. I developed solutions for un-trivial problems while working there and was always proud of the result, but something was missing. I missed the fun-factor of programming.&lt;/p&gt;
&lt;p&gt;I recently joined a small startup writing it&amp;#8217;s first lines of code for a new awesome product. When I sat down to write the first line of code I realized something. Developing new software for a company is much like hacking a small video game when you&amp;#8217;re eleven.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s an idea, you visualize how it can be done and you do it. Starting with an empty project and growing it into a product people love. It felt just like those Atari hacking hours after school when I was a kid. The &lt;strong&gt;fun-factor&lt;/strong&gt; was back.&lt;/p&gt;
&lt;p&gt;It was fun clicking that &amp;#8220;New Project&amp;#8230;&amp;#8221; button in my editor. It was fun seeing the product come to life. It was fun seeing the first user signs up for our system. It was fun spotting people use the product in real life and it&amp;#8217;s fun getting great feedback about it from our users.&lt;/p&gt;
&lt;p&gt;How much fun are you having at work? if it&amp;#8217;s somewhere below 11, you might need to find a new job.&lt;/p&gt;</description><link>http://berzniz.com/post/13348931777</link><guid>http://berzniz.com/post/13348931777</guid><pubDate>Sat, 26 Nov 2011 10:08:20 -0500</pubDate></item></channel></rss>
