DragonFireSDK FAQ

From DragonFireSDK Wiki
Jump to: navigation, search

Contents

Product Information

What is DragonFireSDK?

DragonFireSDK is a Microsoft Visual C/C++ library. Its API consists of C/C++ functions that call native iPhone Objective-C functions enabling iPhone App creation in Windows. DragonFireSDK is not a hack, it is 100% legal and extremely fast as you are actually using Objective-C.

Where can I buy it?

You may purchase DragonFireSDK at http://www.dragonfiresdk.com/products_new.htm.

What do I need to begin creating apps with DragonFireSDK?

In order to get started creating apps with DragonFireSDK, you will need a C/C++ compiler. DragonFireSDK supports Visual C++ starting with version 6.0 and higher. The freely available Express Editions are also supported. You may download Visual C++ from Microsoft here: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express

What do I get when I buy DragonFireSDK?

In the installer package, you will receive a Visual C++ library that contains the Windows iPhone Simulator for DragonFireSDK, DragonFireSDK documentation as well as sample apps to explore and learn about DragonFireSDK. If you purchased an Ultimate edition, you get all of the above, plus access to the Build Center, which is for creating builds for your device. The Ultimate edition also entitles you to publish apps to the App Store.

I reformatted my hard drive. Is there any way to download DragonFireSDK again?

Yes! Please email support@dragonfiresdk.com and we will take care of you.

Does my purchase include free upgrades?

Yes! Maintenance releases (those with the same version number you purchased) are free. Major updates (those with different major version numbers) require a new purchase.

How big is the DragonFireSDK download?

The DragonFireSDK installer weighs in around 5-7MB! It’s very lightweight and is a “no-bloat” system.

Can I test my code on Windows?

Yes! With your project loaded in Visual C++, hit F5, and you will see your app running in our iPhone or iPad Simulator!

Is DragonFireSDK only for creating games?

No way! DragonFireSDK is an excellent platform for creating games, to be sure, but it can be all business, too! There’s nothing stopping you from creating any kind of app that you can dream of!

Can I install DragonFireSDK on my desktop and my laptop computer?

As long as you only use your DragonFireSDK installation on one computer at a time, then, yes, you may definitely install your copy on two computers. If you have multiple developers that need to use DragonFireSDK concurrently, then you would need to purchase a license for each user.

Development Questions

What programming language does DragonFireSDK use?

DragonFireSDK uses standard C/C++, allowing you to leverage your existing programming language knowledge. No need to learn any proprietary language like Objective-C!

Is my code converted to Objective-C?

No conversion takes place. DragonFireSDK uses Objective-C objects under the hood on the iOS side, and when you call DragonFireSDK functions from C, you are using the native iOS objects.

Where can I find documentation?

You may find the DragonFireSDK documentation online at http://www.dragonfiresdk.net/help/DragonFireSDKHelp.html or on your computer in the directory where DragonFireSDK was installed in CHM format. There you will find each function documented with sample code.

What image file format(s) does DragonFireSDK support?

DragonFireSDK supports PNG images.

What sound file format(s) does DragonFireSDK support?

DragonFireSDK supports files in the SND format (a utility for converting WAV files to SND files is included with DragonFireSDK). DragonFireSDK also supports MP3 files.

What libraries may I (safely) include in DragonFireSDK projects?

You may add #include statements for any standard C or C++ headers, including, but not necessarily limited to:
<stdio.h> <stdlib.h> <math.h> <time.h> <string.h>
Header files that will not compile for the iOS device include, but are not limited to:
<windows.h> <winsock.h> <stdafx.h>
or any other Microsoft-specific headers.

How do I add additional code modules to my project?

If you want to add additional modules to your project, you may put your code into header (.h) files. Any code you might normally put into a .cpp file, you’ll need to put into the aforementioned header file.

How do I add an image?

To load an image file in DragonFireSDK, use the ImageAdd() function. A typical call to ImageAdd() might look like this:

int MyImage = ImageAdd("Images/MyImage.png"); // Loads the image.
ViewSetImage(MyView, MyImage);                // Tells "MyView" to display "MyImage".

I tried adding an image and all I see is this little red square. Why?

If you see a red square where your image should be, that means that your image failed to load. It's possible your path may be incorrect, or the case of the file name does not match exactly between the source code and the name of the file on disk.

Why does an image (or sound or MP3) load on the Simulator, but not on the device?

The file system on Windows is not case sensitive, whereas the one in iOS is. If the case of the name does not match exactly the image will not load on the device.

Thus, if your file is named "MyImage.png" on the file system, but in your code you refer to it as "myimage.png", iOS will be unable to find the image because it matches the case of the file name exactly.

How do I add a view?

If you need to put an image on the screen, you need to create a view. To create a view, use the ViewAdd() function. A typical ViewAdd() call might look like this:

int MyView = ViewAdd("Images/MyImage.png", 100, 100); // Initializes a view with an image at 100, 100.
ViewSetVisible(MyView, 0);                            // Sets the view to be invisible.

The above would load the image at "Images/MyImage.png" and display it at 100 pixels from the left side of the screen, and 100 pixels down from the top of the screen.

How do I add a sound?

If you need to load a sound, you need to use the SoundAdd() function. A typical call to SoundAdd() might look like this:

int MySnd = SoundAdd("Sounds/MySound.snd"); // Loads the sound file.
SoundPlay(MySnd);                           // Plays the sound that was just loaded.

How do I add an MP3 that has my background music / sounds?

If you need to load an MP3, you need to use the Mp3Add() function. A typical Mp3Add() call might look like this:

int MyMp3 = Mp3Add("Sounds/MyMp3.mp3"); // Loads the MP3 file.
Mp3Play(MyMp3);                         // Plays the MP3 file that was just loaded.

How do I add text to the screen?

To add text to the screen, you need to use the TextAdd() function. A typical TextAdd() call might look like this:

int MyText = TextAdd("This is the text I want to display", 100, 100, MyFont);

The above would put the text "This is the text I want to display" at 100 pixels from the left side of the screen and 100 pixels down from the top of the screen using the font represented by MyFont.

Fonts

How do I create a font?

There are two types of fonts available in DragonFireSDK: bitmap fonts and native fonts. Bitmap fonts are composed of PNG images for each letter, number or symbol in the font. Native fonts use the built in font rendering in the device (or simulator). In each case, you would need to use the FontAdd() function.

Bitmap fonts

A typical FontAdd() call to create a bitmap font might look like this:

int MyFont = FontAdd("Fonts/MyFont");

The above call tells the font rendering engine to use the specified folder to locate the images for the bitmap font.

Native fonts

A typical FontAdd() call to create a native font might look like this:

int MyFont = FontAdd("Helvetica", "Regular", 12, 0xFFFFFF);

The above call tells the font rendering engine to create a font object using Helvetica font, Regular (meaning no styles such as italic or bold applied), 12 point, white color (the color is expressed as a hexadecimal number, representing an RGB value).

How do I add an edit field to the screen?

If you need to get text input from the user, you would need to use the EditAdd() function. A typical call to EditAdd() might look like this:

int MyEdit = EditAdd(10, 50, 50);

The example above would put an edit field at 10 pixels from the left side of the screen, 50 pixels down from the top and would make the edit field 50 pixels wide.

Is the built-in iOS keyboard supported?

Yes! Simply add an edit control with EditAdd() and when the user touches the edit control, the iOS keyboard will be displayed. When the user taps "Done" on the keyboard, the keyboard will be dismissed.

What is AppMain()?

The AppMain() function is where your app will begin its life cycle. This is where you will place all of the code to initialize your application. Here you will create all of your images, views, sounds, etc.

What is AppExit()?

The AppExit() function is where your app will end its life cycle. This is where you will clean up any memory you may have allocated or save any data you need to save.

What is OnTimer()?

The OnTimer() function is your app's main loop. This function gets called 30 times per second, and this is where you will perform any animations or anything else you need to do in your app.

Does DragonFireSDK support Retina displays?

Absolutely! In order to support the higher resolution Retina displays on devices that have them, simply include "@2x" (Retina and Retina HD displays, including iPhone 6) or "@3x" (for iPhone 6 Plus Retina HD) versions of your images and they will be used in place of your lower resolution images. For example, say you have an image named "MyImage.png". The Retina display version of that file would be named "MyImage@2x.png" (or "MyImage@3x.png"). The device looks for image files with "@2x" or "@3x" infix on devices with Retina and Retina HD displays.

How can I drag an image around on the screen?

It's easy with DragonFireSDK to move images around the screen in response to a touch event. The code snippet below shows just how easy it is!

Note: You could also use code like this to scroll a very long image. Just update the Y coordinate, and you have a scrolling page...

#include "DragonFireSDK.h"

int MyView;
int MyViewWidth;
int MyViewHeight;

// This is the callback for when the view gets touched:
int MyViewEvent(int id, int event, int x, int y)
{
    if (event==2) // Event 2 = Move Event.
    {
        // Calculate new x and y values so that the image will be centered under the touch:
        int NewX = x - (MyViewWidth / 2);
        int NewY = y - (MyViewHeight / 2);
        // Position the view:
        ViewSetxy(MyView, NewX, NewY);
    }
    return(0);
}

void AppMain()
{   
    // Load the image into a view and set a callback:
    MyView=ViewAdd("Images/Ball.png", 0, 0, MyViewEvent, 1);
    // Calculate the view's width and height so we can center it under the touch:
    MyViewWidth=ViewGetWidth(MyView); 
    MyViewHeight=ViewGetHeight(MyView);
}

void OnTimer()
{

}

void AppExit()
{

}

How might I detect a swipe gesture in DragonFireSDK?

To detect a swipe gesture in DragonFireSDK, you need to keep track of where the user begins to drag their finger and once the distance travelled reaches a certain threshold, you can determine that a swipe has occurred.

The code snippet below shows a simple way to detect swipe gestures in each direction (up, down, left and right).

#include "DragonFireSDK.h"

const int VERTICAL_PAGES=3;     // Number of vertical "pages" to show
const int HORIZONTAL_PAGES=8;   // Number of horizontal "pages" to show
const int PAGE_WIDTH=320;       // Page width for iPhone is 320; iPad is 768
const int PAGE_HEIGHT=480;      // Page height for iPhone is 480; iPad is 1024
const int SWIPE_THRESHOLD=100;  // How far we need to drag our finger to make a swipe

int MyPageView;
int SwipeStartx;
int SwipeStarty;
bool Swiping=false;

// SwipeLeft() shifts the big view to the left by the screen width until we hit our page limit
void SwipeLeft()
{   
    int newx = ViewGetx(MyPageView)-PAGE_WIDTH;
    if (newx<(HORIZONTAL_PAGES-1)*-PAGE_WIDTH)
        newx=(HORIZONTAL_PAGES-1)*-PAGE_WIDTH;
    ViewSetxy(MyPageView, newx, ViewGety(MyPageView));
}

// SwipeRight() shifts the big view to the right by the screen width until x gets to 0
void SwipeRight()
{
    int newx = ViewGetx(MyPageView)+PAGE_WIDTH;
    if (newx > 0)
        newx = 0;
    ViewSetxy(MyPageView, newx, ViewGety(MyPageView));
}

// SwipeDown() shifts the big view down by the screen height until y gets to 0
void SwipeDown()
{
    int newy = ViewGety(MyPageView)+PAGE_HEIGHT;
    if (newy > 0)
        newy = 0;
    ViewSetxy(MyPageView, ViewGetx(MyPageView), newy);
}

// SwipeUp() shifts the big view up by the screen height until we hit our page limit
void SwipeUp()
{
    int newy = ViewGety(MyPageView)-PAGE_HEIGHT;
    if (newy<(VERTICAL_PAGES-1)*-PAGE_HEIGHT)
        newy=(VERTICAL_PAGES-1)*-PAGE_HEIGHT;
    ViewSetxy(MyPageView, ViewGetx(MyPageView), newy);
}

int OnTouch(int id,int event,int x,int y)
{
    if (event==1)
    {
        Swiping=true;
        SwipeStartx=x;
        SwipeStarty=y;
    }
    else
    if (event==2 && Swiping)
    {
        // In each case, we are checking to see that the touch has travelled 
        // at least SWIPE_THRESHOLD pixels before deciding that a swipe has occurred.
        if ((x-SwipeStartx)>SWIPE_THRESHOLD)
        {
            SwipeRight();
            Swiping=false;
        }
        else
        if ((SwipeStartx-x)>SWIPE_THRESHOLD)
        {
            SwipeLeft();
            Swiping=false;
        }
        else
        if ((y-SwipeStarty)>SWIPE_THRESHOLD)
        {
            SwipeDown();
            Swiping=false;
        }
        else
        if ((SwipeStarty-y)>SWIPE_THRESHOLD)
        {
            SwipeUp();
            Swiping=false;
        }
    }
    else
    if (event==3)
    {
        Swiping=false;
    }
    return(0);
}

void AppMain()
{
    MyPageView=ViewAdd("Images/MyBigImage.png", 0, 0);
    TouchAdd(0, 0, PAGE_WIDTH, PAGE_HEIGHT, OnTouch, 0);
}

void AppExit()
{

}

void OnTimer()
{
    
}

How can I make Random() "more random"?

The Randomize() function that initializes the random number generator in DragonFireSDK uses the same value to set the seed for random numbers, so it will use the same seed each time your app starts for the random number generator.

If you want to have a more genuinely random set of random numbers, you can do so by using the time() function in <time.h> to set the random seed each time your app starts to a different value each time by using the RandomSetSeed() function.

#include "DragonFireSDK.h"
#include <time.h>

const int RANDOM_MAX=100;
int RandomNumber;
int Pass=0;

void AppMain()
{
    RandomSetSeed(time(NULL));
}

void AppExit()
{

}

// Increment Pass each time OnTimer() gets called.  When it hits 30
// get a random number and print it to the console then reset it.
// This has the effect of printing a random number to the console once per second.
void OnTimer()
{
    Pass++;
    if (Pass>30)
    {
        RandomNumber=Random(RANDOM_MAX);
        printf("Random #:%d",RandomNumber);
        Pass=0;
    }
}

What functions would I use to read or write data to file(s) in Documents?

All iOS applications have a writable folder called "Documents". In this location, you can save configuration files, game data, high scores, you name it! DragonFireSDK provides the following functions for handling files: FileCreate() creates a new file on disk. FileOpen() opens an existing file and returns a handle to the file. FileRead() reads data from the file into a buffer. FileWrite() writes data from a buffer to the file. FileSeek() sets the location in the file where reads and writes will occur. Please see the DragonFireSDK documentation for more information on "File" functions.

How do I ship a file for the Documents folder?

You may not ship writable files in your app's Documents folder, but you can include them in your Assets folder. The first time your app runs, you can load the file from Assets and then write it to Documents. Here is an example of how to do this:

#include "DragonFireSDK.h"

int MyFile;
int MyNewFile;
char MyFileBuffer[200];

void AppMain()
{
    MyFile=FileOpen("MyFile.txt");
    
    if (!MyFile)
    {
        MyFile=FileOpenAsset("MyFile.txt");
        FileRead(MyFile, MyFileBuffer, 200);
        MyNewFile=FileCreate("MyFile.txt");
        FileWrite(MyNewFile, MyFileBuffer, 200);
        FileClose(MyNewFile);
    }
    else
    {
        FileRead(MyFile, MyFileBuffer, 200);
    }

    if (MyFile)
        FileClose(MyFile);
}

void AppExit()
{

}

void OnTimer()
{

}

The above sample tries to load the file "MyFile.txt" and if this file does not exist, it is opened from Assets, and then written to Documents for the next run of the application. Please see the online DragonFireSDK documentation for more information on the "File" functions.

How do I create a High Scores file for my app?

The sample below should get you started with creating a high scores table for your app. This example checks for an existing "Scores.dat" file and creates a default one with the names of the ghosts from a very popular classic video game if the file does not exist:

#include "DragonFireSDK.h"
#include <string.h>

// Constants to be used below:
// You can change these to suit your particular needs.
const int SCORE_MAX = 100; // Number of high score records to store
const int NAME_LEN = 50; // Max length of the name in the file
const char SCORES_FILE_NAME[NAME_LEN] = "Scores.dat"; // Name of the high scores file

// Define the high score record structure:
typedef struct
{
    char name[NAME_LEN];
    int score;
} score_record;

// We will keep track of the top SCORE_MAX scores:
score_record scores[SCORE_MAX];

// File Handle for our scores file:
int ScoresFile;

// Clears the entire array of score records:
void ClearScores()
{
    int i;
    for (i=0;i<SCORE_MAX;i++)
    {
        scores[i].name[0]=0;
        scores[i].score=0;
    }
}

// Saves the record array to a file:
void SaveScores()
{
    int i;

    ScoresFile=FileCreate((char *)SCORES_FILE_NAME);
    for (i=0;i<SCORE_MAX;i++)
    {
        FileWrite(ScoresFile, (char *)&scores[i], sizeof(score_record));
    }

    FileClose(ScoresFile);
}

// Inserts a new high score into the appropriate spot in the array of records:
void InsertScore(char *name,int score)
{
    int i,j;

    // Find the index for insertion.  Matching scores that come later will be added after existing score records:
    for (i=0;i<SCORE_MAX;i++)
    {
        if (score>scores[i].score)
            break;
    }
    
    // Start at the end of the list and shift each value down until we get to the insertion point:
    for (j=SCORE_MAX-1;j>0;j--)
    {
        strcpy(scores[j].name, scores[j-1].name);
        scores[j].score=scores[j-1].score;
        if (j==i)
            break;
    }
    
    // Insert the new score:
    strcpy(scores[i].name, name);
    scores[i].score=score;
    SaveScores();
}

// Creates a new save game file with names of ghosts from a popular classic video game:
void CreateDefaultScoresFile()
{
    ClearScores();
    strcpy(scores[0].name, "Inky");
    scores[0].score=1500;
    strcpy(scores[1].name, "Blinky");
    scores[1].score=1400;
    strcpy(scores[2].name, "Pinky");
    scores[2].score=1300;
    strcpy(scores[3].name, "Clyde");
    scores[3].score=1200;
    SaveScores();
}

void ReadScoreRecord(int index)
{
    ScoresFile=FileOpen((char *)SCORES_FILE_NAME);
    if (ScoresFile)
    {
        FileSeek(ScoresFile, (index * sizeof(score_record)));
        FileRead(ScoresFile, (char *)&scores[index], sizeof(score_record));
    }
    FileClose(ScoresFile);
}

// Loads the scores from the file.  Creates a new default one if none exists yet:
void LoadScores()
{
    ScoresFile=FileOpen((char *)SCORES_FILE_NAME);
    if (!ScoresFile)
    {
        CreateDefaultScoresFile();
        ScoresFile=FileOpen((char *)SCORES_FILE_NAME);
    }
    FileClose(ScoresFile);

    for (int i=0;i<SCORE_MAX;i++)
    {
        ReadScoreRecord(i);
    }
}

void DeleteScores()
{
    FileClose(ScoresFile);
    FileDelete((char *)SCORES_FILE_NAME);
}

int OnDeleteFile(int id)
{
    DeleteScores();
    return(1);
}

void AppMain()
{
    int i;

    ButtonAdd("Images/DeleteFile", 100, 100, OnDeleteFile, 1);

    DeleteScores();

    LoadScores();
    
    // Print all of the high score records to the console:
    for (i=0;i<SCORE_MAX;i++)
    {
        printf("High Score record #%d: NAME=%s\t\tSCORE=%d\n",i,scores[i].name,scores[i].score);
    }

    InsertScore("Mister Cool", 1000000);
}

void AppExit()
{

}

void OnTimer()
{

}

Can I play a YouTube video, open the SMS messenger, open the Phone dialer, etc. with DragonFireSDK?

Yes! Using BrowserLaunch() you can launch various built-in apps based on the URL you pass. See the example below for more information:

#include "DragonFireSDK.h"
 
int AppStoreButton;
int SMSButton;
int DialerButton;
int MapsButton;
int MailButton;
int WebButton;
int VideoButton;
 
float Latitude;
float Longitude;
 
int OnButton(int id)
{
    char URL[300];
 
    switch (id) {
    case 1:
        // Go to the App Store
        sprintf(URL, "http://itunes.apple.com/us/app/ditto/id363392316?mt=8&ls=1");
        break;
    case 2:
        // Open the SMS application
        sprintf(URL, "sms:5555555555");
        break;
    case 3:
        // Dial a phone number
        sprintf(URL, "tel://5555555555");
        break;
    case 4:
        // Open the Maps Application
        LocationGet(Latitude, Longitude);
        sprintf(URL, "http://maps.google.com/maps?q=%f,%f", Latitude, Longitude);
        break;
    case 5:
        // Open the Mail Application
        sprintf(URL, "mailto:support@dragonfiresdk.com?subject=Ignore");
        break;
    case 6:
        // Open Mobile Safari
        sprintf(URL, "http://www.dragonfiresdk.com");
        break;
    case 7:
        // open YouTube
        sprintf(URL, "http://www.youtube.com/watch?v=uDueddAn6zM");
        break;
    default:
        break;
    }
 
    BrowserLaunch(URL);
    return(1);
}
 
void AppMain()
{
    LocationMonitorLocation(1);
 
    AppStoreButton = ButtonAdd("Images/AppStore", 10, 80, OnButton, 1);
    SMSButton = ButtonAdd("Images/SMS", 10, 140, OnButton, 2);
    DialerButton = ButtonAdd("Images/Dialer", 10, 200, OnButton, 3);
    MapsButton = ButtonAdd("Images/Maps", 10, 260, OnButton, 4);
    MailButton = ButtonAdd("Images/Mail", 10, 320, OnButton, 5);
    WebButton = ButtonAdd("Images/Safari", 10, 380, OnButton, 6);
    VideoButton = ButtonAdd("Images/YouTube", 10, 440, OnButton, 7);
 
    AdBannerInit(0);
}
 
void OnTimer()
{
 
}
 
void AppExit()
{
 
}

How can I perform collision detection?

Here is a short code sample that will place some images of circles at random locations and they will proceed to bounce off the walls as well as each other. Feel free to play around with this code to see how it works!

#include "DragonFireSDK.h"

const int SCREEN_WIDTH=320;
const int SCREEN_HEIGHT=480;
const float STEP=0.0025f; 

const int MAX_BALLS=15;

typedef struct
{
    int ViewHandle;
    float XVelocity;
    float YVelocity;
} BallInfo;

int BallWidth;
int BallHeight;
int BallImage;
BallInfo Balls[MAX_BALLS];

float xcur;
float ycur;

float x2cur;
float y2cur;

float collx;
float colly;

float aci;
float bci;

float mag;

float d;

void AppMain()
{
    Randomize();
    
    BallImage=ImageAdd("Images/Circle.png");
    BallWidth=ImageGetWidth(BallImage);
    BallHeight=ImageGetWidth(BallImage);

    for (int i=0; i<MAX_BALLS; i++)
    {
	Balls[i].ViewHandle=ViewAdd(BallImage, Random(SCREEN_WIDTH-BallWidth), Random(SCREEN_HEIGHT-BallHeight));
    	Balls[i].XVelocity=Random(SCREEN_WIDTH)/Random(SCREEN_WIDTH)<SCREEN_WIDTH/2 ? -1000 : 1000;
        Balls[i].YVelocity=Random(SCREEN_HEIGHT)/Random(SCREEN_HEIGHT)>SCREEN_HEIGHT/2 ? -1000 : 1000;
    }
}
 
void OnTimer()
{
    // Get the circles moving:
    for (int i=0; i<MAX_BALLS; i++)
    {
        xcur=ViewGetx(Balls[i].ViewHandle);
        ycur=ViewGety(Balls[i].ViewHandle);
        
        xcur+=Balls[i].XVelocity*STEP;
        ycur+=Balls[i].YVelocity*STEP;

        if (xcur+BallWidth>SCREEN_WIDTH)
        {
            xcur=SCREEN_WIDTH-BallWidth;
            Balls[i].XVelocity*=-1;
        }

        if (xcur<0)
        {
            xcur=0;
            Balls[i].XVelocity*=-1;
        }

        if (ycur+BallHeight>SCREEN_HEIGHT)
        {
            ycur=SCREEN_HEIGHT-BallHeight;
            Balls[i].YVelocity*=-1;
        }

        if (ycur<0)
        {
            ycur=0;
            Balls[i].YVelocity*=-1;
        }

        // Collision detection:
        for (int j=i+1; j<MAX_BALLS; j++)
        {
            x2cur=ViewGetx(Balls[j].ViewHandle);
            y2cur=ViewGety(Balls[j].ViewHandle);

            d=sqrtf((x2cur-xcur)*(x2cur-xcur)+(y2cur-ycur)*(y2cur-ycur));
            
            if (d>BallWidth || d==0)
                continue;
                
            collx=(xcur-x2cur)/d;
            colly=(ycur-y2cur)/d;
            
            aci=Balls[i].XVelocity*collx + Balls[i].YVelocity*colly;
            bci=Balls[j].XVelocity*collx + Balls[j].YVelocity*colly;
            
            Balls[i].XVelocity += (bci-aci)*collx; 
            Balls[i].YVelocity += (bci-aci)*colly;
            Balls[j].XVelocity += (aci-bci)*collx; 
            Balls[j].YVelocity += (aci-bci)*colly;
            
            collx = ViewGetx(Balls[j].ViewHandle)-ViewGetx(Balls[i].ViewHandle);
            colly = ViewGety(Balls[j].ViewHandle)-ViewGety(Balls[i].ViewHandle);
            mag = sqrtf(collx*collx + colly*colly);

            x2cur += (collx/mag) * (BallWidth-d);
            y2cur += (colly/mag) * (BallWidth-d);
            
            ViewSetxy(Balls[j].ViewHandle, x2cur, y2cur);
        }

        ViewSetxy(Balls[i].ViewHandle, xcur, ycur);
    }
}

void AppExit()
{
 
}

What functions would I use to draw lines and shapes on the screen?

DragonFireSDK provides lots of functions that allow you to draw on the screen. First, you need to create a "draw surface" on which to draw your shapes. To do this, you would need to call DrawAdd(). A typical DrawAdd() call might look like this:

int MyDrawSurface = DrawAdd(0, 0, 320, 480);

You can then draw on the surface using any of the functions that start with "Draw". For example, If you wanted to draw a square on the surface, you would call DrawSquare(). A typical call to DrawSquare() might look like this:

DrawSquare(MyDrawSurface, 50, 50, 100, 100);

Please refer to the DragonFireSDK documentation online for more information about the other "Draw" functions.

What functions would I use to manipulate individual pixels on the screen?

DragonFireSDK provides the ability to manipulate individual pixels on a "bitmap surface". To create a bitmap surface, you would need to call the BitmapAdd() function. A typical call to BitmapAdd() might look like this:

int MyBitmapSurface = BitmapAdd(100, 100, 100, 100);

This creates a bitmap surface at 100 pixels to the right of the left side of the screen and 100 pixels from the top. It also sets the width and height to 100 pixels each.

If you wanted to set an individual pixel in a bitmap to a certain color, you would need to call BitmapSetPixel(). A typical call to BitmapSetPixel() might look like this:

BitmapSetPixel(MyBitmapSurface, 20, 20, 255);

This would set the pixel at 20 pixels to the right of the left side of the bitmap surface and 20 pixels from the top of the bitmap surface to the color 255 (white).

The sample below creates a gradient that shifts from black to blue on the x axis and from black to red on the y axis:

#include "DragonFireSDK.h"

const int SCREEN_WIDTH=320;
const int SCREEN_HEIGHT=480;

int MyBitmap;
float Red;
float Green;
float Blue;

void AppMain()
{  
    MyBitmap = BitmapAdd(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    Red=0;
    Green=0;
    Blue=0;
    for (int x = 0; x < SCREEN_WIDTH; x++)
    {
        Blue+=(255.0f/SCREEN_WIDTH);     // Screen will go from black to blue starting at the left.
        for (int y = 0; y < SCREEN_HEIGHT; y++)
        {
            Red+=(255.0f/SCREEN_HEIGHT); // Screen will go from black to red from top to bottom.
            if (Red>=255)
                Red=0;
            BitmapSetPixel(MyBitmap, x, y, Red, Green, Blue, 255);
        }
    }
    BitmapUpdate(MyBitmap);
}
 
void AppExit()
{
 
}
 
void OnTimer()
{
 
}

Please refer to the DragonFireSDK documentation online for more information about "Bitmap" functions.

What function would I use to communicate with a Web Service?

DragonFireSDK provides a function called NetSend() for communication with remote servers and provides a method for getting a response from the server. A typical call to NetSend() might look like this:

int OnResponse(int event, char *response, int length);

NetSend("http://www.mysite.com?var1=x&var2=y", OnResponse);

The OnResponse line above is a forward declaration for a callback function to be called when the server gives a response to the app. That function is where you would want to parse the response from your server and perform any other necessary actions. Please refer to the DragonFireSDK documentation online for more information about the NetSend() function.

Can DragonFireSDK support Unicode strings?

Yes and no. Unicode strings should work correctly on the device if you save your file with UTF-8 encoding. To achieve this in Visual C++, simply go to the File menu and select "Advanced Save Options..." and select "UTF-8" as the encoding. When your file is saved with this encoding and uploaded to the Build Center, your Unicode string should appear correctly in your Texts as well as your Edits. Once you do this, the following examples should work correctly (each one says "I like it!" in a different language...):

int MyText = TextAdd(0, 0, "Мне нравится!");

or

int MyText = TextAdd(0, 0, "אני אוהב את זה!");

or

int MyText = TextAdd(0, 0, "我喜歡它!");

General device questions

How do I detect when the user tilts the device?

To read data from the device's accelerometer, you have three functions available: TiltGetx(), TiltGety() and TiltGetz().

TiltGetx() returns a value between -1000 (device tilted left) and 1000 (device tilted right) depending on the left / right orientation of the device in a 3D space. A zero value indicates that the device is resting level on this axis.

TiltGety() returns a value between -1000 (device tilted top down) and 1000 (device bottom down) depending on the top / bottom orientation of the device in a 3D space. A zero value indicates that the device is resting level on this axis.

TiltGetz() returns a value between -1000 (device tilted facing the ground) and 1000 (device tilted facing the sky) depending on the face up / face down orientation of the device in a 3D space.

The Accelerate sample from DragonFireSDK illustrates how to use the "Tilt" functions to move an image of a ball around the screen in response to the user tilting the device:

#include "DragonFireSDK.h"

int BallImage;
int BallView;

void AppMain()
{
    // Set up an image of a ball to move around the screen:
    BallImage = ImageAdd("Images/Ball.png");
    BallView = ViewAdd(BallImage, 0, 0);

    AutoRotateInit(0, NULL);
}

void OnTimer()
{
    int BallX, BallY;
    int AccX, AccY;

    // Get tilt (accelerometer) data for each axis.
    AccX = TiltGetx();
    AccY = TiltGety();
 
   // Update the ball's next X and Y values based on G-Force and the strength of gravity:
    BallX = ViewGetx(BallView) + (AccX / 100);
    BallY = ViewGety(BallView) + (AccY / 100);

    // Don't let the ball go off the screen:
    if (BallX >= 283)
        BallX = 283;
    if (BallX <= 0)
        BallX = 0;
    if (BallY >= 443)
        BallY = 443;
    if (BallY <= 0)
        BallY = 0;

    // Update the ball's position:
    ViewSetxy(BallView, BallX, BallY);
}

void AppExit()
{

}

How can I convert the tilt of the device to an angle in degrees?

If you would like to display the tilt angle of the device in degrees, you can certainly do that with DragonFireSDK! Here's a quick code sample that shows you how to do this:

#include "DragonFireSDK.h"

char TiltText[100];
int TextTilt;

void AppMain()
{
    AutoRotateInit(0, NULL);

    int MyFont=FontAdd("Helvetica", "Regular", 17, 0x00FF00);
    TextTilt=TextAdd(10,10, "Tilt angle:", MyFont);
}

void OnTimer()
{
    float xtilt;
    float ytilt;
    float angle;
    
    xtilt=TiltGetx()/1000.0f;
    ytilt=TiltGety()/1000.0f;
    
    angle=atan2f(ytilt, xtilt); // get the tilt in radians for the device orientation...
    angle*=57.2957795f; // convert radians to degrees...
    
    sprintf(TiltText, "Tilt angle: %f degrees", angle);
    TextSetText(TextTilt, TiltText);
}

void AppExit()
{

}

The sample above will report the device angle as follows:

-90 degrees = device is in the standard "portrait right side up" orientation. 0 degrees = device is tilted so that the "home key" is on the left. 90 degrees = device is tilted in the "portrait upside down" orientation. 180 degrees = device is tilted so the the "home key" is on the right.

How do I get general information about the device?

If you need to know specific information about the device your app is running on, such as UDID, Model Name, Device Type, Battery Level, and so on, you may use the "Device" functions to get those values.

The DeviceInfo sample from DragonFireSDK illustrates how to use the "Device" functions:

#include "DragonFireSDK.h"

int MyFont;
int MyFontSmall;
int BatteryLevelText;
int BatteryStateText;
int LocaleIDText;
int ModelText;
int MultitaskingText;
int NameText;
int SystemNameText;
int SystemVersionText;
int UDIDText;
int UITypeText;

int Value;
char ValueText[50];
char TextBuffer[100];

void GetBatteryStateText()
{
    Value = DeviceGetBatteryState();
    switch (Value)
    {
        case 0:
            sprintf(TextBuffer, "Battery State: Unknown");
            break;

        case 1:
            sprintf(TextBuffer, "Battery State: Unplugged");
            break;
    
        case 2:
            sprintf(TextBuffer, "Battery State: Charging");
            break;
            
        case 3:
            sprintf(TextBuffer, "Battery State: Full");
            break;
    
        default:
            sprintf(TextBuffer, "Battery State: Unknown");
            break;
    }
}

void AppMain()
{   
    LandscapeMode();

    DeviceSetBatteryMonitoring(1);
    MyFont = FontAdd("Helvetica", "Regular", 18, 0x00FF00);
    
    Value = DeviceGetBatteryLevel();
    sprintf(TextBuffer, "Battery Level: %d%%", Value);  
    BatteryLevelText = TextAdd(10, 10, TextBuffer, MyFont);

    GetBatteryStateText();
    BatteryStateText = TextAdd(10, 40, TextBuffer, MyFont);
    
    DeviceGetLocaleID(ValueText, 50);
    sprintf(TextBuffer, "Locale ID: %s", ValueText);
    LocaleIDText = TextAdd(10, 70, TextBuffer, MyFont);
    
    DeviceGetModel(ValueText, 50);
    sprintf(TextBuffer, "Model: %s", ValueText);
    ModelText = TextAdd(10, 100, TextBuffer, MyFont);
    
    Value = DeviceGetMultitaskingSupported();
    if (Value)
        sprintf(TextBuffer, "Multitasking Supported", ValueText);
    else 
        sprintf(TextBuffer, "Multitasking Not Supported", ValueText);
    MultitaskingText = TextAdd(10, 130, TextBuffer, MyFont);
    
    DeviceGetName(ValueText, 50);
    sprintf(TextBuffer, "Name: %s", ValueText);
    NameText = TextAdd(10, 160, TextBuffer, MyFont);
    
    DeviceGetSystemName(ValueText, 50);
    sprintf(TextBuffer, "System Name: %s", ValueText);
    SystemNameText = TextAdd(10, 190, TextBuffer, MyFont);
    
    DeviceGetSystemVersion(ValueText, 50);
    sprintf(TextBuffer, "System Version: %s", ValueText);
    ModelText = TextAdd(10, 220, TextBuffer, MyFont);
    
    DeviceGetUDID(ValueText, 50);
    sprintf(TextBuffer, "UDID:%s", ValueText);
    ModelText = TextAdd(10, 250, TextBuffer, MyFont);
    
    Value=DeviceGetUIType();
    if (Value==0)
        sprintf(TextBuffer, "UI Type: iPhone");
    else 
        sprintf(TextBuffer, "UI Type: iPad");
    UITypeText = TextAdd(10, 280, TextBuffer, MyFont);
}

void OnTimer()
{
    Value = DeviceGetBatteryLevel();
    sprintf(TextBuffer, "Battery Level: %d%", Value);   
    TextSetText(BatteryLevelText, TextBuffer);
    
    GetBatteryStateText();
    TextSetText(BatteryStateText, TextBuffer);
}

void AppExit()
{

}

How do I set the screen to landscape mode?

It's simple to set the device to landscape mode. Just call the LandscapeMode() function. If you ever need to go back to portrait mode, call PortraitMode().

How do I control auto-rotation of the device?

It's a snap with DragonFireSDK. All you need to do is to call AutoRotateInit() with the appropriate flag, and that will tell your app which orientations it will support. Please see the DragonFireSDK documentation for AutoRotateInit() for more information about auto-rotation.

How do I keep the screen's back light from dimming?

If you have a game that uses the "Tilt" functions for input (for example), you might not want the screen to dim while your game is running. To prevent the screen dimming from kicking in after the user-specified period, simply call LcdStayOn(1).

How do I make the device vibrate?

It's a piece of cake. Simply call the Vibrate() function. Note: If the device does not have a vibration motor, then this call will have no effect.

How can I get information about the location of the device (latitude / longitude)?

If you want to get the location of the device, you'll want to use the "Location" functions. The most common "Location" function would be LocationGet(). A typical call to LocationGet() might look like this:

float lat;
float lng;

LocationGet(lat, lng);

The above call will do several things. It will cause a dialog to be displayed to the user (if they have not yet agreed to let your app collect location data) asking for permission to allow location updates. It will then use the best available means to determine the device's location. If the device has GPS, it will use that. If it has only WiFi, it will use that service to determine the location of the device.

Here is the code from the Location sample in DragonFireSDK to give you a better idea of how the "Location" functions work:

#include "DragonFireSDK.h"

int MyFont;
int LatitudeText;
int LongitudeText;
int AltitudeText;
int CourseText;
int HorizontalAccuracyText;
int SpeedText;
int VerticalAccuracyText;
int HeadingText;
int DistanceToCupertinoText;
int DistanceBetweenCupertinoAndEquator;
char TextBuffer[100];

// Cupertino, California is located at approximately 37.33294444,-122.0325556
float CupertinoLat = 37.33294444f;
float CupertinoLng = -122.0325556f;

void AppMain()
{
    LandscapeMode();

    // Begin monitoring location
    LocationMonitorLocation(1);
    LocationMonitorHeading(1);
    
    MyFont = FontAdd("Helvetica", "Regular", 24, 0x00FF00);
    LatitudeText = TextAdd(10, 10, "Latitude:", MyFont);
    LongitudeText = TextAdd(10, 40, "Longitude:", MyFont);
    AltitudeText = TextAdd(10, 70, "Altitude:", MyFont);
    CourseText = TextAdd(10, 100, "Course:", MyFont);
    HorizontalAccuracyText = TextAdd(10, 130, "Horizontal Accuracy:", MyFont);
    SpeedText = TextAdd(10, 160, "Speed:", MyFont);
    VerticalAccuracyText = TextAdd(10, 190, "Vertical Accuracy:", MyFont);
    HeadingText = TextAdd(10, 220, "Heading:", MyFont);
    DistanceToCupertinoText = TextAdd(10, 250, "Distance to Cupertino:", MyFont);
    DistanceBetweenCupertinoAndEquator = TextAdd(10, 280, "Cupertino to 0, 0:", MyFont);
}

void OnTimer()
{
    float lat;
    float lng;
    
    LocationGet(lat, lng);
    
    sprintf(TextBuffer, "Latitude: %f", lat);
    TextSetText(LatitudeText, TextBuffer);

    sprintf(TextBuffer, "Longitude: %f", lng);
    TextSetText(LongitudeText, TextBuffer);
    
    float altitude;
    altitude = LocationGetAltitude();
    
    sprintf(TextBuffer, "Altitude: %fm", altitude);
    TextSetText(AltitudeText, TextBuffer);
    
    float course;
    course = LocationGetCourse();
    
    sprintf(TextBuffer, "Course: %f degrees", course);
    TextSetText(CourseText, TextBuffer);
    
    float horizontalAccuracy;
    horizontalAccuracy = LocationGetHorizontalAccuracy();

    sprintf(TextBuffer, "Horizontal Accuracy: %fm", horizontalAccuracy);
    TextSetText(HorizontalAccuracyText, TextBuffer);

    float speed;
    speed = LocationGetHorizontalAccuracy();

    sprintf(TextBuffer, "Speed: %fm/s", speed);
    TextSetText(SpeedText, TextBuffer);

    float verticalAccuracy;
    verticalAccuracy = LocationGetVerticalAccuracy();

    sprintf(TextBuffer, "Vertical Accuracy: %fm", verticalAccuracy);
    TextSetText(VerticalAccuracyText, TextBuffer);

    float heading;
    heading = LocationGetHeading();
    
    sprintf(TextBuffer, "Heading: %f degrees", heading);
    TextSetText(HeadingText, TextBuffer);
    
    float dist;
    dist = LocationDistanceFrom(CupertinoLat, CupertinoLng);

    sprintf(TextBuffer, "Distance to Cupertino: %fm", dist);
    TextSetText(DistanceToCupertinoText, TextBuffer);
    
    dist = LocationDistanceBetween(CupertinoLat, CupertinoLng, 0.0f, 0.0f);

    sprintf(TextBuffer, "Cupertino to 0, 0: %fm", dist);
    TextSetText(DistanceBetweenCupertinoAndEquator, TextBuffer);
}

void AppExit()
{

}

Does DragonFireSDK support In-App Purchase?

Absolutely! Use of In-App Purchase requires that you set up a store in iTunes Connect with at least one item for sale.

You need to declare a callback to receive notifications from iTunes by using the StoreInit() function:

StoreInit(OnStoreEvent,',');

The call above sets the function OnStoreEvent() the receive callbacks from iTunes and sets the delimiter for field data to comma. If you need to specify a different delimiter, you can do so with StoreInit()

Your OnStoreEvent() callback might look something like this:

void OnStoreEvent(int type,int flag,int value,char *desc)
{
    switch (type)
    {
    case 1: // Product Request
        printf("Product Request event\n");
        break;
    case 2: // Provide Content
        printf("Provide Content event\n");
        break;
    case 3: // Record Transaction
        printf("Record Transaction event\n");
        break;
    }
}

In this callback, type identifies the kind of callback being made. A type of 1 signifies that product request data is being delivered. This is as a result of a call to StoreRequestProductData(). You will receive a call back for each product id requested. A type of 2 signifies that the user purchased the product specified in desc. At this point, you must make the purchased content available to the user. A type of 3 signifies that you should record the transaction. This is optional.

Call StorePurchaseProduct() to initiate a purchase from your store. StorePurchaseProduct() takes a single param, product_id which is the id of the product in your store. If this does not match precisely the product id you set up in your store, this function will not result in a callback to your app.

For example, if you have a product in your store with a Product ID of "com.mycompany.myapp.myproduct1" then your call to StorePurchaseProduct() must look like this:

StorePurchaseProduct("com.mycompany.myapp.myproduct1");

See iTunes Connect for more information on setting up your app's store.

My call to StorePurchaseProduct() or StoreRequestProductData() doesn't seem to work! Help!

The most common cause for calls to StorePurchaseProduct() or StoreRequestProductData() is that the requested product id does not match what is set up in the iTunes Connect In-App Purchase screen. In the iTunes Connect In-App Purchases screen, your product id should be formatted in the reverse domain name style to assure uniqueness. For example, if your app's bundle id is "com.mycompany.myapp" then it is recommended to make the product id's for your app follow the same convention, for example: "com.mycompany.myapp.product1", and so on. The "reference Name" field in the In-App Purchase screen can be anything you choose.

In your code, be sure to call StoreRequestProductData() and StorePurchaseProduct() using the very same product id.

For example:

StorePurchaseProduct("com.mycompany.myapp.myproduct1");

Does DragonFireSDK support Game Center?

Yes! DragonFireSDK suppports Game Center leaderboards and achievements. In order to use Game Center with DragonFireSDK, you must have set up at least one leaderboard or achievement in iTunes Connect.

Does DragonFireSDK support Box2D?

Yes! DFSDK now supports the Box2D physics engine (v2.1.2). All you need to do is to add the following line of code to begin using Box2D:

#include <Box2D/Box2D.h>

Check out the DFSDK Box2D sample app for more information about adding physics to your app.

Box2D documentation is available here:

http://www.box2d.org

What are Containers?

Containers are a new feature in DragonFireSDK 2.0 that allow you to group screen elements together and treat them as a single entity.

Build Center Questions

What is the Build Center?

The DragonFireSDK Build Center is an automated, online service that will compile your DragonFireSDK code for your iOS device(s).

How do I create a build for my device?

By following the instructions on this page: http://www.dragonfiresdk.net/help/iphone_builds.htm for iPhone builds or this page: http://www.dragonfiresdk.net/help/ipad_builds.htm for iPad builds you can send your app to the Build Center and in short order, you will be able to download the build that you can install on your device. To do this, all you need to do is plug in your device, start iTunes, and drag and drop your .app folder and your .mobileprovision file onto the iTunes library. You may see this page for more information: http://www.dragonfiresdk.net/help/installing_on_your_device.htm

I received an e-mail stating that I can download my app Over the Air (OTA). Is this legit?

Yes! DragonFireSDK's Build Center will now send an e-mail to the registered address (the same e-mail you use to log in to the Build Center) with a link to download your app straight to your device! This eliminates the need to sync your app via iTunes and should be much, MUCH simpler for all of our customers.

I tapped the link for my OTA download, but it says "Unable to Download Application"... Why?

You will see this message if you try to install your app on a device for which it was not provisioned. If you need to provision additional devices, contact DragonFireSDK Support.

I never received an e-mail from the Build Center with the link to my download. Why?

If you never received your OTA download link from the Build Center, it could be because you're not checking the registered e-mail address. Otherwise, it could be that your build failed. In the latter case, please download your app from the Build Center and check to see that your build completed successfully.

I'm having an issue syncing my app in iTunes! Help!

If you have trouble getting your app to install through iTunes, there are a few steps you can take to troubleshoot the problem:

  1. Please verify that you created your Build.zip file correctly for Build Center processing.
  2. If the zip file you downloaded from the Build Center contained a file named Errors.txt, then your build failed, and it won't sync through iTunes. Correct the issues outlined in the file and submit your build again.
  3. If there is no Errors.txt file in the zip, move on to checking the .app folder for a file with no extension, named the same as your app. If this file does not exist, then your app build failed. The most common reason builds fail without an Errors.txt file is that the user failed to include a folder called Assets in the Build.zip.
  4. If the app built correctly and still fails to install in iTunes, open the .mobileprovision file and search for the UDID of the device you're trying to install the app on. If the UDID for your device does not exist in the .mobileprovision file then the app cannot be installed on your device.

How long does it take to get my app from the Build Center?

The Build Center is automated and typically processes your app build in just a few minutes. However, if you have just submitted your device's UDID, it can take around 24 business hours (between 9AM and 5PM Central Time in the USA). Once we provision your device, builds will process much faster for you.

How do I provision a new device?

You can provision your device one of two ways, depending on whether you're provisioning your first device, or if you are provisioning an additional device or devices.

Provisioning your first device

When you log in to the Build Center, if you have yet to provide the UDID of your device, you will see a field where you will be able to enter the ID of the device you want to build for. Once we provision the device (typically within one business day) any app you may have submitted will be processed and you'll be able to sync it to your device using iTunes.

Provisioning additional devices

If you need your build to run on devices other than the initial one you got free with your purchase, you may purchase additional provisions for US$5 each. Send your payment (via PayPal) to sales@zimusoft.com and email DragonFireSDK Support at support@dragonfiresdk.com with the UDID's to be provisioned. We will handle the rest!

How do I include my own launch image(s) and icon(s) for my app?

If you want to provide a custom launch image (splash screen) and / or icon for your app, use the tables below to create your icons, launch images and iTunes artwork images in the required dimensions:

iPhone / iPod touch requirements

File Type File Name Image Dimensions
Application Icon (non-Retina) icon.png 57x57 pixels
Application Icon (Retina) icon@2x.png 114x114 pixels
Application Icon (iOS 7 and higher, including iPhone 6) icon-120.png 120x120 pixels
Application Icon (iPhone 6 Plus) icon-180.png 180x180 pixels
Launch Image (non-Retina) Default.png 320x480 pixels
Launch Image (Retina - 3.5 inch screen) Default@2x.png 640x960 pixels
Launch Image (Retina - 4 inch screen) Default-568h@2x.png 640x1136 pixels
Launch Image (Retina HD - 4.7 inch screen) Default-667h@2x.png 750x1334 pixels
Launch Image (Retina HD - 5.5 inch screen - Portrait) Default-Portrait-736h@3x.png 1242x2208 pixels
Launch Image (Retina HD - 5.5 inch screen - Landscape) Default-Landscape-736h@3x.png 2208x1242 pixels
iTunes Artwork iTunesArtwork (note: no extension) 1024x1024 pixels

iPad requirements

File Type File Name Image Dimensions
Application Icon (non-Retina) icon-72.png 72x72 pixels
Application Icon (Retina) icon-72@2x.png 144x144 pixels
Application Icon (non-Retina iOS 7 and higher) icon-76.png 76x76 pixels
Application Icon (Retina iOS 7 and higher) icon-76@2x.png 152x152 pixels
Launch Image (Portrait, non-Retina) Default-Portrait.png 768x1024 pixels
Launch Image (Portrait, Retina) Default-Portrait@2x.png 1536x2048 pixels
Launch Image (Landscape, non-Retina) Default-Landscape.png 1024x768 pixels
Launch Image (Landscape, Retina) Default-Landscape@2x.png 2048x1536 pixels
iTunes Artwork iTunesArtwork (note: no extension) 1024x1024 pixels

Does it cost anything to build on the Build Center?

No! Ad hoc builds for your device are free.

App Store Distribution

I'm ready to send my app to the App Store. Where do I begin?

When you're ready to begin the App Store submission process, go to this page of the DragonFireSDK web site and follow the steps provided: http://www.dragonfiresdk.com/distributionmethod_new.htm.

Do I need an Apple Developer Account?

No. If you want to publish a free app, then Zimusoft will publish it for you. You only need to have an Apple Developer account if you plan to publish paid apps, or if your app will contain iAds, use GameCenter or In-App Purchase features.

How much does it cost to submit an app to the App Store?

Your first App Store submission is free. Subsequent submissions (including updates) cost US$10 each.

What if I want to publish a paid application?

You will need to have your own Apple Devloper Account to publish your paid app, so you can receive the proceeds you make with your app directly from Apple. We can upload your paid app to your specific Apple Developer Account for you so you can publish it yourself. Zimusoft will only publish applications that are free.

How long after my app is submitted will it take for my app to get to the App Store?

Apple typically takes around two weeks from the time an app enters "Waiting for Review" status until the app enters "Ready for Sale" status.

Do I need to submit a new CSR Request for each App Store submission?

Not usually. Signing Certificates are good for one year, and you only need one distribution certificate at any one time. If your signing certificate ever expires or if you decide to revoke the existing certificate for any reason, then you will need a new certificate (as well as a new CSR Request file).

What do you need if I created my own CSR file on my own Mac?

If you have created a Certificate Signing Request file on a Mac under your own control, we will need a .p12 file in order to digitally sign your app. In order to create a .p12 file on the Mac, open Keychain Access and select the certificate in question. Right- (or Control-) click the certificate and select "Export <certificate name>..." You may then select a password (optional) and send the newly-generated .p12 file to support@dragonfiresdk.com with the password (if you added one) so that we can sign your App Store build.

Can I create a CSR file on my Windows computer?

If you have OpenSSL (a free and open-source program available at http://www.openssl.org) you may be able to create your own CSR file.

Once you have OpenSSL installed, you'll need to first create your own private key file by typing the command below:

openssl genrsa -out mykey.key 2048

Save the file created here. You'll need it later. Make sure not to ignore any possible errors. If you see errors, please verify that you entered everything correctly.

Now that you have your private key created, you can create your CSR file with a line like the one below:

openssl req -new -key mykey.key -out CertificateSigningRequest.certSigningRequest -subj "/emailAddress=yourAddress@example.com, CN=John Doe, C=US"

Be sure to replace the e-mail address and the name after "CN=" with your name and the country after "C=" with the appropriate two letter abbreviation of your country.

The file created by this command is what you will upload to Apple to create your signing certificate.

Once you have your distribtion_identity.cer file from Apple, you now need to convert it into a .p12 file so that DragonFireSDK staff can build and sign your app with your certificate.

First, convert the .cer file to a .pem file:

openssl x509 -in distribution_identity.cer -inform DER -out distribution_identity.pem -outform PEM

Finally, create the .p12 file for DragonFireSDK:

openssl pkcs12 -export -inkey mykey.key -in distribution_identity.pem -out distribution_identity.p12

That's all there is to it!

Apple rejected my app! Now what?

If Apple has rejected your app for any reason, they likely provided a specific reason. Address the issue provided and you'll have the opportunity to resubmit your app. If Apple still rejects your app for whatever reason, you may appeal the decision using the tools available on your Apple Developer account.

Other questions

Where do I turn when I have a question not answered here?

If you have a question that has not been answered here, you may e-mail DragonFireSDK Support at support@dragonfiresdk.com.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox