Posts Tagged ‘cocoa’

Testing Macruby and Objective C Together

MacRuby logo
When working on Macruby apps, there is a wealth of useful Cocoa code snippets and open source frameworks online, but they are primarily in Objective C. Macruby can use Objective C code transparently, but if we want to access that code in individual unit tests we need to set up our project so that the Objective C parts are compiled and accessible to the test.

One way we can do this is to use embedded frameworks to hold some (or all) of the code in our app.
This little tutorial describes how to set up your a Macruby project so that you can run your unit tests both from Xcode or from the command line, and have access to any Objective C classes your project uses when running individual tests from the command line.

This Mac Dev Center article talks about creating Frameworks.

Here are the steps I followed to organize third-party code into framework and build a testing target that used those frameworks (the information came from this tutorial on Cocoadev and the Macruby TDD tutorial).

These steps assume you have used the one of the Macruby templates current at the time I wrote this, which include a “Unit Tests” target that has a Run Script phase that calls Tests/run_suite.rb.

  • Organize Your Code

    If it is not already, organize the code you wish to build into an embedded framework into a directory and either include it in your project as a folder reference or create a corresponding group. Xcode does not require you to do this, but it makes life much easier. Let’s call it MyFramework for this example.

  • Create A New Framework

    Create a new Cocoa Framework Build Target in the project (you do this by right-clicking on Targets and choose Add > New Target…, and then choosing the Cocoa > Framework template). Then enter MyFramework and click “Finish”. The resulting target will have the icon for a framework. There should also be an entry under Products called MyFramework.framework, which will be red because it hasn’t been built yet.

  • Set the Installation Directory

    Select the “Build” tab of the Info Pane for the new target. Find the “Installation Directory” setting in the “Deployment” setting group.

    The default value is

    $(HOME)/Library/Frameworks

    Change it to

    @executable_path/../Frameworks

  • Link the Framework in the Application Target

    Next you need to make sure the application target links your framework. To do that, drag MyFramework.framework from the Products group into the “Link Binaries With Libraries” phase of the application target (the target with the same name as your Xcode project). In a new Macruby project, this will already have entries for Cocoa.framework and Macruby.framework.

  • Copy the Framework into the Application

    You also need to have the application target copy the built framework into the application. To do this, add a new “Copy Files” build phase to the application target. You do this by right-clicking the application target and selecting Add > New Build Phase > New Copy Files Build Phase. Then drag MyFramework.framework from the Products group into the new build phase.

  • Add Framework as a Dependency

    Now you need to make sure that building the application or running the unit tests also builds the framework if it needs building, by adding MyFramework as a dependency to the application target and the “Unit Tests” target. To do that, do a “Get Info” on each target, and in the General pane click the + under Direct Dependencies and add MyFramework.

  • Accessing the Framework in Unit Tests

    Next we need to tell our unit tests where to find the framework, which we can do by adding:

    # Tell MacRuby where to find our framework
    ENV['DYLD_FRAMEWORK_PATH'] ||= ENV['BUILT_PRODUCTS_DIR']
    

    to the Tests/run_suite.rb file.

In order to run tests from the command line that have dependencies on this , we can do this:

export DYLD_FRAMEWORK_PATH="${HOME}/builds/Debug" # or whatever your build directory settings are

If the code in the framework changes, we can rebuild them in XCode, or use the command line:

xcodebuild -project MyApp.xcodeproj -target MyFramework

Programming Cocoa With MacRuby: Part One

In this series of articles, I will work through the Pragmatic Programmer book Programming Cocoa with Ruby by Brian Marick, porting the examples to MacRuby.

Examples from Chapter 2

The first few examples are almost identical. require 'osx/cocoa' becomes framework 'cocoa'. MacRuby lets us use the familiar SomeObject.new instead of SomeObject.alloc.init, and there is no need to explicitly inherit from NSObject, since NSObject replaces Object in the standard class hierarchy:

irb(main):011:0> class Foo;end;Foo.ancestors
=> [Foo, NSObject, Kernel]
irb(main):012:0>

most-basic-app.rb

#!/usr/bin/env macruby
framework 'cocoa'
NSApplication.sharedApplication
NSApp.run

no-ui.rb

#!/usr/bin/env macruby
framework 'cocoa'

class AppDelegate
  def applicationDidFinishLaunching(aNotification)
    puts "#{aNotification.name} makes me say: Hello, world"
  end
end

our_object = AppDelegate.new
NSApplication.sharedApplication
NSApp.setDelegate(our_object)
NSApp.run

Pages: 1 2 3

Return top

Web Application Developer

LastObelus hacks on web applications for enterprise. Usually in Rails or Merb these days, but he has worked WebObjects, J2EE, and various PHP frameworks.