Application Frameworks • 1:02:47
Beginning with Mac OS X version 10.2, Sherlock uses a powerful, new model for channels that gives developers much more flexibility in how their data is displayed. View this session to learn why you'd want to create a Sherlock channel; what's involved in creating one; how to use the developer channels, JavaScript, XQuery, and XML specifics; as well as general tips and tricks for getting the most out of your channel.
Speakers: Wayne Loofbourrow, Jessica Kahn, Kevin Agren, Riley Howard, Eric Koebler, Sarah Wilkin
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
This is one of the technologies that we've got at Apple that I think has tremendous potential. And there are a lot of developers that are already taking advantage of Sherlock channels today, particularly on intranets and within corporations, to deliver internal web services to their customers. And there's some really cool Sherlock channels that have appeared from third parties.
that you've probably played with. And so this is a great, we think, Sherlock channels, and people are finding that Sherlock channels are a great way to actually get onto Mac OS X if they don't know Cocoa or Carbon, in fact. If they can use their expertise in JavaScript and XML, they can get onto the platform and take advantage of some technology that's there to deliver some services on Mac OS X without having to write a fully native app. That's certainly one advantage people have seen. And there's lots of others that we'll get into in this session. So I'd like to invite Wayne Lufro on stage, and he's going to talk you through the specifics. Wayne runs the engineering team that's responsible for Sherlock channels.
Thanks, and welcome to the last of the Internet Technology Sessions: Delivering Web Services Using Sherlock Channels. So in this session, we're going to talk about how to deliver web services using Sherlock channels. And we'll talk about, well, what are web services? When is using a channel to implement web services a good idea? How to get started, and some of the new things that we've provided in Panther.
So what you'll learn is first what's new in Sherlock the application, some of the developer opportunities, the structure of a Sherlock channel, and then some of the details about how to develop a channel, as well as some of the new features for Sherlock channel developers. And then we'll get into some advanced topics.
So first, what's new in Sherlock the application? Well, so when we thought about doing a new version of Sherlock for Panther, we wanted to do three things. We wanted to enhance the existing channels. We wanted to improve the performance. And we also wanted to provide a solution for the channel management problem.
So in particular, with channels, one of the channels that we put a lot of effort into is the Yellow Pages channel. And we've had some requests to add white pages, which we've done. And we've also added some additional features to the Yellow Pages themselves, which we'll talk about in a bit.
For performance, we rewrote the XQuery engine from the ground up and made it two to three times faster in the Panther release, as well as more conformant with the emerging XQuery standard. We've also made substantial improvements in launch time for the application, as well as channel switching between channels.
As far as channel management is concerned, there's been, with all the third-party channels that have come out, your toolbar gets pretty busy and it's often hard to find the channel that you're looking for. So we've provided a solution to organize your channels that's patterned after the Safari bookmarks.
In addition, we found that folks were really interested in using a bunch of third-party channels, but they didn't know where to find them. And you had to kind of do a Google search and rummage around to try to find where they are. So we decided to build the third-party channels directly into the application.
So first, the phone book. You'll notice that on the left side, there is a little control to decide whether you're searching white pages or yellow pages. But in addition, we've had a lot of requests for category-based searching. If I want to search for Japanese restaurants, I'm not really looking for a business that has Japanese restaurant in its name. I would really like to be able to find by category instead of just by business name. So we support both in Panther.
The other request we got a lot was being able to find near not just a zip code or a city, but also near a very specific address. I'm going to this theater, I want to find the nearby restaurants. And then we made printing from your phone book easier as well with a one-button print.
The channels view is the solution to the channel management problem. Your toolbar just gets too crowded putting everything in the toolbar. So we looked at the way Safari did bookmarks and we patterned the Sherlock channel management view after the way Safari bookmarks are done. And this allows you to control both what's in your toolbar, what's in your channel menu, as well as have direct access to all the channels that Apple provides, even those that are for other countries. And we've added a view for third-party channels. And this is where we showcase all of your channels and make them easily available to users so they can find them, drag the ones they like to the toolbar, or even create their own collections.
It's also the place where the channel development tools show up. So if you're a channel developer and you enable the channel development tools, you'll see them show up in the channels view. So to demonstrate this, I'd like to invite Jessica Kahn, the Sherlock Channel Development Lead, up. Welcome, Jess.
First we're going to show the phone book. So as you'll note, on the left side there's a control for white pages and yellow pages. Right now we're in yellow pages mode. The first field there is the business name or category field. And if you notice, as Jessica starts typing, it automatically auto-completes to one of the categories. In this case, she typed "restaurants" and it auto-completed after just a few characters. And you'll note that in the pop-up, we show maybe some variations on restaurants. So you can choose a particular one. For example, say I want to look for Indian food. I choose Indian.
The next field over is the Find Near field. And just like before, you can type zip codes and city names. But the thing we've added is that it auto-completes city names. So it has a database of cities. And as you start to type, it auto-completes and you'll see San Francisco with just a few characters.
The other thing it supports is it directly supports your address book and auto-completion. So for example, if you want to find restaurants near a friend of yours, you could type the name of a friend of yours in there. Or in this case, we've added Moscone Center to our address book because we've been coming to Moscone Center a lot. So we'd like to see what restaurants are near Moscone Center. And as you see, as Jessica types, it auto-completes from the address book. And then when you do the search, you'll find Indian restaurants near the Moscone Center.
And driving directions to boot. Maybe walking directions. So, right. So the other thing we'd like to show is the channel management view. Now, we're showing the, as noted, there's a toolbar and a channels menu, which allows you to control what's in the toolbar, what's in the channels menu. But we also provide access to all the Apple channels, so if you decide you want to use some or others, you can toss them from your toolbar and then decide later to go back and put the ones you're interested in.
Or if you'd like, you could... So let's go back to the Apple channels. So what Jessica's done is added the Japanese news channel to the toolbar. And if we decide we no longer want the Japanese news channel, we can also remove it from the toolbar just as easily.
You'll also note that at the bottom there, there's a grouping called My Channels. Now, you can actually create as many of these as you like. It's really a lot like the left column on iTunes where you can create your own music collections. Well, here you're creating collections of channels. So let's say there are particular favorites I have. I could select a number of channels. And then drag them right to my channels. And then that's provided a custom collection of the channels that I might like to use together.
And then finally, and maybe the most importantly for the folks in this audience, we've added other channels, which is really where all of your channels shine. It gives customers direct access to all the creativity that's out there. It provides a listing of the channel names as well as descriptions of each channel, which you can customize in your channel on the web.
So these channels, there are two sources for this information. One is the DMOS open source directory, which is where we get an initial listing. But also, if you're interested in making sure that your channel shows up in this list, you're welcome to submit your channel to Apple. And we'll talk a bit about the submission process a little bit later. So, thank you, Jess.
So let's go back to slides. So Sherlock is web services for the rest of us. But what are web services? Maybe web services are SOAP or .NET or WSDL or UDDI or any of a number of buzzwords, but we don't think that's what web services are. Web services are airline reservations, movie listings, yellow pages, translating things, shopping, finding things on the net. That's really what web services are to a customer.
So what we try to do is deliver web services in a way that customers would like to see them. But there are a number of challenges in doing this. One is integration of information. Information can really come from many sources. And so in order to present the user one unified view, you'd really like to integrate it from a number of different places. And you can do this in a web page.
However, the traditional method of doing this in a web page is to create frames and to have some information in one frame and another information in another frame. But what we'd like to do instead is to bring this information together in a way that not just displays the information, but really harnesses it and allows you to interact with a unified interface, rather than just seeing the information that's there.
So the other challenge is providing a user interface. And on the web, of course, you can create fairly creative user interfaces, but there are limits to it. And what users really want is a native Aqua user interface. And so what Sherlock does is provide a native user interface that users prefer in the context of a web service.
Another challenge is change. So let's say you deliver a web service as an application, but your information source changes. Maybe what you had to do in order to get certain information was to screen scrape a particular site. Well, what happens if that site changes? Your application breaks. You have to, you know, your users are now out to lunch for a while until you give them a new version of the application. So we have to be able to deal with change.
Another challenge is security. Users aren't necessarily comfortable downloading a binary application on their disk. They're very comfortable browsing web pages and following URLs because those provide a sandbox environment. So you'd really also like something that has that capability easily. You can get to it easily through a single link. You'd like to be in a sandbox environment. So, excuse me, I'm going to take a drink.
So what Sherlock Web Services provide are a native user interface. They're easy to create. They provide sandbox security. They also support changes on the web because they live on the web. The Sherlock channel doesn't reside on your disk. It resides on the web. And so when you make changes on the web, it's reflected immediately.
Additionally, they integrate multiple sources of information. So instead of just displaying bits of information from the web in one page, they allow you to actually harness that information and do computation based on it. Maybe you take a city and state and look up a zip code and then use that zip code to query another site to get some information about what theaters are available. And then you might use that theater list to query another site to find out what movies and show times are available.
And much like web pages, they are accessible by a web link. You can click a single URL and get a Sherlock channel to come up. Much like applications, you can put them in the dock. You can actually save a shortcut to a Sherlock channel, put it in your dock, and in a single click, you've opened that web service. And we've added third-party channels to Sherlock to make them much more easy to find.
So one question is when do you want to create a channel versus, say, a web page or an application? One way to think about it is that a channel is kind of somewhere in between the two. So when you want something that's more than a web page, you want more of a native user interface, but you don't want something as complex as an application or that maybe to some users may be interpreted as having some risk of downloading it, then you might want to choose a Sherlock channel. We're very, very pleased with the number of third-party channels and the creativity out there in creating channels. And I'd like to demonstrate one of the third-party channels. I'd like to invite Kevin Agren, the Senior Business Development Manager of Version Tracker.
First of all, thanks for having us out. I'm here to talk about two reasons. First one being why we chose to do a Sherlock channel. Second one being how it's going to benefit Version Tracker today and in the long haul. We know right now that we have the world's biggest Mac software database. We're tracking over 30,000 applications. But what we're seeing is that some users would rather view this offline or in a Sherlock channel versus seeing this just on the version tracker site.
Mostly what we feel is that the clean interface of Sherlock and the quick search functions versus coming to a website, especially if you're looking for multiple products, The Sherlock channel can offer you a much cleaner look, the information you want right away, and it's very accurate as well.
In the polls, what we've seen is a lot of people now are coming over and using Sherlock as a primary user interface versus going through the web. We also see that Apple put this in the doc, and so strategically as a business, to be part of Sherlock for version tracker is very important.
The channel development for us was almost as fluid as doing a web page because it's already built and it's a simple XML feed, so we're pulling content down right into it. As far as the business benefits, I'm just going to take a quick run here on the version tracker channel.
And so what you can see here is that this is today's Mac software updates. You can also easily do this by a search if you go in for Sherlock. You're going to pull up not only Apple Sherlock here, but every other application that's going to be relevant to it as well.
Search this in Sherlock. You're going to save time. You're also going to be able to look at many applications versus what's going to be found in our database. The important part as a business for Version Tracker is that we're also a media company on top of building our own software applications. A lot of our revenue comes from advertising dollars, and when users decide to click a page, they're going to come on to Version Tracker.
And we're generating impression-based ad revenue from every user that comes through here. It's amazing to us, but what we have seen now is that Version Tracker gets over 1 million searches per month through the Sherlock channel, so it's a significant part of our business. When users are in the search pages and deeper than the homepage, it's a more educated user, and advertisers right now see that this is a highly valuable position.
You've seen probably a couple hundred different advertisers come and go off the site, but our revenue comes from the long haul. Companies like CDW that are believing in the Mac user and spending money online with us definitely gives us the time, the money, and the manpower at Version Tracker to further develop our product, Version Tracker Pro.
And it also allows us to put your developer's products out in front of as many users as possible. With Sherlock being in the dock and version tracker being a channel, it's very nice for us to increase our brand awareness to all Mac users who are not already aware of version tracker.
When a developer registers with us and they post their product, we expect to get that out as quick as we can. We also expect to get that out to as many people as possible. So, when you have the application posted here, In our Sherlock channel, what you're going to see is that it's coming down the home page. On Version Tracker, it's picked up instantly in the Sherlock channel as well. So for the developer, your advantage is you're also reaching these people through our Sherlock channel that weren't on Version Tracker as well.
One other thing that we can say about Sherlock is with more OS X users coming on, more Mac users all the time, when they use this, learn about Version Tracker, we're also seeing an increase in our sales for Version Tracker Pro. And the last thing is that the strategic positioning for version tracker in here is we really feel like where the web is going is users want to interface with something like a Sherlock channel so that they can come on, make it part of their morning, they're going to get on, maybe look at their stocks, check the software applications that they care the most about. And that's really all we have to say from Version Tracker. Thank you, Kevin. Okay, go back to slides. Okay, we can go back to slides.
So now I'd like to take a survey. How many folks out there have developed a Sherlock channel already? Okay, a few. How many folks are thinking about maybe developing a Sherlock channel? Quite a few. Quite a few. Great. Okay. Well, you know, this is really a developer opportunity. As you saw, you can provide a more compelling user interface through a Sherlock channel, much more immediate, right there. You can update it on the web.
You can get to it from a web link from your website. But also, we built the channels right into Sherlock, so your user can see it either way. And it's comfortable for users. They can follow a link to get to it, or they can simply select the channel from within Sherlock. And it provides better visibility for your web services than just having a website out in the sea of millions and millions of websites.
So, if you'd like to develop a channel, we've provided a number of tools built right into Sherlock to help you do that. There's actually a debug menu in Sherlock that normally isn't visible to most users, but if you enable it, you'll see a number of tools, and we'll start to talk about those later. So the first step is, of course, to develop your channel, and that's what the bulk of this talk will be about.
Once you've done that, you can submit your channel to Apple. And the way you do that, we've got a menu item right there in the debug menu. You just choose that item with your channel up front, and you'll go right to a web page that'll allow you to submit it to Apple. And then we'll add it in. It'll be built right into Sherlock.
So let's talk a bit about how to create a Sherlock channel. And first, I want to kind of give an overview of the structure of a Sherlock channel to set the stage for understanding the components and how they all fit together. First, we'll talk about some channel design principles briefly.
Then we'll go into some detail about the key elements of a channel. We'll give a demonstration of XQuery, which is a great XML processing technology that is under development by the W3C. That we've adopted in Sherlock. And we'll talk about some of the Sherlock extensions to that technology.
So first, briefly, the channel design principles. One thing to think about is simply to focus on one topic. Searching version tracker is an example. Very specific purpose. Finding movies, very specific purpose. Another guideline is to -- it's great when your channel launches to have some information showing. You'll note in the version tracker channel, the moment the channel was opened, it showed the latest updates on version tracker. So the user didn't have to enter a query, although they could, but immediately they saw relevant information.
A third thing to consider is for performance reasons, you really want to query the web only when necessary. Obviously, on the Internet, there can be arbitrary delays. And for our modem users, it can take a long time to download significant amounts of content. So obviously, there are times when you need to query the Internet to get information. But to keep that to a minimum, cache stuff as much as possible, which Sherlock provides mechanisms to let you do.
Another guideline is to remember user state. If you go to a channel and use it to do a search, let's say for movies and a particular zip code, it's great if next time you go to that channel, it knows the zip code that you entered last time so you don't have to re-enter it. That's a basic guideline. And of course, follow the Aqua guidelines as with any application.
So now let's talk in some detail about what composes a channel and how it's made up. The key elements of the channel are shown here, the top one being the user interface, the data store below that, and then triggers and services, and we'll talk about each of those in turn.
So that's the user interface. What's shown here is the user interface for the Yellow Pages channel, but it's really tiny and hard to see, so let me zoom in a little bit. So now we're looking at the text entry field where you enter the category, say, like restaurants or the business name, and you're seeing a little bit of the results down below that.
So this is the user interface. The question is how do you make a user interface for Sherlock, if you'd like to make a Sherlock channel? And the answer is really it's the same as making it for an application. You use Interface Builder, it creates Nib files. The only difference is, although it's like an app in this respect, it's not like an app in that there's no Objective C code or C++ code or C code. And it's web resident, unlike an application.
So how do we do this? Well, we've added a palette inside Interface Builder that lets you name the UI elements in your user interface. And you'll see later how that allows us to make the channel do what it needs to do without adding a lot of code. So as an example, in the Phonebook channel, the main query field might be named Phonebook.QueryField. And it's sort of like a path where dot is used as a separator, and it can be arbitrarily deep. The results down below might be called Phonebook.Results. And it, of course, has structure within that that would be accessed by adding dot more stuff.
So then there's the data store. Now the data store is created at the time you run a channel. So it's not something you have to put in your channel, but it's created at the time you run. And it contains all the data, all the active data. It contains temporary data that you're using at the moment. It also contains persistent data. And it also reflects the data that is contained in your UI.
It's a hierarchical structure made up of arrays and dictionaries, arbitrarily deep. And it's addressed by these dotted paths that I mentioned earlier. Items in the data store can be created at any time for your own purpose, and they're created as they're referenced. Or it automatically, when your channel runs, directly reflects the contents of your UI.
So you can access any value that's in your UI by simply reading a data store path, and that will tell you what the current value is. If the user changes it, you can be notified of that change and you can respond to it. But if you read the value from that data store entry, it will always reflect the current value.
If you write to that value, it's going to change the UI. So if you decide you want to change the default on the text entry field, you simply write a new string in there and then the UI changes. It's a very powerful metaphor for quickly putting together a user interface.
The third area is triggers. This is where you make things happen. Triggers run whenever a particular element of the data store changes. And this may be an element that's tied to user interface, so if the user interface changes, the trigger runs. Or it may be an element that, say, reflects data coming in from the web. So the moment the data comes in, a trigger can run to respond to that data arriving.
A trigger can invoke services, which we'll talk about in a bit, and then perhaps perform calculations based on the results of those calls, and then change the UI. So it's really the workhorse. One way to think about triggers and the JavaScript that you write in triggers is it's very much analogous to JavaScript on a web page. You could think of the data store as being like the DOM of the web page, and the triggers as being the code that causes changes to happen in that DOM.
And last, I'd like to talk about the services. Now, these are the basic ways you get information from the web. They're implemented in XQuery, which is a powerful XML and HTML processing language. They let you query the web and say, get a web page and extract the information you need from that web page.
Or maybe you're querying a SOAP service and extracting the information you need from the XML that comes back. It's also very good at constructing XML in order to send queries and processing the results. One example is you might create a service to, given a city-state pair, query the web and get back a list of theaters that are available in that particular city and state.
By packaging it as a service, it then becomes one function call that the JavaScript trigger can call to get that information. And the details of where it has to go to get the information, how that HTML is processed, perhaps, or XML, and how to extract the results is all hidden in the service.
So I want to say a little bit about XQuery. XQuery is a new emerging language that is under development by the W3C. And if you go to W3C.org, you can see the current spec. It's really designed for processing XML. It has a relationship with XSLT, and that both share XPath underneath. So if you're familiar with those standards, XQuery would be pretty straightforward to pick up. So now I'd like to invite Jess back up to demonstrate XQuery and also the XPath Finder channel. So we go to demo one, please.
So Jess has opened the XPath Finder channel. Now this is one of the channels that you'll get in the development tools, which you can subscribe to directly from the debug menu. It's really just a Sherlock channel, but it helps you in developing Sherlock channels. So at the top there you see a text field where you enter the URL. So if we get the HTML from this website, which is apple.com, you'll see down below it displays the content of the website, and that's using a Safari WebKit view.
And up above it shows you the structure of the HTML that is being fetched from that site. So it's a column browser and you'll see HTML on the left. We go ahead and select HTML and drill down. You'll see the two things happen. One is we start to see the tags that are within that.
So we see head and body and we can click on body and go further. But you'll also see that down below as we drill down, the content rendered below also changes. So what we're doing is zooming in through the content and seeing what portion of the HTML page we're seeing. This is a much more convenient way of drilling down and finding the bit of information you want to extract than staring at HTML and trying to figure it out.
Down at the bottom, you'll see there's an XQuery path. And this is the XQuery code that is used to access what you see in the display below. So if you want to get at that particular tab, this is the XQuery code that will do it. And in fact, it's an XPath path. So let's go ahead and copy that out of the XPathfinder channel. And we'll switch over to the XQuery channel.
The XQuery channel is used for being able to execute and test out any sort of XQuery. It's a great way to learn XQuery. Try something out, hit run, and you'll see the results. So let's go ahead and paste it in the XQuery channel. And if we can zoom in so we can maybe read it a little bit better.
So you'll see there what this XPath or XQuery is doing is, it's fetching the document, it's looking at the HTML tag within it, and then going into the body tag within that, the center tag within that, the table tag within that, and the TR tag within that. And that's how we zoom in on the bit of data that we want. But in fact, this is a little bit fragile because if we change the order of what's happening in the web page, this may no longer work.
And so one of the things that we want to be able to do is to make it more robust. So the XPath channel is a great starting point to get you roughly where you want to be. But then you probably want to massage the expression a little bit to make it more robust. So, Jess, you want to... Jess Meyerson: I guess I'm taking over at this point. So I'm going to zoom you back out so that I can type and change things without making you feel ill.
And basically what I'm going to do here is I'm going to append a bit of text, which I will show you when I zoom in again, but I'm adding a path that calls our source function, and that's going to display the results of what we execute in this channel in a way that you can read.
Basically, when you execute something in XQuery, the data type that's returned by default is an XML tree, and so you need to sometimes convert that into a human-readable form if you want to play with it in the XQuery channel. So just to make this a little less fragile, you would probably want to do something like, oh, take out HTML body and center.
Add a slash in there. If you guys know about XQuery or if you take an XQuery or XPath tutorial, the double slash says, "I want all tables in this document." But then we know we want the first table, so we're just going to add in a brace that says, "Give me the first table." So let me zoom.
Well, first I'll run this, and then I'll zoom in and show you what I've done. So basically, this is giving you the same TR that we got in the XPath Finder channel. And I'll zoom in here. And you can see I've been able to remove three path elements in my command, and so that's basically three fewer things that can break if the web page you're querying changes. I think that's about it. Great. Thanks, Jess. Okay, let's go back to slides.
So as you can see, we've provided the tools to make it easy to get at the information you need to on the web and extract it for use in your channel. We've also provided some extensions to both JavaScript, which is used in triggers, and XQuery, which is used in services, to make it easier to do different kinds of HTTP requests, for example, posts and dealing with cookies and headers and those sorts of things, to deal with URL encoding and translation, and to do data matching, which is kind of the traditional Sherlock 2 way of extracting information.
So now I'd like to invite Jessica back up to go into much more detail about how to actually develop a channel that nitty-gritty. Welcome, Jess. Thank you. Hi, everybody. As Wayne said before, I'm the channel development lead, and I'm gonna talk to you about how to actually get started with developing your channels.
Please forgive me if I'm rushing through, but I'm a little short on time and I want to make sure that we have plenty of time for questions. Okay. So, what I'm going to cover today is developing channels in four steps. That's honestly all it takes. Then I'm going to cover a little of what's new for developers in Panther, and then a few advanced topics.
So what are the four steps for developing channels? You create your channel, you customize your channel, you probably have to debug your channel, and then you deploy your channel. So I'm going to talk about creating your channel first. So the steps to creating the channel all involve using Xcode, our development environment, which you've probably all received on your CDs.
And the first step that you want to take is launch Xcode and create a new project. And you'll find that in your list of choices, you can choose to create a Sherlock channel. We've provided a template for that kind of project. So choose to make one of those.
Next, you're going to be presented with a panel to save your channel project somewhere, and make sure you save it in an HTTP accessible directory. When you deploy your channel, it goes out on the web, but to be able to test your channel locally, it needs to be in either the global web server documents folder or maybe in your sites folder in your user directory. Next, make sure you turn on personal web sharing. It'll save you a lot of pain. You're going to wonder why your channel's not showing up, and it's because you forgot to turn on personal web sharing. So you do that in the Sharing Preference panel in System Preferences.
Finally, go back to Xcode and build and run your project. Basically, Sherlock's going to launch, and it's going to launch with the right environment variable set to get the debug menu. In the debug menu, you want to add your channel to Sherlock. We've realized that this is an extra step that you probably don't want to do, so in future revisions, hopefully we will automate that for you, but remember to add your channel. This will present you with a dialogue where you have to type in a little Sherlock URL, but there's one there by default, so you really only have to edit a couple of pieces of it to make sure that it's pointing to your channel's definition file.
Once you hit add, then Sherlock's going to display your channel. But it's our channel, because it's the one in the template. So this probably isn't exactly what you want. That's why you're going to customize it. So customizing your channel involves two steps. You give your channel its own identity, and then you enhance our starter code to meet your specific needs.
Giving your channel its own identity involves naming it, describing it, setting its identifier, and then giving it a beautiful icon to really attract your customers to it. Naming is pretty simple. It's done in the localized resources plist file. That's where all strings that could be displayed in multiple languages are defined in a Sherlock channel. So that you can see what that file actually contains, I've highlighted the channel name key, and then I've named my channel WWDC 2003 Example.
In that same file, you can describe your channel. That's the channel description key, and I've said this example demonstrates basic channel development tasks. What's that going to get you? Well, setting the name and setting the description is going to show up in the other channels view, in our channel management view. So you want to make sure that you describe accurately what your channel does, sell it a little bit, it'll get users to click on it.
Set its identifier. This is important not for your customers, but for Sherlock. If you've developed applications on our platform outside of Sherlock, a Cocoa app, a Carbon app, you're probably familiar with the concept of a bundle identifier, and this is basically the same thing, but for Sherlock. Here, I've set the identifier to com.apple.wwdc2003_example. So just like with bundle identifiers, a three-part string comprised of com, your company, your product name, will make it sufficiently unique that you probably won't collide with other channels.
Finally, the last bit is to give it a beautiful icon. This is really important. It puts a level of polish on your channel that users are really going to appreciate. I can't emphasize enough that giving your channel an identity that makes users want to double-click on it in the other channels' view is going to give you a larger customer base.
How can you give it a beautiful icon? Well, briefly, you can download the Aqua Icon Kit from our developer website, or you can hire a professional design agency if you're not a graphic artist. So you've given your channel an identity, but it still does what our default channel does. So enhance the starter code to meet your needs.
Back to the diagram that Wayne was using earlier, channels consist of interface, triggers, and services, at least from a developer's point of view. That's the stuff that you need to worry about customizing. First, we're going to talk about customizing the interface. As Wayne mentioned, the interface is designed with Interface Builder.
It's the same as a regular nib used in any other kind of app on our platform. What's the point of the interface? Well, you display a pretty picture to your users, but also you need to set up data in the interface to connect your triggers so that when your user interacts with your channel, something happens to execute a search out onto the web.
So here I've opened up channel.nib, which is the default nib that comes as a result of creating the Sherlock channel in the project template in Xcode. And I've clicked on the search button, and now I've gotten info about it with the project inspector, or the nib inspector, rather.
So as Wayne mentioned earlier, again, you can assign these Sherlock names or Sherlock IDs to UI elements, and this is where you do it. Choose the Sherlock item from the pop-up there, and then your main view has its own identifier, and then you can identify the button. So here I've named it Internet.SearchButton.
This is going to be useful to us in my next example. So, let's move on. Triggers are executed when a value for a data store path changes or when the data store path is notified. So, you can programmatically just sort of touch a data store path inside of a trigger and that can cause the trigger to execute, another trigger to execute. Triggers tend to use JavaScript.
Why? Because JavaScript is going to execute in a linear and more deterministic fashion than XQuery. If you're familiar with channel development at all or you've looked at any of our sample stuff, in XQuery, you can return a dictionary, right? And the keys can be data store paths and you can be setting values to those paths. But there's no guarantee that if the dictionary has, say, four items in it, they're going to return in that order. So, sometimes order is important, so it's better to use JavaScript and datastore.set.
So here's an example of a trigger, and I'm going to whiz past the screen because you probably can't read it, but triggers tend to live in a file called channel.xml. And they look something like this. So think back to that inspector where we set internet.searchbutton.action is one of the default datastore paths for NSButtons. You're going to want to check out our documentation on the web, the inside Mac-like documentation.
All of the default datastore paths for any particular kind of object are listed there, including NSButton actions. So briefly, what this trigger is doing is using DatastoreSet to set the results table to a particular -- it's setting it to null, to empty it out. It's turning on the network arrows via another default path, .animating, and then it's kicking off a search by notifying or touching another datastore path to perform the search.
Okay, services. You want to perform your search, you want to do this in a service. So that next data store path will probably execute a search service. Services are called by triggers. They encapsulate data source transactions, as Wayne was mentioning. We find that this makes it easier to maintain a channel because it's much more likely that your service is going to need periodic maintenance when the web changes. So to isolate that from your channel trigger code means that when you need to change to accommodate a change to a website, you're only changing your services file, and you don't need to upload your whole channel file again.
They tend to use XQuery because it's a great XML parsing mechanism. So again, you can't really see this, but SOAP.xml is actually a services file that we ship today, and we use it ourselves in our shipping channels. And basically this is just a definition of a function called SOAP query. It takes a few parameters. It's using the dictionary call to set up HTTP headers, and then it's doing a post with the headers and asking for the data back from that post, returning it. Pretty simple to execute a SOAP query.
So, I've gone running through how you can make your channel. You've given it an identity, you've customized it to talk to your web service and return your results to your users, and ideally, it would just work fine. But it probably doesn't. And if the web changes, as it often does, and your service changes, you might need to debug it.
Debugging in channels is a little different than debugging a Cocoa app or a Carbon app, and so you need to learn a few new tricks. First, you need to make liberal use of message and debug statements, which are sort of like printf, but message is for XQuery and debug is for JavaScript.
More importantly, I think, is liberal use of the XQuery and JavaScript channels during your channel development phase. I'll explain why in a bit. Finally, there's the enhanced debug menu, which Wayne mentioned. We've had a debug menu all along, but we've added a lot more interesting stuff to it in Panther, a lot more useful stuff for you.
First, message and debug. Again, message is used in XQuery code. Basically, this little sample is getting the HTML down from Apple's website. Then it's logging it out. If you execute message statements, you will find that they -- if you're running Sherlock from within Project Builder, or rather Xcode, as we are in this example, you'll find these message statements in its console.
But if you're just running Sherlock standalone without Xcode, you're going to want to look in console app for these messages. So it's logging out the HTML from the site and then continuing along and returning what it wanted to return from the service. Similarly, you can use debug. I've basically done the same thing here, just making use of the XML query JavaScript object and calling document, getting the data, debugging it out to the console, and returning it.
More importantly, though, as I said, XQuery and JavaScript channels. You didn't see the JavaScript channel earlier, but it's the same concept as the XQuery channel, which we did demonstrate. Why do you want to use these? You really want to unit test blocks of code as you're developing your channel, so that when you paste it into your channel file, you just know it works. A caveat, though.
In your channel file, because it's an XML file, you need to escape special characters. So, you know, a less than symbol would have to be ampersand LT colon to work in your channel file. To work in the XQuery channel, you don't want to escape it. It's not an XML file. So you just need to sort of global search and replace ampersand LT for a real less than sign. Make sure you do that.
So, a little picture of what these do. Here I've got an XQuery channel picture up there. I'm getting, again, the data from Apple.com. I've got a little XQuery executing to grab all the image tags, and then I'm asking for their source attributes. And when you hit run, all the source attributes get put out in the results area. Similarly, the JavaScript channel. I couldn't really think of a good example, so I'm just checking that 5 plus 16 still equals 21. And in fact, it did.
Finally, the debug menu. So the way you turn it on, although someone's edited my slide to capitalize D, and you don't want to do that, you want to turn it on with a defaults command, which is executed in terminal, defaults, write, com.apple.sherlock, Sherlock debug, 1. The next time you launch Sherlock, it's going to come up with the debug menu.
And there are a number of things we've added. You can turn on and off different levels of logging. You can turn off HTTP caching, which is pretty excellent as you're developing a channel, because you're making changes all the time. So you'd rather just have the fresh copy right away, as soon as you've made a change. You can look at the data store and also tickle the data store. You can change its values or notify things. You can look at your NSVU hierarchy. All kinds of good stuff in there.
All right, so hopefully now you've got the tools to debug your channel and you're ready to deploy it. So there are a few things to think about when you're deploying. First is, do you want to use subscriptions and checkpoints? Once you've decided all that, you've got to figure out how to FTP your files to the web server of your choice, and then you just submit your channel to Apple, and it shows up in our other channels view.
This is kind of a wordy slide, and I'm going to gloss over it. Subscriptions and checkpoints. So the subscription file lists channels you're deploying. It's useful when you ship multiple channels like Apple does. So we use subscriptions for, for instance, our Apple channels, our other channels, which are the third-party channels, our channel development tools, all of those things that show up in the left-hand column of the channel management view.
They will increase your channel's visibility if you choose to use a subscription for that very reason, that they'll show up as a separate folder or collection on that left-hand side of the channel management view. And they're also very convenient for your user, because if you're shipping multiple channels, if you want to deploy them one by one, the user has to click on a URL each time to add a channel, one at a time. So just ship them all at once in a subscription, and they just have to add the subscription, they're done.
Why else are they useful? Well, subscriptions allow you to control who sees your channels. In a subscription file, you can require specific Sherlock versions or require a specific geographic region, for instance. Okay, now that you've decided to use a subscription file, perhaps, you need to wonder as to whether you want to use checkpoints.
What are checkpoints? Basically, you can designate certain files in your channel hierarchy as a checkpoint, and it helps Sherlock to know what's changed. So if you change the mod date on your web server, once you've deployed, of a file that is a checkpoint, Sherlock's going to know that it should take a look at everything below that and possibly update it.
All right, so you're using a subscription or you're not, you're using checkpoints or you're not. Either way, you're FTPing your files to a public web server. You could deploy on your company's web server, you could deploy on .Mac if you've got a .Mac account, you could deploy on any HTTP server.
If you're using a channel for internal purposes at your company, you can deploy on something like that. But if the channel is external, make sure you submit your channel to Apple. We can't stress enough how much this is going to raise your channel's visibility. So in that debug menu, use the Submit Channel menu item, and your channel will appear in the other channels collection.
So hopefully, I should note at this point actually that the reason I'm glossing over the details of some of these things, like how do you create a subscription file and what does a checkpoint look like, it's because it is actually pretty well covered in our documentation. And so if you take a look at the inside Mac-like documentation out on developer.apple.com, also you want to take a look definitely at the release notes on your CDs that you got in developer documentation release notes because we took great care to update them with all the new information, which is what I'm going to talk about right now.
So what's new for Sherlock Channel developers in Panther? We've got some user interface enhancements. We've got inter-application communication abilities that weren't there before. We've added some support for Address Book. We've added per-channel help support for Help Viewer. And we've added some versioning capabilities so that you can adopt all of these things safely.
First off, the interface enhancements. In NS Table View, we've changed it so that you can turn on type selection in columns or in entire tables. You have more control over whether users can delete rows or not. You can set the scroll position of the table. You can have check boxes in table cells. And table sorting can be done for you automatically.
We've changed the NS Combo box, too. There, we've changed it so that you can turn on text selection on first mouse down, or you can turn that off. And you have just generally greater control over the list behavior. The HTML view, of course, is now using the fabulous WebKit, and that's going to add a lot of capabilities if you want to display more complicated HTML.
You can set the default car set. So let's say you've narrowed down a chunk of HTML in one of your services, and in so doing, you've managed to strip out the car set tag. You can just tell the web view that every time you're displaying HTML, the default car set should be whatever.
Finally, you can turn on browsing within Sherlock. So links will be followed within your HTML view versus if the user clicks on a link now in Jaguar, rather. If they click on a link, it will definitely be sent out to the default handler for HTTP URLs. So you can actually just browse within Sherlock now because the WebKit is powerful enough to handle that.
Inter-application Communication. So, Sherlock is a playground, and that makes it safe for users, and we think it's pretty easy to develop for, but it's not the only app out there. So, maybe your channel wants to talk with other applications. We've enabled this by using special URLs. So, there are address book URLs, iCal and WebCal URLs to talk to iCal, and help URLs so that you can open Help Viewer from within your channel.
The way you would use these URLs is you create one in your channel source, and then you send it to the JavaScript system object with the open URL command. And if the URL's in there, the system object will decide what the proper handler for that scheme is via Launch Services, and the right application will be opened.
Address Book Support. So, as you saw in the phonebook channel, we've got combo boxes that do all kinds of neat completion. They complete city-states, they complete on titles in the user's address book, they'll even complete, you didn't see this, but they will complete on addresses in the user's address book.
So, that's done in the Sherlock address combo box. We've packaged it up so that you can just drag it in Interface Builder, drag a combo box in, change the custom type to Sherlock address combo box, and you've got the same functionality we have in the phonebook channel. Also, there's a JavaScript address book object, and through that object, you can add things to the user's address book, and you can search the user's address book.
Per-channel help. It's really good user experience. It's basic Aqua savvy to provide help for your software and to do so in Help Viewer. And so we've enabled that in Panther. Basically, you tell us where your help file is, and we take care of the rest. We add an item to the help menu that points to your channel's help.
We open it when the user chooses that item. You're going to want to take advantage of versioning if you take advantage of any of these new functionality, of any of this new functionality, though. If you're familiar with the concept of Gestalts or anything like that, you can check to see that something is there before you use it or you can check to see that Sherlock itself is a particular version before you use something and that's done by checking for the existence of new JavaScript objects.
You can call channel version from X query and that will give you back the version of Sherlock and you can use version or max version attributes on triggers or services or subscriptions and again, this is all covered in the documentation so I won't go into the exact details.
Very briefly, because I know I'm running out of time, advanced topics, three of them, the most important in my opinion. Localized resources, printing, and performance tips. If you take advantage of any of these three advanced things, you're going to provide your user with a much better user experience.
Localized resources. So, not everybody in the world speaks the language that you're developing your channel in. And if you have the ability to localize your channel into other languages, Sherlock will let you do that. Basically, you set a localized base URL, which tells Sherlock where to look for your localized resources.
And then you can access localized resources from your code as well. So, if you're setting a string dynamically, so let's say you're setting a label from within a trigger with a datastore.set to the label's path, you would call localized resource, get the right string, and then set it. You can also call localized URL to get a URL that points into the right Elproj directory.
Printing - channels can be kind of complex. There's a lot of information in there, particularly because you're aggregating information from multiple websites or you're trying to do better than a web page could do, and so you're showing a lot of stuff. I mean, let's look at the phone book channel. We've got tables of results. We've got driving directions. We've got a big map.
Sometimes that looks great in Sherlock, but it doesn't look great when you print it out on an 8 1/2 by 11 piece of paper, and so I can't help but stress that if you print it out and it doesn't look too good, your user is really not going to appreciate that. Create a custom print view. You just add a new view to your nib.
You reorganize your UI elements so that it will look good for 8 1/2 by 11, and then if you do that, be sure to set your channel's main view identifier data store path so that as Sherlock loads your channel, it knows that one view is actually the view to show in Sherlock and the other view is your print view.
Performance tips: Nobody likes to use a channel that's slow, and we've been working to make ours faster, and I want to share with you a little bit of what we've learned about that. Avoid initialize bloat. Initialize is a special chunk of code that all executes before your channel shows up. There's a lot of stuff that we were doing in initialize that did not have to be done before the channel appeared. If you are doing stuff that doesn't have to be done in initialize, move it to a later trigger.
Execute any given XPath only once. So let's take a little example. Let's say I download some HTML with the document command and it's in a variable, $HTML. And I wanna get all the anchors in that HTML and then I'm gonna need all of the anchors, Ahrefs, and all of the text for those anchors.
Well, I could say $HTML/A/text, and then $HTML/A/@href. But since I'm doing //a twice, and that might be expensive, why don't I save that in a variable? Next, favor cache update for infrequently changed resources. We've made use of this ourselves, and basically it's a flag that you can set on an HTTP request.
And if you know a resource out on the web isn't going to change very often, there's an image out there that's pretty static, if you set that flag, you're able to get the image from the cache first, and then Sherlock will go check to see if it's changed and pull it down in the background. So the next time you access it, you'll have the new thing in the cache.
Stream return data into the view as it becomes available. Examples of where we do this are the pictures channel and the internet channel. If you have some info first and you're waiting for others, don't make your user wait. Splat it out into the view and wait for your stuff, and then splat the next stuff out.
Finally, show cache data first and then refresh. Wayne mentioned this as a tactic for having a good channel user interface. We do this in the movies channel. If you do a movie search and we get your list of theaters and movies, we'll show that to the user again the next time they launch and then update it in the background. So I'm going to invite Wayne back up for a wrap-up for our session.
Thank you, Jess. So in summary, Sherlock allows you to deliver web services today. You can create them quickly. They're updatable on the web. They provide a native Aqua UI, much like an application. But you can link to them directly from the web or launch them from the dock. And in Panther, they're built right into Sherlock.
So for a roadmap, now of course all of these sessions have already happened, but for those of you watching on DVD, or if you'd like to get the DVDs, The Internet Technology Safari Overview provides a high-level overview of the technologies used by Safari and, of course, by Sherlock as well.
The WebKit and the Foundation URL APIs. If you'd like to add help to your channel, then you might be interested in session 408 for the Apple Help updates and how-tos. The next one there is more about Safari and web standards, which again is interesting for HTML views and such.
And then the session, Internet Application Development: The New Frontier, is an environment provided by Macromedia that aims to provide Internet applications that may also be of interest if you're doing a lot of graphics like you would in a Flash kind of context. And of course, our friend John is the guy to contact if you'd like to ask for features or any sort of thing like that.
And for more information, there's the Sherlock Developer web page, which is very easy to get to: developer.apple.com/macos10/sherlock. It has all the information you need there. There's a mailing list if you'd like to ask questions. If you're in the midst of channel development and you run into a problem you're not sure how to deal with, please ask on the mailing list. We're more than happy to answer questions there, or other developers will also chime in and answer.
Inside Mac OS X Sherlock Channels is the documentation for how to create Sherlock Channels, and that's up at the developer website. And it's also on your disk. And then of course the release notes will tell you specifically new features that have been added in various releases along the way, including Panther.
If you'd like to learn more about the JavaScript language, there are lots and lots of references out there. The sort of main standard reference is out on the ECMA site, and there's the URL there. But of course, there are many books out on JavaScript. XQuery is much newer, of course, and it's not yet a final standard. And so there really aren't as many references out there. But the main reference is at the W3C site. And this is both the language and then the functions it provides.