Chapter 10: TwiTorial: A Twitter Application
In This Chapter
• Using the Twitter integration components
• Creating custom colors in App Inventor
• Using the Notifier component as a screen space-saver
Twitter has been at the cutting edge of the social media revolution ever since the company started. The micro blog enabling users to send 140-character messages to the world has become an integral part of the Internet presences of people and corporations alike.
App Inventor includes a Twitter component that has many features required to create your own complete Twitter application. The App Inventor Twitter component has its limitations, which I note as you move through this project.
The value of this project is not just in putting together a Twitter application, but also in exploring how Twitter can be integrated into other applications. You should consider social network integration in many types and categories of applications. Posting statuses or updates to a Twitter feed can be an excellent way to create brand exposure. Status updates can also be used as triggers for your applications. For instance, your App Inventor application can be monitoring a Twitter account for a certain text string as a trigger event.
Creating the TwiTorial Application
The TwiTorial application is quite complex. In terms of number of events and processes, it may be one of the most complex in this book. The instructions for TwiTorial exclusively use typeblocking to create blocks in the Blocks Editor. Because of the sheer number of events and user interactions, I show you a couple of new tricks for maximizing your user interface space and create pleasing design elements. Here are some of the things I cover in this chapter:
• Using the Twitter components
• Truncating very long lists
• Using procedure with result as a text formatter
• Using dynamically sized arrangements to maximize the screen area
• Using a Notifier component as a text input mechanism
• Setting custom Android colors with numbers
Your design
The TwiTorial design specifications contain three screens, as shown in Figure 10-1. A lot goes on with a Twitter application, so you need to use some clever tricks to maximize your screen real estate and make sure the busy interface is pleasing.
Figure 10-1: Your design sketches
Your primitives
These are the basic building blocks of functionality that will be required to meet your design goals:
• Buttons/events for requesting timelines (streams of collected messages in chronological order), direct messages (DMs), mentions, and followers (those who choose to receive your tweets)
• Method for formatting for display any list returned by the Twitter component
• Buttons/events/methods for viewing, following, and unfollowing
• Method for creating single color dividing visual elements
• Method for setting custom colors
• Method for truncating extremely long lists
• Method for accepting input from user without wasting screen space for text boxes
New components
This is the primary new component for the TwiTorial project.
• Twitter component
New blocks
These are the new blocks you will be using for the project:
• Length of list
• Add items to list
A lot of primitive concepts and basic capabilities that you use for this application have already been covered in earlier chapters. The preceding list includes only new or unique primitives: A complete list of primitives would probably be three times as long.
Your progression
There is a lot going on in the TwiTorial application. The following logical steps will help you build the primitives up in a fairly progressive way:
1. Set up the user interface elements for VirtualScreen1.
a. Place the Timeline label and display elements.
b. Place the Status, Message, and Followers buttons.
2. Set up the user interface elements for VirtualScreen2.
a. Place the Followers label and display elements.
b. Place Back, Follow, and Unfollow buttons.
3. Place the VirtualScreen3 user interface elements.
a. Place the Direct Messages and Mentions labels and display elements.
b. Place the DM, Refresh, and Back buttons.
4. Place the non-visual components:
a. Three notifiers: TinyDB, Clock, and Twitter components.
5. Set up .Initialize
with authorization and formatting logic.
6. Set up the timeline polling.
7. Set up the timeline received logic.
8. Build procedures for formatting incoming lists from the Twitter API.
9. Build status update button event using a Notifier component.
10. Set the DMs and Mentions button event logic.
11. Handle the DMs received event.
12. Handle the Mentions received event.
13. Set up the Followers button event.
14. Handle the Followers received event.
15. Handle the Followers Back button event.
16. Handle the Follow Tweep button event.
17. Handle the Unfollow Tweep button event.
18. Handle the DM Send button event.
19. Handle the Refresh DMs and Mentions button events.
20. Handle the DM and Mentions Back button event.
As of this writing, the direct message functionality of the Twitter component is not working, but Google is working on a fix that may be done by the time this book is available. I show you how to build the Direct Message functionality and disable it. When Google releases the fix, you can reactivate the blocks for the Direct Message functionality.
Getting Started on TwiTorial
Start a new application project and name it TwiTorial
.
1. Make sure the Scrollable
property for Screen1 is checked. Lots of information can come in via Twitter and your user may need to be able to scroll the Android screen.
2. Upload the icon from the Chapter 10 project files and set the Icon
property.
3. Set the Title
property to TwiTorial
. You set this property here, although it changes as soon as a user authenticates with the Twitter application programming interface (API). The Title
property shows not only the title of the application but the user name who is currently authenticated.
The Twitter API is the command’s returned data that Twitter exposes from their servers to allow developers to create Twitter applications. All of the Twitter API programming has been done for you with the App Inventor Twitter component. When you use the Twitter component, all of the blocks, methods, and function calls send commands to the Twitter servers via the Twitter API.
The TwiTorial project is long enough that you may want to create checkpoints along the way. Refer back to Chapter 1 for a refresher on using the Checkpoints as version control.
Start by building up the user interface elements. The TwiTorial application has three screens. The first, VirtualScreen1, is the default screen and contains the Twitter follower timeline. The follower timeline is all of the status messages that are recent from the people you have followed. The VirtualScreen1 also provides buttons for updating your status message on Twitter. The update status or tweets are handled, like most of the other Twitter API calls, by built-in component method calls. You call the methods by using events controlled by your buttons.
1. Drag and drop a VerticalArrangement and change its name to VirtualScreen1
.
2. Set the Width
and Height
property to Fill Parent
.
Next, place the timeline display labels. These labels indicate to the user that they are looking at the timeline from their friends. Set the size of the font a little smaller than normal to get more on the screen. Be careful not to make it too small to comfortably to view. Check the view on your connected Android device.
1. Drag and drop a label into the VirtualScreen1. Rename the label lblTimelineLabel
. This label is static and indicates that the next label is displaying the timeline.
2. Set the Text
property to say Timeline from friends:
.
3. Drag and drop another label below the previous label. Rename the label lblTime-lineDisplay
.
4. Clear the default Text
property.
5. Set the Width
and Height
property of lblTimelineDisplay to Fill
Parent
.
Now place the navigation elements and buttons in a HorizontalArrangement. You need a button to allow your user to send a tweet and buttons to access VirtualScreen2 and VirutalScreen3, which are the Direct Messages and Followers screens, respectively.
1. Drag and drop a horizontal arrangement below the display label.
2. Set the Width
property to Fill
Parent
.
3. Drag and drop a button into the HorizontalArrangement. Rename it btnUpdate-Status
.
4. Change the Text
property to Update Status
. Set the FontSize
property to 12.0
pixels.
5. Drag and drop another button to the right of the previous button. Rename the button btnMessages
.
6. Change the Text
to DMs/Mentions
and change the FontSize
property to 12.0
pixels.
7. Drag and drop another button to the right of the previous button. Rename the button btnFollowers
.
8. Change the Text
to Followers
. Change the FontSize
property to 12.0
pixels.
The timeline display label is populated by the .TimelineReceived
event that is generated after a request for the timeline. The timeline consists of status updates from all the tweeps you follow on Twitter in chronological order. (Tweeps are people who use Twitter. I think it’s is a conflation of Twitter and peeps, but don’t hold me to it.) When the application initializes and the authorization is completed, the Clock timer is enabled and the timeline is regularly refreshed with the request for the timeline.
Next set up the VirtualScreen2, which is the screen where you display followers and allow your user to follow and unfollow tweeps:
1. Drag and drop a VerticalArrangement below VirtualScreen1 and rename the VerticalArrangement VirtualScreen2
.
2. Set the Width
and Height
property to Fill Parent
.
3. Drag and drop a Label into the VirtualScreen2
and rename it lblFollowerLabel
. Set the Text
property to Followers:
.
4. Drag and drop another label below the first. Rename it lblFollowersDisplay
. Remove the default Text
property text.
5. Set the Width
and Height
property on the second label to Fill Parent
.
Use a HorizontalArrangement to hold all the navigation and follower action buttons at the bottom of the followers display:
1. Drag and drop a HorizontalArrangement above the display labels and set its Width
property to Fill Parent
.
2. Drag and drop a button into the HorizontalArrangement. Rename it btnBack-Followers
.
3. Set the Text
property to Back.
4. Drag and drop a new button to the right of the previous button and rename it btnFollow
.
5. Set the Text
to Follow
Tweep
.
6. Drag and drop a ListPicker to the right of the buttons and rename it lstpkrUnfollow
.
7. Set the Text
property to Unfollow Tweep
.
In the series of steps, you will be building the third VirtualScreen, which is used to display both direct messages and mentions from the Twitter API. You will learn a method to divide the screen with a visual element designed to differentiate between direct messages and mentions. I show you a new method for of maximizing the screen real estate without having to control the sizes of all the elements inside of a VirtualScreen. You place all of your components into a VerticalArrangement that you will call AutoSizeArrangement
. Then you use Blocks Editor logic to set the size of the AutoSizeArrangement. This accomplishes the same result as merely setting the VirtualScreen
to Fill Parent
, with the difference that you can select which parts of the VirtualScreen will be considered free for expansion. In other words, you don’t want the entire VirtualScreen to expand out to accommodate the incoming messages and mentions — this would push the navigation buttons well below the visible screen. This would force your user scroll to the bottom of all the incoming messages to reach the navigation buttons. Instead, you want just the labels displaying the incoming data to actually expand to maximum size.
This is a little bit of an academic exercise, but it teaches you how to make a dynamic arrangement that is not dependent on all of your elements expanding to fill the screen. When you’re designing for larger than average screen sizes such as tablets, this can be even more useful.
The method you use sets the AutoSizeArrangement to be as tall as all of the available Screen1 size, less the size of the HorizontalArrangement holding the navigation elements. The algorithm for making dynamically sized elements is to use Width
and Height
properties blocks to set the size, using a minus block to remove the size of elements you wish to exclude. You will build the blocks later. For now, just place the required component pieces:
1. Drag and drop a new VerticalArrangement below the existing virtual screens. Rename it VirtualScreen3
.
2. Set the Height
and Width
properties to Fill
Parent
.
3. Drag and drop another VerticalArrangement into the VirtualScreen3. Rename it AutoSizeArrangement
.
4. Drag and drop a label into the AutoSizeArrangement and rename lblDMLabel
.
5. Set the Text
property to Messages:
.
6. Drag and drop a Label component beneath the previous label and rename it lbl-DMDisplay
.
7. Remove the default text.
Now you use a clever trick to create a visible element similar to HTML horizontal lines or bars that are used to build web page design elements. Use a horizontally expanding Label with its background color set to black
and its Height
property statically defined. This creates a horizontal line separating the direct messages from the mentions.
1. Drag and drop a label into the AutoSizeArrangement and rename it lineLabel1
.
2. Remove the default text.
3. Set the BackgroundColor
to Black
.
4. Set the Width
property to Fill Parent
.
5. Set the Height
property to 5
pixels.
This creates a horizontal line 5
pixels high that expands to fill the AutoSizeArrangement and separates the direct messages and mentions. Now place your mentions display elements and the navigation elements below the separator line.
1. Drag and drop a Label component below the horizontal line and rename it lbl-MentionsLabel
.
2. Change the Text
property to Mentions
.
3. Drag and drop another Label component below the previous label and rename it lblMentionsDisplay
.
4. Remove the default text.
Now place a HorizontalArrangement in the VirtualScreen3 below the AutoSizeArrangement:
1. Drag and drop a HorizontalArrangement below the AutoSizeArrangement.
2. Drag and drop a ListPicker into the HorizontalArrangement. Rename it lstpkrSendDM
.
3. Change the Text
property to DM
and the FontSize
to 10
.
4. Drag and drop a Button component to the right of the ListPicker. Rename the button btnRefreshDM
.
5. Set the Text
property to Refresh DMs
and the FontSize
to 10
.
6. Drag and drop another Button component to the right of the previous button. Rename it btnRefreshMentions
.
7. Change the Text
property to Refresh
Mentions
and the FontSize
to 10
.
8. Drag and drop another button to the right of the previous button. Rename it btnBackDM
.
9. Set the Text
property to Back
and the FontSize
to 10
.
All of the visible user interface elements should be in place at this point. Now place the nonvisible components. The TwiTorial application makes use of multiple Notifier components for its text entry pop-up. The app also uses the Clock component, the TinyDB component, and, of course, the Twitter component.
1. Drag and drop a Clock component to the Viewer.
2. Drag and drop three Notifier components.
3. Drag and drop a TinyDB component.
4. Drag and drop the Twitter component from the Social palette.
Twitter uses OAuth for communication with its API. OAuth stands for Open Authorization, a standard for authorizing and authenticating applications and users across the Internet. You can read more about OAuth at the OAuth Web site at ouath.net
. Because Twitter requires that all third party applications use OAuth to use the API, your application must be authenticated with their system before it can be used. When a user first fires up your application, it asks the user to authorize your application to access their Twitter account via the Twitter API.
There are two parts of the OAuth transaction. First, your application has to be authenticated with Twitter by you, the developer. That’s what the Consumer Key and Consumer Secret you get a little later are for. Second, your user needs to authorize the application to be used with their account. They do this by entering their username and password at the Twitter Web site when they are prompted by your application.
For this to work, you need to register your application with the Twitter OAuth mechanism. The process is fairly easy, but requires some attention to detail. The end result of registering your application is two pieces of information that you must plug into the Twitter component: the Consumer Key and Consumer Secret. Follow the steps below to get your key and secret.
1. Log into your Twitter account or the account that will represent your company, application, and so on. The account doesn’t have to be your personal one but should be an account that will have the information that Twitter and possible users need to contact you.
2. Navigate your browser to http://twitter.com/oauth_clients/new
.
3. Fill out the following fields on the New Clients form:
a. Application Name: This must be a unique name for your application. You can’t name the application TwiTorial
because I’ve already used that name. You might use something like “Jason’s TwiTorial” instead. The name you choose is what the user sees when they are asked to verify that they want your application to access their Twitter account. In this case, it asks the user if they want the Jason’s TwiTorial application to have access to their account.
b. Description: Enter text here to indicate what your application does to any user that is authenticating. Such as “The TwiTorial application is a simple Twitter client that is used to demonstrate the Twitter API integration with App Inventor.”
c. Application Web Site: This is a required field. This is the URL of a Web site where your users can access more information about your application. If you don’t have such a Web site, enter the URL for your home Web site or some other Web site. This field can’t be left blank.
d. Application Type: Set this to Browser.
e. Callback URL: This must be a valid URL; however, it doesn’t matter what URL you put here because the App Inventor Twitter component populates the correct value here. Just use the same URL you used for the Application Web site field. For developers creating Web or desktop integration, this is the return URL after the user authorizes.
f. Default Access Type: Set this to the Read/Write option.
You can leave the other fields blank.
Make sure you fill out the CAPTCHA at that bottom of the form — you know, the stretched-out twisted series of numbers and letters. The CAPTCHA is to make sure that you are a human filling out the form and not a robot.
4. When your application is registered, you see a page that displays your Consumer Secret and Consumer Key. Write these down and transfer them to the appropriate Consumer-Key
and ConsumerSecret
properties of the App Inventor Twitter component.
5. From the Design view of your TwiTorial project, click the Twitter component to make it active.
6. In the Properties column, copy the Consumer Key and Consumer Secret to the appropriately labeled property fields.
Your TwiTorial user interface should look like the one in Figure 10-2. Take special note of the dark horizontal line on VirtualScreen3 and the Consumer Key and Consumer Secret in the Twitter component properties.
Now on to building the logic and flow of your Twitter client. Try to keep in mind that this project is more to familiarize yourself with the options available for Twitter integration than it is to make yet another Twitter client. Many Android Twitter clients already do an incredible job. But is there an application that tweets the score and schedule of your PeeWee football league to all the parents? There can be, with the Twitter component and App Inventor.
Begin your Blocks Editor work by setting up the Screen1.Intialize
event handler. The .Initialize
event has quite a bit to do in the TwiTorial Application. It sets the color of the Screen1.Background
to an appropriate Twitter blue. You are familiar by this point with the preset color blocks available in the Colors drawer on the Built-In tab of the Blocks Editor. However, those are all primary and rather non-nuanced colors. Android is capable of displaying millions of colors and App Inventor is capable of using them. All colors in App Inventor are set using numbers that indicate the channel value of the RGBA. The maximum value of each channel is 255. For the R or Red channel, a setting of 255 indicates maximum red. The same is true of all the channels: Red, Green, Blue, and Alpha.
Figure 10-2: The completed TwiTorial user interface
You can read more about Android colors on the Android Developer Web site. Learn how to find the right number for the color you want at some of the App Inventor color mixing Web sites listed in the App Inventor Resources site at sites.google.com/site/appinventorresources/home/tutorial-topics/colors
.
Use a custom number value to set the color of the Screen1 background to be a light blue color:
1. Typeblock the Screen1.Initialize
event handler.
2. Typeblock the Screen1.BackgroundColor [to]
block and snap it into the event handler.
3. Typeblock a number block with the number -7164945.0
and snap it into the .BackgroundColor
block. You have to type the numbers first and then add the negative sign after the numbers are in the number block.
To test the color with your device attached, right click the Screen1.BackgroundColor block and click the Do It button. Your attached device’s background color should turn the desired Twitter blue. A number, when plugged into a set color block, is interpreted as a color value.
The Screen1.Initialize
event also has the logic for the AutoSizeArrangement in VirtualScreen1. You set the Height
property of the AutoSizeArrangement to the Screen1 height minus the height of the HorizontalArrangement holding the buttons and navigation elements on VirtualScreen3.
1. Typeblock the AutoSizeArrangement.Height [to]
block and snap it in below the .BackgroundColor
block.
2. Typeblock a minus operation block and snap it into the .Height
block.
3. Typeblock the Screen1.Height
block and snap it into the first socket on the minus operation block.
4. Typeblock the HorizontalArrangement3.Height
block and snap it into the second socket on the minus operation block.
The HorizontalArrangement you are using as a reference point should be the HorizontalArrangement that contains your buttons on the VirtualScreen3. VirtualScreen3 should be your DM and Mentions screen if you created them in the order indicated previously.
These blocks then set the AutoSizeArrangement to maximize the screen space regardless of the screen size.
Twitter uses OAuth and you should have populated the Consumer Secret and Consumer Key in the Properties column in the Design view. Here I show you how to test to see whether any information is stored in TinyDB that would indicate that a user has previously authorized the TwiTorial application. If the user has previously started your application, they would have been prompted to enter their user name and password that process will authorize your application. If you find a token indicating authorization, your application loads that into a variable so it can be tested to see if authorization is current:
1. Define a variable and set its name to varIsAuth
. Plug a blank text
block into it.
Your first set of blocks tests whether the TinyDB is empty. If it is not, it loads the contents of the TinyDB into a variable.
2. Typeblock an If
block and snap it in below the AutoSizeArrangement in the Screen1.Initialize
event handler.
3. Typeblock a not
block and snap it into the test
socket on the If
block.
4. Typeblock an equals comparison operator and snap it into the not
block.
5. Typeblock a TinyDB1.GetValue
block and snap it into the first socket on the equals comparison operator.
6. Typeblock a text
block and replace the default text with isauth
. Snap it into the .GetValue
block.
7. Typeblock a text
block and remove the default text. Snap it into the second socket on the equals operator (=
).
These blocks ask the question “Does the database contain a null
value? If not, execute the following blocks.”
1. Typeblock the varIsAuth [to]
block and snap it into the If
block.
2. Typeblock a TinyDB1.GetValue
block and snap it into the varIsAuth
block.
3. Typeblock a text
block and replace the default text with isauth
.
These blocks then load the contents stored under the isauth
tag into the varIsAuth
variable. If you attempt to load a null
value from the database into a variable, you get an error that crashes the application. Although it may seem that you sometimes initialize a variable with a nothing or null value through these projects, a blank text
block is a zero-length string and not a null value. In traditional programming, a zero-length string is frequently used as a placeholder for later data. You can think of it as a zero-length string being an empty CD but a null value being the absence of a CD.
Next, test the variable to see if it contains a true
token to indicate that the application has been authorized. If it has, the application should enable the Clock1.Timer
. If there is no true
token, the Authorize
method call needs to be called.
1. Typeblock an IfElse
block and snap it into the .Initialize
event handler under the If
block.
2. Typeblock the varIsAuth
block and snap it into the test
socket on the IfElse
block.
You can use these kinds of tests if the contents of the variable is a true or false value.
If the variable is true
, your app knows that the application has been authorized before and can get on with the business of being a Twitter client:
1. Typeblock the Clock1.TimerEnabled [to]
and snap it into the IfElse
block.
2. Typeblock a true
block and snap it into the .TimerEnabled
block.
3. Typeblock the Twitter1.RequestFollowers
block and snap it in below the .TimerEnabled
block. This requests the followers from the Twitter API, but you have to handle the actual data with the .FollowersReceived
event handler.
4. Typeblock the Screen1.Title [to]
block and snap it in below the Twitter1.RequestFollowers
.
5. Typeblock a make
text
block and snap it into the .Title
block.
6. Typeblock a text
block and change the text to TwiTorial, Logged in as:
. Make sure to leave a trailing space after the text.
7. Snap the text
block into the text
socket on the make text
block.
8. Typeblock the Twitter1.Username
block and snap it into the next text
socket on the make
text
block. This block reports the user name of the authorized user. Thus the Title of Screen1 is changed to TwiTorial, Logged in as: Jwtyler,
or whatever user name is authorized on the device.
9. Typeblock the Twitter1.RequestFriendTimeline
and snap it in under the Screen1
title block. This requests the status updates of your followed tweeps. The data is returned from the Twitter API and handled with the Twitter1.FriendTimelineReceived
event handler.
If the varIsAuth
indicates that the device has been authorized previously, the timer is enabled and a request for followers is sent. The Screen1.Title
is set to indicate the authorized user.
If the varIsAuth
does not contain true
, the else-do
socket is called, which in turn calls the authorization call from the Twitter component.
Typeblock the Twitter1.Authorize
block and snap it into the else-do
socket on the IfElse
block.
Your completed Screen1.Initialize
blocks should look like those in Figure 10-3.
Figure 10-3: The completed Screen1.Initialize blocks
The .Authorize
block calls the Twitter OAuth Web site, where the user enters their username and password to authorize your Twitter client. The authorization token is then recorded for your client.
When the .Authorize
method is called and your client successfully authorizes, the .IsAuthorized
event is generated. You use this event to record a true value to the TinyDB and the varIAuth
. The .IsAuthorized
event handler is also generated when you call the .CheckAuthorization
method.
1. Typeblock the Twitter1.IsAuthorized
event handler.
2. Typeblock the varIsAuth [to]
block and snap it into the event handler. Snap a true
block into the to
socket.
3. Typeblock a TinyDB1.StoreValue
block and snap it in next in the event handler.
4. Typeblock a text
block and change the text to isauth
. Snap it into the tag
socket on the .StoreValue
block.
5. Typeblock a text
block and change the text to true
. Snap the true
block into the valueToStore
socket on the .StoreValue
block.
6. Typeblock the Twitter1.RequestFriendTimeline
and snap it in the event handler under the .StoreValue
block. This requests the status timeline after the user has been authorized by entering their username and password.
The Clock1.Timer
component is the engine that keeps your Twitter client up-to-date. It is relatively simple, calling the .RequestFriendTimeline
every few minutes.
1. Typeblock the Clock1.Timer
event handler. Make sure the TimerInterval
property is set to 120000
milliseconds in the Properties column of the Design view.
2. Typeblock the Twitter1.RequestFriendTimeline
block and snap it into the event handler.
You have called both the timeline and followers data from the Twitter API, and now you need to handle the returning data events. However, for both of those events, you build a procedure to handle data returning from Twitter that is formatted as a list by the App Inventor Twitter component. This is very useful when you need to display data that comes in from Twitter. Almost all returned data from the Twitter API is a list. You save yourself lots of work by creating a subroutine that handles any inputted list and returns formatted data:
1. Typeblock a variable and rename it varFormattedList.
Snap in a blank text
block.
2. Typeblock a new procedure with result
and rename it procFormatAnyList
.
3. Typeblock a name
block and rename it List
. Snap the name
block into the arg
socket on the procFormatAnyList
.
4. Typeblock the varFormattedList
global variable block and snap it into the return
socket at the bottom of the procedure.
Clear out the temporary formatting variable in preparation for formatting the incoming data passed to the procedure:
1. Typeblock the varFormattedList [to]
block and snap it into the procFormatAnyList
.
2. Typeblock a text
block and sets its contents as blank. Snap it into the varFormattedList
block.
Next use a ForEach
block to format whatever list is passed to the procedure. Your ForEach
block formats the text and writes it to the varFormattedList
variable. When the ForEach
has processed everything in the list, the procFormatAnyList
returns the formatted data in the varFormattedList
variable. It becomes more apparent how this works when you use it.
1. Typeblock a ForEach
block and snap it into the procFormatAnyList.
2. Typeblock the varFormattedList
value block and snap it into the list
socket at the bottom of the ForEach
block.
Make sure that the variable socket on the ForEach has a name block in it with a var name. If you have previously placed ForEach blocks, or you have typeblocked the ForEach, the ForEach variable socket may not populate. If your ForEach block is created without a block in the variable socket, just typeblock a name block and change the name to var#, with the # being a sequential number.
3. Typeblock the varFormattedList [to]
block and snap it into the ForEach
block.
4. Typeblock a make
text
block and snap it into the varFormattedList
block.
5. Typeblock the varFormattedList
global block and snap it into the text
socket on the make
text
block.
6. Typeblock a text
block and change the default text to the newline character (
).
7. Snap the newline character into the next text
socket.
8. Typeblock the var
value block and snap it into the next text
socket.
9. Typeblock a new text
block and change it into a newline character. Snap it in the next text
socket.
10. Typeblock a text
block and change the text to a line of separator characters like this: ----------
.
Your completed procFormatAnyList
should look like Figure 10-4.
Figure 10-4: The completed procFormatAnyList procedure
Now that you have a procedure for formatting incoming lists, you can start handling some of the Twitter components’ received events.
The .FollowersReceived
events not only populate the lblFollowersDisplay label, but are also used to populate the two ListPickers you have included in your interface. lstpkrSendDM
allows users to select a follower to send a direct message to; lstpkrUnfollow
selects a follower to unfollow.
1. Typeblock the Twitter1.FollowersReceived
event handler. Notice the followers
value that is generated for use in the event.
2. Typeblock the lstpkrSendDM.Elements [to]
block and snap it into the event.
3. Typeblock the followers
value block and snap it into the .Elements
block.
4. Typeblock the lstpkrUnfollow.Elements[to]
block and snap it in under the previous ListPicker
block.
5. Typeblock another followers
value block and snap it into the new .Elements
block.
Now you use the procFormatAnyList
to format the followers
value list and then place that formatted list on the lblFollowersDisplay label.
1. Typeblock the lblFollowersDisplay.Text [to]
and snap it in below the ListPicker element blocks.
2. Typeblock the procFormatAnyList
call
block and snap it into the lblFollowersDisplay
.
3. Typeblock the followers
value block and snap it into the procFormatAnyList
block.
The data returned by the .FollowersReceived
event is passed to the procFormat-AnyList
procedure and the returned formatted data is displayed in the label.
Your completed .FollowersReceived
event should look like Figure 10-5.
Figure 10-5: The completed Twitter1.FollowersReceived blocks
You do much the same thing with the Twitter1.FriendTimelineReceived
event. However, because the data coming in with that event is likely to be a very long list, you need a method to truncate long lists. Use the Add Items to List
block in conjunction with a series of Select List Item
blocks
to pull only the five most recent status updates from the incoming timeline list. You build a new list held in the varTrimTimeline
and then pass that list to the procFormatAnyList
to be formatted and then displayed in the timeline display label.
1. Define a new variable and name it varTrimTimeline
.
2. Typeblock a make a list
block and snap it into the varTrimTimeline
variable.
3. Typeblock the Twitter1.FriendTimelineReceived
event handler. Make sure there is a name
block with the name set to “timeline” in the timeline
socket.
First, clear anything in the varTrimTimeline
variable from previous trim events:
1. Typeblock the varTrimTimeline [to]
block and snap it into the event handler.
2. Typeblock a make a list
block and snap it into the varTrimTimeline
block.
Never clear a variable defined as a list with a null text value. Doing so causes an error when you attempt to save list items to the variable.
3. Typeblock the lblTimelineDisplay.Text [to]
block and snap it into the event handler.
4. Typeblock a Make a List
block and snap it into the lblTimelineDisplay.Text
block.
Next build an IfElse
block that tests to see whether the incoming list is longer than five items. If it is longer than five items, the IfElse
calls the truncating blocks in the then-do
socket. If not, it just sends the list straight to the procFormatAnyList
and then to the display label.
1. Typeblock an IfElse
block and snap it in next in the event handler.
2. Typeblock a greater than (>
) comparison block and snap it into the text
socket on the IfElse
block.
3. Typeblock a Length of List
block and snap it into the first socket on the comparison operator. The Length of
List
block returns a number that is the number of items in the list snapped into the list
socket.
4. Typeblock the timeline
value block from the .FriendTimelineReceived
event and snap it into the Length of List
block.
5. Typeblock a numeral 5
number block and snap it in the second socket on the comparison operator.
Now build the trimmed timeline to use if the timeline list is longer than five items:
1. Typeblock an Add Items to List
block and snap it into the then-do
socket on the IfElse
block.
2. Typeblock the varTrimTimeline
global variable block into the list
socket on the Add Items to List
block.
3. Now typeblock a Select List Item
block and copy it four times so that you have a total of five Select List Item
blocks.
4. Plug each Select List Item
block in an item
socket on the Add Items to List
block. It creates a new socket for each one used.
5. Typeblock a timeline
value block that is generated when you create the Twitter1.FriendTimelineReceived
event. Copy it and paste it five times to create a total of five value timeline
blocks.
6. Snap each of the timeline
blocks into the list
sockets on the Select List Item
blocks.
7. Create five number blocks with the numbers one through five on them so that you have 1, 2, 3, 4, and 5 blocks.
8. Snap each of the sequential blocks into the Select List Items
blocks’ index
sockets. Starting with the number one block in the first Select List Items
block, go down through the blocks snapping the next sequential number into the index
sockets.
9. Typeblock the lblTimelineDisplay.Text [to]
block and snap it in below the Add Items to
List
blocks.
10. Typeblock the procFormatAnyList
procedure call and snap it into the lblTimelineDisplay.Text
block.
11. Typeblock the varTrimTimeline
global variable block and snap it into the procFormatAnyList
procedure call.
Now create the else-do
case blocks for the IfElse
block. These blocks are called if the incoming list is less than five items. If you attempt to do the trim
event on a list smaller than five items, it returns a nasty error and crashes the application:
1. Typeblock the lblTimelineDisplay.Text [to]
block and snap it into the else-do
socket on the IfElse
block.
2. Typeblock the procFormatAnyList
procedure call and snap it into the text
block.
3. Typeblock the timeline
value block and snap it into the procedure list
socket.
Your completed .FriendTimelineReceived
event handler should look like Figure 10-6.
Figure 10-6: The completed Twitter1.FriendTimelineReceived blocks
At this point, you have handled incoming followers and incoming timeline events. You have also handled timeline polling and text formatting. Now you need to start taking care of some of the button events on your user interface. The Update Status button on your VirtualScreen1 is used to send a status update to Twitter. To save screen real estate, you use a Notifier component with a text box pop-up instead of having a text box directly on the user interface. The Notifier component allows your user to input a message into a pop-up text box and then generates an event called .AfterText
input. First you call the Notifier component with the button event, and then you handle the .AfterTextInput
event for sending the status update.
1. Typeblock the btnUpdateStatus.Click
event handler.
2. Typeblock the Notifier1.ShowTextDialog
block. This is the block that pops up a text box for input.
3. Typeblock a text
block and set its text to Enter Status update <140 characters
.
4. Snap the text
block into the message
socket on the .ShowTextDialog
block.
5. Typeblock a text
block and change its text to Update Your Twitter status
.
6. Snap the text
block into the title
socket on the .ShowTextDialog
block.
Now you need to handle the .AfterTextInput
for Notifer1. Twitter status updates can be no more than 140 characters in length, so you need to test the user’s input string to make sure it is within those parameters. You also need to test for a blank text field entry because that will cause an error:
1. Typeblock the Notifier1.AfterTextInput
event handler. Make sure the response
socket has a name
block named response
in it.
2. Typeblock an IfElse
block and snap it into the event handler.
3. Typeblock an equals (=
) comparison operation and snap it into the test
socket on the IfElse
block.
4. Typeblock the response
value block from the .AfterTextInput
event and snap it into the length
block in the first socket on the comparison operator.
5. Typeblock a text
block and set its contents blank.
6. Snap the blank text
block into the second socket on the comparison operator.
7. Typeblock the Notifier1.ShowAlert
block and snap it into the then-do
socket on the IfElse
block.
8. Typeblock a text
block, set its text to No Status Entered
, and snap it into the Notifier1.ShowAlert
block.
If the user has entered some text into the text box, you need to test whether it is greater than the maximum 140 character limit and alert the user if it is. You use an IfElse
block nested in the else-do
socket:
1. Typeblock a second IfElse
block and snap it into the else-do
socket on the IfElse
block already in the .AfterTextInput
block.
2. Typeblock a greater than (>
) comparison operator and snap it into the test
socket of the new IfElse
block.
3. Typeblock a length
block and snap it in to the first socket on the comparison operator.
4. Typeblock the response
value block and snap it into the first socket on the comparison operator.
5. Typeblock a number 140
block and snap it into the second socket on the comparison operator.
6. Typeblock the Notifier1.ShowAlert
block and snap it into the then-do
socket on the second nested IfElse
block.
7. Typeblock a text
block and set its text to Status
update must be less than 140 characters
.
8. Snap the text
block into the notice
socket on the .ShowAlert
block.
9. Typeblock the Twitter1.SetStatus
block and snap it into the else
-do
socket on the nested IfElse
block.
10. Typeblock the response
value block and snap it into the status
socket on the .SetStatus
block.
This last nested IfElse
block checks to see whether the response from the user in the pop-up dialog box is greater than 140 characters and then appropriately either warns them or sends the status update to Twitter.
Your completed btnUpdateStatus.Click
and Notifier1.AfterTextInput
blocks should look like Figure 10-7.
The DMs and Messages buttons on the main screen are primarily navigation buttons in that they bring up VirtualScreen3, where the direct messages and mentions are displayed. However, they also make two Twitter API calls to prepare the display labels with content. The .RequestDirectMessages
method and .RequestMentions
method send a request to Twitter. When Twitter responds with the requested data, an event is generated and it is formatted as a list. You need to handle the btnMessages.Click
event and then move on to handling the incoming data when a successful request is made.
Figure 10-7: The completed btnUpdateStatus.Click and Notifier1.AfterTextInput event handlers
As mentioned at the beginning of this project, the Twitter Direct Messages functionality is currently broken in App Inventor. However, the issue is likely to be fixed very soon. I show you how to build the functionality and then use App Inventor’s deactivate block function to keep the Direct Message request from being called. When the Google developer team announces a fix at http://groups.google.com/group/app-inventor-announcements
, you can reactivate the blocks.
1. Typeblock the btnMessages.Click
block.
2. Typeblock the VirtualScreen1.Visible [to]
block and snap it into the event handler.
3. Typeblock and snap a false
block in the VirtualScreen
block.
4. Typeblock the VirtualSceen3.Visible [to]
, snap it in next, and set it with a true
block.
Next make the calls to the Twitter API for the direct messages and mentions:
1. Typeblock the Twitter1.RequestDirectMessages
block and snap it in next in the event handler. Right-click the .RequestDirectMessages
block and select the Deactivate option from the right-click menu.
Right-clicking any block and selecting Deactivate from the right-click menu prevents the block and any blocks it contains from being executed by your application on your Android device. Deactivated blocks turn white. To re-activate a deactivated block, just right-click and select the Activate option. The Deactivate option is a good troubleshooting tool, too. When you are unsure if an event or series of blocks are causing a bug or issue, deactivate them to see if doing so resolves the issue.
2. Typeblock the Twitter1.RequestMentions
block and snap it in next.
Now you need to handle each of the events generated when the direct messages and mentions are returned from Twitter. Thanks to your procFormatAnyList
procedure handling, the incoming lists are as simple as passing the incoming data to the procedure and placing the return result into the appropriate display label. Your procFormatAnyList
procedure starts to pay off in spades at this point. Handling repetitive tasks with a subroutine like procFormatAnyList
really speeds up development:
1. Typeblock the Twitter1.DirectMessagesReceived
event handler. Make sure there is a name
block snapped into the messages
socket with the name set to messages
.
2. Typeblock the lblDMdisplay.Text [to]
block and snap it into the event handler.
3. Typeblock the procFormatAnyList
procedure call and snap it into the text
block.
4. Typeblock the messages
value block into the List
socket on the procFormatAnyList
block.
5. Right-click the Twitter1.DirectMessagesReceived
event handler and select the Deactivate option from the right-click menu. You can reactivate this event handler when the direct messages issue is resolved by Google.
Thanks to the work being done by your list processing factory, that’s all you have to do. Now do the same for the .MentionsReceived
event:
1. Typeblock the Twitter1.MentionsReceived
event handler. Make sure a name
block is snapped into the mentions
socket with the name set to mentions.
2. Typeblock the lblMentionsDisplay.Text [to]
block and snap it into the event handler.
3. Typeblock the prodFormatAnyList
and snap it into the label block.
4. Typeblock the mentions
value block and snap it into the list
socket on the procedure call.
The btnMessages.Click
, .DirectMessagesReceived
, and .MentionsReceived
events should look like the ones in Figure 10-8.
Figure 10-8: The btnMessages.Click, .DirectMessagesReceived, and .MentionsReceived completed event handlers
Like the DMs and Messages button on VirtualScreen1, the Follower button on VirtualScreen1 is primarily a navigation button. It also sends a request to Twitter for a latest list of followers. As before, you handle the return data from Twitter in a separate event:
1. Typeblock the btnFollowers.Click
event handler.
2. Typeblock the VirtualScreen1.Visible [to]
block set it with a false
block and snap it into the event handler.
3. Typeblock the VirtualScreen2. Visible [to]
block, set it with a true
block, and snap it into the event handler.
4. Typeblock the Twitter1.RequestFollowers
block and snap it into the event handler.
You have already setup the .FollowersReceived
event because it was called from the Screen1.Initialize
block. You call the .RequestFollowers
here to make sure that the locally displayed list is still fresh.
VirtualScreen2 has three buttons: Back, Follow, and Unfollow. The Back button is purely navigational, allowing your user to return to the main screen:
1. Typeblock the btnBackFollowers.Click
event handler.
2. Typeblock the VirtualScreen1.Visible [to]
, snap it into the event handler, and set it with a true
block.
3. Typeblock the VirtualScreen2.Visible [to]
and snap it into the event handler. Set it with a false
block.
The Follow button uses the same Notifier pop-up method we used previously. It allows your user to input a Twitter user’s (or tweep’s) name and follow that person:
1. Typeblock the btnFollow.Click
event handler.
2. Typeblock the Notifier2.ShowTextDialog
block and snap it into the event handler.
This is the Notifier2 component. You are using separated Notifier components because you need unique .AfterTextInput event handlers.
3. Typeblock a text
block, set the text to Enter User Name to Follow
, and snap it into the message
socket on the Notifier2 block.
4. Typeblock a text
block, set the text to Follow Tweep
, and snap it into the title
socket on the Notifer2 block.
Now you need to handle the event generated by the user entering text in the pop-up dialog box:
1. Typeblock the Notifier2.AfterTextInput
block. Make sure there is a name
block snapped into the response
socket and that it is named response1
.
2. Typeblock the Twitter1. Follow
block and snap it into the event.
3. Typeblock the response1
block that is generated by the event handler and snap it into the user
socket on the Twitter1
block.
The Follow blocks should look like those in Figure 10-9.
Figure 10-9: The completed btnFollow.Click and Notifier1.AfterTextInput blocks
The Unfollow button is a ListPicker that is populated by the follower’s returned event. Your logic blocks allow the user to select a user and unfollow them using the ListPicker. Because the elements are already populated, all you need to do is handle the .AfterPicking
event to unfollow the selected user:
1. Typeblock the lstpkrUnfollow.AfterPicking
event handler.
2. Typeblock the Twitter1.StopFollowing
block and snap it into the event handler.
3. Typeblock the lstpkrUnfollow.Selection
block and snap it into the user
socket on the .StopFollowing
block.
VirtualScreen3 has four buttons on it. Refresh DMs and Refresh Mentions are for refreshing the display. Their event handlers access the Twitter component .RequestDirectMessages
and .RequestMentions
methods. The Direct Message button is for sending a DM to another Twitter user. The Direct Message button uses the same method as you have used previously, except with a ListPicker to populate the user field. Tapping the DM button brings up a list of followers. After a follower is selected, a Notifier dialog box appears with a text box that allows the user to enter a text message. You then handle that text with the .AfterTextInput
event. The Back button returns your user to the main screen.
First use the .AfterPicking
event to call the notifier:
1. Typeblock the lstpkrSendDM.AfterPicking
event handler.
2. Typeblock the Notifier3.ShowTextDialog
block.
This is Notifier3. You do not want to create duplicate .AfterTextInput events from a previously used notifier. Duplicate events from the same component cause your application to error out and force close.
3. Typeblock a text
block and replace the text with Enter Text for DM
. Snap the text block into the message
socket.
4. Typeblock a text
block and replace the text with Enter Message
. Snap it into the title
socket.
Now you need to handle the .AfterTextInput
event generated when your user enters some text and taps the OK button:
1. Typeblock the Notifier3.AfterTextInput
event handler block. Make sure there is a name
block snapped into the response
socket and that its name is set to response2
.
2. Typeblock the Twitter1.DirectMessage
block and snap it into the event handler.
3. Typeblock the lstpkrSendDM.Selection
block and snap it into the user
socket.
4. Typeblock the response2
value block and snap it into the message
socket.
Your user taps the DM button and is presented with a list of followers. After the user selects one of the followers, the Notifier dialog box appears with a text field for text entry. The user types their DM text, taps OK, and sends the message to Twitter. Your completed Direct Message events should look like the ones in Figure 10-10.
Figure 10-10: The completed lstpkrUnfollow.AfterPicking and Notifier3.AfterTextInput events
The Refresh buttons on VirtualScreen3 are fairly simple. They call the Twitter API to send the mentions and DMs to the device. This, of course, generates the .Received
events that you have already handled. The Back button is strictly navigational and takes the user back to the main VirtualScreen1:
1. Typeblock the btnRefreshDM.Click
event handler.
2. Typeblock the Twitter1.RequestDirectMessages
and snap it in the event handler.
Next, handle the Mentions refresh:
1. Typeblock the btnRefreshMentions.Click
event handler.
2. Typeblock the Twitter1.RequestMentions
and snap it into the event handler.
The Back button is navigational and takes the user back to VirtualScreen1.
1. Typeblock the btnBackDM.Click
event handler.
2. Typeblock the VirtualScreen3.Visible [to]
block and snap it into the event handler. Set the block with a false
block.
3. Typeblock the VirtualScreen1.Visible [to]
and snap it in to the event handler next.
4. Set it with a True
block.
With all of your events and all of your design goals met, it’s time to package the TwiTorial application for your phone. If you generate any errors, look back over the figures and double-check your blocks. Refer to Chapter 1 for a refresher on how to package your application.
The TwiTorial application is large and has a lot of events going on. The primary purpose of developing the TwiTorial app is to help you understand the Twitter integration that is possible for App Inventor applications. As I mentioned earlier, you can use Twitter integration in many applications that are not primarily Twitter clients.