Video hosted by Apple at devstreaming-cdn.apple.com

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: wwdc2014-715
$eventId
ID of event: wwdc2014
$eventContentId
ID of session without event part: 715
$eventShortId
Shortened ID of event: wwdc14
$year
Year of session: 2014
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2014] [Session 715] User Privac...

WWDC14 • Session 715

User Privacy in iOS and OS X

Core OS • iOS, OS X • 45:58

Learn about new iOS and OS X privacy features and get details on new and updated APIs. Hear best practices for delivering great features and respecting your customers' privacy.

Speakers: Katie Skinner, David Stites

Unlisted on Apple Developer site

Transcript

This transcript has potential transcription errors. We are working on an improved version.

Good afternoon. My name is Katie Skinner and I work at Apple Product Security and Privacy. That means I work with teams all across Apple on user privacy and protecting our users. This includes our platforms like iOS, Siri, and applications like iPhoto. Today, in this session, David Stites and I are going to talk about ways you can protect your users' privacy and changes made to the Apple ecosystem to improve user privacy. Thank you. So, we're going to start out talking about privacy and reputation, identifiers in iOS, how to prompt your users well, new classes for data isolation, and some privacy best practices.

So, privacy and reputation: your users are so important to you. They're the key to your success. So maintaining your relationship with them is your most important thing. They're the people who download your app, tell their friends how great it is, don't think twice before uploading photos, or granting you access to contents. Or alternately, those are the users who will uninstall your application, or think twice about using location with you. So, privacy and how you protect your users' data is a big part of this.

Lately there's been an appetite in the media for stories about privacy, from large stories like Target, to smaller ones. But, they continue to appear over and over again. The best bet is to be trustworthy with your users, because rebuilding user trust is hard. It's much more difficult than maintaining your users' trust.

Now, I'm going to talk about the identifiers available in iOS. There are three purpose-scoped identifiers. The first one is the application identifier, NSUUID UUID. The second one is the vendor identifier, UIDevice currentDevice, identifierForVendor. The third one, advertising identifier, UIDevice currentDevice identifierForAdvertising. Now, I'm not going to talk about these in a lot of detail today.

Last year, we talked about them, how to use them, their behavior, lifetime. So, if you're new to the platform, you should go and look at "Protecting User's Privacy" from last year's WWDC. It's a great place to start. Now, this is a great reference slide to look at when you're thinking about which identifier to use for a particular use-case. I'm going to pull out a couple points. The application identifier is used to identify something uniquely within a single app.

The vendor identifier can be used across multiple applications and it's all in the same device with the same team ID. Now, the application identifier you need to manage yourself, but the vendor identifier iOS will manage for you. The advertising identifier should be used for all user tracking for advertising, or related to advertising.

Now, there's been a lot of discussion about how to use the advertising identifier - what are the supported use-cases? But, before we get into that I want to allay one point with you guys, is be clear with your users about how you advertise, especially if you're using their user data as part of your advertising practices.

You should not cache the advertising identifier. You need to respect a user's ability to reset this identifier. They can reset it under Settings, Privacy, Advertising using the Reset Advertising ID button. Also this year, for TestFlight apps, the advertising identifier will be different each time you call the API. This is another reason why you shouldn't count on the advertising identifier to be a stable value. In iOS we've given users a choice about how they want to be served advertising and that really comes back to Limit Ad Tracking.

Before using the advertising identifier you need to check the value of Limit Ad Tracking. This is ASIdentifierManager sharedManager advertisingTrackingEnabled. Note, this may be controlled -- this can be controlled by restrictions, and with Family Sharing this year this may affect more of your users. Even if you, yourself, are not writing the code to handle the advertising identifier and you're using a third party advertising library, you need to ensure that that library is also checking Limit Ad Tracking before using the advertising identifier. When advertisingTracking Enabled is set to No, the advertising identifier is not permitted to be used to collect data for, or to serve, targeted advertising.

You can use it only for the purposes enumerated in the iOS Program License Agreement. This includes frequency capping, conversion events, fraud detection for advertising, and debugging for advertising. Note, for fraud detection and debugging this can only be used - not for all fraud detection, not for all debugging - only debugging advertising issues.

This year in iTunes Connect, now you need to explain and attribute why you're using the advertising identifier for which of these uses. You should select one, two, or three depending on how you use the advertising identifier. The first one's pretty clear: serve advertisements. The second one: attribute app installation, now once a user installs your application, this means attributing that installation to an advertisement they may have seen in a different application. The last one: attribute an action. This could be Coins Bot or any other in-app purchase. Attribute that action taken to a previously served advertisement, either within your app or another application.

Now, here's where you go and make these choices in iTunes Connect. You can see the first thing that you do is say, "Are you going to use the advertising identifier, or not?" Then, select which of the three choices, or more than one, that you'll be using the advertising identifier for. And then, lastly, you must say that you will check Limit Ad Tracking before using the advertising identifier. Now, I'm going to talk about a couple changes coming to iOS 8 and OS X Yosemite that are privacy-related.

The first one's Family Sharing. This means that this year there'll be an increased number of child accounts within the Apple ecosystem. There's a great talk by Chris Espinosa right after ours that will go further into the implications that you should be thinking about as a result of this, so I would encourage everyone to stick around after our talk to hear "Kids and Apps". He'll talk a little bit more about the relevant laws like COPPA to be thinking about for this; for the additional number of children on this system. So, here's the talk, right in here.

In iOS 8 the Mac address during probe requests and probe responses, as well as region monitoring, will be locally administrated and random. This means if you interact or design a piece of external hardware, you should not count on a stable Mac address until after authentication. Go test some iOS 8 and understand the impact this may have for you.

This year in Safari there's a new setting. This will allow users to block third party cookies and it is available both on iOS and OS X. Now, I assume most of you, if not all of you, in the audience have a web presence, even if it's only a website that points and has a link to the App Store, you have a web presence.

So, go on iOS, enable this setting, and visit your web presence. Understand the impact that this will have on you and ensure that your users will still be able to do the things they need to do on your website; go to the App Store, FAQ, whatever it is.

Here you can see where you can go and find this setting. On iOS it's under Settings, Safari, in the Privacy and Security Section. On OS X you can find this under Safari Preferences on the Privacy tab. Note, this setting is not on by default but this is a choice that users can make.

Also in iOS, we've now given the ability for you to utilize the People Picker without requesting Contacts access to the full address book from your users. This is a great win for apps that don't need the whole address book, that maybe only you need to send an invite to one person you're going to share every so often with a single user. But, note, this will provide only a static -- static information. If the user then, later, goes and decides to change or update this contact you will not receive any of that information.

In a future seed, some of the iOS 7 delegate methods are going to be deprecated, so you need to update and migrate if you're currently using the People Picker. We have a great sample code project for you to go and check out and see how to implement on iOS 8. These are the delegate methods that will be deprecated: ABPeoplePicker NavigationController Delegate peoplePicker NavigationController shouldContinueAfterSelecting Person and shouldContinue AfterSelectingPerson :property:identifier.

And, we also have some new properties and delegates in iOS 8; ABPeoplePicker NavigationController .predicateForEnablingPerson, predicateFor SelectionOfPerson, and predicateFor SelectionOfProperty. And then new delegates are ABPeoplePicker NaviagionControllerDelegate peoplePicker NavigationController :didSelectPerson and didSelectPerson :property :identifier. So, go and update, and migrate early. Now, I've gone through several different privacy changes and what I want to encourage everyone here to do is, if they're not already have a device on iOS 8 and OS X Yosemite, update now.

Understand the impact these changes will have on you because you have a great experience for your users today, and you don't want to mess it up as they move and migrate to iOS 8; keep a consistent great experience. Now, I'm going to hand it over to David, who's going to talk more about the keys to prompting with purpose and how to be successful at that.

[ Applause ]

Thank you, and good afternoon. As Katie mentioned, I'm going to talk to you about both prompting your users with purpose and then dive into data isolation, and how it works on both iOS and OS X. Prompting with purpose, means designing the experience your users will receive when they're confronted with a privacy dialog. There are five core principles that form the basis for prompting with purpose: consent, transparency, context, clarity, and minimization, and we'll talk about all of those coming up.

The first principle is consent. Consent is getting your user's approval to access their user data. This should already be familiar to you. The model that Apple has chosen to adopt is the Just in Time model, meaning that consent is only presented to the user at the exact time that the access occurs. We think that Just in Time access is a key-differentiating feature of our platform. If the user decides to allow access, then you'll get data back. And, if they decide not to allow access, you won't get anything.

Transparency, is the second principle. Transparency is complementary to consent in that it answers the question of why an app needs access to user data. Apps are given a dedicated space to tell users, called a purpose string. And purpose strings are as an apps chance to explain the proposition value of allowing that access. If the user understands that there might be more willing to allow your application access. In this example, Calendar wants to use Location to estimate travel times and improve location searches.

The third principle is context. Context is making it clear to your users what action led to the consent dialog. Consider this example. Here we have the App Store, and, when the user goes to the Near Me tab and taps the Show Popular and Near Me link they're presented with this dialog saying the app would like to use their location to find relevant apps near them. Contrast this with a conga line of alerts that are presented to the user right when the application first opens, not a great user experience. Conga lines don't work because they're not presented at the correct time, so make sure you choose to present yours at the correct time.

The fourth principle is clarity. Clarity is distilling the purpose of your request down to its essence because it helps users build clear mental models about what you're going to do with their user data. You can think of this as improving the why, and when, and where. Give the user a guide of what they can expect from your application. Be concise, but include sufficient detail.

In this example, Reminders clearly states what its using Location for. The last and fifth principle is minimization, and this one's super simple because it's exactly what it sounds like. If you don't need access to that data, then you shouldn't ask. Scared users are more likely to tap Don't Allow.

All of the consent dialogs support a purpose string, and their use is highly encouraged because it makes what you're going to do with the user data, very transparent. All of the data classes support one purpose string, except for Location Services in iOS 8, which supports two, and we'll talk about that coming up.

You can set these purpose strings in your application's info.plist. And for those of you who localize your applications, you can set the localized versions in Localizeable.strings. What you need to do is you need to go to X code, select your target, select the info.plist, and then fill out the strings.

You should look for the privacy-data class keys. Now, X code is simply a front-end to the info.plist so, if you want to, you can always edit the info.plist manually. In this example we see we have a new application here that wants to access Camera and Microphone so that they can help you record that new music video for your album.

Now, there are several new purpose string keys on iOS, including Location, Camera, HealthKit, and Motion Activity. The reason Motion Activity is listed here is because it was announced after WWDC last year. You can always find the full list of purpose string keys in the Information Property List Key Reference located on the Apple Developer website.

When a user wants to go manage their privacy settings on iOS, they understand that they need to look in the Settings app, then Privacy, and then look for the data class that they want to manage. Similarly, on OS X, users will go to System Preferences, Security and Privacy, then Privacy. This is what Apple and developers have tried to communicate with users.

However, users may want to update their privacy settings from time to time. Perhaps your application came out with a new feature and they want to take advantage of it, or perhaps they've just simply changed their mind on one of their privacy settings. We're excited to give you a brand new ability today to send users directly to their privacy settings so that they can manage them. You can do that with UIApplication sharedApplication openURL and then pass it a URL with a string UIApplication OpenSettings URLString.

This is going to drop them directly into their settings bundle. For each application installed on iOS 8, the device will now have their own settings entries, as well as full privacy settings. Users can go to these settings and manage those settings. If your application already has a settings bundle, then these entries will be prepended to it so you don't have to worry about losing your settings.

All of the things that we've talked about so far form the principles for data isolation. For the developers who are new out there, data isolation is a technical design where the OS intervenes between an application and the user's data on behalf of the user. This occurs outside the address space of your process, however, it's completely transparent to your application. Just simply calling the existing APIs will help you gather consent and inform the user. If they decide to allow the application to access the data, you'll get data back. And, if they don't allow access, then you will receive nothing back.

There are several new data classes and updated data classes on iOS 8, including Location, Contacts, Camera (which is now worldwide), Motion Activity, and HealthKit. OS X Yosemite supports all the same data classes that it did in OS X Mavericks: Location, Contacts, Calendars, Reminders, and Social. However, there were no new additions or updates.

If you're already shipping an application on the App Store, that's great! This data isolation applies to your application from day-one. You don't have to recompile or resubmit your application to the App Store. However, certain changes can help you improve the user experience. For example, if you are accessing Camera, new this year we've added that to data isolation, so additional UI might be helpful to explain to the user why they're receiving a black screen, or essentially all zeroes in their video stream. Also, adding purpose strings can help clarify why you need access to this data. So, now that we know what data isolation is, let's briefly discuss what that looks like on OS X.

On OS X, when an application calls the purpose specific API, the OS will handle that request and present the dialog to the user. For example, if you call ABAddressBook sharedAddressBook ABPerson alloc init then that will call the system to pop up the dialog. On OS X the calls are synchronous. So, you're going to want to use Grand Central Dispatch and wrap the invocation in a block to keep the UI responsive while your user decides. After the user has made their initial decision, the APIs will return immediately.

As I said before, when the user makes their decision, if they decide to grant you access, then you will receive populated objects. And, if they decide not to allow access, then you will either receive nil objects or no objects. For applications that use system services, such as Spotlight or AppleScript, then the OS will still prompt on the user's behalf.

On OS X applications can participate in the app Sandbox, and if you ship on the Mac App Store then you are required to participate. For the new developers out there, the Sandbox is a security design that isolates your process from the other processes on the system, as well as the operating system. Applications that are Sandboxed typically have a tight set of restrictions that are imposed upon them. So, if you're going to Sandbox your application there's going to be more work that you'll have to do to get these consent dialogs to show up.

You'll need to add entitlements to your entitlements plist, which we'll talk about here in a second. An important note is that if the permissions ever change in the future while your application is running, the system will prompt the user of whether they want to terminate the app immediately or wait until its next launch to make the Sandbox consistent.

To add the entitlements to the application all you have to do is go to the entitlements plist or use Xcode to modify those entitlements. What you would do is you would go to the targets, My Application, Capabilities, turn on the App Sandbox, and then select the entitlements that you want. You should only build with the entitlements that you need.

If you're interested in learning more about the App Sandbox, there's a reference at the end of the talk to a practical guide to the App Sandbox that was presented in WWDC 2013. So now that we've talked about data isolation on OS X, let's talk a little bit about data isolation on iOS and contrast it to that.

On iOS, data isolation is obligatory because applications are built on top of the App Sandbox. However, you don't need to add entitlements to your application as you did in OS X. Also, access is asynchronous so API calls will return immediately, and then data would be returned via a block or a delegate call.

Unlike OS X, if the user decides to change the permissions of your application, then you will receive a SIGKILL signal immediately. There is no chance to wait or have the user decide at a later time. You need to be prepared to handle changes in permission status via change notifications and, honestly, this was a good idea anyway because the user can change their permissions at any time. There's multiple ways to trigger these data consent popups and all you have to do is simply call the API. There's four new APIs in iOS that will trigger these consents: Location, Photos, Camera, and HealthKit; and, we're going to go over some examples of that right now.

Location Services in iOS 8 now supports two different modes of updating device location: when in use and always. And the functionality that is provided in both sounds similar to how they're named. Also, depending on what targets you want to support with your binary, you may need to conditionalize your logic to call the appropriate methods.

When In Use is exactly what it sounds like. You're only able to access the devices location while the application is in the foreground. The API that you would call is CLLocationManager requestWhenIn UseAuthorization and the info.plist key that you would use is NSLocationWhen InUseUsage Description. This is a more privacy-friendly mode because applications cannot update location while they're in the background. Additionally, applications won't have access to functionalities such as Region Monitoring, the Significant Location Change API, or the Visits API.

Also, if your application implements the UI Capability's Background modes for Location, in their plist, then if you start updating Location in the foreground, and then serialize the application to the background, then the OS will implicate your application as using Location in the background by drawing a double height status bar. Here we can see that where Fitness is using our Location in the background.

Always Authorization is the second mode. Its API is CLLocationManager requestAlways Authorization and the info.plist key that you'll need to implement is NSLocationAlways UsageDescription. You should only try and use this mode when necessary because it has an increased privacy impact to the user, because applications can start accessing Location data in the background and the app has access to the significant Location Change APIs, the Visits APIs, as well as the Region Monitoring APIs.

The default mode for applications that are not updated to take advantage of these new APIs will be Always Authorization. And, if you use Always Authorization then the OS will occasionally re-prompt the user for access to Location. You should only use this mode if you think your users will thank you for doing so.

So, previously on iOS 7, you could implement this info.plist key, NSLocation UsageDescription. That's now deprecated. And, on iOS 8 there are two new purpose strings, NSLocationWhen InUseUsageDescription and NSLocationAlways UsageDescription. You must put one or two of these plist keys in your info.plist. Calling the APIs without these keys will not work.

If you want to target multiple operating systems in a single binary then you may need multiple keys. So, let's take a look at what a code example might look like for this. On iOS 7 you probably would have had some code that looks similar to this, CLLocationManager. You get a shared manager object, and then you call startUpdatingLocation.

This is what implicitly prompted the user for access to location. In iOS 8 we're changing that so that you explicitly request access to a user's Location by calling requestWhenIn UseAuthorization. In this example we see we're asking the Objective-C runtime, "Do you respond to the selector Request When in Use Authorization?" And if not, then we call the old way of doing it. Alternatively, you can also call requestWhenInUse or requestAlways Authorization. Note that if you fail a particular request, either Request Always or Request When in Use, you can't request the other mode; you're done. You can't prompt up or down, in terms of access rights.

So, we've talked a lot about Location, and the changes to Location, and what's new. Here are the important takeaway points. There's two new modes in iOS 8 versus iOS 7, and there's two new info.plist keys that you'll have to implement. While there is a bunch of implications to which modes you use, you should check out what's right for your application by going to see "What's New in Core Location" that was presented on Tuesday of this week.

The second example I would like to talk about is Camera. In iOS 8 Camera is a data isolated data class. Here, we create an ABCapture Session, and then we create an ABCaptureDevice, and simply calling the API AVCapture DeviceInput deviceInput WithDeviceError will present the dialog to the user. While the user decides, the video stream will be all zeroes, or essentially a black screen, so you need to be able to explain that to your user. Then below, you can either handle the failure or the success as you choose. The last code example I want to show is HealthKit.

On this code example, we're checking first to see if HealthKit data is available on this device. Then, we're allocinatting an HKHealthStore and asking for access to the heart rate type identifier. This is an important point because access to HealthKit data types is very, very granular. And you should only ask for access to the data classes that you're going to actively use.

What you would do then , s call requestAuthorization ToShareTypes completion to prompt the user. Now, you can't check to see whether or not the user gave you access to read or if there, in fact, is any data at all of that data type. That's part of the privacy design. So, the success variable in the block actually indicates whether the user was prompted or not, not what the response of the user was. If the request was not successful, then the error, the NS error, will be populated.

Writing is slightly different. You can check to see if you have authorization to write, and you do that by calling authorizationStatus ForDataType. This will return you back in authorization status, which you then can then conditionalize your logic on. Also, applications can only edit, or modify, or delete data that they have written, not other applications' data. So, you should check your authorization status first, and then if you need to, ask the user for permission.

Calling saveObject and deleteObject will modify those particular objects. So, we've talked about data isolation - what are the differences on the different platforms - and that's a lot of information. So, we need to be able to test it, and it's really easy to test. All you need to do is run your application.

You should already be testing on-device, however the simulator does support a lot of the data isolated classes. Note that apps can only trigger the prompt once, so if you need to go back and retrigger it, on the iOS, you need to go to Settings, General, Reset, Reset Location and Privacy, or, on OS X, use tccutil.

Consider all of the different test cases, and there's four of them: permission being sought and denied, permission being sought and granted, permission previously denied, and permission restricted. You might even want to consider building these in to your unit tests so that you don't ship any regressions. I'd like to talk a little bit about permission restricted, as that's a special, interesting case.

Restrictions can prevent your users from changing their privacy settings even if they want to. For example, enterprise restriction or on-device restrictions can prevent the user from changing their privacy settings. So, you should try to send users to Settings, but your code should be resilient to the lack of data returned.

The OS can help you fail gracefully. Some of the picker classes in iOS will actually show a lock page indicating the user has previously declined access to that data type, so you shouldn't design dialogs that say go flip the switch in the case that you're restricted because users may not actually be able to flip the switch. It's easy to test with restrictions. All you have to do is go to Settings, General Restrictions, and then choose the data type that you want to test restrictions with.

So, we have some great iOS sample code out there for you today. It's called "Checking and Requesting Access to Data Classes in Privacy Settings" and it's available on the iOS Developer Library. You can use it directly in your project or just download it and play with it. So, that's data isolation and prompting your users with purpose. I'm now going to give it back to Katie so she can take you through privacy best practices. Thank you.

[ Applause ]

Thanks, David. So now, I'm going to finish off talking about some things that you can do and apply in your application. I'm going to talk about transparency, data collection, avoiding fingerprinting, and how to protect your users' data. So, David talked about transparency already. He talked about in terms of consent and Just in Time alerts, but transparency is important even wider. This is all about insuring that your users understand what's happening to them and what's happening to their data.

Users should never be surprised if you explain to them how your code works or what's happening to their data. Think about what the user expectations are. This is what you should go back to and think about. What would users think is happening here? So, there's other ways that we can be transparent.

Logging is one of those places. For instance, both on iOS and OS X, if the user has selected to submit logs to Apple via Diagnostics and Usage the user can go and look at these. You can go in iOS under Settings, Privacy, Diagnostics and Usage, and look at all the logs that will be sent to Apple. You can also see them via the console on OS X.

Another example of this on OS X is for Crash Reports. You can then expand out and view the data that would be sent to Apple. I would also encourage you to think about his when you have a data store of user data. Figure out a way to visualize this data and let them see what information you're storing. Users like when they have the control to be able to see and understand what's happening.

Your Privacy Policy is another way that you can be transparent to users. It's a great tool. Your Privacy Policy should include: what data you collect, what you plan to do with that data, and if you plan to share it with any third parties, who they are. As a family's sharing, you may need to include a kid section of your Privacy Policy, as well.

There are four different areas this year where we are going to be requiring a Privacy Policy if you're taking advantage of this functionality. The first one is apps that link against HealthKit. Second, HomeKit. Third, third party keyboards. And lastly, if you want your app to show up in the kids' section of the app store, you will also require a Privacy Policy.

We make it easy to submit a link and you can do it right in iTunes Connect, and then this will be visible in all of the App Stores. So, here you can see in iTunes Connect, you probably know this page, it's where you write the description of what your app does, what it is, and at the bottom, here's where you add a link to your Privacy Policy.

Then, in the App Store - on the first page, if you scroll down - you can see, and users can go and click on, your Privacy Policy and go read it. Now this, users can see it and read it before they have downloaded this app, so it gives them the ability to understand what's happening before it happens to their data.

Next, I'm going to talk about data collection. So, data collection is a really powerful tool. It's great to understand where users are having problems, where they're running into issues or crashing, where users are spending the most time in your apps so you can expand more engineering resources there.

But, we believe that all data collection does have privacy impact, so you want a weigh the benefits against the risks. The thing that I work with teams and talk to teams about is think about the decision that you're trying to achieve, the decision you're trying to make with the data collection, and the question you're trying to answer.

That's where you should start with data collection. And, if you can't think of a question, you can't think of anything that you're going to do with the data, the best question is - because I think it sounds interesting, because I wondered - then that's a good sign that we shouldn't be collecting that amount of data, and that data.

So, we've all heard about, and heard in the industry about, breaches. And, one thing to think about is, unfortunately, if this happens to you, you want to be able to explain how you plan you use and have a clear explanation for all the data that you're storing. If you don't have a good explanation, and users want to understand, this will have more of an impact to your reputation and your company's reputation. Now, this is true both for applications and servers, so you shouldn't think of just this on the iOS or OS X side.

There are six data collection techniques on this slide. Now, last year we got into depth about them, we talked about and defined them, we gave examples on how to apply them. So, if you're interested in these, and they're great to use to protect your users' privacy when doing data collection, go and watch last year's talk.

And, these are great techniques to use to avoid fingerprinting. That's really one of their main uses. So, what is fingerprinting? I mean, we hear about fingerprinting, but what is it? This is when a large number of fairly static metrics are collected. A configuration, collecting configurations is a good example of this, and then they can be pieced together to form a fairly stable, semi-persistent fingerprint. So, then, any other data that is logged with this information is then associated to this device.

This can happen very easily, it can happen accidentally, and it can happen without collecting any personal information. You may think, "Well, there's no personal information in my logs, in my logging, so there's no privacy impact." This is not true. You should go back, look at what you're logging to see if you have accidentally been fingerprinting your users.

Now, I'm going to take us through an example that helps illustrate a little bit more about how easy fingerprinting can happen, and how accidentally. So, here we have an initial user population. All these dots, they're devices. So, first we're going to take all the devices that have OS X Yosemite installed, then have a certain screen resolution, a certain time zone, Pacific Standard Time.

Do they have Java installed? Are cookies enabled? A certain version of Flash? And, with a User-Agent string of Safari OS X Yosemite, we're down to a single device, Alice. So, this is where I encourage all of you to go and look at your data collection and think about if this is happening to you. And, this is where you can easily apply some of the data collection techniques. Maybe what you're doing, it doesn't really matter what screen resolution they have. Bucketing it into high, medium, and low maybe enough for your use, but it'll have more people fall into each bucket.

We all are creating way more data these days, and users are sharing it with us. So, you need to be mindful about how you're protecting all this data that users are entrusting you with. So, there are a bunch of different tools, in both iOS and OS X. And, we have provided a help and make it easier to protect your users' data. The first one is the keychain.

All application credentials should be stored in the keychain. Think about whether they need to be synchronized or if they can be stored only on a single device. Also, think about Touch ID, presence APIs, can you use this to help protect your users' data? All client-server communication should be encrypted.

Also, for the data you are storing on-disk, use data protection. This is great on iOS that we have different data protection classes so then you can pick out data that may be most sensitive and store it at the highest level. Now, we've talked about a bunch of different changes, new data classes for data isolation, but the thing I want to leave you with is a couple of things you can do and act on immediately. Make sure, if you don't have a device that's upgraded to iOS 8 or OS X Yosemite, that you do today. Test on them. Understand the impact this has to your users to ensure there's not going to be user impact upon launch.

Prompt users well, and this really means purpose strings. If you don't have purpose strings, go add them. Look into the new data classes, see if you can provide a great experience by taking advantage of the new classes. If you don't have a Privacy Policy link, go submit one to iTunes Connect. And lastly, think about privacy throughout the design process. And this will help you maintain your reputation and a strong relationship with your users.

Now, Paul is our Evangelist and he is a great resource, if you have any questions after today, to go and reach out to. Also, we have two pieces of great sample code projects. We have two sample code projects. The first one, privacy prompts: this is a help start for how to adopt data isolation, and especially great to look out for the new data isolation classes. Then, people picker: this is good to look at if you currently use the people picker, or are wanting to adopt it in iOS 8.

We talked about today a few best practices for maintaining your users' privacy, but there are a lot more. Go look at this documentation and see which other ones you can adopt. Also, there's always great information to be found at the Apple Developers' Forums. We mentioned several talks, the first one is "Kids and Apps". It's happening right here after ours and I would encourage you guys all to stay.

"What's New in Core Location", and "Keychain Authentication with Touch ID" already happened this week, but are great to go watch. And then from last year or previous years, "Protecting your User's Privacy", "Protecting User's Data", and "A Practical Guide to the App Sandbox". From David and I, thank you very much.

[ Applause ]