MANNING IN ACTION Brendan G. Lim WITH Jerry Cheung AND Jeremy McAnally MacRuby in Action MacRuby in Action BRENDAN G. LIM JERRY CHEUNG AND JEREMY MCANALLY WITH MANNING SHELTER ISLAND For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 261 Shelter Island, NY 11964 Email: email@example.com ©2012 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without elemental chlorine. Manning Publications Co. 20 Baldwin Road PO Box 261 Shelter Island, NY 11964 Development editor: Technical proofreader: Copyeditors: Proofreader: Typesetter: Cover designer: ISBN: 9781935182498 Printed in the United States of America 1 2 3 4 5 6 7 8 9 10 – MAL – 18 17 16 15 14 13 12 Sara Onstine Nick Howard Lianna Wlasiuk, Tiffany Taylor Melody Dolab Marija Tudor Marija Tudor brief contents PART 1 PART 2 PART 3 STARTING WITH MACRUBY ...........................................1 1 ■ Introducing MacRuby 2 ■ 3 Using Macirb and the Apple development tools 3 ■ Going beyond the basics with Xcode Interface Builder 37 64 TAKE IT FOR A SPIN ....................................................85 4 ■ Using the delegate pattern 5 ■ 87 Notifications and implementing the observer pattern 6 ■ Using key-value coding and key-value observing 7 ■ Implementing persistence with Core Data 8 ■ Core Animation basics 104 120 141 168 MACRUBY EXTRAS ....................................................187 9 ■ HotCocoa 189 10 ■ MacRuby testing 203 11 ■ MacRuby and the Mac App Store v 216 contents preface xiii acknowledgments xiv about this book xvi about the authors xix about the cover illustration PART 1 1 xx STARTING WITH MACRUBY ...............................1 Introducing MacRuby 3 1.1 1.2 Introducing MacRuby 4 The MacRuby difference Hello World, part 1 6 4 ■ Setting up your environment 5 Cocoa: What you need to know 7 Important classes and concepts 8 common design patterns 10 1.3 ■ How Cocoa implements Objective-C and Ruby: what you need to know A shared heritage 12 Ruby 101 17 vii ■ Objective-C 101 13 11 viii CONTENTS 1.4 Diving into MacRuby 21 Class structure 21 Creating MacRuby classes 23 Syntax and method signatures 24 Using Ruby and Objective-C methods 26 Creating user interfaces 27 ■ ■ ■ 1.5 Hello World, part 2 28 Creating an Xcode project 29 Creating the interface 30 Creating the controller 32 Connecting the interface and controller 34 ■ ■ 1.6 2 Summary 35 Using Macirb and the Apple development tools 37 2.1 Using external libraries with MacRuby 38 Loading frameworks 38 Loading Objective-C libraries as bundles 39 Loading Ruby gems 41 ■ ■ 2.2 Exploring Macirb 42 Comparing the Ruby and MacRuby consoles 42 Working in the MacRuby console 43 Macirb tips and tricks 43 ■ 2.3 Building a Pomodoro application in Xcode 47 Creating a new MacRuby project 47 Constructing the interface 50 Creating the controller 53 Connecting the controller and the interface 56 Running the application 58 Releasing the application 58 ■ ■ ■ ■ 2.4 3 Summary 63 Going beyond the basics with Xcode Interface Builder 64 3.1 About Interface Builder 65 History of Interface Builder 65 Builder 65 3.2 Creating connections Getting around Interface 69 Understanding outlets 69 3.3 ■ ■ Understanding actions Creating the Todo List application 71 73 Constructing the user interface 73 Creating the model 79 Creating the controller 79 Connecting outlets and actions 82 Running and packaging the application 83 ■ ■ ■ ■ 3.4 Summary 84 ix CONTENTS PART 2 4 TAKE IT FOR A SPIN .........................................85 Using the delegate pattern 87 4.1 What are delegates? 88 How do delegate methods work? pattern 89 4.2 ■ Implementing the delegate Delegation as an extension technique Delegation the Cocoa way Forwardable 93 4.3 88 93 92 Delegation using ■ Using delegation in a custom MacRuby web browser 94 Creating the browser interface 94 Setting up the controller 95 Implementing delegate methods in the controller 98 Connecting outlets and actions 100 Taking MacRuby Browser for a spin 102 ■ ■ ■ 4.4 5 Summary 103 Notifications and implementing the observer pattern 104 5.1 Notifying multiple objects 105 When to use notifications 105 5.2 Setting up notifications Managing notifications 106 107 Creating notifications 108 notification center 108 5.3 ■ ■ Posting notifications to the Queuing notifications 109 Using posting styles 109 Coalescing notifications 110 Queuing multiple notifications 112 Removing notifications 113 ■ ■ 5.4 Responding to notifications Adding notification observers observers 116 5.5 6 114 ■ Removing notification Building an iTunes-notification observer Creating the script 116 5.6 114 Summary ■ 116 Running the script 118 118 Using key-value coding and key-value observing 120 6.1 Simplifying code with key-value coding 121 Accessing object properties with KVC 121 Handling unknown keys 123 Understanding key paths and collection operators 125 ■ ■ x CONTENTS 6.2 Using KVO to implement observers 128 Adding and removing observers 128 Manually notifying observers of changes 129 Responding to observed objects 130 ■ ■ 6.3 Building out the Product Inventory application 131 Creating the user interface 131 Using KVC to retrieve product information 132 Adding features with KVC and KVO 137 ■ ■ 6.4 7 Summary 140 Implementing persistence with Core Data 141 7.1 Introducing Core Data 142 Core Data concepts 142 Differences between Core Data and traditional databases 142 Creating a base Core Data project 143 ■ ■ 7.2 Understanding the persistent store and managed objects 145 Anatomy of a persistent store 146 Working with the managed object model 147 Working with entity properties 149 Defining a managed object class 152 ■ ■ 7.3 Working with managed objects 154 Creating managed objects and updating properties Persisting changes to managed objects 155 7.4 Retrieving objects from Core Data 154 157 Filtering and sorting with predicates and descriptors 157 Fetching objects from Core Data 158 7.5 Creating a Core Data version of the Todo List application Building the user interface 160 Creating the tasks controller 161 Connecting the interface to the controller 164 Running the application and inspecting the persistent store 166 ■ ■ 7.6 8 Summary 167 Core Animation basics 168 8.1 Introduction to Core Animation 169 What is Core Animation? 169 Class structure 169 Core Animation’s rendering architecture 170 Creating a basic animation with Cocoa Animation 171 ■ ■ 160 xi CONTENTS 8.2 Core Animation layers 173 Layer coordinate systems Layer content 175 8.3 174 Layer geometry 174 ■ Animating with Core Animation 179 Basic animations 179 Keyframe animations 181 Grouping animations 182 ■ 8.4 PART 3 9 Summary 185 MACRUBY EXTRAS ........................................187 HotCocoa 189 9.1 Introducing HotCocoa Getting started 9.2 189 190 Built-in mappings 191 Applications and menus 191 More advanced layouts 198 9.3 Building a speech application using HotCocoa Laying out the views 200 speak to you 201 9.4 10 Windows and controls ■ Summary ■ 193 200 Making your application 202 MacRuby testing 203 10.1 10.2 10.3 10.4 Testing MacRuby applications with MiniTest 203 Installing and configuring MiniTest 205 Application vs. logic testing 207 Where to start testing 209 Application initialization 209 Core Data 210 Managing persistence store for testing 212 Testing predicates 214 ■ ■ 10.5 11 Summary 215 MacRuby and the Mac App Store 216 11.1 Introducing the Mac App Store 217 Benefits of releasing on the Mac App Store of the Mac App Store 218 217 ■ Limitations xii CONTENTS 11.2 Knowing the App Store rules 219 Functionality 219 User interface 219 contributions 220 11.3 ■ ■ ■ Metadata 219 Location 219 Privacy 220 Charities and Legal requirements 220 ■ ■ Submitting a MacRuby application 220 Creating certificates 220 Registering your Mac App ID 223 Preparing icons and screenshots 224 Adding your application to iTunes Connect 225 Packaging and submitting your application 227 Dealing with application rejection 231 Submitting an update 231 ■ ■ ■ ■ ■ 11.4 appendix A Summary 231 Scripting with MacRuby index 241 232 preface When I was first learning Ruby, I immediately fell in love with the language. I knew early on that I wanted to work with Ruby professionally, which became possible later when I created my first startup using Ruby on Rails. I later worked for a Ruby on Rails consulting company where I spent a few years focusing on Ruby before I headed up the mobile development department. I’ve had an interest in mobile development since I was young and it was a very exciting time to work on iOS and Android applications. With iOS development came the need to learn Objective-C, which ultimately led me into the world of Cocoa for Mac development. I developed a few Mac applications personally and professionally and thought how great it would be if I could write Mac applications using Ruby. I’d heard of RubyCocoa, but I knew of its shortcomings. Then I learned about MacRuby: it was the solution I’d been waiting for. When I was contacted by Manning to work on this book, I knew I’d be able to reach many other individuals who were Rubyists and who wanted to create rich Mac applications without having to use Objective-C. This book is meant for you if you love the Ruby language and want to get into Mac development BRENDAN G. LIM xiii acknowledgments Putting together a book like this is no easy feat, and many people behind the scenes worked countless hours to get the book into your hands. First and foremost, everyone at Manning deserves all the thanks we can give them. Without them, we wouldn’t have been able to create such a great book for you. We interacted frequently with a few individuals from Manning and would like to specifically mention them. We’d like to thank Troy Mott, our acquisitions editor, who originally came to us to work on this book and helped us through thick and thin. Sara Onstine, our development editor, guided us through the formalities of writing a book like this. And Marjan Bace, our publisher, always challenged us to find ways to improve the book’s content and organization. We’d also like to thank our book’s production team. Lianna Wlasiuk, Tiffany Taylor, and Melody Dolab, our copyeditors and proofreader, read the entire manuscript and made sure everything was organized and presented properly. Nick Howard, our technical proofreader, caught errors that we didn’t know were there. Over the course of the development of the book, many people generously volunteered to review it to help make it as good as it could be. These reviewers deserve a tremendous amount of credit for the impact they made through their feedback. Our thanks to Pradeep Elankumaran, Brent Collier, Adam Bair, Philip Hallstrom, Mike Stok, Alex Vollmer, Coby Randquist, Jerry Cheung, Greg Vaughn, Warner Onstine, and Daniel Bretoi. xiv ACKNOWLEDGMENTS xv BRENDAN would like to thank his father, Chhorn, his mother, Brenda, and his two brothers, Chhorn and Chhun, for their support and encouragement. He also wants to thank his wife, Edelweiss, for her love and support and for letting him spend night and day working on this book. Last but not least, thanks to Pradeep Elankumaran, who let Brendan spend so much time writing this book after they both quit their jobs to focus on their startup, Kicksend. JERRY would like to thank his parents, Margaret and Kevin, and his wise-guy brother Randall. He’d also like to remind Wendy that he beat her to her thesis (thanks, love, for letting me win this one). A special shout-out goes to Brendan for getting Jerry interested in MacRuby and Mac development in the first place. JEREMY would like to thank his wife, friends, and dogs for sustaining him through yet another writing project. Without their support, he would likely end up a raving maniac under an overpass tapping out code examples while throwing cans at passing cars. about this book MacRuby in Action was written to give Rubyists the ability to create rich Cocoa applications for the Mac OS X platform without having to learn Objective-C. Our goal is to have you, the reader, creating amazing Cocoa applications using MacRuby by the end of the book. Throughout the book, you’ll learn in the ins and outs of MacRuby while exploring the Cocoa framework, design patterns, system scripting, testing, and getting your application into the Mac App Store. We know that sometimes the best way to learn is to get your feet wet. That’s why you’ll be creating useful Mac applications along the way so you can apply the key topics as you learn them. Who should read this book This book is aimed at developers interested in writing software for the Mac platform. It doesn’t matter if you’re new to both the Mac and the Ruby language or you’re an experienced Ruby developer looking to learn how to write Mac apps. If you have the desire to create beautiful Cocoa applications for the Mac platform and want to do so using the elegant and highly productive Ruby language, then this book is for you. If you’re new to Ruby, we give you a brief overview of the language so you’ll feel comfortable enough to take on the rest of the book. MacRuby in Action is also a more approachable introduction to Cocoa development than traditional Objective-C books. Throughout the book, we explore practical code examples that you’ll face when creating your own applications. MacRuby in Action can act as a guide for using MacRuby and Cocoa from the ground up, or you can use it as a reference if you’re looking to dive deeper into MacRuby. xvi ABOUT THIS BOOK xvii Roadmap The book has 11 chapters divided into three parts as follows: Chapter 1 explores the inner workings of MacRuby and how to set up your development environment. There’s also an introduction to Ruby and an overview of Objective-C syntax. We then go into the MacRuby syntax, give a few examples, and end with two “Hello World” examples. Chapter 2 takes a deeper dive into MacRuby with more in-depth examples. We look into using external frameworks, Ruby gems, and the MacRuby console. At the end of the chapter, you build a MacRuby Pomodoro application. Chapter 3 talks about Apple’s development environment tools. You spend more time using Xcode’s Interface Builder to create rich Cocoa user interfaces. You then use your Interface Builder knowledge to create an application to manage to-do lists. Chapter 4 introduces and explains a code design technique known as delegation. This design pattern is used often in the Cocoa framework and is important to know because it’s a core concept. You explore delegation by creating a web browser with MacRuby. Chapter 5 covers Cocoa’s notification system, which lets you set observers throughout an application to listen for and react to changes. This is another pattern that is used frequently in Cocoa. At the end of the chapter, you build an iTunes notification observer. Chapter 6 explores key value coding (KVC) and observing. KVC is a mechanism in Objective-C that’s used throughout Cocoa. You learn about KVC, bindings, and keyvalue observing. Chapter 7 introduces the Core Data framework. Core Data is Apple’s answer to object-relational mapping. We compare Core Data with other persistence solutions that you may be familiar with. At the end of the chapter, you use Core Data to add persistence to the Todo List application you built in chapter 3. Chapter 8 discusses image manipulation, animation, and much more with Core Animation. Throughout the chapter, we go through examples to showcase what you can do with Core Animation once you scratch the surface. Chapter 9 dives into the MacRuby-oriented mapping library HotCocoa. HotCocoa gives developers an alternative to Interface Builder by making it easy to create interfaces in code. You end up building a small application of your own. Chapter 10 discusses testing with MacRuby. Testing is an essential part of software development, and it has gained a strong focus within the Ruby community. We look at different ways to test with MacRuby. Chapter 11 explains how to release a MacRuby application to the world with the Mac App Store. We go into detail about the different review guidelines, how to provision your application for submission, and finally how to submit it for review. Appendix A talks about scripting with MacRuby. We first provide a little history and an introduction to AppleScript. We then look at how you can use MacRuby to create scripts to automate functionality. xviii ABOUT THIS BOOK Code conventions There are many code examples throughout this book. These examples always appear in a fixed-width code font. If we want you to pay special attention to a part of an example, it appears in a bolded code font. Any class name or method within the normal text of the book appears in code font as well. Many of Cocoa’s methods have exceptionally long and verbose names. Because of this, line-continuation markers ( ➥) may be included in code listings when necessary. Not all code examples in this book are complete. Often we show only a method or two from a class to focus on a particular topic. Complete source code for the applications found throughout the book can be downloaded from the publisher's website at www.manning.com/MacRubyinAction. Software requirements An Intel-based Macintosh running OS X 10.6 or higher is required to develop MacRuby applications. You also need to download MacRuby, but it’s freely available at http://macruby.org. The book offers full coverage of MacRuby and Xcode 4. Author Online Purchase of MacRuby in Action includes free access to a private web forum run by Manning Publications where you can make comments about the book, ask technical questions, and receive help from the authors and from other users. To access the forum and subscribe to it, point your web browser to www.manning.com/MacRubyinAction. This page provides information on how to get on the forum once you’re registered, what kind of help is available, and the rules of conduct on the forum. Manning’s commitment to our readers is to provide a venue where a meaningful dialog between individual readers and between readers and the authors can take place. It’s not a commitment to any specific amount of participation on the part of the authors, whose contribution to the AO remains voluntary (and unpaid). We suggest you try asking the authors some challenging questions lest their interest stray! The Author Online forum and the archives of previous discussions will be accessible from the publisher’s website as long as the book is in print. about the authors BRENDAN G. LIM is a professional Ruby and Objective-C developer. He is also a noted conference speaker who specializes in developing Ruby on Rails, Android, iOS, and Mac applications. Brendan graduated from Auburn University where he studied Wireless Software Engineering. He is also a Y Combinator alum and cofounded the filesharing startup Kicksend. During his free time, Brendan enjoys rock climbing and taking photos and videos. JERRY CHEUNG loves creating software. He started experimenting with Ruby on Rails in 2007 and has been hooked on Ruby ever since. Upon graduating from Berkeley, he joined Coupa, and later he went on to start his own company, Outspokes, with several friends from Berkeley. He currently works as a Rails engineer at Intridea and experiments with emerging technologies like MacRuby and Node.js. When he’s not furiously typing, Jerry might be out running, brewing beer, or enjoying a BBQ and getting a serious sunburn. JEREMY MCANALLY is founder and principal at Arcturo, a web and mobile development firm. He spends his days hacking Ruby and Objective-C. xix about the cover illustration The figure on the cover of MacRuby in Action is captioned “A man from Ubli, Dalmatia.” The illustration is taken from a reproduction of an album of Croatian traditional costumes from the mid-nineteenth century by Nikola Arsenovic, published by the Ethnographic Museum in Split, Croatia, in 2003. The illustrations were obtained from a helpful librarian at the Ethnographic Museum in Split, itself situated in the Roman core of the medieval center of the town: the ruins of Emperor Diocletian’s retirement palace from around AD 304. The book includes finely colored illustrations of figures from different regions of Croatia, accompanied by descriptions of the costumes and of everyday life. Ubli is a town on the island of Lastovo, one of a number of small islands in the Adriatic off the western coast of Croatia. The figure on the cover wears blue woolen trousers and a white linen shirt, over which he dons a blue vest and black jacket, richly trimmed with the colorful embroidery typical for this region. A red turban and colorful socks complete the costume. The man is also holding a pistol and has a short sword tucked under his belt. Dress codes and lifestyles have changed over the last 200 years, and the diversity by region, so rich at the time, has faded away. It’s now hard to tell apart the inhabitants of different continents, let alone of different hamlets or towns separated by only a few miles. Perhaps we have traded cultural diversity for a more varied personal life— certainly for a more varied and fast-paced technological life. Manning celebrates the inventiveness and initiative of the computer business with book covers based on the rich diversity of regional life of two centuries ago, brought back to life by illustrations from old books and collections like this one. xx Part 1 Starting with MacRuby M acRuby is a combination of technologies that together create a powerful and very usable new technology. Part 1 of this book provides the basics needed for new MacRuby users to understand the background and underlying details of how MacRuby works so the development environment, language, and platform make sense. With this grounding, you’ll be able to pick any sections in the rest of the book and learn about the areas that are most interesting or relevant to you. Introducing MacRuby This chapter covers ■ Exploring and installing MacRuby ■ Important Cocoa concepts ■ Objective-C and Ruby fundamentals ■ MacRuby syntax and methods ■ Developing with the Xcode IDE MacRuby gives you the ability to write full-fledged Mac applications while enjoying the benefits of the Ruby language. You won’t take a deep dive into writing your first releasable application worthy of the Mac App Store just yet—you’ll do that in chapter 2. To write great MacRuby applications, you first need to become familiar with its foundation. The MacRuby language is deeply rooted in the Ruby and ObjectiveC languages so it’s important to have a good understanding of both of these to fully leverage all that MacRuby offers. In this chapter, we’ll briefly cover the Cocoa framework, Ruby, and Objective-C. After you have an understanding of these topics, we’ll dive into some real MacRuby code. You’ll even get a chance to write a Hello World application; we’ll show you two approaches to user interface development. To get started, let’s learn what MacRuby is all about and get it installed on your system. 3 4 1.1 CHAPTER 1 Introducing MacRuby Introducing MacRuby MacRuby is an Apple-sponsored development project. Over the years, Apple has shown support for Ruby as a language, and, since 2002, Apple has included Ruby as part of the Mac OS X operating system. Apple bundled a Ruby Scripting Bridge implementation called RubyCocoa with Mac OS X Leopard. Prior to MacRuby, RubyCocoa was the only way to work with Ruby and the Cocoa framework together. In this section, you’ll learn how MacRuby is different from past attempts at combining Ruby and Objective-C and what makes it such a great language. We’ll also jump right into getting MacRuby installed onto your system and introduce you to MacRuby’s class structure. Let’s set the stage for MacRuby. 1.1.1 The MacRuby difference The goal of MacRuby is to provide an implementation of the Ruby language on top of core Mac OS X technologies, such as the Objective-C runtime, garbage collection, and Core Foundation. In MacRuby, all classes are Objective-C classes, all methods are Objective-C methods, and all objects are Objective-C objects. Unlike RubyCocoa, you don’t need a bridge between Ruby, Objective-C, and the Cocoa framework. MacRuby is implemented on top of the Objective-C runtime as shown in figure 1.1. MacRuby gives you the ability to do almost anything you want with the Mac platform—all while givMacRuby ing you the clean, concise syntax of the Ruby Objective-C language. Another thing that sets it apart from Ruby libraries Cocoa libraries RubyCocoa is that you get this functionality without making performance sacrifices because MacRuby Objective-C runtime doesn’t rely on a bridge implementation. Figure 1.1 MacRuby is built on top MacRuby is similar in concept to the IronRuby of the Objective-C runtime. and JRuby projects in that it’s an implementation of Ruby on top of another runtime. IronRuby runs on the .NET runtime for Windows, and JRuby runs on the Java Virtual Machine (JVM) runtime. MacRuby is currently under active development by Apple, which gives the language a great deal of support and momentum. Think of MacRuby as the child of two languages: Objective-C and Ruby. MacRuby is rooted in the Objective-C object hierarchy, but it also has the Ruby 1.9 core functionality layered on top. Syntax-wise, MacRuby resembles Ruby more than Objective-C. Theoretically, you could write a Ruby 1.9 script and run it under MacRuby. The key difference in MacRuby is that you can directly access Objective-C frameworks, classes, objects, and methods. Before you write any code, you’ll want to install MacRuby and Xcode on your system. Xcode is Apple’s suite of developer tools needed to create Mac OS X applications. After all, what good are code examples if you can’t follow along? Introducing MacRuby 1.1.2 5 Setting up your environment Install the Xcode development environment first. It’s best to install MacRuby after you have Xcode set up on your machine. If you don’t install in this order, tools such as Interface Builder (which is now built into Xcode 4) won’t be able to recognize your MacRuby code. INSTALLING XCODE Registered Apple Developers can download the latest version of Xcode for free at https://developer.apple.com/xcode/. If you don’t have an Apple Developer Account, you can purchase Xcode for $4.99 from the Mac App Store. TIP Xcode is a big file; take a break while you wait for it to download. After the download is complete, run the installer to set up Xcode on your system. Xcode will be available from your /Developer/Applications folder. INSTALLING MACRUBY Installing MacRuby is a simple two-step process: NOTE Make sure that you’re running an Intel-based system with Mac OS X 10.6 or higher, which is the minimum requirement for MacRuby. 1 2 Download the latest stable release. From http://macruby.org, proceed to the download section. A self-installable binary should be available for you to save and run, which should install the latest version of MacRuby on your system. Test the MacRuby installation. Open the Terminal application, type macirb, and then press Enter. You should see something similar to the following code: $ macirb irb(main):001:0> This puts you directly into Macirb, the MacRuby console, which is a great tool for experimenting with MacRuby. You’ll learn about Macirb in more detail in chapter 2. Next, type this command: p "Hello World!" If your installation was successful, you’ll see the words Hello World! printed out without any errors. If you see errors, try installing again. NOTE If Xcode doesn’t recognize MacRuby files, return to this page and reinstall MacRuby. If everything went as planned, congratulations! You’ve written your first line of MacRuby! You can now follow along throughout the book. Let’s start with a MacRuby script. 6 1.1.3 CHAPTER 1 Introducing MacRuby Hello World, part 1 The MacRuby scripting runtime provides a way to execute MacRuby scripts as Cocoa applications, without the need for any other tools. To get a taste of MacRuby, you’re going to write a script that, when run, looks like figure 1.2. Open your favorite text editor, and create a file Figure 1.2 The MacRuby script in action and save it with the name hello.rb. The .rb indicates that it’s a Ruby source file. MacRuby uses the same file extension as standard Ruby, but it uses its own command to run scripts, as you’ll soon see. The Hello World application shown in listing 1.1 is 25 lines long because you’re creating it programmatically rather than using the interface development tools built into Xcode. Most of the code is for the user interface, which is why most people choose to use HotCocoa or Xcode. Let’s start by looking at the code in the script, and then we’ll break it down into digestible bits. Listing 1.1 MacRuby Hello World script framework 'cocoa' app = NSApplication.sharedApplication b Initializes NSApplication win = NSWindow.alloc.initWithContentRect ➥ ([300,500,400,200], ➥ styleMask:NSTitledWindowMask | NSClosableWindowMask ➥ | NSMiniaturizableWindowMask | NSResizableWindowMask, ➥ backing: NSBackingStoreBuffered, defer:false) C label = NSTextField.alloc.initWithFrame 45)) label.setStringValue "Hello World!" label.drawsBackground = false label.bezeled = false label.font = NSFont.fontWithName("Arial", size:45.0) label.editable = false Sets up NSWindow ➥ CGRectMake(0,0,250, d Creates label label.frameOrigin = NSMakePoint ➥ ((win.contentView.frameSize.width/2.0) ➥ -(label.frameSize.width/2.0), ➥ (win.contentView.frameSize.height/2.0) ➥ -(label.frameSize.height/2.0) ) e Centers label win.contentView.addSubview(label) win.title = "Hello World" win.display win.orderFrontRegardless win.makeKeyWindow app.run f g Configures app window Adds subview Cocoa: What you need to know 7 The first line uses the framework method to load the Cocoa base framework for MacRuby. This method loads both the Foundation and AppKit frameworks into your environment so that your application has access to the core Cocoa classes. You start by initializing the NSApplication singleton B for the app. Every Cocoa program has a singleton instance of NSApplication responsible for managing the application’s run loop. You create a variable, app, and assign it a reference to the NSApplication singleton. Next, you set up the application window. At c, you create an instance of NSWindow with parameters and assign it to the win variable for reference. To add subviews to the application, you reference the main window (win). You also specify the size of the window as the first parameter of the NSWindow instance. To display the Hello World! message, you need an element to display the text. You create an instance of NSTextField d and then set the text for it to Hello World! You also set its bounds so that it displays centered in the window e. The frame origin of the text field is set to roughly the center of the window based on the window’s dimensions. Next, you add the text field as a subview of the application window’s content view f. The view hierarchy in Cocoa lets you easily add views on top of existing views. You finish by setting the application window title, and telling the window to display and then become the front key window g. Finally, you tell the NSApplication instance to run the application. That may have felt heavy for a Hello World, but that’s because there was a good amount of setup for the interface elements. To run the script, type the following in the terminal (assuming you’ve named your script hello.rb): macruby hello.rb When the application runs, you’ll see the application window appear (see figure 1.2). You created a simple Hello World application using a single MacRuby script. In reality, you aren’t likely to write too many apps like this. But this is a great way to initially dip your toes into Cocoa and MacRuby. This script uses a few of the core classes from the Cocoa frameworks—the most important of these are NSApplication and NSWindow. Every Cocoa application works with NSApplication. It’s also likely that you’ll be dealing with NSWindow in your applications. To get a feel for the common operations and functions available to these two classes, we recommend that you read the Cocoa API documentation for both of them. You’ll build several applications throughout this book that use these classes. Before we look any further at MacRuby, it’s important that you learn (or, in some cases, review) a few concepts about Cocoa, Objective-C, and Ruby. 1.2 Cocoa: What you need to know To fully understand and appreciate MacRuby, you’ll need to learn a little about Cocoa development. If you’re already familiar with Cocoa, feel free to skip this section. Cocoa is the high-level programming API for Mac OS X and is widely considered the best programming environment for writing native Mac applications. As an API, Cocoa 8 CHAPTER 1 Introducing MacRuby provides an elegant way to interact with the operating system and the window manager. Cocoa consists of a powerful set of libraries. Known as frameworks, they cover virtually every task imaginable to work with the operating system, and they provide a great set of tools for writing desktop applications. In this section, we’ll first discuss Cocoa’s important classes and concepts, and then give you a brief overview of frequently used design patterns. 1.2.1 Important classes and concepts What makes an application a Cocoa program? Is it the language? The tools you use? The platform it’s running on? The answer to all these questions is no. What makes a program a Cocoa program is that all the objects inherit from the root class NSObject and can run on the Objective-C runtime. The NSObject class is defined in the Foundation framework. In Cocoa programming, the two core frameworks are Foundation and Application Kit (AppKit for short), which provide the core set of libraries that you need to write a Mac application. When you wrote your Hello World script, you may have noticed that both frameworks are required for Mac application development. All other frameworks that you may include in your project can be viewed as optional. About the NS name prefix The classes, data types, constants and functions defined in Foundation and AppKit have a name prefix of NS. The NS is a holdover from Steve Jobs’ old company, NeXTSTEP, and—you guessed it—it stands for NeXTSTEP. You’ll see more of the NS name prefix as you develop in Cocoa and MacRuby. Let’s take a closer look at the Foundation framework. FOUNDATION FRAMEWORK The Foundation framework provides a set of classes that act as the support layer for your Cocoa applications. Whether a class is in Foundation or in AppKit is determined by one factor: its role in the user interface. If a class doesn’t exclusively interact with the user interface then it’s part of Foundation; if it does, it’s part of AppKit. Foundation supports several paradigms that include the following: ■ ■ Object retention and disposal—Foundation and the runtime provide two ways for Cocoa applications to manage objects: the older style of manual management using retain/release memory references and the newer garbage collection technology. For our purposes, all you need to know is that garbage collection is available in Objective-C 2.0, because MacRuby, at least for now, relies on it to manage memory under the hood. Mutable class variants—Many of the data-handling classes in Foundation have both an immutable base class and mutable subclasses—these include NSArray, Cocoa: What you need to know ■ 9 NSDictionary, NSString, and many more classes. To modify the data after initialization, you need to use a mutable variant. You’ll find that MacRuby does this for the classes that underlie its array, hash and string classes. Notifications—Notifications are used heavily in Cocoa, and we’ll discuss the Cocoa view of the design pattern in the next section. In general, notifications provide a broadcast mechanism for inter-object communication in synchronous, asynchronous, and distributed modes. Foundation is the framework responsible for handling the base value objects in your Cocoa application. These include primitive types, structures, and pointers. Foundation is responsible for collection objects such as arrays and hashes (NSArray, NSDictionary). The framework provides enumerators and, as already mentioned, both mutable and immutable variants. As a quick overview, Foundation framework also supports these functional areas: ■ ■ ■ ■ ■ ■ Operating system services—File system, threading, networking Archiving and serialization XML processing Scripting Expressions Many more The other important framework we mentioned was the AppKit framework, which is short for Application Kit. Let’s see how this framework can help you with your UI-based Mac applications. APPLICATION KIT FRAMEWORK The Mac OS X user interface is an event-driven system, and AppKit provides the classes you need to interact with this event-driven GUI. AppKit provides a large number of UI components; its classes indirectly support the UI components. AppKit provides the Application object that each Cocoa app will have as a singleton instance for running in the main event loop. AppKit also gives you access to UI objects such as windows, views, menus, cursors, table views, and most anything needed to create a robust user interface. You’re interacting with AppKit when you use MacRuby code to manipulate the UI. You can also interact with AppKit with different tools, such as Xcode and HotCocoa. If you’re not familiar with HotCocoa, it’s a layer of Ruby mappings on top of Cocoa that allow you to quickly construct interfaces programmatically. We’ll introduce HotCocoa in more detail in chapter 9. Some of the other functions that AppKit provides are graphics and color, internationalization, printing, and faxing. NOTE For a full description of the capabilities of Foundation and AppKit, see Apple’s Cocoa Fundamentals Guide (http://mng.bz/HT7j).