2008 • 1:16:44
iPhone 2.0 and the iPhone SDK provide in-house developers a compelling platform for the creation and deployment of mission critical business applications. Come learn the networking, security and web services frameworks most relevant to an in-house developer and tips and techniques useful for creating web and native applications that leverage existing IT resources.
Speaker: Mark Malone
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Again, my name is Mark Malone. My email is down at the bottom of this presentation, so please capture it and send me email all about the incredibly exciting internal applications that you guys are building, workflow apps, all sorts of things. I'm always interested in internal implementations. The app store has got plenty of things on it, but I think the in-house applications are the ones that are really exciting. So let me know how we're doing and how you're doing with how you're deploying applications. Mark Malone So I'm going to take a bit of a romp through the SDK and it's basically my swag based on what I think in-house application developers are interested in doing.
I used to do a lot of development within large organizations before I came to work at Apple, which is a large organization as well. So I figure I kind of know my way through here and you can always tell me that I'm wrong. Here's basically the list that I came up with.
So a little bit on architecture, development, and then I'm going to talk a little bit about the application itself. Here's a little bit on architecture, development, and then I'm going to talk a little bit about the application itself. Here's a little bit on architecture, development, and then I'm going to talk a little bit about the application itself. bit on architecture. Development platforms, there are two for iPhone. Displaying web content, in-house applications typically show web content. We love the browser. We love the deployment mechanism. We've got all these existing assets already that we display within web browsers on the desktop.
Calling a web service, sort of stepping back from the presentation piece. Talk a little bit about web services support on iPhone. Parsing XML, if I'm calling web services then XML matters to me. If I've got a native application, how do I write data locally? What are the formats that I can use to go and write it in the classes? Security services associated with iPhone SDK based applications, so where can I store passwords and certificates, those kinds of things. Where do I store it? How do I write it? And then finally deploying iPhone applications, so sort of soup to nuts.
Sound good? Yay, all Let's go on, let's begin with architecture, so I can't have a decent presentation without talking a little bit about the architecture of iPhone, especially since it carries over so much from the desktop environment of Mac OS X. So at the baseline, we've got a standard Unix kernel, something that's been tuned so that it works well on these mobile devices.
And so what you get with Unix is you get stability, something that's highly tested, you also get a lot of POSIX compliant capability that you can actually leverage within your application. On top of that, we create a stack called core frameworks. The core frameworks are our typical data types that we support in native applications. There are CF network code, those things at a low level that you're probably familiar with already if you've ever built anything for a machine or a device running Mac OS X.
On top of that, we've provided a stack that's great at displaying. Playing media content, rich media, so animated graphics, OpenGL, core animation, those kinds of things that folks are used to seeing on our desktop, playing back video, stereo audio, recording audio as well, nice rich media stack at that level. On top of that, we've got the Cocoa Touch frameworks. These are the classes that you're going to use to provide user interface, interaction between your application logic and the user who is actually tapping on the screen.
So, you're tapping around, interacting with your application. So that's all within the Cocoa Touch layer. And then in comes your application and sits on top of it. So although I've presented it as a typical stacked architecture, the reality is an application can reach down to just about any place that it wants to within the frameworks as long as they're publicly exposed APIs to get to those. So if you want to open a BSD socket, go to town, you can do that.
You can use the high level networking classes as well. But if you're more comfortable down at the Unix level, there's a lot of functionality that you get just through the SDK. So your application sits on top and it sits in sort of a sandbox. A lot of folks are familiar with web-based sandboxes and the Safari on iPhone lives in its own sandbox as well. So it can pull content from a particular domain. It can write cookies. But it doesn't have willy-nilly access to the file system.
It can't go and read and upload files. So it's a very sort of user interaction based model. And a lot of folks are used to this when they're doing browser-based applications. Same sort of implementation on iPhone. If you're building an application that runs within the Safari browser, it sits in a sandbox.
Now it can access the various applications or some of the various applications on iPhone. And the way that it does it is through web APIs. So I can go and I can launch a mail, a blank mail message, have it pre-filled with a file, with the to, the body, the subject, those kinds of things.
Just based on within my web content having a mail to URL within the web content. Same thing with the phone. If I want to go and present a phone number to the user for them to dial, I can have a tell URL within my web content. So you see we've got this sort of web API layer there that you as a web developer need to go through in order to access those things outside of your sandbox. And it's very much like the desktop model. There's a lot of information. There's a lot of integration you've got on the desktop through these same sort of APIs.
[Transcript missing]
So those are development platforms. Let's talk a little bit while we're on this web rant about displaying web content. So just at the baseline, if you've got an in-house application that looks great in Safari and iPhone, then odds are great that it's going to look... Sorry, looks great in Safari on the desktop, odds are great that it's going to look great in Safari and iPhone. We've done our best to try to take you out of the loop when it comes to making the content look good on iPhone. So without a lot of tweaking on the back end, it should display fine.
It should be interactive. It should have all the capability that it had before. There are obviously some caveats. Gesundheit. So deploying an application via the browser, what do you get on iPhone? You get the same sort of compatibility that you would expect with Safari on Mac, Safari on Windows. Same sort of desktop capability, but in a portable platform.
We think we've got the best implementation of the W3C standards. So if you care about a standards-based implementation of DOM or CSS, or ECMAScript, then we think we've got one of the best implementations and we love to gather bugs about where we might be off-base in this statement that we think we're the best.
So we've got a great implementation there for standards, but we also know that there's a web reality out there. There's a myriad of websites that perhaps you created within your organization or that folks get to, your users get to, just through trolling the web that weren't built with standards in mind.
They were code-generated for IE only, or it was code-generated for IE only, or it was code-generated for Netscape, or it was generated out of some sort of server, or, you know what, it was published just because it worked in IE, and that's fine. So the browser is full of all sorts of optimization technology that we go through in order to make sure that we don't necessarily stumble over content that's not standards-based.
So the caveat is, the biggest caveat is there's no plug-in support. So perhaps you've got Flash on your internal app, perhaps you've got Java applets. Maybe you've got content in some sort of MIME type that requires a plug-in, perhaps Windows Media or something like that. Then we're not gonna support that. So we support standards code, we support HTML, we support pretty much the web reality from a pretty grand perspective.
But when it comes to plug-in support, we don't have a plug-in model in the browser on iPhone like we do on the desktop. So that's sort of the number one thing that you need to do if you're migrating an app from the desktop browser to iPhone, is make sure that there aren't any plug-ins in there.
So what do you get that's new and sexy? Well, CSS visual effects. I mentioned that that capability was there on iPhone as sort of a nice partner to core animation for a native-based application. And it's just pure CSS syntax for doing animation on screen. So transformations, moving objects around on a page with only using CSS, no JavaScript necessary. A lot of folks wrote iPhone applications based on web technology and used JavaScript in order to be moving divs around.
within a page, very clunky. The CSS stuff is just incredibly fast, tuned for the device, and pretty darned groundbreaking as well. So transforms, we've got support for transitions. So again, pure web interface, but it's got the same sort of transition speed capability that you would expect from a native application. Animation as well, here's a web template that's in Dashcode that does that same rotation that you would see in the stocks widget, or in the weather widget.
You get that same capability just by using CSS animation. Or you can come up with something that's completely out of the box. You can mix and match these technologies to create an experience that's still pure web-based, but something that your users would never think this is a web-based application, just by using a combination of these. So the CSS visual effects are incredible. I mentioned they're hardware accelerated because you definitely want to use this if you've got any sort of animation that you're providing within your web-based interface. And that the JavaScript way of sliding in divs is definitely the clunky way to go.
Public specification for the CSS visual effects is available via webkit.org. Webkit.org is the open source repository of the engine underneath Safari on iPhone as well as Safari on all the other platforms that you see Safari. So you can go and check out the specifications there. Our goal is to push CSS visual effects to be part of the CSS3 specification. We want to make sure that other user agent vendors besides us are pushing this technology. So we're definitely keen to make sure Firefox as well as IE implement these. And as a result, the specs are out there in the public.
[Transcript missing]
Loading code from the application bundle just as easy. The key here is you need to find a path down to your application bundle. Your application bundle is basically that folder of data, your resources folder that you added to your native application. You need to build a path to that and then based on that path you can load it into the view as well. So here I'm grabbing the main bundle.
I'm building a path to a directory. My web route that I just dragged into my resources directory, I called it local hostess. Within local hostess is an index.html file. That's the file I want to go and load into my web view. So here's the full path that you get as a result of that call. You can see that you definitely don't want to go and hard code any of these paths. There's a unique application signature there but you can see it all resolves down to that index.html. Throw that into an NSURL.
Create a request, tell the web view to go and load the request, boom. All that content, just like the web route was sitting on the server, is now loaded from within my native application bundle. I can do the same thing from the file system, the path just points to a file system URL instead of an application bundle.
So let's talk a little bit about that interaction between the UI web view and native back and forth. So if I want to execute JavaScript from native code, within my native application I want to have something happen within the UI web view. There's some JavaScript functions that are sitting in there.
All I need to do is create a string that contains that JavaScript function that I want to call. So again, build up an NSString. Here I'm going to tell my UI web view to display a common JavaScript alert to the user. So I'm saying window.alert, throwing some text in there to present to the user.
And then I call the UI WebView method passing that string. And there's a long function name here, string by evaluating JavaScript from string. Just pass in that string. And as a result, that alert's going to be presented within the context of the web content being displayed. Really straightforward. I can have any sort of get element by ID call.
I could say window.location.href equals, tell it to navigate. Any of that JavaScript that you're used to calling within the context of the web page, you can build up a string of that and call it just like that. Just by passing it through this particular native function to the view itself.
Key is to only inspect the DOM after the web view is loaded. So I mentioned that there's this web view did finish load delegate that's called after the UI web view is completely loaded. Once it's completely loaded then the DOM is fully intact. You can make any sorts of calls that you want to the content that's sitting in there.
Until this particular method is called, you don't want to call any JavaScript because it's not fully there yet and so you might not get the results that you were expecting. So only call it after it's been loaded. Now let's go the other way. Let's go and call into native based on the user doing something within the context of UI web view.
So the way that we do that is we take advantage of the fact that we've got a delegate within the UI web view that gets called every time UI web view has been asked to load content. So if I tell a UI web view to go and load content from the web, this particular delegate function is called and it should start load with request. So my web view is being asked to load content from the web.
So I'm going to call it every time UI web view has been asked to load content. So if I tell a UI web view to go and load content from the web, this particular delegate function is called and it should start load with request. So my web view is being asked to load content from the web.
So I'm going to call it after the user doing something within the context of UI web view has been asked to load content. So the way that we do that is we take advantage of the fact that this thing is being called every single time and trick it to call our own scheme, our own destination.
So instead of having content like a link or a button within my web context that calls, that points to HTTP colon my function up in the cloud, I would call it every single time. So I would come up with my own scheme and it would be like my app colon slash slash and then a whole chunk of data. So I know that my should start load request is going to get called.
Based on any sort of navigation, so here's a little snippet. I've got a button element that's sitting within a piece of web content and a JavaScript function and an unclick handler there. My delegate gets called any time that UI WebView is asked to go somewhere to load a request.
So I say window.location which tells the view to go and load some content and instead of having it point to the public web, I use my own scheme. So I put my app colon and then some raw data there. That's the data that I want to pass from the web context down into the native context.
So as a result of that particular function getting called, I can look at the scheme and if it's a scheme that I own, it's something that I wanted to trigger from my web context, I can grab it and do something interesting. If it's an HTTP scheme or it's something that I know the browser just knows how to handle, then I can just let the browser handle it. I can just let it pass through and not grab it.
So that's the mechanism for communicating between the two. We've got a class on the desktop, Mac OS X desktop called WebKit. UI WebView is quite a bit different from WebKit even though there's overlap from some of the API perspectives. You definitely don't want to leave here thinking that there's an equivalent API to WebKit on iPhone. The web views are significantly different. So a web view is significantly different from a UI web view. But this little mechanism, this little trickery allows you to talk from one to the other.
All right, so that's displaying web content, all the different document types we support, the standards-based content as well as some manipulation between the two different architectures. Let's talk a little bit about calling web services. There's two standards that I certainly know about. One is SOAP and the other one is REST. So I'm gonna talk a little bit about each one of them. I'm gonna talk less about one and you can probably guess which one I'm gonna talk less about. Let's start with it. It's called SOAP.
Folks that aren't used to seeing any sort of SOAP APIs or even know what I'm talking about, I've got a little diagram. It's basically a client server call, right? You've got the client, that's the iPhone. Most SOAP calls are a post. SOAP calls are a post because of the envelope associated with the SOAP method. So client, be it iPhone or whatever, creates an XML envelope, makes an HTTP post to a service. The server then responds with a SOAP envelope that's got the XML content within it. And this is what a typical SOAP request looks like.
It's got HTTP headers associated with it. It's got this thing called the SOAP envelope that sits around the particular call. And then lo and behold, in the middle here is this little piece of functionality. This is the actual data that we're sending back and forth to the server. That's got basically the unique characteristics of this call.
SOAP's a really nice technology because it allows an abstraction. It's sort of like Corba for the web. From my perspective, it provides a nice abstraction between various interfaces. That's a SOAP request. This is what a SOAP response looks like. Again, typical HTV headers that you would expect. Again, the SOAP envelope.
And then in the middle there is the result of that particular function call that I made. So a lot of folks think that SOAP is something that's a little overly verbose. There is a lot of content here, but you do get some nice retrospection capability and other things out of using SOAP.
So what do we have on the iPhone? Well, anybody that's used to building Macintosh applications will see that we've got a huge web services star set of frameworks and such on the desktop. None of that stuff is over on the iPhone. So from a SOAP perspective, you can either build and parse SOAP manually using the XML classes that we've got. But there's also some interesting third party libraries out there that you might wanna take a look at. The first one is GSOAP out of Florida State University, and the second one is Access2 from the Apache Foundation.
So both of these are great libraries for making SOAP calls. Access2 is particularly useful if you love WSDL. So if you love WSDL, then Access2 supports it. GSOAP does not, but both of them work fine for making SOAP based calls on iPhone. Compile them into your application. Both have generous legal agreements so that it's easy for you to distribute it without begging for permission out of these guys. So this is the SOAP implementation that you can use if you've got SOAP within your environment.
If you're using a RESTful type of application, you can use RESTful technology, something on the back end that's more RESTful. Well, you've got the same sort of client server model where you're making these web services calls. However, RESTful calls are typically GETs, right? A little less heavy. And the responses are XML, right? There isn't a SOAP envelope going in either direction. It's really up to the user to define what those interfaces are.
So still client server. This is a typical RESTful request, right? It's a URL. It's got the destination. It's got the object. It's got the method name. And it's got any parameters just sitting right on it. That's why it's typically a GET request. So this is a RESTful request, RESTful responses. Sky's the limit, right? It's up to the server to define what kind of XML comes back so it's all sorts of content, right? There isn't a defined DTD like there is in the SOAP world for these kinds of transactions. So this is an HTTP response.
So there's three core networking classes that you're going to use to make these kinds of calls on iPhones. On iPhone. You're going to use them all over the place. The first one, NSURL, I already mentioned, you're going to use that for loading content into a UI web view. Anytime you want to go and access any sort of web service, you're going to use the same high-level class to go and reference a service that's sitting in the cloud.
As I showed for the UI web view example, it supports file-based, so something sitting locally as well as cloud-based URLs. And it's really a nice class to use even though it just basically holds a string because you can go and dissect the parts of a URL. So if you want to ask a URL object for its port or for its path, its query string, all sorts of things, you've got high-level access there. Most of our classes, our networking classes require an NSURL object as one of the parameters. Second, one that you're going to use most often is NSURL request. That's encapsulating the payload of a request. Typically, a GET request is what you would get if you're using NSURL request.
If you want to do a post to a RESTful service, then you're going to use NSMutable URL request. When you're using the Mutable URL request, you've got access to all the parts of the body. So you can put in your own headers. You can set the body if you'd like. So you can set the body if you'd like. You can do multi-part uploads if you're doing basic form completion. You can embed your own cookies within the posts, all sorts of things. This is the class that you would use.
One nice thing about it is it gives you great control over locally cached content. So you can create an issue or a request and you can provide arguments to it that indicate whether it's okay or not to use content that was previously fetched from the same destination. And there's a shared cookie store.
So any cookies that I may have retrieved through a session interaction over on the Safari browser side are available to me within a native application where I'm using these classes. So as long as the cookies came from the same domain, once I'm over in a native application, those cookies are going to be posted with each one of the posts to that same domain when I'm using these native classes.
So it allows you to build something where you can share session information, all sorts of things, just by jumping between the two. Final class that you're going to use is NSURL connection. And this does the management of the communication with the back end. It's that final piece when it's time to go and send that request up to the server.
So it supports synchronous as well as asynchronous loading of content. So you could block your user interface, you can block your thread while you're going and pulling down data if you want to do that. You probably shouldn't. There's a slew of callbacks associated with redirects, which is nice, especially if you're building an application that you want to be secure. If you tell your application to point to somewhere in the cloud and the cloud says, no, you know what, the data's really over here.
It'd be nice to know within your application that somebody's telling you to go somewhere other than where the data really does reside. So this particular class has a callback associated with it where it will say to your application, hey, you know, the server says you should go over here for the content. You've got the capability to look at that URL and say, no, I don't want to go to this particular site anymore. Something's been breached. There's a man in the middle or something going on here.
There's also callbacks for authentication challenges. We'll handle all the sort of standard authentication challenges that occur. So if there's a certificate sitting on a server through which you're trying to talk to a particular web servers and that certificate we have a route within our search store, we'll take care of that authentication challenge. That's already handled.
But if we hit a challenge, there's a server up there that we can't validate or somebody on the server side is trying to authenticate through another mechanism. We've got a callback there. We'll call back to your application and say, okay, there's a challenge here. We don't know how to handle.
How do you want to go? And so people take advantage of those callbacks in order to go and implement their own authentication mechanisms within their network. And so that's something that we're trying to do in our native application. The final piece within NSURL connection is you've got even more granular control over caching capabilities.
So there's a final class that I talk about but is not available, you shouldn't use. It's called NSURL download. It's actually in the documentation. It works in the simulator but once you move your code over to the iPhone itself or an iPod touch, it doesn't work. So it's fairly useful except it does something that we don't want a lot of users doing and that's writing to disk. This particular class, all you do is you point it to a URL in the cloud and you get a file as a result of it.
We want to try to make it a little bit harder, a little more intentional for people writing to flash-based memory on these devices. So those are the three primary classes and the one not to use. A little graphic here for calling a particular web service in the cloud.
The call is going to be made based on my native application. Within my native application, I've created my own class called My Data Grabber. This is the guy that's going to be in charge of talking to the data grabber and he's going to be talking to my web service up there in the cloud. So I instantiate my data grabber.
First thing I'm going to do to go and talk to my service in the cloud is create this NSURL object, right? It contains a string that points to my web service. Next thing I'm going to do is create an NSURL request passing in that URL as one of the arguments.
And then the third step is to create this NSURL connection object and pass it the request object in. And I'm going to pass in a reference to my class because my class is going to want to hear about interesting things that are happening with this particular communication to the server. So once I go and I call this particular method with this NSURL connection instantiation, a call is made up to the server pointing to that particular URL that was provided. The get goes up and then the data comes back down from the server.
Something to keep in mind is that the data is not necessarily going to come back in one fell swoop. It might be packed up by the server and sent in a, in a bulk. And each time we get a chunk of data from the user, this particular method is going to get called on the delegate, the listener that cares about this communication.
It's going to call did receive data. Data is going to be passed as an argument. It's going to get called each time I get a buffer of data from the server. So you're going to want to go and concatenate that data structure up within your native application until the transaction is complete. And the way that you know the transaction is complete is connect to the server.
And then you're going to want to wait until the connection did finish loading is called. Now all of that data that I received can be thrown together and maybe it's an image, I can present it, maybe it's a chunk of XML, I can throw it to a parser and parse it. So you want to wait until that particular method is called, then you're good to go with the So those are the core classes.
The examples that we've got that take advantage of these are reachability, very useful to determining if a particular URL is available. It's important to find out if a URL is available before you make the call. And the nice thing about reachability is you can detect whether it's going to be accessible via a Wi-Fi connection or a cellular connection. So that's pretty useful. Ytap and Bonjour Web both take advantage of these three core classes. And URL cache is particularly interesting for looking at the caching mechanism associated with the various network calls.
So that's calling web services. Web services typically respond with some sort of XML content. We've got a couple open source libraries that we provide at the bottom layer on iPhone. They're also on the desktop. The first one is libxml2. So if you want C-based access to parsing XML content, then you've got it just through the libxml2 library.
We've also got libxslt on iPhone and iPod Touch as well. So if you're doing any sort of XML transformations based on XML style sheets, then you can leverage this library to perform those transformations. The Safari browser as well as the UI web view will take any XML content that's being presented and transform it on its own without you having to use this library as long as it includes an XML style sheet within it.
So you don't necessarily need to go and use this library if you're just taking XML content and presenting it as HTML, for example, within a UI web view or within the browser. So these are the two low level libraries that you have access to. They're open source, so the documentation is open source as well. So it's xmlsoft.org. There's examples up there as well as the documentation, so take a look at that.
We've got a high level XML support class built into iPhone as well. So at a higher level on top of that XML lib, we provide an NSXML parser. And what this is is a single pass parser, no DOM. So you don't have access to functions in order to query for particular nodes. It's all about sort of top down. Let me walk through all of your XML and then provide you callbacks each time I hit elements within the XML itself. Single pass.
So it's delegate based. And you basically get a callback within your class that responds to the NSXML parser delegate methods for each time an open element is found within the content. It calls didStartElement, passes a dictionary of the attributes for the particular open element. There's a callback each time we find content within an element between a begin and end tag. And that's foundCharacters.
FoundCharacters is buffer based as well. So you want to buffer up any string that's returned because that could be called multiple times. And it'll be called multiple times until the close element is reached for any item within your XML. And when a close element is reached, didEndElement is the method that's called in your parser delegate. Once the didElement function is called, all your concatenated string is ready for presentation or ready for use within your application.
SDK samples, Seismic XML, best example out there for using NSXML parser. It does it in a asynchronous mechanism, it asynchronously loads a table as well. So it's a pretty useful example for all sorts of things, spawning threads, parsing XML, and presenting data in a table in a threaded manner.
While we're talking about high level support, one thing that you should think about is P-List formatted XML. If you own the back end and you own the structure, the DTD of the XML content that you're pushing down to the clients, you might consider putting it in P-List format. P-List DTD is something that we use all over the Macintosh as well as iPhone for holding configuration information.
It's basically our default text file format for configuration information and preferences and those kinds of things. So if you own the back end and you can create your XML in this particular format using this particular DTD, then you get a big bang for it. So this is what P-List formatted XML looks like. You can see it's got a limited set of entities, so things like dict, therefore dictionary objects, there's strings, you also see key value pairs, there's array types in here. So it's a fixed set of entities.
if you can live within this particular environment what you get is very easily marshaled data types. Basically, we'll parse through P list formatted XML and do the conversion for you to data types that are native on iPhone itself. So, anytime we hit a string element we'll convert it to an NSString. An array will become an NSArray.
A dict will become an NSDictionary along with all its keys and the values within it. Bool and its number and its data and its date accordingly. So, it's really easy way to go and do the marshaling for a lot of different data types. So, you don't have to do all the string conversion on your own.
So, easily loaded, NSDictionary class can take PList formatted XML directly. So if you've made a web service call, it's come down as PList formatted XML. You can instantiate an NSDictionary class directly with the contents of a file, with the contents of a URL, the contents of a data buffer and you get a dictionary object out of it as a result.
The dictionary object then you've got very much like a DOM implementation where you can ask it for its keys, you can ask for the objects associated with keys. It's a really nice implementation and really easy to go and hook up to things like table views and picker selectors and those kinds of things within the iPhone user interface.
So, and they're very fast. I mean we use these file formats all over the place. And so the code that we've written is highly optimized for parsing this kind of content. So I've got an example where I've loaded my entire iTunes dictionary into a, a P list into an NSDictionary. And it loads it incredibly fast. It navigates the keys incredibly fast. And it's a huge file. So it's, it's something you should definitely take a look at.
If you've never seen any of these files or you want a high level application to create your own P list formatted XML. There's a property list editor application that's on every Macintosh. Allows you to interactively go and create these files, choose data types associated with fields. And then you can generate an XML file as a result of using this app and take a look at the, the data that it's formatted. So give that a whirl if you haven't seen it before.
That's parsing XML, pretty straightforward. Moving on to saving data locally. I mentioned that web applications as well as native applications live in a sandbox. Well, you've got the ability to write files to that sandbox. You can read files from that sandbox as well, those ones that you've written. One thing that folks want to do is deploy multiple applications. Well, there's some restrictions there.
Multiple applications can read and write to a sandbox. However, they can't read and write to each other's sandboxes. The goal is to provide a completely secure environment where native applications can't just troll across the file system and read willy-nilly. What that means is from an application perspective, you can't read outside of your particular area as well, even if you own both of the applications and boy, it sure would be great to share the data between the two.
If you do own application one and you do own application two and you want to share the data between the two, there's other mechanisms. There's the cloud that's there. If I've got content that I want to share between two applications, I can stick it in the cloud. My model can exist in the cloud and both of these applications can access that same data because it's up there. It's centrally located. These are always connected devices or at least most of the time connected devices. If I need to transfer information, I can do it through the cloud. Another mechanism that we've got is basically an open URL call.
Where one application says, "Hey, I've got a bunch of data and I want to send it to another application." He just throws it up to the operating system. The operating system catches that data and says, "I know who cares about this kind of stuff," and then launches the second application and tells it to go ahead and load the data.
That's all through an open URL mechanism. The way that you configure your application to receive this catch or to receive this tossed data is by modifying your Info.plist, going to the URL types, specifying a URL scheme within there. That scheme is the URL type that you care about within your application.
Now any time a web-based application or a native application calls a URL that begins with that scheme, in this example it's myapp2, your application is going to get launched and the rest of the query string is going to be passed to your particular application. I've got an example of what it looks like in just a second.
The key here is that you want to make sure that your scheme is unique. There's a lot of different applications that might want to go and implement this sort of data passing mechanism. You want to make sure that yours is unique and the best way to do that is to define your scheme as your application signature. Application signatures are guaranteed to be unique for any application that's distributed.
If you use the same URL scheme as your application signature, then you're going to have something that's inherently unique. You also want to make sure that you don't use any of the schemes that are supported by built-in applications. Don't say that your application can automatically handle HTTP or automatically handle FTP or SMS or any of those other things that we do within the native applications because it's going to be our application that's called every time. HTTP is going to launch Safari. Mailto scheme is going to launch the mail application. SMS is going to launch the SMS application. Those are the examples to stay away from. Come up with something of your own. Come up with something that's unique.
That's key. So here's an example. I've got application one, wants to send some data over to application two. So I create this URL string and have the scheme in it, as well as a bucket of data, this text data. I know that application two responds to that particular scheme, my app two. So I build up this URL.
Then I call open URL. This is a method on the application, the shared application object. And I pass in that URL, so I'm passing in that string myapp2 and then some data. And as a result of me calling that particular application method, my application is dropped, application 2 is launched, and then the handle open URL method is called on application 2. And that URL is passed in, so the myapp2:text data is passed to application 2 through this particular mechanism.
One thing that you want to remember when you're implementing this in your own application is URLs can get launched by a whole slew of different things, right? It can be any sort of native application can decide to call your application scheme just because it wants to, right? I could put a URL on a web page and surf to that web page within Safari on iPhone.
And if it's got a link in it that's got your scheme on it, you can put that URL on it. If the user taps on it, we're going to launch your application and pass it the data. So you want to be very cognizant of the fact that this scheme can get called by other people, other applications, random places on the web.
So come up with a unique way of securing your own data communication between your applications or your services where you're going to go and take advantage of this. Don't just take whatever string that you get from the wild and throw it into a database, you know. It's a great mechanism for doing buffer overflow. It's a great way to get the data that you're going to be using to your application.
So look at the data that comes in, come up with a convention for how that data is going to be passed to keep it secure. You might even encrypt the data that's sitting there on the string when you pass it and only your native application, the one that receives it, knows actually how to decrypt it. And then anything that it doesn't know, your application is going to get launched but you're going to just kick it off and say, "I don't want to talk to any of this data." All right, so there's ways around it.
So that's the mechanism for passing data back and forth. Process the architecture. So that's the arguments within the URL again. Just be very cautious about how you process those arguments because they could come in from a whole bunch of different ways. LaunchMe is probably the only sample that we've got in the SDK that shows you how to do this.
Basically, it's something that a native application you build, you install, tells you to go over to Safari, type launchme:/ and then some text. Once you load it in the browser, it goes and loads the native application and says, "Hey, it worked." So a nice thing about it though is it shows you what you need to put within the info.p list in order to respond to these types of URLs.
So core file classes that you're going to use in order to go read and write. First is NSFileManager. You'll use this class for all sorts of operations associated with managing files and directories, setting the various bits, permissions, those kinds of things on files and directories, determining whether files exist or not as well as creating them. You'll use an NSFileHandle class all over the place to read and write.
So anytime you've got a file sitting in the file--within the file system, NSFileHandle is the class you'll use to actually read and seek and flush and all sorts of things there. So these are the two primary classes. You definitely want to avoid hard-coded paths, especially if you're going to be talking to any of the folders that you have permissions to talk to. The way you do it is through the NSSearchPathForDirectoriesInDomains JavaScript function.
It's JavaScript function, C function. This C function allows you to request from the OS a path to your documents directory if you pass in the NSDocumentDirectory constant. You could also pass in other constants as well, saying, "Oh, I want the temp directory," or "I want the caches directory." You can ask for those, but you have to ask through this particular C function and we'll build up a path to that particular resource for you, to that particular folder. So use that before you go and write.
So here I've got an example using those classes. So I'm going to write a file called "myfile.txt." And then I get a file handled to the class, that saved file, and then I use the file handle to do all my writing synchronization as well as closing in the file, reading, those kinds of things. So straightforward process. The key is that you definitely want to use the C function for determining where to--where your particular directories reside.
All right, so while we're writing files, we can also write out SQLite files as well. We've got a SQLite implementation on iPhone, much like on the desktop, and it's LibSQL version 3. So I can write files that conform to my own file format, or I could write out database files just using LibSQL. SQL92 with caveats, so if you're used to writing typical SQL, then there's a good chance that you can shoot the same sort of SQL to SQLite.
It supports things like transactions and triggers and views. Views are read-only, however, and supports common data types including integers, reels, texts and blobs. So there's a nice SQLite API for writing out these various types. You could write out objects that you've got in memory as well. You can use the blob field for holding all sorts of content including anything that you've got sitting in memory.
Things that are in memory, classes that you've instantiated on your own. As long as you've got them in your own, as long as they conform to the NSArchiver, NSCoding implementations, then you can serialize those and throw them into the database as well. So LibSQL version 3, files that you create using the APIs in a native application on iPhone, those same files can be opened anywhere that SQLite is used. It creates the same sort of SQLite compliant files. It's an open source library, LibSQL, so the documentation is open source, SQLite.org, lots of great examples there.
And we've got an SDK sample called SQLite Booklist that does reading and writing of records to a SQLite database. It's got a great implementation where it takes the stub of the database that it's going to use for all its transactions out of its bundle, writes it to the local file system where it's got write capability, and then uses it for each additional write that you might want to use. So it's a particularly good example. And the URL cache example uses it to store data as well. So those are some good samples if you're interested in saving data that's SQLite based.
As long as your writing files out, it's good to see the results, the fruits of your labor, and you can do that within the Organizer. You don't necessarily need to write something that reads all the stuff you just wrote out just to validate that it's actually successful at writing. You can open up the Organizer window within Xcode.
You'll see all of your in-house applications listed down here, and if you rotate the little triangle associated with your particular application, you'll see an application data element there. Click on the little down arrow, and what you'll get is a prompt to save your entire documents directory somewhere within the operating system. You'll be prompted to save this folder, so you know, stick it on your desktop, stick it wherever you want, and then what you get within the Organizer view is the hierarchy of those documents that you just wrote out.
So this is my image cloud sample that goes and hits a bunch of images up in the cloud, writes them out to the local file system. You'll see on the left-hand side I've just selected one of the images. Xcode will present what it can. If it needs to be, it can be sent to the local file system. If it needs to be, it can be sent to the local file system.
And then you can see what it can, if it knows the file types. If they're text types, it'll show it in there as well. Of course, that directory is still sitting somewhere with my file system as well, because I saved it there so you could romp through it manually as well, open the directories and see what was written out.
If you're doing simulator-based developments, simulator has a documents directory as well. It's an incredibly long URL, but there's a documents directory there as well, so you can see the results of all your rights within the simulator. You don't necessarily have to have a native-based application to take a look at that.
All right, so that's saving data locally. Just ripping through the last couple ones quickly. Got some security services available on iPhone. First one I talked about in the initial presentation, in-house certificates, as well as a lot of the most common routes. They're useful for authentication and signing. We have a keychain API on iPhone, much like on the desktop for Macintosh programmers.
Common crypto APIs, so if you wanna do any sort of unique random number grabbing, SHA, any sort of ad hoc encryption of content, files, those kinds of things, then you'd use the common crypto library. And then we've got the CF network framework. It's a lower level network, below NS network layer for TLS. If you're doing any sort of secure networking and you wanna get down to the nuts and bolts at that level, then CF network is the place to go.
I'm going to spend a little bit of time on digital certificates and keychain because these are probably two of the most used by in-house applications or soon to be. So at the get-go we've got support for routes like server and identity certificates. The most common are built-ins. We've got over 132 sitting within the keychain on iPhone, basically the same set that you would see on the Macintosh desktop if you opened the keychain access application and clicked on certificates.
Most common are built-ins. So if you want to use them, they're good to go. They're stored in the keychain so they're securely stored. You can import your own certificates if you're your own certificate authority and you want to use those certificates as part of authentication for back-end resources.
You can import them via Safari. Going to a secure web server, users can import an in-house cert or they can also be distributed to users for use via an attachment in email. And in the previous presentation I also mentioned that the iPhone configuration utility is a great way to go and push via configuration profiles certificates out to your users as well. So we support in-house as well as the most common routes already within the keychain and you can use them for doing all sorts of things. So you can use them to authenticate with the built-in app.
So Safari can use your in-house certificate to authenticate to a server sitting within your organization that has your own certificate on it instead of using a public route. You can also, since you have access to the keychain, use certificates that you've deployed through whatever mechanism as a way of providing authentication within your own application as well. You've got access to that search store so you can use the search as part of your chain of trust for communication to a back-end, all sorts of things.
So certificate support, it's there. Keychain support, so we've got a pretty significant keychain API on the desktop if you're used to it. We've greatly simplified it. The keychain provides support for all sorts of storage of information that's considered secure. So things like cryptographic keys, certificate information. If you're going to collect any sort of passwords from a user and you want to store it for sessions, then throw it in the keychain. It's a secure way to go and store it.
It's encrypted. You don't need to worry about it. You don't need to worry about it sitting out in the file system or anything like that. When you launch your application, you can go and pull it out of the keychain again. It hasn't been tampered with in any sort of way. So if you're going to store passwords, throw it in the keychain.
There's a shared keychain store, basically one encrypted store that all the passwords for all applications are stored in. But based on application signatures, there's restricted access to basically little slices of the keychain. So application one has access to applications one's keychain or slice of the keychain. Application one can only read and write from a particular portion of the keychain. They can't necessarily read passwords, certificates or any other information that was written there by another application unless, of course, that other application has the exact same signature.
So there is a mechanism for deploying applications that have a little star as part of their application signature. If you deploy that way, they... Then those applications that conform to that signature protocol can all share the same slice of the keychain. And the documentation for doing that is on the...I think it's in the distribution tab of the program portal on how to do that.
The secret is protected by hardware, not password. I mean, this is interesting to folks that are used to unlocking the keychain on a Macintosh based on logging in and a password associated with the keychain. There aren't any prompts in iPhone for access to the keychain. People that are used to the desktop experience, if Safari wants to access the password associated with a particular website, you see a dialog that's presented by Safari.
Hey, we want to go get your password out of here so we can use it for auto form complaint. There isn't that kind of implementation on iPhone. Mark Malone The security associated with the keychain on iPhone is all about a hardware password. There's something unique about the hardware that's used to go and lock the keychain.
Backup occurs, but it's tied to device. So if you want to recover a keychain onto a phone, it'll only go back to the phone that that particular keychain came from. Since it's locked with something unique about that device, it would be useless anywhere else anyway because it's encrypted with that device secret.
So keychain APIs, there's four of them, concise set of C functions, sec item matching, that's all about finding something within the keychain. I've stored a password there, I wanna go and retrieve it now, so I just ask the keychain using this particular API to give me back that password that I wanna use based on whatever criteria.
Perhaps it's a name associated with that particular password or a domain associated with that password. If I wanna add something to the keychain, it's sec item add. If I wanna update something sitting within the keychain, it's just one big array of data types. I can update just one aspect of it, I would use this particular API call. And then finally, if I wanna remove something from the keychain, I would use sec item delete. The reason I've listed them here is because it's a much smaller set than what folks might be used to if they're using the keychain APIs on the Macintosh desktop.
SDK samples you might be interested in if you're doing anything with the keychain, generic keychain example, throws stuff on, pulls it off based on lookups, deletes, those kinds of things. And then the crypto exercise example is particularly interesting, especially if you want to do any bulk encryption of content.
If you want to take a file and encrypt it before you write it out to disk or if it's sitting on disk and you want it encrypted or decrypted or you want to set up a secure communication based on certificates between a client application and the server, that's a great example. That crypto exercise application is a great sample for getting your hands around how that's done.
So that's security services. Going to wrap it up with deploying iPhone applications. Should be pretty short. Two different application architectures, two different ways to go and deploy, at least within these particular architectures. First, there's a web app deployment. Everybody knows that, right? Everybody knows how to deploy a web application.
Pretty straightforward, especially for a single one. All you need to do is find a place to go and host your particular web app, poke a hole in the firewall, pass out the URL to your customers, your end users who are using it. And once they've got it, they'll create a home screen icon so it stands right next to the rest of the native applications on their iPhone or iPod Touch.
One thing that you should consider if you're deploying multiple web-based applications is coming up with an iPhone portal. So basically one destination where users would go and get all of their web-based services through one particular URL. It saves you having to open up multiple ports in the firewall or distributing multiple icons, having multiple icons on the home screen. And it's something that we've done within Apple for our deployment of web-based applications.
So in my sample here, I've got the little single icon. You tap on that to go to all the Apple web-based services. Since it's all coming through a portal, all of these apps use the same authentication mechanism. If I authenticate successfully to the system, then I get in. If I don't, then I'm blocked. Once I get in, then these are all just web-based icons that are sitting within my portal web-based application.
A great user experience because basically all that session information is leveraged. Then the user goes and taps on the various one, whether it's the directory app or something else, launches it, and the presentation is great. So consider using a portal if you're going to deploy more than just one iPhone-based app. It's a great shortcut.
From a native application deployment perspective, there's three different mechanisms for deploying a native application. The first one is enterprise. Enterprise deployment are for folks who are members of the enterprise developer program at Apple, so the iPhone enterprise developer program. It allows you to deploy unlimited applications to unlimited devices. There's no tie between a device ID and the application that you're distributing.
It's unlimited. The only real caveat is that you can only deploy to members of your own enterprise. It's not a deployment mechanism that allows you to deploy outside of your enterprise. It's for in-house applications. It's for in-house application distribution only to folks who are part of your enterprise organization.
So that's enterprise distribution. There's ad hoc application distribution. Ad hoc is all about tying the capability of a particular application to run on very specific known devices. So there's a set of iPod Touches or iPhones that I want my application to run on, and none other than I'm doing an ad hoc deployment. And then finally, you know what you love it.
It's the App Store deployment, right? It's all about pushing it up, and this is for commercial and free applications. So these are the three mechanisms of deployment. The ones that are most important to in-house developers are typically the enterprise and ad hoc distribution methods. Although there's a lot of enterprises that are commercial application developers as well, so typically they'll have an App Store account as well. And they'll use that for deploying to customers that are folks outside of their organization.
So enterprise and ad hoc deployment, the process is build, authorize, deploy and install. There is no over the air capability for deploying in-house applications for doing iPhone enterprise application development or ad hoc. Only the app store mechanism is the way to get it over the air. In order to go and deploy an application that's ad hoc or enterprise, first thing I need to do is to sign, create a signed distribution build of my native application.
Then I need to interact with the program portal at Apple, so sign in. Perhaps I'm doing an ad hoc distribution, so I need to select the device IDs of the devices that I want my application to run on. As a result of interacting with the portal, I'll get back a distribution provisioning profile. If I want to do an enterprise deployment, I would still go through this same process, but I would not select devices and tie that particular distribution to those devices.
I'd say, no, I don't choose the radio box that says I want to do an enterprise deployment, and then the need to select device IDs goes away. So as a result of interacting with the portal, you'll get a distribution provisioning profile. It's signed by us to make sure that it's not monkeyed with.
Once you've got that provisioning profile and your signed application in hand, it's time to go and deploy it. And you can deploy it in any mechanism that you want to do, as long as it gets it to the desktop of the user that needs to have it installed. So you can use the application to deploy it.
So you can use email. You can push it through any sort of mechanism. You can use a thumb drive, whatever it takes to get it out there, but it's got to land on the desktop. You can't push it to the email of a client on the iPhone. It's got to land onto a desktop.
The reason it's got to land on the desktop is because the only way to go and install in-house applications is via iTunes. So the way you install applications with iTunes is you drag and drop them on top of the icon for iTunes, either on a Windows machine or on a Macintosh. If iTunes is already running, I can drag both of them into the library section of iTunes as well.
There's the iPhone Configuration Utility which I talked about in the previous presentation. It's got the capability of adding provision profiles as well as apps. So if you're an IT organization and you want to prep a bunch of iPhones before you give them to developers, you can use that tool to do the same thing.
Once they're there, once the user clicks their phone in and synchronizes, the in-house application is pushed over to their device. They're good to go. App Store Deployment, a lot simpler than that, right? All you need to do is still create a distribution signed build of your application. The next step is you push it up to the iTunes Connect portal and then we take care of the distribution to the App Store either on iTunes on the desktop or the App Store application on the mobile device.
So that's the application distribution mechanism. And that's it from a presentation perspective. I've got some links here at the end. Links to the iPhone configuration utility, developer documentation. I mentioned some CSS effect public specification is out there at webkit.org. Interesting Ruby library that I use for generating SVG graphics if you're into SVG and trying to figure out how you're going to go and generate some of those, that's pretty interesting. And my email is at the top so if you've got any sort of headaches or things that you're running into as part of your deployment, building, any of the process associated with in-house application development, please keep in touch.