<?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>Kim Bach . Org &#187; cocoa</title>
	<atom:link href="http://www.kimbach.org/tag/cocoa/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kimbach.org</link>
	<description></description>
	<lastBuildDate>Fri, 27 Jan 2012 20:14:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>DrupalCamp Copenhagen 2008: Guess what, I&#8217;m the hero &#8211; Introducing Droopy your new microblogging service</title>
		<link>http://www.kimbach.org/2008/12/05/drupalcamp-copenhagen-2008-guess-what-im-the-hero-introducing-droopy-your-new-microblogging-service/</link>
		<comments>http://www.kimbach.org/2008/12/05/drupalcamp-copenhagen-2008-guess-what-im-the-hero-introducing-droopy-your-new-microblogging-service/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 05:00:00 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[Blogs]]></category>
		<category><![CDATA[Computere og Internet]]></category>
		<category><![CDATA[Hackers]]></category>
		<category><![CDATA[Historier/Stories]]></category>
		<category><![CDATA[Kim Blog (English)]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupalcamp]]></category>
		<category><![CDATA[drupalcampcopenhagen]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[kim bach]]></category>
		<category><![CDATA[presence]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[social media]]></category>
<category>cocoa</category><category>drupal</category><category>drupalcamp</category><category>drupalcampcopenhagen</category><category>event</category><category>feature</category><category>internet</category><category>kim bach</category><category>open source</category><category>presence</category><category>presentation</category><category>social media</category>
		<guid isPermaLink="false">http://www.kimbach.org/?p=739</guid>
		<description><![CDATA[taxonomy['tags'] = array($vid => $tags);


/**
 * Create a droop node programatically.
 * @param $param
 * Either a droop - enabled node type or a $node object with at least valid $node->type.
 * @param $title
 * The body of the droop post.
 */
function droop_create_node($param, $title, $tags) {
  if (is_object($param)) {
    $node = [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://drupalcamp.dk/"<img src="http://drupalcamp.dk/sites/all/themes/dcampcph/logo.png" border="1" align="left" hspace="4" vspace="4" alt="DrupalCamp Copenhagen Logo" title="DrupalCamp Copenhagen Logo" longdesc="DrupalCamp Copenhagen Logo" /><em>The Danish Drupal community, </em><em><a href="http://drupaldanmark.dk/">Drupal Danmark</a></em><em>, organised a miniconference, </em><em><a href="http://drupalcamp.dk/">DrupalCamp Copenhagen</a></em><em>, in the weekend of the 15th and 16th of November 2008 at </em><em><a href="http://www.laoficina.dk/">La Oficina</a></em><em>, a new &#8211; FANTASTIC &#8211; co-working space in Copenhagen</em><br />
<strong><br />
Show your &lt;3 for Drupal</strong><br />
People that know me, also knows that I&#8217;m a big fan of the Content Management System (CMS) Drupal, and I constantly push it.</p>
<p>One of the main reasons I LOVE Drupal is that it, besides the pure open source license &lt;3, also tries hard to support standards, rather than doing &#8220;clever&#8221; things in core. This is in strong contrast to other tools, that attempt to make it easy for the user, but then locks you in.</p>
<p>Personally I love HTML and the constant cry for a rich editor in core is lost on me, but then again, I&#8217;m writing this using the off-line client ecto <img src='http://www.kimbach.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong>A restless 2008, but where&#8217;s the inspiration</strong><br />
2008 has been an amazing year for me, and I&#8217;ve attended several events that should have made me so inspired that I&#8217;d blog up a storm, but somehow this failed to happen, and I was reluctant to sign up for DrupalCamp Copenhagen, because I was also involved in the organisation of <a href="http://barcamp.dk/category/tags/bc82cph">BarCamp Copenhagen</a> the following weekend &#8211; I was afraid to overcommit myself, resulting in me burning out.</p>
<p>It turned out that I was &#8220;pushed&#8221; &#8211; nah let&#8217;s say inspired &#8211; to sign-up by a guy I&#8217;ve never met in person, but  knew well from the Danish Mac community.</p>
<p>&#8220;Unfortunately&#8221; I got so inspired that I even had the audacity to suggest that I should host a session at DrupalCamp Copenhagen &#8211; oh no what a fine mess I got myself into, this happens every time I get inspired, like I said, I tend to overcommit myself.</p>
<p>Then all was quiet for a while, like forever, and DrupalCamp Copenhagen was only four days away, when a preliminary schedule was sent out to the participants, which, by the way, was now exceeding the capacity of the venue, pretty Fanø amazing!</p>
<p>Hmm, my session wasn&#8217;t on the schedule, ok, I guess I don&#8217;t have to prepare anything then <img src='http://www.kimbach.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>So you want to be a Drupal Star, well the stage is yours!</strong><br />
On Wednesday night the final schedule was sent out, and lo-and-behold, my session was actually featured, &#8220;<a href="http://drupalcamp.dk/node/58">Using Drupal as a Web Application Framework</a>&#8220;, hmm I&#8217;ll be addressing a bunch of hardcore Drupal professionals, and they have payed a fee, albeit a nominal one, to attend, but still this is the first time ever that I was to address a paying audience, pretty daunting when you think about it.</p>
<p>So I started thinking hard about the theme of the session. </p>
<p>When I sugested the session, I had promised that the session would be much more of a participatory session, than a presentation, and that I was hosting it to learn from the failures I had trying use Drupal as a framework for web-applications.</p>
<p>In my mind a different idea began to take hold, one that focused on the things that I learned, and was succesful in achieving instead of focusing on the failure of my projects.</p>
<p>I decided that I&#8217;d start by asking the question: &#8220;What is a web-application?&#8221;, and inspired by one of my &#8220;failed&#8221; projects, I decided that I&#8217;d do a walk-through of how you could build a Twitter like site without any, or close to no, coding on your part.</p>
<p>Twitter is the perfect candidate for demoing a web-application implemented using Drupal, since it&#8217;s all about content and simplicity. Strangely enough my choice of Twitter as a model for a sample aligned itself perfectly with the Miki&#8217;s session, Modules 101, on Sunday, even though he took a different approach than I did, and actually did a fair amount of coding.</p>
<p>One could have the idea that we had co-ordinated this, we hadn&#8217;t, so I&#8217;ll just rack it up to coincidence, and the fact that Twitter is the second most hyped thing on the Internet these days.</p>
<p><strong>Guess what, I&#8217;m the hero</strong><br />
<a href="http://www.flickr.com/photos/kimbach/3031418087/"><img src="http://farm4.static.flickr.com/3069/3031418087_0ef2cc3954.jpg?v=0" height="82" width="81" border="1" align="left" hspace="4" vspace="4" alt="Drupal Droopy Dog" title="Drupal Droopy Dog" longdesc="Drupal Droopy Dog" /></a>I won&#8217;t go into serious details about my session, but it saw me show praise for open source and Drupal, do a hands-on step through of how to build a Twitter clone, called Droopy, and demo my first Mac OS X Cocoa application EVER!</p>
<p>Droopy is a fictonal web-application, the name was inspired by the Tex Avery cartoon, but it also sounds like Drupal.</p>
<p>Droopy allows you to post microblog content using a simplified form. Microblog content, or &#8220;Droops&#8221;. A &#8220;Droop&#8221; is a standard Drupal content-type, that you can submit to the site by using a custom form. Implementing the form took some 10 lines of code to implement as a module.</p>
<p><strong>At your service</strong><br />
The real star of the show was, however, the wonderful Drupal <a href="http://drupal.org/project/Services">services module</a>. If you install the services module you can access Drupal using a varity of web-service standards, but as default it support XML-RPC, so that&#8217;s what I focused on.</p>
<p>The services module implements a number of methods that you can use, I focused on the node and the user services.</p>
<p>The node service implements methods for retrieving, deleting and updating nodes, the user service implements methods for login and logout.</p>
<p>One of the nicest features of the services module, is that it has a nice UI for browsing and testing the exposed services.</p>
<p><strong>A KISS from Droopy</strong><br />
You can, of course post content using /node/add/droop, but like I said I&#8217;d like to do that a little smarter/simpler, so for that purpose I developed a small module that utilises the Form API to implement a simplified data entry-form to post the content-type a &#8220;droop&#8221;.</p>
<p>This was quite simple to do, the only problem I had was that I wanted to tag my content (flat taxonomy), and in order to do that, you can&#8217;t simpy use the standard mechanism to save a node, this is how I implemented a method to create a node programatically including creation of tags, the vid that is hardcoded to 2 might be problematic, but the thing to focus on is the line: </p>
<pre name="code" class="php">
$node->taxonomy['tags'] = array($vid => $tags);
</pre>
<pre name="code" class="php">
/**
 * Create a droop node programatically.
 * @param $param
 * Either a droop - enabled node type or a $node object with at least valid $node->type.
 * @param $title
 * The body of the droop post.
 */
function droop_create_node($param, $title, $tags) {
  if (is_object($param)) {
    $node = $param;
  }
  else {
    $node = new stdClass();
    $node->type = $param;
  }
  $node->title = $title;
  $node->body = $title;
  $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
  // If this is a new node, fill in the default values.
  foreach (array('status', 'promote', 'sticky') as $key) {
    $node->$key = in_array($key, $node_options);
  }
  // Get the content-type settings as default
  node_object_prepare($node);
  global $user;
  $node->uid = $user->uid;
  $vid = 2;
  $node->taxonomy['tags'] = array($vid => $tags);

  node_save($node);
  return $node;
}
</pre>
<p>In order to have the custom form show up, I decided to do a theme hack, this could probably be done much cleaner, but it&#8217;s really simple to have a form show up on a page.</p>
<pre name="code" class="php">
print(drupal_get_form('droop_simplified_form', $currentGroup));
</pre>
<p>Below is a screenshot of a simple theme that shows the simplified form:</p>
<p><a href="/wp-content/DroopForm.png"><img src="/wp-content/DroopForm-tm.png" border="1" hspace="4" vspace="4" alt="Droopy and Droop form screenshot" title="Droopy and Droop form screenshot" longdesc="Droopy and Droop form screenshot" /></a> </p>
<p><strong>Fat client</strong><br />
I already had a functional XML-RPC client written in PHP, but I wanted to do something a little smarter.</p>
<p>Fundamentally I believe that the web is extremely ill suited to host applications, what you can do with a full client that has direct access to the rich presentation services that the operating system exposes, is just so much easier to develop, than trying to support x-number of browsers. I&#8217;m a huge fan of applications like iTunes, since they combine webcontent with a fat client, I think that&#8217;s going to comeback in a big way, powered by the mobile platforms, that, due to limited resources, forces us back to writing applications that tagets specific platforms.</p>
<p>In my daily job I work with Microsoft .NET on a standard Lenovo pc, but when I&#8217;m at home, I swear by my beloved PowerBook G4 12&#8243;, and that doesn&#8217;t run Windows and Visual Studio, so how could I develop a fat client to use to demo how to shout &#8220;DOWN BOY!&#8221; to Droopy, I had never ever had any success developing for Mac OS X? OTHO, that was a challenge, and I love those, even though this was now late Friday morning, and my presentation was less than 48 hours away!</p>
<p><strong>Schizoid development platform from the last century</strong><br />
Development for Mac OS X is strange, Apple does bundle the development tools you need to target Mac OS X with Leopard, but that&#8217;s basically where the help stops.</p>
<p>So I knew that I need to enlist the help of Google, and I already knew what I was looking for, so how difficult could it be, well it turned out that it was.</p>
<p>For one, development for Mac OS X is not very widespread, but I did manage to find a number of samples, one of them implemented what is know as a framework, which basically extends Mac OS X with additional features, but hey, I just wanted to call a service using some simple XML that I wanted to post using HTTP, did that really require a framework?</p>
<p>Another strange fact, was that the samples I found were really old, but I found out that Mac OS X actually contains some nice high-level APIs that you can use to call web-services, they&#8217;re all prefixed with WS, for instance WSMethodInvocationCreate, WSMethodInvocationSetParameters and WSMethodInvocationInvoke, the strangest thing about these interfaces was that I saw several warnings against using these functions, strange.</p>
<p><a href="/wp-content/DrupalXMLRPCCocoaClient.png"><img src="/wp-content/DrupalXMLRPCCocoaClient-tm.png" border="1" align="left" hspace="4" vspace="4" alt="Drupal XMLRPC Cocoa Client" title="Drupal XMLRPC Cocoa Client" longdesc="Drupal XMLRPC Cocoa Client" /></a>Oh well I manged to find a suitable sample here: <a href="http://ranchero.com/cocoa/xmlrpcdemo/">Ranchero Software: Cocoa XML-RPC Demo</a>, and I managed to change it so that I could call the node.load method exposed by the node service, but this was when trouble arose.</p>
<p>The node.load  service allows you to supply a list of node-fields that you want to to have returned, if you supply an empty list, you&#8217;ll get all the fields. I tried several things, to no avail, my service kept returning node not found errors, this was a problem that I never manged to fix.</p>
<p>The problem has something to do with the way Apple&#8217;s API serialises it&#8217;s parameters, Drupal is expecting a list, that will get de-serialised into a PHP array, I couldn&#8217;t get that to work.</p>
<p>I then decided that I&#8217;d try to interface with the user service instead, and that faired better, and I manged to login to Drupal from my client, heavenly bliss <img src='http://www.kimbach.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>OK, next step would be to add an additional button to my client, called &#8220;Login&#8221;, and have two buttons in my application, this was when I hit rock-bottom, I just couldn&#8217;t figure out how to hook up an InterfaceBuilder push-button with an Objective-C eventhandler.</p>
<p>This is something that is super-simple to do with almost any other development tools, why oh why has Apple decided to stay in the 80ies, I want a double-click in the designer to generate a stub and open my event-handler code in the editor.</p>
<p>Oh well, my application works, but I think that I&#8217;ll follow the advice, and stop using the WS* APIs, and start interfacing directly with the HTTP POST API, and serialise/deserialise the XML myself, another benefit of this approach, is that it&#8217;ll also works on the iPhone <img src='http://www.kimbach.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  </p>
<p>Below is the code required to do a login to Drupal using XML-RPC from Mac OS X.</p>
<pre name="code" class="cpp">
- (IBAction) doUserLoginLogin: (id) sender {

	/*
	Called when the Login button is clicked.
	*/

	int ixState = [numberField intValue];
	NSNumber *stateNum = [NSNumber numberWithInt: ixState];
	WSMethodInvocationRef rpcCall;
	NSURL *rpcURL = [NSURL URLWithString: @"http://localhost:8888/droopy/?q=services/xmlrpc"];
	NSString *methodName = @"user.login";
	NSDictionary *result;
	NSMutableDictionary   *params;

	params     = [[[NSMutableDictionary alloc] init] retain];

	[params setObject:@"user" forKey:@"username"];
	[params setObject:@"password"            forKey:@"password"];

	/*First create a method invocation.*/

	/*First parameter is the URL to the XML-RPC web service.
	Second parameter is the name of the XML-RPC method to call.
	Third parameter is a constant specifying XML-RPC protocol.*/

	rpcCall = WSMethodInvocationCreate ((CFURLRef) rpcURL, (CFStringRef) methodName, kWSXMLRPCProtocol);

	/*Then set the parameters. (There's just one in this case.)*/

	/*First parameter is the invocation created above.
	Second parameter is a dictionary containing the parameters.
	Third parameter may be an array specifying parameter order.
	(Since there's just one parameter, NULL is passed for parameter order.)*/

	WSMethodInvocationSetParameters (rpcCall, (CFDictionaryRef) params, NULL);

	/*Do the actual XML-RPC call and get the result.*/

	result = (NSDictionary *) (WSMethodInvocationInvoke (rpcCall));

	/*Display the result.*/

	if (WSMethodResultIsFault ((CFDictionaryRef) result)) /*error?*/
		[resultField setStringValue: [result objectForKey: (NSString *) kWSFaultString]];

	else /*no error; all's well*/
		[resultField setStringValue: [result objectForKey: (NSString *) kWSMethodInvocationResult]];
	} /*doLogin*/
</pre>
<p><strong>Lessons learned</strong></p>
<ul>
<li>It&#8217;s easy to develop a web application with little, or no, coding using Drupal.</li>
<li>I&#8217;ve actually learned a LOT from my failures</li>
<li>Work with the framework, not against it</li>
<li>I can haz OS X apps</li>
<li>Oh and: Don&#8217;t hack core <img src='http://www.kimbach.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
</ul>
<p><strong>Thank you to the organisers<br />
</strong>DrupalCamp Copenhagen 2008 was a tremendous success, 100 people, including visitors from as far away as Canada, a venue filled with energy, amazing sessions, especially the sessions hosted by <a href="http://mikkel.hoegh.org/">Miki</a> and <a href="http://acquia.com/">Acquia</a> filled with practical advice, but it&#8217;s also amazing that the Danish newspapers showed up, ready to share their experiences on how to performance optimise Drupal, I guess that print media is finally getting the Internet and the concept of open and free, and it fills me with optimism!</p>
<p>I&#8217;m now ready to face the world with renewed faith in Drupal and my own abilities to put it to use, gentlemen start your Drupal engines!</p>
<p><strong>One more thing</strong><br />
<a href="/wp-content/SylvesterTweety.jpg"><img src="/wp-content/SylvesterTweety-tm.jpg" vspace="4" hspace="4" align="left"/></a>Come to think about it I should have named my Twitter clone, Sylvester, OTOH Sylvester never manages to catch &#8220;Tweety Bird&#8221; does he <img src='http://www.kimbach.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>External links<br />
</strong>
<ul>
<li><a href="http://ranchero.com/cocoa/xmlrpcdemo/">Ranchero Software: Cocoa XML-RPC Demo</a></li>
<li><a href="http://drupal.org/project/Services">Drupal services module</a></li>
<li><a href="http://jaiku.com/channel/drupal/presence/48967738">#drupal @ Jaiku.com: DrupalCamp Copenhagen http://drupalcamp.dk is in full swing, first speakers for advanced track were delayed</a></li>
<li><a href="http://jaiku.com/channel/drupal/presence/48977363">#drupal @ Jaiku.com: Another great session hosted by Robert of Acquia on using the ApacheSolr Seach engine with Drupal</a></li>
<li><a href="http://jaiku.com/channel/drupal/presence/49038109">#drupal @ Jaiku.com: DrupalCamp Copenhagen: &#8220;miki&#8221; is on about module development in the big room now</a></li>
<li><a href="http://jaiku.com/channel/drupal/presence/49041155">#drupal @ Jaiku.com: DrupalCamp Copenhagen 2008: It&#8217;s a Wrap! Thanks to the organisers for putting together such a great event! See you in May 2009!</a></li>
</ul>
<p><em>Droopy is a trademark of and copyright MGM, Sylvester and Tweety are trademarks of and copyright Warner Brothers. I claim fair use</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kimbach.org/2008/12/05/drupalcamp-copenhagen-2008-guess-what-im-the-hero-introducing-droopy-your-new-microblogging-service/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

