Do you have an idea for an app but lack the programming knowledge to begin building it? In this weekly blog series, How to Unleash Your Inner App Developer, I will take you, the non-programmer, step by step through the process of creating apps for the iPhone, iPod touch, and iPad. Join me each week on this adventure and you will experience how fun turning your ideas into reality can be! This is Part 10 of the series. If you're just getting started now, check out the beginning of the series here (this post has been updated to iOS 7.1.)
In my previous post, you learned the basic mechanics of sending messages. There's very little you can do in Objective-C, the language of iOS development, without sending messages. In this post, we're going to put into practice what you have learned about messages and integrate social media into the iAppsReview app we've been working on in this blog. I'm also going to introduce a new Cocoa Touch Framework concept known as collections. You can get the latest version of iAppsReview from this link.
Social Media and iOS
Starting in iOS 6, Apple beefed up the abilities of iOS devices to share text, images, web pages, and so on with others by means of social media. iOS 5 already included sharing via Twitter, but iOS 6 introduced integration with Facebook as well as sharing to Chinese social networks such as Sina Weibo (indicating how important the Chinese market has become to Apple). For example, if you are in the Safari mobile browser, you can tap the Share button at the bottom center of the Safari window as shown on the left side of Figure 1. This displays a panel, shown on the right side of Figure 1 that contains a variety of sharing options including Twitter and Facebook.
|Figure 1 - The iOS Share options panel lets you share web links with others via Twitter & Facebook.|
Depending on the item you want to share, different options appear in the Share Options panel. For example, if you want to share a picture from your photo library, when you tap the Share button, the Share Options panel includes other options such as Slideshow, Assign to Contact, and Use as Wallpaper (Figure 2) in addition to the Twitter and Facebook options.
|Figure 2 - The Camera Roll Share Options panel|
Cocoa Touch Framework and Social Media
With the release of iOS 6, Apple made it much easier for developers to integrate social media with its apps by releasing the Social Framework. As you will see, it is amazingly simple to integrate with social media using the Social Media framework. When you're finished with the steps in this blog, you can compare your project to the completed (so far) version of iAppsReview, which you can get from this link.
To begin, you must first add the Social Framework to your project as outlined in the following steps:
- Open the iAppsReview project in Xcode;
- In the Project Navigator on the left side of the Xcode window, select the very top iAppsReview node. This displays the Project Editor as shown in Figure 3. On the left side of the Project Editor, under Targets, select iAppsReview. Afterwards, scroll down to the section labeled Linked Frameworks and Libraries and click the plus (+) button (Figure 3);
|Figure 3 - Adding the Social Framework to the iAppsReview project|
- Clicking the plus button displays the Add Framework dialog as shown in Figure 4. In the text field at the top of the dialog, enter the letters So to search for the Social Framework. When it appears in the list, click on Social.framework, and then click the Add button.
|Figure 4 - Filtering the list in the Add Framework dialog|
After you click Add, the Social.framework is added below the Frameworks group in the Project Navigator as shown in Figure 5;
|Figure 5 - The newly added Social.framework|
Wiring Up the iAppsReview Share Button
Now that you have the Social Framework added to the project, you're ready to create an action method for the iAppsReview Share button and write some code to display the iOS Share Options panel.
- In the Project Navigator, select the Mainstoryboard.storyboard file to display the storyboard in the design surface;
- Click the status bar at the top of the Write Review scene's view controller;
- With the Write Review scene selected, go to the Editor button group at the top of the Xcode window and click the center button to display the Assistant Editor. The WriteReviewController.m file should be displayed in the Assistant Editor. If it isn't, click the button that says Manual in the Assistant Editor toolbar, and then select Automatic > WriteReviewViewController.m from the popup menu;
- In the Write Review scene, select the Share button at the top-right corner of the scene. With the Share button selected, go to the Connections Inspector (the button on the far right in the Inspector toolbar), click the selector connection well and drag down into the WriteReviewViewController.m file between the @interface and @end statements as shown in Figure 6;
|Figure 6 - Drag from the selector connection well to create an action method.|
- When you see the Insert Action popup (Figure 7), let go of the mouse button to display the Connection popup shown in Figure 7. In the action method Name text field, enter shareReview;
|Figure 7 - The Connection popup|
- Click the Connect button in the Connection popup. This adds a new shareReview: action method declaration in the WriteReviewViewController.m file as shown in Figure 8;
|Figure 8 - The new shareReview: action method|
- We no longer need the Assistant Editor, so you can hide it by clicking the left button in the Editor button group at the top of the Xcode window;
- In the Project Navigator, click the WriteReviewViewController.m implementation file to display it in the Code Editor. Scroll to the bottom of the code file and you can see the implementation of the shareReview: method shown in Figure 9 has been added.
|Figure 9 - The empty shareReview: method implementation|
Before we get down to the business of writing code, I need to introduce a new concept that you will use when integrating social media into your app. We'll begin with the concept of variables.
A variable is a place in memory where you can store and retrieve information. It's called a variable because you can change the information that you store in it. You can store one piece of information in a variable, and then store another piece of information in the same variable. Variables declared within a method are called local variables because they can only be accessed locally from within the method in which they are declared.
You can name variables anything you want, although something meaningful is best. Also, variable names must be unique within the same scope. This means that you can't have two variables in a method with the same name. However, you can have variables with the same name if they are in different methods.
Although you can change the information stored in a variable, there is a limit on the type of information you can store. Take for example the NSString variable declaration shown in Figure 10.
|Figure 10 - An NSString variable declaration|
The first word in this statement, NSString, indicates the variable can only store information of the type NSString. As you have already learned, the NSString class is part of the Cocoa Touch Framework and represents a set of characters, so you can store any set of characters in the firstName variable, but you can't store other types of information such as an integer, true or false values, and so on. When you declare a variable in Objective-C, you always declare the type of information that it can hold.
The asterisk following the NSString declaration indicates that the variable being created holds a pointer, or reference to an object (we will learn more about pointers later in this blog series). In this case, the object is an NSString object. If you create a variable that does not hold a reference to an object, but points to a single, scalar value such as an integer or Boolean (true or false) value, you don't use an asterisk as shown in the BOOL variable declaration in Figure 11.
|Figure 11 - A BOOL variable declaration|
So, if you see a variable declaration that includes an asterisk, the variable contains a pointer to an object. If it doesn't contain an asterisk, the variable contains a single, scalar value.
Understanding Arrays and Other Collections
Now that you have a basic understanding of variables, it's time to learn about arrays and other collections.
When you hear the word "collection," you might think of stamp or coin collections. This is a good metaphor for collections in Objective-C because they provide a way to group one or more related objects together.
All the variables and properties you have worked with so far have held a single value (such as a Boolean (BOOL), or a single object). In contrast, Cocoa Touch Framework collection classes allow you to group multiple items together into a single collection. The primary collection classes are:
Often, collections are used in iOS apps to create lists. For example, you can have a collection of strings used as a list of songs, or an array of images used to display album covers. Note that items in a collection are usually of the same type, but this isn't a restriction. In fact, the list we are going to use to integrate with social media will eventually contain different types of items.
We'll be talking more about the different collections available in iOS apps, but in this post, I'm going to concentrate on NSArray. The NSArray class is one of the most basic kinds of Objective-C collections. You declare an NSArray variable just as you would any other variable. Notice that you use an asterisk when declaring an NSArray variable indicating that it's a pointer as shown by the declaration in Figure 12.
|Figure 12 - An NSArray variable|
To initialize an array with a set of values, you can use the initWithObjects: method. For example, check out the code shown in Figure 13. We'll be learning a lot more about alloc and init methods in a future post, but for now, you just need to know that this code creates an array with five strings and stores the array in the names variable.
|Figure 13 - Initializing an array with a set of values|
Notice the last item in the list is nil, indicating the end of the list. If you forget to put a nil at the end of the list, you will get the compiler warning, "Missing sentinel in method dispatch", although I think "Missing nil" would be a bit clearer!
When using Xcode 4.5 or later with the Apple LLVM Compiler 4.0 or later, you can create an NSArray more easily using the syntax shown in Figure 14.
|Figure 14 - The new array initialization syntax|
The '@ sign' and square brackets are part of the new syntax. Notice you don't have to end the list of objects with a nil (in fact, you'll get a compiler error if you do).
To find out how many items are in an array, you can access its count property as shown in Figure 15.
|Figure 15 - You can get the number of items in an array from its count property.|
There are a few things to notice about this code. First of all, the itemCount variable doesn't have an asterisk, so this indicates it holds a single, scalar value rather than a reference to an object. Secondly, when referencing a property on an object, you specify the name of the object (names in this case), type a period, and then type the name of the property (count in this case). You'll learn much more about properties later in this series.
Creating an Outlet
Now that you have a basic understanding of variables and arrays, it's time to move on and write some code. The code that we write will take the text that the user entered in the Write Review scene's text view and share it in a variety of ways including Facebook and Twitter.
However, in order to get the text the user enters in the text view, we need a way to reference the text view from the WriteReviewViewController code file. It often surprises new iOS developers that, by default, there is no way to reference a user-interface control on a scene from the associated view controller. Fortunately, it's very easy to make this happen using Xcode. Ultimately, you need to create an outlet, which is a special type of property through which code in the view controller can reference a user-interface control. Let's do that now.
- First, select the Mainstoryboard.storyboard file in the Project Navigator and then click on the navigation bar at the top of the Write Review scene to select the scene's view controller. Afterwards, display the Assistant Editor by clicking the middle button in the Editor button group at the top of the Xcode window. If the WriteReviewViewController.m file is not automatically displayed in the Assistant Editor, select the file using the instructions I provided earlier in this post;
- Next, hold down the Control key, click the text view in the Write Review scene and drag your mouse pointer down into the WriteReviewViewController.m file directly above the shareReview: method declaration as shown in Figure 16;
|Figure 16 - Control+Drag down from the text view into the WriteReviewViewController.m file.|
- When you see the Insert Outlet or Outlet Collection popup appear, let go of your mouse button and the Control key. This displays the Insert Outlet popup shown in Figure 17;
|Figure 17 - The Insert Outlet popup|
- In the outlet Name text field enter tvwReview and then click the Connect button. This adds the outlet property declaration shown in Figure 18 to the file.
|Figure 18 - The new tvwReview outlet property|
In Objective-C, properties are similar to variables. They provide a place in memory where you can store and retrieve information. Let's take a closer look at the property declaration that Xcode generated for us. Here are some important things to note:
- The property declaration begins with the keyword @property;
- The weak and nonatomic keywords are advanced concepts that we will discuss in a future post;
- The IBOutlet keyword indicates that this property is intended to be connected to a user interface control on the associated scene;
- UITextView * specifies the type of information the property can hold—in this case a reference to a UITextView object. Just as with variables, the asterisk indicates the property contains a reference to an object;
- The name of the property is tvwReview. I like to name my outlet properties with a three-character prefix that indicates the type of object the property is associated with. I use tvw for text views, txt for text fields, img for image views, and so on.
There is one other important concept to note about properties. Properties can be accessed from within methods declared in the same class as well as from methods in other classes. In object-oriented terminology, this means that properties are public;
- There is one other very important point to note about this outlet property. As shown in Figure 19, if you hover your mouse pointer over the connection well to the left of the outlet property, the associated user-interface control is highlighted in the design surface. Very nice! By the same token, if the connection well has light gray center rather than a dark gray center, it indicates that the outlet is not connected to any user-interface control. When you see a disconnected outlet property, this is usually a problem because an outlet that's not connected to a user-interface control is useless!
|Figure 19 - Hover over the outlet's connection well to see the associated user-interface control.|
- Let's close the Assistant Editor since we don't need it right now. To do this, click the left button in the Editor button group at the top of the Xcode window.
Implementing the shareReview: Method
Now that you have an outlet connection to the Write Review scene's text view, you're ready to write the code that shares the review via social media.
- In the Project Navigator, select the WriteReviewViewController.m implementation file;
- Click in the code window directly to the right of the left curly brace at the end of the first line of the shareReview: method. Press the return key twice to add two empty, blank lines within the method's curly braces;
- Now we are going to declare an NSString variable that can hold the text the user has entered in the Write Review scene's text view. To begin, type the code NSString *reviewText as shown in Figure 20;
|Figure 20 - Create a reviewText variable|
- Now we need to retrieve the text from the text view and store it in the reviewText variable. To do this, type a space and then type the code = self.tvwReview.text; as shown in Figure 21. In Objective-C, a single equal sign is the assignment operator. It assigns the value on the right side of the equal sign to the variable or property on the left side of the equal sign.
|Figure 21 - Retrieve text from the text view.|
On the right side of the equal sign, the code in Figure 21 references the tvwReview outlet property you created in the previous section. Notice when referencing a property that's declared in the same class as your method code, you first type self, which refers to the class (in this case the WriteReviewViewController class). Next, you type a period, and then the name of the outlet. After that, you type the name of the property on the text view object that you want to access (in this case, text), and then you finish the line of code with a semicolon;
- Now we are going to add another line of code that declares an array that will contain the items that we want to post on social media networks. To do this, press return and then type the code NSArray *activityItems as shown in Figure 22.
Figure 22 - Declare the activityItems array.
Based on what you have already learned, you can determine that this code declares a variable named activityItems that holds a reference to an NSArray object. Now let's write some code that creates an array and stores it in the activityItems variable. As shown in Figure 23, type the code = [NSArray arrayWithObjects (make sure you type an "s" at the end). This displays the Code Completion popup.
Figure 23 - Create the activityItems array.
Make sure the highlight bar is on the first arrayWithObjects: method in the list, and then press the return key. This inserts the template shown in Figure 24 into the code file.
|Figure 24 - The arrayWithObjects: code template|
Based on the information you learned in my previous post, you should be able to determine that the code you have entered so far sends an arrayWithObjects: message to the NSArray class. This method creates an array containing the arguments you pass—one array item for each argument. For now, we're just going to pass one piece of information (the review text), and we'll come back and enhance the code later;
- In the code template placeholder (shown in Figure 25), type reviewText, then press the tab key to move past the closing square bracket and type a semicolon (;) to complete the line of code. When you're finished, your code should look like Figure 25;
|Figure 25 - The completed code for the array|
- Now you're ready to write the actual code that displays the iOS Share panel. With your cursor still at the end of the previous line of code, press return to create a new, empty line. Now enter the code UIActivityViewController *avc as shown in Figure 26.
|Figure 26 - Declare a variable named avc of the type UIActivityViewController.|
UIActivityViewController is a class that is part of Social.framework that makes it extremely easy to display the Share Options panel in your iOS apps;
- Next, you're going to write some code that creates an object from the UIActivityViewController class. Again, we'll dive in more deeply on creating objects in a future post. For now, just enter the code [[UIActivityViewController alloc] and press return as shown in Figure 27. We are writing a single command, but Objective-C allows you to wrap a single command onto multiple lines. When this technique is used properly, it can make your code easier to read;
|Figure 27 - Continue writing the code that creates a UIActivityViewController object.|
- Now enter the code initWithA and the Code Completion popup will appear as shown in Figure 28;
|Figure 28 - The initWithActivityItems: method appears in the Code Completion popup.|
- Press return to insert the code template for this method. The first placedholder contains text that indicates it wants you to pass an array. Type activityItems to pass this array as an argument and then press return to break the command into yet another line (Figure 29);
|Figure 29 - Pass the activityItems array as an argument.|
- Press tab to go to the final placeholder in this code template, and type nil as the argument. This argument specifies custom services that your app supports. Since the app doesn't have any custom services, we entered nil. Next, press the right arrow (located at the bottom-right corner of your keyboard) to move past the closing square bracket, and then type a semicolon (;) to complete the statement. When you're finished, your code should look like Figure 30;
|Figure 30 - The completed code statement that creates a UIActivityViewController object.|
- Now that you have created an object from the UIActivityViewController class, you need to display the view controller. Now that I've guided you through using Code Completion and entering arguments into the code template, you're ready to try this one on your own. Go ahead and enter the new line of code shown at the bottom of the method in Figure 31.
|Figure 31 - Show the Activity View Controller.|
Take a moment to see if you can figure out what this line of code does (I'll wait for you).
This code sends a presentViewController:animated:completion: message to self, which is the WriteReviewViewController. In the big picture, you are asking the WriteReviewViewController to display, or present, the activity view controller. When you pass YES for the animated argument, the screen appears with a nice animation—sliding upward from the bottom of the screen. We don't need any code to execute after the view controller appears, so we pass nil for the second argument.
Now let's run the app in the Simulator and see how it works!
Testing the App in the Simulator
All right, now it's time to kick the tires and see how the code you have just written works.
- Click Xcode's Run button to run the app in the Simulator;
- Before you try out the new social media feature of the app, you must first set up Twitter and Facebook accounts on the Simulator. To do this, click the iPhone Simulator's Home button (the large circular button at the bottom of the iPhone). This displays the iPhone Home screen. Click the Settings app's icon on the Home page and scroll to the bottom of the screen until you see the Twitter and Facebook options shown on the left side of Figure 32. Select the Twitter option and add your Twitter account (the center image in Figure 32), then select the Facebook option to set up your Facebook account (the image on the right in Figure 32);
|Figure 32 - The Simulator's Settings app allows you to set up Twitter and Facebook accounts.|
- After setting up your accounts, click the Simulator's Home button to display the Home screen, and then click the iAppsReview app icon to launch the application again. When the app appears in the Simulator, click the Write a Review option. Click in the text view control, and when the keyboard appears, type in any text you want. For example, you could write a shameless plug for iPhone Life magazine and tout your new-found app-writing skills at the same time:
I posted this message from an iPhone app I created myself from tutorials in an iPhone Life blog. Awesome!
- Whatever you decide to write, when you click the Share button at the top right of the scene, the Share Options panel appears as shown in the image on the left in Figure 33. If you click the Twitter button, your review text appears in the Tweet window shown in the center image in Figure 35. If you click the Facebook button, your review text appears in the Facebook window shown in the image on the right in Figure 35. If you click the Send button in the Tweet window or the Post button in the Facebook window, it will really post these messages for you. Give it a try!
|Figure 33 - The Share options panel allows you to tweet or post your review text to Facebook.|
Conclusion—Your Homework Assignment
Now that you have learned the basics of variables, arrays, properties, outlets, as well as working with the iOS Social Framework, I've got an assignment for you. I find that trying something on your own really helps test what you know and provides an invaluable learning experience.
As it stands right now, the name of the app you are reviewing (as specified in the text field of the Write Review scene), doesn't get posted—only the review text is shared. For your homework, I'd like you to enhance the app so the name of the app as entered in the text field in the Write Review scene is also posted on Facebook and included in your Tweet. Here are the basic steps you need to follow to make this happen:
- Create an outlet for the text field;
- Change the shareReview: method to append the name of the app to the text of the review (hint: check out the NSString stringByAppendingString: method);
In my text post, I'll provide the solution to this assignment and you can see how well you did!