This Code Stinks - University of Waterloo

Download Report

Transcript This Code Stinks - University of Waterloo

Mobile Application Development
Getting started with Application development of the iPhone and Blackberry
Introduction
 Hello
 I’m a Mac (iPod Touch), and
 I’m a PC (Blackberry Bold)
 Sorry wrong commercial but technically correct
 iPhone SDK was designed to run on Mac OS X 10.5.7and
 Blackberry SDK was designed to run on MS Windows though it can sort of run on
Linux under wine.
 A Tale of Two Phones
 How to build “Hello World” app on iPhone and Blackberry
 Skills learned
 in 45 minutes you will leave knowing (I hope) how to get started on app
building for both platforms
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
iPhone










http://www.apple.com/iphone/specs.html
4.5”(H) X 2.4”(W) X 0.48”(D)
Weight: 4.8 ounces (135 grams)
Screen size: 3.5”
Screen resolution: 320 by 480 at 160 ppi
Input method: Multi-touch
Operating system: OS X
Storage: 4GB or 8GB
Data standard: Quad-band GSM (MHz: 850, 900, 1800, 1900)
: Wi-Fi (802.11b/g) + EDGE + Bluetooth 2.0
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
what it looks like
Apple iPhone
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
What I need
 What is needed to get started
 Platform, equipment, registration
 What is SDK
 What limitations are there
 Storage, memory, energy, SDK
 What to do when things go worng
 What example.
 What do I do to get it from code to phone.
Prerequisites
 In order to begin programming on the iPhone or
iPod touch you will need:
1.
2.
3.
4.
5.
6.
7.
A copy of Apple’s iPhone SDK
An iPhone or iPod touch
An Apple iPhone Developers Licence
An Intel-based Macintosh running 10.5.4 and >
An available USB port
An internet connection, and
A familiarity with some OOP
SDK
 Download your copy of iPhone SDK from Apple’s
iPhone Dev Center –
http://developer.apple.com/iphone/
 You must also join the developer program before
you download
 Current release Sept 21st, 2009 is 3.1.4
iPhone/iPod
 You do not need an iPhone or iPod touch since
Apple does supply a simulator in SDK
 But you will need a unit if you are going to do some
serious code building and testing
 There is currently no tether less capabilities with the
iPhone so you have to use the supplied cable to install the
software you built
ADP
 Apple Developer’s Programme –
http://developer.apple.com/iphone/program
 You need a licence to be able to sign your app, download
to platform, and to test and debug
 Program costs $99.00US/year for individual and
$299.00US/year for enterprises.
 The University is a member of the ADP and can register up
to 200 units per year.
Mac
 SDK requires a Macintosh unit






iMac, MacBook, mini,
Intel-based
32 bit – why?
Leopard Mac OS X 10.5.4 or higher
Snow Leopard Mac OS X 10.6
At least 1G ram and lots of disk space
USB
 At least 1 available USB 2.0 port
 Enables you to tether your iPhone to your computer for
transfers and testing
Internet Connection
 Allows for testing with WiFi and EDGE
OOP
 Object Oriented Programming
 Usually objective-C or objective C++
 Objective-C is based on standard C with OO extensions
 Consult any objective-C or Cocoa books to get up to speed
SDK
 The Software Developers Kit consists of several
components:






Xcode
Instruments
Dashcode
Simulator
Interface Builder
Cocoa touch
Xcode
 Most important tool in SDK
 Provides comprehensive project development and
management
 Source editing
 Documentation
 Graphical debugger
 Built around GNU tools – gcc and gdb
Instruments
 Profiles how apps work under the hood
 Samples memory usage
 Monitors performance
 Provides graphical time-based performance plots which
shows resource use
 Built around Dtrace package from Sun
 Helps track down memory leaks
 Makes sure apps run efficiently on the iPhone
Dashcode
 Creates stand-alone Web-based applications that
run outside of browser environments
 Works like a browser with layout and debugging tools
 Web-based development approach
Simulator
 Runs on Macintosh and enables you to create and
test applications
 Does not need a connection to an actual iPhone or iPod –
as shown in the build example
 Offers same API as on the iPhone
 Runs x86 code natively on the Macintosh
 You need to recompile with ARM-based code used on the
iPhone
Interface Builder
 IB provides a rapid prototyping tool
 Allows graphical layout of user interfaces
 Lots of prebuilt interfaces from Xcode
 You draw the interface using visual design tools and then
connect them to objects and method calls in your
application
Cocoa touch
 Consists of a library of classes provided by Apple
for app development
 Large number of framework libraries such as windows text
and tables that help build graphical event-driven
applications
 Same as AppKit on the Mac OS X
 Main reason why iPhone apps are so small
Limitations








Storage
Data Access
Memory Limits
Interaction
Energy
Application
User
SDK
Storage
 Entire iPhone OS fills just a few hundred
megabytes of space
 Provides an extensive framework library
 Compact apps for telephony, audio playback, email, web browsing
 Just enough programming support to create flexible interfaces
Data access
 Every app is sandboxed
 Cannot access from other apps or folders including
onboard iTunes library.
 Can access any data freely available over the internet
Memory
 TIGHT
 Memory management is critical
 Does not support disk-swapping virtual memory
 When you run out of memory the device reboots
 Random reboots are not what the user wants
 Too many high resolution images or audio files will bring your app
into auto terminate zone
 Use PNG images as your preferred image format since SDK has
an app called pngcrush that optimizes the image file
Interaction
 No need to fret about losing physical input devices
 Multitouch allows for a screen size larger than the actual
physical reality you hold in your hands
 Autocorrecting onscreen keyboard
 Accelerometer to detect orientation
 Focus app design efforts on easy-to-tap interfaces
 You can only use one window at a time
Energy
 You cannot ignore energy limitations
 SDK helps in design of apps to limit CPU use
 Suspend programs when not in use
 Some programs when left running produce high levels of waste heat – so much
so that the device becomes hot to the touch
 The camera app is one such example
Application
 Strong “one-app-at-a-time” policy
 Cannot run in the background like Apple’s mail and Phone
utilities
 Each time the app runs it must clean up before passing
control onto the next app
 Cannot leave daemons running
 An “Open SDK” created by users exists which bypasses this limitation but
these apps cannot be added to or sold by the iPhone store
 Does support push data from Web services
User
 Must design your app around short interaction
periods
 Must be prepared to be cut off (i.e. when the user puts
the device back into their pocket)
 Save your app state between sessions and relaunch
quickly to the state the last time the program ran
SDK
 SDK has limitations
 Garbage collection is non existent – you are responsible
for retaining and releasing objects in memory
 Many libraries are only partly implemented
 You cannot use some proprietary classes
 Public SDK frameworks are not as varied as private ones –
i.e. Those from the open SDK jailbreak world
debugging
 Shark
 Code profiler can help optimise performance
 Dtrace
 Comprehensive dynamic tracing framework created by
Sun for trouble shooting kernel and application problems
in real time
 D programs are awk like in structure
 Instruments
 Dtrace GUI
Example









Start Xcode
Create new iPhone/iPod “hello World” Project
Build and run app
Status bar
Setting the background
Idle timer
Using Xcode assistant
Using Xcode console and printf
review
Start Xcode
 Apple provides a tool named Xcode as the Apple Integrated Development Environment, or IDE,
for both Mac OS X and iPhone development. Here you will startup Xcode.
1. Click on Finder, which is at the bottom left of the screen on the Dock. This opens
Finder, showing your disk and files on the disk.
2. Near the top left of the Finder window, find the word Devices.
3. Under the word Devices, observe the word Macintosh HD.
4. Click on the Macintosh HD, and observe the Folder named Developer.
5. Double-click on the folder named Developer.
6. Look for the folder named Applications.
7. Double-click on the folder named Applications.
8. Look for the icon labeled Xcode.
9. Double-click on the icon named Xcode.
10. After a moment you should observe Xcode running, as shown by the top-level menu
saying Xcode.
Create new iPhone/iPod app
 In this step, you will create a new Xcode project named helloworld.
1. From the Xcode menu, select File > New Project.
1. Click on iPhone OS Application category (if not already selected).
2. Click on Window-Based Application.
3. Click on Choose button.
4. Enter the name helloworld.
5. Click on Save button.
 The result of the above steps is that Xcode will create a new project named helloworld that
includes template files to start your development.
Build and Run helloworld
 Here you will build and run helloworld, observing the results of the default build.
1. In Xcode, find the icon in the top tool bar labeled Build and Go.
2. Click on the Build and Go, which will build your project, and start it, running it in the
iPhone Simulator.
3. NOTE: If the iPhone Simulator is already running, you may get an error in Xcode
saying it cannot startup the iPhone Simulator. If you get this error, press
“Command+Tab” key until you select the iPhone Simulator, and then exit the
simulator.
4. Observe the helloworld App running in the iPhone Simulator, making note of the toplevel Status Bar, and the all-white window.
5. Press the Home key on the iPhone Simulator (at the bottom of the iPhone) to stop the
helloworld app and return to Home on the iPhone Simulator.
Hello World Code
1. Create a new iPhone project of the “View-Based Application” type.
2. Open HelloWorldViewController.m in the “Classes” folder, uncomment the
ViewDidLoad method on line #35 and add this code to it:
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *helloLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 30, 100,
30)];
[self.view addSubview:helloLabel];
helloLabel.text = @"Hello World";
}
3. Hit the “Build and Go” button and watch the magic
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
This is what you get
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Enhancing the helloworld app
 While the default helloworld is a good start, we can enhance the
application as follows:
1. Hide the Status Bar.
2. Make sure background of window is always white.
3. Disable timer so that display does not turn off after a short delay of non-use.
Status Bar

Since we want as much light as possible from the helloworld, it makes sense to hide the Status Bar that is at the top of the Window. Follow these steps to
create the code to hide the Status Bar, followed by a rebuild and a re-run in the iPhone Simulator:

1.
Press the Command+Tab keys until you return to Xcode.





2.
3.
4.
5.
6.
Looking at the Xcode, on the left you will see a window named Groups & Files.
Under the Groups & Files, you will see helloworld.
Under helloworld, you will see a folder named Classes.
Click on the Classes folder.
After clicking on the Classes folder, you should see two files listed under File Name on the right side of the screen:

o
helloworldAppDelegate.h

o
helloworldAppDelegate.m

7.

8.
Observe the helloworldAppDelegate.m code shown on the lower right portion of the Xcode screen, looking for a line of code
that looks like this:
Click on helloworldAppDelegate.m.

o
- (void)applicationDidFinishLaunching:(UIApplication *)application

9.

10.
At the end of the line, notice the application parameter. This parameter gives you access to the application object that is the
heart of your iPhone application.
11.
Observe the line of code that looks like this:

This method, applicationDidFinishLaunching:, is called at the end of your application launch.


o
// Override point for customization after application launch
12.
This is a comment, and it tells us to add code below this point to customize the helloworld application after launch. This is
indeed what we want to do, i.e., we want to hide the Status Bar after our application launches.
Cont.

12.
At the line below the comment, start typing the following code, but instead of pressing the return key at the end of the line,
press the ESC key to display the list of choices at this point in your code:

[application

14.
your code.

15.
With the list of choices displayed, use your mouse to scroll down until you find the choice named setStatusBarHidden:
(observe that the : is part of the name).
16.
Double-click on setStatusBarHidden:, and you will see the following line of code in your helloworldAddDelegate.m:




o
To repeat: you should type [application, and then press the ESC key. This will show you all the choices you can enter next in
[application setStatusBarHidden:(BOOL)
17.
Observe that “(BOOL)” is highlighted, and if you immediately type YES, the (BOOL) will be replaced by the YES, resulting
in your line of code looking like this:

o
18.
[application setStatusBarHidden:YES
Complete the line of code by adding the closing ] and a semicolon:

o
[application setStatusBarHidden:YES];

19.
Make a mental note of what the above line says: “Send the message named setStatusBarHidden:, with the argument YES, to
the object referenced by application”. This line of code is Objective-C, which is a super-set of the C programming language.

20.
Again, make sure you know how to “say” the line of code above: “Send the message names setStatusBarHideen: with
the argument YES to the object reference by application.”
21.
Once again click on Build and Go.
22.
Assuming you did not have any errors from the previous step, you should see the helloworld App running in the iPhone
Simulator with the Status Bar hidden.
23.
While in the iPhone Simulator, press the Home button to stop the helloworld application, returning to the home screen.




o
As a review, in this step you used the Objective-C message passing syntax to send a message to the application object, telling it to hide the Status Bar.
Setting the background colour

Although the window background is set to white by default by the template, in this step you will set the window to a white background under program
control. Along the way, you will temporarily set the window background to red, to confirm that you indeed have control of the window background.

1.

2.
The helloworldAppDelegate.m code should still be visible from the previous exercise. If not, click on the
helloworldAppDelegate.m name to make the code visible in the editor.
3.
Under the line of code you added in the previous exercise, start typing the following code, including the “.” at the end of the
word window, then press the ESC key:

Press Command+Tab to return to Xcode.

o
window.

4.
After pressing the ESC key, you should again observe a pop-up window, showing you choices.


5.
6.
Using your mouse, scroll to find backgroundColor.
Double-click on backgroundColor, which results in your code looking as follows:


7.
window.backgroundColor
Continue typing the line so that it appears as follows, once again pressing the ESC key at the end of the text:


o
o
8.
window.backgroundColor = [UIColor
After you press the ESC key, you will see the window of choices, and use your mouse to select redColor:

o
window.backgroundColor = [UIColor redColor
Cont.
 9.
Then go ahead and add the ending ] and ; to complete the line:
 o window.backgroundColor = [UIColor redColor];
 10.
The line of code you just entered says to do two things:
 1. Send a message named redColor to the class named UIColor.
 2. Set the window property named backgroundColor to the results of the [UIColor
redColor] message.
 11.
Click on Build and Go.
 12.
Assuming there are no errors from the previous step, you should see that your window
now has the background color of red.
 13.
Click on the iPhone Simulator Home key to exit helloworld.
 14.
Return to Xcode, and change the redColor to whiteColor:
 o window.backgroundColor = [UIColor whiteColor];
 15.

Click on Build and Go.
 16.
Assuming there are no errors from the previous step, you should see that your window
now has the background color of white.
 17.
Click on the iPhone Simulator Home key to exit helloworld.
As a review, in this step you learn how to set the background property of the window object. You also learned
how to send a color message to the UIColor class.
Idle timer
 As a review, in this step you disabled the idle timer by sending a
message to the application object at program startup. You also
sent another message to the application object to re-enable the
idle timer at program termination.
 Hint - use
[application setIdleTimerDisabled:(BOOL)
Xcode research assistant
 In the previous step, how did I know about the
applicationWillTerminate: message? The answer is that I used the
Xcode Research Assistant, and in this step you too will find
how to make use of the Xcode Research Assistant.
 Hint - Double-click on UIApplicationDelegate to select the complete
word
 Using the Xcode menu, click on Help > Show Research
Assistant
A bit of debugging
 Although helloworld is a graphical app for the iPhone, you can
send status and/or debugging information to the Xcode console
by using the printf() function. In this step, you will put printf()
functions in the helloworldDelegate.m code, so you can see
when the application starts, and when it ends.
Review of Key Skills
 As a review, you have learned the following skills during this example on
constructing a helloworld App

How to setup a software development environment for the iPhone.

How to use Xcode to build an iPhone Window-Based Application.

How to hide the iPhone Status Bar.

How to change the background color of an iPhone window.

How to disable and re-enable the iPhone idle timer.

How to use the Xcode Research Assistant.

How to use the Xcode console to view output from printf().
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
From Xcode to iPhone
 You have to sign your app
 Best place is to go through the developers site and obtain
a certificate.
 Then build for the device
Summary




Briefly Covered iPhone app development
Limitations
Example
3.1.x unjailbreaks – so far can only run 3.0.4 or
2.2.4
References
 http://developer.apple.com
 http://cydia.saruk.com
 Numerous books on iPhone,
Blackberry
 The Blackberry Bold uses the Marvell "Tavor" PXA930 624 MHz ARM
Architecture based - XScale processor
 Multimedia built-in GPS and Blackberry maps
 QWERTY keyboard
 Half-VGA (480x320 pixel resolution)
 65,000-color display
 Quad-band (GSM 850/900/1800/1900)
 Wi-Fi (802.11a/b/g)
 Bluetooth 2.0 with full A2DP support
 Measures: 4.5" (H) X 2.6" (W) x 0.5" (D)
 Weighs: 4.7 ounces.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
What it looks like
Blackberry Bold
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
What I need
 What is needed to get started
 Platform, equipment, registration
 What is JDE
 What limitations are there
 Storage, memory, energy, JDE
 What to do when things go worng
 What example.
 What do I do to get it from code to phone.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Platform
 You will need:
 Computer running Windows 2000 SP1, Windows XP,
Windows Vista, or Windows 2007
 The more RAM and CPU speed you have, the better
 For all Blackberry development tools such as free
downloads, developers knowledge base, etc., head for:
 http://www.blackberry.com/developers
 You will need to download two development environments
 Blackberry Java Development Environment (JDE)
 Blackberry JDE Plug-in for Eclipse
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
JDE
 Fully integrated stand-alone environment
 Need JDK installed first
 Everything is included
 Writing code with built-in editor
 Debugging with array of device simulators
 Building and signing your application
 To load your application onto a Blackberry device directly
from your computer (i.e. without uploading to a server and
download via a wireless connection)
 Need to install Blackberry Desktop Manager which include
the device drivers for the blackberry
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Getting Code Signing Keys
 You need to get code signing keys from RIM if your
application:





Uses persistent store
Cryptography APIs
Embeddable web browser
A set of code signing keys costs $20.00
More info at:
 http://na.blackberry.com/eng/developers/javaappdev/codekeys.jsp
 https://www.blackberry.com/SinedKeys/
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
You need to remember
 Limited CPU and memory
 Java as the Native API
 Always in a garbage-collected, bytecode-interpreted
environment without real-time access to the hardware
 Limited screen real-estate
 Largest screen measures 3.25” and has a 360 X 480
resolution
 User input
 The Storm has a touch screen – other devices don’t
 Many different devices
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Create a BlackBerry device
profile
 In the BlackBerry® Smartphone Simulator, double-click the
fledgelauncher.exe file.
 In the drop-down list, select Create a new simulator profile.
 In the Software version drop-down list, select the software version.
 In the Handheld model drop-down list, select the BlackBerry® device you
want to use.
 In the Profile name field, type a name for this profile.
 Click Configure.
 In the Edit simulator profile dialog box, on the Hardware tab, specify the
hardware settings for this BlackBerry Smartphone Simulator.
 On the Network tab, specify the network settings.
 On the Advanced tab, specify advanced settings such as LCD timeout, and
add command line arguments for the BlackBerry Smartphone Simulator.
 Click OK.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Launching Blackberry Simulator
 In the BlackBerry® Smartphone Simulator
directory, launch fledgelauncher.exe.
 In the drop-down list, select Launch a simulator.
 In the Profile list, select the profile.
 Click Go.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Hello World
 I want to show you how to create a simple
Blackberry application in Java. Of course since this
is Java, we will be typing way more than it is
logically necessary. For example, a simple Hello
World application requires no less than two
classes, with a full complement of boring
boilerplate code. If you are a long time Java
programmer you probably just went “Only two?
Phew! I thought it was worse”.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Hello World
 Our first class is basically there just to hold the
main function, because that’s what you do in Java.
You create a class, then you declare your main
function, and then you writhe your procedural code
inside:
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Import net.rim.device.api.ui.UiApplication;
public class HelloWorld extends UiApplication {
public HelloWorld()
{ pushScreen(new HelloScreen()); }
public static void main(String[] args) {
HelloWorld instance = new HelloWorld();
instance.enterEventDispatcher(); }
}
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Hello World
 There are two things here that might require
explanation. The pushScreen method takes an UI
container as a parameter and then paints it on
screen. In our case this container is going to be a
class extending
net.rim.device.api.ui.container.MainScreen – I will
show you how to create one in just a second.
 The enterEventDispatcher method enters the main
loop and handles capturing and dispatching events.
The rest should be self explanatory.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Now for the actual GUI container:
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
public class HelloScreen extends MainScreen {
public HelloScreen() {
super();
LabelField applicationTitle = new LabelField("My First
Applicaiton");
setTitle(applicationTitle);
LabelField hello = new LabelField("Hello World!");
add(hello); } }
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Hello World
 As you can see, blackberry apps are built just like
any other Java GUI apps. You initialize container,
label, field and button objects, you add them to
each other creating hierarchies. There are some
layout classes that can help you out and if you
need to capture events you attach a listener to an
object just like you would do it in Swing app. This
is how our app looks like in the emulator:
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Building Your App
 With all of the components in place, we're ready to build and deploy
your application to your BlackBerry device. From within the JDE,
select Debug | Go to start the build process. The progress of the
build will appear in the status window at the bottom of the JDE.
 Once the build process has completed successfully, the client
simulator will open and display your application
 You can use the simulator to test your application and ensure that
the program runs as expected. In this example, you should be able
to use the controls on the simulator to scroll to your program icon
and use the return key to launch it. It should display the text "Hello
World" on the BlackBerry screen. To exit the program, use your
mouse to click the Escape button on the side, or use the [Esc] key
on your keyboard.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Deploying Your App
 Since we've developed this application using the BlackBerry JDE, deployment
is pretty easy. When you build your application, the development
environment builds the .JAD (Java Application Descriptor) file that is
required to distribute your application, along with the required .COD files.
 The easiest way to distribute these files is to make them available on a Web
server that your BlackBerry users can access. Before you can publish these
files, you'll need to do some configuration on the Web server to make this
happen. On your Web server MIME settings, you'll need to ensure that you
have the following settings:
 .JAD
text/vnd.sun.j2me.ap-descriptor
.COD
application/vnd.rim.cod
 You can then give users a URL that points to the .JAD file. When they browse
this file from their BlackBerry, it will trigger the installation of the program
you've created.
 This is a very simple application example—given that the Blackberry uses
Java, you can develop just about any application that you can imagine.
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
This is what it looks like
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
An Actual Tutorial
 http://blizzard.cs.uwaterloo.ca/eaoliver/blackberry_tutorial.html
 Created by a student in the tetherless computing lab
WatITis | Strengthening Collaboration | December 8, 2009 | Mobile Application Development
References
 http://na.blackberry.com/eng/developers/resources/
 Beginning Blackberry Development, Apress, ISBN 978-14302-7225-0-53999
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Blackberry versus iPhone
 A comment I found to spark the debate:
 And how do they stack up? Frankly, I've concluded it's
time to bury the BlackBerry. A revolution in its time,
thanks to its ability to provide instant, secure e-mail
anywhere, the BlackBerry has become the Lotus Notes of
the mobile world: It's way past its prime.
 Numerous websites on comparisons between the
two devices
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***
Conclusion
 Saw courses on app development are available
 Both blackberry and iPhone
WatITis | Strengthening Collaboration | December 8, 2009 | ***Program Title***