Creating an iOS Testing App

Another way to create a testing application for your iphone/ipod/ipad is through the use of Apple's xcode programming environment. To be able to use it, you must own an Apple computer such as a Macbook with a Mountain Lion or Snow Leopard version of the Apple OS X Operating system. You also have to register with Apple before downloading xcode and the iOS SDK. You only have to pay when you're ready to run your apps on your own device or if you want to distribute the app. Since the membership runs for one year, it's best to delay this step until you have an app that is ready to run on a device.

The goal of this tutorial is to allow you to build a basic testing app that will let you easily recreate and distribute new apps (tests) simply by modifying the data contained in an XML data structure called a property list. Later, we can add functionality to the application such as allowing you to launch multiple tests from your application.

Design and Programming Methodology

Although each programmer feels comfortable developing applications in their own particular way, it is generally a good idea to use some kind of a methodology. For developing this particular app, I started out by thinking about what the user interface would look like. Next, I built the user interface with the xcode GUI builder. After that, I tied the button and text widgets in the GUI to method stubs that would be associated with their activity (note, I haven't started programming yet). For buttons, this would be done by associating an action with a button press. For textboxes, an outlet would take care of filling the textbox with information. Next, I thought about what the data structure of the property list should look like for the questions/answers. I then created the property list with 10 sample questions and answers. Lastly, I created the two variables that will track the correct and incorrect counts.

At this point I'm ready to program the application.

I started by writing the code for retrieving a random question from the property list and displaying it in the question textbox. Next, I wrote the code for the action performed when the user clicks the test button: compare the answer in the answer textbox to the correct answer and then display the correct answer in the correct text box. The correct or incorrect counter will be incremented accordingly.

And that's it. The application should now be ready for distribution after testing on your device and verification by Apple.

The Details

Registering as an Apple Developer and Downloading xcode

Before downloading the Xcode application development environment and the SDK for iOS development to your Apple computer, you will have to register as an Apple Developer. You can do this at the site at this link

Creating the Application

  1. In xcode, select New->Project
  2. Since this application only has a single window, select Single View Application and click Next
  3. Fill in the screen appropriately. Make sure that use Storyboards is unchecked. Click on next.
  4. Accept the defaults and create your project.

You'll see that xcode created the file stubs you will need in the left hand pane. For this application, we'll be populating several of these files.

Building the User Interface

  1. Double click on the file xxxxViewController.xib in the left hand pane
  2. Click on the "Show the file inspector tab" in the right hand pane. Uncheck "Use Autolayout"
  3. Drag all widgets you want to use in your application from the Objects section at the bottom of the right hand pane to the application screen. We'll be using 4 labels, 2 rect round buttons, and 5 Text Fields, To save time you could just copy and paste them into your application frame by clicking on the widget that you want to reproduce, go to the Edit Menu, select Copy, click on the application background and then select Paste. Position your widgets where you would like them to appear. Because you turned Autolayout off, they should appear exactly how you have positioned them when the app is being run.
  4. Now you can change the text of your widgets and the main application screen. You can change the characteristics of a widget by clicking on it, then going to the right hand pane and selecting the appropriate tab. To change the text, double click on the widget (e.g. for buttons or labels). For example you can change your preferred background colour by clicking on the application screen, selecting the "show Attributes Inspector" tab, selecting the Background list, selecting Other, and clicking on the preferred colour in the colour pie.
  5. Now you are ready to compile and run your working application that doesn't do anything in xcode's simulator by clicking the Run arrow in the top right-hand corner. Don't forget to click on stop when you have finished viewing it.

Associating Actions and Outlets

  1. Let's change the names of our action (button) and outlet (textbox) widgets so that they are easier to manage. Ideally you want to have the placeholders window beside the .xib editor. Double-click on the appropriate widget under Objects and change the name. (another way to change the name is to select the widget from the Objects list and change the name in the identity inspector Label field)

  2. Add the following code to your test1ViewController.h file. Note that we are only adding method definitions for widgets that will either be outlets or triggering an action. We are also instructing iOS, through the property directive, to retain their values in memory if a memory cleanup is performed.

  3. Create the method stubs and synthesize directives in test1ViewController.m. The synthesize directives should conform with the property directives created in the .h file.

  4. Now we should assign the Action code in the test1ViewController.m file to the appropriate push button in the application. Press the ctrl-key and click on the questionPB button, drag to the File's Owner icon in the Placeholders section. Select the questionPBWasClicked method from the displayed sub-menu. Next, press the ctrl-key and click on the testmePB button, drag to the File's Owner icon in the Placeholders section and select the testmePBWasClicked menu.

  5. Now that we are done associating the actions, lets associate our outlets. From the Placeholder's section, right-click on the Files Owner icon and find the questionTB outlet. While holding down the ctrl-key click and drag to the questionTB field in the application. Repeat this process for the other 3 outlets.

  6. Now is a good time to compile and run the application to see if you get feedback in the console when the test button is clicked (Shift-Command-R opens the console if it does not open automatically)

    Building the Property List

    Since we are creating a test, it would make sense that the questions and answers would be paired together and should be accessible via the same index (i.e. an array). The test would in turn be an array of these question/answer elements. In other words, we will create a plist that is an array of an array of 2 strings (1 string is the question, the other is the answer).
    1. Right-Click on the project folder in the left hand pane file browser and select Add file. Click on Resource then plist. Click on the new plist file in the file browser in the left-hand pane and change the name to "questions.plist"
    2. Right-click on the questions.plist file in the file browser in the left-hand pane. Select "Open As" Property List.
    3. Right-click on the root element and select Add Row. Change the type of the Root element to Array (click in the type cell to select from a dropdown list). Change the type of the "Item 0" element you just created to Array as well.
    4. Right-click on the "Item 0" element and select Add Row twice (once for question, once for answer). Ensure that the type of the "Item 0" and "Item 1" elements that you just created are String. Click on the value cell of each and change the question value to the desired question, and the answer value to the desired answer.
    5. Right-click on the "Item 0" element again and select "Copy".
    6. Right-click on the Root element and select "Paste" for however questions/answers you want in your test.
    This file should be the only modification you need to make apart from cosmetic changes to labels and titles if you want to publish a new test.

    The XML of the plist file may also be viewed by choosing the "Source Code" option when right-clicking on "Open As".

    You next need to load this data into an array in working memory for the application to use. You should only have to do this once when the application initially loads. To do this, modify the "viewDidLoad" method in the test1ViewController.m file. Note that it is always a good idea to write the contents of the arrays out to the console to ensure that the contents of the plist resource loaded into your program successfully. Since plist files are easily corrupted, you might have to recreate them to get them to work properly with your application.

    Lastly, you should define the two arrays we'll be using (call them pair_array and pair), the question, the answer, the right_count, and the wrong count in the .h header file because we will be using these throughout the application and not just locally. We are also instructing iOS (through the property directive) to retain their values in memory if a memory cleanup of the device is performed.

    Don't forget to update your .m methods file with the synthesize directives for all variables declared through the property directive in the .h file.

    Programming the Retrieve Question Method

    We now have to program the questionPBWasClicked method to retrieve a random question from the property list and to display it in the questionTB text box. We will also retrieve the question and answer from the arrays and save them to string variables. We also want to set the testme and correct text boxes to blank in expectation of the user's answer.

    Programming the Test Answer Method

    Once the user has presumably typed their answer in the testmeTB textbox and clicked the testme button, we want to retrieve this answer and compare it to the correct response as retrieved from the property list. If the response is correct we want to increment the value in rightTB, otherwise we want to increment the value in wrongTB.

    You should now have a fully functioning iOS testing application. You can put some final touches on it such as adding question/answer pairs to your plist file, rearranging the screen widgets so that they are all visible above the keyboard, commenting out any NSLog statements and changing the title.

    Running the app on your device

    1. enroll in the iOS developer program ($99 per year as of this writing) here
    2. after you have registered and activated your developer account, itunes will automatically detect that your are a developer when you plug in your device and will prompt you if you would like to use the device in question for development. (*important*, You should plug the device into the computer you hope to do future development on). If you answer yes, your provisioning profile will have been created and all necessary certificates and key files will have been created in your developer program account for download into your device
    3. go into xcode->window->organizer->provisioning profiles and ensure that a profile has been setup that will allow you to load your app into your device (note: the provisioning profile will only be valid if it has been downloaded onto the same computer into which you plugged the first device into in the step above when creating the initial profile),
    4. you can now use your device instead of the simulator for testing an application on your device. To switch between the simulator and the device as the targets when running your application from xcode, go to the Product->Scheme menu and edit the scheme to send output to the appropriate target:

    5. Plug your device into the computer that you are compiling the app on. You will be prompted if you wish to install the key onto your device and after you answer yes, you should see an icon of your app in your apps list that you should now be able to run and test (even after you unplug the device).

    Creating your own icons for distribution

    You probably noticed that the app icon is a boring white square so we might want to change it to something better.
    1. save the image that you would like as an icon as a .png file in a tool like Paintbrush or iPhoto
    2. the requirements for all of the icons needed when submitting your app for verification are very difficult to track. The site creates all requisite icons for both iphone/ipod/ipad and Android developers. Just upload your .png file to the site and a .zip file containing all of the required images will be emailed to you.
    3. Once you receive the email, open the ios folder and drag the Icon.png to the first box in your project->summary tab's "app icon" section. Then, drag the Icon@x2.png file to the second box with retinal display printed underneath it.

    4. while the device is connected, delete the current app from your device through the itunes apps tab.Then, rebuild your app with output set to your device and the app with the new icon should appear on your screen.

    Try using Voice Input for your Answers

    One advantage of using an iOS app for vocabulary tests would be the possibility of entering your response verbally through the iPhone's microphone. To do this, you would need an iPhone 4S+ or an ipad 3+ (if you also compiled your app for the ipad).
    1. Ensure that you have a connection to the internet
    2. On your iPhone, go to Settings->General->Siri . Switch it to On, Enable Siri. Select the Language that you want to answer with

    3. Go to Settings->General->International and select the language that matches the one that you selected in the previous step.
    4. Bring up the test. When you are ready to answer, go to the numeric keypad and click the microphone. (the microphone will appear on the normal keypad after first use).Make sure the keyboard matches the one you are using or it may interpret your response in a different language (use the globe key to switch keyboards).

    5. Speak the answer into the microphone and click on the DONE button

    6. Your answer should fill in the text box where you would normally type your response. (it is also a way you could check your pronunciation)

    Siri also works to fill in text fields in the canned tests or the self-created html tests. It does, however, always capitalize the first letter so you might want to take this into account when setting the answer.

    Cloning a project for a new word list

    Cloning a project can be awkward from within the xcode development environment. I do most of the cloning work at the file system level by replacing the new files of a newly-created project with the original's. What I usually do if I want to keep my old test but also create a new one is the following:
    1. create a new project with a different product name but identical other settings as the original project. It is especially important that the class prefix value be the same as the original.
    2. Copy all *ViewController.m and *ViewController.h files from your original project folder on your Macbook to your new project's project folder.
    3. Copy the .xib file from the en.lproj folder of the original project to the en.lproj folder of the new project.
    4. In the new project, create a questions.plist file using the same procedure you used to create the original. (just create the file, you don't have to add the data)
    5. Copy the questions.plist file from your original implementation (or a newly created one using some kind of XML-creation script) and replace the questions.plist file that you just created for your new project
    6. with your new project loaded in xcode, go to Product->Clean.
    7. now try to build your project and it *should* start up exactly as desired
    Once everything is in order, you can replace the icon of the newly created project using the previously discussed procedure so that you don't confuse it with your original project when running them on your iphone. Another option is using the same icon but changing the "Bundle display name" in the *Info.plist file to differentiate by name instead.

    Click here if you would like to see how you would allow your app to launch one of several tests from the main screen.

    Submitting the Application for Verification

    There are several steps involved when submitting your application for public download from the iTunes store. The first is to test it on one/some of your own device(s) to make sure it works correctly. In order to do this, you have to register the device with Apple (as you've already done in the Running the app on your own device section). If the app is for personal use only, this step should be sufficient

    If you want to submit your app for public use, you have to submit it to Apple for approval.

    Because the procedure can change often, it is best to consult the Apple developer's site for instructions. The current link as of this writing is here .

    The following are some pointers for eventually getting your app into the app store. This site, was an invaluable aid in getting to the point where an app can be submitted to the app store. The steps are nicely arranged. Be aware though, that there can be administrative roadblocks at several steps that can cause delays that are out of your hands (the whole procedure took about 1 month for me). At a high level, the following are the steps I took and the approximate order I took them in:

    1. At the itunesconnect site, set up contract and banking information in contracts, tax, and banking pages. Canadian users beware that you may have to add leading zeros to your bank transit number until your bank is found.
    2. Add your app in itunesconnect->Manage your app (this can be done before all contracts, etc are finalized). Be aware that the Bundle ID and version numbers that you assign here should match exactly the Bundle IDs and version numbers in your Project-info.plist file. You might also want to have a 1024x1024 master icon for your app handy that will be used in the itunes store to identify your app. You will also be asked to provide screen shot(s) in varying formats so make sure you have some kind of an image manipulation program handy (I used paintbrush for Mac)
    3. Add a provisioning profile which uses your distribution certificate at the developer member center. (certificates, identifiers, and profiles->iOS provisioning profiles). A provisioning profile must be created for each app you submit to the itunes store.
    4. Before validating your app you must successfully archive it in xcode through Product->Archive. This will check the certificate validity and will ensure that you are not submitting an app that gives off compiler warnings.
    5. You will become very familiar with the Project->Build Settings Screen in xcode. Make sure that your Code signing identity entries are set with your distribution certificate. To overcome archive errors which are related to an invalid certificate, you may have to (re)create your distribution cert. To do this you will have to go to the developer member center , certificates, identifiers, and profiles, iOS Provisioning Profiles, and ensure that you have a valid distribution profile. If not, create one.
    6. Once you have successfully archived your app, you can bring up Window->Organizer->Archives in xcode and validate your app. If your app has been successfully validated and setup correctly in itunesconnect and it is at status "ready to upload", you can upload your app for Apple validation by clicking on the submit button.
    7. After submission you may get an email from Apple indicating that there are some minor issues that fell through the cracks (e.g. you are now required to submit a 120x120 icon for the new iphone 5 screensize). You would then have to add the icon to your project (Add file menu) and then add it to your Project-info.plist file icons array. To resubmit you would have to reject your original binary in itunesconnect->Manage Your app->Your app->app details->binary details page and go through the archive->validate->submit process again

    By: Rene Kondratzky