fun with ruby and cocoa
DESCRIPTION
Use RubyCocoa and MacRuby to write scripts that take advantage of the Cocoa frameworks.TRANSCRIPT
![Page 1: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/1.jpg)
Ruby and CocoaFacilitate development on OSX
![Page 2: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/2.jpg)
About me
![Page 3: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/3.jpg)
About me
![Page 4: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/4.jpg)
Rapperswil
![Page 5: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/5.jpg)
http://www.flickr.com/photos/turtlemom_nancy/4026208166/sizes/l/
![Page 6: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/6.jpg)
huesler informatik
![Page 7: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/7.jpg)
huesler informatik
upstream agile
![Page 8: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/8.jpg)
huesler informatik
upstream agile
co-up.de
![Page 9: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/9.jpg)
Ruby and Cocoa
![Page 10: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/10.jpg)
Ruby
![Page 11: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/11.jpg)
passionatehttp://www.flickr.com/photos/gi/378823/sizes/o/
![Page 12: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/12.jpg)
Apple OSX
![Page 13: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/13.jpg)
![Page 14: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/14.jpg)
passionate
http://www.flickr.com/photos/gi/378823/sizes/o/
![Page 15: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/15.jpg)
Landscape
http://www.flickr.com/photos/kiumo/4203883504/sizes/o/
![Page 16: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/16.jpg)
Cocoa
http://www.flickr.com/photos/luder5/4100921399/sizes/l/
![Page 17: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/17.jpg)
Cocoa
![Page 18: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/18.jpg)
Cocoa
• Core Foundation
![Page 19: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/19.jpg)
Cocoa
• Core Foundation
• Appkit
![Page 20: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/20.jpg)
Cocoa
• Core Foundation
• Appkit
• Core * (Audio/Video/Image/Data etc.)
![Page 21: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/21.jpg)
Cocoa
• Core Foundation
• Appkit
• Core * (Audio/Video/Image/Data etc.)
• Scripting bridge
![Page 22: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/22.jpg)
Cocoa
• Core Foundation
• Appkit
• Core * (Audio/Video/Image/Data etc.)
• Scripting bridge
• others
![Page 23: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/23.jpg)
Interface Builder
![Page 24: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/24.jpg)
XCode
![Page 25: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/25.jpg)
Objective-C
![Page 26: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/26.jpg)
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 arrayfor (NSString *s in anArray) { NSLog(s);}//Release the array[anArray release]
![Page 27: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/27.jpg)
![Page 28: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/28.jpg)
Ruby And Cocoa
![Page 29: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/29.jpg)
![Page 30: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/30.jpg)
Ruby Cocoa
![Page 31: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/31.jpg)
![Page 32: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/32.jpg)
HotCocoa
picture shamelessly cropped from http://www.slideshare.net/mattetti/macruby-hotcocoa-presentation-by-rich-kilmer
![Page 33: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/33.jpg)
Scripting Bridge
http://www.flickr.com/photos/bensonkua/2851908095/sizes/l/
![Page 34: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/34.jpg)
Good to know
![Page 35: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/35.jpg)
Good to know
• Available commands for each application are in a .sdef file
![Page 36: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/36.jpg)
Good to know
• Available commands for each application are in a .sdef file
• Terminal.app/Contents/Resources/Terminal.sdef
![Page 37: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/37.jpg)
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)
![Page 38: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/38.jpg)
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
![Page 39: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/39.jpg)
![Page 40: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/40.jpg)
Control Terminal
![Page 41: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/41.jpg)
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)
![Page 42: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/42.jpg)
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)
![Page 43: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/43.jpg)
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)
![Page 44: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/44.jpg)
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)
![Page 45: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/45.jpg)
Problems with MacRuby
![Page 46: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/46.jpg)
Problems with MacRuby
![Page 47: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/47.jpg)
Problems with MacRuby
• Some methods don’t seem to be available
![Page 48: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/48.jpg)
iTunes
![Page 49: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/49.jpg)
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
![Page 50: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/50.jpg)
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
![Page 51: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/51.jpg)
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
![Page 52: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/52.jpg)
Core Location
![Page 53: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/53.jpg)
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 )
![Page 54: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/54.jpg)
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 )
![Page 55: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/55.jpg)
1 def locationManager( 2 manager, 3 didUpdateToLocation: new_location, 4 fromLocation: old_location 5 ) 6 7 puts "loc: #{new_location.description}" 8 end
![Page 56: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/56.jpg)
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 )
![Page 57: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/57.jpg)
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 )
![Page 58: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/58.jpg)
Grand Central Dispatch
![Page 59: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/59.jpg)
Grand Central Dispatch
![Page 60: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/60.jpg)
Grand Central Dispatch
• MacRuby only
![Page 61: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/61.jpg)
Grand Central Dispatch
• MacRuby only
• Synchronous
![Page 62: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/62.jpg)
Grand Central Dispatch
• MacRuby only
• Synchronous
• Asynchronous
![Page 63: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/63.jpg)
Grand Central Dispatch
• MacRuby only
• Synchronous
• Asynchronous
• Parallel
![Page 64: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/64.jpg)
Grand Central Dispatch
• MacRuby only
• Synchronous
• Asynchronous
• Parallel
• Synchronization
![Page 65: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/65.jpg)
Asynchronous
![Page 66: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/66.jpg)
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
![Page 67: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/67.jpg)
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
![Page 68: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/68.jpg)
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
![Page 69: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/69.jpg)
Synchronous
![Page 70: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/70.jpg)
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
![Page 71: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/71.jpg)
Synchronized
![Page 72: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/72.jpg)
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
![Page 73: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/73.jpg)
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
![Page 74: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/74.jpg)
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
![Page 75: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/75.jpg)
Concurrent
![Page 76: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/76.jpg)
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
![Page 77: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/77.jpg)
.plist files
![Page 78: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/78.jpg)
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 )
![Page 79: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/79.jpg)
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 )
![Page 80: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/80.jpg)
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 )
![Page 81: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/81.jpg)
Keychain Access
![Page 82: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/82.jpg)
Details
![Page 83: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/83.jpg)
Details
• MacRuby has issues with void pointer (patch pending)
![Page 84: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/84.jpg)
Details
• MacRuby has issues with void pointer (patch pending)
• Use objective c wrapper instead (dynlib or bundle)
![Page 85: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/85.jpg)
Details
• MacRuby has issues with void pointer (patch pending)
• Use objective c wrapper instead (dynlib or bundle)
• Generate metadata to make it work
![Page 86: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/86.jpg)
Details
• MacRuby has issues with void pointer (patch pending)
• Use objective c wrapper instead (dynlib or bundle)
• Generate metadata to make it work
![Page 87: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/87.jpg)
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
![Page 88: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/88.jpg)
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 )
![Page 89: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/89.jpg)
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 )
![Page 90: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/90.jpg)
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 )
![Page 91: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/91.jpg)
1 # Query the keychain 2 status, *password = SecKeychainFindGenericPassword( 3 nil, 4 service.length, 5 service, 6 account.length, 7 account 8 )
![Page 92: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/92.jpg)
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}"
![Page 93: Fun with Ruby and Cocoa](https://reader038.vdocument.in/reader038/viewer/2022103000/554f982ab4c905ad218b475d/html5/thumbnails/93.jpg)
That’s all!Questions?