Showing posts with label library. Show all posts
Showing posts with label library. Show all posts

Saturday, August 4, 2012

Tutorial 12 - Submitting to the App Store Part 1

Webcomic Courtesy of Ethanol & Entropy

12.1 The App Store Journey


For many people the whole point of writing applications is to see them published in the App store and available for download from iTunes. Before you quit your job and go out and buy matching Porsche 911's you would be wise to get a few months of sales data under your belt. Like most endeavours, there is a bell curve of App sales. Everyone hears about Angry Birds developers making $70m, but there is a lot less media coverage at the other end of the bell curve. 

In a recent survey of more than 1,500 developers in 83 countries, it was found that the average per-app revenue is roughly $1,200 to $3,900 depending on the platform. Additionally, the survey noted that an app has roughly a 35% chance of generating between $1 to $500. This obviously means that most developers cannot rely on app development as their main source of income. However, it does mean that if you put the effort in you can make enough to fund your development habit. 

Our own experience is that you can never tell which Apps are going to be regular sellers (LifeGoals) and which will sink like a stone (LifeMovie). The Reefwing stable of Apps currently nets us around AUD$10k per annum, which is sufficient to purchase a MacBook Air, a new iPad, external development costs (Apple Developers Licence, App Sales Analytics, web-site and forum costs, etc.) plus a bit of change for the highly caffeinated beverages which programmers run on. We only work on this the odd night and weekend so with more application we imagine the rewards would be better. The thing that we are no where near recovering is the time spent developing. The average App takes us about 3 months from start to finish and while the proceeds roll in for some years to come, it isn't really passive income because sales quickly decline if you aren't frequently updating your App. 

However, lets face it - we would code if we didn't get paid anything so anything we do get is a very pleasant upside. There is also something addictive about tracking the daily "sales" of you App (even if it is free).

The other thing that most developers don't realise, is that the Apps which are successful in the App store, have as much time and money spent on marketing their Apps as they do on developing them. There is the odd exception but these are an exemption. Books have been written on this subject and we will provide our thoughts on the best approaches to marketing in a later tutorial.

But for now, let's have a look at how we go about getting our Minesweeper game submitted for approval.


Figure 1. Xcode in the Mac App Store.


12.2 What do I need and how much will it cost?


The process of getting your App approved is fairly straight forward but there is a fair bit of assumed knowledge which we will attempt to clarify. Sometimes we may miss a step due to our familiarity with the process and software, so don't hesitate to drop us a comment if you get stuck. This will help not only yourself but future readers.

To get your App in iTunes there is a bit of an investment. Presumably if you are reading this you already have an iPad and Codea, so we will assume that they are a sunk cost. All of the costs below are in Aussie Dollars unless stated otherwise. In addition to Codea on your iPad, you are going to need:

  • Some variety of Mac which will run Xcode (there are virtual machine solutions for those who want to do it the hard way or save money (e.g. for Windows or the Mac In the Cloud solution), but that is outside the scope of this tutorial). Any recent Mac will do the job so the cheapest new solution at the time of writing would be a Mac mini from $699 if you already have a monitor and keyboard.
  • A paid App Developer Licence. These come in a variety of flavours but the cheapest will cost you $99 per year. We have a company licence for tax reasons but individual is fine (and simpler to apply for). There is a bit more effort required if you want to sell apps (as opposed to making them free) but it doesn't cost any more, apart from the 30% cut of every sale that Apple keeps. You can register for free developer licence but this doesn't allow you to upload an App on iTunes. This process used to take a bit of time so apply before you need the licence. 
  • A copy of the Apple Xcode 4 Integrated Developer Environment (IDE), which is available as a free download on the Mac App Store (that also includes the OS X. and iOS  Software Development Kits - see Figure 1) to registered members of Apple’s iOS and Mac Developer Programs. This tutorial is based on version 4.4 of Xcode which runs on the Lion and Mountain Lion variants of OS X.
  • A copy of iExplorer from Macroplant so that you can extract your Codea project from your iPad and load it into Xcode. This costs $31.04 (US$31.49). We are using version 3.0.1.2 for this tutorial. There is also a free program for linux users called libimobiledevice which I understand comes in Windows and OS X variants but we haven't used it (thanks to Andrew Stacey for pointing it out). Another FREE option is iFunBox (thanks to Keebo for this suggestion).
  • The Codea Runtime Library - Which we will discuss in some detail in the next section. It is available free, courtesy of Two Lives Left. Version 1.4.3 was the version we used for the tutorial, it appears to still be a Beta version but works fine apart from some warnings when you compile.
  • And finally an internet connection is required, so that you can upload your App to iTunes Connect.

12.3 Step 1 - Download and Extract the Codea Runtime

    
[UPDATE: An assumption here is that you have already developed your App in Codea and it is operating without any obvious run time bugs. Don't bother submitting buggy code to Apple it will just be rejected and if by some chance it gets through the approval process, you will get a reputation for developing poor quality software. 

One of the issues with the App store process is that if you delete an App from your device it prompts you to rate it and provide a comment. Obviously, if a user is deleting an App it is likely that they are not going to rate it very highly. Since most happy users of you App wont bother to rate it (unless asked to), this can lead to a negative bias in ratings and comments which will dramatically effect your downloads and sales. 

To offset this bias it is good practise to prompt your users to rate and comment on your App just after something positive has occurred (e.g. a level in a game was completed) or if they have been using the App for some period of time. Under these circumstances you are much more likely to get a positive review. Like most things, moderation is the key, badgering your users for positive reviews will likely produce the opposite effect to what you were intending.

IMPORTANT: The latest version of Codea (v1.4.3) supports dependencies. These are a great tool for re-using code but unfortunately the current runtime (also v1.4.3) doesn't know how to handle them. So don't use dependencies if you plan on submitting your code to the App store.]

In order to submit your App you first have to get it working in the simulator on your Mac. We will also use this opportunity to add a touch more polish. The native language of iOS is Objective C so getting your Lua Codea App to run in Xcode requires the Codea Runtime Library


Figure 2. Git repository of the Codea Runtime Library.

Clicking on any of the Codea Runtime Library links in this tutorial will take you to the Git repository for the code (Figure 2). From here you can read a short description of the library, the current version, licence information (Apache License v2.0), requirements and setup. Have a read of all of this and then click on the zip button in the top left of the page to download a zipped copy of the Library and a script (make_project.sh), to your Mac development machine. We use chrome as our browser and in this you can right click (control click) on the downloaded file and select "Show in Finder" to take you to the file. Whatever you are using, locate the downloaded zipped file which is probably in the Downloads folder (depending on your preferences) and called something like "TwoLivesLeft-Codea-Runtime-1.4.3-0-g1539e18.zip", and then double click on it to decompress the archive.

This will create a folder called "TwoLivesLeft-Codea-Runtime-1539e18" or similar which contains a Codea Template folder, a copy of the licence, the readme file and the make_project script. To save on typing in the next step we renamed the folder "TwoLivesLeft-Codea-Runtime-1539e18" to "Codea" - but this is optional.

The next step requires us to get our hacker hat on and use Terminal. This is where the setup instructions in the Codea Runtime library assume a bit of knowledge, but don't worry we will take it slowly.


12.4 Step 2 - Enter the Terminal


    
Terminal is a program included with all versions of Mac OS X. It is located in the Utilities folder within the Applications folder. When launched, it provides a command line interface to control the UNIX based operating system. The default UNIX shell in Mac OS X Panther (10.3) or later is called Bash.


Figure 3a. The Terminal Application.

Go ahead and launch Terminal, you will see a window like that shown in Figure 3a. You should be in the root directory at this point. Type "ls" (don't include the double quotes) and you will see a list of files and directories which are in the current directory. You need to navigate to the directory which contains the files you just downloaded and extracted. In our case we first change directories to Downloads by typing "cd Downloads", you should see the  Terminal prompt change to something equivalent to:

DS-MacBook-Air:Downloads dsuch$ 

Type "ls" again if you have forgotten what the extracted zip folder is called, we changed the name to "Codea" so that we could remember, thus at the prompt we now type "cd Codea". 

Okay you should now be where we need to be. Type "ls" to check, hopefully you see:

DS-MacBook-Air:Codea dsuch$ ls
CodeaTemplate README.md
LICENSE-Codea.txt make_project.sh
DS-MacBook-Air:Codea dsuch$ 

This next step will create an Xcode template for your Codea project with the same name as your App. At the command line prompt, type "./make_project.sh yourAppName" where "yourAppName" should be replaced with the name of your App. Don't miss the full stop "." at the start of the script, this means run a command script in the current shell.

Note: if you plan to release your game on the iOS App Store please do not use the word "Codea" in the title of your game. (You may, however, mention Codea in the description and keywords for your game. Or in the game itself.)

There will be a brief pause when you execute the script and then the command prompt will return. Do another "ls" to see the newly created Xcode folder. Remember our App is called Minesweeper so the results look like:

DS-MacBook-Air:Codea dsuch$ ./make_project.sh Minesweeper
DS-MacBook-Air:Codea dsuch$ ls
CodeaTemplate Minesweeper make_project.sh
LICENSE-Codea.txt README.md
DS-MacBook-Air:Codea dsuch$

Notice the new directory called Minesweeper? That's what we need. We won't go into the detail of the bash script used but those really interested can work it out themselves by looking at the list of bash commands and the contents of the script.
      
You can now close down Terminal (command w will close the window), but remember where your new Xcode folder is located.

Figure 3b. The custom Dropbox.spritepack folder on the iPad
 
[Update: If you use custom sprites in your project then you need to copy across your Dropbox.spritepack folder (using iExplorer it is in Apps -> Codea -> Documents - see Figure 3b) and place it in the SpritePacks folder in the project created by running the script. In our example, the destination folder is Minesweeper -> SpritePacks. You will see the other standard sprite packs in the same location. To save space you could delete the images you don't use in this App from the copy of your Dropbox.spritepack folder.

If you haven't used iExplorer before then read section 12.6 below to get it set up. To copy from your iPad to the Mac, navigate to the location of the Dropbox.spritepack folder and right click on it, then select "Export to Folder" from the pop up menu.]

The next bit is optional but we think it is good practise. All of our Xcode projects are kept in a directory imaginatively called "Xcode Projects". Locate your newly created Xcode folder (in Downloads\Codea: for us) using Finder and copy or drag across to the directory where you will store your projects (Figure 4). 

Figure 4. Codea Runtime Xcode Template in Finder

In Figure 4. you will see a file in the Minesweeper directory called CodeaTemplate.xcodeproj, you can double click on this to load the project into Xcode, or follow the instructions in the next step.


12.5 Step 3 - Opening up the Codea template in Xcode


Stage 1 is almost complete. Open up the Xcode App, click on file, open in the menu bar and navigate to your new Xcode directory described in the previous section. Single click on the directory name and then click on the open button in the bottom right of the open file dialog. This will load the CodeaTemplate project into Xcode. 

[UPDATE: DO NOT run and compile the default runtime until your project is loaded and has replaced the Dungeon Roller project (see the next section). When the runtime is executed it copies the Lua files from the Project.codea folder into the iPad's document folder for this App. If you do this with the default folder it will copy across all the Dungeon Roller files and leave them there. At worst you may have Lua files with the same name which will cause very odd behaviour and will probably cause the App to crash. At best you are taking up unnecessary space on your iPad.]

If you do want to just see the default runtime project in operation, then in the top left of the Xcode screen you will see a play button, click on that to compile and run the loaded project code (Figure 5). As the project compiles you may see a bunch of warnings, don't worry about those. Eventually the iPad simulator will launch with the default Codea App "Dungeon Roller", one of the example Apps provided with Codea.



Figure 5. Xcode 4 and the iPad Simulator.

It is all very well to have an operating Codea Template project, but how do we inject our App so that it is playing in the simulator not "Dungeon Roller"? This is where iExplorer comes into play. Leave Xcode open as you do the next step.


12.6 Step 4 - Extracting your Codea project from the iPad


Connect your development iPad to your Mac using the USB cable and then launch iExplorer. All going well, iExplorer should look like Figure 6.


Figure 6. iExplorer connected to iPad

Using the left hand pane, navigate to Apps -> Codea -> Documents (Figure 7) and find your App folder (Minesweeper.codea in our case), right click (control click) on this and select "Export to Folder" from the pop up menu. It doesn't matter too much where you save this folder, we put it in Downloads.


Figure 7. Find your App in iExplorer and Export it to your Mac.

Back in Xcode, open up the classes folder using the left hand navigation panel (if you can't see the folders and files then click on "show the project navigator button" in the top left hand corner - it looks like a grey folder). Delete the existing Project.codea folder by right clicking (control click) on it and choosing delete from the pop up menu, select "Move to Trash" in the subsequent dialog box.

Open up Finder on your Mac, locate the yourAppName.codea directory and rename it "Project.codea". Drag your Project.codea folder into Xcode (just below the classes folder) and when you release the mouse button you will see Figure 8.


Figure 8. Import your Project.codea directory into Xcode


Check the "Copy items into destination folder's group (if needed)", Select "Create folder references for any added folders" and make sure your app's target is selected, then Click Finish.
 
You should now be able to compile and run your application in the Xcode iPad simulator. 
   
[Update: An alternative approach to that described in the Codea runtime (which we have described above) would be to: 
 
  1. Close Xcode.
  2. In iExplorer navigate to your Apps folder within Codea (e.g. Apps -> Codea -> Documents -> Minesweeper.codea).
  3. Right click on this folder and select "Export to Folder"
  4. Navigate into the folder created by step 2 (section 12.4). In our case it is called Minesweeper. Within this folder you will see a folder called CodeaTemplate.
  5. Within CodeaTemplate you will see the Project.codea folder. Export your project file (e.g. Minesweeper.codea) into this location.
  6. Right click on the default Project.codea folder and select "Move to Trash" from the popup menu.
  7. Rename your file to Project.codea
  8. Open Xcode and from the Menu -> File -> Open: select CodeaTemplate.xcodeproj from the folder created in step 2. ]

Sunday, July 29, 2012

Tutorial 10 - A Simple Dial Class


10.1 Your Personality and a Little Maths


This tutorial is based on some code that we ported from our iPhone App Personality Profile. In this App you use a dial to answer a number of questions and a profile is provided based on your selection. We used a dial because we wanted a touch friendly solution and this seemed like an intuitive approach. The App is FREE on iTunes so download it and compare the functionality of the Objective C version to our Lua implementation. The embedded video above gives you an idea of how it works but the effect is better understood when used on your iDevice.


The trick to working out how to move the dial is a mathematical one. In essence you need to convert the cartesian co-ordinates of your finger on the screen to equivalent polar co-ordinates.

It is about now that you realise that those maths lessons way back weren't completely useless and perhaps you should have paid more attention. Don't panic, all you need to know is that it is possible to convert from a point (x, y) to polar co-ordinates which consist of an angle and a distance. The angle tells you how much to rotate the dial and you can use the distance portion to work out whether a point is within a circle which is handy for detecting if a tap was on the dial.

To make life easy we created a function which does all the hard work. We have reproduced it below but note that you also  need the math.hypot() function which isn't available in the Codea version of Lua. Both of these functions (and more) are contained in the Math tab of RSLibrary.

We have made use of the new Codea dependency functionality so if you download the entire tutorial code in one file, then you also need to download RSLibrary and link it as a dependency to DialDemo. See Tutorial 9 if you want to understand dependencies better or see what is in RSLibrary. For this tute you only need the Math and Button tabs but you might as well grab the whole thing.

As an aside, a handy trick which we use in the math.polar function is to assign a default value to a parameter using "or". This works because nil evaluates to false in Lua. See the code below to understand how you can use this to overload functions.



10.2 The Main Class

   
In this instance the Main class is just there to demonstrate the Dial Class. Both Landscape and Portrait orientations are supported using the orientationChanged() function.


      

10.3 The Dial Class


The Dial Class is where the magic happens. We only have a licence to use the knob and dial images in our App, so you are going to have to draw or obtain your own version. Strictly speaking you only need a knob image (the bit that moves). The class should handle any differences in size to our sprites.


   

Friday, July 27, 2012

Tutorial 9 - Dependencies & Libraries


Webcomic Courtesy of Ethanol & Entropy


9.1 What is a Dependency and why do I want one?


The latest version (v1.4.3) of Codea introduced the concept of Dependencies. This feature is used to address the problem that over time there are certain functions or classes that you use again and again but you don't want to have to re-type these in each project. 

Prior to version 1.4.3 the answer was to copy and paste the relevant bits from one project to another. This works ok but it is a bit slow, breaks up your workflow and can lead to version problems if you forget where the master copy is located.

A better solution is to have a library which contains all of these functions and classes which you can then "include" in your projects as required. If you select the library as a dependency to your project then all of the code (outside the Main tab) within the library becomes accessible to that project.

You don't have to create a specific Library to use dependencies, any project can be selected as a dependancy, but to address the version control issue it is better to keep this code in a consistent location. We haven't worked out if it is better to have many small libraries or one big one. Our guess is that it won't make a difference as the compiler will just lift out the code it needs and a large library won't create unnecessarily bloated byte-code. 

9.2 How do you create a Library?


A Library is just another project. There are no rules or guidelines as to what a Library should look like so we are just going to do what seems sensible and allow it to evolve over time. To provide something to talk about we created the (Reefwing Software) RSLibrary which is a collection of code which we have found useful but isn't currently available within the Codea framework. 

We have structured the Library with the Main tab containing metadata (contents, version, date, etc.) and which if run, will demonstrate the main functionality of the code in the Library. Each subsequent tab contains the code we want to share grouped in what we think is a logical fashion.

Over time we suspect that people will tailor there own libraries using the best of breed from other shared code. Feel free to adopt some or any of the code in RSLibrary. We have freely borrowed from other contributors on the Codea Forum such as Two Lives Left, Vega and Bri_G.

9.3 Download RSLibrary

  1. Main.lua v1.1 - metadata and demonstration of the library functionality.
  2. Math.lua v1.0 - math.hypot(x, y), math.hypot2(x,y), math.polar(x,y,originX,originY), math.constrain(value,min,max), math.pi(), and math.round(value).
  3. Collisions.lua v1.0 - pointInCircle(pointX, pointY, centreX, centreY, radius), pointInRect(pointX, pointY, x, y, w, h).
  4. Colors v1.0 - Definitions of the 17 predefined colours from UIColor.
  5. Button v1.2 - Modified Vega mesh Button Class.
  6. RoundRect v1.0 - Modified Bri_G Rounded Rectangle Class.
  7. TextBox v1.0 - Two Lives Left TextBox Class (from Spritely example project).

9.4 How do I link a Library to my Project?


So you have created your shiny new Library, how do you make this a dependency of your project. The process is very simple.
  1. With your Project open there is a [+] tab in the top right corner.
  2. Tapping this will pop up a menu with three options:
    • Create New Class;
    • Create Blank File; and
    • Dependencies.
  3. Not surprisingly the section called Dependencies is where you select your library. Tap it to select and it will indicate the available tabs (6 for RSLibrary).
And that's it. You can remove a dependency using the same process.

9.5 What's Next?


As the idea of Libraries and Dependencies is evolving we would welcome thoughts and observations on the best structure or alternate approaches, so that we can share them here.

9.6 The Main Class

Here is a copy of the Main Class so you can see how RSLibrary is structured.
--# Main
-- RSLibrary by Reefwing Software (www.reefwing.com.au)
-- This Library contains functions and definitions which are commonly used
-- but not currently available in the Codea framework.
-- It includes code from: Two Lives Left
--                                        Vega
--                                        Bri_G

--
-- CONTENTS
--
-- Math Extensions:

--     1. math.round(value)
--     2. math.hypot(x, y)
--     3. math.hypot2(x, y)
--     4. math.polar(x, y) or math.polar(x, y, originX, originY)
--     5. math.pi()
--     6. math.constrain(value, min, max)
--
-- Collision Detection Functions:
--     1. pointInCircle(pointX, pointY, centreX, centreY, radius)
--     2. pointInRect(pointX, pointY, x, y, width, height)
--
-- Color Extensions: UIColor Predefined Colors
--     1. blackColor        10. yellowColor
--     2. darkGrayColor 11. magentaColor
--     3. lightGrayColor 12. orangeColor
--     4. whiteColor        13. purpleColor
--     5. grayColor          14. brownColor
--     6. redColor            15. clearColor
--     7. greenColor       16. lightTextColor
--     8. blueColor          17. darkTextColor
--     9. cyanColor
--
-- Classes:

--     1. Vega Modified Mesh Button Class v1.2
--     2. Two Lives Left TextBox Class v1.0
--     3. Bri_G Modified RoundRect Class v1.0
--
-- Note the Main class of the Library is just used to demonstrate the Library
-- functionality. Nothing defined here is available using dependancies.


function setup()
    -- Library Metadata
    version = 1.1
    saveProjectInfo("Description", "Reefwing Software Library v"..version)
    saveProjectInfo("Author", "Reefwing Software")
    saveProjectInfo("Date", "26th July 2012")
    saveProjectInfo("Version", version)
    print("RSLibrary v"..version.."\n")

    -- Parameters to demonstrate the RoundRect Class
    parameter("cr",0,2,1)
    iparameter("border",0,4,2)
    iparameter("x",0,WIDTH - 200,275)
    iparameter("y",0,HEIGHT - 40,350)
    iparameter("w",100,WIDTH,200)
    iparameter("h",0,HEIGHT,40)

    -- Construct the rounded rectangle
    roundRect = RoundRect(x, y, w, h, border, "test", cr)
    -- Construct a TextBox
    textBox = TextBox(WIDTH / 2 - 100, HEIGHT - 120, 200, "Enter your name!")
    showTextBox = false
end

function draw()

    -- This sets the background color to black
    background(blackColor)
    -- Update our roundRect with the latest parameter values (not required if they
    -- don't change). The larger the width and height the smaller cr needs to be
    -- otherwise you will end up with an ellipse.

    roundRect.x = x
    roundRect.y = y
    roundRect.w = w
    roundRect.h = h
    roundRect.cr = cr
    roundRect.border = border

    -- Set the rectangle fill and border colours. Text colour is also available.

    roundRect.fillColor = blueColor
    roundRect.borderColor = redColor

    -- call the roundRect draw() function
    roundRect:draw()
    -- If tap is not on the rectangle then draw the textBox
    if showTextBox then
         textBox:draw()
    end
end

function touched(touch)

-- Use this method to demonstrate the pointInRect() collision detection function
    if touch.state == BEGAN and pointInRect(touch.x, touch.y, x, y, w, h) then
         showTextBox = false
         print("Rounded Rectangle Tapped.")
    elseif touch.state == ENDED and not pointInRect(touch.x, touch.y, x, y, w, h) then
         showTextBox = true
         showKeyboard()
    end
end


-- KeyBoard handling function
-- Used to enter name if touch is not on the rounded rectangle


function keyboard(key)
    if key ~= nil then
        if string.byte(key) == 10 then
-- <RETURN> Key pressed
            print("Hello "..textBox.text)
            showTextBox = false
            hideKeyboard()
        elseif string.byte(key) ~= 44 then
-- e.g. filter out commas
            textBox:acceptKey(key)
        end
    end
end