General • 2:00:57
Speakers: Bertrand Serlet, Scott Forstall, Eric Seymour, Ali Ozer, Simon Patience
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Ladies and gentlemen, please welcome Vice President of Software Engineering, Bertrand Serlet. Good afternoon. It's a pleasure to be here with you on this very memorable day, as I'm sure you've noticed this morning.
[Transcript missing]
So with this, I'd like to turn to my colleague, Scott Forstal, who heads Platform Experience, to tell us more about best practices.
How's everyone doing? Is the food better this year than last year? I had nothing to do with it. All right, as Bertrand said, we're going to talk about best practices today. Now, had we given this talk a year ago, we would have talked about the top 10 best practices for building a killer Mac OS X application. And then Steve made this big announcement this morning. And so, well, watch this. STEVE BAZYL: The numbers all go to 11. These go to 11.
That's right, this year our list of best practices goes to 11. And we will start off with the new best practice, number 11, to be processor independent. Bertrand said we're going to have some fun with cars, so let's start with an analogy and we will beat it to death over the next two hours.
We'll start off, if you even think about the Mac as being this great car, right, this beautiful great car. And inside we've had this engine, the PowerPC engine, which has done a wonderful job for us for the last decade and will continue to for the next year or so.
But now, as we look out to the future, we know we want to add another flavor of the exact same car, just with a different engine. So we have one car has a PowerPC engine, one car has an Intel engine. But to the consumer, when you look at the cars, they look the same, and that's important. So what does that mean to you? You've all been writing these great applications for Mac OS X, which run on PowerPC.
We're asking you to take that same application and make a version of it which runs on Macs running Intel as well. Now after this morning's announcement, some of you look like this, right? Some were pretty happy. Some of you look like that, and I saw a few of you who looked a little like this.
So what you're all asking yourself, right? You're puzzled over, How much work is it going to be? This is what you're caring about. How much work is it going to be for you to take your application, which runs on PowerPC, and make it run on Intel as well? The great answer is very little. But the real answer is it depends.
We have a good art department. So what does it depend on? It really depends on the type of project that you're working on. So I'm going to split these into four different project types. It's a different four than Steve split them in this morning, but it's very close. I'm going to add a little geek factor for number two.
The first type of project are scripts and Java projects. So this is all of your standard shell script languages right from C# to Bash to Corn. There'll be a rumble outside to figure out which one's the best. But it's all the standard shell scripting languages. Then the higher level scripting languages from Perl to Ruby, again, I'm sure there's camps that will fight over Python. We have the higher level scripting languages like AppleScript and JavaScript.
Even Automator with its workflows, those workflows are scripts. So these all count under the scripting languages. And surprising to some, even dashboard widgets are scripts. So they're really just web pages with JavaScript for the animation. So all of those fit into the scripting part of this. Now I said it was Java and scripts. Java, you know, there's thousands and thousands of applications. Many of you have probably wasted many hours on Yahoo Games. So all the Java applications.
So that's the first category. The great thing about this first category is they all just work. Right? They all, they're platform independent by design because scripting languages in Java, they're either interpreted or they're just in time compiled. They have intermediate languages. They're meant not to have anything specific to the binary type they run on in them themselves. So all of these just work. Yay. So all the scripting people can leave. You're done.
Unix projects. So these are, you know, all your X11 applications, a lot of your GNU applications. In fact, if you look out on SourceForge, it lists over 28,000 of these types of projects. So second level are Unix projects. Most of these projects are already cross-platform. They already run on Intel and other processors. And so the time to port most of these is really going to be the time it takes you to copy your source over and recompile it. That's it.
The third type of project are Cocoa applications. So this includes a lot of the new applications coming to Mac OS X. A lot of the new ones are written in Cocoa. And we'll talk a little bit more about how long it takes to do these. Steve this morning said a few days. As you'll see, it could be less. And the last are Carbon applications. And of course, this is the stable of applications which defines the Mac, has defined the Mac for a long, long time.
So again, it depends how much of Xcode you're using and whether your application is cross-platform already to determine how long it's going to take for you to move these across. So throughout the rest of this talk, as we go through the other top 10 best practices, we'll show you how adopting these best practices will ease your transition to make it processor independent and will help fill in this column. So as I said, the new best practice number 11 is 2D. And that is to build a processor independent application. I said that, and it was a few minutes ago, and I kind of lied.
It's true, but it's not the whole truth. In fact, we do want you to continue to build your applications and run on PowerPC. There's a huge installed base of Macs out there running PowerPC, so we want you to keep on selling into that installed base, and to the new base as it emerges over the next couple years with Intel processors. But we don't need to build two applications, one that runs on PowerPC and one that runs on Intel. So what we've done is we've provided a technology that enables you to build a single application that will run on both.
and this application, this type of application we call universal. So universal application is an application which can run on both PowerPC and Intel, double click, just works. Now why would we want to do that? There's a lot of reasons. All right, so this means best practice number 11 is to be universal, not processor independent.
So as I was saying, why would we want to do this? Well, one reason is it removes a lot of IS department headaches. The last thing your IS department wants to do when they start adding Macintoshes that are running Intel is to have to have -- An applications folder that has one folder which is Intel and in there are listed all of the Intel-based Macintosh applications and below is one labeled PowerPC, right? This is really confusing. Here's even a worse example that we conjured up where every single application is listed twice and you look in the kind column and figure out which one and then try to look at your about box and what kind of machine are you running.
You don't want this. You want any user to be able to sit down on any machine, double click and run any application and it just runs. They should be able to connect to a server, the server has a bunch of applications on it, double click any application on the server and it just runs. So, no IS department headaches. The next is really for you which is you should have, you know, one SKU.
If you're building this application, jam on it. It doesn't exist, but we'll give it out to you if you'd like to build one. You don't want to have to have two boxes with this fine print on the side of the box where a user has to walk into the store, look at that fine print and say, which one is for PowerPC and which one's for Intel, and then buy the correct one.
People don't want to know that. They don't want to have to know what kind of machine they're running. They just know they're running a Mac. And so instead of selling two boxes, you should be able to sell a single box that can run on any Mac out there.
The basic story is, as you walk around the show floor, you're going to see a lot of these machines. And some of those machines are going to be running PowerPC inside. Some of those machines are going to be running Intel. But as far as the consumer is concerned, it shouldn't matter. Your applications, all of the applications should just work on all of them, and they should just work natively.
So if this is your user interface on a Mac running PowerPC, then this is your user interface on a Mac running Intel. If this is your dashboard on a Mac running PowerPC, this is your dashboard on a Mac running Intel. It's the exact same. The experience for the consumer is the same. So, best practice number 11, the new one, is to build universal applications. Build one application, the same one you have today, and enable it to run on both PowerPC and on Intel.
All right, now let's go to the next of the top 10 best practices. We've taken and split it into two categories, the best practices for user features and the best practices for implementation. So let's get to the cars. Here's a big garage. I'm going to start on the five best practices for user features. So tell us what's behind door number 10.
So best practice number 10 is to build the ultimate driving experience, which really is to build the ultimate Mac application. A lot of people come to us and ask, you know, what are the guidelines, what are the rules, what are the tips, what are the tricks to build the best Mac application possible? And so I'm going to go through a set of those that should help.
The first one should be obvious, right? Start with a killer idea, start with that killer idea that you know is going to sell, and then know your target customer. And this is really important. A lot of people don't do that. You know, are you selling to a consumer? Are you selling to a professional? Are you selling into education? Are you selling to the enterprise? So really know your target customer.
Next, design for Aqua and Mac OS X. So clearly Aqua is the user interface, so design so it fits in and feels like an Aqua application. But also, especially if you have a cross-platform application, make sure that when it runs on Mac OS X, it feels like a Mac OS X application. What do I mean by that? Well, simple things like we have a single menu bar, so make sure you take advantage of that. But also, we have a dock, which moves around the screen. So make sure you're listening to the API so when the dock moves, it doesn't include your document and you can resize. So there's a lot of things like that.
We sell a ton of portables. Make sure that your application deals with mobility extremely well. Let's get back to the Aqua part of that. Here is a cross-platform application, which is a chat app. It's a Mac OS X application, which clearly was designed with the lowest common denominator. It works, but it doesn't feel like a Mac application. It does not feel like an Aqua Mac OS X application. Our users really demand that people build great applications that feel like Mac applications. So let's get back to the Aqua part of that.
The next thing is keep it simple. It's often much easier to build an application which has more and more features and to allow the feature creep to happen where suddenly it becomes this mess of tons and tons of features that someone sitting down to the app can't figure out, can't use.
It's much better to figure out exactly which app-- which features you want to implement and implement them well. So looking at this, you know, there's a lot of features in there, but it's extremely daunting for the new user. Next, iterate on elegant layout. When you have a killer idea and you start to implement it, don't stick with the first layout that you come up with. Really iterate until you have a fantastic layout. Let me give you an example.
A company called Stamps.com has what I believe is a killer idea. They want you to be able to use the photos from your iPhoto library and create stamps that you can then use for the US Postal Service. So use pictures of your kids that will then be the stamps you can send out. Very cool. The first implementation, the first layout of this did not communicate the power of the idea. So let's walk through a few things that aren't right in this layout and then show you what they did.
First, where's the star of this application? This application is all about building a stamp, a great stamp, but it's hard to see that with this really crazy layout and there's all these controls all around. So where's the star? Next thing, information flow. Information flow is key to simplicity. Good information flow is key to finding out how you use an application, how you walk through the application and construct what you're doing. This looks sort of like a lightning bolt. It's confusing to figure out which set of steps you take.
There's not enough information. One of the key parts of this application is picking a photo you're going to use for your stamps. And you can barely even see three photos from your iPhoto library in it. Next is control clutter. You'll see that there's actually some controls in the content region. There's some controls below the content region. There's some controls even further down. You know, what acts on what? It's not clear.
Choose your controls wisely. If you look at this, they've chosen to go with the metal application, and yet they're not using the metal variants of the controls. So make sure you use the right control for the right job. And speaking of metal, there's big wastelands of metal on this, which don't look very good either.
So that's what they started with. And they iterated and iterated and iterated, and here's what stamps.com came up with. It's far better, and it solves all the problems we just talked about. There's a clear star. The star is the stamp you're building in the middle. Information flow clearly flows from the top to the bottom.
There's more information. You can see eight photos here instead of only being able to see three photos. There's no clutter anymore. All of the controls are lined up nicely below the content region. You know what they work on. And they've used the metal variants of the controls. And there aren't giant swatches of metal all over the place.
So again, they started with this, a great idea, but weren't communicating it well, and then iterated to this. So when you are working on your application and you think you have a killer idea and you have a layout, really iterate through each of the points we talked about to build the killer application.
Next, adopt killer technologies for Mac OS X. So here is a cross-platform chess application. And again, it works, but it clearly doesn't feel like a Mac application. It's not taking advantage of anything that's specific to Mac OS X. This is Big Bang Chess. So Big Bang Chess, it uses Quartz and OpenGL and QuickTime for animations to make it beautiful to get these reflections.
It ties in with iTunes so you can play different songs while you're playing a game. It actually uses the address book to find opponents you can play against. It uses iChat and Mail to send out and actually ask requests. It ties in with Bonjour to find people local to you to start chess games with. And in fact, you can even have it send an email each time you make a move because you're slow to remind the other person that you're still playing and it's their turn.
So Big Bang Chess, a lot of features it ties in. And using, leveraging all these features of Mac OS X makes it that much better of an application. So Big Bang Chess, a lot of features it ties in and using, leveraging all these features of Mac OS X makes it that much better of an application. application.
And next, really deliver high production value. Mac users demand that you have high production value. Let's say you're building an application that's going to catalog everything you see on your shelves at home. So your movies, your DVDs, your books, your games. You could build an application that looks a lot like a spreadsheet. And it's functional, it works, but compare that to Delicious Library.
Delicious library has a photorealistic shelf. It integrates with the address book for the people on the left. It integrates with Spotlight so you can find these things anywhere. It has a widget. It uses OpenGL and a bunch of the core imaging stuff or a bunch of the Quartz stuff to draw these things nicely.
It even integrates with the iSight so you can hold an iSight up to your book. And it actually scans the barcode and then looks out and gets you the picture of the book so you don't need to type anything in. So it really integrates with all these different technologies and then has this very high production value feel to it.
So here are six great points for building a killer application on the Mac. Now, one thing we found over the last several years is that technology advancements are enabling experience enhancements. So technology is advancing very fast, and that enables us to make the user experience even better. Specifically, I want to talk about the improved performance of the GPU, of the graphics card.
If you look back seven years, Seven years ago, we could render about 30 million pixels a second. So using the state of the art for graphics seven years ago, we could render 30 million pixels a second. If you look to Moore's law to predict where we'd be today, Moore's law says that you double the processing power every 18 to 24 months, we'd be at about 250 million pixels per second today. Let's go ahead and graph what really happened.
I can only graph two points on this chart without changing the scale. And this is because GPUs have vastly outperformed Moore's Law. Let me change the scale here and show you what's actually happened in the GPU space over the same time. We can now calculate and render well over 6.5 billion pixels a second, when Moore's Law would have actually suggested we could render about 250 million. So this is fantastic improvements in technology.
Why does the user care? The answer is there are benefits to the user of the increased GPU speed, and it's benefits that basically you get by leveraging that increase in power. The first thing it does is it gives you increased fidelity. A little more than a decade ago, this little game came out. It was Myst, and it was considered a breakthrough in multimedia gaming.
When you look back at it, it was basically a slideshow of a few renderings, and every once in a while, you get these tiny thumbnail pre-rendered movies at 256 colors that would play. and that was considered great multimedia for a game. In the fall, Myst 5 is gonna be released.
Myst 5, of course, is 32 bit deep instead of 256 colors. It's full screen instead of tiny thumbnails and this renders 15 to 30 frames per second whereas the original Myst rendered a single scene in 24 hours on a Mac Quadra. So we've gone from 24 hours for a frame to 15 to 30 frames per second and that's all to the increased power of the GPU.
The next thing the fast GPUs have done is they decreased the wait time. So in the past, you spent a lot of time waiting when you want to be doing. An example of that is render time. A lot of video applications had this very slow render time. And so you'd add a transition.
You weren't sure it was going to be the right one. You sat and waited for it to render. If it wasn't the right one, you had to redo it. And it really got in the way of the creative process. So the faster GPUs have enabled us to move from render time to real time.
If you look at Final Cut Pro, Final Cut Pro used to have all these render panels where you'd have to wait. But now, most of these transitions, when you add them, are done real time. There's no longer a panel. You can see it immediately. So faster GPU has decreased the wait time.
And last, it's really enabled new applications. Things like iChat U+3 we could not have done without fast GPU. All of these reflections, the skewing of the people, that's all done on the card. We couldn't have done this application without these fast GPUs. Motion. Motion is all about real-time effects and being able to manipulate these real-time effects.
Motion couldn't have been done without these fast GPUs. So GPUs have done a lot for us. It's up to you guys to take advantage of it, but they increase your fidelity, they decrease the wait time, and they enable whole new classes of applications that you guys can come and think of and implement.
If you sort of step back and see what we've done with this, we start with both the GPU, the fast GPU, and the CPU, and really just consider that processing power. And on top of this processing power, we build these really powerful graphics libraries, right? Everything from OpenGL to Quartz, Core Image, Core Video, and QuickTime. So we build these great, powerful graphics libraries. And your application, of course, sits on top of these.
Now, these libraries both allow you to leverage the power of the GPU and the CPU, and they insulate you from it. So for a while, you've been using the power of, say, programmability on an ATI card in the right Mac. But none of you had to go and learn how to program the ATI card. We did it for you, right? We employ smart people who do exactly that for you. And so we've already insulated you from that. And the same way.
If you code to our high-level APIs across the board here, then you don't have to worry whether or not you're running on a power PC or Intel. As far as graphics would be concerned, you'll already be universal. So we have these great graphics libraries. They'll insulate you from it, and they'll take advantage of exactly the right GPU or CPU.
In fact, as CPUs become more and more parallel and GPUs become more and more programmable, we'll do the right thing in our libraries to take advantage on the system that your app is running. To maximally leverage the power of the processor there. All right. So that is best practice number 10 to provide a killer user interface. What is behind door number nine? The answer is building in a navigation system.
A navigation system in your car is all about finding things, right? Finding where you're going, finding a gas station along the way, finding a restaurant. We've believed for quite some time that finding and searching are really important to improve the user experience of using an application. So if you look across the board, each of our applications, you know, more and more of our applications have built-in search fields and a built-in find. We think it's extremely important.
And that's why in Tiger, we built in what we believe is the ultimate in searching, and that's Spotlight. So I'm sure you all know Spotlight. Top right of your menu bar, you can click on it, you get a search field, you can type anything you want, and we'll search your entire drive, and extremely quickly we'll come back with a set of results based on your search being of either metadata or the contents of those files. It's great. Now it's your turn.
Now what we want you to do is make sure that you integrate well with Spotlight to make the Spotlight experience for all the customers even better. The first thing you should do is embrace metadata. If you're working on a document-based application, then the first thing you want to do is augment your document with metadata. So for something like this, you should add, you know, what kind of camera took the picture, add some keywords, add, you know, was there an alpha channel or not.
So augment your documents, whatever they be, with appropriate metadata that people might want to search on. The next thing you should do is preserve that metadata. So if you open up a file that has metadata in it, when you save that file, make sure you don't lose it all. Make sure you preserve the metadata across savings. So first thing for Spotlight, embrace metadata.
The second thing is you'd like to spotlight enable your documents. So what does that mean? Let me take you behind the curtain of Spotlight to explain at a high level how Spotlight works, and then we can see how you can Spotlight enable your documents. At the center of Spotlight is a central index for the entire system. So we have this great, very fast, robust central index. It's tied in closely to the kernel in the file system, and that is the Spotlight index. There's two ways of interacting with this index. There's populating it, and then there's using it. So let's talk about populating.
The index is populated by a series of importers. So each of these importers knows about one or more document file types. And whenever one of those file types appears on the system or changes on the system, the importer notices it and tells Spotlight about it. We try to provide almost all these standard file type importers out of the box. But if you have a custom document type, if your application creates a custom file type, then you need to create an importer to let your documents in on the Spotlight game.
So to spotlight enable your documents, you should write Spotlighter importer plugins where necessary. The last thing is really using Spotlight APIs. So again, looking to the other side of this, the using side, we have a great set of APIs where your application can sit, it can make rich queries of the Spotlight index, and you'll get results back. These queries can be compound queries. They can have multiple criteria. They can be standing queries. So if anything ever changes in the file system, you'll immediately be notified of that change, and your query will always be live.
An example of where we do this is mail. We can do a search in mail. That's a spotlight query. You can actually save that as a smart mailbox, which makes it persistent. All of that's done using the spotlight APIs. So three great ways to use the spotlight APIs. And that's the way to build navigation into your car. In this case, your application. All right. Next car. What's it going to be? The answer is? Pimp Your Ride.
HR has left the room. So it's popular to pimp your car nowadays, right? It's popular to pimp your ride. So in Tiger, we believe we've added a way to pimp your OS. And you can do that through a set of accessories called dashboard widgets. But we've been getting questions from people saying, how do I build a dashboard widget that really fits in with the rest of dashboard? Dashboard is a completely new UI paradigm in the system. So how can I build the right kind of dashboard widget? So let me go ahead and give you some guidelines on how to build killer dashboard widgets. First, don't bogey the screen.
Dashboard widgets, unlike Windows from any other application in Mac OS X, aren't meant to occlude each other. They're meant to sit side by side. They're not meant to sit on top of each other. And the reason is, you bring dashboard up and you dismiss it very quickly. So the last thing you want to do is bring up dashboard, have to move some things around to find the information you're looking for. So don't build some giant dashboard widget that takes up most of dashboard because, frankly, no one's going to use it.
What you should do is build a nice small dashboard widget with exactly the right information. And if there's more information someone might want, if these are headlines of stories, they can click on that dashboard widget and you can take them somewhere else, take them, say, to Safari to read the full story. But this is the place just to get that quick information in a nice size. So don't bogart the screen. Next, one widget per function.
This widget right here has three completely separate functions in here. It's a clock widget, it's a weather widget, it's a calendar widget. Instead, build three different widgets. That allows the user to decide which of those widgets they actually care about and will pull off and use, and it doesn't sort of confuse the story. So you should have one widget per function.
Next, dashboard widgets, as I said, are not Aqua applications. So if you look on here, one of these stands out. And it's the middle one because there's Aqua controls in the front. Everywhere else, we try to use custom controls that fit in very nicely with the dashboard. And so you should do the same. You shouldn't put Aqua controls in the front of your dashboard widgets. You should make something feel very, very Aqua-like, or very, very dashboard-like.
Next, communicate key information quickly. As I said before, the dashboard's meant to be brought up and dismissed quickly, right? People bring it up just to look at something. So here's a weather widget which doesn't communicate hardly anything. It's sunny in 73, somewhere in there. But again, this weather widget, you know, with a large number for 73, with a large sun, immediately communicates the weather conditions. And if you want, the smaller numbers on here will communicate highs and lows for the day. But the key information is, what's the temperature right now? Is it sunny? Is it raining? Is there lightning? All right, next.
Uh, baby's got back. So the front of your widget is for communicating information. Right? The front of your widget is for communicating information. The back of your widget is for configuration. So make sure you put all the configuration on the back of the widget and keep all the information flow on the front of the widget.
And last, really make it beautiful. Dashboard widgets are supposed to have this really fun feel, make them beautiful. There's one thing I'll point out that we've tried to do, which is try not to create a widget with too many colors. Right? Don't create this Christmas tree of a widget. Try to pick a main color and then play off that color for the rest of the widget.
So if you look at the stock widget up there, blue is clearly the color of the widget. I think there's four different blues in there. They're different shades of the same blue to help tie it together. But distinguish the different regions where necessary. So really make your app, make your widgets beautiful. And that is number eight. Pimp your ride. So behind door number seven, we have make room for everyone.
For years now on Mac OS X, we've been adding accessibility sort of throughout the OS. And we feel very, very strongly about this. We've added zooming, white on black display, it goes on and on. We've been adding more and more accessibility. But with Tiger, we think we've hit a home run in that we've built in something called VoiceOver. And VoiceOver is a screen reader for both the blind and the visually impaired users.
When we went about building this, we wanted to build the best screen reader in the world, and we wanted to build it in to every copy of Mac OS X. Because we feel very, very strongly that if a student at a school goes to the lab and they're blind or visually impaired, they should be able to use every single machine in that lab. They shouldn't be told you can use that one in the very back, which might not even be on today. They should be able to walk up to any machine in that entire school, sit down, and use it.
We believe if someone goes into a library, they should be able to walk up to any machine in that library and use it. And the great thing is, if that library, if that school is running Tiger, they can. We don't believe this is just for after you've, yeah, absolutely.
We feel very strongly about this, and we hired the team for this. We said, we are going to build the best in the world here, because we want everyone to be able to use every Mac. We didn't say they should be able to use it after everything's installed. We said they should be able to walk up to a machine and install Tiger themselves. So we build VoiceOver right into the installation. We try to make it permeate the entire OS so people are never felt like they're a second class citizen running Mac OS X.
So that's what we've done. Now it's your turn to help make this work throughout the OS with all the applications. The first thing you should do is support the accessibility APIs. So this is a set of APIs which will tell VoiceOver what your application is doing so it knows what to read. It knows to say, this is the button you're on. Here's the text the person's typing. You have to support these accessibility APIs to integrate with VoiceOver.
Next, you should add full keyboard access. By adding full keyboard access, you further improve the fidelity of using your application with VoiceOver. You should also make sure there's keyboard alternatives to all mouse operations. And we've actually added a lot of tools to help you out here. So if you take your application and you run it through the accessibility verifier, it'll create a report customized for your application saying what needs to be done to make your application accessible.
The Accessibility Inspector is an application which, while you're running your application, will tell you what parts are accessible and you can sort of, you know, at runtime test things out. And of course there's nothing better than just turning on VoiceOver, which if you're running Tiger today, you can do on any machine, I think it's Control-F5, it'll turn on VoiceOver and you can see how well your application runs with VoiceOver. So if all of this wasn't enough, there's a stick.
And the stick is that some organizations won't even buy your software unless you're accessible. But we should all do it for the right reason, not for the stick. To really experience VoiceOver and how well it works, I think you really need to have a demo. So I'd like to bring up Eric Seymour, the manager of the VoiceOver team, to show it off. Eric.
Okay, so as Scott said, one of the most important features of voiceover for somebody who's visually impaired is that you can just walk up to any Tiger system, no matter where it is, and turn it on. So let's do that right now. I'm just going to hit Command F5, turn it on.
VoiceOver off. There we go. Let's do it again. VoiceOver on Safari app window back. Dim button. So VoiceOver speaks to me. It lets me know what's going on on my desktop. And now I'm going to move around a little bit without using the mouse, by the way. Forward.
Dim button. Reload button. And as I move, VoiceOver gives me an indication of each item that I'm landing on, so it helps me along my way. So I'm going to quickly jump forward to the search field. Add bookmark but HT splitter blank Google search text field. And I'm going to search on something. C E I E E C space C E O V R.
So that sound you hear is VoiceOver telling me that the page is done loading. And I'm simply going to start reading the page. VoiceOver Search, Advanced Search Preferences, Link Web. So VoiceOver isn't only designed for users who can't see the screen at all. It's actually quite optimized for folks who have low vision and who still rely on some of that vision. And also for users who have full vision who want to collaborate with a VoiceOver user. A lot of times people work at a computer at the same time, same computer.
So let me show you some of those features. One of them is I can make the VoiceOver cursor bigger. VoiceOver 3, 4, 5. And continue moving around. Did you mean VoiceOver? Link Apple, Mac OS X. Mac OS X Tiger introduces VoiceOver app. Now if I have difficulties tracking the VoiceOver cursor as it moves around the screen, I can also move it to center. So let's do that now. Dial visuals.
Link Apple. Accessibility. Link the VoiceOver cyber style and expensive. All right, now let me make it small again. Voice 3, 2, 1. And let's move it back to center. Or move it back to normal. Dial visuals. And let's finish up and follow a link. Link the VoiceOver. Link Apple. Accessibility. VoiceOver. Press Apple. OK. So that's VoiceOver. Now I'm going to turn VoiceOver off.
VoiceOver off. So VoiceOver relies on the accessibility APIs. And of course, we're asking everybody here to implement the accessibility APIs in your application. And this is important because this is how VoiceOver talks to your application and gathers information about the user interface experience as it's happening, as it's changing. And it turns out that this is a really powerful feature inside of Mac OS X.
And it opens up all sorts of interesting opportunities for applications that have nothing to do with accessibility. So I just want to show you an example of that. Let's say that I wanted to build some online help. And I want to vend it via the web, HTML. So here's what that might look like.
So here we have some online help. Somebody could go to this website and see step-by-step instructions. So we've got some text describing each thing, and we've got screenshots with circles around each item of interest. And in this particular case, this tells me how I can set the recent number of applications in the Apple menu using system preferences. So it turns out the accessibility APIs can help us create this type of documentation fairly easily. So we have a little sample application, some concept where that does that. So I'm going to show that to you.
All right, so the first thing I'm going to do is launch this little sample application. It's called Follow Me. And I'm going to start recording. So... Notice now as I move around my user interface, a little red circle follows me underneath the mouse. So this is Follow Me asking the accessibility APIs, what's under the mouse? What's its screen rectangle? And then it uses that information to produce this circle. So that's fairly basic. So let's go ahead and create some steps for our step-by-step tutorial. So step one is going to be click on System Preferences from the doc. And now let's go ahead and click on it. And step two is going to be click on Appearance.
And now let's go there. And step three is going to be go to this pop-up here. And step four is going to be-- let's use 50 for our example. Let's screenshot that. And we're done. So let's quit System Preferences. Don't need that anymore. And let's take a look at the results and follow me. So now, of course, we have four clean steps here. And we've got screenshots with each step with the circle drawn in the right position.
But more importantly, we've got text. And I didn't enter any of this text. And the text is actually quite useful and accurate. So click System Preferences in the doc. Make selection from the pop-up. From the pop-up button, choose 50. Now this is, follow me, using accessibility APIs and asking very specific questions of the user interface. Not only where is it on the screen, but what's its purpose? What's its purpose in the application? What's its title? What's its value? And then it turns around and presents that in an alternative way. VoiceOver is doing the exact same thing for folks with disabilities.
So there's a mainstream use of the accessibility APIs. It's a very, very powerful feature, often overlooked in Tiger. And it's very well supported by Carbon and Cocoa. And I just want to leave you with one reminder that VoiceOver is on every single Tiger system. So I strongly encourage you, hit Command-F5, turn it on, see how accessible your applications are. Thanks very much.
Thanks, Eric. Yeah, and VoiceOver is fantastic. It's really going to open up our applications to everyone, to all blind and visually impaired users, and the accessibility APIs are going to open up a whole other class of application to be able to do things like this Follow Me demo that was shown today. So that's accessibility in VoiceOver. Next car, Baited Breath.
Joyride. So this is about making your apps fun and compelling, things that people really, really want to use. And I could have a whole set of slides about this and try to explain it, but I think the best way to explain it is just to give you a demo of two applications that I think sort of fulfill this category. So let's go over here.
So the first application is called Comic Life. There's actually an interesting developer story with this. Five different engineers are working on this. They've never met each other in person. They met on the internet. They live on three different continents. And they decided to write a Cocoa application for Mac OS X to build comic strips.
So let me go ahead and grab a picture for the top here. How about a couple longhorns? What do you think? So you see, as soon as I drop that picture on, and these pictures here are all from your iPhoto library, so it integrates with iPhoto, it performs a core image effect.
I can go over here and I can change the core image effect, things like your hatched grayscale, how it's drawn bright. So all of these are core image effects applying almost immediately. All right, so what would Longhorn say? Shouts from the audience. I like to chew my cud.
Isn't that what longhorns do? They sit around and chew their cud? Okay. So there we go. There's one image. Let's go and add -- how about a tiger? Very nice. Let's get a speech balloon for that. He's a little more rambunctious. He says, catch me if you can. Move that over there. Boom. All right. So this is also integrated in with the EyeSight. So I can go down here and I can say Capture. And here am I. Let me see if I look this way. Now it's there. There we go. It just cartoonified me.
And I'll say see you on the other side. I can squeeze that guy around, move this over here. I don't like that. Off my nose. Nice. All right. See you on the -- let's make it a little bigger. The other side. Notice there's sound effects for everything. That's not my lunch. And one more here, so how about this image from the chasm? Nice tiger jumping a chasm and this longhorn looks slightly frightened. So we'll say, "Whoa!" Convert that to graphics.
Boom.
[Transcript missing]
There we go, put that around there. So again, a really nice Cocoa application done by these people around the world. Now I have this great cartoon I'd like, this comic strip I'd like, I want to publish it. Well, .Mac has public APIs now, so you can publish things in your applications to .Mac. So let me go ahead up here and do as simple as saying, publish to .Mac.
And it'll go ahead and create this. Here we go. Looking for .mac. Here we go. Tiger, rocks, tiger. Boom, publishes it. It creates a JPEGs of each of these images. It creates the HTML. It uploads it to my dot Mac account. And boom, there we are. Let me open it up in your browser. Here it is. There's the cartoon. So just like that. It's a comic strip. It's a really nice example of a very fun, engaging application, a joy ride. All right, so let me show you the next one.
This next application is called Unity. And it's a 3D gaming engine, plus it's an environment to both create the game and to play it, to test it at the same time. So if you look up here, this top pane is all about creating your game, laying it out, and the bottom is all about using it. So I can go ahead and just start running it, and here I am playing this game.
Run around. All right, great. So again, the top is about setting it up. So I decide I want to move this light source. I can just grab the light source, move it over here. This is a fan light source, so you can see when I run it, it's rotating, the fan's all rotating. And I can run through it.
So let me go ahead and take this box. I can move the box over a little bit, right about there. Again, run it. It's great, except it seems odd that a box is floating in midair, so the engine's better than that. I can turn on gravity. Now I turn on again. Look, the box will actually fall through the ground.
OK. So there must be something I'm missing here. Let's go to Component, Dynamics, and turn on the box collider. And let me go ahead and run that again. And boom, it falls and it rocks the other box. So very, very cool. Real time, you can sit there, play, learn about it.
So this is great. So I'd like to pimp my ride. I'd like to make a game out of it. Now I can just go here and say build game, which will build a game I can spit out. It can build it for a full screen player. It can build it for the web page. But notice we've been out for, what, 40 days? You can build a widget out of this. No, they say, impossible.
My great game. All right, so I'll go ahead and create the game. So again, it's walking through, finding every one of the objects, creating them, creating all the characters, and it has spit it out, so let me hide this. Here's the new widget, double-click. Yes, I'd like to accept.
It's loading it up, initializing all the different pieces. It has created this nice little game frame, and here we are. You see the box just fell. I can go around, blast things, and now I have this pretty high-fidelity game, which I can spend the next 10 hours playing for you, you know, right here.
So very, very cool. It's a game... Using the APIs of Mac OS X, using things like OpenGL, they've built this great Cocoa both building environment and test environment, and they can even go out to widgets already. So very, very cool. So that is Joyride. It's to make very fun, compelling, engaging applications. And even if you're building something which is for the enterprise, find ways to still make it compelling, make it fun. So here are the five user features. Now I'd like to turn it over to Bertrand to go through the best practices for implementation. Bertrand. Thanks, Scott.
[Transcript missing]
Now we've added a twist to it, and that's the Maco binary format. This format takes the executable section compiled for PowerPC and glues that to the piece of executable that is compiled for Intel. This is being multi-architecture by design. We planned this a while back, just in case. We've also changed the drivers, the GCC driver, so that you can specify several arguments at the command line, and it will build this universal binary.
This is the way to compile code to have your code universal. Could it be easier? Answer, yes, it could be easier with Xcode, because with Xcode, you just have this checkbox. The two checkboxes that Theo mentioned this morning, they are there. Now, this checkbox produced not just a universal binary, but they produce a universal application.
Because as you know, in Mac OS X, an application is a token in Finder, but in fact, there's a whole set of things underneath. You have, obviously, the executable. Now, it's a binary that's universal. But you also have all the resources that you need when you run your application. And you have all the localization so that everyone from the world can run this application.
You have these applications that can live on a server, that can serve people that have a Macintosh with PowerPC. Some will have a Macintosh with Intel. And they can even use different languages. This is truly universal. So my first best practice here, you need to literate. And that means using a universal set of tools using GCC and Xcode.
Next, best practice: open it up. This is all about openness. Because over the last decade or so, there's been a major shift in the computer industry towards open systems. And in fact, Apple is at the forefront of a shift. If you think like a decade ago, we had an operating system that was not so open. I'm talking of Mac OS 9 and its predecessors. It didn't integrate very nicely in the rest of the world. Think, for example, of networking.
It didn't have much bridges, too many bridges towards open kind of systems, open subsystems. On the other hand, Mac OS X is a very open system. Of course, you have Unix. I mean, you can do more open than Unix. Unix define openness in many ways. But you have also all those bridges towards things like X11.
So there are two sides to openness. You have open standards and open source. Why do open standards? Well, the first reason is obvious, to avoid reinventing the wheel. There's lots of people who've thought deeply about those topics. You may not be an expert in that area. Just use a standard.
But there's a deeper reason for that. It's Metcalfe's law that states that the interest of a protocol grows as a square of the number of people who speak that protocol. This is a very conceptual law that I think applies to a lot of what we do in the computer field.
Now then you have open source. Now open source of course implements open standards. That's very typical for open source. There's one reason to use open source that has grown over the last few years and that's the security advantage of open source. Because when you have some code that's open source, you can trust the code. Because many people are looking at the code.
If it's open source, they can look at the code. They can, if there's any weakness, look at it and make sure all the weakness get addressed. On the other hand, if you have closed source, you have to trust the entities that provide you the source. This is why we've made, this is one of the reasons why we've made the whole lowest level of Mac OS X open source. Open source. Code as well is very reliable. Because again, lots of people have contributed to fixes.
It's also a good thing for the community in general. So that's a little kind of fuzzy and mushy, but I think you can do open source just for self-interest as well. Because you benefit of all the improvements of the community and it lets you focus where you add value. The place where you are an expert, that's where you add value and that's a place where you can open source your code or you can keep it closed source. We, Apple, as a model of doing both open source and closed source.
Now we have a number of components in Tiger that are open source. Let me talk quickly about three of them. The first one is SQLite, which is an open source SQL database. Now for a number of WWDC in the past, I had folks coming to me and saying, "Well, can you please bundle the database? I have an application that wants to use the database and there's no standard database coming with Mac OS X, so I have to do that on my own and persistence is not so trivial." So we decided at the beginning of Tiger to look around and see what open source database we could bundle in the system. And what we discovered is that there were several groups within Apple, because of course we had the need as well, who already were using SQLite. They were using SQLite because it was very, very lightweight and it was fast.
And so we said, "This is perfect." And we have added SQLite bundled in the US and we use it in major applications like Mail, Safari. Our experience with SQLite has been exceptional. This is very reliable, very fast, very lightweight. And it solved this persistency problem when you want to have a database.
Now remember, as we go towards Intel, that every once in a while, you have, when you do persistent data structures, you have this byte ordering problem, this Indian issue. And so they solved that. By having a database, you solve this byte ordering issue. So it is a key in having an application universal.
Next open source subsystem, that's WebCore. Now we decided to engage in doing our own Brassler a few years ago. And we looked around and said what open source base are we going to start from? We actually considered doing our own, okay, recreating all that from scratch. But very quickly, we abandoned that idea.
Because again, I mean, you have such a leg up when you start with something that's open source that has been iterated, and that's really good. And we decided to pick KHTML, and WebCore is a derivative of KHTML. Because it was a next generation rendering engine. It was designed with modern concepts in mind, things like cascading style sheets. Very, very modern code base that we knew we could evolve. It was also much smaller than anything else we looked at for the same functionality.
So we have made open source drops of WebCore at regular intervals. I'm very happy to announce today that our CVS repository is now live for WebCore. So you will be able to see the progress as we make it. Now beyond that, we have added an object-oriented wrapper called WebKit so that you don't have to deal with all the details of WebCore. And we've decided to make WebKit open source as well. So you'll be able to see.
You will have a great code base to look at to see how to best use WebCore. And that will go live later this week. Now we added also one feature in WebCore in Tiger that is worth mentioning. In Panther, you could of course render HTML. In Tiger, you can edit HTML as well. This is an important feature. If you use mail, you are using that feature every day, every time you send a message because that's done with the WebCore editing facility.
Next, open source subsystem, JavaScript. Now JavaScript is a language. It's one of those interpreted languages that has been growing over the past. By the way, scripted languages are the fastest growing areas in terms of languages. A lot and a lot of you are using more and more scripted languages, and I think that's great. Now, when you look 10 years ago at the web, people were saying, well, you know, maybe Java is going to take over the web for all the dynamic contents. This hasn't really happened.
What has happened is that JavaScript has taken over. You have more and more dynamic pages that are written using JavaScript. Why? Because it's very lightweight. It's a very simple language. I mean, you don't need to have, like, object-oriented constructs in many cases, and you can just type a few lines of JavaScript and do what you want. It's also very well integrated with the browser. And of course, we use that in Safari.
We have an open source implementation, KJS, and we use that for dashboard widgets. So we are fully committed to improving our implementation of JavaScript over time. We are fully committed to JavaScript. It's becoming one of the key languages on the platform. And one of the nice things of JavaScript that has been mentioned earlier is that it's universal.
So these were three open source components. We have a lot more open source components in Mac OS X. In fact, between the client operating system and the server operating system, we reshape about 100 different open source projects. Now this is maybe a good time to do a parenthesis, open up a parenthesis on Mac OS X server.
This is a product you may or may not be familiar with. If you are a long time Apple follower, you know that this product derives from the Apple share products that we had like a decade ago. Apple share product was file and print using the AFP protocol. It was a very closed protocol, fundamentally. It was not an open product. Now we've changed totally that over the years because nowadays Mac OS X server is all focused on open source.
What Mac OS X server is, is a container of open source products that we can use to run our open source projects. Fundamentally, what we do is we take the best open source projects, we qualify them, something which is not always done in the open source community. We integrate them together. For example, we carburize the services.
We make sure all the open source projects that we shape play well together. And of course, we put an easy to use UI on top of that so that anyone can administer their machines with Mac OS X server. So this is what Mac OS X server has become. very focused on open source.
Okay, so what is the best practice here? Well, it is to do what we do, which is to use open source projects whenever you can. You have a rich collection of the web of open source projects, pretty much any piece of functionality that you can describe in a few sentences. There's an open source project that implements it out there, and there's many open source projects. So you can pick the ones that you want, whether you need some command or whether you need a library.
You then download the open source code, you recompile it. Typically, the code has been run on a variety of platforms, and so it will run as well on PowerPC as on Intel. And if you make improvements to that, you can share them. But the big thing with open source code is that it is universal. And in fact, this morning, Theo mentioned that in Mathematica, there's a number of open source projects that are used, and those projects came along very nicely. So this was my best practice number four, open it up, which is all about using open standards and open source.
Now, next best practice: build from parts. The car industry has realized that you can reuse components from one car to the next. Well, the analogy applies of course to the software industry, where you can reuse components. This is all about object orientation. Now, some of you, when you think of object orientation, you may think about Java.
Mac OS X is a great platform for Java. There's a natural match between the way Java was developed with Unix and the pinnings, Unix stream, Java stream. There's a very nice impedance match with the platform. At the same time, we've made all the work to really make Java apps great citizen on the platform so that our users don't need to know. We support both latest version of Java, 1.4.2 and Java 1.5.
Java 1.5, if you are confused, is also the same as Java 5.0. There's been a little renaming change here. And both versions are available on the Apple development system, which is... The system that you have that has an Intel that you will be able to get your hands on this week that has an Intel processor inside.
So Java, of course, enables your application to be universal. We do all the heavy lifting in terms of making sure it works on any of the processors. There are a number of great applications that are done in Java. Many of you, or some of you, may be using Eclipse, which is a Java IDE geared towards Java applications. In fact, there's a number of great usage of Java. It's ideal for server code. And this is a place where Java has totally taken off the application servers kind of business. It's also great for custom application.
It's great whenever you need to have cross-OS portability. Java is all fantastic for that. But Java is also a lowest common denominator. So if you want to really leverage a platform, it may not be ideal. That's where you want to go towards a native object-oriented framework for the platform, and that's Cocoa.
Now we have, at the inception of Cocoa, we had a bit of philosophy. We wanted to make sure it was possible to write an application without much code. Because we all know that the more code you have, the more work it's going to take to write that code, to maintain that code, obviously.
So there's been a lot of thought that went into making sure we have automatic behaviors in Cocoa, so that when you instantiate your object, you don't need to do a lot of setup steps. Your object is ready to go, ready to be useful right there. We optimize for the 80% case, not the 20%.
We also provided a rich toolbox with encapsulated objects for a lot of the functionalities you may want. But at the same time, we recognized the fact that to make your application special, there had to be a few things where you deviate from the default behavior. That is the added value of your application. That's the 20% case.
And so for those few things, we provided a lot of extensibility mechanisms. We provided, of course, subclassing, but we also provided this mechanism that's called categories that is extremely powerful. It enables you to have a network of objects that is instantiated and to define behavior, added behavior, additional behavior for those objects that got instantiated. This is fairly unique to Objective-C and Cocoa. And we support delegation, which is another very interesting form of extensibility that in many cases is your friend to get with very little code customizable behavior.
Now, Cocoa is built on this language that's called Objective-C. Now, saying that Objective-C is a language is a little bit of misnomer because Objective-C is really a very thin layer on top of C. If you look at the syntactic production in the grammar, most of Objective-C is C. It's just adding a little bit of sugar, syntactic sugar, for object-oriented concepts like classes and methods. Now because it's mostly C, it also means that it integrates really well with C++ and we have a number of applications that are a mix of C, C++, Objective-C.
At the heart of Objective-C, there is a runtime. This is where the power of Objective-C lies. This runtime is really powerful because it enables introspection. So you can take an Objective-C object and ask, "Okay, what kind of methods can you handle?" This in turn enables rapid application development tools like Interface Builder. And that's why you get a higher productivity with Cocoa-based tools because you can specify the behavior right there.
Now, the language is one thing, but a lot of the power of Cocoa comes from its frameworks. We've worked really hard to make sure we have a rich set of frameworks, but very consistent set of frameworks, very consistent, very predictable naming of the methods and so on. Very orthogonal APIs. You are not going to find a little kind of property list abstraction in one part of the API, and another kind of not quite the same, but very close abstraction in another part of the API. No, we factorized all that.
We've added a number of subsystems over the years. There's all the basic subsystems that you can think of, you know, views, text, and so on. Even some very high level ones like document architecture or scripting. and each release we add new subsystems. Let me go through a couple of the subsystems we added in Tiger. First one is Core Data. Now at first glance, Core Data is about object-oriented APIs for persistency.
An implementation of SQL, of Core Data sits on top of SQLite. That means you can have this, in the abstract, this network of objects, but they are stored in an SQLite file and they are handled with SQLite. You can also go to XML files for debug. That's not very scalable, but that's handy. And so you can edit your object graph. You can manipulate it and automatically it will get reflected on file incrementally. This is not like, you know, a big button that says save the entire object graph.
No, this is all incremental, which makes it fast. But Core Data is actually a little more than persistency. It actually provides the abstraction of a model if you use a model view controller paradigm. So it is very powerful in that sense because it abstracts all handling of data, pure data.
And we have a number of tools that enable you to define schema for your object graph. And so that gets rid of a whole lot of code. So very quickly, by using the tools, with direct manipulation of the tools, you can specify what are your objects, what your objects look like, and hook them up to all the UI very quickly.
Next up, system, Sync Services. This is about data synchronization. We all live in a world that has a lot of computers around, computers, devices, and you have your data that's replicated across all those different environments, all those machines. And so this is the problem that Sync Services is solving, how to synchronize all the data between the different places.
Think Services give you very fine control over the syncing process. You can do incremental syncing, of course. You can specify what happens when there's a conflict. We use that for all the system data types you are used to-- things like addresses, calendars, bookmarks, and so on. But it is highly customizable. So you can use that for the data types that are specific to your application. And you'll be able to have your users sync via .Mac or sync with devices.
Next-up system, Core Image. Scott mentioned that a bit. This is about making accelerated graphics easy. I don't know about you, but I do not know how to program the ATI chip or the NVIDIA chip, and I don't really want to know. I want to use filters, what we call image units, and I want to have a large collection of filters. This is provided by Core Image. I want to define new image units, and there's a little language to that that's independent of the GPU.
And then I want something that's really, really fast. No more slow random time. Real time. And that's what Core Image does. It has some rocket technology here to look at the sequence, the composition of your effects and say, okay, what kind of code I can dynamically generate on the fly to have the optimal kind of per pixel composition.
It creates that code dynamically and then it runs it. That's how Core Image works. Really rocket science. And it is GPU and CPU independent, as I mentioned earlier, so it will work whatever machine the user has. In that sense, it is another tool for getting a universal application.
Last Cocoa Subsystem I want to mention, that's QtKit. Over the years, a number of you have come to say, "Wow, we really love QuickTime. There's so much power in QuickTime. The things that you can do with QuickTime are just amazing." But the APIs are a little complex to use.
You know, you have several thousand of APIs to grok, and that's a little overwhelming when you're not very familiar with that. So we've decided to add an object-oriented API that perfectly fits with Cocoa. It is very much in the Cocoa spirit. I think it's been a beautiful job there of having that perfectly fit Cocoa.
It's simple, but... It's simple but powerful. In fact, it is so powerful that this is what we're using in the QuickTime player that is in Tiger. We rewrote the QuickTime player from scratch in order to use the Qt Kit APIs. You know, this is a principle of dog food, which is kind of a religion in Cupertino. So you can get the same power as a QuickTime player in your application by using those APIs. So these were just a few of the subsystems that we've added in Tiger, in Cocoa. There are a lot more.
Now, let me tell you a secret. You may have noticed over the last few years that Apple has produced a few more apps, both system apps and iLife apps and iWork apps. We've produced those apps really fast. They are high-quality applications. What's the secret? Well, most of those new apps written from scratch have been written in Cocoa because Cocoa gives you increased productivity because a Cocoa app is higher level, has less code. It's hard to exactly quantify that. Some people are saying, you know, 5X.
Others are saying 10X. I don't know what the exact number is. It doesn't really make sense. But for the same functionality, you have way less code. That is a fact. And that really makes you write new applications much more easily. Now, what about universality? What about Indianness in particular? Well, the good news there is that Cocoa is a high-level API.
And so it handles a lot of the low-level things for you. And byte ordering is a very low-level thing. For example, if you use the Unicode abstraction and a string in Cocoa, you don't need to bother into exactly what kind of for the Unicode bytes. Same thing for serializations. There's a number of APIs at different levels with different serializations. And all those APIs in Cocoa handle, of course, byte ordering perfectly.
So if you have a Cocoa application, you may have to do minor tweaks because remember, you may have a portion of your application written in C. You can go as low level as you want. And if you go very low level, you may have some tweaks to do. But for the most part, it should just be a recompile. And then you will have a universal Cocoa application.
So I would like now to invite Ali Ozer, who is manager of the Cocoa team, to demonstrate what you can do to make Cocoa applications universal. Thank you, Bertrand. Hello, everybody. So let's say you want to play some Solitaire. And since this mission-critical application does not come with Tiger, you search the web. So if you go to randomoracle.com, there's a very nice little solitaire game there. Let's download it.
Okay, so there it is. Nice icon. Let's run it. There you go. Now, first thing to note is the number in the title is not the number of games I've actually played. As a matter of fact, I'm not very good at this game at all. I can never win for some reason, but I know, you know, you're supposed to grab the reds and put them on top of blacks. The game is pretty nice because it will give you hints. There you go. You know, you can play those, too. You can even undo moves if you make a mistake.
So there you go. Pretty nice little solitaire game. Now, one thing to note, though, this game, I just downloaded. It's clearly a PowerPC application, a Cocoa application written for the PowerPC. However, if we look You'll see that it is one of those Intel boxes. You saw earlier one. Steve was on it. And here you go. This one is also an Intel box. So what's going on here is that this application, this PowerPC application is running translated. It's being translated through Rosetta.
Now, important to note, we downloaded this and ran it, and there was no panels, nothing telling you you're going to do this, no UI to indicate that it's running in this funky mode. It's a transparent UI. You also notice that it's dynamic. It's happening on the fly. It's very compatible. It's very fast. And you just can't tell. So it's doing a very good job.
However, now that we know that this is translated, being developers, it's like, well, translated is great, but what would be even better is if we had a native version of this application, one that was actually built for Intel. So let's see if we can do that. Now it turns out the website I downloaded this from also comes with the source code, which is great. So let's download that.
So there's a tar file containing the sources. I will expand it and I will open it. You'll notice that it's a fairly small size. It's about 3,000, 4,000 lines of Objective-C source code. We'll go ahead and open the project. Now, when you open an older project, any project, either from old days or Xcode 2.0 even, in Xcode 2.1, you'll be asked to upgrade. And you can save the project file aside if you don't want to write over the one you have. So I will go ahead and do that.
So the project is saved and it's opened and as you can see it's got the source code in there. Now before I build this, one more note, if you open a fairly old project, not Xcode 2.0, if you open a Jam-based project or a project builder project, you'll notice that the project is not yet using the native build system of Xcode.
You know that because the menu item here, upgrade all projects and all targets in project to native. That indicates that this is still using the old build system. Now you want to upgrade to the native build system. It's not necessary, it's optional, but you want to do that if you want to take advantage of features like zero link or if you want to build universal.
So it's a good idea to do. And I will go ahead and do that now. It tells me what it's going to do. And it does it. I won't read this, but the gist of it is that the upgrade went well and that should be the experience with most of you.
Okay, now that we've done this, we're about ready to build. One more thing I want to show you is that I'm going to click on the upgraded target and bring up the info panel. Now, so far, you've been seeing the fake version of this on slides, but here's the real panel. The architecture here shows you native architecture.
That's the default situation. If I double click on this, you'll see that panel, the one that's been shown on slides, showing you the Intel and PowerPC buttons. I will leave the Intel selection, and I will go ahead and hit build and go. So, again, this project just came off the web, fresh. It wasn't built. It didn't know anything about Intel. And there you go. So the project came up and running on Intel with zero lines of code change and very minor tweaks, which is nice.
And it seems to be working as well as before. There you go. I can make my moves. Now, you might not believe me at this point, of course, that this is Intel. One way to tell is that you can bring up the application in Finder, the executable, or the application itself. And if you look at this last column with summary of information, you'll see that the architecture is indeed Intel. So I will close this, and I will quit the game. Now I'll go back to Project Builder.
Bring up the info panel. Bring up the architecture panel, and I will double click both. Because, of course, the best practice for shipping your application when you're done with it and you're ready to ship it is to ship it universal. So it runs on Macintoshes of both Intel and PowerPC flavor.
Now, when I do that, and I go back and say again, build, note that it starts building again. Now, this time, it's already built to Intel before, so it's just building the PowerPC binaries, and it's packaging it all up, and it's finished building. So let's go ahead and run.
And again, now this is the universal application. It runs just like the other one did. No problems. You can't tell. The only way that if you want to really tell and convince yourself is you say show in finder. And you'll see that the architecture here is Intel and PowerPC. So zero lines of code change and you have yourself a universal binary. Let me show you one more application.
Now, this one, as I said, is a fairly small app. This one is an application called GNU Mail. This is about -- I think it uses a reusable framework and along with the framework it's about 95,000 lines of code. The app itself is 60,000 lines of Cocoa Objective C and the framework is about 35,000 lines. It's called pantomime, a pretty nice framework for message delivery and so on. So I downloaded this earlier and I built it and I will now get it running for you.
Notice it's doing some last few linking, relinking everything, and it's going to get started right now and copy the resources. And there you go. So this is a... This is, as I said, a fairly large Cocoa application, a full-featured mail application. And you can click on the messages. You'll see that it's got -- by the way, here's where you go for the beer bash on Thursday. Catch that? If you're not taking the bus. Oh, there's the Beagle my nieces just bought and my Apple store order.
But as you can see, it's got support for rich text mail and so on. It's got a nice set of preferences. You can see here you can click expert and see more preferences. And it's interesting to note that although I did download this earlier and prepared for the demo, the number of lines of code I had to change were zero. Zero lines of code change. Again, just build and ran. So here we have two unsuspecting apps that just ran on Intel, no problem.
And as a matter of fact, I actually tried another six, another half a dozen applications, downloaded and tried them, and they all, all of these built and ran with zero lines of code change. So I think for the most part, most of you are going to be in for a nice surprise. And I hope you get a chance to try this out on your Apple devices. own applications soon. Thank you.
Thank you, Ali. Zero line change. That's amazing. So this was building from parts, which is really about using object orientation for high-level programming. Now, what about Carbon? Well, let's talk about Carbon. Let's soup it up. A lot of the big names applications on the platform are Carbon applications.
[Transcript missing]
The best practice here is to continue to perfect your Carbon application and also, of course, to make it universal. Now, you may encounter two areas of difficulty in terms of making your Carbon application universal, and the first one is resources.
If you use resources for standard UI element, well, you're done because we have done the work of dealing with the byte ordering issues that may occur with resources. Of course, the best practice there is that if you want, you can switch to interface builder and then it will become even easier and you have direct manipulation.
If you are using custom resources, well, you are on your own here. You may have to tweak by hand the resources. As you get things of the resource files, you may have to flip the bits or flip the bytes. We provide you a mechanism called flippers to ease that a little bit.
The second category of difficulties that we've seen with Carbon application is document formats. Now, if your application has a kind of standard document format or has been ported on Windows where it's using the same document format, chances are you have nothing to do. Your document format is already end-in-safe.
But if you have some in-memory data structures that you are making persistent by blasting those data structures onto disk, you may have some difficulties because the PowerPC layout is different from the Intel layout. So you will have then to handle end-in-ness. And again, you can tweak by hand. Or you can change your format if that's a possibility for you and use a standard XML format or other APIs like the HRI archive I mentioned.
So looking at the steps to make a Carbon app universal, first step to tweak and then recompile. Ah, but to recompile, you need to have universal tools. And the only universal tools, at least for the moment on the platform, are GCC and Xcode. So first, you need to switch to Xcode.
The good news there is that we've made it easier to import your Carbon application into Xcode. In Xcode 2.1, there are new facilities that enable you to keep the structure for the sources that you have into, when you import it into Xcode. We have a mechanism called configurations that enable you to produce different binaries, different tools. And all this works with precompiled headers so that you can have the best speed for C code or C++ code. And we've improved the debugger. All that will be covered with a lot more length in an hour. or so.
So summarizing the steps to make a Carbon app universal. First one, if you are not there already, switch to GCC index code. Step two, tweak. Step three, recompile. And you will have a universal application. So the best practice for your Carbon application is to beat up. Is continue to evolve your Carbon application as we are evolving Carbon.
Next best practice and my last best practice, probably the most important, pedal to the metal. In order to delight your users, your application needs to be fast. Speed is the key. Now in order to have a fast application, you need a fast operating system. And you know, it's a bit of a challenge when you have 200 new features, including some deep features like Spotlight, to make the system as fast as it was. Yet we've done that. We measure always at each release a number of metrics. And the vast majority of all the metrics we measure tell us that Tiger is a little bit faster than its predecessor. And this is a trend we've carried for a number of releases now.
How do we do that? Well, it's a lot of hard work. We get the entire team to spend several months just thinking, focusing about performance. There's no secret here. It's really a lot of hard work. We turn every stone. You know, we look at everything we can do, and we do it.
Starting with the kernel and the OS, we are trying to be a little more stingy with resources. And the key here is laziness, lazy evaluation. We try to save the memory until you use a certain subsystem. And that's the key. We try to save the memory until you use a certain system.
We have improved boot time. We added a great new facility for those of you who are in the unique space called LaunchD. I recommend that you go to the BSD sessions that talk about that. That enables us to launch all the process lazily in the dependency order. We changed the kernel so that it's a lot more efficient on multiprocessor machines. The fine-grained locking. We've done a lot of things to optimize specific tasks in the OS itself.
Now there's also the frameworks. Now the frameworks are highly leveraged because if we save 1k bytes in, say, the system framework, every single process that uses a system framework, and typically you have like 50 or 100 of those on a typical machine, is going to save this 1k bytes. So you've saved now a significant portion of the RAM that your users have. And you have certain code paths that are very critical for performance. The graphics code path, the text code path, you know, certain operations like drag and drop. So we've optimized all this.
And then there's the tools. We benefit from the improvements in GCC, the improvements that we do, but frankly, we should not take credit here for the community. There's a lot of improvements that the community does in terms of generating more efficient code. We have a lot of improvements that the community does in terms of generating more efficient code. So we benefit from all that.
And in fact, for the last two categories, the improvements we do in the frameworks and in the tools, you directly benefit from that. So you'll get an automatic speed up with your application on Tiger. Do you want more speed? The answer is yes, of course, always maximum speed. That's the best practice here.
And to gain more speed, the first step in all the textbook is first to measure and then to optimize. But you need to know first what is the problem here. And for that, we have a number of performance tools. I think they are very good tools. And the reason why is, again, the dog food principles. We use those for our own system applications. We have tools for pretty much every performance aspect in the system. We have tools to measure CPU activities at shark and sampler. We have tools to address memory usage.
We have tools to look at the threading, at the drawing, a number of tools. I think you will find that our tool collections for performance is really rich. And by the way, all those tools are present on the Apple development system, the boxes that have an Intel processor that you can touch in the labs throughout this week. So those tools are universal.
Now, once you have found out what are the problem areas, what are the hotspots, you want to optimize. And here, all the textbooks say that, and they are right. The first thing to do is to work on the algorithm. Okay, that's the key. But of course you are doing that. And so let's assume this is done.
Then the temptation might be to write assembly code. Okay, let's record this in assembly. It's going to be faster. Yes, you can do that. But you know, it's hard to write assembly. That's right. You are going to spend a lot of time debugging that. And it's very hard to maintain. If you want to use a vector instructions, you know, the LTVec and SSE, this is really like rocket science. So as much as possible, you want to avoid that.
One thing that may save you there is the new GCC feature that is in the latest version of GCC, which is called auto vectorization. GCC will try for certain patterns of loops to use at best the vector registers. And this is whether it's a PowerPC machine using the LTVec vector registers or an Intel machine using the SSE vector registers.
But there's another best practice here to optimize your code that has a deep algorithm where you want more speed. And that's to use the Accelerate framework. We have designed the Accelerate framework for that purpose. What is the Accelerate framework? It's a bunch of facilities for doing vector math, for doing operations on large integers, for doing linear algebra, for doing signal processing, you know, fast Fourier transforms and the like, and for doing image processing, all the filters that you may want to do using the CPU. We've optimized all of those for PowerPC using the Altivec vector registers, but also we've started to optimize them for Intel. We're not done there. We just started.
But we will optimize them for Intel. We will have the... We will have the best implementation of those functions that we provide. This is a commitment that we have. We are committed to have the fastest implementation on both architectures. If you find a function that's not fast enough, that could be made faster, please tell us.
We'll optimize it. And we are committed to have a richer set of functions. We already have 4,500, but we want to add more over time. So the Accelerate framework is a key framework for universality, for getting your application to be universal and fast. And it also saves some code, by the way.
So this is pedal to the metal, making your application fast, accelerate your application. And this is my last best practice. Throughout this presentation, I've used at times the word "tweak" and I've talked about "Indian-ness". So you may not know all the implications of "Indian-ness". You may not know where the word "Indian-ness", the terminology, comes from.
It actually comes from Gulliver's Travel, because in Gulliver's Travel you have two nations, the Little Indians and the Big Indians, and they are at war. They are at war because they have a divergence of opinion on how to best crack a hard-boiled egg before you eat it. Should you start with the big end or should you start with the little end? Now Gulliver's Travel was written by Jonathan Swift, who is an Englishman, and so I thought that to talk about all the subtleties about "Indian-ness", I should invite on stage another Englishman. And that's Simon Patience, who is leading the Chorus team. Simon. Thank you.
Good afternoon. Although I am English, I hope that's the only similarity between me and that photograph of Jonathan Swift. So, as Steve mentioned earlier on, we've been working on this for some time. And in fact, for the last few months, we've actually been working on porting some applications. And so, what I'd like to do is to share with you some of our experiences.
And to start off We found that actually we had a large number of applications that came over, reported a large number, and they came over with zero lines of code changed. And we were actually quite amazed at just the sheer quantity of applications that needed no change whatsoever.
Was it all easy going? Was it all completely without event? Well, no. There were some incidences. We had some applications crash. We had some unanticipated numerical results. We had some unanticipated colors. We also had some strange texts from time to time. We had bad reads and writes from disks.
It's great when you've got kids. And we had some strange network behavior. So what I thought I'd do is we'd look behind what actually caused all these. So let's debug some of these problems, shall we? So the first thing you do is you say, well, you've got two different architectures here, so it's pretty obvious that you're going to have problems.
But the reality is that once you get past the instruction set, which the compiler hides for you, then the architectures are really not that different. There are clearly some differences, and those are the things that are tripping you up, but it's not like we're talking about two things that are radically different.
So the first thing that Bertrand has mentioned before is end in this. So what I want to do is to show you some of the things that we've seen that you'll see when you hit end in problems. So you can see in this dialog box, we've got some buttons here which are yellow.
The buttons next to them have got nothing in them at all and that's clearly not right. And then there's this sort of pinkish box down on the left hand side which really should be the same color as the rest of the background. So these are the kinds of visual clues that say that you have an end in issue. The next one, we have an RGB image here, which is pretty much all R. So that's not right. And finally we have a YUV image here which is pretty much all wrong because Tim looks nothing like that when you iChat him.
So endiness, also known as byte order. So let's have a look at a bit about what's going on here. So we'll pick a number. So there's a nice number. So we'll look to see how it's laid out in memory on the two different systems. So we have on the big Indian, it's a nice logical layout. It reads left to right, just as you would if-- And on a little engine, you see it's backwards. But actually, it's still logical, because the lowest order byte is at the lowest order address. And this goes to all the multi-byte types.
Now the interesting thing is when you put two shorts together and have a look to see how they're organized and on a Big Endian machine they look remarkably like an integer. But this is not true on a Little Endian machine. So remember Big Endian, PowerPC, Little Endian, Intel.
So let's go back to our two integers, and let's have a look at a piece of code that has made some assumptions. Now the assumption that's been made here is that the address of the integer is the same as the address of the lower order byte. But of course if you look at the result, you end up getting two very different values. And this is why you start getting strange colors and things on your screen.
If we go back to the two shorts example, and we have a little code fragment here, that is definitely making the assumption that when you put those two shorts together in a structure and then cast it to an integer, you're going to end up with a legitimate integer. Now, again, if you look at the result there, that's not the case.
Now, the way to solve these problems is just to remove the assumptions out of your code, and if you're doing things like the assignments, then do them in an end-in-safe way. It's okay to have that structure there, but when you extract the elements out of it, you have to do it in a way that is end-in-sensitive.
Another related part of endianness is bit fields. So here's a bit field with four elements in it. This is on a big endian machine. And we'll have a look and see how that's laid out on a little Indian. And the first thing you notice is that the bit fields are ordered backwards compared to the big Indian machine. But if you look at the bit fields themselves, if you look at B, for example, then the bits within that bit field are actually ordered in the same way.
So this makes life very confusing and is in fact a big interoperability risk. If you send this bit field across between two applications through a socket, for example, to the other instance of the application on a different machine that's a little endian, it will get incorrect data. And similarly on a disk layout, you'll have the same problem. So that was endianness. The next topic was divide by zero.
So divide by zero is actually pretty good because it's fairly obvious when you hit it because you get this crash log and it says divide by zero. Now, you'd think that this wouldn't happen very often. I mean, we're all good programmers, right? So, you know, you wouldn't go off and do things like that. But we actually saw this much more frequently than we expected. So let's have a look and see why.
So here's a little code fragment, very little one actually. So set A to zero, perhaps do a bit of stuff in between, and then we go off and assign B a value, which is an integer divided by A. Let's have a look to see what they look like on the two different platforms.
So on PowerPC, B is assigned the value of zero, and your program will continue on and run, and you're all set. You're not even aware of the fact that you've actually divided by zero. On Intel, however, Your program stops. And this is why we see it a lot, because on the PowerPC, there was no real exception caused by the fact that you had divided by zero.
The next thing I want to talk about is structures and unions. Now, you've probably noticed that I'm talking a lot about multi-byte types, and these are really the things that can cause a lot of problems, especially if you make assumptions about how they're laid out in memory. So here we have a structure, or a union I should say, containing a short and a structure which assumes that the bytes are ordered in a certain way.
But if you look in the layout, memory layout of them, then you find that the low byte and the high byte get different values depending on which end in this machine you're in. Now this is a very simple problem to fix, and in fact you'll find this in a lot of code, especially in the Unix world, where you just use a big end in conditional and you just make sure that the right orders are encapsulated in that conditional.
So that's the way that you address those. The thing that Bertrand referred to earlier on was data file formats. So if we take ourselves on a big engine machine, let's say we write out a whole bunch of things, multibyte data, unions, bit fields, and then we go to a little engine machine, we take the file across, and we read it back. And what do we get there? Well, basically, you get garbage.
So how do you address this problem? Well there are three ways which we recommend. The first way is to use the high level APIs, the APIs that you'll find in core data or in foundation or core foundation. So there's APIs at any level of the system, regardless of how you're programming. And they will handle the writing out of data into your files in an endian safe way and reading it back again. So that's the best way to go.
But you may already have a data file that you have, that you've defined, and it's in XML format. That's pretty good too, because XML, as long as you're not writing binary information into it, is also safe. You have to deal with management of the file itself, but you're still in pretty good shape. But you've already shipped your application.
The users are out there using it. They've created the files. And unfortunately, it was on a PowerPC, and therefore it's got big engine information in it already. So what do you Well, use flippers. So flippers are either archive formats or archive plug-ins that will actually exchange the byte ordering on the fly for you, or we have data flippers, which are things like OS byte order, which you put into the stream of data that will invert the byte ordering on the fly as the data comes in or goes out of your file. The good thing about them is that if your endiness sense in the file is the same as the endiness sense of the host, then it doesn't do anything, so you don't incur any overhead.
The next big activity that you have done for your application is optimizing it for performance using Altevec. Now this is hard because you probably spent a long time doing this and invested a lot of effort into it. The good news is that there are a lot of similarities between AltiVec and SSE.
So the structure of your program that you've had to adopt in order to be able to do the vector arithmetic is the same on the two sides. So that helps. Many of the operations that you find on AltaVec are the same as they are on SSE. And most of the capabilities of the two systems are the same. So you're in good shape.
But there are a few differences. Some of the algorithms are not quite equivalent, which means that you have to be careful about what exactly you were depending on and whether it's exactly the same when you get to SSE. Some of the semantics of the operations are slightly different, so you may find that you get unexpected results.
and some of the capabilities of Altevec are just simply not there in SSE, in which case you have to look for alternative algorithms to be able to move across. So we've done quite a few applications that have been accelerated and we've made these ports. And so our recommendation initially is to start with C code. You take your Altevec functions and you just write straight C.
Now the reason for this is twofold. First it gets you up and running faster. And secondly, software is pretty much a living organism. And so what we found is that after a while some of the things that were on the hot path are no longer on the hot path. And so therefore we've had a number of instances where we actually didn't bother turning the C code into SSE because it was no longer a performance issue.
If you're already a cross-platform app, you will have SSE code for other operating systems, say Windows. This you can bring over and use in your OS X app pretty easily. You may have to do some editing to change some of the formats, but it's a real leg up on getting your accelerated code going.
But as Bertrand said earlier on, the best answer is to use Accelerate whenever possible. So take this opportunity to look for the chance to be able to adopt the Accelerate interfaces. And we do have over 4,500 functions and growing. And Accelerate framework is already universal. So you just do this once and you can forget about it for always. So the last thing I want to talk about is some platform assumptions that we've seen in code.
What we've seen is that there's a number of pieces of code that have in their source code an assumption that if it's on Windows, it must be Intel. So you have if-def Windows, then a bunch of Intel-specific code. We've also seen applications which have got the same sort of assumption about, well, if it's OS X, then there must be some PowerPC stuff in here.
So as of this morning, this assumption is no longer true. OS X is now on Intel. So you have to make sure in order to build your code properly that these assumptions are correct. That if you have Intel-specific code, it's in an Intel if-def, and OS X-specific code, and it's an OS X-specific if-def.
So if you followed all these things, then you should be well on your way to having a universal application. But clearly I've only covered some part of this, so you want to know more, I assume. So we've written this document. It's called the Universal Binary Programming Guidelines. You'll find a link to it on the Apple Developer website at developer.apple.com.
And this is a fantastic guideline for you to help to get you to a universal application. It lists the sorts of problems that you're likely to see, the causes of those problems, and what you can do about it. It has code examples. It's a great document. You'll also find it on your CD, so you should be able to look at it today.
The other thing is that clearly I've only touched on some of the elements here. So you need to look through the program schedule and find all the other porting sessions that are going on this week, which will go into much greater depth. And then there's all the labs that you should take advantage of. So hopefully that's explained some tweaks and endings. Thank you, Bertrand. Thank you, Simon.
So let me recap. We went through a number of best practices for building amazing applications, user features for creating the best applications that our users want to buy. We talked about best practices for the implementation so that we can develop those applications really fast and high quality implementations.
We've drawn examples throughout the presentation from Tiger. Tiger has a number of fantastic technologies that bring the platform to a new high. and Tiger is universal. Now a little recap if you were asleep during the various presentation, if this is the UI on a PowerPC system, this will be the UI on an Intel system.
If this is a structure of the system on PowerPC, and by structure I mean those boxes, okay, symbolic boxes, but I really mean APIs because the structure of the system implies the APIs. These are the APIs on a Mac for Intel. It's the same APIs, no change. Same UI, same APIs.
Now, as far as the work that needs to be done for the various kinds of projects, for the first category, all the scripted projects, Java projects, JavaScript projects, widgets, and so on, it just works. For Unix projects, it's just a very short recompile. For Cocoa Apps, I've been conservative and said it's small tweaks and a recompile. But you saw Ali do a demonstration where he took a number of apps and it was just a recompile.
For Carbon Apps, the first move is to move to Xcode if you're not already there. After that, you may have to do a few tweaks and then a recompile. And remember Theo this morning from Warframe Research. Okay, two hours. Now, maybe this was the best guess, but I am sure there will be a broad spectrum here.
You can start today. We have a number of sessions. We have a number of labs. These labs are by technology area. We have seven labs. In those labs, we have a hundred computers with an Intel processor, the Apple development systems. And you can order today the Developer Transition Kit that contains usage for an Apple development system, that contains all the tools that you need, including the latest Xcode 2.1, as well as these great documents, these very thick documents, the Universal Programming Guidelines. I read it.
It's a high-quality document that can really help you transition. We are blessed with having a very vibrant ecosystem with your applications. We have now over 12,000 of your applications. Thank you. Now my request to you. My request to you starting today is to make those applications universal. Thank you.