Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2006-115
$eventId
ID of event: wwdc2006
$eventContentId
ID of session without event part: 115
$eventShortId
Shortened ID of event: wwdc06
$year
Year of session: 2006
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC06 • Session 115

Publish & Subscribe with RSS

Application Technologies • 47:14

Take advantage of the PubSub framework to easily add sharing and casting features to your application in Leopard. The PubSub framework provides high-level access to the power of RSS and Atom so developers can easily add support for these internet standards without having to be XML or http experts. Let the PubSub framework deal with the complexities of evolving syndication standards and networking so that you can concentrate on creating great sharing opportunities for your users.

Speakers: Ricci Adams, Jens Alfke

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good afternoon. My name is Ricci Adams. I'm an engineer on Apple's social software team and this is session 115, Publish & Subscribe with RSS. Now, as you may have guessed from the title, we're going to be talking about RSS today. And there's three things I'm going to tell you. First, I'm going to give you a brief overview of what RSS is.

And then I'm going to tell you some of the pitfalls that you may run into when trying to implement RSS in your software. And finally, I'm going to tell you about some of the great new technology we have in Mac OS X Leopard that's going to make your lives easier.

So first the overview. You're probably all familiar with blogging. It's one of the hot new phenomenons on the web. And so how it works is there's a web application. Now this could be a web application that you've installed, something like MovableType or WordPress. Or it could be a service you're subscribed to like Vox.com or TypePad or Blogger.

And how this works is you log into the service and you write a post. Say a post about attending WWDC. And then when you hit the submit button, that web application is going to generate an HTML resource which your readers can then browse to using Safari or another web browser and read.

How this works is you log into the service and you write a post, say a post about attending WWDC. And then when you hit the submit button, that web application is going to generate an HTML resource which your readers can then browse to using Safari or another web browser and read.

So instead of this, the web application will also publish an XML resource in the RSS or other formats and then it becomes much, much easier to read. And so you have applications, Apple applications for example, like Safari RSS, the new Mail RSS or Quartz Composer, and there's also your applications such as NetNewsWire or Mac Reporter that can read this XML file and display it however you want.

So you're probably here today because you're interested in using RSS in your application. And you know what? That's great. But there's three things you need to know. First, you're going to have to know and you're going to have to parse the feed. And then you're going to have to interpret the contents of each entry.

And finally, you're going to have to difference the feeds over time in order to see what's new and what's been updated. So let's talk about parsing. You know, we use the term "RSS" as a generalized term to mean web feeds. But there's actually four formats that you have to be concerned with.

There's RSS 0.9, RSS 1.0, RSS 2.0, and Atom. And if you want your application to be able to read a good number of web feeds out on the web, you're going to have to support all four of these applications. So that might be a little bit more work than you thought, but it's still not bad. But there's more. Because in addition to these four formats, a bunch of the time, you're going to encounter invalid XML. Sometimes a feed might be missing an ending element, or there could be an entity that's not part of the XML spec.

And since everybody can use HTML in their feed post, you're going to also encounter invalid HTML. So you have to worry about that, too. Well, So you've actually got the feed now. You've been able to figure out what part of the file pertains to different entries. But you actually have to interpret those entries. Let's say the author of a web feed wanted to use an ampersand in his feed's body.

Well, you know, there are six different ways to represent that ampersand. Sometimes your XML parser can handle this for you. Other times you're going to have to make a hard choice. Do you want to singly escape the entry? Do you want to doubly escape it? It's a tough call to make.

There's also differencing. You see, the RSS protocol isn't really dynamic. You can't say, "Hey, feed server, can you send me all the feeds since last Sunday?" It doesn't work like that. In the RSS file, there's only a list of the last entries. And so what you have to do is every single time you download that file, you have to store what you've downloaded.

The next time you download it, you have to take the new version and you have to compare it to the old version. And this would be simple if every entry had a unique identifier. Unfortunately, that's not the case. They're not guaranteed to have those. And so really, it becomes quite hard.

In fact, trying to do all of this is kind of a giant hoop that you have to jump through when in the first place you just wanted to be able to read a feed. So wouldn't it be nice if there was a framework in the system that would do all this for you? Thank you. Today I'm proud to announce that there is.

It's going to be shipping to your customers in Leopard and it's available as a preview on your developer DVD. The name of the framework is PubSub and we're going to be talking about it for the remainder of the session. So first let's talk about the features of the new PubSub framework.

Well as you can probably gather from the name, it both publishes and it subscribes. So we're going to be talking a bit more about the publication part in a bit. For now let's focus on subscriptions. What can it subscribe to? What can it parse? Well, all four of those things I mentioned previously.

It's going to be able to handle RSS 0.9 feeds, RSS 1.0 feeds, 2.0, and Atom. And it's even going to be able to handle malformed feeds. So you just point it at a feed, it parses it, and it's going to take this and pull it down into a common data model, which you can then access using Objective-C classes and methods.

And it's not just restricted to the attributes defined in the RSS and Atom spec because we're also going to provide support for XML extension elements. And what this means is there's a bunch of extensions right now that you could find in RSS feeds. For example, iTunes has a podcasting extension. There's the Yahoo Media extensions. FeedBurner.com has their own set of extensions.

And we're not going to throw this data away. We're going to provide a way for you to get at it. So those are some of the main features. Let's talk about the architecture of PubSub. And I'm going to explain this from the perspective of a user who wants to subscribe to a web feed, say Slashdot, in mail.

So we have MailRSS, we have SafariRSS, and hopefully your application. Hopefully you pay a little bit more for a graphic designer than just this. And they all link against the PubSub framework. Now there's also a fourth application on the system, and that's the PubSub agent. And so when the user goes to subscribe to Slashdot, through the PubSub framework, Mail's going to send an IPC message to the agent. And the agent's going to be responsible for all network I.O.

So the agent then goes out to the web, grabs the feed, parses the feed, and stores that in a database. Next, the agent is going to send a notification to all clients of PubSub saying, "Hey, I have this new feed, slash dot." Mail's going to then pick up on that and say, oh, my feed's been parsed. It's now in the database. Let me grab that.

And then it grabs it from the database and you can display it how you want. So the advantage of this architecture is all the data is shared. So if you've subscribed to the same feed in both MailRSS and SafariRSS, and say you go to do a manual download in Safari and there's five new entries, those entries are going to appear at the same time in Safari or Mail or at the same time in Safari in your application. And the other advantage is that we're only downloading the feed once, so it reduces network traffic.

So now that I've talked about the architecture, we've made a few cool demos that we want to show you now. And I'd like to introduce my coworker, Jens Alfke, who's going to come up on stage and present those to you. Jens? Okay, let's see, we need demo machine C. We have our magic switch ready.

We're on the correct machine there. We're live. OK, hi. So I've got two applications to show right now, two simple little apps. And the first one of these is already on your developer CD in the developer examples PubSub folder. It's what else but a very simple news reader, the obvious thing to build with this framework.

So it's got a pretty typical layout. On the left here, you see there's a list of the feeds that have been subscribed to. We can click on a feed and see the articles here. We're seeing the entry titles, the dates, the authors, if they had authors, and the read and unread state. We can click on any entry in here and see the contents down below.

There's not a whole lot more to it than that. The other application Does a little bit more. So we want to give you the idea that this is not just about building yet another newsreader because we have a whole lot of newsreaders on the OS already. We have some really good ones. Both Apple and other developers have written really good ones. So what's more interesting is to take this kind of content that you can get now really easily from the web and do interesting stuff with it.

So as an example, one of these feeds I've subscribed to here is this iTunes new releases feed. So we can look at these and see little pictures of the album covers and what the artist name is and so on. And we can kind of scroll through the list and see stuff.

But as an example, I built an application that specialized for viewing this feed, both the iTunes new music feed and the eMusic, which is another music store feed. So it accesses the same data. In fact, it's the same data that I'm using. So it's the same records in the database that the other application is showing. But this one does a number of interesting things with it.

First of all, this is a core data application and does all the kind of fun core data things like filtering things down using filter view or sorting in different directions. So it's got its own persistent data store based on core data, but this integrates really easily with the persistent data store from the Pub/Sub framework. And synchronizing between the two is really easy. So as new information arrives from the web and goes into the Pub/Sub framework, this application gets notified, grabs those entries and adds corresponding entries to its own core data database.

And its database is based on the kind of metadata that you would expect for albums. So it's based on the artist name, the album name, the genre. And so we can do all kinds of interesting filtering on the Pub/Sub framework. So we can filter by artist name, we can filter by genre, so we can just get-- If we had any tech note, nope. All alternative, et cetera.

And the way that it does this is by looking at the additional XML elements that are in the feed. The iTunes music store feed, in addition to having the human readable HTML content that shows you the artist and picture and so on, it also has some invisible XML elements there in the entries which this application goes and tweezers out and uses those to put into its database.

So its database is keyed off of things like artist name. It also grabs data like the music clip. So we have a nice UI in here so it can-- if we had audio, you can just listen to little clips of the album right here in the browser itself. And that's it.

Can we switch back to the slides please? Oh. Can we switch back to the slides? Thank you. Thank you, Jens, for that fine demo. So now that you've seen the NewsReader application that we built, I'm going to talk about how we built that. So you see here a screenshot of the NewsReader application. And the first thing that you need to know is to use PubSub, you're going to need a PS client.

And PS Client is going to be an instance that is tied to your bundle's identifier. So PS Client, you'll use that to subscribe to feeds, to unsubscribe to feeds. And speaking of feeds, each one of those is represented by a PS Feed object. So using the PS Feed object, you can get the feed's title, you can get the last time it was updated, and more importantly, you can get a list of its entries, which we use PS Entry for that. So PS Client, PS Feed, and PS Entry. Let's look at a code example that uses these three. So first you need to get your PS Client.

And you make a call into PSClient application client and that's a convenience method that's going to return you your PSClient that's key to your application's bundle identifier. Once you have that, you can subscribe to a feed. So we'll use NSURL, URL with string, get an NSURL and then tell the client, "Hey, I want to add a feed with this URL." It'll return to you a PS feed. So now you can do stuff with that PS feed like get its title. You can also get its entries. Like the below example, get its entries, get an enumerator, enumerate over them, and then get the title of each entry.

So going back to the demo application, in the bottom right-hand corner, you saw the actual content of each entry. And in our API, we use PSContent to represent this. Well, you might ask, Why not use an NSString? Why use a separate object? Well, the answer is that in the RSS and Atom formats, content can either be plain text or it can be HTML.

So here's an Atom example, content type text, "Hi mom and dad." Now, the author of this feed is intending for this to be displayed as plain text. You can also say content type HTML and then of course you'd have to doubly escape your entities, "Hi mom and dad." But the thing is, you don't need to worry about this because PS content is going to do it for you. We have a plain text string accessor, we have an HTML string accessor, and whatever you want, we're just going to handle that conversion on the fly.

So, for a code example, Let's take one of the PS entries and let's take its summary and put it into a text field. Let's take its content and put it into a web view. So here we have a PS feed and a PS entry and we've gotten those previously.

Now we're going to get the summary. So we call the summary method on psEntry that returns us a psContent. Now we can call plaintext string on that. And now we have a plain text NSString so we can shove it into an NS text field. Next we want to get the actual content, which will probably be in HTML, and put it into a web view.

So here you see how we're doing that. We say entry content, that returns us the PS content. Call HTML string now and then we can just put that into a web view. And again, it doesn't matter what was in the original feed. If it originally was in plain text and you want it to be in HTML, we'll handle it for you.

So in addition to PS content, there's two more classes I'm going to discuss. We're going to talk about authors now. So in the RSS and Atom formats, there's a wide range of how you can display author information. So the top example is the easiest case. Author John Doe, just the author's name. The next example has both the author's name and the author's email address.

And the final example is from Atom and you can see the Atom specification breaks it out into three. So there's the author's name, the author's email address, and the author's homepage. So instead of just providing this to you as an NSString and making you parse out the bit you want, we're going to use the PS Author class, which has a name accessor, an email accessor, and a URL accessor. In addition, we're going to provide the capability to link PS Authors to AB person objects from Address Book Framework.

Today we're going to discuss enclosures. And you might not exactly know what an enclosure is, but if you've ever used a podcast or listened to one, or if you've ever viewed a photo cast, you are actually using enclosures. So you have your RSS resource on the web server.

And in addition to this, in the case of a podcast, you're also going to have MP3 files or AAC files for each one of your episodes. And if you look in that RSS file, You're going to see something like the following: rel type enclosure, the size of the enclosure in bytes, the mime type, and an actual link to that.

And so let's say you're trying to build a podcasting application with our framework. Well, you're going to use the psEnclosure class. And as you can see there, we have URL, we have the size in bytes, and we have its mime type that you can get at. So these are our six classes. In summary, let's go over them again.

We have PS Client, which you'll use to add subscriptions and remove subscriptions. PS Client has an array of PS Feeds, which represent the feeds you're subscribed to. And then PS Feeds have PS entries. There's also PS Author for dealing with author information, PS Content for the content, and PS Enclosure for enclosures. And that is the subscription API of PubSub. Next up is Jens, who's going to discuss the publication side.

Okay, I have the clicker. So we don't just let you subscribe to RSS feeds, we let you actually publish feeds. And this is a little kind of broader, more bleeding edge, vaguer, so I'm going to approach this.

[Transcript missing]

I'm going to answer a couple of questions. First, you might be asking why.

Why would I want to publish stuff? What's this going to do for me? Then, assuming you accept that, well, how? How do I use the API? What's the architecture like? Then, where can I publish stuff to? What kind of servers, what kind of protocols are we talking about? And last, I'm going to talk a little bit about who, by which I mean access control. As we'll see, some of the information that you want to publish may not be world readable. You may not want everyone to be able to see your address book that you're publishing or something like that.

So first, why? First reason is kind of the obvious one, personal publishing. And blogging is kind of the obvious example of that. And there's the famous quote, freedom of the press is limited to those who own one. And at least in many countries now, that means pretty much anybody because you can go and set up your own free blog at any number of different sites and start publishing your own important commentary to the world.

So you could publish anything. Blogging, podcasting, of course. You can actually have audio data or music that you can publish. Photocasting, like iPhoto does. Flickr also has feeds like that. Video casting. There are, in fact, podcasts now that include video content that you can watch on your iPod or on your computer. And next year, I'm sure they'll be announcing smell-o-casting. Be afraid.

So beyond blogging or all of these things which are kind of one-to-many, like I am taking this content and putting it out in public for the world to see, there are some more applications for this that are more two-way, they're more collaborative. In the future, everyone will be famous for 15 people. These 15 people, this mutual admiration society, may well want to be able to publish things to each other, share information.

So small group, many-to-many content publishing. This is not probably the way that we're going to have many thousands of people mailing lists working, but you can do some really interesting stuff with this. There are two different approaches. There's sort of a centralized and a decentralized way of doing it. First one, we have a shared read/write store.

And in our diagram, we've got a couple clients that want to be exchanging data with each other. In the middle, we have an Atom store, by which I mean a server that is using the Atom publishing protocol for publishing information. And each of the clients makes a connection to that server and is publishing information.

And they can actually be publishing data to the same feed, and they're also simultaneously subscribed to that feed. So each of them is seeing the things that the other people are doing, as well as the things that they put in. Other people can modify data that one person has put in.

So this is nice if you happen to have an Atom store and most of the blogging services now support the Atom API. We happen to be supporting it in Leopard server, but you may not always have that available. So the decentralized approach is done, one approach that's being looked up by a lot of people is cross-subscribed feeds where again we have three clients.

But we don't have a shared server. Instead, each client is sort of one way or another publishing a feed. And they might be publishing it with personal web sharing. They might happen to have a spare web server somewhere that they can go and toss up the XML data to-- something like that.

So each client then is publishing their own information into this feed that they own. And then each client is subscribed to all of the other clients' feeds. So in effect, we get the same behaviors in the first case, where the data that each client publishes becomes visible to the other clients as well.

This obviously is not going to scale terribly well because it has this N squared problem. But for small groups and especially on local networks where you know that the group size is not too big, the bandwidth is really high, the latency is low, this is actually pretty attractive.

So reason number three for doing publishing is data flow. And there's a good quote from this by one of the architects of the internet, by which I mean, of course, Ted Stevens of Alaska. "The internet is a series of tubes." A brilliant metaphor. So use a different metaphor.

Web 2.0, a lot of this whole hype is about using websites as applications, not as this individual, isolated thing that you go to in your browser, but an application that can do stuff for you. And that has APIs so that other applications, whether local or remote, can access that data and do stuff with it. So these APIs were, of course, in their infrastructure using HTTP as the function call mechanism.

And fundamental operators in HTTP are POST for creating a new piece of information, GET for retrieving that information, PUT for replacing an existing piece of information's content, and DELETE for making something go away. In particular, this way of looking at it has become widely known as the REST architectural style.

So if we have these applications up on the web with APIs, you can sort of look at a feed as a data pipe, a tube that you can set up from one point to another point or from one point to many different points. And the entries are these little cylinders with stuff inside that go shooting through these tubes. And so you can use this as a wiring model for connecting different servers, different sites, different applications together.

There are several startups that have been exploring this space. RSS Bus is explicitly doing it with RSS feeds, which is pretty interesting. KnowNow is another company that's been doing this for a couple of years, and they've been doing some really interesting work with how to do this in a real-time or near-real-time way.

And then IBM has actually been doing a lot of interesting stuff with this. They have a good quote. "An enterprise service bus is a pattern of middleware that unifies and connects services, applications, and resources within a business." The Service Bus is a pattern of middleware that unifies and connects services, applications, and resources.

If you think about all these different services that you might use, whether on your machine, on local machines, on the internet, websites like Flickr, blogs, all this kind of stuff, you can think about ways of plugging things together, of passing things on to other people, of using them in different ways. You can think about passing data from one to another using feeds by having these entities both publishing and subscribing information.

So after all this hand waving, let's have an actual demo, show you some real stuff. Ricci and I put this demo together a couple of months ago to impress some executives. We didn't want to do something with just text because that's kind of boring and so we thought, okay, iPhones, done photos already, but what if we made Photo Booth do casting? So we have Booth casting.

[Transcript missing]

And just like normal photo booth, we can take pictures with it. All the interest of science. Okay.

Now, when I look at this picture, there's a new button here called Boothcast. So I can actually mark this picture to be published. And now I can run this PhotoWatcher application So I'm subscribed to my own machine here, so my picture just showed up down here. But I'm also subscribed to Ricci's machine.

In fact, I can go here and look. This is using Bonjour to show me all of the other clients on the local network that are running booth casting. So if Ricci now takes a picture. I have a slight issue here. Oh, technical difficulties. Don't tell the audience. Just work around it. OK, I'll distract them by taking another picture myself. So let's pick a different effect. Glow, I like glow. Looks good on you.

Plank. And over in the photo watcher, if all goes according to plan, It will drop into place, right? Oh, yeah. You need to publish. Duh. See, it's a privacy control. This is a feature. You don't want these dorky pictures getting published unless you actually tell it that you want to publish them. It's not a bug.

So now that I'm sharing it, it shows up. OK, so that could all be smoke and mirrors. It's on the same machine. So if-- So go ahead and show them the RSS feed. Yeah, OK. So the way this works is, like this being the RSS session, we're actually publishing this as a feed. And I can view this just in Safari RSS.

You got pictures here? Just click on the photos and you can get each one. Oh, right, because they're enclosures. So it's just a regular feed. We're using the Atom enclosure element. To point to the pictures which are also being served, it's the same Apache server that's used for personal web sharing.

And so we subscribe to the feeds from the other machines in this PhotoWatcher application. And when a new item appears, we download the picture for it and it shows up in the window. Since we're using Bonjour, we can actually, in addition to just broadcasting the fact that we're running this application, it can also broadcast the modification date of the feed.

And that is propagated pretty much in real time, within a couple of seconds. So when a picture is published by anybody else out on the network, this application will detect that there's a new picture, fetch the new feed, and display it in a couple of seconds. So unfortunately I thought I was going to get to display some fine photos for you. A slight issue here with the video camera, so Jens, back to you. Oh well. So back to the slides please.

Okay, down to how. Let's look at how this actually works. The good news is that the publishing API is pretty simple. It's really just like subscribing, just in reverse. So I'll take an example. The user of your application has just typed in an incredibly important blog post, and they want to get it published. So you will grab this text out of the text view, and you wrap it up in a PSContent object. The same class that Ricci was telling you about, just now you're actually creating one from nowhere and stuffing the text into it.

The PSContent then goes into a new PSPublishedEntry. PSPublishedEntry is a subclass of PSEntry. You can think of it as being the mutable subclass, sort of like NSMutableArray. So you can create one of these, and then you can actually start putting content into it, setting all the metadata, the title, et cetera, et cetera. The entry you then put into a PSPublished feed. Again, this is a subclass of PSFeed where you specify where to put the data, where it gets uploaded to, what the title of the feed is, et cetera.

But you might not just have text. Finally, all the stuff now goes into the PubSub database, the persistent store that we have. But you might not just be publishing text. If this is a podcast, then you might have this audio file sitting out here. Simple. You just take the audio file, you create a PS enclosure object, point it at the file, and then add that to the entry.

Similarly, if you have some kind of custom XML data, it might be like metadata using the Dublin Core namespace or some kind of custom namespace that you made up or something like iTunes data, you just take that XML and add it to the PS Published entry using another accessor.

Finally, when you're all done, when the feed's been assembled, the entry's been added, and the user goes and hits that Publish button, The agent kicks off, reads the feed out of the database, and then sends it off to the world. We have a couple of different mechanisms here for publishing, different protocols.

First, we can directly assemble the feed as XML data and upload it to pretty much any web server. We can use either the FTP protocol or the WebDAV protocol, for example, for iDisk-type servers. We can also upload it similarly to .mac in much the same way that iPhoto uploads feeds for photocasting. And we can use the Atom publication protocol, which is sort of the cousin of the Atom syndication format. It's a protocol that the same working group is developing for uploading entries, feeds. And that's supported by pretty much all of the major blogging and content management systems.

And lastly, as demoed with the boothcasting demo, we can use Bonjour to advertise the feed and the Apache server that's already on your machine to serve that feed to machines on your local network, or even beyond if you have a static IP address and the other machines that subscribe know what your address is. Let's look at an example of the code for doing this. I'm going to go through pretty much the same example that I showed you in box form. Just this time we're going to have some nice comforting monos-based font for it.

So first we're going to create some content. We have some data that we pull out of our NSTextView. We create a PSContent object. We init it with the data. And we give it MIME type text HTML. Now we create an entry. We just initialize a PSPublished entry, give it a title, and pass the content in.

We create the published feed. Just init the published feed. The protocol here, we have a couple of constants that you can use to indicate which publishing protocol, which of those nice icons in the previous slide that you want to use. There is a server information dictionary that you pass in which has key value pairs that indicate protocol-specific information like the URL of the server or the account name that you're using for login, things like that. And you can also pass in an identifier. This is the GUID, the universal ID that your feed will acquire. Usually you pass in nil and we'll make up a unique ID for you.

Then finally, you take that feed and you add your entry to it. To publish that stuff out to the world, you just call publish on the feed. That's it. That takes the content from the local database and uploads it to the server. This is an asynchronous operation, so since obviously it's a network transfer, it might take a while. You might not actually be online at the moment. The server might be down. So you can use notifications to find out when the information actually gets published.

But after you publish an entry, that's not really the end of the story. So your UI will probably want to show the user a list of the entries that they previously published. How do you do that? Well, it's pretty easy. Since PSPublishedFeed is a subclass of PSFeed, that means you get all the same accessors that you had on PSFeed. So you can call entries. You can get the entire list of entries. You can get entry with ID.

So if you create an entry and you grab the entry's ID accessor and store that away, which is what the core data album browser example that I showed you does, the ID is just a short string. And if you remember that ID, you can go back later any time. It's persistent. So you can come back any time in the future and ask the feed for the entry with that ID and get it back.

So in particular to update an entry, if the user finds a typo, they go back, select the entry, edit the text, hit Save. First you get the entry back from the feed by calling feed entryWithIdentifier and the enter ID that you have. Now you can call setTitle, setContent, setEnclosures.

There's a bunch of accessors here that you can use to update all the information in that entry. And then when you're done, you just say feed publish. And the feed will go and upload either the entire feed or just that one entry to the server, depending on what protocol you're using.

Similarly, you might want to remove an entry. This is useful when you wake up in the morning after a drunken stupor remembering that, oh yeah, you wrote that blog post at 2:00 AM about your boss. And easy. You just call feed, remove entry on that entry after you get the entry back with its unique identifier. And then you call feed, publish, and hopefully it gets up to the server before your boss logs in in the morning.

I should clarify that this is-- you only need to delete entries if the user actually really wants that entry to go away forever. The feeds will only show a list of the last 20 entries or so. You're not really responsible for managing that. We take care of maintaining the feed at a fixed maximum size. So you can keep all the old entries there in the database. We'll just put the latest end of them in the feed for you.

So now onto where. I showed you the nice icons and kind of waved my hands a bit about the protocols. Let's look at those in some more detail. We have these four constants that you pass in when you create a PSPublished feed. PSUploadPublishingProtocol, .macPublishingProtocol, AtomPublishingProtocol, and BonjourPublishingProtocol. PS upload publishing protocol is really straightforward. It's just a direct upload. You can either use webdav, in which case we use an http put command to upload the contents, or you can use ftp, in which case we'll log in with ftp.

And pretty much any web server in existence that you actually have write access to can be talked to using one of those two protocols. So anywhere that you can put web content, you can now put a feed. The PS.Mac publishing protocol is sort of similar. It's specialized to talk to .Mac. It uses your .Mac identity, it gets your .Mac password out of the keychain, and will just upload the feed, the individual entries of it, up to .Mac.

Atom Publishing Protocol needs a little bit more explanation. As I said, this is a kind of cousin of the Atom syndication format. The syndication format has sort of gone golden master. It's been released as an RFC. The publishing protocol is a little bit earlier. It's still under development. The current state of it is an internet draft which gets updated periodically.

But in practice, it is fairly stable. And the protocol has been adopted already by most of the major entities in the blogging and content management world. I've got a list of them there. So Leopard Server will support the Atom Publishing Protocol, Blogger, Blogspot, MovableType, LiveJournal, TypePad, et cetera, et cetera. If you want to track the progress of this protocol and look at the details of it, you can use the URL there to look at the different drafts going around.

So finally there's the Bonjour publishing protocol which is sort of I guess the Apache and Bonjour publishing protocol which is used for basically personal feed sharing. The way it works is that the agent uses Bonjour to advertise the fact that you have a feed. This is similar to the way that Apache already advertises the fact that you have web sharing turned on and if you go into Safari and look in the Bonjour column there in the bookmarks view, you can see a list of the other web servers. We use kind of a specialized version of this to say, hey, we are sharing feeds.

So another user, another client on the local network can see this. It can see the name of your feed, its URL, and then they can go and fetch it. The request comes in from http. The Apache server receives that request, and through some fancy plumbing, it gets redirected over to our agent, which then gets the content out of the PubSub database and sends it back as XML data to the client that requests it.

And as I talked about during the demo, Bonjour has this capability that in addition to broadcasting the existence of something, you can broadcast metadata about it. And a piece of metadata that we broadcast with the feeds is the modification date. And that information gets pushed out and updated pretty much in real time.

Within a second or two, if there's a lot of packet loss, it might take five or 10 seconds. But really quickly, it will get there, which is much, much better than the typical kind of half-hour latency that you get with RSS feeds, where the agent or the client or whatever sits there and polls the server every once in a while saying, is there anything new? Is there anything new? In this case, the server will actually tell the clients that there's new stuff. So this enables some sort of interesting new applications like the booth sharing, where stuff just shows up in real time. You could even imagine doing a chat application with this.

Finally, if all those protocols aren't enough and if we just weren't imaginative enough to meet your needs, you can take things in your own hands and get access to the feed data yourself. So I've got some examples here. You can call data representation of type on a PSPublished feed and actually get the raw Atom data for that feed or the raw RSS 2.0 data and then put it wherever you want.

If you want to manipulate it a bit more, you can call XML representation on the feed. And what we give you is essentially a DOM tree. It's this NSXML element of the root entry of the feed. And you can crawl through this tree, look at the data in it, maybe even manipulate it.

It's very easy then to convert it into XML if that's what you want to do after you're done changing it. Similarly, you can get the XML representation of any individual entry if you want to do stuff on an entry-by-entry basis. So hopefully that's enough flexibility to do really anything that you can imagine with feeds.

So finally, a little bit about who. In the case of some of these applications, like the small group publishing, you might have information that isn't world accessible information. It might be your address book you're publishing. It might be confidential company information. So you really don't want to have this usual model where you've got a web server that's wide open to the world and anybody can come along and subscribe to your feed.

So we're going to give you some means of access control. Essentially, an ACL, an access control list for any feed that you publish. The identities that will be the items in the access control list are identity services identities. This is another new framework in Leopard. There are going to be some sessions about it during the conference.

The support for this kind of depends on what protocol you're using just by we're limited by what we can do. So with the .mac publishing protocol, if you're publishing your feed up to .mac, then you can use .mac identities to specify who has access to the feed or not.

If you're using the Atom publishing protocol and you're publishing up to, say, a Leopard server, you can use any identities that are known to directory services by both you and that server to specify who has access. And if you're using the Bonjour publishing protocol, pretty much you can use any sort of identity that can use its credentials to verify itself to your local Apache server.

And I think that some of the OS X server sessions are talking more about those kind of things, how those credentials work. The API for this is even more preliminary than the rest of it. In fact, it's not there at all on your seed. We're working on designing the API for that.

Okay, so what? Here's the big conclusion. You can write applications that use a straightforward, high-level API that's based on widely adopted open standards, i.e. RSS, Atom, Atom publishing protocol, etc. to publish, collaborate, push and pull distributed data across the internet or around your local network. And that is PubSub.

So Mark Malone is your internet partnership manager contact if you want to talk about more uses for this. We have set up an email address, [email protected] that you can send emails to if you have feedback for us. We can try to reply on an individual basis. It's not really an actual discussion group mailing list, but you can send us information that way.