[ Applause ]
Welcome to Session 704, "Building Apps for Enterprise and Education."
My name is Dave Rahardja.
I'm a software developer in iOS, and today I'll be joined by Alex Botkin, who also works with me on iOS device management.
So building apps for the enterprise and for the education market really is not that much different from building apps in the App Store, right?
You've got to get an app that solves a problem.
You have to have an app that is well-designed.
And it's got to be a pleasure to use for the user.
But in an enterprise, you've got some unique requirements usually.
Your client's devices are very likely going to be managed under mobile device management.
These devices may be supervised.
And if you're not familiar with what supervised means, we'll talk about that in a minute.
And there may be special use cases that are kind of peculiar to the business and education market.
So today what I'm going to present to you is some tips and tricks to help you to write your next enterprise and education apps so that they're that much more pleasurable to use and makes you a much better developer in this field.
So let's get started by talking about mobile device management.
So what's mobile device management?
Mobile device management is a protocol that's built into iOS and OS X that allows a server to remotely manage that device.
A server that's managing a device using MDM can install network access such as VPN or Wi-Fi.
It can install accounts such as email, calendar contacts and so forth.
New in iOS 8, they can now install books such as PDFs, ePubs and iBooks Author as well as books from the iBookstore and manage them.
They can install single sign-on using Kerberos.
And new in iOS 8, Kerberos can now use an identity certificate so that their identity can be renewed without the user ever having to type in a password.
[ Applause ]
And most important to you today, an MDM server can install and configure your apps, so this is very important.
And here's your first tip for today.
Allow MDM to configure your apps.
And we'll talk about how that can be done exactly in a few minutes.
So mobile device management.
Let's talk a few minutes about managed apps and accounts.
So this is a little bit of a terminology that we have.
Anything that MDM installs on iOS, we call "managed".
These include everything that you saw from the last slide.
In iOS 8, as you know, you can install third party keyboard extensions.
The way you install third party keyboard extensions on iOS 8 is you install an app that has an extension in it.
If that app was installed using MDM, that keyboard extension is then considered as managed as well.
Of course in iOS 8 we have this great new feature called "document providers," thank you.
It's a really powerful feature.
And if you install an app that happens to vend a document provider extension, such as an app that gives access to your intranet resources, or you know, your network file storage, that app also becomes "managed."
So this is in contrast with things that the user installed themselves.
If the user goes out and installs an app from the App Store on their own BYOD device for example, those things are considered not managed.
So we have managed, which is the stuff that MDM installed.
And you have not managed, which is what the user installs.
So why do we do this?
Well it helps iOS to restrict data flow so that your enterprise data doesn't flow into your user's data space and vice versa.
So for example, if you are in a managed app and you are looking at a document and you tap open in - you know that list of apps that shows up on the bottom of your screen?
All the apps that can handle that document.
That list of apps will be filtered down so that, because you started from a managed app, only other managed apps and accounts will show up on that list.
And we do this automatically.
Conversely, when you are in an unmanaged app and you tap open in, the list of apps that you see will not include managed apps.
So in that way, without the user ever having to do any switching of, you know, work and home, we protect your data.
And we do this everywhere.
Emails. So you can't forward a corporate email using your iCloud account for example.
We do it in calendars.
We do it - in iOS 8 we have managed domains in Safari.
So if you specify certain domains in Safari as belonging to your corporate intranet, documents that you download from those domains will only go into managed apps.
[ Applause ]
And managed apps get access to Per-App VPN.
This is a feature we've had since iOS 7, and it's proven very popular.
And what this is, just as a review, is that managed apps will get the data tunneled through this VPN, but not anything else, not the user's data.
So your VPN carries your data and not the user's data.
Yet another way to separate enterprise and personal data.
So what's the takeaway?
Rely on iOS to manage the data flow between apps and accounts.
Don't try to do it yourself.
iOS has a great way of allowing this to happen in a very clean and intuitive way, using the fact that you're managing a device over MDM.
So that's MDM.
Next let's talk about supervised devices.
So what's this?
A supervised device is a device that has been activated into, you know, a supervision.
It tells iOS that the device is owned by the enterprise.
This is in contrast to a device that's owned by a user such as Bring Your Own Device.
Right? Supervision can only be set at activation.
There are two ways to set supervision during activation.
The first way, and you saw this in the keynote yesterday, is Device Enrollment Program.
With DEP, devices that your enterprise purchased from Apple can be configured so that they're supervised and enrolled into your MDM right out of the box.
You don't have to touch it at all.
You hand the shrink-wrapped box to the end user.
They unbox it.
They walk through the setup assistant.
And they're supervised and enrolled.
The second way is Apple Configurator, which requires you to take the device out and plug it into USB.
Depending on your use case and your scenarios, one of these should serve your needs.
So why do we supervise devices?
Well, I'll tell you why.
You get access to a whole bunch of different restrictions and controls that we only allow on enterprise-owned devices.
Such as Always-On VPN new in iOS 8.
Global HTTP proxy.
Third-party content filter, also new in iOS 8.
Single App Mode, which locks your device into a single app.
Perfect for kiosks.
And we'll see some examples of that later.
We've got restriction to prevent the user from erasing their own device anyone with students here?
And preventing enabling restrictions also students.
When you're local, you know, in your settings.
And many more.
The takeaway here is please supervise your enterprise-owned devices.
If you own it, supervise it.
You won't regret it.
OK. So for the next part of our presentation, we're going to show you some example apps that may illustrate some of the use cases that you may face when developing apps for the enterprise.
The first app we're going to show you is a Document Access app.
This app is designed to access a secure document, like a sensitive document maybe over your intranet, and store it on the device in a secure manner.
The second app that we're going to see is a Point of Sale app.
This may be something like you use in a retail store to check out customers, you know, buying your items.
And the third will be something that education may use, an Assessment app where the student uses your app to take exams.
All right, so three example apps.
Point of Sale.
And along the way, we will illustrate some of the things that we talked about earlier.
So let's start with the first app.
Okay, Secure Document Access.
Again, this app retrieves a document securely and displays it to the end user.
So let's talk a little bit about MDM App Configuration.
So you remember a few minutes ago I talked about allowing an MDM server to configure your apps.
Well how do you do this?
It's really very simple.
All you have to do is to watch for the special key in NSUserDefaults com.apple.configuration.managed.
When you read this key from your NSUserDefaults, you get a dictionary that magically appears when the MDM server pushes a configuration down to your app.
So the MDM server pushes down a dictionary, and you can access it using this key.
Your app can then respond to configuration changes.
So why do you want to do this?
Well what's the first thing that you want to do when you install an app?
You want to configure its URL probably, hit some server.
You may have an app that is deployed in more than one branch of your business, and you want to configure it for that particular location.
Instead of having the end user read instructions and say, "Oh tap this and tap that and go here and go there.
Type this URL in.
What could go wrong?"
You define your own keys and say, "Hey if you install my app over MDM, push down these keys and I'll see them and I'll use them for my app without any user intervention."
Right? So app configuration.
So URLs are great, so in this example we are going to do some URL configuration.
And a trusted list of server root certificates is also very important.
It helps you to prevent man-in-the-middle attacks.
And we'll show you how to do that in the code example.
I'm going to ask Alex to come up here.
And he's going to show you a little code example that demonstrates MDM App Configuration.
So, good morning developers.
So, we're going to switch over to our demo laptop.
We're going to look at some code.
So our first application that we're looking at today is our Secured Document Access App.
Which we've called "Secretive" in our example.
With MDM App Configuration, the most important thing that you need to do is to make sure that you register for the NSUserDefaultsDid ChangeNotification.
This is the notification that will be sent out when an MDM app configuration is pushed down to your device.
So you need to be listening to this notification, and then rereading the defaults when you receive it.
So in our example I have a ViewController.
When the ViewController loads, I'm going to register for this notification.
And every time I receive it, I'm going to call re-default values so that I can get my values back again.
And in this example, I'm going to load up re-default values as soon as I get the view up, so that I can get the first initial load.
So in my example here - so you remember that we talked about the com.apple.configuration.manage key?
This is the key in NSUserDefault where we're going to be stuffing the NSDictionary with your configuration.
And so you'll notice that I've suggested some other keys here.
And in my dictionary I'm going to have a key which has a string for my server URL.
Which is going to be the URL for the document I'm going to be retrieving.
And you'll also notice that I have a key for a server root certificate.
We'll get to this later in the presentation, but that's also why I'm going to be pushing down in this MDM App Configuration.
So you'll notice some re-defaults.
All I do is I call into NSUserDefaults.
I make sure I call into that configuration key.
And then from the dictionary I pull out the relevant information that I need, such as the server URL.
An important thing to note is do put error checking on this to make sure that you're not loading bad values.
And so now what we'll do is I'll switch over to the iPad and I'll push down an examp MDM App Configuration.
So you'll notice that I have my app over here called "Secretive."
And when I open it up, I don't have an MDM App Configuration here currently.
I've installed the managed app, but you know, right now I don't have my server URL.
So over on my MDM server, I've loaded up a command to send down the magical app configuration.
And so I'm going to send that notification down.
And you'll notice that when I receive the notification for NSUserDefaultsDidChange, I automatically started up a session and retrieved this document from the server URL that I was given.
So that is MDM App Configuration.
And we'll return to Dave.
[ Applause ]
It's like magic.
Your apps get configured correctly, without having your user do anything.
I hope you caught that little remark that Alex made.
"Please validate the input that you get from the server."
Because as far as you are concerned as an app writer, the server is an unknown network entity, and they're going to be pushing down keys that may be misformatted or of the wrong type.
So please validate the keys and make sure that you understand what they are.
Also publish what you understand so that the server admins can configure you correctly.
So that's MDM App Configuration.
Next. All right.
Let's talk about Single Sign-on.
Single sign-on is a Kerberos - we offer a Kerberos single sign-on on iOS that can be applied by the MDM server across the entire system.
So that once you log in, you will be logged in across several different apps when you're accessing the same network resource.
So using Single Sign-on couldn't be easier.
You just have to use HTTP or HTTPS.
Which most of you probably are.
If you use NSURLConnection, or NSURLSession, Kerberos Single Sign-on is free to you.
So here's the takeaway.
Don't do anything, and it works; it's great.
The MDM server will apply the configuration, and your apps will either get a 200 OK or a 401 Fail.
If it's a 200 OK, assume that the resource is available to you and just use it.
Of course your apps may provide alternate authentication, such as you know, HTTP Digest.
And Kerberos authentication will be attempted first.
And if that doesn't work, iOS will fall back to reporting an error to your app, and you get the chance to authenticate using a different scheme.
So don't do anything.
Here is something that we've gotten asked several times.
How do I download files securely all the way from my server down to the flash on iOS?
As you may or may not know, all files that you create from your app already get this protection level.
So just a recap, this means that the file is encrypted.
Unreadable after you restart your iOS device.
Once you enter your passcode, the device - the file is readable and it remains readable across device locks.
Until you restart the device again.
So what we want to do is we want to upgrade this file.
If you do nothing and you use, you know, just write a file to disk, this is what you're going to get.
But we want to upgrade that.
So we want to have the file be specified as data protection complete.
Which means that whenever you lock the device, the file becomes unreadable, cryptographically.
And the next time the user enters their passcode, the file becomes readable again etcetera.
So we're going to use NSURLSession data task to do this.
And as a little bonus here, so maybe this document is extra sensitive, you don't want this document to appear in your user's backup.
So iCloud backup or iTunes backup.
So we're going to show you how to mark files so that they don't get backed up.
All right, let's switch over back to Alex and he's going to show you some code to do this.
So back on our demo machine.
You'll notice that we have on our ViewController set it as implementing the delegates of NSURLSession and NSURLSessionData.
And the reason we've done this is we're going to use those delegate callbacks during our secure download.
So down here in SecureURLSession that I have set up here, I'm going to take that server URL that I pulled down from MDM App Configuration, and I going to create an NSURLSessionDataTask right here.
And you'll notice that I've left the completionHandler as a nil.
And the reason I've done this is by setting nil for the completionHandler, I will get the delegate callbacks for the data task.
And that's the most important thing for me.
So in URLSession DataTaskDid ReceiveResponse.
I'm going to get this call as soon as we make the connection, and I'm going to create a file where I'm going to download my strategic plan PDF.
And so you'll notice that I call NSFileManager defaultManager createFileAtPath contents and attributes.
And the attribute I'm going to pass into it is this NSFileProtectionKey.
And in that NSFileProtectionKey I'm going to specify that I want NSFile protection complete and less open.
What this means is that the file will be unreadable when the device is locked, unless the file is already open when the device locks.
So while I'm downloading I'm going to set the attribute to that.
And so the other important thing that we've mentioned already is that we want to turn off file backup.
And so what I'm going to do is I'm going to set onto the file URL a resource value.
The key I'm going to set it on is NSURLisExcluded fromBackupKey.
And this key will make it so that this file will not be backed up in iTunes or in iCloud.
And so we'll go on in URLSessionDataTask to receive data.
This delegate method is going to be called, every time I receive new data from my server.
And I'm just going to store it all into that file I created earlier.
And then at the very end in URLSession taskDidCompleteWithError.
I'm going to make sure there were no errors.
And if there were no errors I'm going to then change it so that the attribute for NSFileProtectionKey is changed to complete.
Because at this point I decided, you know, when the device locks, I want this file to be unreadable.
And that's pretty much it.
I would show you the demo, but we've already shown you that in MDM App Configurations.
So let's go back to Dave.
So Downloading to a Secure File.
Here's how you do it.
You create an NSURLSession.
Create a file, when the request begins, create a file with dataProtection CompleteUnlessOpen so that you can continue to write data to that file as you're downloading it, even if your device is locked.
When the file has completely downloaded, upgrade that protection to FileProtectionComplete.
And as you can tell, as you can see, there's an NSURLMethod you can call to set a bit that says don't backup this file to iTunes and iCloud.
Next. HTTPS Certificate Pinning.
We all know that HTTPS is a way for the client to tell whether it's talking to the correct server.
This only works if the certificate chain is trustworthy.
So one of the things that we usually do is we can specify for this connection that only these certificates are to be trusted and not any other certificate in your database that may otherwise be trusted, for example, Safari.
And to do this of course you need HTTPS.
You need to specify your trusted root certificates during HTTPS authentication.
And you do this to prevent man-in-the-middle attacks that pretend to be your server.
And here's the takeaway - use certificate pinning instead of doing things like SSID detection.
Especially in, you know, like retail scenarios.
A lot of people use SSIDs or some other kind of heuristic to tell whether or not they're talking to the correct server.
Instead of doing that, make sure you are talking to the correct server regardless of the environment that you're in.
To show you a short example of how we do certificate pinning, let's switch back to Alex and his code.
So you will remember that I mentioned that we had that root certificate key that I set.
So when I push down the MDM App Configuration, I push down the data for my server's root certificate.
Because I want to check to make sure that I'm not connecting to the wrong server, and verify that my users are connecting to the server I want them to.
So you will notice that I have here a method that I've implemented called URLSession didReceiveChallenge with completionHandler.
And this is going to be called when I try and connect to my HTTPS server.
And when I try and connect, I want to double check that the authentication method that was in the challenge's protection space is a NSURLAuthentication MethodServerTrust.
If so, I'm going to get the SecTrustRef from the server, which is in challenge.protection Space.serverTrust.
The next thing I'm going to do is I'm going to load up that root certificate that I got from MDM App Configuration.
In this example, I've already loaded that when I did the NSUserDefaultsReadback.
I put it into a variable called self - or into serverRootCertificateData.
So I'm going to load up that data.
And I'm going to create a SecCertificate with it.
And I want to double check that the certificate was created correctly by making sure that's not null.
If so, I'm going to then set the anchor certificates on the server's challenge trust that I got.
The reason I do this is I want to make sure that I only trust the root certificate I sent down.
I don't want to trust any of the default certificates that are included in the iOS device.
And by saying the root anchor certificates, I can exclude them.
You'll notice that I've called - also have this method SecTrustSetAnchor CertificatesOnly.
If I wanted to make it so that I also trust the default certificates installed on the device, I would set this yes value at the end to no.
If you are only setting it for the anchor certificates that you trust, you do not have to set this.
I've only done it in this example to show you how you can trust the device's certificates if you want to.
And so the last thing that I'm going to do is I'm going to do a SecTrustEvaluate with the serversChallengeTrust and I'm going to get a trust result.
From that trust result I'm going to make sure that, you know, I didn't receive any errors.
And make sure that the SecTrustResult is either unspecified or proceed.
And then if I find out that I do trust this certificate, or if I've turned off certificate pinning, I'm going to automatically just say, call the completionHandler with NSURLSessionAuth ChallengeUseCredential and give it the credential that the server gave me.
If I don't trust the certificate, I will call instead completionHandler NSURLSessionAuthChallengeReject ProtectionSpace.
And that will tell the app that no, I'm not going to allow you to download this.
So in our example, we'll go back to the iPad again.
You'll notice I've already downloaded this file.
In settings I've set up a pin here called certificate pinning, and I'm going to turn it on.
The next thing I'm going to do is - oop they already went through this, so let me just reset this.
So when I call into the app - yeah, so you'll notice, ignore the crash.
With this, when I called back into the app it tried to load up the document again from the server.
And you'll notice that it's telling me that my certificate pinned by the server - the certificate presented by the server is not the same as my pin certificate.
Let me go back to my server, and I'm going to change it so that it presents the right certificate.
So I've set up my server; I've fixed the certificate.
So I'm going to click on my refresh.
And when I refresh, the pin certificate was correct this time, and so I was able to load the document.
And so that is how you do certificate pinning.
[ Applause ]
HTTPS Certificate Pinning assures you that there's no man-in-the-middle attack with your connection to your trusted server.
So what have we learned from the first example app?
The Secure Document Viewer?
We learned that MDM App Configuration is awesome.
Server can configure your apps just right.
The user doesn't have to do it.
And you can offer keys to the server admin to configure, to set up your app just the way they'd like it.
By the way, app configuration can be delivered as you're installing the app.
There is no race between app installation and configuration.
We also learned that Single Sign-on is also awesome.
Because you don't have to do anything and it works.
All you have to do is use HTTP or HTTPS.
And if your admin has configured Single Sign-on on the device, then it will just work or you will get an auth failure.
We learned how to download files securely using NSURLSession DataTask and setting the correct protection level at different parts of the download as well as excluding from backup.
And, of course, we saw how to pin our HTTPS certificates.
So that's our first app.
All right, next app.
Point of sale.
For this example we're going to show you a little - maybe a device that a sales associate might carry.
So we have a scanner on the left-hand side here on the tab bar which will scan barcodes.
And we have a catalog that lets them look up prices for products, etcetera.
So the first thing I want to talk to you about is Single App Mode.
Single App Mode is a way that an MDM server can lock the device into just your app.
You can send a command down and tell the device just run this app.
If the app crashes, it relaunches the app.
If the user presses the Home button, this gets stuck in the app.
So that's all in Single App Mode.
We'll show that later in a later example.
But first, I'd like to talk about iBeacon.
So iBeacon is awesome.
It gives you context.
It tells your device, it tells your app that you're near something, right?
You're near something that you specify.
So you can use iBeacon to provide your app with context.
In this case, for the Point of Sale app, we want to provide the app the knowledge that you're actually using the barcode scanner near the checkout register, right?
So if you take the device elsewhere, they will not allow you to scan prices, to scan barcodes.
So using iBeacon in conjunction with other core location technologies such as, you know, GPS and location, gives you a really fine-grained control over how your app is used.
And it gives you an ability using MDM App Configuration to let the admins configure your apps so that your app can only be used in this particular retail store.
Or in that particular context.
Right? So here's a tip.
Use iBeacon to verify your location-sensitive operation.
So now I'm going to hand it off to Alex again, and he's going to show you a little example.
So for our point of sale app, I have a [inaudible] app called "Moolah," which is for selling baby clothes.
And so in my example, what I have is I have this app delegate.
In this app delegate I'm going to create a CLLocationManager object.
I'm going to set the app delegate as the delegate for the Location Manager.
The important thing for the iBeacon, where we're going to this method here of startMonitoringForRegisterBeacon is that what I need to do is I need to set up an NSUUID for the region that I want this to work in.
In my example, let's imagine in our point of sale example that we have - we want our people at the register to be, you know, in a general area.
We don't want them in the back room scanning things and selling things without the security cameras around them.
So for our region I'm going to create a UUID specified here, and I'm going to give an identifier of the app - so "Moolah" in this case.
And I'm going to create a CLBeaconRegion using the proximityUUID I created and the identifier.
I'm going to call on to the location manager to start monitoring for this region.
One of the important things that you need to make sure you implement is this method of locationManager didDetermineState forRegion.
This method will be called when your app is not - is in the background, so that your app can receive region notification changes.
So let's say, they closed my register app.
They walked out of the store.
And then they opened - walked out of the store.
You will receive this method callback when they leave the region.
And so in this example I'm just going to - I have it so that when you are inside the Beacon region, I want to start figuring out how far away they are from the iBeacon.
Because I want to make sure that my cashiers are right close to the beacon.
I don't want them, you know, all the way on the other side of the store.
So I'm going to start ranging the beacons in the region, and one of the things I'm going to do is I'm going to implement this method of locationManager didRangeBeacons inRegion.
And I'm just going to get the closest beacon, because I don't particularly care about which iBeacon they're close to, as long as they're close to one of them.
And I'm going to check the proximity and make sure that it's not far or unknown.
If it's not, I'm going to say that they're near the register.
Otherwise they're not near the register, and I set that variable appropriately.
One of the other things you're going to notice is I've also implemented the methods of locationManager didEnterRegion and locationManager didExitRegion.
Which will be called when the app is in the foreground.
For my example I'm going to go over to the trusty iPhone I have over here.
You'll notice I have my "Moolah" app here.
I'm going to open it up.
You'll notice right here I have my Scan Barcodes View.
You'll notice right now it's telling them to return to the register area because there's no iBeacon that it can currently detect.
So back here on my demo machines I'm going to start up an iBeacon.
And so you'll notice that as soon as it detected that the iBeacon - that I was within the region and that I was ranged correctly, I got this nice little barcode view, so I have a nice little camera.
My cashiers can just run through the barcodes and do that.
This view will only show up while I'm in the - near the iBeacon that's appropriate for it.
And so when I turn this off, eventually this app will receive a notification that I've left the region and that this view should probably be turned off.
And you'll notice that I also have a catalog section.
So you'll notice now that I've turned off the iBeacon that I am no longer near the register, and so the view is turned off.
And that is how you use iBeacons.
[ Applause ]
There's so much you can do with iBeacons that can provide a really awesome user experience.
Both for your admins and for the end users.
All right, next I'd like to talk about Network Reachability.
Network Reachability is a set of APIs that lets you know whether a server is reachable at all on the network.
And best of all, it actually tells you when the server becomes reachable or becomes unreachable.
So for the following example I want you to note you can use Network Reachability to provide intelligent, offline behavior.
So back to Alex, and he's going to show you how that's done.
So back in our "Moolah" app, I have this method.
So I created an SCNetworkReachabiltyFlags.
And I'm going to create a reachability reference.
Which I do by SCNetworkReachability CreateWithName.
And the name I'm going to pass into here is a domain.
So in my example up above, I have defined apple.com as the domain I want to watch for and see the reachability of.
So once I do that, if the reachability is null, I can call SCNetworkReachabilityGetFlags.
Then once I do that I can check the flags, and I'm going to check that SCNetworkReachabilityFlags is reachable.
And using that flag I'll know when I cannot send a network operations because the user is in airplane mode for example.
Now this is nice and good, but this is just one off method.
I don't want to be calling this all the time.
So what I really want to do is I want to register this so that every time the reachability configuration changes, I get notified.
And so what I've done down here is I've created an SCNetworkReachabilityContext, which I'm feeding in the nice little block that I've created to check the flags.
If the flags say that it's not reachable, I'm going to set my offline variable appropriately.
And what I'm going to do is I'm going to is I'm going to call SCNetworkReachability SetCallback.
I'm going to feed it the reachability.
And I have to give it this method, reachability change, which is written in C.
The reason I put earlier in that context that info with that call block is I want to keep all my code in Objective-C.
So all I'm going to have my C method reachabilityChanged do up here is I'm just going to have it call that block that I feed into the info.
So that I don't have to mess around with C code that much.
With the SCNetworkReachability I set the callback.
I set the C method that I'm calling into in the context.
And the next thing I need to do is I need to make sure I schedule this so that this gets called every once in a while.
The way I do that is I call SCNetworkReachability SetDispatchQueue.
I give it the reachability reference I've created.
And I'm going to call this on the main queue in my example.
You can do this on other queues.
I've chosen this just for simplicity.
So now, if we return to my iPhone example, you're going to notice I have this nice little catalog of baby clothes that I can buy.
What I want to do is I'm just going to switch the app into airplane mode.
When I switch it off you're going to notice that SCNetworkReachability has changed my label to inform the user that they are currently offline.
And so you can use this to gate behavior that you don't want users to do while they're offline, like try and edit a document that you want to sync up between multiple users.
And so that's SCNetwork Reachability.
Well thanks Alex.
Network Reachability allows you to provide intelligent, offline behavior without having to send a request and timing out and things like that.
You know up front that the network, or your particular server actually is not reachable and you can take the appropriate action.
So in summary, our second app example shows us that you can put an app into Single App Mode using MDM, again example to follow.
You can use iBeacon to provide context for your app and change your app's behavior, depending on whether it's near something.
You can use this with core location to allow your admins to really configure your apps to a very fine grain.
And finally, network reachability allows you to behave intelligently when a server is not available.
Let's talk about our third and final app example, Assessment.
So this is your typical exam-taking app.
There are several modes of operation here for exams.
For our example the flow that we want to show you is a student operating on an iPad, taking an exam.
And we're going to download the exam packet from a document provider from your school's file system.
Once the user begins taking the exam, the exam app will lock them in and they'll take the exam and they'll submit it.
And the students will be allowed to use the iPad again.
So let's start with Document Providers.
So document Providers, as I mentioned before, is a really awesome, new feature of iOS 8.
It allows you to exchange documents between apps.
When you install an app as a document provider, you are actually installing network access for other apps.
To access Document Providers, use the UIDocumentPickerViewController.
This is the same one you use for iCloud Doc folder.
Use Document Providers to get access to enterprise network resources.
Don't build in network protocols into your app.
Instead, rely on the admin to configure network access apps that allows your app to access those network resources.
So let's go back to Alex and he's going to show you a little bit of an example.
So you'll notice that I have an application, which I've called "Pencils Down."
What Pencils Down is going to do is that when the user starts the test, I want them to go into their high school's document app, and I want them to retrieve the test.
And then I'm going to proctor the exam on behalf of the high school.
So in this example, when I do start tests, I have this UIDocumentPickerViewController.
And I'm going to create one in initWithDocumentTypes that I'm going to allow.
In this case I'm going to choose HTML, Tacs [phonetic] and RTF.
I'm going to set the mode.
In this case I'm going to use UIDocumentPickerModeImport.
Because I want to get the file and keep it in my app bundle.
The other thing I'm going to do is I'm going to set the delegate on the UIDocumentPickerViewController to myself.
And I'm going to present that ViewController to the user.
Now when they go into that document pick, I can get two different callbacks.
If, for example, they fail to pick something, they click done they don't find the test file that they want, I'm going to get this documentPicker WasCancelled callback.
And in this case I'm just going to send a notification on the console that "Hey, I couldn't find the document."
If, for example, they actually did pick a document, I will call this documentPicker didPickDocumentAtURL will get called by the system.
What I'll do is I will double check that there's a natural URL and then I'm going to open up the document.
And if I am successful in opening up the document, I am going to request Single App Mode and load up the test for them.
If we go over to the simulator, we have our example here.
So I have "Pencils Down."
I go into my app.
You notice I have this nice little testing view.
I'm going to click start test, because I want to start a test with - that my high school has given me.
So I go into locations.
And you'll notice that I have this MHS Doc which is a Document Provider.
I'm going to go into here, and you'll notice that it has this view.
This view is actually coming from the MHS Docs App that I have installed in the simulator.
This view is not created by your app.
And so in this case if I wanted to, I could log in.
MHS Docs would check my credentials; make sure I'm actually a high school student.
So I'm just going to log in with some blank credentials, and I'm going to select my programming test that I need to do.
And so you'll notice that once I selected it, my app got that document back, and I loaded it up into my nice little web views, and started the test.
And so that's how Document Providers work.
[ Applause ]
Document Providers are very powerful, but they're very easy to use as you can tell.
Next, let's talk about Autonomous Single App Mode.
We've mentioned before that MDM can put your device into Single App Mode.
Which means that it will only run one app.
But in the case of this exam app, we want the app to be able to put itself into Single App Mode.
So this mode of operation is called Autonomous Single App Mode.
Your app has to be preauthorized by the MDM Server to do this.
This can only be done on a supervised device.
But once that's in place, your app can offer itself and say "Hey, I want control of the iPad for now."
So use Autonomous Single App Mode to lock the user into your app.
But please do it sparingly because the user will get stuck in your app if you don't get them out.
Your app will crash and restart, crash and restart.
And the user will not get out of it.
So please be careful when you do this.
But it is a really powerful feature.
So Alex is going to demonstrate how you can do this.
So we're back to my "Pencils Down" application.
You're going to notice that here I have this requestSingleAppMode method that I've created.
What I'm going to call into is UIAccessibilityRequest GuidedAccessSession.
This is the method that will start up Single App Mode.
What I do is I feed it a Boolean of whether I want Single App Mode on or off.
The other thing I'll feed into it is a completion block which is void BOOL didSucceed.
This Boolean that I get will tell me if I was able to successfully enter or exit Single App Mode, depending on which mode I set in the other Boolean.
It's very important to balance your calls.
Because as we mentioned, you will lock the user into your app if you don't call back into this to turn off Single App Mode as well.
Another important point is to make sure that you register for the UIAccessibilityGuidedAccess StatusDidChangeNotification.
This notification will be sent out when Single App Mode changes.
And so what I've done is I've created a little method called GuidedAccess DidChange Notification.
When I receive that notification, I am just going to update my Single App Mode - what is it?
State. So you'll notice here I have GuidedAccess StatusChanged.
And I said, you know, I am in Single App Mode if I receive this notification.
And so we'll move over to our iPad.
On this iPad is a supervised device I've already set up.
I've also pushed down an MDM profile that defined that "Pencils Down," giving its bundle ID is allowed to start Single App Mode autonomously.
So if I go into "Pencils Down."
I'm going to start my tests.
I'm going to skip over the file provider section for now.
You'll notice that I am now in my test.
If I try and exit the app by pressing the Home button, nothing happens.
I'm locked into here.
Let's say I don't know any of these questions so I'm just going to submit the test.
And the test was successfully submitted.
And so you'll now notice if I press the Home button I'm able to exit because I balanced the calls.
[ Applause ]
Autonomous Single App Mode.
Use it sparingly.
Make sure the user can get out of it eventually.
Okay. Summary of the third app.
New feature in iOS 8.
Use it to gain access to network resources in your enterprise.
Add an app equals at network access.
Autonomous Single App Mode.
Allows you to lock your own app into Single App Mode so the user cannot go to a different app.
So what have we learned today?
We learned that we should assume that MDM will be used to manage your apps and devices.
When you're writing apps for business and education, assume MDM's going to be there and is going to configure the environment for your app.
You can safely assume that enterprise owned devices will be supervised.
So check out the list of features that are available to you when the device is supervised and use them.
On the other hand, if you're writing for Bring Your Own Device environment, you can assume that the devices will not be supervised.
So if your app is going to work in both environments, be aware of the features that are available in each case.
And finally, rely on iOS to provide a great set of systemwide features that your apps can leverage.
VPN. Global Proxy.
Manage data flow between the managed apps and the unmanaged apps and accounts.
Single App Mode.
Both MDM driven and autonomous.
iBeacon and Core Location for context.
All right, finally I want to call your attention to a great new portal that we've just put online, developer.apple.com/enterprise, made for developers just like you.
[ Applause ]
For more information, our Evangelist is Paul Danbold.
There's that enterprise portal again.
You will find most of what you need in there.
And of course the developer forums is a great resource.
Some related sessions.
This morning we had "Managing Apple Devices."
Please check out that video.
We have "Distributing Enterprise Apps" right here, following this session.
And if you're interested in digging into Doc Providers - Document Providers - "Building a Document-Based App" is a must-attend.
Thank you very much.
[ Applause ]