localStorage.setItem("name", "Brian");
var name = localStorage.getItem("name");
localStorage.setItem("data", {"foo":"bar","flip":"rep","arr":[1,3,4]});
var data = localStorage.getItem("data");
localStorage.setItem("name", "Brian");
var name = localStorage.getItem("name");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"downloadcell"];
if(cell==nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:@"downloadcell"] autorelease];
UIProgressView* downPreView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
downPreView.tag = 1234;
downPreView.frame = CGRectMake(400,70, 200,10);
[cell.contentView addSubview:downPreView];
}
//update the progress
UIProgressView* downPreView = (UIProgressView*)[cell viewWithTag:123]; downPreView.progress = downloadPre;
var string = device.uuid;
PhoneGap api docs are here if you need any more info... http://docs.phonegap.com/phonegap_device_device.md.html#device.uuid |
Vector contactList = Phone.getContactsByPhoneNumber(inputNumber); Contact contact = (Contact) contactList.elementAt(0); byteStream = contact.getBinary(Contact.PHOTO, Contact.ATTR_NONE); EncodedImage contactPic = EncodedImage.createEncodedImage(byteStream, 0, byteStream.length); String picType = String.valueOf( contactPic.getImageType() );
Instead of using a UIWebView, you can pull the webpage down as an NSData object using an NSURLConnection. When you get the initial response from your request from
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
the webserver should return a value of "expected content size" (which should be included in the response). Then you will keep getting the following method called each time you receive data:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
Keep appending the data to an existing NSData object. Then you can check the size of your current data object (NSData.bytes) against the expected response size.
percentage = (myData.bytes/theResponse.expectedContentSize)*100;
Then you can update a progress bar with that percentage! When
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
runs, use your data to call
[myWebView loadData:myData MIMEType:myMimeType textEncodingName:myEncoding baseURL:baseURL];
and it will load everything you pulled down into your web view.
/* * Some references: * http://www.cocoadev.com/index.pl?MethodSwizzling * http://samsoff.es/posts/customize-uikit-with-method-swizzling * http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1 * http://developer.apple.com/iphone/library/documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html * http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html * http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html * */ /* UINavigationBar+Additions.h */ #import @interface UINavigationBar (Additions) - (void)drawRectCustom:(CGRect)rect; @end /* UINavigationBar+Additions.m */ #import "UINavigationBar+Additions.h" @implementation UINavigationBar (Additions) // When the object is set up it calls drawRect, which then loads this method because of the method swizzling - (void)drawRectCustom:(CGRect)rect { // If the style of the bar is the default style, apply our custom visuals if (self.barStyle == UIBarStyleDefault) { // Create the drawing context CGContextRef ctx = UIGraphicsGetCurrentContext(); // Set the background color of the navbar [[UIColor blackColor] set]; CGRect fillRect = CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height); CGContextFillRect(ctx, fillRect); // Create an instance of the image we want to draw UIImage * logo = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"path/to/logo" ofType:@"png"]]; // Get the absolute center points relative to the image and the screen NSNumber * centerX = [NSNumber numberWithFloat:(self.frame.size.width/2 - logo.size.width/2)]; NSNumber * centerY = [NSNumber numberWithFloat:(self.frame.size.height/2 - logo.size.height/2)]; // Draw the image [logo drawInRect:CGRectMake(centerX.floatValue, centerY.floatValue, logo.size.width, logo.size.height)]; // End execution of the method return; } // By this time drawRectCustom is actually referencing to drawRect [self drawRectCustom:rect]; } @end /* main.m */ #import #import // Needed for the Method objects #import "UINavigationBar+Additions.h" // Needed to reference the method we wish to swizzle int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; /* Method Swizzling */ // Get our drawRectCustom method Method drawRectCustom = class_getInstanceMethod([UINavigationBar class], @selector(drawRectCustom:)); // Get the original drawRect method Method drawRect = class_getInstanceMethod([UINavigationBar class], @selector(drawRect:)); // Swap the methods, drawRect now becomes drawRectCustom and vice-versa method_exchangeImplementations(drawRect, drawRectCustom); /* End Method Swizzling */ int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; return (retVal); } @end
1. json-frameworkA strict JSON parser/generator for Objective-C
2. GTMBase64 Google Toolbox for Mac
3. TouchXML xml解析
4. SFHFKeychainUtils 安全保存用户密码到keychain中
5. MBProgressHUD 很棒的一个加载等待特效框架
6. ASIHTTPRequest http等相关协议封装
7. EGORefreshTableHeaderView 下拉刷新代码
8. AsyncImageView 异步加载图片并缓存代码
9. 类似setting的竖立也分栏程序
There are a lot of options when it comes to parsing XML on the iPhone. The iPhone SDK comes with two different libraries to choose from, and there are several popular third party libraries available such as TBXML, TouchXML, KissXML, TinyXML, and GDataXML. How is a developer to choose?
I have been recently taking a look at the various options out there, and ended up extending the XMLPerformance sample from Apple to try out each of the above libraries to learn how they worked and compare their performance. I thought I’d share what I’ve learned thus far to others who might be searching for the best XML library for their iPhone project.
In this article we’ll give a detailed comparison of the features and performance of the most popular iPhone libraries, explain how to choose between them, and give a sample project showing how to read XML data using each of the above libraries.
Before we begin, I wanted to make sure everyone is aware of the most important difference between XML parsers: whether the parser is a SAX or a DOM parser.
Ok, now let’s discuss some of the libraries!
In my research, here’s what seemed to me to be the most popular XML Parsers for the iPhone, and a brief description of each one:
Ok, now let’s start comparing all these libraries!
Apple has made an excellent code sample called XMLPerformance that allows you to compare the time it takes to parse a ~900KB XML document containing the top 300 iTunes songs with both the NSXML and libxml2 APIs.
The sample allows you to choose a parsing method and then parse the document, and it keeps statistics on how long it took to download the file and parse the file in a database. You can then go to a statistics screen to see the average download and parse times for each method.
I thought this would be an ideal way to test out how these various APIs performed against each other, so I extended the sample to include all of the above libraries. You can download the updated project below if you want to try it out on your device. It also serves as a nice example of how to use each of the above APIs!
Download Updated XMLPerformance Project
A note on the project: if the library included XPath support, I used it for a single lookup, because I felt it represented the way the library would be used in practice. But of course XPath is generally slower than manually walking through the tree, so it adds to the benchmarks for those libraries.
So anyway – I’ll discuss the results of how things performed on my device here with the sample written as-is – but feel free to give it a shot on your device, or tweak the code based on the actual XML data you need to parse!
Here’s some graphs that shows how quickly the various parsers parsed the XML document on my device (an iPhone 3Gs):
As you can see here, NSXMLParser was the slowest method by far. TBXML was the fastest, which makes sense because many features were taken out in order to optimize parse time for reading only.
I was surprised, however, to see that TBXML and some of the other DOM parsing methods performed faster than libxml2′s SAX parser, which I had thought would be the fastest of all of the methods. I haven’t profiled it, but my guess as to why it is slower is because of the frequent string compares needed to parse the document in the SAX method.
However, don’t discount libxml2′s SAX method by looking at this chart. Remember that libxml2 is the only one of these methods that can parse the document as it’s reading in – so it can let your app start displaying data right away rather than having to let the download finish first.
Ok, here’s a graph that shows the peak memory usage by parser (this was obtained through running the various methods through the Object Allocations tool):
Note that the DOM methods usually require more memory overhead than the SAX methods (with the exception of TBXML, which is indeed quite efficient). This is something to consider when you are dealing with especially large documents, given the memory constraints on an iPhone.
Also note that libxml2′s SAX method is the best option as far as peak memory usage is concerned (and I suspect it would scale better than the others as well).
Finally, let’s wrap up with a chart that summarizes the differences between the parsers and everything we’ve discussed above:
NSXML | libxml2 – SAX | TBXML | TouchXML | KissXML | TinyXML | GDataXML | libxml2 – DOM | |
---|---|---|---|---|---|---|---|---|
Included with SDK? | Yes | Yes | No | No | No | No | No | Yes |
Seconds to Parse | 1.87 | 1.19 | 0.68 | 1.1 | 1.37 | 1.27 | 1.07 | 0.84 |
Peak Memory Usage | 3.11 | 3.01 | 3.07 | 6.5 | 5.25 | 4.8 | 4.15 | 4.97 |
Parse While Downloading? | No | Yes | No | No | No | No | No | No |
Edit/Save XML? | No | No | No | No | Yes | Yes | Yes | Yes |
XPath Support? | No | No | No | Yes | Yes | Yes* | Yes | Yes |
C or Obj-C | Obj-C | C | Obj-C | Obj-C | Obj-C | C | Obj-C | C |
License | Apple | MIT | MIT | MIT | MIT | ZLib | Apache | MIT |
* = with TinyXPath
Which XML parser to choose really depends on what you want to do with the parser.
What about the ones I didn’t mention?
I took a look at two other XML libraries during the course of this investigation (VTD-XML and Objective-XML), but I couldn’t get them working. If someone else has had more luck with these, feel free to extend the sample project to include them!
If you’re looking for some help using one of these libraries, check out my post on How to Read and Write XML Documents with GDataXML.
And if anyone has any additional feedback about these libraries or tips that may help other developers, please chime in below!
If you require only a single instance of an object in your application, where should it go? How should you control and manage it? Here are some different approaches, their implementations, their strengths and their weaknesses.
Global variables is a term that invokes a sense of dread in experienced programmers. They are feared because a program filled with global variables (when it should use scoped variables instead) is a program without structure; a totally unmanageable mess.
This post will be entirely about writing and using global variables.
The reality is that applications need to have some global state; we must have global variables. A variable will need to be global if all of the following are true:
If all of these are true, then you should use a global variable.
If you're wondering, variables that fall outside these rules should be (respectively):
- child variables of the object that manages them
- children of the object that manages the collection
- a
#define
or aconst
(constants are state for the compiler, not the program)
Actually, what I will be showing are the "in practice" global variables of a Cocoa program — in reality, none of the techniques I show you will be true global variables in the Standard C Language sense but these approaches have replaced true global variables in Cocoa programs in almost all cases.
I will be showing you top-level child objects (children of the application delegate) and singleton objects. Explaining why these are normally considered equivalent to globals:
As every Cocoa programmer knows, an application delegate is created in the MainMenu.xib file:
or the MainWindow.xib file for the iPhoneSDK.
A globally accessed variable can be initialized in the applicationDidFinishLauching
delegate method:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { myGlobalObject = [[MyGlobalObject alloc] init]; }
and assuming myGlobalObject
has an associated getter method, you can now access it globally using:
[[NSApp delegate] myGlobalObject]
or on the iPhone:
[[UIApplication sharedApplication].delegate myGlobalObject]
Since the delegate
property returns an id
(instead of the actual class of your delegate), you can't use property notation for the myGlobalObject
itself unless the myGlobalObject
is a property and you wrap the delegate in parentheses and inside the parentheses cast the delegate to your application delegate's class, like this:
((MyAppDelegate *)[UIApplication sharedApplication].delegate).myGlobalObject
Although I have seen people declare the following macro in their delegate's header:
#define UIAppDelegate \ ((MyAppDelegate *)[UIApplication sharedApplication].delegate)
which then allows you to use:
UIAppDelegate.myGlobalObject
from anywhere that includes your delegate's header.
Having explained that the above could be done, I will tell you that in my programs, I avoid using the AppDelegate
for anything other than:
NSApplication
delegate methods (including applicationDidFinishLaunching:
to finalize application construction)Relying on your AppDelegate
object to manage your global variables can quickly get scary for the same reason that global variables in general are considered scary: you can easily put too much into this top level and it becomes a big, unstructured mess. This problem is an anti-pattern, often called the Big Ball of Mud.
It is a bad idea structurally for two reasons. The first is encapsulation. The AppDelegate should only really be connected to things related to the AppDelegate (i.e. the NSApplication
object and related state). If you store data related to other objects inside the AppDelegate, you rob those other objects of control over themselves.
Separation of concerns is the other serious problem. It is not the application delegate's responsibility to be the gatekeeper and manager of non-Application-related variables within the program.
A well-designed program organizes its classes so that they are all discrete, self-contained entities, shoving connections to everything into the AppDelegate
violates this idea.
The solution to the encapsulation problem is to create classes that manage any global data as discreet modules. This is done through a singleton.
The basic recipe for making a singleton is given by Apple: Creating a Singleton Instance.
I personally like to put these singleton methods into a macro, which you can download in my SynthesizeSingleton.h file. If you #import
this header at the top of a class implementation, then all you need to do is write:
SYNTHESIZE_SINGLETON_FOR_CLASS(MyClassName);
inside the @implementation MyClassName
declaration and your class will become a singleton. You will also need to add the line:
+ (MyClassName *)sharedMyClassName;
to the header file for MyClassName
so the singleton accessor method can be found from other source files if they #import
the header.
Once your class is a singleton, you can access the instance of it using the line:
[MyClassName sharedMyClassName];
Note: A singleton does not need to be explicitly allocated or initialized (thealloc
andinit
methods will be called automatically on first access) but you can still implement the defaultinit
method if you want to perform initialization.
A well-designed singleton is a discrete, self-managing object that manages a specific role within your program.
Where variables hung off the Application delegate may have nothing in common with the delegate object itself, a singleton should be entirely focussed on its own specific role and responsibilities.
Search the Mac OS X 10.5 Reference in XCode for methods that begin with "shared" to see the ways in which Apple use singletons to create "manager" objects which allow you to get, set and manipulate entities that exist only once in a program.
Also, since the singleton is accessed through a method, there is some abstraction around the specific implementation — you could move from a true singleton to a per-thread based implementation if you needed, without changing the external interface.
Don't use globals unless you need to do so. An overwhelming majority of the data in your program has a sensible parent that is not the top-level. Singletons and top-level data should be used only when the data they contain truly belongs at the top level.
Cocoa singletons are flexible and useful when you need them. Using your application delegate to hold top-level data will work but try to limit its responsibilities to MainMenu.xib allocated objects where possible.
Posted by Chris Danielson in iPhone Development on December 4th, 2009
Welcome to the club of searching for an overly simple UIWebView a.k.a. WebKit example! In this example, I’ll show you simply how to hand code a quick UIWebView into your program as well as to add a UIActivityIndicatorView a.k.a. an activity indicator. Without jabbing Apple too hard here, the documentation is pretty bad and that is why it’s nice to have an example just shown to you as-is. I hope this example helps shine a light on the situation for anyone wanting to implement a nice and quick Apple iPhone WebKit solution.
#import |
/* Inside the @implementation FirstViewController ... */ - (void)viewDidLoad { //We have a NIB file in play here, so I dropped the loadView here. Just make sure that your loadView is not getting called twice! [super viewDidLoad]; [self loadView]; } - (void)loadView { UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; self.view = contentView; CGRect webFrame = [[UIScreen mainScreen] applicationFrame]; webFrame.origin.y = 0.0f; myWebView = [[UIWebView alloc] initWithFrame:webFrame]; myWebView.backgroundColor = [UIColor blueColor]; myWebView.scalesPageToFit = YES; myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); myWebView.delegate = self; [self.view addSubview: myWebView]; [myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.maxpowersoft.com/"]]]; activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; activityIndicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0); activityIndicator.center = self.view.center; [self.view addSubview: activityIndicator]; } - (void)dealloc { [activityIndicator release]; [myWebView release]; [super dealloc]; } #pragma mark WEBVIEW Methods - (void)webViewDidStartLoad:(UIWebView *)webView { // starting the load, show the activity indicator in the status bar [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; [activityIndicator startAnimating]; } - (void)webViewDidFinishLoad:(UIWebView *)webView { // finished loading, hide the activity indicator in the status bar [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; [activityIndicator stopAnimating]; } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { // load error, hide the activity indicator in the status bar [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; // report the error inside the webview NSString* errorString = [NSString stringWithFormat: @" |
That is all there is to it. It’s really simple as you can see. Feel free to copy and paste accordingly.
All too often an iPhone application’s launch sequence is an overlooked detail. The most common approach is to misuse the provided Default.png file as a splash screen. As it turns out, this detailing of an application is more than a little challenging if you want to get it right and stay within Apple’s guidelines.
The key to a smooth and professional looking launch sequence starts with knowing exactly where the application will land at startup. Some applications start at exactly the same place each and every successive launch, others attempt to preserve the application’s state and launch into the screen where the user last used the application. Keeping this in mind can change the strategy of how the launch sequence is implemented. This includes screen orientation as well as how and even if the status bar it to be displayed.
One may witness flickering of the status bar from blue, to black or from black to blue during the launch sequence. This is mainly due to the fact that there are two places to change the behavior of the status bar. One is hidden in the info.plist file, and the other is typically via code in the Application Delegate’s applicationDidFinishLaunching
method. The info.plist
configuration is used before the main window is loaded, and the code in the Application Delegate is used during the launching of the main window. The reason one may want to utilize both styles is to take advantage of a full screen splash page, and then enable the appropriate looking status bar once the application has finished loading.
For the purpose of this example application, we will assume that the user state is preserved between executions, and we do not know exactly what the screen will look like when the user enters the application. We will therefore be implementing a full-screen splash view that will have the status bar hidden during the launch sequence. Once the splash view has disappeared, a black opaque status bar will be utilized throughout the application. It is also assumed that the application will launch in portrait mode, and that the first screen the user will see will also be in portrait mode.
The first order of business is to take care of the status bar. In Xcode, locate the info.plist
file for the project. To add an additional property to the plist file, simply select one of the entries and click on the plus tab that appears to the right and select Status Bar Style from the drop down list:
There are only three different styles to choose from. Try each style out to see which one fits the needs of the application being developed. For this example we will set the style to UIStatusBarStyleDefault
.
UIStatusBarStyles:UIStatusBarStyleDefault
— Gray (the default)UIStatusBarStyleBlackTranslucent
— Transparent black (specifically, black with an alpha of 0.5)UIStatusBarStyleBlackOpaque
— Opaque black
If on the other hand the desire is to hide the status bar when the application launches, then yet another property needs to be set. In this case, add the “Status Bar is initially hidden” property to the plist file and be sure to check the box next to the property.
So now that the status bar style is set, and initially hidden, how does one get the status bar to display again? You can actually turn the status bar on and off programmatically via code. This is particularly handy when the need arises to display a full screen view, such as the splash screen this application is utilizing. In the applicationDidFinishLaunching
method of the Application’s designated AppDelegate class, add the following line of code to make the status bar visible again:
1 | - ( void )applicationDidFinishLaunching:(UIApplication *)application { |
2 | // Override point for customization after app launch |
3 | [window addSubview:viewController.view]; |
4 | [window makeKeyAndVisible]; |
5 | [[UIApplication sharedApplication] setStatusBarHidden: NO animated: YES ]; |
6 | } |
Surprisingly, the size of this file is not as important as the naming convention of the file. Default.png is a case sensitive PNG file. The image should be 480×320 according to Apple. Following Apple’s conventions, this image should look like the view that the user will see when the application has launched, and not the actual splash screen.
Xcode provides a mechanism to create a Default.png file from an attached device running the application. From the Organizer window, select the device, click on screenshots and click capture. To make that screenshot your application’s default image, click Save As Default Image. Even though the image that is created includes the status bar as it looked when the screen shot was captured, the iPhone OS replaces it with the current status bar when your application launches. Just to be clear, this is not a splash screen…not yet.
So far, this is what most applications will implement if they implement any sort of controlled visual experience when the application launches. If you follow Apple’s guidelines, and the image you produce is the first screen that the user will see, all is good. Except, what if the launch sequence is not as fast as the user expects? What if the application preserves state and lands on a different view based on the users last know state? Then this technique is not up to the task.
Photoshop a branded image representing the application and save it as a PNG image sized at 480×320. Do not include a status bar of any kind in the image file being created. Add this image file to the project. Now the application sort of has a splash screen, through a misused implementation of the Default.png file. To correct this, simply add an image view as a property to the App Delegates header and create it as follows:
1 | splashView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; |
2 | splashView.image = [UIImage imageNamed: @"Default.png" ]; |
3 | [window addSubview:splashView]; |
4 | [window bringSubviewToFront:splashView]; |
At this point, the image view is utilizing the exact same image file that was created in Photoshop. There’s no chance of the initial view being different than the Default.png file at this point. The one remaining problem is the timing of when to remove the image view from the subview. This can be handled in one of two ways…
The first option is for those with quick startup times that just want a splash screen. In this situation, create a method to remove and release the splash view, then calling that method via a timed perform selector call as follows:
1 | [ self performSelector: @selector (removeSplash) withObject: nil afterDelay:1.5]; |
The removeSplash
method does just that, removes the image view from the subview and releases the object.
1 | -( void )removeSplash; |
2 | { |
3 | [splashView removeFromSuperview]; |
4 | [splashView release]; |
5 | } |
The second method uses the same remove splash method, but relies on the built in event management to trigger when the method gets called.
1 | [[ NSNotificationCenter defaultCenter] addObserver: self |
2 | selector: @selector (saveClaim:) |
3 | name: @"RemoveSplashScreen" |
4 | object: nil ]; |
Now all that needs to be done is to post the notification from anywhere. This technique is particularly useful if the reason that the launch sequence is taking a long time has nothing to do with code that was implemented in the App Delegate.
1 | [[ NSNotificationCenter defaultCenter] |
2 | postNotificationName: @"RemoveSplashScreen" |
3 | object: nil ]; |
This technique can be employed from anywhere within the application. Removing the observer after the fact may avoid crashes if there is an opportunity for this notification to be fired multiple times. Releasing an object when no object it there to be released can lead to troublesome crashes to track down. The quick and dirty is to use the delay on the performSelector
call.
And there it is, a splash screen that conforms to Apple’s guidelines. No hidden APIs, no hacks, no special sauce. A simple, straight forward approach to making the initial interaction with the user as pleasant as possible.
References:
12-17-2010 02:05 PM
hey shethab,
dont sweat it we've all be there! here's how you set the background color of your application. Where there are two ways:
First set the meta data to a solid background color like this:
package
{
import flash.display.Sprite;
[SWF(width="1024", height="600", backgroundColor="#CCCCCC", frameRate="30")]
public class MyApplication extends Sprite
public function MyApplication()
{
(...)
}
}
}
The background is in the same format as HTML coloring. The second way is by creating a shape object as large as the screen and adding it as the first child to your program like so:
package
{
import flash.display.Shape;
import flash.display.Sprite;
[SWF(width="1024", height="600", backgroundColor="#CCCCCC", frameRate="30")]
public class MyApplication extends Sprite
{
public function MyApplication()
{
var appBackgroundColor:Shape = new Shape();
appBackgroundColor.graphics.beginFill(0xFF0000);
appBackgroundColor.graphics.drawRect(0,0,1024,600);
appBackgroundColor.graphics.endFill();
addChild(appBackgroundColor);
(...)
}
}
}
To add an image is like the second step only using the Image class like this:
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.filesystem.File;
import qnx.ui.display.Image;
[SWF(width="1024", height="600", backgroundColor="#CCCCCC", frameRate="30")]
public class MyApplication extends Sprite
{
public function MyApplication()
{
var appBackgroundImage:Image = new Image();
appBackgroundImage.setImage(File.applicationDirectory.resolvePath('path/to/image.png').url);
appBackgroundImage.setSize(1024,600);
appBackgroundImage.setPosition(0,0);
addChild(appBackgroundImage);
(...)
}
}
}
hope that helps! good luck!