App Frameworks • iOS • 51:15
Learn how to integrate Twitter into your applications. If you're new to Twitter, or have existing applications, we'll show you how easy it is to make the most of our new framework for single sign-on accounts.
Speakers: Scott Herz, Glen Steele
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript was generated using Whisper, it may have transcription errors.
Well, good afternoon. Welcome to session 124, Twitter integration. My name's Glen, and I'm an iOS software engineer. And I'm going to be joined on the stage in a couple of minutes by my colleague Scott. Scott and I both worked on the Twitter integration in iOS 5. And we're just really excited to share with you the APIs and things that we've been working on. Scott's got some awesome demos for you to see, so you can look forward to that.
So this is one of my favorite quotes from the TV show "The Simpsons," and it's from the blackboard gag at the beginning of the show where Bart writes out his punishment for the day. And it just reminds me so much of Twitter. If you look up the term "Twitter revolution" on Wikipedia, you'll get no less than four disambiguations for that term. And these aren't just like silly metaphors or hyperbole. These actually are referring to real national revolutions that have happened. And to me that just speaks a lot to the influence of Twitter in our society as a communications tool today. And this starts to really flesh out when you look at some of the numbers. I mean, Twitter has 200 million users.
And they process -- Scott mentioned this in the keynote on Monday -- 1 billion tweets per week. And that is just an incredible amount of, like, meaningless banter going across the Web. It's not all just meaningless banter, right? I mean, during the Japan earthquake, they were processing 5,500 tweets per second. And these are people communicating with each other, sharing about what's going on in our world, and who knows, maybe even communicating with their families, letting them know they're OK. But I think for us as iOS developers, this is a really interesting number to me. There's over 3,000 apps in the App Store or on iOS that have Twitter integration.
And so, you know, as we were thinking about Twitter integration in iOS, one of the big goals for us was to just make it a whole lot easier and lower the bar for you as developers to integrate Twitter into your applications. And so that's really what we strive to do. So what are we going to learn today?
Well, we're going to talk first about -- we split the talk up into three parts, and the first is what I like to call pain-free tweeting. And so if you're an application developer and you just have really simple Twitter integration needs, you just want to pop up a sheet, allow the user to type in a tweet, send it off, then this is really what you want to pay attention to, because we've got a really neat way for you to do that in iOS 5. Now, if you've got a more complex Twitter client, you need access to the entire Twitter API, then we're going to move on and talk about how to access system accounts, because Twitter accounts now on iOS are actual system accounts that you can access and use to interact with the entire Twitter API that's available to you on the web. So we're going to talk about how to do that.
All right. So this is what we call the tweet sheet. And this is the part of this talk where we talk about pain-free Twitter integration. And as I mentioned, we like to refer to this as the tweet sheet. Hopefully you've had a chance to play with this a little bit. We love it. Our HI design team just did a phenomenal job with this. It looks beautiful. It has this whole index card motif and a character countdown. It's got -- you can add your location to it. You can even add attachments. And it's just really great and really simple to integrate into your application. So let's talk about how you do that. What we've done is as well as integrate this into iOS applications like Safari and Maps and Address Book, we've made this and exposed this as an API that's available to you and it comes in the form of the TWTweet Compose View Controller. So how do you invoke this thing? Well, there's four steps that you basically have to take. And the first is that you need to check for service availability.
So if-- yeah, that's not a joke. So not Twitter service availability. I'm talking about whether the user actually has an account set up on their device. If they don't have an account set up on their device, you may decide that you don't want to show the UI element that shows your tweet button or whatever it is that invokes your tweet sheet. So once you've done that, it's just a matter of creating the the view controller, that is the actual tweet sheet and getting an instance of that, and then supplying a completion handler to tell the tweet sheet what to do once the users hit cancel or send.
Now that you've got that all set up, it's just a matter of presenting it modally over your current view controller. So let's look at how we do this in code. And so I've got just a sample view controller, like my view controller, and I'm just deciding to override the load view method. And to check whether the user actually has a Twitter account set up, it's just a class method on the TWTweet Compose View Controller called can't send tweet. And that'll just return a Boolean value that tells you if the user can actually do a tweet. And so in this case, we're setting an instance variable that will indicate to us later in-- whenever our UI loads, whether we want to show our tweet button.
So let's just imagine for a moment that the action on that tweet button is to call this tweet button tap method. And let's take a look at what actually happens when you drill into this method. So now that we've checked for our service availability, the next thing we need to do is just create our tweet sheet. And to do that, it's really simple. We just do a TWTweet, ComposeViewController, allocant it, simple Objective-C stuff that you're all familiar with, hopefully, and then SupplierCompletionHandler. Now, in this case, we're deciding to do something really simple. We're just going to dismiss the tweet sheet when it's done. You may want to react to the tweet sheet being canceled or sent or the Send button being tapped in a different way. In this case, we're just going to dismiss it.
And just to note that this is actually the default behavior if you decide not to provide a completion handler. And once we got that, now we just call presentModalViewController over our current view controller, and that will pop up the tweet sheet. So that's really as simple as it is to set up the tweet sheet in your application. It's just a couple lines of code. But that's not all it can actually do. It has a lot more power than that, and it comes in the form of attachments. So you can actually prime the tweet sheet with some values before you present it to the user. And there's three ways that you can do that. The first is you can set the initial text on the tweet sheet itself. And that's just done by calling set initial text and providing your string. And you'll notice that there's a return value here. And all this does is let you know if it was a successful operation. OK, so why might that not be the case? Well, if you provided a string that's too long-- hopefully we're all aware of the Twitter 140 character limit. I don't think that's going to change anytime soon. But if you've gone too long, then that's one situation where you might get a negative result. The other is if you've already presented the tweet sheet modally, and then you try and call this, we actually actively disallow you from setting any of these things after that. Because we don't want the user to be interacting with the device and then the tweet sheet to be changing under their feet. So that's another reason why that might happen.
And you'll notice that we don't return any kind of error here because it's not really a condition that you can recover from. Okay, so you can set the initial text. The other thing that you can do is add an image to the tweet sheet, which is great, and this follows the same general pattern that we talked about before with the set initial text. You just provide your UI image and then get a returned result. Now, when you decide to do this, we actually take care of resizing the image for you and uploading it to Twitter's image hosting service and doing the URL shortening for you automatically. And so, you know, that URL takes some of your characters, and again, you may get a negative result if you decide to add too many or you've already used up too many characters in the tweet sheet. The last thing you can do is set up a URL. And again, very similar to what we said before, we handle the URL shortening for you, and a Boolean result is returned.
Okay, so I've talked about this a little bit as I've been going over the tweet sheet, but just to reiterate, you know, there are sizing constraints. There's the 140-character maximum. Images and URLs use some of your characters when you decide to add them. And just an interesting side note is that the URL shortening uses 19 characters. Now, you know, that's a cool little tidbit of information to know, but it's really not something you should rely on, right? Because as the namespace fills up and the URLs get longer, the 19-character length of the URL shortening is not something you want to rely on. So instead, make sure that you're paying attention to the Boolean return values, because that's what you ought to trust is the truth. Okay. So I'm going to ask Scott to come up and give you a demo of how to use the Tweet Sheet in your application. So please welcome Scott.
So this is a real simple demo just to kind of show you how to pop up a tweet sheet and see how we add attachments to it. So what I've done here is just written a simple little app. It's got a number of buttons. And each one of these buttons represents a kind of an attachment type that you might want to add to the tweet sheet. So this guy up here, we've got some text. That's the initial text you might want to set. These guys down here are just a couple images, and then just a sort of a random link. And so when I click these buttons, what's going to happen is it's going to go and make those calls that Glenn was just showing you. It's going to set the initial text, or it's going to add an image or a URL. And if the result of that is true, then we're going to see a cute little green check box. And if it's not so good, then you're going to see this sort of angry red indicator. So let's go ahead and try a couple here. So I'm going to click this guy. So that text, that fit, was less than 140 characters, so we're still good to go. I click another one here. That, we added the image, and it knew The Tico length today is 19, so we're still all good to go. Can add a couple more. Then when I try to add this one, that one didn't work. So let's try it again with just a couple simple ones. Just these three things here.
Hit the Tweet button. Pop it up, and you can see the Tweet sheet is as we know and love. Let's show you just some of the code here that it took to do that. as I flail around with the mouse. There we go. And you can also get-- You can watch me learn how to scroll and line. So this here is-- we're just making a new tweet sheet, right? So just Alec and NIT1. Just like Glenn did, we're building a very simple completion handler block. And all we're going to do here is-- it's not particularly interesting. Whether or not the user hit cancel or done, we'll go ahead and just dismiss our sheet. And then here's where we set it. And then down below, as I was clicking those buttons, again, we're just using these simple methods-- add image, add URL, et cetera. And we're just returning out the back, like, OK, did this work or not? And then there's some other UI kit machinery to actually show the indicators.
So lastly, when I click that button, the Tweet button, so simple. Like all you have to do is just take your Tweet sheet that we made and present it modally, animated, and it pops up all nice, and you're good to go. So that's how easy it is to add a Tweet sheet to your app. So I hope to see a lot of them. Thanks.
Great. Thank you, Scott. So just a couple tips and tricks when you're interacting with the tweet sheet. Remember that the tweet sheet is really only designed for modal presentation. So you kind of want to stay away from trying to put this thing in a UI navigation controller stack or in a UI popover on the iPad. It's really designed to be presented modally over your application.
So use the presentModalViewController method on UIViewController to present it. Again, just to reiterate, set the properties prior to presentation. We don't want you messing around with the tweet sheet under the user's feet while they're using it. So do that before you present it. And then check the canSendTweets method if applicable for you. So one little detail to note here is that if the user doesn't actually have an account set up in Settings and you decide to invoke the tweet sheet, we'll actually context switch the user back to Settings to allow them to set up an account. And this may or may not be a behavior that you want. So you should be aware of it and make sure that you check the canSendTweet class method on the View Controller. The other thing is just to be aware that we are doing image resizing. We are uploading things. So if you provide a huge image to the addImage method, then it's going to take a few seconds to resize if necessary. Okay, so that is the tweet sheet. That is pain-free Twitter integration. It took us about 10 minutes to go through that. It's really, really simple. And I encourage you, if you have simple Twitter integration needs in your application, use this. You get a great UI for free, and it's really easy to invoke it.
Okay, so we talked about that, and now we're going to move on to talk about something else that's pretty cool, which is the new accounts framework in iOS 5. And this is a really cool feature, but it's kind of a sleeper feature, right? It's not really talked about a lot, but what it allows you to do is access built-in system accounts that are on the device. Now, for iOS 5, we're only supporting Twitter accounts, but there's still a lot of power in that. And we also allow you to add accounts in certain situations and make system accounts as well from your application. And we'll go into why you might want to do that and how to do that in a little bit. And if you do decide to do that, we also take care of the validation for you. We make sure that the credentials that you provide us are good to go with Twitter before we add the account and make it become a system account. All right, so just a word on the architecture of the accounts framework and how it's laid out. So you've got your application. It's in its sandbox. And we've got the accounts database and the protected file system. So how do these things communicate with each other? Well, there's an intermediary process called accountsd that basically acts as the arbiter between your application and the accounts database itself. And this architecture gives us a couple nice features. One is obviously security.
We can store the credentials for the user securely in the protected file system and, you know, a bunch of applications can't get at it without going through our frameworks. And it also gives us a layer of abstraction for your application and other applications to access the accounts which, you know, limits in the way that they can access the database and make sure they're not, you know, messing it up for you, right? So that's just a quick overview on how it's laid out. And this is basically what the class diagram looks like, and it's very simple. We've got four that are there, but I want to focus on these three to begin with. And essentially what you have is an account store, and in your account store you've got a bunch of accounts and each account has an account type, and that's really all there is to it. But what I'm going to do is go through each of these classes and just describe them to you so you can, you know, maybe understand their function a little better. And we'll start out with the account store. So the account store is your connection to the account's database. And when you allocate and initialize one of these, automatically your connection to the account's database is established.
Now, these are things that you generally want to keep as long-lived instances, right? You typically don't want to allocate one of these, interact with the account, and then throw away the account store, especially if you have the kind of application that's going to be using the account throughout its lifecycle. So it's something you probably want to put maybe in your application delegate or your review controller, you want to keep it around. Now, it's also important to remember that the account instances themselves are bound to the account store from which they came. So if you access an account and pull it out of an account store and then deallocate that account store and try to use that account with another account store, bad things are going to happen. There's an implicit connection between those two objects that needs to be respected. The other thing I want to point out is the AC accounts change notification, which is defined in this header. And this is something that any application that is implementing code that uses the accounts framework needs to respect. It's a notification that fires when the accounts database changes. So if the user goes into settings, adds an account, or removes an account, or maybe revokes permission for a particular application, this notification is going to fire. And you need to respond to it and observe that notification. And any instances of accounts that you have lying around, You need to refresh and obtain new ones from the account store because otherwise you're going to be dealing with outdated information.
So that's the account store. And the next one that I want to look at is the AC account object, which is really what you're interested in. This is the object that represents the account itself. And it's got five basic properties on it. It's very simple. It has a unique identifier. It has an associated account type, username, credential, and description. And I just want to point out the description. So when we create a Twitter account, we automatically create the description by appending the @ symbol to the username. But the user can actually go into settings and adjust this thing so that it can read however they want it to. So typically, if you're presenting UI that references a particular account, the description is what you want to use, because that's what the user has told the system, hey, this is what I want this account to be known by.
Okay, the next one is the AC account type object. And so every account has an account type. And it's got three simple properties as well. Again, it's got an identifier. And these just aren't just -- you know, the account type is not just a string or something. This is a real object that lives in the account store. And it has a description. And then it's got this interesting property called the access granted property. And that tells you whether the user has granted access to accounts of this type to your application. So you can check this at any time to figure out if you have permission to use accounts of this type.
Okay, so let's talk about that a little bit more. How do you actually request permission to use a particular account? It's very simple, and we're going to step through it by code. As I mentioned, accounts are protected by account type. So once you have access to, you know, one Twitter account, you essentially have access to all of them, and we message it to the user in that way.
So to get permission for an account, you just create an account store. Again, very simple, AC Account Store, Allocanit. Your connection is now established to the database. And then you obtain the account type that you're interested in gaining permission for. In this case, it's always going to be Twitter, right? So to do that, it's just a call to account type with account type identifier. And you'll notice this identifier. So all supported account types, we define an identifier for them, and it's in the header. So in this case, it's the AC account type identifier for Twitter. We pass that in, and now we have our Twitter account type object, and we can request permission to use that from the user by just calling on the account store, request access to accounts with type, and that comes with the completion handler. So we've used completion handlers a couple of times now, and I just want to point out, this is probably a good time to point out that we make heavy use of blocks and Grand Central Dispatch in these frameworks. So if you're not familiar with those, I'd encourage you, get familiar with blocks in Grand Central Dispatch. It's going to be useful if you're interacting with these APIs. So you'll notice in our completion handler, we return a Boolean that indicates whether you got permission or not, and an error in case anything else went wrong. And you can check the granted Boolean value. And if it's true, then you know you have permission to access the accounts. OK. So now that you've got permission, You've requested it from the user. They've granted it to you. How do you actually go and get an account instance? And there's two ways that you can do this. And the first is you can request all the accounts of a particular type.
So let's take a quick look at how you do that in code. Again, obtain that Twitter account type by calling account type with account type identifier. And then just ask the store for all the accounts of a particular type, and you'll get an ordered array in the same order that the accounts were added of the accounts that are on the system.
The other way that you can do this is to request an account by a particular identifier. And so I mentioned each account has a unique identifier. And you may decide that you want to save that identifier aside somewhere in your code, maybe in a plist or something, and access that exact account later on or maybe in a different instance of your application. So to do that, it's just a simple call to account with identifier, and that'll give you your AC account object. So those are the two ways that you can access accounts using the accounts framework.
All right. So we've talked about the three basic classes. And -- but there's one more that I want to cover, and it's the AC account credential class. And this is a really interesting one because what it makes possible is for you to actually add accounts to the device by providing credentials. So if you're an application developer and you've got a full-fledged Twitter client, It's a pretty good bet that you've got the OAuth access tokens and the token secret associated with those accounts stored in your application. And wouldn't it be nice if you could migrate those credentials to become system accounts themselves?
So that's what we're allowing you to do because we realize that for those of you who are implementing Twitter clients, you know, you've already got your user's account information and it may not be guaranteed that they've gone and set up a Twitter account as a system account already. So what we do is we allow you to actually provide credentials that we will then store as system accounts. Thank you. So that's exactly what we're describing here. You can add new system Twitter accounts from your app. And you do that by migrating OAuth credentials.
And we'll show you how to do that. When you provide us with the OAuth credentials, we take care of going and talking to Twitter, making sure that your OAuth credentials are OK, and then setting up a system account on the device. And it all happens really pretty seamlessly and automatically.
Okay, so let's look at in code how you actually do this. The first thing you do is create your account object. It's got one initializer. Every account has an account type, so it's init with account type. I've showed you a couple times how to obtain the account type from the account store. You just pass that in, and now you've got a new account instance. It's not saved in the database yet, but 'cause we've gotta add a couple of other things, or really one more thing. So the next thing you do is create your OAuth credential. And so you take your OAuth access token and access secret for your particular account and initialize a credential object with it. And then set that credential on the account. And once you've done that, you're ready to go. And it's just a matter of calling Account Store, save account, pass in your account instance with its OAuth credentials, and we'll go ahead and verify that the credentials are valid. And it's pretty cool. Right in Settings, your Twitter account will actually appear. And this is really powerful, right? Because it means that your account that you've been using is now accessible to the user. It can be used in the tweet sheet. It can be used in other applications as well, which is really great.
So a couple of tips and tricks in dealing with the accounts framework. One is to ask for access when you need it. So if you've got a full-fledged Twitter client and you're using our frameworks and you want to use the user's accounts, which we encourage you to do, then it makes sense for you to ask at the outset, right at application launch time. Ask the user if you can use their accounts, because if you don't, it's essentially for you, right? But if you're using Twitter kind of, you know, as an auxiliary function to your application or it's just a neat social feature, then, you know, don't bug the user with an alert right when your application launches. Instead, ask for permission when they decide to use that Twitter feature, right?
Important to note that certain operations are always gated with alerts. So for instance, requesting access to an account obviously is going to pop up an alert. And adding an account to the system using existing OAuth credentials will also pop up an alert. We're going to ask the user if it's okay to add this account to the system.
Again, don't cross the streams. Don't take an account from one account store and try and interact with another account store. Using that account, it's just not a good idea. And pay attention to that notification that I was telling you about. And this is an important note as well that I'm going to mention a couple more times. You know, often as a result of interacting with these APIs, you need to update UI, right? And you need to make calls to UIKit. And all of the block-based APIs that we have are not guaranteed to return on the main thread. So if you are updating UI as a result of any of these calls, then make sure you're dispatching that call to the main thread or performing a selector on the main thread. My favorite way of doing it is this, is just to use dispatch async. And this is more GCD magic. Use dispatch async, get the main queue, and then throw in a block that calls your method that'll actually update your UI.
Okay, so that is a quick overview of the accounts framework. It allows you to access built-in system accounts and use them and interact with the Twitter API using them. It also allows you to migrate existing OAuth credentials that you have and graduate them to become system accounts that can be used by the tweet sheet and other applications if necessary.
So now we're going to move on and talk about the Twitter request API. Now, I think at this point, it's probably a good idea to just kind of take a step back and take a look at what the Twitter ecosystem looks like on iOS. And so what we have is on iOS, we have the best mobile Twitter clients around, thanks to you guys. I mean, we have awesome Twitter clients that are available. And then we've got this expressive and useful Twitter API that's available to you. And that's great, but it's really not the whole story, because kind of sandwiched in the middle of this thing is this other thing called OAuth that you have to deal with if you're interacting with Twitter. And as we were thinking about implementing Twitter in iOS and talking to our counterparts at Twitter and talking to people who've implemented Twitter clients, it became apparent really quickly that the biggest stumbling block to doing this is using OAuth and using-- and I'm not just talking about the steps of going to a website and authorizing applications. I mean, just the mechanics of signing your requests. Many of you have to use open source or third party libraries to do this kind of thing. And so one of our big goals when we were creating the Twitter API in iOS 5 was just to get rid of this whole layer entirely. It's OK. Yeah, you can clap. Because I think it's pretty cool.
I mean, this really gets a big stumbling block out of your way completely, right? And it allows you to interact with the Twitter API directly and not really have to worry about all these details of how to sign requests and all that stuff. We just take care of it for you. You don't have to worry about it.
So how do we do that? Well, it comes in the form of the TWRequest object. And this is the other class that's available to you in the Twitter framework. And another design decision that we made was not to just go and make an Objective-C abstraction of the Twitter API. One of the things we could have done is we could have gone to the Twitter docs, looked at every single API that's there, and made an Objective-C abstraction to it. Most of you are familiar with Objective-C. It's really nice and elegant, you can use it, and that's great, but it's kind of limiting, right? Because it means that whenever Twitter makes an update to their API or they introduce some cool new feature and you want to write an application that's on the cutting edge, you can't because you have to now wait for us to rev iOS to respond to that, and that's not something you want to do. So it's not an Objective-C API, but what it is is a quick and easy way to make arbitrary requests to Twitter and use their full API.
We take care of the OAuth signing for you. As I was mentioning, we do all the heavy lifting of that. And all you have to worry about is your application and how to interact with the Twitter API. And you can use any of the Twitter accounts, thanks to the new accounts framework, in conjunction with the TW request object, provided the user has granted you access to do so.
The other thing we added was support for multi-part data. So some of the APIs that Twitter uses or exposes requires you to upload pictures or things like that. And the way that's done is by using multi-part form data. And so we have just a really easy way for you to add that to your TW requests and not have to worry too much about the details. So we'll show you how to do that too. All right, so this is our TW request object. And you can see it's got four basic properties to it, right? And if you're familiar with using the Twitter API and looking at the Twitter documentation, these probably look pretty familiar to you because every piece of Twitter documentation out there has essentially an analog to these four pieces of information in the TW request object. And so when you're coding up your TW requests, I encourage you, have the Twitter docs open right next to it. And it should be--it should feel almost as natural as like just filling in the blanks as you go through the documentation. So, you know, we have a URL property. Every Twitter doc has the URL property which represents the endpoint that you're interacting with. We have the request method.
So Twitter APIs support get post and some of them support delete. We support all of those and you just tell us which one you want us to use. And then each doc--each--the documentation for each API spells out whether the request that you're making is an authenticated request or not. And so that just corresponds to the account property. So if it's an authenticated request, hey, just pop in one of the accounts and we'll use that account to sign the request.
And then each piece of documentation also spells out some parameters. So if you want to limit the request in some way by providing some parameters, we take care of that in the form of a dictionary that you just provide to us, and we assemble the request for you.
OK. So let's take a quick look at how you would code this up. And it's, again, really simple. Well, before we do that, I want to point out that there are two ways, once you have your TW request object, to perform a request. And the first way you do this is we have a convenience method right on the object called perform request with handler. Now, this will take care of actually doing all the communication with Twitter and delivering the data back to you in a single atomic request. Okay. So what do I mean by that? Atomic is kind of a weird word here, but it's--all I mean is that we will go and perform the request and return the data all at once, okay? It's asynchronous, but it happens all at once and you get delivered the result at the end of it. The other way to do it is by asking for a signed NSURL request. Now, you know, many of you have mature Twitter clients.
You've already, and you've got this whole NSURL connection stack that handles errors, it handles streaming data and partial downloads and things like that. Well, how do you plug our stuff into that? So we thought of that, and we figured the best way to do it was to give you something that you can just plug right into that infrastructure. So you can call on the TWRequest object and ask for a signed URL. We take care of the signing. You dump it into your infrastructure. It does the requesting. And it's all taken care of for you.
So now I mentioned that we wanted to get rid of the OAuth stuff. And we did that in terms of the way that you guys view it. But it's still there, right? It's still under the covers. OAuth serves a really important function. It authenticates your application and your user to Twitter. So we still need to deal with it. So I figured I would show you exactly what's really going on under the covers here. So you've got your Twitter client. And it implements the Twitter framework. And you now want to make a request. And so you make up one of these TWRequest objects. And that's represented by the little Twitter bird. And now you go and you call performRequestWithHandler or you ask for a signed NSURL request. What happens next? Well, what we do is we ship that request over the wire to the accounts.de process, which has access to the user's credentials in the secure file system. And we take care of doing the OAuth signing. So we set up the base URL. We order the parameters correctly. We take care of doing all the SHA-1 stuff and setting up the NSURL request. And once that's done, then we ship it back over the wire to your process. And then it's up to your process to actually make the request to Twitter, either by using the request with handler, perform request to handler or dispatching your signed NSURL request in your network stack, right? So one thing I want to point out here is-- and I've seen a little bit of chatter about people wondering, how is my app going to be identified? Is everything going to show up as from iOS? So as part of this signing process, we actually embed enough information about your process that Twitter can identify your application correctly and attribute tweets that come from you on the Twitter website. So you won't lose that identification, right? So once it's been shipped back over to the Twitter framework, then your client app sends it over to Twitter, and they process the request and return the result back to you.
OK. So we talked about the structure of this stuff. Let's look at a little bit of code to see how you do this. So the first thing we need to do is pick the endpoint that we're going to use. And so in my example, what I'm going to do is write some code to download the user's home timeline. Now, if you're familiar with the Twitter API, you know that each of these endpoints basically can be suffixed with the kind of data that you're looking for in your response. So in this case, we're suffixing the URL with the.json suffix. And that means we're basically expecting JSON data back.
So once we've done that, then we create our parameters dictionary. And that's just a matter of-- in this case, we want to limit the number of tweets that come back on the home timeline to 10 instead of the default 200 or whatever it is. So we create a dictionary. And if you look in the Twitter docs, that's just using the count parameter. set the value to 10, the key to count. And now we go and create our TWRequest object. And so it's got one initializer that takes three values. The first is the URL that you created. The next is the dictionary of parameters to narrow down your request, and then next is the request method. And in this case, we're just going to do a simple get.
Okay, so we've done that. We've created our TW request. Now what's next? Well, in this case, we just want to use the convenience perform request with handler method. And so we're going to do that. And it returns in its block handler the response data and the NSHTTP URL response and any errors that might come back. Now, if you're familiar with NSURL connection, this might look familiar. This is the same stuff that comes back if you send a synchronous request, right? But again, it's not synchronous. It's atomic. And it'll come back and give you the response data. So let's take a look at how we handle this in our completion handler.
So I mentioned before that we suffixed our URL with the.json suffix, which means we're expecting JSON information. And there's this great new class in iOS 5 called NSJSON serialization, which will take in JSON raw data and give you a foundation object on the other side. And so that's what we're using.
And basically, what we get is an array of tweets back. Now, You know, for the sake of space, I'm not really acting on errors here, but I just want to reiterate and encourage you, handle your errors, make sure you're checking your--that NSError and the JSON error there and responding appropriately. And we're just going to assume that we have some kind of method that's updating our timeline.
So we call that update timeline, pass in that array of tweets into it. And again, completion handlers are not guaranteed to be returned on the main thread, so to be sure, we're going to dispatch async onto our main queue and call the code that updates our UI. And that's really as simple as it is. All right.
So a quick word about multipart data. How do you upload multipart data if you want to update a profile image or something like that? So I've got a little example in code of how to do that. And in this case, we're going to use the update profile image endpoint, again, with the JSON suffix, create our TW request object, pass in the URL. We don't have any parameters this time.
And then call this great method called addMultiPartData. And in this case, it's a JPEG image. Now, I'm assuming that, you know, in this code, you use the image picker or something and you get a UI image back. So we're just going to use the UIMG JPEG representation convenience method to to convert that to an NSData in JPEG format. And then Twitter expects images that are uploaded to be--that part of the form is called media, so that's the name that we're going to assign to it. And then, of course, we have to set the MIME type to be image/JPEG. And that's as simple as it is to upload multipart form data in your TW request.
Again, call perform request with handler and deal with the results that come back from that. Okay. One more time I'm going to bring Scott up to give you a demo of how to use all these APIs. We've covered a bunch of them. And he's going to do that. I think you're really going to like it. Let's give him a hand.
So thanks. So actually, if you would allow us just a moment to be a little bit serious. There's an issue that's very close to Glenn and I, and that is the current plight of monkeys. I think you can agree that they all face a lot of problems, not the least of which is issues like shrinking habitat. That's a real problem. They often are evicted from their homes, end up in zoos, where oftentimes they then become addicted to cigarettes, tobacco products. Probably a larger problem than that There's really no good Twitter client that is dedicated just to monkeys. So we're gonna try and address that today with a little app we call MonkeyGram.
So make sure I've done everything right. So this is our monkeygram application. It's very simple. It's just designed to present some wheels for a monkey to be able to roll around with and build a tweet. When it launches, the first thing it does is using the API that Glenn has discussed. It goes and tries to get a Twitter account, because monkeygram without a Twitter account isn't super interesting. So we're going to say yes. Let's allow it.
So by rolling these wheels here, we're affecting the mention, right? And rolling these guys here affects the tweet body itself. And then down here, over to the right, is the hashtag. So-- Bieber isn't big into economics, so I trust him. So we're going to say tweet. And what this is going to do is use that API that Glenn discussed to actually send the tweet. So let's take a look at some of the code that we wrote for that.
So as Glenn mentioned at first, we get our account store, we get our Twitter account type, and then we set about trying to find an appropriate Twitter account. Now I'm only-- this is just a demo, so I'm only going after the very first Twitter account that I find. One thing to keep in mind is we support multiple accounts, right? So it's kind of important when you write an app to keep that in mind. Don't just go and use the first one you find. So do as I say, not as I do. As Glenn also mentioned, based on whether or not you're going to use any UI or anything, you really need to keep track of which queue you're on. So we don't exactly know what queue this is coming on, what we're going to get this account on. So I've wrapped this code in this async call with a block so that it all executes on the main queue. And I do that because down here, depending on whether or not we found an account or not, we're going to go ahead and enable or disable that little button at the bottom.
So here's sort of the meat of sending a text-only tweet. It looks very similar to the stuff that Glenn showed you, the differences being that we're hitting a different endpoint, so we're hitting Update. And the keys that we're using are slightly different. It's very simple. It's just status, and then you put the text in there, and you're good to go. So, we would assign these parameters. These parameters are called query parameters. They go in as part of the query. They're different than the multi-part parameters which we'll show you just in a second.
So when the tweet goes out, it comes back. And as you'll see, I'm not really checking in your errors. It just plays a monkey sound, which you didn't hear, which is a damn shame, because I made that sound myself. And I'd love to have you here. So that's what would happen once the request comes back. And here, down below, you'll see I'm just using the very simple kind of fire, let it go off, and figure out what happened, and then come back and tell me about it request method. So that's how we send simple text tweets. Now if we want to do something a little more impressive, we can take a look at what it would take to send a multi-part tweet.
So this is, again, a different endpoint. It's update with media. It hits their new photo endpoint. As I mentioned, there's two types of parameters, right? There's the query parameters and the multi-part parameters. So in this, with the update with media, you don't use any of the query parameters. It's all just described in terms of multi-part data.
So this endpoint is authenticated, right? We are doing this to your account. So this is where we make sure to prime this request with the account that we got earlier. I have a little method called image data, which goes off and makes a cute little image, which I'll show you. And we add that as a part. And we go ahead and tag it with the tag media and set the type to image JPEG.
And so here you can see sort of where the status text actually comes into play. Instead of putting it as a query parameter, it comes in as just a named multi-part data thing. And again, like we discussed a little bit earlier, I wanted to show you if you wanted to fit this into an existing NSURL connection workflow, what would that look like? And so what we're doing is using this tweet request that we've made, we're getting a signed URL request. And as Glenn mentioned, that goes off and does all the OAuth hoo-ha and comes back with this special NSURL request.
And we can take that and put it into an NSURL connection that we all know and love and tell it to start. So I'm not paying attention to too many of the delegate messages, but I do want to show a little progress this time when we send a tweet, because we're pushing up this image and it could take a little bit. And so all I've done is just-- I'm overriding. I'm listening to one of NSURL's connection-- NSURL connection's delegate messages connection did send body data. And I grab the progress and we'll do something cute with it. So that's that. So let's take a look at what we did. We'll stop that one.
So let's send another tweet. Can't let Bieber have all the fun. There we go. So we'll send that guy. And now we'll actually see a little bit of progress. It was super-- network's good here. And it would have made a monkey noise, I promise. So let's go take a look and see what we actually sent. So I'm going to come over here to Twitter. And here was the message that we sent.
So you can see there's the tweet, the text part. And then we made this cute little image to go along with it. So it's very straightforward. It takes a lot of the hard work, the grunge work, of doing all this OAuth stuff. And it lets you guys go do the stuff that you presumably want to do, which is make cool, entertaining applications and not so much signing OAuth. So that's how that works. Thanks a lot.
Thanks, Scott. Wasn't that awesome? I don't think we can put it on the App Store, but we've been playing a lot with it at work, and it's pretty cool. So just a couple tips and tricks with using the TW request and the Twitter API in general. One of the important things is to remember, follow the Twitter rules of the road. They've got this document. And follow the Twitter guidelines as appropriate. Now don't do things like send tweets on behalf of the user without giving them any visual indication that you're doing so. Those are all the kind of policies that are outlined in the documents.
And then, again, I just want to point out, make sure you call those completion handlers and--or any calls that you make from your completion handlers that have to do with UI, dispatch those on the main thread to make sure things operate as UIKit expects them to. So that is Twitter integration.
It allows really simple-- it gives you a really simple interface to access the full range of Twitter's API and do really powerful Twitter clients and applications in a really simple way. So if you want more information, contact Bill Dudney. He's our application framework evangelist. Check out the Twitter documents on our frameworks at developer.apple.com and, of course, the Twitter API.
And a couple related sessions. We talked a lot about block-based APIs here, so make sure you brush up on that and check out the blocks and Grand Central dispatch and practice talk. That already happened, but there's always iTunes or ADC on iTunes. And again, you know, we're dealing with networks here, so the CoreOS networking key principles talk is probably a good one to take a look at as well. Just in summary, we covered the tweet sheet, pain-free Twitter integration, accessing system accounts, and using the TW request APIs to use the full range of Twitter application APIs. So my send off to you is go and make some really cool apps and use these APIs. And thanks for coming, and thanks for listening.