SlideShare ist ein Scribd-Unternehmen logo
1 von 93
Downloaden Sie, um offline zu lesen
Ruby and Cocoa
 Facilitate development on OSX
About me
About me
Rapperswil
http://www.flickr.com/photos/turtlemom_nancy/4026208166/sizes/l/
huesler informatik
huesler informatik

upstream agile
huesler informatik

upstream agile

co-up.de
Ruby and Cocoa
Ruby
passionate
  http://www.flickr.com/photos/gi/378823/sizes/o/
Apple OSX
passionate
  http://www.flickr.com/photos/gi/378823/sizes/o/
Landscape
 http://www.flickr.com/photos/kiumo/4203883504/sizes/o/
Cocoa
http://www.flickr.com/photos/luder5/4100921399/sizes/l/
Cocoa
Cocoa
•   Core Foundation
Cocoa
•   Core Foundation
•   Appkit
Cocoa
•   Core Foundation
•   Appkit
•   Core * (Audio/Video/Image/Data
    etc.)
Cocoa
•   Core Foundation
•   Appkit
•   Core * (Audio/Video/Image/Data
    etc.)
•   Scripting bridge
Cocoa
•   Core Foundation
•   Appkit
•   Core * (Audio/Video/Image/Data
    etc.)
•   Scripting bridge
•   others
Interface Builder
XCode
Objective-C
NSMutableArray *anArray = [
      [NSMutableArray alloc]   init
    ];
[anArray addObject:@"Element   1"];
[anArray addObject:@"Element   2"];
[anArray addObject:@"Element   3"];

//Use a for each loop to iterate
through the array
for (NSString *s in anArray) {
     NSLog(s);
}
//Release the array
[anArray release]
Ruby And Cocoa
Ruby Cocoa
HotCocoa
picture shamelessly cropped from http://www.slideshare.net/mattetti/macruby-hotcocoa-presentation-by-rich-kilmer
Scripting Bridge
    http://www.flickr.com/photos/bensonkua/2851908095/sizes/l/
Good to know
Good to know
•   Available commands for each
    application are in a .sdef file
Good to know
•   Available commands for each
    application are in a .sdef file
•   Terminal.app/Contents/Resources/
    Terminal.sdef
Good to know
•   Available commands for each
    application are in a .sdef file
•   Terminal.app/Contents/Resources/
    Terminal.sdef
•   gem rb-appscript (native extension
    so not for MacRuby)
1 <command name="do script" code="coredosc"
 2     description="Runs a UNIX shell script or command.">
 3     <cocoa class="TTDoScriptCommand"/>
 4     <direct-parameter type="text"
 5         description="The command to execute." optional="yes"/>
 6     <parameter name="with command"
 7         description="Data to be passed to the Terminal..."
 8         code="cmnd" optional="yes" hidden="yes">
 9         <cocoa key="Command" />
10         <type type="text" />
11         <type type="any" /> <!-- support null case -->
12     </parameter>
13     <parameter name="in"
14         description="The tab in which to execute the command"
15         code="kfil" optional="yes">
16         <cocoa key="Target" />
17         <type type="tab" />
18         <type type="window" />
19         <type type="any" /> <!-- support null case -->
20     </parameter>
21     <result type="tab"
22         description="The tab the command was executed in." />
23 </command>
24
Control Terminal
1 #!/usr/bin/env ruby
    2 require 'rubygems'
    3 require 'appscript'
    4 include Appscript
    5
    6 terminal = app('Terminal')
    7 current_window = terminal.windows.first
    8 current_tab = current_window.tabs.last
    9 process = app("System
Events").application_processes[
   10   "Terminal.app"
   11   ]
   12
   13 process.keystroke('t', :using => :command_down)
   14 terminal.do_script('top', :in => current_tab)
1 #!/usr/bin/env ruby
    2 require 'rubygems'
    3 require 'appscript'
    4 include Appscript
    5
    6 terminal = app('Terminal')
    7 current_window = terminal.windows.first
    8 current_tab = current_window.tabs.last
    9 process = app("System
Events").application_processes[
   10   "Terminal.app"
   11   ]
   12
   13 process.keystroke('t', :using => :command_down)
   14 terminal.do_script('top', :in => current_tab)
1 #!/usr/bin/env ruby
    2 require 'rubygems'
    3 require 'appscript'
    4 include Appscript
    5
    6 terminal = app('Terminal')
    7 current_window = terminal.windows.first
    8 current_tab = current_window.tabs.last
    9 process = app("System
Events").application_processes[
   10   "Terminal.app"
   11   ]
   12
   13 process.keystroke('t', :using => :command_down)
   14 terminal.do_script('top', :in => current_tab)
7 current_window = terminal.windows.first
    8 current_tab = current_window.tabs.last
    9 process = app("System
Events").application_processes[
   10   "Terminal.app"
   11   ]
   12
   13 process.keystroke('t', :using => :command_down)
   14 terminal.do_script('top', :in => current_tab)
Problems with MacRuby
Problems with MacRuby
Problems with MacRuby

•   Some methods don’t seem to be
    available
iTunes
1 #!/usr/bin/env macruby
    2
    3 framework 'ScriptingBridge'
    4
    5 itunes =
SBApplication.applicationWithBundleIdentifier(
    6   "com.apple.iTunes"
    7 )
    8 library = itunes.sources.objectWithName
("Library")
    9
   10 library.userPlaylists.each do |playlist|
   11   puts playlist.name
   12 end
2
    3 framework 'ScriptingBridge'
    4
    5 itunes =
SBApplication.applicationWithBundleIdentifier(
    6   "com.apple.iTunes"
    7 )
    8 library = itunes.sources.objectWithName
("Library")
    9
   10 library.userPlaylists.each do |playlist|
   11   puts playlist.name
   12 end
2
    3 framework 'ScriptingBridge'
    4
    5 itunes =
SBApplication.applicationWithBundleIdentifier(
    6   "com.apple.iTunes"
    7 )
    8 library = itunes.sources.objectWithName
("Library")
    9
   10 library.userPlaylists.each do |playlist|
   11   puts playlist.name
   12 end
Core Location
1   #!/usr/bin/env macruby
 2   framework 'CoreLocation'
 3
 4   loc = CLLocationManager.alloc.init
 5   loc.delegate = self
 6   loc.startUpdatingLocation
 7
 8   # keep the script running
 9   NSRunLoop.currentRunLoop.runUntilDate(
10     NSDate.distantFuture
11   )
1   #!/usr/bin/env macruby
 2   framework 'CoreLocation'
 3
 4   loc = CLLocationManager.alloc.init
 5   loc.delegate = self
 6   loc.startUpdatingLocation
 7
 8   # keep the script running
 9   NSRunLoop.currentRunLoop.runUntilDate(
10     NSDate.distantFuture
11   )
1 def locationManager(
2         manager,
3         didUpdateToLocation: new_location,
4         fromLocation: old_location
5   )
6
7   puts "loc: #{new_location.description}"
8 end
2   framework 'CoreLocation'
 3
 4   loc = CLLocationManager.alloc.init
 5   loc.delegate = self
 6   loc.startUpdatingLocation
 7
 8   # keep the script running
 9   NSRunLoop.currentRunLoop.runUntilDate(
10     NSDate.distantFuture
11   )
1   #!/usr/bin/env macruby
 2   framework 'CoreLocation'
 3
 4   def locationManager(manager,
 5                        didUpdateToLocation: new_location,
 6                        fromLocation: old_location
 7                      )
 8     puts "location: #{new_location.description}"
 9   end
10
11   loc = CLLocationManager.alloc.init
12   loc.delegate = self
13   loc.startUpdatingLocation
14
15   # keep the script running
16   NSRunLoop.currentRunLoop.runUntilDate(
17     NSDate.distantFuture
18   )
Grand Central
  Dispatch
Grand Central Dispatch
Grand Central Dispatch
•   MacRuby only
Grand Central Dispatch
•   MacRuby only
•   Synchronous
Grand Central Dispatch
•   MacRuby only
•   Synchronous
•   Asynchronous
Grand Central Dispatch
•   MacRuby only
•   Synchronous
•   Asynchronous
•   Parallel
Grand Central Dispatch
•   MacRuby only
•   Synchronous
•   Asynchronous
•   Parallel
•   Synchronization
Asynchronous
1   #!/usr/bin/env macruby
 2
 3   queue = Dispatch::Queue.new(
 4       'ch.huesler-informatik.scotrubyconf.gcd'
 5     )
 6
 7   queue.async do
 8     puts 'Starting asyn. NONE BLOCKING!'
 9     sleep 2.00
10     puts "Finished asyn"
11   end
12   puts "code not being blocked"
13
14   NSRunLoop.currentRunLoop.runUntilDate(
15       NSDate.distantFuture
16     )
17
1   #!/usr/bin/env macruby
 2
 3   queue = Dispatch::Queue.new(
 4       'ch.huesler-informatik.scotrubyconf.gcd'
 5     )
 6
 7   queue.async do
 8     puts 'Starting asyn. NONE BLOCKING!'
 9     sleep 2.00
10     puts "Finished asyn"
11   end
12   puts "code not being blocked"
13
14   NSRunLoop.currentRunLoop.runUntilDate(
15       NSDate.distantFuture
16     )
17
7   queue.async do
 8     puts 'Starting asyn. NONE BLOCKING!'
 9     sleep 2.00
10     puts "Finished asyn"
11   end
12   puts "code not being blocked"
13
14   NSRunLoop.currentRunLoop.runUntilDate(
15       NSDate.distantFuture
16     )
17
Synchronous
1   #!/usr/bin/env macruby
 2
 3   queue = Dispatch::Queue.new(
 4       'ch.huesler-informatik.scotrubyconf.gcd'
 5     )
 6
 7   queue.sync do
 8     puts 'Starting sync. BLOCKING!'
 9     sleep 3.0
10     puts 'Finished sync'
11   end
12   puts "code being blocked"
13
14   NSRunLoop.currentRunLoop.runUntilDate(
15       NSDate.distantFuture
16     )
17
Synchronized
1   #!/usr/bin/env macruby
 2
 3   worker_queue = Dispatch::Queue.new(
 4       'ch.huesler-informatik.scotrubyconf.gcd'
 5     )
 6   group = Dispatch::Group.new
 7
 8   0.upto(10) do |i|
 9     puts "Dispatch #{i} to GCD"
10     worker_queue.async(group) do
11       puts "working on #{i}"
12     end
13   end
14   puts "waiting for gcd"
15   group.wait
16   puts "done"
17
1   #!/usr/bin/env macruby
 2
 3   worker_queue = Dispatch::Queue.new(
 4       'ch.huesler-informatik.scotrubyconf.gcd'
 5     )
 6   group = Dispatch::Group.new
 7
 8   0.upto(10) do |i|
 9     puts "Dispatch #{i} to GCD"
10     worker_queue.async(group) do
11       puts "working on #{i}"
12     end
13   end
14   puts "waiting for gcd"
15   group.wait
16   puts "done"
17
7
 8   0.upto(10) do |i|
 9     puts "Dispatch #{i} to GCD"
10     worker_queue.async(group) do
11       puts "working on #{i}"
12     end
13   end
14   puts "waiting for gcd"
15   group.wait
16   puts "done"
17
Concurrent
1   #!/usr/bin/env macruby
 2
 3   group = Dispatch::Group.new
 4   result = []
 5   1.upto(10).each do |i|
 6     Dispatch::Queue.concurrent.async(group) do
 7       sleep 2
 8       result << i
 9     end
10   end
11   group.wait
12   puts result.inspect
.plist files
1 #!/usr/bin/env ruby
    2 require "osx/cocoa"
    3 include OSX
    4
    5 file_name = 'Info.plist'
    6 plist =
NSDictionary.dictionaryWithContentsOfFile(
    7            file_name
    8          )
    9
   10 plist['CFBundleVersion'] = '2.0.1'
   11
   12 plist.writeToFile_atomically(
   13     file_name,
   14     true
   15   )
1 #!/usr/bin/env ruby
    2 require "osx/cocoa"
    3 include OSX
    4
    5 file_name = 'Info.plist'
    6 plist =
NSDictionary.dictionaryWithContentsOfFile(
    7            file_name
    8          )
    9
   10 plist['CFBundleVersion'] = '2.0.1'
   11
   12 plist.writeToFile_atomically(
   13     file_name,
   14     true
   15   )
3 include OSX
    4
    5 file_name = 'Info.plist'
    6 plist =
NSDictionary.dictionaryWithContentsOfFile(
    7            file_name
    8          )
    9
   10 plist['CFBundleVersion'] = '2.0.1'
   11
   12 plist.writeToFile_atomically(
   13     file_name,
   14     true
   15   )
Keychain
 Access
Details
Details
•   MacRuby has issues with void
    pointer (patch pending)
Details
•   MacRuby has issues with void
    pointer (patch pending)
•   Use objective c wrapper instead
    (dynlib or bundle)
Details
•   MacRuby has issues with void
    pointer (patch pending)
•   Use objective c wrapper instead
    (dynlib or bundle)
•   Generate metadata to make it
    work
Details
•   MacRuby has issues with void
    pointer (patch pending)
•   Use objective c wrapper instead
    (dynlib or bundle)
•   Generate metadata to make it
    work
1 export FILE_PATH = ~/Library/BridgeSupport
    2 export FRAMEWORK_PATH = ~/Library/BridgeSupport/
Security.bridgesupport
    3 mkdir $FILE_PATH
    4 gen_bridge_metadata -f Security -o $FRAMEWORK_PATH
1   require 'osx/cocoa'
 2   include OSX
 3   require_framework 'Security'
 4
 5   # Set up some relevant variables
 6
 7   service = "ch.huesler-informatik.scotrubyconf.keychain"
 8   account = "Highlander"
 9   original_password = "Rrrueby"
10
11   # Add password
12   SecKeychainAddGenericPassword(
13       nil,
14       service.length,
15       service,
16       account.length,
17       account,
18       original_password.length,
19       original_password,
20       nil
21   )
1   require 'osx/cocoa'
 2   include OSX
 3   require_framework 'Security'
 4
 5   # Set up some relevant variables
 6
 7   service = "ch.huesler-informatik.scotrubyconf.keychain"
 8   account = "Highlander"
 9   original_password = "Rrrueby"
10
11   # Add password
12   SecKeychainAddGenericPassword(
13       nil,
14       service.length,
15       service,
16       account.length,
17       account,
18       original_password.length,
19       original_password,
20       nil
21   )
1 # Add password
 2 SecKeychainAddGenericPassword(
 3     nil,
 4     service.length,
 5     service,
 6     account.length,
 7     account,
 8     original_password.length,
 9     original_password,
10     nil
11 )
1 # Query   the keychain
2 status,   *password = SecKeychainFindGenericPassword(
3           nil,
4           service.length,
5           service,
6           account.length,
7           account
8       )
1   # Password-related data. Shifting pointers
2   length = password.shift
3   data = password.shift
4   plain_password = data.bytestr(length)
5
6   puts "Password: #{plain_password}"
That’s all!
Questions?

Weitere ähnliche Inhalte

Was ist angesagt?

Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsYandex
 
Adventures in infrastructure as code
Adventures in infrastructure as codeAdventures in infrastructure as code
Adventures in infrastructure as codeJulian Simpson
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Zend by Rogue Wave Software
 
YASPS OPENNING
YASPS OPENNINGYASPS OPENNING
YASPS OPENNINGJeen Lee
 
Better detection of what modules are used by some Perl 5 code
Better detection of what modules are used by some Perl 5 codeBetter detection of what modules are used by some Perl 5 code
Better detection of what modules are used by some Perl 5 codecharsbar
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidenceJohn Congdon
 
PL/Perl - New Features in PostgreSQL 9.0 201012
PL/Perl - New Features in PostgreSQL 9.0 201012PL/Perl - New Features in PostgreSQL 9.0 201012
PL/Perl - New Features in PostgreSQL 9.0 201012Tim Bunce
 
How to inspect a RUNNING perl process
How to inspect a RUNNING perl processHow to inspect a RUNNING perl process
How to inspect a RUNNING perl processMasaaki HIROSE
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)Robert Swisher
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)xSawyer
 
DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101Jan Stamer
 
entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101Jan Stamer
 
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystembetterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystemJan Stamer
 
DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environmentEvaldo Felipe
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPANcharsbar
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingSteve Rhoades
 
Php assíncrono com_react_php
Php assíncrono com_react_phpPhp assíncrono com_react_php
Php assíncrono com_react_phpRenato Lucena
 
Perl: Coro asynchronous
Perl: Coro asynchronous Perl: Coro asynchronous
Perl: Coro asynchronous Shmuel Fomberg
 

Was ist angesagt? (20)

Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.js
 
Adventures in infrastructure as code
Adventures in infrastructure as codeAdventures in infrastructure as code
Adventures in infrastructure as code
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
 
YASPS OPENNING
YASPS OPENNINGYASPS OPENNING
YASPS OPENNING
 
Better detection of what modules are used by some Perl 5 code
Better detection of what modules are used by some Perl 5 codeBetter detection of what modules are used by some Perl 5 code
Better detection of what modules are used by some Perl 5 code
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidence
 
PL/Perl - New Features in PostgreSQL 9.0 201012
PL/Perl - New Features in PostgreSQL 9.0 201012PL/Perl - New Features in PostgreSQL 9.0 201012
PL/Perl - New Features in PostgreSQL 9.0 201012
 
How to inspect a RUNNING perl process
How to inspect a RUNNING perl processHow to inspect a RUNNING perl process
How to inspect a RUNNING perl process
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)
 
DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101DevOpsCon 2021: Go Web Development 101
DevOpsCon 2021: Go Web Development 101
 
entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101entwickler.de Go Day: Go Web Development 101
entwickler.de Go Day: Go Web Development 101
 
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und ÖkosystembetterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
betterCode() Go: Einstieg in Go, Standard-Library und Ökosystem
 
DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environment
 
Shell Script
Shell ScriptShell Script
Shell Script
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time Messaging
 
Php assíncrono com_react_php
Php assíncrono com_react_phpPhp assíncrono com_react_php
Php assíncrono com_react_php
 
Anyevent
AnyeventAnyevent
Anyevent
 
Perl: Coro asynchronous
Perl: Coro asynchronous Perl: Coro asynchronous
Perl: Coro asynchronous
 

Andere mochten auch

Edisi 12 Medan
Edisi 12 MedanEdisi 12 Medan
Edisi 12 Medanepaper
 
15jan Aceh
15jan Aceh15jan Aceh
15jan Acehepaper
 
BI Portfolio
BI PortfolioBI Portfolio
BI Portfoliotcomeaux
 
Fvcp Presentation Openoffice
Fvcp Presentation OpenofficeFvcp Presentation Openoffice
Fvcp Presentation OpenofficeStraight North
 
Edisi1oktaceh
Edisi1oktacehEdisi1oktaceh
Edisi1oktacehepaper
 
Credit Its A Brand New Day
Credit Its A Brand New DayCredit Its A Brand New Day
Credit Its A Brand New DayAndre Williams
 
Edisi Nasional 27 Maret
Edisi Nasional 27 MaretEdisi Nasional 27 Maret
Edisi Nasional 27 Maretepaper
 
Edisi 28 Medan
Edisi 28 MedanEdisi 28 Medan
Edisi 28 Medanepaper
 
Edisi 7 Feb 2010
Edisi 7 Feb 2010Edisi 7 Feb 2010
Edisi 7 Feb 2010epaper
 
12jan Aceh
12jan Aceh12jan Aceh
12jan Acehepaper
 
TIM Day in NY
TIM Day in NYTIM Day in NY
TIM Day in NYTIM RI
 
Edisi 2 Maret Medan
Edisi 2 Maret MedanEdisi 2 Maret Medan
Edisi 2 Maret Medanepaper
 
2 Des Aceh
2 Des Aceh2 Des Aceh
2 Des Acehepaper
 
Skapa en sökmotorvänlig webbplats!
Skapa en sökmotorvänlig webbplats!Skapa en sökmotorvänlig webbplats!
Skapa en sökmotorvänlig webbplats!Guava Sweden
 
Edisi 1 Maret Medan
Edisi 1 Maret MedanEdisi 1 Maret Medan
Edisi 1 Maret Medanepaper
 
Top Flex 7 Unit One- phrasal verbs
Top Flex 7 Unit One- phrasal verbsTop Flex 7 Unit One- phrasal verbs
Top Flex 7 Unit One- phrasal verbsDaniela Lyra Cardoso
 
Webinarium affiliate
Webinarium affiliateWebinarium affiliate
Webinarium affiliateGuava Sweden
 

Andere mochten auch (20)

Edisi 12 Medan
Edisi 12 MedanEdisi 12 Medan
Edisi 12 Medan
 
15jan Aceh
15jan Aceh15jan Aceh
15jan Aceh
 
BI Portfolio
BI PortfolioBI Portfolio
BI Portfolio
 
Fvcp Presentation Openoffice
Fvcp Presentation OpenofficeFvcp Presentation Openoffice
Fvcp Presentation Openoffice
 
Edisi1oktaceh
Edisi1oktacehEdisi1oktaceh
Edisi1oktaceh
 
Credit Its A Brand New Day
Credit Its A Brand New DayCredit Its A Brand New Day
Credit Its A Brand New Day
 
Ocean lifeguard expo 2010
Ocean lifeguard expo 2010Ocean lifeguard expo 2010
Ocean lifeguard expo 2010
 
Edisi Nasional 27 Maret
Edisi Nasional 27 MaretEdisi Nasional 27 Maret
Edisi Nasional 27 Maret
 
Edisi 28 Medan
Edisi 28 MedanEdisi 28 Medan
Edisi 28 Medan
 
Severe Weather2010 Mar12
Severe Weather2010 Mar12Severe Weather2010 Mar12
Severe Weather2010 Mar12
 
Edisi 7 Feb 2010
Edisi 7 Feb 2010Edisi 7 Feb 2010
Edisi 7 Feb 2010
 
12jan Aceh
12jan Aceh12jan Aceh
12jan Aceh
 
TIM Day in NY
TIM Day in NYTIM Day in NY
TIM Day in NY
 
Stres
StresStres
Stres
 
Edisi 2 Maret Medan
Edisi 2 Maret MedanEdisi 2 Maret Medan
Edisi 2 Maret Medan
 
2 Des Aceh
2 Des Aceh2 Des Aceh
2 Des Aceh
 
Skapa en sökmotorvänlig webbplats!
Skapa en sökmotorvänlig webbplats!Skapa en sökmotorvänlig webbplats!
Skapa en sökmotorvänlig webbplats!
 
Edisi 1 Maret Medan
Edisi 1 Maret MedanEdisi 1 Maret Medan
Edisi 1 Maret Medan
 
Top Flex 7 Unit One- phrasal verbs
Top Flex 7 Unit One- phrasal verbsTop Flex 7 Unit One- phrasal verbs
Top Flex 7 Unit One- phrasal verbs
 
Webinarium affiliate
Webinarium affiliateWebinarium affiliate
Webinarium affiliate
 

Ähnlich wie Fun with Ruby and Cocoa

From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016Susan Potter
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxbobmcwhirter
 
Advanced JavaScript Development
Advanced JavaScript DevelopmentAdvanced JavaScript Development
Advanced JavaScript DevelopmentJussi Pohjolainen
 
Bulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & CouchbaseBulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & CouchbaseAlex Derkach
 
DevOps in PHP environment
DevOps in PHP environment DevOps in PHP environment
DevOps in PHP environment Evaldo Felipe
 
Node.js basics
Node.js basicsNode.js basics
Node.js basicsBen Lin
 
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf Conference
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Getting Started with iBeacons (Designers of Things 2014)
Getting Started with iBeacons (Designers of Things 2014)Getting Started with iBeacons (Designers of Things 2014)
Getting Started with iBeacons (Designers of Things 2014)Daniel Luxemburg
 
Splunk n-box-splunk conf-2017
Splunk n-box-splunk conf-2017Splunk n-box-splunk conf-2017
Splunk n-box-splunk conf-2017Mohamad Hassan
 
Continuous Delivery: The Next Frontier
Continuous Delivery: The Next FrontierContinuous Delivery: The Next Frontier
Continuous Delivery: The Next FrontierCarlos Sanchez
 
MINCS - containers in the shell script (Eng. ver.)
MINCS - containers in the shell script (Eng. ver.)MINCS - containers in the shell script (Eng. ver.)
MINCS - containers in the shell script (Eng. ver.)Masami Hiramatsu
 
Présentation "Docker + Kubernetes" @ Pastis.tech #2
Présentation "Docker + Kubernetes" @ Pastis.tech #2Présentation "Docker + Kubernetes" @ Pastis.tech #2
Présentation "Docker + Kubernetes" @ Pastis.tech #2Blue Forest
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.Mike Brevoort
 
No Callbacks, No Threads - RailsConf 2010
No Callbacks, No Threads - RailsConf 2010No Callbacks, No Threads - RailsConf 2010
No Callbacks, No Threads - RailsConf 2010Ilya Grigorik
 

Ähnlich wie Fun with Ruby and Cocoa (20)

From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBox
 
Advanced JavaScript Development
Advanced JavaScript DevelopmentAdvanced JavaScript Development
Advanced JavaScript Development
 
infra-as-code
infra-as-codeinfra-as-code
infra-as-code
 
Bulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & CouchbaseBulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & Couchbase
 
DevOps in PHP environment
DevOps in PHP environment DevOps in PHP environment
DevOps in PHP environment
 
Node.js basics
Node.js basicsNode.js basics
Node.js basics
 
Vagrant for real
Vagrant for realVagrant for real
Vagrant for real
 
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
ZFConf 2012: Capistrano для деплоймента PHP-приложений (Роман Лапин)
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Getting Started with iBeacons (Designers of Things 2014)
Getting Started with iBeacons (Designers of Things 2014)Getting Started with iBeacons (Designers of Things 2014)
Getting Started with iBeacons (Designers of Things 2014)
 
Splunk n-box-splunk conf-2017
Splunk n-box-splunk conf-2017Splunk n-box-splunk conf-2017
Splunk n-box-splunk conf-2017
 
MyShell - English
MyShell - EnglishMyShell - English
MyShell - English
 
Continuous Delivery: The Next Frontier
Continuous Delivery: The Next FrontierContinuous Delivery: The Next Frontier
Continuous Delivery: The Next Frontier
 
MINCS - containers in the shell script (Eng. ver.)
MINCS - containers in the shell script (Eng. ver.)MINCS - containers in the shell script (Eng. ver.)
MINCS - containers in the shell script (Eng. ver.)
 
Présentation "Docker + Kubernetes" @ Pastis.tech #2
Présentation "Docker + Kubernetes" @ Pastis.tech #2Présentation "Docker + Kubernetes" @ Pastis.tech #2
Présentation "Docker + Kubernetes" @ Pastis.tech #2
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
 
No Callbacks, No Threads - RailsConf 2010
No Callbacks, No Threads - RailsConf 2010No Callbacks, No Threads - RailsConf 2010
No Callbacks, No Threads - RailsConf 2010
 

Mehr von Patrick Huesler

Technical Challenges of Developing a Facebook Game
Technical Challenges of Developing a Facebook GameTechnical Challenges of Developing a Facebook Game
Technical Challenges of Developing a Facebook GamePatrick Huesler
 
Culerity and Headless Full Stack Integration Testing
Culerity and Headless Full Stack Integration TestingCulerity and Headless Full Stack Integration Testing
Culerity and Headless Full Stack Integration TestingPatrick Huesler
 
Client Side Optimization
Client Side OptimizationClient Side Optimization
Client Side OptimizationPatrick Huesler
 
Building and deploying Cocoa applications with ChocTop
Building and deploying Cocoa applications with ChocTopBuilding and deploying Cocoa applications with ChocTop
Building and deploying Cocoa applications with ChocTopPatrick Huesler
 
Choctop Lightning talk EuRuKo 2010
Choctop Lightning talk EuRuKo 2010Choctop Lightning talk EuRuKo 2010
Choctop Lightning talk EuRuKo 2010Patrick Huesler
 
Small Cocoa Apps with MacRuby
Small Cocoa Apps with MacRubySmall Cocoa Apps with MacRuby
Small Cocoa Apps with MacRubyPatrick Huesler
 

Mehr von Patrick Huesler (9)

Technical Challenges of Developing a Facebook Game
Technical Challenges of Developing a Facebook GameTechnical Challenges of Developing a Facebook Game
Technical Challenges of Developing a Facebook Game
 
Culerity and Headless Full Stack Integration Testing
Culerity and Headless Full Stack Integration TestingCulerity and Headless Full Stack Integration Testing
Culerity and Headless Full Stack Integration Testing
 
Client Side Optimization
Client Side OptimizationClient Side Optimization
Client Side Optimization
 
Building and deploying Cocoa applications with ChocTop
Building and deploying Cocoa applications with ChocTopBuilding and deploying Cocoa applications with ChocTop
Building and deploying Cocoa applications with ChocTop
 
Choctop Lightning talk EuRuKo 2010
Choctop Lightning talk EuRuKo 2010Choctop Lightning talk EuRuKo 2010
Choctop Lightning talk EuRuKo 2010
 
Small Cocoa Apps with MacRuby
Small Cocoa Apps with MacRubySmall Cocoa Apps with MacRuby
Small Cocoa Apps with MacRuby
 
Erlang, an overview
Erlang, an overviewErlang, an overview
Erlang, an overview
 
Migrating legacy data
Migrating legacy dataMigrating legacy data
Migrating legacy data
 
Active Record No No's
Active Record No No'sActive Record No No's
Active Record No No's
 

Kürzlich hochgeladen

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 

Kürzlich hochgeladen (20)

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 

Fun with Ruby and Cocoa

  • 1. Ruby and Cocoa Facilitate development on OSX
  • 10. Ruby
  • 13.
  • 17. Cocoa
  • 18. Cocoa • Core Foundation
  • 19. Cocoa • Core Foundation • Appkit
  • 20. Cocoa • Core Foundation • Appkit • Core * (Audio/Video/Image/Data etc.)
  • 21. Cocoa • Core Foundation • Appkit • Core * (Audio/Video/Image/Data etc.) • Scripting bridge
  • 22. Cocoa • Core Foundation • Appkit • Core * (Audio/Video/Image/Data etc.) • Scripting bridge • others
  • 24. XCode
  • 26. NSMutableArray *anArray = [ [NSMutableArray alloc] init ]; [anArray addObject:@"Element 1"]; [anArray addObject:@"Element 2"]; [anArray addObject:@"Element 3"]; //Use a for each loop to iterate through the array for (NSString *s in anArray) { NSLog(s); } //Release the array [anArray release]
  • 27.
  • 29.
  • 31.
  • 32. HotCocoa picture shamelessly cropped from http://www.slideshare.net/mattetti/macruby-hotcocoa-presentation-by-rich-kilmer
  • 33. Scripting Bridge http://www.flickr.com/photos/bensonkua/2851908095/sizes/l/
  • 35. Good to know • Available commands for each application are in a .sdef file
  • 36. Good to know • Available commands for each application are in a .sdef file • Terminal.app/Contents/Resources/ Terminal.sdef
  • 37. Good to know • Available commands for each application are in a .sdef file • Terminal.app/Contents/Resources/ Terminal.sdef • gem rb-appscript (native extension so not for MacRuby)
  • 38. 1 <command name="do script" code="coredosc" 2 description="Runs a UNIX shell script or command."> 3 <cocoa class="TTDoScriptCommand"/> 4 <direct-parameter type="text" 5 description="The command to execute." optional="yes"/> 6 <parameter name="with command" 7 description="Data to be passed to the Terminal..." 8 code="cmnd" optional="yes" hidden="yes"> 9 <cocoa key="Command" /> 10 <type type="text" /> 11 <type type="any" /> <!-- support null case --> 12 </parameter> 13 <parameter name="in" 14 description="The tab in which to execute the command" 15 code="kfil" optional="yes"> 16 <cocoa key="Target" /> 17 <type type="tab" /> 18 <type type="window" /> 19 <type type="any" /> <!-- support null case --> 20 </parameter> 21 <result type="tab" 22 description="The tab the command was executed in." /> 23 </command> 24
  • 39.
  • 41. 1 #!/usr/bin/env ruby 2 require 'rubygems' 3 require 'appscript' 4 include Appscript 5 6 terminal = app('Terminal') 7 current_window = terminal.windows.first 8 current_tab = current_window.tabs.last 9 process = app("System Events").application_processes[ 10 "Terminal.app" 11 ] 12 13 process.keystroke('t', :using => :command_down) 14 terminal.do_script('top', :in => current_tab)
  • 42. 1 #!/usr/bin/env ruby 2 require 'rubygems' 3 require 'appscript' 4 include Appscript 5 6 terminal = app('Terminal') 7 current_window = terminal.windows.first 8 current_tab = current_window.tabs.last 9 process = app("System Events").application_processes[ 10 "Terminal.app" 11 ] 12 13 process.keystroke('t', :using => :command_down) 14 terminal.do_script('top', :in => current_tab)
  • 43. 1 #!/usr/bin/env ruby 2 require 'rubygems' 3 require 'appscript' 4 include Appscript 5 6 terminal = app('Terminal') 7 current_window = terminal.windows.first 8 current_tab = current_window.tabs.last 9 process = app("System Events").application_processes[ 10 "Terminal.app" 11 ] 12 13 process.keystroke('t', :using => :command_down) 14 terminal.do_script('top', :in => current_tab)
  • 44. 7 current_window = terminal.windows.first 8 current_tab = current_window.tabs.last 9 process = app("System Events").application_processes[ 10 "Terminal.app" 11 ] 12 13 process.keystroke('t', :using => :command_down) 14 terminal.do_script('top', :in => current_tab)
  • 47. Problems with MacRuby • Some methods don’t seem to be available
  • 49. 1 #!/usr/bin/env macruby 2 3 framework 'ScriptingBridge' 4 5 itunes = SBApplication.applicationWithBundleIdentifier( 6 "com.apple.iTunes" 7 ) 8 library = itunes.sources.objectWithName ("Library") 9 10 library.userPlaylists.each do |playlist| 11 puts playlist.name 12 end
  • 50. 2 3 framework 'ScriptingBridge' 4 5 itunes = SBApplication.applicationWithBundleIdentifier( 6 "com.apple.iTunes" 7 ) 8 library = itunes.sources.objectWithName ("Library") 9 10 library.userPlaylists.each do |playlist| 11 puts playlist.name 12 end
  • 51. 2 3 framework 'ScriptingBridge' 4 5 itunes = SBApplication.applicationWithBundleIdentifier( 6 "com.apple.iTunes" 7 ) 8 library = itunes.sources.objectWithName ("Library") 9 10 library.userPlaylists.each do |playlist| 11 puts playlist.name 12 end
  • 53. 1 #!/usr/bin/env macruby 2 framework 'CoreLocation' 3 4 loc = CLLocationManager.alloc.init 5 loc.delegate = self 6 loc.startUpdatingLocation 7 8 # keep the script running 9 NSRunLoop.currentRunLoop.runUntilDate( 10 NSDate.distantFuture 11 )
  • 54. 1 #!/usr/bin/env macruby 2 framework 'CoreLocation' 3 4 loc = CLLocationManager.alloc.init 5 loc.delegate = self 6 loc.startUpdatingLocation 7 8 # keep the script running 9 NSRunLoop.currentRunLoop.runUntilDate( 10 NSDate.distantFuture 11 )
  • 55. 1 def locationManager( 2 manager, 3 didUpdateToLocation: new_location, 4 fromLocation: old_location 5 ) 6 7 puts "loc: #{new_location.description}" 8 end
  • 56. 2 framework 'CoreLocation' 3 4 loc = CLLocationManager.alloc.init 5 loc.delegate = self 6 loc.startUpdatingLocation 7 8 # keep the script running 9 NSRunLoop.currentRunLoop.runUntilDate( 10 NSDate.distantFuture 11 )
  • 57. 1 #!/usr/bin/env macruby 2 framework 'CoreLocation' 3 4 def locationManager(manager, 5 didUpdateToLocation: new_location, 6 fromLocation: old_location 7 ) 8 puts "location: #{new_location.description}" 9 end 10 11 loc = CLLocationManager.alloc.init 12 loc.delegate = self 13 loc.startUpdatingLocation 14 15 # keep the script running 16 NSRunLoop.currentRunLoop.runUntilDate( 17 NSDate.distantFuture 18 )
  • 58. Grand Central Dispatch
  • 61. Grand Central Dispatch • MacRuby only • Synchronous
  • 62. Grand Central Dispatch • MacRuby only • Synchronous • Asynchronous
  • 63. Grand Central Dispatch • MacRuby only • Synchronous • Asynchronous • Parallel
  • 64. Grand Central Dispatch • MacRuby only • Synchronous • Asynchronous • Parallel • Synchronization
  • 66. 1 #!/usr/bin/env macruby 2 3 queue = Dispatch::Queue.new( 4 'ch.huesler-informatik.scotrubyconf.gcd' 5 ) 6 7 queue.async do 8 puts 'Starting asyn. NONE BLOCKING!' 9 sleep 2.00 10 puts "Finished asyn" 11 end 12 puts "code not being blocked" 13 14 NSRunLoop.currentRunLoop.runUntilDate( 15 NSDate.distantFuture 16 ) 17
  • 67. 1 #!/usr/bin/env macruby 2 3 queue = Dispatch::Queue.new( 4 'ch.huesler-informatik.scotrubyconf.gcd' 5 ) 6 7 queue.async do 8 puts 'Starting asyn. NONE BLOCKING!' 9 sleep 2.00 10 puts "Finished asyn" 11 end 12 puts "code not being blocked" 13 14 NSRunLoop.currentRunLoop.runUntilDate( 15 NSDate.distantFuture 16 ) 17
  • 68. 7 queue.async do 8 puts 'Starting asyn. NONE BLOCKING!' 9 sleep 2.00 10 puts "Finished asyn" 11 end 12 puts "code not being blocked" 13 14 NSRunLoop.currentRunLoop.runUntilDate( 15 NSDate.distantFuture 16 ) 17
  • 70. 1 #!/usr/bin/env macruby 2 3 queue = Dispatch::Queue.new( 4 'ch.huesler-informatik.scotrubyconf.gcd' 5 ) 6 7 queue.sync do 8 puts 'Starting sync. BLOCKING!' 9 sleep 3.0 10 puts 'Finished sync' 11 end 12 puts "code being blocked" 13 14 NSRunLoop.currentRunLoop.runUntilDate( 15 NSDate.distantFuture 16 ) 17
  • 72. 1 #!/usr/bin/env macruby 2 3 worker_queue = Dispatch::Queue.new( 4 'ch.huesler-informatik.scotrubyconf.gcd' 5 ) 6 group = Dispatch::Group.new 7 8 0.upto(10) do |i| 9 puts "Dispatch #{i} to GCD" 10 worker_queue.async(group) do 11 puts "working on #{i}" 12 end 13 end 14 puts "waiting for gcd" 15 group.wait 16 puts "done" 17
  • 73. 1 #!/usr/bin/env macruby 2 3 worker_queue = Dispatch::Queue.new( 4 'ch.huesler-informatik.scotrubyconf.gcd' 5 ) 6 group = Dispatch::Group.new 7 8 0.upto(10) do |i| 9 puts "Dispatch #{i} to GCD" 10 worker_queue.async(group) do 11 puts "working on #{i}" 12 end 13 end 14 puts "waiting for gcd" 15 group.wait 16 puts "done" 17
  • 74. 7 8 0.upto(10) do |i| 9 puts "Dispatch #{i} to GCD" 10 worker_queue.async(group) do 11 puts "working on #{i}" 12 end 13 end 14 puts "waiting for gcd" 15 group.wait 16 puts "done" 17
  • 76. 1 #!/usr/bin/env macruby 2 3 group = Dispatch::Group.new 4 result = [] 5 1.upto(10).each do |i| 6 Dispatch::Queue.concurrent.async(group) do 7 sleep 2 8 result << i 9 end 10 end 11 group.wait 12 puts result.inspect
  • 78. 1 #!/usr/bin/env ruby 2 require "osx/cocoa" 3 include OSX 4 5 file_name = 'Info.plist' 6 plist = NSDictionary.dictionaryWithContentsOfFile( 7 file_name 8 ) 9 10 plist['CFBundleVersion'] = '2.0.1' 11 12 plist.writeToFile_atomically( 13 file_name, 14 true 15 )
  • 79. 1 #!/usr/bin/env ruby 2 require "osx/cocoa" 3 include OSX 4 5 file_name = 'Info.plist' 6 plist = NSDictionary.dictionaryWithContentsOfFile( 7 file_name 8 ) 9 10 plist['CFBundleVersion'] = '2.0.1' 11 12 plist.writeToFile_atomically( 13 file_name, 14 true 15 )
  • 80. 3 include OSX 4 5 file_name = 'Info.plist' 6 plist = NSDictionary.dictionaryWithContentsOfFile( 7 file_name 8 ) 9 10 plist['CFBundleVersion'] = '2.0.1' 11 12 plist.writeToFile_atomically( 13 file_name, 14 true 15 )
  • 83. Details • MacRuby has issues with void pointer (patch pending)
  • 84. Details • MacRuby has issues with void pointer (patch pending) • Use objective c wrapper instead (dynlib or bundle)
  • 85. Details • MacRuby has issues with void pointer (patch pending) • Use objective c wrapper instead (dynlib or bundle) • Generate metadata to make it work
  • 86. Details • MacRuby has issues with void pointer (patch pending) • Use objective c wrapper instead (dynlib or bundle) • Generate metadata to make it work
  • 87. 1 export FILE_PATH = ~/Library/BridgeSupport 2 export FRAMEWORK_PATH = ~/Library/BridgeSupport/ Security.bridgesupport 3 mkdir $FILE_PATH 4 gen_bridge_metadata -f Security -o $FRAMEWORK_PATH
  • 88. 1 require 'osx/cocoa' 2 include OSX 3 require_framework 'Security' 4 5 # Set up some relevant variables 6 7 service = "ch.huesler-informatik.scotrubyconf.keychain" 8 account = "Highlander" 9 original_password = "Rrrueby" 10 11 # Add password 12 SecKeychainAddGenericPassword( 13 nil, 14 service.length, 15 service, 16 account.length, 17 account, 18 original_password.length, 19 original_password, 20 nil 21 )
  • 89. 1 require 'osx/cocoa' 2 include OSX 3 require_framework 'Security' 4 5 # Set up some relevant variables 6 7 service = "ch.huesler-informatik.scotrubyconf.keychain" 8 account = "Highlander" 9 original_password = "Rrrueby" 10 11 # Add password 12 SecKeychainAddGenericPassword( 13 nil, 14 service.length, 15 service, 16 account.length, 17 account, 18 original_password.length, 19 original_password, 20 nil 21 )
  • 90. 1 # Add password 2 SecKeychainAddGenericPassword( 3 nil, 4 service.length, 5 service, 6 account.length, 7 account, 8 original_password.length, 9 original_password, 10 nil 11 )
  • 91. 1 # Query the keychain 2 status, *password = SecKeychainFindGenericPassword( 3 nil, 4 service.length, 5 service, 6 account.length, 7 account 8 )
  • 92. 1 # Password-related data. Shifting pointers 2 length = password.shift 3 data = password.shift 4 plain_password = data.bytestr(length) 5 6 puts "Password: #{plain_password}"