This is the Core OS Networking Session.
I'm Brett Halle.
I'm the Senior Director responsible for kernel and networking technology for all of our products.
And today we're going to talk a little bit about what we've been doing in terms of networking for the various operating systems and I'm going to start first by reminding people of how we got here.
As us humans have been trying to communicate for it seems like forever and we've tried just about everything we can to transfer information back and forth.
Back in the early 70's you may all remember of the days when really things got started with Unix and systems of that time.
Those of you who were back in that era might remember for example a system called Plato which was probably one of the first network game experiences; I know I ever had the opportunity to experience, it's pretty wild.
But in the early gnarly days of networking BSD, Unix and BSD Networking, it was interesting times, a very difficult challenge of getting everything configured and set up but when it did it worked pretty well.
And over the years we've evolved quite a bit.
Obviously with the advent of the Mac, we brought into play things like AppleTalk and LocalTalk, to try and bring the experience of networking to mere humans; and along the years of course involved more and more capabilities with Ethernet and Wi-Fi and the experience has been pretty good.
But over the past few years, there's been an explosion.
Obviously with the advent of the phone, the iPhone and with the iPad the experience of networking has changed pretty dramatically.
It's gone from being a world that is based on very static to being very dynamic.
Today we're going to talk about the Core OS Networking which is the fundamental networking technology that all of our systems are built upon as part of Darwin.
It obviously starts with Unix, BSD sockets and all the things that you have come to know and love over the years; and on that we build quite a lot of other technology.
CFNetwork, the Foundation classes and other application services and frameworks, things like WebKit and services like that that all build on all of this technology of the system.
It all starts down at the core and Core OS as part of the Darwin Foundation as where I represent.
And we'll talk a lot about the technology we've been adding to that core plumbing today.
And it's important to note that this technology that we have exists on all of the platforms; it's the same networking technology whether it happens to be Mac OS X Snow Leopard or it happens to be iOS 4 it's all built on the same fundamental core and while there are some minor differences it's built using the same both engineering teams and source code and technology.
So we've added a number of things as part of iOS 4 you've probably already noticed, but I wanted to remind you and introduce them to you if you haven't experienced them yet.
First and foremost is IPv6.
So with iOS 4 we brought forward the capability of v6 and brought it in sync with the technology that we have in Snow Leopard; v6 you might wonder why is this important?
Well I'm sure you of course all have heard that we are running out of IPv4 addresses and next time when we meet a year from now I would expect that we have just a little over a month left before we've exhausted the available v4 addresses.
But we've brought v6 onto the iOS 4 platform because we believe it's an essential technology moving forward not only for being able to deal with the challenges of running out of IP addresses, but the fact that is we move globally and we're dealing with different challenges everywhere we go in the globe.
Some places such as China and Japan are extremely focused on moving forward to using v6 whereas here in the states we're lagging a little bit behind although there's some great progress with folks like Comcast and others who are moving forward to delivering v6 to the home.
It should be noted if you haven't noticed already that we've enabled v6 here at the conference.
So if you happen to have the developer preview or you're running Snow Leopard on your laptops, v6 is available over Wi-Fi and on your developer preview for iOS 4, you can get a v6 address and we have v6 support all through the conference this week.
But as part of iOS 4 we've brought the stack from Snow Leopard 4 to iOS 4 and we've also added some additional capabilities.
For example, we've added the initial support for DHEPv6, particularly the stateless support, meaning we don't get the IP address from DHEP but because we take advantage of router advertisement, the capability that's kind of a fundamental capability that exists as part of IPv6, but we get the other important information that's necessary to get a good connection experience such as your DNS server address, search domains and things of that nature.
If you're writing to the upper layers of the system to CFNetwork and above, chances are your apps are already ready to go as far as IPv6 is concerned.
Certainly v6 support is available and visible at the stack level all through the socket interface, CFNetwork and above, and if you're using CFNetwork like I said you're probably already done.
All you need to do is test and make sure everything works as you would expect and you should be good to go.
However if you're not using CFNetwork, you may have some work that you need to do and should certainly be aware and check your code, particularly if you've got older source code that you're incorporating into your projects, potentially open source or other things.
When you're writing for v6 after using the lower levels, there's some things to keep in mind-number one write your code to be address independent; you're going to be now getting different responses from your DNS servers.
It's very likely that you'll get some combination of IPv4 and IPv6 addresses in response to DNS resolution.
And if you're storing or displaying IP addresses, you need to make sure that you're using the right data structures and that you are not making dependencies on what an IP address looks like.
And frankly you shouldn't really be needing to display an IP address for the most of the users unless they're very sophisticated.
But use the APIs that are available for independent hostname lookups, getaddrinfo in particular, and again be prepared for dealing with a combination of responses depending where you are at.
Also make sure you're using the right data structures again for storing your addresses; and if you're using a kind of a conventional allocate open a socket, resolve your DNS name and then do a connection, you need to rethink that process because what you need to do first is resolve your DNS name and from that you can determine whether or not you're dealing with a v4 or v6 address, then open the appropriate socket and then make the connection.
And there's some appropriate APIs to use and some good documentation that already exists as part of Mac OS X that can help you do this effectively.
Also if your apps are listening on connections, you want to be listening really only on v6 sockets because we do the necessary work to be able to provide the v4 connection for you.
So you don't need to listen on both.
Listen on v6 only and you should get the right experience.
The other thing is due to the nature of the legacy; that is, BSD sockets interfaces and others, that there are functions and structures that are IPv4 specific and you want to be avoiding those.
Again, you need to start moving forward taking advantage of the fact that v6 is here and it provides a lot of important capabilities.
Not just the addressability challenges that we're facing but frankly it's a much better experience as you're dealing with peer-to-peer connections; because you can imagine for example in a room like this where there's quite a large number of you allocating the four addresses for being able to do peer-to-peer connections can be a challenge and chances are you'll exhaust even that addressability, whereas the v6 address provides considerable more flexibility there.
Another feature that we've enhanced for iOS4 is our support for captive networks.
We introduced this capability of supporting captive networks in iOS 3 and what is a captive network?
If you go to Starbucks or McDonald's or to the airport or to a hotel, chances are you've dealt with the situation that when you go to the Wi-Fi they want you to either click OK to agree to their use terms or you have to put in a user name and a password and credit card information because it's some type of paid connection.
This is a captive network.
And what's interesting is that a few years ago when these came into being, most of the experience from our users was most likely a laptop, when their first experience when they opened their laptop was to go to a web browser.
And when they tried to open their first page, they'd get this UI that would have them enter user name and password or accept terms.
Well the experience on these mobile devices is extremely different.
It's very likely that you'll be connecting to something else other than your web browser first.
The user is most likely going to be running your app or checking stock ticker or news or something else, and the web browser is probably not something that's going to be their first connection experience.
And the captive network support that we put in place detects when you have connected to a captive network so that what happens is at the point of detection, the UI is brought up for the user regardless of where they are as opposed to requiring them to go to the web browser first.
And it will automatically keep track of any user info for log information or other information so that the next time they can connect to that network they don't have to go through the experience again and again.
In addition if you're dealing with carrier hotspots because one of the things that we've seen is given the extreme load on the 3G networks, that the carriers are more and more providing free Wi-Fi capability if you happen to be a user of their 3G service because they want to get the load off of their 3G backend; that they provide free Wi-Fi and we detect when you're in those situations and we automatically will connect you so then again the user gets the right experience.
One of the things that's new for iOS 4 is that we intentionally make the Wi-Fi interface unavailable or as a secondary interface while we go through the process of authentication.
During iOS 3 there could be situations where if your app was up and running and trying to use the network that your app and our authentication process would actually collide until the network was truly available.
The Wi-Fi experience is usually you go and you associate to the network and then our experience has been well then you can start moving backwards back and forth.
But the really is in a captive network that there's one more step which is this authentication step and so what we've done now is make the Wi-Fi interface so that it's not primary and available until we've gone through and made it non-captive and properly authenticated.
We've also introduced some support for our hotspot management applications.
There's folks like Boingo and others who may need to provide some advisory information to us to let us know that there are Wi-Fi hotspots or SS ID's that they have an interest in that maybe we might not want to try and authenticate because they have more information than we do.
So we've introduced some initial support in iOS 4 to make this process better.
Another feature we've added in iOS 4 is SSL VPN and this is a combination of some significant new OS level plumbing that we put in place to allow our partners, Cisco and Juniper, to implement SSL VPN solutions.
SSL VPN is interesting in that it's kind of the current and moving forward wave of enterprise connection to deal with the complexities that we are facing with more complex networks particularly when you're dealing with mats and double mats and other firewalls, IP sec and existing or older forms of VPN connectivity may not be able to very easily connect and deal with negotiating through those network channels.
SSL VPN arose as a way to deal with these challenges to use the one fairly consistently known path for being able to get a connection which is the SSL connection port.
And so what Juniper, Cisco and others have done is create, albeit proprietary, but solutions for being able to deal with these kinds of connections in all these various situations particularly in mobile.
So we've added a considerable amount of plumbing to iOS 4 to enable them to do that and they've implemented solutions for the platform that are available via the app store.
But it's important to you as the developers to know that now there are some even additional ways that your users may be connecting into secure environments.
Probably one of the most significant changes in iOS 4 is support for multitasking.
And when you're dealing with networking in the multitasking situation there's some things you need to be aware of.
In particular when your app is backgrounded your network sockets will persist for some arbitrary period of time; but if the system needs those resources back they will be reclaimed and those sockets will be closed.
Which means you need to deal with situations in potentially failure conditions that you may not have anticipated previously.
We encourage you to respond to going to background notification because when you do that there are probably things you can do to shut down connections or preserve state so that you get the right experience when your user returns your app to the foreground.
Probably the most important thing though is you really need to deal with new forms of errors that you may not have been testing for before and make sure that you respond to all the situations where you may be getting networking errors.
This is one of these cases where reading the documentation is going to be really important.
There are also a couple of other sessions going on this week that we strongly encourage you to go to be able to get more information on how to deal with things.
Certainly documentation in these sessions can help if you're developing VoiceOver IP solutions or background music demo service, things like that play services.
I encourage you to go to the adopting multitasking on the iPhone OS Part 1 and Part 2 sessions, as well as simplifying network using Bonjour sessions.
All these sessions will talk in a lot more detail about the challenges you'll face when you're dealing with multitasking.
As I mentioned early on these new devices have really changed the experience that users have now as far as how they deal with networking.
In the old days and it's kind of humorous to think of it in those terms, most users' network experience was using the browser and checking your e-mail and maybe a couple of other things; but the reality is, is that a huge number of applications that are being developed now are network-enabled; and this is the experience our users want to have when they have these devices, that's the advantage.
They can move anywhere, they can get access to information on the fly, it's really, really a cool thing for them to be able to expect.
And what it means though for you as developers is a real significant change in your mindset in terms of how you develop networking applications.
The mobility is not the exception it's the reality, it's the norm.
Things used to be simple, big computers plugged into UPS's in the wall.
If you are an old-timer like me, you know, an Ethernet cable was a big coax cable that was connected to the back of the computer, probably there was an assistant administrator involved for configuring everything, and your entire local networking environment was under somebody's control.
I'm sure you experienced yesterday that local networking environments may not necessarily be easy to control anymore.
Nothing is static anymore.
And although networking when it was originally designed assumed a lot of static pictures in terms of its design model.
The reality is that this is no longer the case and that everything is dynamic and you can assume anything will change signal strength, cell availability, Wi-Fi ability, whether or not the public or private Wi-Fi environment, whether you're dealing with VPN connectivity or whether or not you have a whole bunch of people in the audience who have brought their own base stations just to make demos challenging.
All of those things can come to play.
From the user's perspective networking is scary.
It feels a little like smoke signals, they don't really know how it works, sometimes from our perspective it feels a little like cans with string between them; but the reality is this experience usually cannot even be as good as that because at least if you've got the string you know you've got a connection.
What we need to do though, everybody in this room, is we need to make sure that if you're a user that it really feels like it's a magical experience; that the right things happen that they're not having to think about what's involved and all the challenges that are involved with their network experience.
So with that I want to talk a little bit about what I call the Networking Top 10 the things that I encourage you to remember while you're writing the next great app.
Starting with number 10. Don't assume the network is free.
The reality is that usage is likely to be and it appears from recent announcements from AT&T that it's very likely to be charged by time or amount.
That you need to be aware that the traffic that you're putting over this connection might be costing you user money.
So if you can avoid unnecessary traffic, retransmitting information, transmitting unnecessarily large things when doing the scaling down on the device, that that's a wise thing to do.
If you can make sure that you're dealing with potentially data-appropriate information and can keep your connections down you'll cost the user considerably less.
Certainly your 3G or Wi-Fi situation may be fee-based.
If you're in a captive network they again might be paying by byte, they might be paying by time; these are things that you need to consider and to make sure that you're not spending the user's money when they're not looking.
Obviously if you've dealt with 3G and you've gone overseas and have turned on 3G data roaming for example and manage to get one of those bills, it's kind of scary.
Nothing like a few thousand dollar bill when you get back from your trip to wake you right up; so again we want to be very, very sensitive to the fact that those things cost the users money.
And again cache when you can.
Number 9, robustly deal with network errors.
The reality is in this environment, in a mobile environment, you're going to be dealing with networking errors that you've probably never dealt with before.
Connections will go down it's a guarantee.
Just plan for it.
Know that those things are going to happen, check for error conditions in your networking code in all cases, and unfortunately it means a lot of testing and in different environments.
You need to make sure that you've tried all the various flavors of Edge, of 3G, whether you've done the various flavors of Wi-Fi because I don't know if you noticed yesterday in the keynote, one of the phones worked and the other didn't.
You may not be aware but the older phones do not have n capability where 80211n whereas the iPhone 4 does.
And that's a situation where those two phone environments were on an actually different Wi-Fi network bandwidth frequencies and those things can impact what your experience will be.
Certainly n will provide you greater throughput capability but you need to make sure you've tested for all those variants.
Packets are going to get dropped just the nature of the beast in a mobile environment.
And timeouts are going to occur.
You in particular need to be much more aware with iOS 4 of how to deal with backgrounding; make sure that you're dealing with it intelligently and close things down when you can it makes sense.
Number 8 networking is asynchronous by definition.
It is the most asynchronous activity that will happen on your system; and you need to write your code this way and unfortunately the number of apps that I've experienced that put synchronous calls on the main thread is kind of frightening and sad.
Do not, do not put synchronous calls on the main thread.
If you are for example trying to get host by name on the main thread and you happen to be in an environment where you've got a flaky connection, or the DNS thing isn't responding very quickly, you've probably experienced that your app is going to get shot.
Frankly, as a developer I'm surprised your user hasn't shot you.
It's really a bad experience for the app to go away for long periods of times and not be responsive or to just quit unexpectedly.
And the reality is that because of the asynchronous nature of networking, you don't want to be putting things in a situation where it's going to block the user experience.
Use event-driven APIs to give a better experience.
Make sure you take advantage of things like Bonjour and the Foundation APIs and with RunLoop event sources and other things to get the right experience.
Put things on threads when it makes sense to do so.
But most importantly keep it off the main thread; don't block UI.
But also realize that there are some calls in the system that also return information asynchronously.
If you're for example trying to do a peer-to-peer connection or connecting to a local network using Bonjour, you will get data returned to you of services available over time as they are discovered and are made available on network.
And the user really expects that that's going to be the case so you shouldn't just grab what you happen to get in just the few first seconds or two and only show that information but realize that it's going to be updating potentially as their connection remains live.
Your UI needs to reflect the reality of this asynchronousity.
Number 7 link quality is completely variable.
We again all experienced that yesterday.
Wi-Fi, 3G and some things that I've certainly have seen or will be seeing more of layered networks.
Some airplanes for example today are now providing Wi-Fi on board.
But obviously you're not getting Wi-Fi back to a cable, back to the ground, that would be amusing.
The reality is that they're going through some satellite connection or through some other secondary transport which is a lot worse than your initial connection.
So you can't assume just because you've got a great Wi-Fi connection all the bars are up and everything that that's going to be the speed of your communication.
The reality is that you might be stocked behind someday.
Turns out we happen to have some commuter buses that we use frequently and there's Wi-Fi on the busses that's great, but they go through a 3G connection and so again while it may look like it's all a great connection, you're dealing with potentially a lot of aggregated traffic on a much slower link behind your initial connection.
You need to expect changes in speed; you need to deal with latency delays and other challenges and again packet loss.
Number 6 deal with no network conditions.
There's going to be situations where your user's in an environment where there is no network at all.
My wife happens to be a teacher and every time I go into her classroom I'm convinced I'm in a Faraday cage.
There's absolutely no signal of any type for anything.
And if I launch an application that happens to use the network and I might not even realize that it's network enabled at first but because it has some network behavior built into it, and the Apple all of a sudden doesn't respond at all the way you would expect.
One example of this is an app that might have a synchronous, an asynchronous call on the main thread, and sitting there trying to resolve DNS when I've got no network.
Well, all of a sudden that app is effectively dead to me.
You need to make sure that you deal with the fact that the network may not be there when you launch, and more interestingly may disappear as the user walks down the street or they move from one room to another.
You need to deal with that and there's a few ways, good examples that I've seen either caching information, but giving people reasonable feedback to know their network isn't available they may not get quite the experience that they would hope for.
Your app needs to behave intelligently, it needs to be graceful.
Again test for this.
Number 5 Assume the network is insecure.
You may be in a public Wi-Fi environment, a hotspot; you might be here at the conference.
What's the chances are that you've actually connected to a spoof network that somebody has actually created to look conveniently just like the network that you're expecting.
That's very possible and our users are certainly nowhere near as sophisticated as you are and can easily get in an environment where they're either in a public environment or somewhere where they might be in a spoof network.
You need to be careful about the kind of information that you're moving over the line.
Again, it used to be you could assume if you were running a certain class of application that would only be run in an enterprise environment and of course it was their responsibility to make sure everything was secure.
The world's different now and you're going to be dealing with various forms of communications and connections and you need to be sensitive to it.
Don't transmit user information in the clear.
If you can, take advantage of things like transport-level security (TLS) or other mechanisms for making sure that users information is protected.
They're trusting that you're going to do the right thing and again they're not network experts.
Number 4 Make sure you're IPv4/IPv6 agnostic.
The reality is that v6 is here and if you have an application that's global or you're dealing with different environments, you need to deal with v6 now.
It's available on iOS 4 and certainly it had been available on our desktop, laptop products for a number of years.
It's here in our products for you to be able to take advantage of and it's used throughout the world.
Make sure you're not making any assumptions as to the kinds of address types that you're using, don't assume things or before, be prepared for multiple DNS resolution responses, and make sure that you check your open source and older source code for v6 compatibility.
For whatever reason you can't completely support v6, at least make sure you're not doing anything foolish so your app doesn't respond badly.
Because we can certainly assume while v6 gets rolled out more and more to the world, that it's probably a good chance that there'll be a combination of v4 and v6 connectivity that's available.
You at least need to make sure you deal with that well and make sure that if you do get v6 responses that you again respond intelligently.
Number 3 Use Bonjour to advertise and find services.
It's a dynamic world, nobody remembers an IP address and if you haven't experienced a v6 address yet, I challenge you to memorize one.
I certainly, for whatever reason been doing this many years, I have a whole bunch of v4 addresses that seem to be permanently burned in my brain but there's no way in the world I'm going to memorize one of these v6 addresses.
And the reality is that the user should never have to deal with this.
So they should always be using obviously for Internet related connectivity you would expect that they're going to be using DNS and various URLs and such for their connections.
But more importantly if you're creating a peer-to-peer solution where you're sharing information over a local network, take advantage of the mechanisms that we've built into the system; use Bonjour.
You can advertise your services; you can browse and resolve.
It provides all the plumbing and capability to it to get a great peer-to-peer experience.
And if you're using Bonjour you'll actually get the support for being able to do Bluetooth connectivity for free.
On the desktop OS it's worth noting that we also have some additional capabilities if you are providing a service; for example, file sharing or some other service that if you're running on top of Snow Leopard, that we provide this capability called sleep proxy support.
What this means is in order to create as truly a green environment as we can, we enable this ability so if you've got a service on a desktop or laptop environment, a laptop that's plugged into the wall power wise, that that service will be available even if the machine is put to sleep.
Because what happens at the point of being put to sleep is that any of that service information that you've registered with Bonjour gets sent to a sleep proxy server that's on your network.
The sleep proxy server can be an airport base station, a time capsule, Apple TV, these are all devices that are always on and can be in a situation to listen for those services even though your desktop machine may be in full sleep mode.
And what ends up happening is when the user connects to that service; the sleep proxy intercepts that request and does the necessary wake on land or wake on wireless to make sure that the actual service providing system is woken up so they can respond.
That way the device can go truly into its lowest power state.
But this is an important capability so if you're doing for example, users doing iTunes sharing or file sharing or you're providing some service so that you can get wireless connectivity when they come back into the house, the right thing will happen when using Bonjour and with the sleep proxy.
I encourage you to go to the Bonjour session later this week to get more information.
Number 2 Power is important as performance.
Obviously everyone wants their apps to be snappy and responsive, that's the expectation that everybody has but power is critical in these environments; portability means batteries and battery means a finite power resource.
Don't power up the radios more than you need to.
You're going "Gee, how do I power up the radio?"
You power up the radio by creating network traffic.
And so if you're doing network traffic, one of the things we encourage you to do is be bursty.
Someone said it's better to group your requests and get a lot of communication done as a burst, than it is to dribble things out over time.
Because as you dribble those connections or keep those connections open and active over a long period of time, most likely you're keeping the radio active, whether it be the Wi-Fi, the Bluetooth or the 3G and that means you're draining battery.
The radios are probably one of the more significant ways you can drain battery from these devices.
This is why we've done what we've done in terms of the background capability, the multitasking; because experience has been certainly as we've seen in other platforms, that if you keep a lot of things active in the background that battery is getting drained at a kind of a significant rate.
So we've worked very hard to try and get the best battery life experience that we can for users.
We need your help to make sure that that experience is as good as it can be.
Take advantage of push notification.
This is the one of the more equivalents to the sleep proxy if you will.
Allow the advice to go to its lowest state and get a delayed notification to be able to deal with various events.
Take advantage of push notifications when you can because that's one way you can avoid keeping connections open more than you need to.
And again on the desktop and Snow Leopard sleep proxy support does a significant job in helping.
And finally Number 1 you've got to assume that there's going to be change at any time.
This is no longer a static world.
Anything and everything as far as your network behavior is concerned will change.
Your available interfaces, it's very possible that in one moment you've got a Wi-Fi connection, then it drops because of connectivity; they've gone into an elevator but you've got 3G connection capability or any number of other combinations or 3G is down and all you can get to is Edge.
There are a lot of things that may change in terms of the network connectivity and experience.
Your signal strength and quality can change dramatically just in a matter of feet or sometimes just standing there because of other interference, right?
So make sure you're not leaving connections open longer than you need to.
The more you're prepared for this kind of change, the more you're able to adapt to this and not be keeping a lots of things open and active, the less sensitive you're going to be to these kinds of changes and the easier it's going to be to give a good experience to the users.
So you want to think about obviously what you're connecting is the key part of your value proposition you're going to have to keep the connections open.
But think about do you need to keep all these connections all the time, are there more efficient ways to make these things so that you can deal with change?
And if you are keeping them open what do you do when there is a change in network state?
Can you behind the scenes change the connection to take advantage of whatever the now available interface is so that the experience is a good one?
The other thing to note is like I talked about earlier, you've got to deal with situations where you may not have a network at all at some point, but the network is likely to come back and this is where good networking behavior comes into play.
Take advantage of the way the system is architected to help you here.
Use the reachability APIs for example, help provide notifications when the network changes state.
One other thing to note here though is the reachability APIs are not a preflight check.
You don't use the reachability APIs to say can I make a connection to this service?
No. Try and make the connection to the service first; if it fails use the reachability APIs to give you change notifications and other feedback so that you know when it might be a good time to try again or deal with some other change in network state.
Change is probably our biggest challenge as network developers; and this is one of the things that you're going to spend most of your time dealing with whether you're testing or other things.
You need to provide an environment that you're testing in to anticipate all the various change conditions that you possibly can so the user is not the one who is being the guinea pig in these situations.
I didn't say it was easy but this is important as far as a great experience.
So with that I want to encourage you to go to a number of sessions that are coming during this week.
There's a lot more detail obviously than I can provide here in this short session.
So certainly for Bonjour, for peer-to-peer capability, for finding services, please go to the Simplifying Network Using Bonjour session on Wednesday.
There are also a couple of sessions on Network Apps for iPhone Part 1 and 2, Wednesday at 2 and Wednesday at 3:15.
This will get you into the details around CFNetwork and other APIs and services that are available on the platform.
I also encourage you to go to a couple of sessions later today if you're looking at multitasking.
The Adopting Multitasking on iPhone OS, Part 1 and Part 2.
Part 2 in particular I believe has a considerable amount of detail around how to deal with some of the challenges of multitasking; and so I really encourage you to take advantage of these sessions and of course documentation.
So I think it's important to note the world has changed over the past few years.
The iPhone made a really dramatic change in the user's expectations of how to deal with mobility; that networked applications really add enormous value to our customers, your customers and ours.
And the more you can do to give them this connective experience, the better.
But unfortunately it means for you there's a lot of work to be done to make sure you deal with all the challenges that are involved.
It's no longer as easy as it was a handful of years ago when the environment that you were dealing with was static.
I'm really looking forward to seeing the apps that you guys produce, I've had the opportunity to play with a substantial number of apps that are out there today that provide really great network experience for users.
And I think as we move forward we're just going to continue to see this explode.
Out of the 225,000 apps that are currently up there we know that a large number of them take advantage of networking.
They may not be obvious to the user.
Some of it is for games, keeping track of the high score lists and things that they don't experience throughout the connection and running and playing of the app, but they experience it at some point.
Whether they experience it as the primary capability of your application or the secondary one, the experience that you provide for them is key and we're here to do what we can to help you make that experience as good as we can.