<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>Adrian Kosmaczewski &#187; Code</title> <atom:link href="http://kosmaczewski.net/category/code/feed/" rel="self" type="application/rss+xml" /><link>http://kosmaczewski.net</link> <description></description> <lastBuildDate>Wed, 08 Feb 2012 08:51:50 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Del.icio.us to WordPress</title><link>http://kosmaczewski.net/del-icio-us-to-wordpress/</link> <comments>http://kosmaczewski.net/del-icio-us-to-wordpress/#comments</comments> <pubDate>Mon, 28 Dec 2009 10:44:59 +0000</pubDate> <dc:creator>Adrian</dc:creator> <category><![CDATA[Blogs]]></category> <category><![CDATA[Code]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[cron]]></category> <category><![CDATA[del.icio.us]]></category> <category><![CDATA[Ruby]]></category> <category><![CDATA[wordpress]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=2157</guid> <description><![CDATA[I&#8217;ve just uploaded a new project on Github called delicious_wp: it&#8217;s a small Ruby script that simply fetches the items stored in del.icio.us the previous week and creates a blog post with them. You can set up a small cron &#8230; <a
href="http://kosmaczewski.net/del-icio-us-to-wordpress/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>I&#8217;ve just uploaded a new project on Github called <a
target="_blank" href="http://github.com/akosma/delicious_wp">delicious_wp</a>: it&#8217;s a small Ruby script that simply fetches the items stored in del.icio.us the previous week and creates a blog post with them. You can set up a small cron job to execute this script every week, which is what I&#8217;ve done for this blog :) I know del.icio.us has a similar feature integrated, but it executes daily, instead of weekly, which is what I wanted.</p><p>To use it, just clone the repository, copy the config.yaml.sample file as config.yaml and edit its values inside. Run the script and voilà! A new blog post entry with your del.icio.us bookmarks.</p><p>The script can also be helpful to those wondering how to use the XML-RPC interface of WordPress from a Ruby script, or how to use the Net::HTTP library to consume a REST API.</p><p>[source:ruby]
def get_delicious_bookmarks
# Connect to delicious and get updates
http = Net::HTTP.new(DELICIOUS_SERVER, DELICIOUS_PORT)
http.use_ssl = true
req = Net::HTTP::Get.new(DELICIOUS_DATES_PATH)
req.add_field(&#8220;User-Agent&#8221;, DELICIOUS_USER_AGENT)
req.basic_auth username, password
response = http.request(req)
results = response.body
[/source]</p><p>[source:ruby]
def post_to_wordpress(title, text)
entry = {
:title => title,
:description => text
}
# Connect to WordPress using the XML-RPC interface
blog = XMLRPC::Client.new(server, path, port)
blog.call(&#8220;metaWeblog.newPost&#8221;, blogid, username,
password, entry, true)
[/source]</p><p>Enjoy! As usual, the code is released with a BSD license.</p> ]]></content:encoded> <wfw:commentRss>http://kosmaczewski.net/del-icio-us-to-wordpress/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Thoughts about Google&#8217;s &#8220;Go&#8221; Programming Language</title><link>http://kosmaczewski.net/thoughts-about-googles-go-programming-language/</link> <comments>http://kosmaczewski.net/thoughts-about-googles-go-programming-language/#comments</comments> <pubDate>Thu, 12 Nov 2009 10:40:51 +0000</pubDate> <dc:creator>Adrian</dc:creator> <category><![CDATA[Code]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[Software]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=2081</guid> <description><![CDATA[Historically, we can distinguish really big software companies for providing, at least, four major kinds of products: an operating system (sometimes open sourced at a certain level), a web browser (with various degrees of standard compliance), a suite of office &#8230; <a
href="http://kosmaczewski.net/thoughts-about-googles-go-programming-language/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Historically, we can distinguish really big software companies for providing, at least, four major kinds of products: an operating system (sometimes open sourced at a certain level), a web browser (with various degrees of standard compliance), a suite of office applications (slightly compatible with everyone else&#8217;s), and a programming language with curly brackets (generally incompatible with everything else). In that particular order, we have:</p><ul><li><strong>Microsoft:</strong> Windows, Internet Explorer, Microsoft Office, and C#.</li><li><strong>Sun:</strong> Solaris, HotJava (sic), StarOffice, and Java.</li><li><strong>Apple:</strong> Mac OS X, Safari, iWork, and Objective-C.</li><li><strong>Google:</strong> Chrome OS, Chrome, Google Docs, and&#8230; Go.</li></ul><p>Precisely, <a
href="http://golang.org/">Go</a> was the last piece that Google had to create in order to fit into the framework above. And it did, with a bright team including Ken Thompson (of Unix and C fame) and Rob Pike (of Plan 9 and UTF-8 fame). With names like that, and with Google&#8217;s own funding and infrastructure, it is normal that the media went into a hype frenzy yesterday.</p><p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/11/bumper480x270.png" alt="bumper480x270" title="bumper480x270" width="480" height="270" class="alignnone size-full wp-image-2093" /></p><p>I think, however, that Google&#8217;s engineers got tired of what the current and upcoming versions of their &#8220;official&#8221; programming languages (Java 7, C++0x and Python 3.0) had to offer, and simply came up with a programming language that fits better their needs and expectations. As <a
href="http://golang.org/doc/go_talk-20091030.pdf">one of the slides</a> of the <a
href="http://www.youtube.com/watch?v=rKnDgT73v8s">TechTalk</a> says, with current languages &#8220;You can be productive or safe, not both.&#8221;</p><p>Features like built-in support for concurrency or garbage collection hide the real true feature behind the language: faster build times with static typing support. This is important for Google from a software economy point of view: they want more productivity from their developers, or, in other words, more bang for their buck, all together with verifiable quality and speed of execution. Go seems to be designed to deliver in these areas. However, Rob Pike is careful to say that the language is experimental, so time will tell if their efforts were worth it.</p><p>In any case, it is worth noting that there was a <a
href="http://en.wikipedia.org/wiki/Go!_(programming_language)">previous programming language called Go!</a> (whose author even wrote a <a
href="http://www.lulu.com/content/paperback-book/lets-go/641689">book about it</a>), and after an <a
href="http://www.informationweek.com/news/software/web_services/showArticle.jhtml?articleID=221601351">InformationWeek article</a> revealed this, <a
href="http://code.google.com/p/go/issues/detail?id=9">a petition has started in the Go bug tracking</a>, asking Google to change the name of the language, all in the name of Google&#8217;s own &#8220;Don&#8217;t be evil&#8221; motto.</p> ]]></content:encoded> <wfw:commentRss>http://kosmaczewski.net/thoughts-about-googles-go-programming-language/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Discovering a Hidden iPhone URL Scheme</title><link>http://kosmaczewski.net/discovering-a-hidden-iphone-url-scheme/</link> <comments>http://kosmaczewski.net/discovering-a-hidden-iphone-url-scheme/#comments</comments> <pubDate>Tue, 04 Aug 2009 05:55:09 +0000</pubDate> <dc:creator>Adrian</dc:creator> <category><![CDATA[Code]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Software]]></category> <category><![CDATA[project]]></category> <category><![CDATA[Twitter]]></category> <category><![CDATA[Xcode]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1779</guid> <description><![CDATA[As an iPhone developer, one of the simplest and easiest mechanisms you have to interact with other applications is through the use of iPhone URL Schemes. These are so important that I&#8217;ve created a wiki page where I keep track &#8230; <a
href="http://kosmaczewski.net/discovering-a-hidden-iphone-url-scheme/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>As an iPhone developer, one of the simplest and easiest mechanisms you have to interact with other applications is through the use of iPhone URL Schemes. These are so important that <a
href="http://wiki.akosma.com/IPhone_URL_Schemes">I&#8217;ve created a wiki page</a> where I keep track of those I come across, including code samples that help me exchange data with them.</p><p
align="center"><img
src="http://kosmaczewski.net/wp-content/uploads/2009/08/xcode.png" alt="xcode" title="xcode" width="256" height="256" class="alignnone size-full wp-image-1801" /></p><p>However, not all editors document the URL schemes they support in their apps, and this blocks reuse and collaboration. I recently came into such a problem, trying to use <a
href="http://twitterfon.net/">TwitterFon</a> from my own apps, to post messages to Twitter. The TwitterFon site <a
href="http://twitterfon.net/how-to-use.html">only specifies</a> the following iPhone URL scheme:</p><p><code>twitterfon:///post?this%20is%20a%20test</code></p><p>The problem is, this URL scheme does not perform an URL-decoding on the message parameter, which means that a phrase like &#8220;this is a test&#8221; will appear in TwitterFon URL-encoded, that is, as &#8220;this%20is%20a%20test&#8221;. Clearly not acceptable.</p><p>However, thanks to <a
href="http://twitter.com/ashleymills/status/3104409559">Ashley Mills</a>, I learnt that the <a
href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=300669003&#038;mt=8">USA Today</a> iPhone app is able to use TwitterFon to share articles via Twitter, and does this properly, without URL-encoded characters. How do they do that? Obviously, they are using an URL scheme exported by TwitterFon, but not documented anywhere (*). I finally discovered that the URL scheme sought is the following (&#8220;message&#8221; instead of &#8220;post&#8221;!):</p><p><code>twitterfon:///message?some%20text%20here</code></p><p>This is how I found out: I impersonated TwitterFon in my own iPhone with an ad-hoc app created in Xcode, that shows me the URL used by USA Today to launch TwitterFon. <span
id="more-1779"></span> These are the steps required:</p><ol><li>Open iTunes and look for the application whose URL schemes you&#8217;re interested in (in my case, TwitterFon Pro); right click on it and select &#8220;Show in Finder&#8221;;</li><li>Duplicate the .ipa file in the Finder and change its extension to .zip &#8211; yes, .ipa applications are simply compressed .zip files;</li><li>Uncompress the .zip file and open the folder; inside, navigate to the &#8220;Payload&#8221; folder, and right-click on the .app file inside; select &#8220;Show Package Contents&#8221;;</li><li>Browse inside the package and open the Info.plist file; inside, you&#8217;ll find two keys that are interesting for us: <strong>CFBundleURLTypes</strong> (&#8220;URL types&#8221;) and <strong>CFBundleIdentifier</strong> (&#8220;Bundle identifier&#8221;). Select them and copy them to your clipboard;</li><li>Create a new Xcode application, using the &#8220;iPhone OS / View-based application&#8221; template;</li><li>Open the Info.plist file corresponding to the default target and remove the existing CFBundleIdentifier (&#8220;Bundle identifier&#8221;) key; paste the two items you&#8217;ve copied in the previous step &#8211; this means we&#8217;re creating an application that will &#8220;impersonate&#8221; itself as the &#8220;real&#8221; one;</li><li>Modify the new Xcode project&#8217;s app delegate adding the following method:
[source:c]
- (BOOL)application:(UIApplication *)application
handleOpenURL:(NSURL *)url
{
viewController.viewer.text = [url absoluteString];
return YES;
}
[/source]</li><li>Add a UITextView to your viewController (you can do this easily in Interface Builder, editing the .xib file), and expose it through a public property (called &#8220;viewer&#8221; above) so that the app delegate can access it;</li><li>Prepare your Xcode project for ad-hoc deployment: add a &#8220;distribution&#8221; configuration, an entitlements.plist file, etc;</li><li>Plug your iPhone, select &#8220;Distribution / iPhone OS Device&#8221;, and &#8220;Run&#8221; your application; the application will build and Xcode will install it into your device. <strong>ATTENTION: this application will overwrite the original one!</strong> This is because it has the same bundle identifier. Be sure to backup your data before doing this, as it will be lost completely;</li><li>Now run the application calling the one you impersonate (in this case, the USA Today one) and force it to call the &#8220;impersonated&#8221; application (in this case, by &#8220;sharing&#8221; an article via Twitter). This will trigger the launch of the impersonated application, the call to application:handleOpenURL:, which itself will display the calling URL on the iPhone screen.</li></ol><p>You can download a <a
href='http://kosmaczewski.net/wp-content/uploads/2009/08/Fake.zip'>zip file with the Xcode project</a> created above if you want. Be careful if you run it on your own device!</p><p>Voilà! Finally, delete your own impersonated app, go to the App Store, re-install the application you&#8217;ve impersonated (normally it&#8217;s a free download, even for non-free apps), and you are done. The same mechanism could be used to find out similar, hidden URL mechanisms in other apps.</p><p>(*) Actually this URL scheme is <a
href="http://twitterfon.net/changes.html">only shortly mentioned in the changelog</a> of the application&#8230;</p> ]]></content:encoded> <wfw:commentRss>http://kosmaczewski.net/discovering-a-hidden-iphone-url-scheme/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Code Organization in Xcode Projects</title><link>http://akosma.com/2009/07/28/code-organization-in-xcode-projects/</link> <comments>http://akosma.com/2009/07/28/code-organization-in-xcode-projects/#comments</comments> <pubDate>Tue, 28 Jul 2009 16:01:50 +0000</pubDate> <dc:creator>akosma software</dc:creator> <category><![CDATA[Architecture]]></category> <category><![CDATA[Code]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[Xcode]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1710</guid> <description><![CDATA[Xcode does not impose any structure to your source code tree. This is both cool and useful to quickly throw a couple of lines for a prototype, but in my experience, this approach does not scale. More often than not, &#8230; <a
href="http://akosma.com/2009/07/28/code-organization-in-xcode-projects/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Xcode does not impose any structure to your source code tree. This is both cool and useful to quickly throw a couple of lines for a prototype, but in my experience, this approach does not scale. More often than not, without any hygiene, your project can become a mess. Just using Xcode defaults, after a while your resources will sit beside your .xcodeproj file, all the project classes will be thrown together in the Classes folder, and if you have a relatively large project, this approach makes finding individual files painful.</p><p>Of course, Xcode provides &#8220;Groups&#8221; to organize your source code, but the idea is to be able to quickly identify the different kind of files that make up your Xcode project, either for Mac or for the iPhone, without having to open the Xcode project file. This means having both a folder structure, and an internal source code file structure. All of this will help you maintain your project in the future, which means cheaper costs, and less time spent looking for bugs.</p><p>All of this is also particularly useful when browsing projects via Google Code, Github or any other kind of file view of source code repositories. If your code is organized in a nice folder structure, it is easier to explore than if all the files sit in the same folder.</p><p>In this post I will enumerate some best practices that I use in all of my projects. <span
id="more-1710"></span> So let&#8217;s say that you start a new Xcode project. Here&#8217;s the Xcode window that is presented to you (seen in &#8220;Condensed&#8221; mode, which is the one I prefer):</p><p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/1.png" alt="1" title="1" width="501" height="555" class="alignnone size-full wp-image-1671" /></p><p>This is the project layout as seen in the Finder:</p><p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/0.png" alt="0" title="0" width="550" height="266" class="alignnone size-full wp-image-1677" /></p><p>As you can see (and as you might have experienced), in the default layout used by Xcode, all new source code files will be thrown into the &#8220;Classes&#8221; folder, while all the new Resources will be just stored in the project root. In the long term, this layout can be really painful to deal with. So let&#8217;s just start rearranging things a bit:</p><h3>Organize source files in folders and mirror them in Xcode</h3><p>When I start a new Xcode project, I usually do the following:</p><ol><li>I remove the &#8220;Classes&#8221; group (just deleting references, not moving the items to the trash, as shown in the image below) <img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/2.png" alt="2" title="2" width="500" height="122" class="alignnone size-full wp-image-1680" /></li><li>Then I add the following subfolders to the &#8220;Classes&#8221; folder:<ul><li>AppDelegate</li><li>Controllers</li><li>Models</li><li>Helpers</li></ul></li><li>Finally,  drag the enhanced “Classes” folder from the Finder to the Xcode project window, asking to “recursively create groups for every subfolder”: <img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/3.png" alt="3" title="3" width="414" height="388" class="alignnone size-full wp-image-1673" /></li></ol><h3>Create separate folders for different Resource elements</h3><p>The next step is to actually create a resource folder in Finder, and add a subfolder for every kind of resource that my project will use: sounds, images, SQLite databases, NIBs, etc. Then I do the following:</p><ol><li>Remove the Resource group from the Xcode project (just deleting references)</li><li>Then I drag the newly created &#8220;Resources&#8221; folder from the Finder to the Xcode project window, asking to &#8220;recursively create groups for every subfolder&#8221;, like we did for the &#8220;Classes&#8221; folder.</li></ol><p>Doing this has an interesting side effect: when you localize your application in other languages, each folder will contain a subfolder with the localized resources inside (for example, an &#8220;en.lproj&#8221; for English, &#8220;es.lproj&#8221; for Spanish, and so on).</p><h3>Organize your code consistently</h3><p>Each @implementation *.m file should always present methods in this order:</p><ol><li>init and dealloc</li><li>public methods</li><li>public @dynamic properties</li><li>delegate methods (for each supported protocol)</li><li>private methods</li></ol><h3>Use #pragma statements to separate the regions shown above</h3><p>Each logic group of methods should be separated from each other using the following lines (just type &#8220;#p&#8221; and hit the TAB key in Xcode!):
[source:c:firstline(79)]
// &#8230;
return cell;
}</p><h1>pragma mark -</h1><h1>pragma mark UIAlertViewDelegate methods</h1><ul><li>(void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex
{
// &#8230;
[/source]
The advantage of this approach is that later, you can use those #pragma marks to generate an automatic layout in the symbols pop-up of Xcode: <img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/6.png" alt="6" title="6" width="305" height="342" class="alignnone size-full wp-image-1687" /></li></ul><p>You can get this pop-up window clicking on this sector of your Xcode window: <img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/7.png" alt="7" title="7" width="438" height="156" class="alignnone size-full wp-image-1688" /></p><h3>Only leave public methods in the header files</h3><p>This means putting private methods definitions in a (Private) category on top of the *.m file. This will remove all compiler warnings (about &#8220;this class might not respond to this selector&#8221;) and will cleanly separate what&#8217;s public from what&#8217;s not:
[source:c:firstline(9)]</p><h1>import &#8220;UntitledViewController.h&#8221;</h1><p>@interface UntitledViewController (Private)
- (id)returnPrivateObject;
- (void)changeInternalState:(NSString *)param;
@end</p><p>@implementation UntitledViewController</p><ul><li>(id)init
{
[/source]</li></ul><h3> Use consistent coding conventions</h3><p><a
href="http://wiki.akosma.com/Objective-C_Code_Standards">You can use my own</a>, if you wish.</p><h3>Treat warnings as errors</h3><p><a
href="/2009/07/16/objective-c-compiler-warnings/">I&#8217;ve said a lot about that in a previous post</a>, but here&#8217;s a quick reminder:</p><p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/4.png" alt="4" title="4" width="500" height="572" class="alignnone size-full wp-image-1681" /></p><h3>Create &#8220;Distribution&#8221; configurations for the new project</h3><p>Duplicate the &#8220;Release&#8221; configuration and create two new ones: &#8220;Distribution Ad Hoc&#8221; and &#8220;Distribution App Store&#8221;. Each one will have to be configured with their corresponding provisioning profiles.</p><h3>Add an &#8220;Entiitlements.plist&#8221; file to the project</h3><p>Remember to uncheck (disable, turn off) the &#8220;get-task-allow&#8221; value (I still don&#8217;t understand why every Xcode project does not create this file automatically). Then add the &#8220;Entitlements.plist&#8221; value to the corresponding key in the &#8220;distribution&#8221; configurations created in the previous step.</p><h3>Use source control</h3><p>As soon as your project source tree is ready, commit it to your repository, whichever this is.</li></ul></p><h3>Conclusion</h3><p>This is how the final project might look like:</p><p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/5.png" alt="5" title="5" width="501" height="593" class="alignnone size-full wp-image-1675" /></p><p>Of course,  you might as well enforce the above best practices using your own default project templates; depending on your requirements, this might be a useful thing to do. You must store those new Xcode templates in the following locations:</p><ul><li><strong>iPhone:</strong> /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Project Templates</li><li><strong>Mac:</strong> /Developer/Library/Xcode/Project Templates</li></ul><p>Hope this helps! As usual, feel free to add your comments, best practices, rants and other reactions in the comments section below.</p> ]]></content:encoded> <wfw:commentRss>http://akosma.com/2009/07/28/code-organization-in-xcode-projects/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Objective-C Compiler Warnings</title><link>http://akosma.com/2009/07/16/objective-c-compiler-warnings/</link> <comments>http://akosma.com/2009/07/16/objective-c-compiler-warnings/#comments</comments> <pubDate>Thu, 16 Jul 2009 12:11:57 +0000</pubDate> <dc:creator>akosma software</dc:creator> <category><![CDATA[Code]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[Quality]]></category> <category><![CDATA[Cocoa]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1633</guid> <description><![CDATA[A recent comment by Joe D&#8217;Andrea in a previous post reminded me about the importance of removing compiler warnings in Xcode projects. Most importantly, it reminded me of a conversation with a fellow developer a couple of weeks ago, in &#8230; <a
href="http://akosma.com/2009/07/16/objective-c-compiler-warnings/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>A <a
href="http://kosmaczewski.net/2009/06/24/opengl-es-2-on-iphone-os-3/#comment-26078">recent comment</a> by <a
href="http://twitter.com/jdandrea">Joe D&#8217;Andrea</a> in a <a
href="http://kosmaczewski.net/2009/06/24/opengl-es-2-on-iphone-os-3/">previous post</a> reminded me about the importance of removing compiler warnings in Xcode projects. Most importantly, it reminded me of a conversation with a fellow developer a couple of weeks ago, in which he told me that he was surprised to see that my projects compiled all the time without warnings. Not a single one. Nada. And that I took the time to remove them before checking code into source control.</p><p><em>He actually didn&#8217;t know you could remove all compiler warnings</em>; he thought Objective-C was the land of compiler warnings. This situation, I think, is far from exceptional, and due mostly to cultural and technical reasons.</p><p>It is my opinion, that removing compiler warnings is <strong>basic project hygiene</strong>, like writing unit tests, or using the Clang Static Analyzer. I will explain in this post some techniques I use to remove warnings in my Objective-C code.</p><p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/warnings2.png" alt="warnings2" title="warnings2" width="547" height="673" class="alignnone size-full wp-image-1636" /> <span
id="more-1633"></span> First of all, why does the Objective-C compiler (or compilers in general) output &#8220;warnings&#8221;? Many developers are puzzled the first time they encounter them, since even if the compiler complained, the application usually runs anyway without (perceptible) problems.</p><p>Warnings are used to signal specific issues in the source code which could potentially lead to crashes or misbehavior under some circumstances, but which should not (pay attention to the verb &#8220;should&#8221;) block the normal compilation and (hopefully) execution of your code (otherwise, it would be a compiler error).</p><p>It&#8217;s the way used by your compiler to say:</p><blockquote>Hey, I&#8217;m not sure, but there&#8217;s something fishy in here.</blockquote><p>Not removing warnings, as I said above, is a problem that originates both in the programming background of the developer, and specific technical issues.</p><p>Culturally speaking, many other programming environments either do not have compilers at all (at least not &#8220;visible&#8221; ones, like Ruby or PHP) or simply do not spit warnings for anything else than deprecated methods (like C# or Java); this situation has made many developers new to the iPhone platform to blatantly ignore them.</p><p>Technically, given the fact that Objective-C is the &#8220;other&#8221; object-oriented superset of C, and that it behaves as a coin with both a static and a dynamic side, compiler warnings convey a great amount of precious information that must <em>never</em> be ignored.</p><p>In this sense, Objective-C has a lot in common with C++. Ignoring warnings in C++ is strongly discouraged, and Scott Meyers explains this in chapter 9 of his book &#8220;Effective C++&#8221;, stating that (third edition, page 263):</p><blockquote>Take compiler warnings seriously, and strive to compile warning-free at the maximum warning level supported by your compilers</blockquote><p>In the case of Objective-C, this can be done by setting GCC_TREAT_WARNINGS_AS_ERRORS (-Werror) to true in your build settings.</p><p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/07/warnings3.png" alt="warnings3" title="warnings3" width="547" height="673" class="alignnone size-full wp-image-1637" /></p><p>Steve McConnell takes this advice to another level of importance in his classic book &#8220;Code Complete&#8221; (second edition, page 557):</p><blockquote>Set your compiler&#8217;s warning level to the highest, pickiest level possible, and fix the errors it reports. It&#8217;s sloppy to ignore compiler errors. It&#8217;s even sloppier to turn off the warnings  so that you can&#8217;t even see them. Children sometimes think that if they close their eyes and can&#8217;t see you, they&#8217;ve made you go away (&#8230;).
Assume that the people who wrote the compiler know a great deal more about your language than you do. If they&#8217;re warning you about something, it usually means you have an opportunity to learn something new about your language.</blockquote><p>To give a concrete example of the importance of warnings, many of us have had to migrate applications developed for iPhone OS 2.x to the 3.0 operating system, mostly because failure to run on the new version of the OS was ground for removal from the App Store. That moment of truth, the rebuild of the Xcode project, unveiled a plethora of compiler warnings, most due to deprecated methods, like the tableView:accessoryTypeForRowWithIndexPath: method of the UITableViewDelegate protocol, or the initWithFrame:reuseIdentifier: method of the UITableViewCell class (which, incidentally, are properly marked as such in the documentation, too).</p><p>Compiler warnings in Objective-C have a multitude of reasons:</p><ul><li>Using deprecated symbols;</li><li>Calling method names not declared in included headers;</li><li>Calling methods belonging to implicit protocols;</li><li>Using some ambiguous commands which might be intentional but are syntactically valid anyway;</li><li>Forgetting to return a result in methods not returning &#8220;void&#8221;;</li><li>Forgetting to #import the header file of a class declared as a forward &#8220;@class&#8221;;</li><li>Downcasting values and pointers implicitly.</li></ul><p>Many solutions exist for these problems, and I do not claim to know them all; I&#8217;ll just describe some of them, and hopefully some of the readers of this post will add others in the comments below.</p><p><strong>1) Make implicit protocols explicit</strong></p><p>This is a really simple one, and it&#8217;s also good for documentation and code clarity reasons. Get all the references of delegate methods you use in the code, and group the methods into their own header file. Import the header file whenever you need, and make classes explicitly implement them:</p><p>[source:c]
//&#8230;
@interface NewClass : NSObject <SomeProtocol> {
//&#8230;
[/source]</p><p>Of course, take advantage of Objective-C&#8217;s @required and @optional keywords in your protocol declarations; they are used by the compiler to verify (or not) the existence of delegate methods in your class implementation. This way, you&#8217;ll surely remove some warnings.</p><p><strong>2) <del
datetime="2009-07-17T07:36:51+00:00">Do not use &#8220;id&#8221; as the data type for delegate fields</del> Using id as datatype for delegate fields</strong></p><p>I personally use the following declaration for delegate fields:</p><p>[source:c]
//&#8230;
NSObject<SomeProtocol> *delegate;
//&#8230;
[/source]</p><p>instead of simply</p><p>[source:c]
//&#8230;
id delegate<SomeProtocol>;
//&#8230;
[/source]</p><p>This is because I always check on delegates before calling their methods. Call me paranoid, but this is what a good delegate call looks to me:</p><p>[source:c]
if([delegate respondsToSelector:@selector(someObj:doesThis:)])
{
[delegate someObj:self doesThis:@"123"];
}
[/source]</p><p>Using NSObject instead of id in the delegate declaration avoid yet another warning. <strong>Update, 2009-07-17:</strong> This is because using id<SomeProtocol> raises a warning that &#8220;respondsToSelector:&#8221; is not defined in SomeProtocol. The solution for this is making SomeProtocol inherit from the NSObject protocol (I always forget this double life of the NSObject symbol):</p><p>[source:c]
@protocol SomeProtocol <NSObject> //&#8230;
@end
[/source]</p><p>This way, you can use id&lt;SomeProtocol&gt; variables without problem.</p><p><strong>3) Create categories for private methods</strong></p><p>Objective-C uses the @private, @public and @protected identifiers only for instance fields, but otherwise methods can only be marked as instance (&#8220;-&#8221;) or static (&#8220;+&#8221;), but all methods specified in the header file are public by default.</p><p>If you need to specify private methods, do that in your implementation file, creating what&#8217;s called a &#8220;category&#8221; of your own class, which basically &#8220;extends&#8221; the class with new methods:</p><p>[source:c]</p><h1>import &#8220;NewClass.h&#8221;</h1><p>@implementation NewClass (Private)
// your methods here
@end</p><p>@implementation NewClass
// &#8230;
@end
[/source]</p><p>This way you can define private methods, not exposing them in the public interface file. And you remove some more warnings.</p><p><strong>4) Turn implicit type conversions and casts into explicit ones:</strong></p><p>This one is inspired by McConnell&#8217;s Code Complete (second edition, page 293):</p><p>[source:c]
int i;
float y, x;
y = x + (float)i
[/source]</p><p>Even if the compiler could work out the &#8220;y = x + i&#8221; expression without problem, the code above will remove yet another warning, and will make your code more obvious and easier to read, since it clearly states your intentions.</p><p><strong>5.1) Support earlier OS versions via runtime checks</strong></p><p>If you have to write iPhone applications compatible with both the 3.0 and 2.x versions, this sample from Apple https://developer.apple.com/iphone/library/samplecode/MailComposer/listing7.html provides instructions on how to do it.</p><p>&#8220;MailComposer runs on earlier and later releases of the iPhone OS and uses new APIs introduced in iPhone SDK 3.0. See below for steps that describe how to target earlier 0S versions while building with newly released APIs.&#8221;</p><p>It is worth noting that this sample application compiles without a single warning!</p><p><strong>5.2) Support earlier OS versions via #defines</strong></p><p>Use #ifdef IPHONE_OS_3.0 and IPHONE_OS_2.2.1 if you can (or must) provide different binaries for each supported platform. This might be the case for in-house applications, but again, it might help removing some warnings too.</p><p><strong>6) Use @class in the @interface, #import on the @implementation</strong></p><p>Whenever you use a class on a header file, to avoid cross-references, use the @class keyword to reference it, but do not forget to #import its header file in the implementation!</p><p>[source:c]
@class AnotherClass</p><p>@interface SomeClass : NSObject
{
@private
AnotherClass *field;
//&#8230;
}
[/source]</p><p>and then</p><p>[source:c]</p><h1>import &#8220;AnotherClass.h&#8221;</h1><p>@implementation SomeClass</p><ul><li>(id)init
{
if (self = [super init])
{
field = [[AnotherClass alloc] init];
}
return self;
}</li></ul><p>@end
[/source]</p><p>The problem is, if you do not #import the file, you get a warning&#8230;</p><p>The advantage of this technique is not obvious in small projects, but it is strongly recommended anyway; it prevents header files from cross-referencing each other, and it reduces build times in projects anyway. It is the Objective-C analog to the technique of using &#8220;class&#8221; statements in C++ header files, instead of #include.</p><p>For more information: Matt Gallagher also wrote about this issue, and I strongly recommend <a
href="http://cocoawithlove.com/2009/04/8-confusing-objective-c-warnings-and.html">his article</a> too! Read also <a
href="http://developer.apple.com/Tools/xcode/compilercodewarnings.html">this article from Apple</a> about the issue of compiler warnings which covers all the options available on GCC in great detail.</p><p>Finally, all of this boils down to the fact that <a
href="http://kosmaczewski.net/2008/12/23/dirty-little-secret/">iPhone programming is not as easy as web development</a>, and that iPhone applications, for many reasons, require patience and attention. Removing warnings from your code <a
href="http://kosmaczewski.net/2009/01/28/10-iphone-memory-management-tips/">is just one of many steps</a> to have great iPhone applications, running smoothly without problems.</p><p><strong>Update, 2009-07-17:</strong> Regarding the &#8220;id vs. NSObject&#8221; issue, I&#8217;ve used NSObject because you get a warning when calling respondsToSelector: on a variable of type id<SomeProtocol>. Now, after reading all the comments I&#8217;ve gone back to Xcode and found out that you can define SomeProtocol as implementing the NSObject protocol itself, and this solves the problem. Thanks everyone for the heads-up!</p> ]]></content:encoded> <wfw:commentRss>http://akosma.com/2009/07/16/objective-c-compiler-warnings/feed/</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>NIBs or code? Why not both? Here&#8217;s nib2objc.</title><link>http://akosma.com/2009/03/17/nib2objc/</link> <comments>http://akosma.com/2009/03/17/nib2objc/#comments</comments> <pubDate>Tue, 17 Mar 2009 19:52:57 +0000</pubDate> <dc:creator>akosma software</dc:creator> <category><![CDATA[Cocoa]]></category> <category><![CDATA[Code]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[design]]></category> <category><![CDATA[git]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[project]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1459</guid> <description><![CDATA[(Somehow this project seems to me so simple, that I&#8217;m sure someone has done this before. Anyway). This is my feeble attempt to bring an answer to the eternal dichotomy between those arguing about the relative benefits of creating user &#8230; <a
href="http://akosma.com/2009/03/17/nib2objc/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>(Somehow this project seems to me so simple, that I&#8217;m sure someone has done this before. Anyway). This is my feeble attempt to bring an answer to the eternal dichotomy between those arguing about the relative benefits of creating user interfaces via Interface Builder or via pure Objective-C code: let me introduce <a
href="http://github.com/akosma/nib2objc/">nib2objc</a>.</p><p>Unbeknown to most of us, the <a
href="http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/ManPages/man1/ibtool.1.html">ibtool</a> utility bundled with Interface Builder and Xcode allows us to inspect the contents of NIB files (or XIBs, for that matter) and get from them nice property lists XML streams, which I transform in NSDictionary instances, which I loop over and over util I get something that looks like this:</p><p>[source:c]
UIView *view6 = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 460.0)];
view6.frame = CGRectMake(0.0, 0.0, 320.0, 460.0);
view6.alpha = 1.000;
view6.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
view6.backgroundColor = [UIColor colorWithWhite:0.750 alpha:1.000];
view6.clearsContextBeforeDrawing = NO;
// &#8230;</p><p>UIButton *view9 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
view9.frame = CGRectMake(167.0, 65.0, 72.0, 37.0);
view9.adjustsImageWhenDisabled = YES;
view9.adjustsImageWhenHighlighted = YES;
view9.alpha = 1.000;
view9.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
view9.clearsContextBeforeDrawing = NO;
view9.clipsToBounds = NO;
view9.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
// &#8230;
[view9 setTitleShadowColor:[UIColor colorWithWhite:0.000 alpha:1.000] forState:UIControlStateSelected];</p><p>// &#8230;
[view6 addSubview:view9];
// &#8230;
[/source]</p><p>Using this tool, I can now use IB for design, and then generate the code for those designs, in case I prefer to use a code-only approach (usually for UITableViewCells, <a
href="/2009/01/28/10-iphone-memory-management-tips/">as I explained before</a>). For the moment it only works with UIKit classes, but I don&#8217;t think it might be a problem to extend it to AppKit classes as well.</p><p>I hope this project is useful to all of you! As usual, open source, public domain and on <a
href="http://github.com/akosma/nib2objc/">Github</a>.</p><p><strong>Update, 2009-04-09:</strong> This project has been <a
href="http://arstechnica.com/apple/guides/2009/04/iphone-dev-convert-xib-files-to-objective-c.ars">featured in an article in Ars Technica</a> by <a
href="http://ericasadun.com/">Erica Sadun</a>!</p> ]]></content:encoded> <wfw:commentRss>http://akosma.com/2009/03/17/nib2objc/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>That iPhone Keypad</title><link>http://kosmaczewski.net/that-iphone-keypad/</link> <comments>http://kosmaczewski.net/that-iphone-keypad/#comments</comments> <pubDate>Fri, 13 Mar 2009 14:10:20 +0000</pubDate> <dc:creator>Adrian</dc:creator> <category><![CDATA[Apple]]></category> <category><![CDATA[Code]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[git]]></category> <category><![CDATA[Objective-C]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1452</guid> <description><![CDATA[Finishing my series of copied flattered UIs, like that Facebook thingy or that Twitterriffic gadget, here&#8217;s Apple&#8217;s own iPhone keyboard, in a really sloppy implementation that has been blatantly and horribly copied, with awful sounds that pop when you tap &#8230; <a
href="http://kosmaczewski.net/that-iphone-keypad/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p><a
href="http://kosmaczewski.net/wp-content/uploads/2009/03/keypad.png" rel="lightbox"><img
src="http://kosmaczewski.net/wp-content/uploads/2009/03/keypad-200x300.png" alt="" title="keypad" width="200" height="300" align="left" class="alignnone size-medium wp-image-1449" /></a> Finishing my series of <del
datetime="2009-03-13T14:01:03+00:00">copied</del> flattered UIs, like <a
href="/2009/02/24/that-facebook-strip/">that Facebook thingy</a> or <a
href="/2009/02/28/that-twitterriffic-editor/">that Twitterriffic gadget</a>, here&#8217;s Apple&#8217;s own iPhone keyboard, in a really sloppy implementation that has been blatantly and horribly copied, with awful sounds that pop when you tap the numbers and such. The <a
href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=290948830&#038;mt=8">Fring iPhone application</a> uses a similar keyboard, but with a different color set.</p><p>This code, apart from showing the keyboard and playing those sounds, it doesn&#8217;t do anything else, even if a simple &#8220;tel:&#8221; URL call might suffice to turn it into a real dialer. As usual the code is on <a
href="http://github.com/akosma/iphone-keypad/">Github</a>; feel free to play with it, extend it, and do what you want.</p> ]]></content:encoded> <wfw:commentRss>http://kosmaczewski.net/that-iphone-keypad/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Asynchronous Loading of Images in a UITableView</title><link>http://kosmaczewski.net/asynchronous-loading-of-images-in-a-uitableview/</link> <comments>http://kosmaczewski.net/asynchronous-loading-of-images-in-a-uitableview/#comments</comments> <pubDate>Sun, 08 Mar 2009 19:33:50 +0000</pubDate> <dc:creator>Adrian</dc:creator> <category><![CDATA[Code]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[Apple]]></category> <category><![CDATA[git]]></category> <category><![CDATA[project]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1441</guid> <description><![CDATA[This is one of the most common scenarios for network- + UITableView-based applications; a UITableView instance whose contents come from the network; not only the text, but also the images! Somehow we all want to reproduce the behavior of the &#8230; <a
href="http://kosmaczewski.net/asynchronous-loading-of-images-in-a-uitableview/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p><a
href="http://kosmaczewski.net/wp-content/uploads/2009/03/asynctable.png" rel="lightbox"><img
src="http://kosmaczewski.net/wp-content/uploads/2009/03/asynctable-161x300.png" alt="" title="asynctable" width="161" height="300" class="alignnone size-medium wp-image-1436" align="left"/></a> This is one of the most common scenarios for network- + UITableView-based applications; <strong>a UITableView instance whose contents come from the network; not only the text, but also the images!</strong> Somehow we all want to reproduce the behavior of the App Store (or of the iTunes) iPhone application, where the icons (or covers) of the apps (or songs) are downloaded one by one, as you scroll the table, without crashing nor opening 1000 simultaneous network connections.</p><p>My solution (there might be many others!) consists in the following key elements:</p><ul><li>Avoid loading images right after the RSS feed is parsed; instead, use the -tableView:willDisplayCell:forRowAtIndexPath: delegate method in the controller to trigger the loading of the image for cells that become visible; this ensures that only the cells that are visible will receive the order to load images from the network;</li><li>Use a &#8220;model&#8221; class for each element of the table, and make the custom UITableViewCell subclass a delegate of this model object; then, the model object is responsible of loading its own image, and will tell the UITableViewCell when done;</li><li>Use the <a
href="http://allseeing-i.com/ASIHTTPRequest">ASIHTTPRequest framework</a>, with a shared download queue in the application delegate, so that all of the requests are properly queued, and network resources are properly used;</li><li>Show feedback to the user with scrolling wheels whenever and wherever appropriate;</li><li>Use the Reachability class from Apple&#8217;s own sample code to see if we&#8217;re really connected to Flickr, and otherwise show an error to the user.</li></ul><p>I have created a sample project, as usual in <a
href="http://github.com/akosma/async-uitableview/">Github</a>, where I gather RSS data from <a
href="http://www.flickr.com/services/feeds/">Flickr&#8217;s public feed</a>, and then I download synchronously the preview images of the feed. I even included a very simple Core Animation effect which reminds me of how the iTunes iPhone application allows us to hear previews of the songs we want to buy (the image flips and shows another view &#8220;behind&#8221;).</p><p>Feel free to contribute, fork, enjoy, read, use in your own projects, as you want. As I said, there might be many other (and most probably better) approaches to do this, so feel free to leave your comments below, as usual.</p> ]]></content:encoded> <wfw:commentRss>http://kosmaczewski.net/asynchronous-loading-of-images-in-a-uitableview/feed/</wfw:commentRss> <slash:comments>32</slash:comments> </item> <item><title>That Twitterriffic editor</title><link>http://kosmaczewski.net/that-twitterriffic-editor/</link> <comments>http://kosmaczewski.net/that-twitterriffic-editor/#comments</comments> <pubDate>Fri, 27 Feb 2009 22:37:06 +0000</pubDate> <dc:creator>Adrian</dc:creator> <category><![CDATA[Cocoa]]></category> <category><![CDATA[Code]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[git]]></category> <category><![CDATA[Twitter]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1428</guid> <description><![CDATA[They say imitation is the best form of flattery. Well, here&#8217;s another attempt at doing that, after my &#8220;attack&#8221; on the Facebook iPhone app (decidedly I&#8217;m on a somewhat copying mood lately). I use Twitterriffic a lot, both on the &#8230; <a
href="http://kosmaczewski.net/that-twitterriffic-editor/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p><img
src="http://kosmaczewski.net/wp-content/uploads/2009/02/twitterriffic-200x300.png" alt="" title="twitterriffic" width="200" height="300" class="alignnone size-medium wp-image-1424" align="left" hspace="10" />They say imitation is the best form of flattery. Well, here&#8217;s another attempt  at doing that, after <a
href="/2009/02/24/that-facebook-strip/">my &#8220;attack&#8221;</a> on the Facebook iPhone app (decidedly I&#8217;m on a somewhat copying mood lately).</p><p>I use <a
href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284540316&#038;mt=8">Twitterriffic</a> a lot, both on the iPhone and on my Mac, and particularly in the iPhone version, I&#8217;ve always liked the little editor for tweets. It grows and shrinks as you type, it appears and disappears following the keyboard, and it provides a standard toolbar with many useful buttons (Actually, I wish the Mac version would have a similar text entry box, which would grow bigger as I type; it&#8217;s probably the only complaint I have about it!)</p><p>Well, here&#8217;s my own attempt at doing something similar, and after 1 hour of work, <a
href="http://github.com/akosma/editorrific/tree/master">the result is published, ready for you to enjoy at Github</a>. As usual, no strings attached, pure public domain stuff, so use it and play with it as you wish.</p> ]]></content:encoded> <wfw:commentRss>http://kosmaczewski.net/that-twitterriffic-editor/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Going Github</title><link>http://kosmaczewski.net/going-github/</link> <comments>http://kosmaczewski.net/going-github/#comments</comments> <pubDate>Wed, 18 Feb 2009 19:24:05 +0000</pubDate> <dc:creator>Adrian</dc:creator> <category><![CDATA[Code]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[git]]></category> <category><![CDATA[personal]]></category> <category><![CDATA[project]]></category> <guid
isPermaLink="false">http://kosmaczewski.net/?p=1391</guid> <description><![CDATA[This is something I&#8217;ve been looking forward to do for some time. After praising git back in 2007, now I&#8217;m moving many of my personal projects to Github, which has an absolutely brilliant service! For the moment I&#8217;m using the &#8230; <a
href="http://kosmaczewski.net/going-github/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>This is something I&#8217;ve been looking forward to do for some time. After <a
href="/2007/11/29/git/">praising git</a> back in 2007, now I&#8217;m moving many of my <a
href="/projects">personal projects</a> to <a
href="http://github.com/">Github</a>, which has an absolutely brilliant service! For the moment I&#8217;m using the free account, but I will most probably switch to a paid account soon. The only thing it lacks, in my opinion, is a bug &amp; issue tracker as you have in Google Code repositories, but other than that, it&#8217;s simply perfect.</p><p>So feel free to check out <a
href="http://github.com/akosma/">the projects I&#8217;ve moved there</a>, and of course, to fork them and enjoy the code as you see fit.</p> ]]></content:encoded> <wfw:commentRss>http://kosmaczewski.net/going-github/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
