Application Frameworks • 50:55
The Advanced Foundation URL APIs are used by both Safari and WebKit to load URL content. These APIs provide powerful services you can use in your application, including high-performance URL loading, improved URL content caching, management of HTTP cookies, a pluggable authentication facility, and a flexible extension mechanism that you can use to add support for custom protocols. We also discuss the migration path for developers using NSURLHandle and URL Access.
Speaker: Ken Kocienda
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Hello, hello, welcome, session 418, as we say, Internet Technologies Advanced Foundation URL. This week, here at the conference, we've introduced a new URL loading API that's going to be in Foundation. I expect probably a lot of you have heard something about it. Well, you're going to be hearing a lot more about it in this session, of course. And yes, so there's sort of, I guess you'd say good news and bad news. The good news is I think you're really going to like this API.
Sort of the bad news is, well, there are some new things that maybe you're going to need to learn about, new classes, new APIs, but there are really also some new features which I think you'll find interesting and useful to you, disk caching, cookies, authentication, a couple of more things. And we'll be talking about these in the whole rest of the session. Until what? Oh, yeah, I do.
OK, so URL loading. We're going to be talking a lot about URL loading. So what do I mean when I say URL loading? Well, let's maybe do a little bit of history. First of all, I'd like to ask you, how many of you are Mac old-timers, real veterans? I see a couple hands.
Oh, a bunch of hands go up. Well, great. Well, then probably you remember loading URLs like this. No, well, maybe not. And, well, I also want to say, you know, this is a doc, right? Well, Steve Jobs is not the only one who's going to do doc minimization tricks there.
These are the jokes, people. Well, of course, all kidding aside, everyone knows that this is the way we load URLs, right? No, no, maybe not. Well, okay. So getting back to the real material, of course, these are a bunch of URLs. This is what we're going to be talking about today. This is sort of the level of networking that we're going to be talking about today, really the level of the URL.
So if you have a URL and you want to use this API, well, the thing you're going to have is, the thing you're going to use is for you have the URL, you want the data, well, this is the API for you. So you start off with the URL.
This API will help you go out to the origin source, whether that be a network, file system, what have you, and get you back the data. So if you're a framework developer, an application developer, this URL loading API is something I think you're going to be pretty, pretty interested in.
And so you might ask, well, why? Why a new API? You see, if you go out on Mac OS X, well, there are many, many APIs for URL loading, right? : Cyberdog, no. Sorry, I've got a five-year-old that one of these things is not like the other. Well, of course, URL Access Manager and Carbon for that. Well, again, we have many, many APIs, but there's really, even though we have all of those, there is one big reason for developing a new URL loading API, and of course, that's Safari.
Um, and when we started developing Safari, it's just about two years ago now, um, well, one of the first things we realized is, well, with Web Browser URL loading, it's, it's pretty complex. I mean, there's a lot of things that you have to do in order to work like a Web Browser in the way that people have come to expect. And, and really, it has to just work all the time. There's not, there's not many, uh, people don't have a, a lot of patience for a Web Browser that doesn't get them through to the places where they want to go. So it has to just work.
And so when we started Safari, well, we knew the URL loading requirements. Well, it had to support a world-class web browser. That was our goal right from the beginning with Safari, is that this was going to be a web browser that everybody on the Mac was going to want to use.
And so in order to get there, we had a short list of things that we were going to try to-- targets we were going to try to hit. And I'll just go over these briefly. Naturally, standards compliance is a big one. There's a very, very long list of RFCs related to web technologies. Naturally, the HTTP RFCs figures very, very prominently for web browsers. So we have to implement that.
But then, of course, out on the real world internet, well, not every site is going to implement every standard to the letter. So we had to make sure that Safari would interoperate with all of these sites. Because people-- people want to go-- go to these sites. So we have to make sure that we can get through there. And of course, there are some real details once you get down to URL loading above and beyond things like you have to do in WebKit and so forth.
And so we wanted to make sure that we had both standards compliance and real world compliance. And then there were features, things that none of those other APIs that I listed before really were going to deliver for us as they stood right there. Things like caching and cookies, things I'll be talking about a little bit later.
And then, of course, there's the issue. There's the issue of performance. We wanted to make sure that URL loading and that the browser was really, really fast. And if I go back to the beginning of the Safari project, well, when I started on this project, I knew how to use a web browser. But I certainly didn't know how to write one. And the first thing that I ever learned about web browsers was this here. If you want to make a fast web browser, you have to have fast URL loading. Nothing else matters if you don't get this right.
And that was told to me by Don Melton. You may have seen his talk. I think it was on Tuesday. He was the first manager of the Safari team. And so this was where I came into the project. And this is what I started doing. And we figured that while we were at it, while we were making sure that we had this good performance and the features and the standards compliance and so forth, if we go one step further and hone those APIs a little bit, make sure there are no WebKit dependencies, no GUI dependencies, and so forth, a couple of other goals we had, that we could have a podcast. a public API usable outside of Safari to do URL loading.
And so that's what we did. And just to get back to this performance issue again, we really do think that it turned out and that it was fast. And I think you see that in Safari. As a matter of fact, I think it turned out to be really fast, to the point where I'm sure you probably saw the keynote, and you saw the G5, and some of the great new technology that's in there. Well, this API is so fast that we had some cooling concerns. And so we wound up dividing Safari up into four different thermal zones.
So you're going to go home and you're not going to know which part of this presentation is the real stuff and which are the jokes. Yeah. Well, anyway, back to the real stuff. So we think this API really does work great. We do. We use it in Safari, and now we want you to use it too. So that's at this developer conference we're going to be making this available. So my job now for the rest of this time is to convince you that it's something that you want to use.
and whether or not you should be interested. And so who should be interested in this API? Well, this API is for you if you load URLs. If not, well, you can probably fall asleep. I mean, you may anyway by the time things are over. But really, of course, loading URLs is a real prerequisite. But then again, if you develop frameworks, applications, this API is really for you. I think it will be suitable for you.
And here's a key point. If you value features more than details, if you're going to be interested in every little socket option, every little bit that's coming over the network, this may not be the right level for you in the stack. You may want to get down maybe a little bit lower on.
But as I said before, if you have a URL and you want to get the data and you don't want to do a lot of extra work, you want it to work correctly, but you don't want to do a lot of extra work, I think this API is something you might be interested in.
And then the last point there is whether you use Objective-C or C, C++, sort of both the Cocoa and Carbon developers should find this API useful. And I want to go and say yes, yes, C, C++, Carbon developers, you can use this API. I won't lie to you. The new API is in Objective-C. But there is no technical barrier to using this in your program. You will need to write a little bit of glue.
But here's my advice on this subject, is that if you like the features, if I do a good enough job convincing you that the features and the API is something you want to use, just link with Foundation and start coding. And the good thing is in the WebKit SDK, which you can download through ADC, there is example code in there which will show you how to do this from a Carbon program. I even have a demo a little bit later, which I'll be showing you briefly. But of course, to really get into it, you're going to need to go and look at that code in the SDK.
And so, any time that a new API is announced and one that affects others, I mean, I can, I've been in your position before. I mean, the question you ask, well, what changes and what stays the same? So let's go through that a little bit. The URL loading API for Safari moves down into the Foundation framework, okay? And it's now called Foundation URL Loading API. I think, you know, heard that turn of phrase quite a few times, okay? There's also another existing API in Foundation to load URLs, NSURL Handle, and that's superseded but supported.
So if you're using NSURL Handle now in your code, that code will continue to work without any change. You don't need to do anything. However, for new code, we suggest if NSURL Handle was something that was attractive to you, I want to convince you to use the API we'll be talking about today instead. Okay.
There's also a number of existing conveniences in Foundation having to do with NSURL. If you have an NSURL and you want to get the data for that, well, those are still fully supported. And one of the things that we're doing-- this is sort of still in progress-- we're re-implementing the internals on top of the new API. I think if we do our job right, this will be done for Panther release.
And as Stream and Foundation is another API, I was just of course introduced to this conference, that's still fully supported. As is CF Stream, still fully supported. But of course, those two APIs are sort of a little bit lower in the stack. And they're not going to have the same features like I'll be talking about. However, they do give you more control in return.
And so that'll be really up to you to decide. They're still fully supported. As is CF Network, it's sort of the same idea. You'll get some more protocol support in CF Network if you want to maybe have more control over threading, that sort of thing. Again, a lower level API. Use it if that's where you want to come into the stack. Still fully supported. As a matter of fact, I should mention, Foundation URL Loading API uses CF Network extensively.
And so this is still good APIs. But again, it's still a matter of leveling, where you are in the stack. URL Access Manager in Carbon, however-- Even though it's still available to you, it's not being removed from the API, removed from the system. However, it's no longer in active development.
And I'd probably refer you to the DVDs. There was a networking overview this morning where Becky Wilrich talked a little bit more about transitioning off old APIs. So you may want to look in your book and look in your DVDs and see a little bit more information about that.
And of course, you can still do it yourself. I mean, if you want to do sockets and go down to that level, you can. But that's a lot of work. Again, if you have a URL and what you want the data, that's really, really going to be a lot of work for you. And I don't suggest that. Instead, I would suggest the foundation URL loading API. It's my talk, so I get the big check mark.
Again, if you have a URL, you want the data, you like the features, and you don't want to write a lot of code, this is probably going to be the API for you. What are the pieces of this API? What are the components? What is the feature set? And so naturally, the first part of it, naturally it's a URL loading API, so a very, very big part of it is URL loading. But then there's also these other pieces which round out that feature set and hopefully will make this API very convenient, easy for you to use, and give you the right combination of power and simplicity. And we'll be stepping through these and doing some good detail about those.
So getting into that, this first piece, URL loading, this is really the basic building blocks of all of those other pieces on that bottom half of that previous slide. So if we go back to that there, right, URL loading is the building blocks for all of those pieces under the break.
So I just want to sort of give us a good grounding and talk about this URL loading piece first. There are some then components in URL loading. The concepts I'm going to talk about first, and we'll talk about how that really fits into the API. We have request, response, connection, and delegate callbacks. You'll be seeing this again and again and again throughout the talk.
So these are things we really want to get a good hold on. So URL loading, begin with request. What is a request? Well, a request is a URL plus load-specific data. So you have a URL, you want to load it, but you want to specify how it should be loaded. So for instance, you may want to bypass the cache, go back to the origin server, pull that data down freshly.
You may want to add a custom HTTP user agent or other HTTP parameters. This would be the place where you would do that in this NSURL request object. So again, request is a URL plus load-specific data. Then we have a response, and a response gives you everything but the data. And so when you send a request out, you're going to get this response back.
You're going to get a response back. You're going to be getting data, of course, but you're also going to be getting interesting metadata that your application is probably going to be pretty interested in. Things like MIME type, content length, or then HTTP-specific information, like whether or not the data should be cached or not. And this is how you get this delivered to your code. And NSURL response, we have a class in the API for this. Thank you.
Okay, connection. A connection is a handle to an asynchronous load in progress. So, if you have a request, you can create a connection with it and start your load. It turns out that request is reusable. You can go and create a request, create a connection with it, go back and modify that request again. Once you start your connection, though, that request is yours.
You can modify it, change the URL, change some of the settings, and use it again to create another connection. Okay? And so that turns out to be really, really convenient in real code. It may seem like a small point now, but it really is really very, very convenient.
And so, as I say, connection uniquely identifies a particular load, a particular request you're sending out. And since this loading happens asynchronously, this connection gives you a handle for canceling, in case you want to stop it before it's all done. And we have a class for this, NSURL connection. Amen.
And so this last piece in this first set of building blocks is these delegate callbacks. Well, so you've got a request, you create a connection, your load begins. Well, interesting things are going to start to happen. You're maybe going to be getting your response back, some data is going to come in, and so forth. Well, the way that we deliver that to your application is with these delegate callbacks.
And so this is for informing you about interesting events and not only informing you, but giving you, in many cases, a chance to take action in your program. This is a very, very important hook for adding that application-specific behavior so that your app can act like it needs to. OK, and some examples of this is, again, you've got the response, you've got some data delivered to you, and your load was finished.
And so we have NSURL Connection Delegate. This is an informal protocol. You implement in your app. You choose out some of these delegate callbacks. And you implement them, and you'll get the callbacks when those events happen. Again, I just touched on it briefly a moment ago, but it's important to mention that these delegate callbacks are optional. There's really quite a nice list of them. However, in your program, you only need to implement the ones that are important for you, that make sense for your application.
And so looking at all these pieces again, we have request, response, connection, and the delegate callbacks. Let me just go back again. These are very, very important. Again, the important building blocks, you'll be seeing them again and again throughout the API when you look at it, and then certainly for the rest of the time during this talk.
Here's a small example just to show you, again, the level at which you would come into this API to go and do some of the work that it knows how to do. So you have maybe a custom method in your program, load URL, you have an NSURL and create a request with it and then create a connection with that request. And that load starts automatically someplace else in your program. Implement a couple delegate callbacks. And this is all you need to do to start using this API.
Again, it gives you that nice level where you have a URL, you get the data back, and you're moving on to the other parts of your code that is really probably more interesting to you than doing the actual loading of data. And so I'd like to do a little bit of a demo.
I could tell you about the demo, but it wouldn't be nearly as interesting. Did the machine go to sleep perhaps? Yes? Okay. Ah, there we go. Okay. Okay, I have a little app here called Visible Loader. Let's just run it. What you'll see here is I have a URL bar. And I'm just going to poke this start load button. And you see some things happening.
Well, what is it that happened? I've got this www.apple.com URL in the address bar. And I just loaded that URL. The visible evidence of that is in this window, which are these. These are the delegate callbacks that I got. That's what this application does with its delegate callbacks, is it logs them in this window. And so you can see I can go around and browse these delegate callbacks and get some nice information about them. Let's kind of just hop back to the code for a second, if I can. Okay.
I seem to have lost my aliases, so you'll have to forgive me. Let me just quit this for a second and see if they come back. No. I had a bunch of aliases that I seem to have lost. Well, there we go. Oh, there they are. And so here are the delegate callbacks that this application implements.
And you'll see in just one of the-- a simple example is I received data, and all that I did in this application was I updated the progress indicator, and I put a little log message in the window so that we can go and look at it. Now, naturally, in your application-- in Safari, for example, what we do is we take that data and we feed it off to the HTML rendering engine. And so this is the way, again, that you begin to hook in your code into this new API.
And again, it just illustrates that this API is not a black box. It gives you a good amount of visibility. In other words, you just don't throw a URL over the wall, get some data back, and that's it. Try to give you a good amount of control over what's happening as it's going on. OK. Go back to the slides, please.
So again, those four pieces, been over them and over them. Again, the basic building blocks for URL loading, the I/O is asynchronous, and there are a bunch of these optional delegate callbacks that you get. OK. So now, using this as a foundation, I'm going to go on and talk about another piece of the API, which is URL file transfers. Excuse me.
And so this is very, very similar to URL loading. However, it gives you some nice features for downloading content instead of just like to maybe the innards of your program or something, just going to download that URL onto disk. And there are a couple extra delegate callbacks, you might imagine, to help you do that. And uploads are coming soon.
And so we take the same picture that we had before, download comes into the middle there and takes the place of connection. But everything else stays the same. We've got this class nsurl-download to go into the place of nsurl-connection. But really, the way that the program works is really very, very similar. And I have another brief demo of that. What I wanted to do for this is illustrate a Carbon. A Carbon example. And so I'm going to run this.
You'll see that-- I'm going to go HTTP. I'm single-threaded when it comes to typing, so you'll have to excuse me. Mac.com and download. And you'll see I'll get a little prompt. And probably just probably on the desktop would be great. So go and do this little download. And you see I've got the file there. And so again, to illustrate, we saw the sheet come down. This is a Carbon program, as I can show you.
There's a slightly modified version of this. It's actually an unhacked-up version, is actually what it is, which is going to be in the developer STK. And you'll see that, again, it's just a bunch of delegate callbacks-- actually a few more than the other program that we looked at. And again, it gives you a good amount of control. Decide destination with suggested file name is the hook that we used to drop that sheet down. So again, you get a good amount of control of things as they're going on.
And then, as you can see down here, this is a little C++ code. So this is an objective C++ file. And it's a little indication of the kind of glue that you'd have to write to get from your C, C++ code over to where you can use this API.
Okay. Good. I'm going to clean. My mommy always told me to clean up after myself, so there we go. Okay, good. So if we can go back to the slides, please. Yes, demo. And so here, seen this picture before, these are the basic, basic building blocks of the API, loading, file transfers, and delegate callbacks. So now I'm going to go on and talk about yet another piece, content caching.
Well, what is this for? Well, after we download a URL, we store the content locally. I don't think this should be news to any of you. Makes future requests for the same URL go faster. Now, the interesting part, I think, about this portion of the API is that it just works automatically. You don't have to do anything. You don't have to call a method or set a flag or anything. Well, I want caching.
No, it's just going to happen for you automatically. It's going to go faster if it can. If it can help you to go faster, it will. But I should also point out that there is an API to provide direct access to the cache and its contents if you wish.
And some of the features of this portion of the API, first there is I like to think that this API presents a good HTTP cache smarts. There's a lot of text in the RFC for HTTP about caching. And we've implemented that. We've gone through, done the work to implement that here.
And so that when you're interacting with this API to go and get content from HTTP servers, it's going to work the way that you want with regard to caching. And so, I mean, that winds up being a bunch of work that you don't have to do. And the benefit is that you'll get the correct combination of correctness and speed.
Another big addition to this API is disk caching, which is, I think, a very nice feature so that your cache will be persistent across multiple runs of your application. And then there's some other things. Configurable policies for request time, like I said before, bypass the cache is perhaps an option.
There's also some other policies, which I'll talk about in a little bit. And then there's, as you might imagine, a delegate callback for response time when things are going to get written into the cache. Now, unlike the APIs that I talked about before, request, response, et cetera, you need to ask yourself, well, is this a portion of the API that I really need to use? And, well, I would answer that by saying, well, if you want the cache to work in the background, if you want it to help you make your program go faster, but you don't really want to know about the details so much, you're not going to need this portion of the API. Again, it just works automatically. And you'll get the benefit. You'll get the benefits without having to do any work. However, you'll need this API if you want, say, custom cache policies for different loads or even, surely, direct access to the cache. You'll need this API.
And so here are the building blocks for this part of the API cache, cache response, and cache policies. Let's just go through that. The cache is actually this single concept, but it turns out to be a stack of memory cache and disk cache. You don't get to see them really separately. There are actually some API methods which will operate on one or the other.
However, when you ask the cache for something, there's no way for us to even report to you through the API, "Oh, this came from memory. This came from disk." Okay? But again, it works transparently. If you're using just the request response API, you won't be involved in interactions with the cache. As you might imagine, it will look in memory first since if it's in memory, it can be returned to your program much faster, and then look on disk, which naturally has much, much more storage to look for information.
Now, I should say that there is--you can configure the sizes of these caches and you can configure where the disk cache will live in case you want to, say, ensure that it lives on a local volume or something like that. And again, of course, it can be accessed directly through the API, and we have a class for this, NSURLCache.
Cache response. A cache response stores the URL data and the metadata. And so it wraps in NSURL response. It wraps in NSData. And when it comes time to disk caching, that object is just serialized right out to disk in a file. You may have looked in your Safari cache on disk and you see a bunch of files with cryptic names. Well, what those are serialized and cached responses. Actually, technically, they're serialized NSCached URL responses.
OK? And then the last portion of this API is cache policies, controls whether the cache data is returned for a URL request. And we have several policies here. You get those good HTTP cache smarts that I mentioned before by default, when you're using HTTP. But you can also say, well, bypass the cache, in case your application may have a reload button. Very, very simply, simple for you to do that.
And then there's also some offline behavior. If you know that you're not connected, you can specify, look, give me this data from the cache, even if it's expired, if it's stale. I just want it because I can't go and refresh it right now. And so this is also very useful for some other applications. We have an enum for those constants.
And so I just wanted to show you a very brief example of how to access the cache directly. Get the shared URL cache. You have a string representing a URL. Create a URL with it. Create a request with that URL. And then you can just go and ask this shared cache object for-- for the object that would map to that request.
And then you can just get an NSData back from that, and then go and do something interesting with the data once you get it. And so, just with a few lines of code, you can take advantage of the direct access cache API. And so, I'd like to do a demo.
: I have a sleepy computer today, it looks like. Could I get a demo? Thank you. And so, here's a little app I call the Disk Cache Inspector. And what this does is it's gone through and it's looked at, provided a list of all of the files in the Safari cache.
And so here they are. And then we can do some interesting things with it. I think they're interesting at least. Is that we can go and give a view of what the content is in the cache. And not only images. You could see that in the case of an HTML page, I've actually got the HTML. This actually is what is in the cache.
And so what you can do with this program is you can SU to root and see what other people have in their disk caches, which is kind of-- : Okay, and so there are some other things here, too, which I think are pretty interesting. Here's... Let's see if I can do this. Ah, yes.
Here's some of, actually much of what is in an NSURL response. You see there's HTTP-specific information in there. That's what's in the cache as well. And then there's also quite a bit of information that comes into use to implement this good cache smarts that I mentioned. So a lot of this information comes into account when you send out a request, the cache is consulted, and the engine has to decide, am I going to use this cache data for this request or not? Or am I going to go out and reload from the network, or really from the network file URLs typically aren't cached.
[Transcript missing]
Okay, just to summarize, again, we've got cache policies, cache, cache response. The cache stores URLs locally, makes things go faster if it can. And again, it has this nice feature where it'll just work automatically if it can. And so fitting this in to the rest of the pieces of the puzzle, we'll be filling those in. And so we've got cache fits in right there.
And so going on to the next piece, HTTP cookies. I think probably most of you, if not all of you, know what a cookie is. Well, when you go out to a website, it'll send you back a small packet of information that then when you go back to that website, you'll send back that little packet of information back to that server every other time you access it. in the future.
And so-- This API enables a lot of e-commerce websites. Website logins rely on this a lot. Another great part, I think, of this API is that, again, it just works for you automatically. So we've got a lot of cookie machinery that'll just kick in whenever you do HTTP. If you need cookies, they'll just be applied for you. But again, this API provides you direct access if you want some more control.
And so the features of this API, we've got persistent cookie storage so that you have your cookie file on disk. Another interesting part of this is that the cookie storage is shared per user. So each user will have their own cookie file, but it's shared among all applications that that user will use. And so if they get some cookie data from, say, Safari, they'll be able to use that cookie data in Sherlock, and you won't have to do anything.
And so but additionally, because cookies, there are some security, some privacy concerns, we do have configurable except policies. And then another piece that we worked very hard on in the cookie API was to interoperate, real world compliance there, to make sure that when sites send us cookies, that we can parse them and read them and use them as the website developer intended. There really isn't a good standard here. It really is just a law of the jungle. And we've really, really tried to make sure that we have a good interoperability with what you'll find out there on the internet.
And so again, do you need this portion of the API? Well, if you want cookies in the background without worrying about the details, you don't. You can just sort of let this work for you and do its good work without having to delve into the details. However, if you want to control cookie except policies or get direct access to the cookie store, then this is a portion of the API you'll need to learn a bit more about. Cookie. Cookie store. Cookie storage. Cookie except policies. These are the three pieces of this API.
And so a cookie, as I just said, this little nugget of information that is sort of exchanged between your program and a server, these are created automatically and sent back automatically. And again, there's extensive rule checking for these. NSHTTP cookie. We have a class in the API for this.
Cookie storage. Cookies are shared on disk, as I said, and are shared among processes. This class will manage that cookie file. It will actually do the work of parsing out this cookie data. And then this is probably where you're going to come in and inspect, set, remove cookies as you wish in your application. We have a class for this. NSHTTP storage.
And cookie except policy. Accepting cookies is governed by this setting. There's actually three different settings. Always accept, always reject. And then accept it only from the same host. And this happens very often. You go to site A. But-- Add server site wants to set a cookie on you when you go to that site. You can set it so that that cookie would get rejected. But any cookies from the site that you navigated to will actually get accepted. And so we have a set of constants for this as well.
Now in Safari, you've probably seen this window here. It may be a little bit hard to see, but the second sort of checkboxes on the top, set of radio buttons, well, that's the cookie accept setting dialog in Safari. It's going to be in the security pane. And when the user goes and checks that, you can see here's just a quick example of just a few lines of code that you'll need to go in and actually implement that setting. This is just actually really just copied right out of Safari, just two other case statements like the one that was listed there, and you're done.
So again, there's sort of the economy of coding that you're going to need to do to use this API and get the features out of what's in there, and we've really, really concentrated on that. And so again, here are the pieces of this API. Cookies help with website logins, e-commerce, and are shared among processes and just work for you automatically. And so we drop that piece into the puzzle. And so moving on, authentication.
Authentication, naturally proving your identity to a software system. In most cases, for websites, this means this sheet will drop down and you're going to need to type in your username and password. I'm sure you've probably, many of you, most of you have seen this dialogue in Safari. And so this portion of the API provides your hooks for a custom UI like you see in Safari.
However, point out that there are actually no GUI dependencies. Again, there are no WebKit dependencies. There's no Cocoa. There's no AppKit dependencies. In this API, so we had to sort of work it out so that that would work, so that would happen. And there's hooks for providing custom authentication schemes, and there's AskOnce capability integration with Keychain.
And so, if you're just interested in loading URLs through the WebKit API, you don't maybe even want to come down to this level. Well naturally, this portion of the API won't be for you, or if you don't need to access protected data. However, if you do want to see that sheet drop down or have functionality similar to that, you're going to need to learn about this portion of the API, the authentication piece, or if you want to develop custom user interfaces. These are the pieces, mercifully.
I'm not going to go and talk through each one individually. Just these are the pieces that we have to represent usernames and passwords, places where you want to authenticate to, individual authentication challenges and so forth. They're all in this portion of the API. And now I'd like to do a brief demo.
So what I've done here is I just went out the other evening and I found this site out on the net that does a lot of, provides a lot of test pages for HTTP authentication. So I'm just going to go up on this very, very first one and get the sheet dropping down. This is the authentication API in Safari being used. I'm just going to log into this site and you'll see that I get access only to rows, basic auth. It's just a little test page, okay? And so you see Safari using this API.
But then I'm going to do another example like going to the same site. I like to call this "That 70s Demo." You see? Sort of like the, I did the nice amber, you know? I couldn't, it was amber or green. I couldn't decide. Well, anyway, this is an example of using authentication from a command line application.
So you see here I didn't even take the trouble of doing, hiding the password. But you can see, again, you just get the output printed to the terminal exactly the same as showed up in Safari. Just showing that, again, this API has, you can use it from command line applications. You don't need to be writing a GUI program to get, to derive advantage from it.
So with that, back to the slides, please. And so authentication, again, providing access to protected data, ask once with the keychain, and no GUI dependencies, as was illustrated. And so--and so-- And so, authentication fits in right there. Going into the next piece, custom protocol. So let's say you have an application and these protocols, HTTP, HTTPS, FTP, file and about, don't suit you. You have Gopher, you have some custom protocol that you want to implement in your application. Well, this will be the API that you'd use to develop your own.
And I think the really, really strong part of this API is that there are no secrets. There's a very, very clean interface to the other parts of the subsystem. It winds up being the same interface that those built-in protocols that we actually wind up do providing. It's the same API that those protocols use. Your protocols are peers to the ones that ship on the system.
I think that's a really, really strong part. Well, naturally, do you need this API? Well, if you're not going to be developing a custom protocol, you don't. And if you are, well, you do. And just two pieces here, protocol and protocol client. This is what actually does-- this is really, in some ways, the classes that implement this protocol concept, they really wind up being the engine of the API. It winds up doing the real work to go out and load a URL in a protocol-specific fashion. Many, many times, these map to a scheme like HTTP.
And they really do work, in many ways, like plug-ins. I mean, you can uninstall and reinstall, actually, even while the application is running. And they just must be registered in order to be used. And we have NSURL protocol is the class for this in the API. And then we have protocol client, which is the piece that provides the interface to the URL loading system. And in some ways, you could think, the whole engine is over here, NSURL protocol instances are over here. And you use this protocol client interface to talk back to the system from your protocol.
And so there's no secret API. And there's this one-way communication. Once a protocol is created, it's the responsibility of the protocol to drive the URL loading process and tell the URL loading system about things that are happening in protocol-specific things having to do with a load. URL protocol client is the API piece for that.
And so here's just a very, very brief example of things that are in the protocol client interface. You'll notice it's actually-- these turns out-- and when you maybe get the SDK and you look, you'll notice that these pieces are actually trying to be very, very similar to what's in the delegate callbacks. Again, these protocols are actually doing the work to drive the load of a URL. And so when interesting things happen, they tell the system, and then the system goes and tells you in your code.
And then actually implementing a protocol, you only need to do a few things. You need to implement a small handful of methods to just go and implement your own protocol and have it be a peer of all of the others. And as a matter of fact, this is a snippet.
It's a good majority of the code that's actually in the About protocol in Safari. And I just highlight out just a couple of lines to show that this is the protocol interface, the About protocol, and it's driving of the load back through to Safari. And you see About protocol never fails.
It always succeeds, did finish loading at the end. And so protocol client, protocol, again, no secret APIs. Your protocols are peers. It's a very, very clean interface to the rest of the system. And so dropping that. Dropping that piece in there. And so I'd like to do just another brief demo.
And I'd like to just point out a feature in Safari, which I don't know if all of you have seen, but this is the activity window. And although in a real program, it's never quite as straightforward as we try to make it up here on stage, but really what winds up happening in this activity window is these are all of the URLs that you loaded. And really what winds up happening, each entry in this list winds up there as a result of one of these delegate callbacks from the URL loading system. That URL got loaded, and eventually that winds up getting reported through the user interface in Safari.
And so this is just, again, yet another example of how delegate callbacks are used. I'd like to do another small demo here to-- This is one I was not planning on doing, but I must have spoken quickly. But this is kind of neat, I think. And so what I've actually done is-- actually, now I have three versions of Safari.
Let's just go with two versions of Safari. And so what I'm going to do is rearrange these windows here. And in both, I'm going to show the cookie list. So that's the cookie list for this window. And, right? And then the, this is the cookie list for this window.
And so what I'm going to do, just to make it easier to see, I'm going to remove all of the cookies from both applications. Now, what you've seen already is that those two copies of Safari, two WebKit clients, two NSURL Foundation API clients, they're cooperating on the cookie store. You remove the cookies from one version of Safari and the other version of Safari, its window just automatically updates with new information about a change in the state of cookies.
And so if I go pick one of these and go back to a site where cookies get set again, you'll see that as soon as I click in that other window, it updates, redraws, and shows that cookies get set in that window as well. So again, an illustration of that cookie API and the cooperation between processes running belonging to a single user.
May I have the slides back, please? And so, to wrap up... This is a roadmap. Some of these conferences, actually half of them, the first two, I see, have already happened. Please go back and review on DVD the open source talk. We use a lot of open source in WebKit and Safari. There's actually no open source, it turns out, in this portion of the API.
This is all implemented by Apple, but if you're interested in Safari technology in general, that's a talk you might be interested in. Safari technology and web standards talks about if you're a website developer, you want to develop content that's going to work well in Safari. If you're just interested in web standards and Apple's implementation stance towards standards, the second one.
Advanced Foundation URL APIs, well, that's this talk, so you saw it. That's all there is to see. And then tomorrow, I really urge you to go to the, if you're interested in Safari technology, go to that last one tomorrow at 9 a.m. Advanced WebKit APIs. If you've seen those demos of wiring things up with WebKit, well, you really go down a step lower and see a little bit more about what's under the hood.
And then, yes, another session tomorrow afternoon, Internet Technologies: Developing Web Services Using Web Channels, some Sherlock technology, Mac OS X networking APIs. Again, I mean, if you saw those checks and Xs before, I mean, I think it's probably, you know, if you're not familiar with the APIs, it's probably a pretty tough choice for you to decide, "Which of these URL loading APIs do I want to use?" Well, I think that session will give you some more good information about that.
And then tomorrow afternoon, CF Network In-Depth will talk to you more about CF Network. And then I also encourage you to come tomorrow at 10:30 to the feedback forum where-- I mean, because you're going to have an opportunity now to ask some questions. But tomorrow you can, you know, come and give us some more feedback about this API and networking as well.
And if you think of something now or if you have other feedback a little bit later, John, if you have anything to add, please feel free to ask. John Galenzi, the email address on the screen is the person to contact for more information and to get further feedback.
And so here's some other information about these APIs. There are some, I think, some very, very nice, the documentation people did a really, really nice job going through and sort of cleaning up what we did and documenting it in such a way that you folks can understand it, hopefully. So I refer you to this documentation.
And then really, if you want to get into this API, you want to get into this API and the WebKit API, I really urge you to go and start working with this WebKit SDK. Again, I should probably--it's been mentioned before, but just to make sure that everyone knows, all the code that you need to do the applications like I wrote here today and the ones that you've seen with WebKit, if you have Panther, you have everything that you need. It's installed on the system.
If you have a Jaguar system and you've installed Safari 1.0, everything is there on the system. You have everything that you need. However, there's some, you know, other examples and such that are really only going to be in the SDK. And so I still do urge you to go out and look at that. urge you to go out and get it.