Felipe Cypriano You are about to read it

Impressions about Objective-C

I'm starting to learn Objective-C reading Apple's documentation and it's very interesting to see features that I love in Groovy are available to use in such old-school language (30 years old). At a first sight I thought this would be a painful language to learn without any cool feature from modern language like Ruby and Python. Also thought Apple doesn't care about its programming language as much as the user experience, fortunately I was wrong.

The strangest thing for those who have a Java background is how methods are called  it doesn't uses dot notation. See the between a method call 'workHard' on an 'employee' object and instantiate a new instance in Java and Objective-C:

JavaObjective-C
new Employee()
[[Employee alloc] init];
employee.workHard();
[employee workHard];

A Dynamic Language

Just like Groovy the Objective-C language defers as many decisions as it can from compile time and link time to runtime. That means among other things that in order to run a code you need not only a compiler but also a runtime system to execute the compiled code, this system is already ready to use in iPhone OS and Mac OS X.

It's possible to declare a variable as strong or weak type, giving us tremendous flexibility.

NSString *myVar; // strong typing
id myVar; // weak typing

The examples above shows how to declare variables to store objects, the first myVar reference accepts only NSString instances and the later accepts any object. The id is just like Groovy's def keyword. Using the id means that we can send a message to that instance even if the compiler can't guarantee it'll work.

(Yes! I thing the word 'id' meaning anything isn't good.)

Categories

Categories let's you add method to an existing class, even if you haven't the source. This is my favorite similaraty with Groovy I found so far I hope there's many more to come, see a sneak peek of the syntax:

@interface ClassName ( CategoryName )
// new methods declarations
@end

Protocols, the Java's Interface

Just like Java's interface, so no need to explain it here, except for one cool feature: we can declare optional methods. In practice when one of our classes conforms to a protocol that define options methods we aren't obligated to implement them.

More Resources

Besides the language itself Cocoa and Cocoa Touch - Apple's framework for Mac OS X and iPhone OS respectively - are great frameworks with lots of functionalities, it's easy to build beautiful applications. Interested in learning more about Objective-C? Take a look at this docs:

Have fun improving your programming skills.

Synchronizing IntelliJ IDEA dependencies with Gradle [Updated]

Based on the great post Managing Intellij dependencies with Gradle from Kallin Nagelberg, I've came to a solution about how to manage Intellij IDEA dependencies on projects that uses .idea directory as its structure.

Basically instead of changing your_project.iml file we create a xml file in .idea/libraries with the jars listed on it. For more details, please, read Kallin's post. This is the task:

// IntelliJ IDEA configuration sync
task intellijSync << {
    final def librariesDir = new File(".idea${File.separator}libraries")
    librariesDir.mkdirs()

    final def gradleLibsPath = configurations.compile.asPath
    final def userHomeGradle = project.gradle.gradleUserHomeDir
    final def libsJar = gradleLibsPath.split(File.pathSeparator).collect {
        it.replaceAll userHomeGradle.path, "\\\$USER_HOME_GRADLE\\\$"
    }
    println libsJar

    final def gradleLibXml = new File(librariesDir, 'Gradle_Libraries.xml')
    gradleLibXml.write """
<component name="libraryTable">
  <library name="Gradle Libraries"/>
</component>
"""
    final def xmlRoot = new XmlParser().parse(gradleLibXml)
    final def classesNode = xmlRoot.library[0].appendNode('CLASSES')

    libsJar.each { jar ->
        classesNode.appendNode('root', [url: "jar://$jar!/"])
    }

    def writer = new StringWriter()
    new XmlNodePrinter(new PrintWriter(writer)).print(xmlRoot)
    println writer.toString()
    gradleLibXml.write writer.toString()
}

The complete build.gradle file is on Gist.

# Update 1

Check the file on Gist, I've updated it to sync test libraries as well.

Grails with ZK: How To Create Components in Runtime with The Builder

ZKGrails plugin has an extremely nice feature which make easier than ever to create ZK components in runtime.

First lets see how is the usual way to create components in runtime using Java. This is the zul representation of what we’re trying to achieve:

<div>
  <toolbarbutton label="Clickable Item" href="#" />
  <toolbarbutton image="edit.png" if="${userHasAccess}" />
  <toolbarbutton image="delete.png" if="${userHasAccess}" />
</div>

And the java code to do the same:

Div div = new Div();
Toolbarbutton tbb = new Toolbarbutton("Clickable Item");
tbb.setHref("#");
tbb.setParent(div);
if (userHasAccess) {
    Toolbarbutton tbbEdit = new Toolbarbutton();
    tbbEdit.setImage("edit.png");
    tbbEdit.setParent(div);
    Toolbarbutton tbbDelete = new Toolbarbutton();
    tbbDelete.setImage("delete.png");
    tbbDelete.setParent(div);
}

As you can easily see the java code is pretty verbose. Using ZKBuilder the code will be easier to understand and smaller, take a look:

Div div = new Div();
div.append {
    toolbarbutton(label: "Clickable Item", href: "#")
    if (userHasAccess) {
        toolbarbutton(image: "edit.png")
        toolbarbutton(image: "delete.png")
    }
}

Which one do your prefer? :) If you want more continue reading to see how to use the builder as a template to a list of items.

Using ZKBuilder as a Template

Handling events on ZK macro components

One of the great features of ZK is the possibility to create a new component based only on other existing components using the declarative language ZUML - the same you've been using in you zul files. Those are called Macro Components. The beauty of macro components is that it's very easy to make a new one and hence avoid code duplication on your pages.

Talk about how to implement a macro component isn't the scope of this post, so I suggest you to read the documentation before continue reading.

We'll work on a very simple macro component. But, don't hesitate when you need to make a very complex one. Our macro component is this: WEB-INF/mymacro.zul

<hbox>
    <label id="myLabel" value="Click the button"/>
    <button id="myButton" label="The Button"/>
</hbox>

Now that you already knows what is and how to make a macro component, let's start talking about what you may think it'll work but actually it doesn't.

Automatically Forward Event Doesn't Work

The standard way to register events on ZK's component, using MVC, is to use the "autowire" feature of GenericForwardComposer. Like this:

WEB-INF/index.zul

<?xml version="1.0" encoding="UTF-8"?>
<zk>
    <window apply="com.felipecypriano.IndexComposer">
        <label id="lblOutside"/>
        <button id="btnOutside" label="Not In Macro"/>
    </window>
</zk>

src/com/felipecypriano/IndexComposer.java

package com.felipecypriano;

import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Label;

public class IndexComposer extends GenericForwardComposer {
    private Label lblOutside;

    public void onClick$btnOutside() {
        lblOutside.setValue("Button 'not in macro' clicked");
    }
}

The button 'btnOutside' belongs to the window component and therefore its composer can automatically access and configure btnOutside events. When the Composer is initializing it detects the method onClick$btnOutside() and sets this method as a 'btnOutside' onClick event listener, in other words when the component is clicked this method is executed.

Knowing this we can think that add an event to 'myButton', which belongs to 'mymacro', is pretty much the same. Don't we? Let's add the macro in the index.zul and create a new method to handle onClick event of 'myButton':

WEB-INF/index.zul

<?xml version="1.0" encoding="UTF-8"?>
<?component name="mymacro" macroURI="/mymacro.zul" ?>
<zk>
    <window apply="com.felipecypriano.IndexComposer">
        <label id="lblOutside"/>
        <button id="btnOutside" label="Not In Macro"/>
        <separator bar="true"/>
        <mymacro/>
    </window>
</zk>

Just before <zk> tag is the macro component definition (line 2), this directive tells to ZK where is the file that contains the component - macroURI="/mymacro.zul" -  and what's the tag name we'll use - name="mymacro" - to reference our component (line 8).

Adding the onClick event on 'myButton' cannot be done by just adding this method to IndexComposer:

src/com/felipecypriano/IndexComposer.java

    public void onClick$myButton() {
        lblOutside.setValue("Button 'myButton' clicked");
    }

So, if this doesn't work what should I do?

Tagged as: , Continue reading