DLog

Yet another blog of dismory, mainly on Objective-C Ruby and RubyMotion

How to Create an OS X Console App With RubyMotion

| Comments

Frankly speaking, the approach I am talking about here is to create a Mac console-like application as we are not able to build a real Mac console application using RubyMotion when I post this article.

It takes only 3 steps, let’s get started.

Firstly, create a RubyMotion project using OS X template. In my example, I call it ConsoleMotion:

1
$ motion create --template=osx ConsoleMotion

Secondly, edit the Rakefile and add the following lines of code:

1
2
3
4
5
6
7
8
9
# -*- coding: utf-8 -*-
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project/template/osx'

Motion::Project::App.setup do |app|
  # Use `rake config' to see complete project settings.
  app.name = 'ConsoleMotion'
  app.info_plist['LSUIElement'] = true # Add this line
end

When the LSUIElement property of your application’s info plist is set to true, your app will not appear in the Dock as the documentation says.

Thirdly, edit the app_delegate.rb and implement applicationDidFinishLaunching method as follows:

1
2
3
4
5
6
7
8
9
10
11
class AppDelegate
  def applicationDidFinishLaunching(notification)
    args = NSProcessInfo.processInfo.arguments # get the arguments passing to your console-like app
    str = args[1] || "hello world"

    # do whatever you want here
    p str

    exit # exit the app when you finish your job
  end
end

the key point is the exit function which quits your app when jobs finish like what the normal console apps do.

Next, build your app and run the executable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ rake
     Build ./build/MacOSX-10.8-Development
   Compile ./app/app_delegate.rb
   Compile ./app/menu.rb
    Create ./build/MacOSX-10.8-Development/ConsoleMotion.app/Contents
    Create ./build/MacOSX-10.8-Development/ConsoleMotion.app/Contents/MacOS
      Link ./build/MacOSX-10.8-Development/ConsoleMotion.app/Contents/MacOS/ConsoleMotion
    Create ./build/MacOSX-10.8-Development/ConsoleMotion.app/Contents/Info.plist
    Create ./build/MacOSX-10.8-Development/ConsoleMotion.app/Contents/PkgInfo
      Copy ./resources/Credits.rtf
    Create ./build/MacOSX-10.8-Development/ConsoleMotion.dSYM
       Run ./build/MacOSX-10.8-Development/ConsoleMotion.app/Contents/MacOS/ConsoleMotion
"hello world"
$ ./build/MacOSX-10.8-Development/ConsoleMotion.app/Contents/MacOS/ConsoleMotion "we're done"
"we're done"

That’s it.

说说 Objective-C 里的 @()

| Comments

Intro

在 Objective-C 中我们可以用 @"foo" 来创建一个 NSString 常量,看起来似乎平淡无奇。

但它背后其实比想象的精彩,@ 可以被理解成一个特殊的宏,其接受一个 C 字符串作为参数,也可写作 @("foo")

之所以说 @ 是一个特殊的宏,是因为其能根据传入的 C 字符串类型不同——C 字符串常量或 C 字符串——在运行时构建返回不同类型的 NSString,参见下面的代码:

1
2
3
4
5
6
7
8
char* obtain_c_string(void)
{
  return "c_string";
}

NSLog(@"%@", @"foo".class);
NSLog(@"%@", @("bar").class);
NSLog(@"%@", @(obtain_c_string()).class);

输出结果如下:

1
2
3
2013-06-05 01:14:15.097 Sandbox[45804:c07] __NSCFConstantString
2013-06-05 01:14:15.098 Sandbox[45804:c07] __NSCFConstantString
2013-06-05 01:14:15.098 Sandbox[45804:c07] __NSCFString

可见,如果传入的是 C 字符串常量,运行时构建的则为 NSConstantString;如果传入的是 C 字符串则创建的是 NSString

Then?

你可能会问这么理解了又怎样?