Tuesday, June 22, 2010

Iphone - The user is always right

After some amazing designer time and some scrambling to get all the UI changes in we got to let a bunch of people play with the app on actual devices, the feed back was awesome! As in extremely useful awesome.

Nothing beats first hand feedback!

Here's a few of the fun things we discovered we had to get right:

1. If the app does not respond to user touch as expected by the user, there will be confusion!

One of our views had editable text fields. Tapping a field would bring up the key pad but there was no cursor indicating that the specific text field was selected and typing would allow you to enter a value.

Result: "The app is broken!", "Um its not working?".

The funny thing is that if you had started typing you would see the values being entered, and it would work, but the lack of a prompt from the text field was enough to cause confusion. Needless to say this important issue has been fixed.

2. Very detailed views will be expected to be zoom-able.

Several of our views contain graphs, these occupy about half the full screen size. These graphs contained points and grids and axes so users would automatically try to zoom into them. Unfortunately, we had not yet put this functionality in. Currently this is a to do item on our list, but it is obvious that our users will expect this functionality, and will be disappointed if its not there.

3. Universal hatred for pop-up warnings about invalid entries.

If a user entered an invalid value, we were displaying pop-up warning messages that would tell you the valid range to use. Almost everyone who tried out the app and got a warning message automatically hated the message. Somehow it would create frustration, even when we thought we were being helpful. I guess the pop-up warnings make a user feel like they've done something really wrong and its broken while all they want is for the d#$# thing to work! We have replaced this with the more user friendly way of indicating invalid values, where a tiny red message is displayed under the text field.

4. Saving should succeed even when not all fields are complete.

If in the users mind, the information they are filling doesn't all need to be specified, then saving should work as long as some required fields have values. This allows the user to enter in the information they have in the moment and still continue using the app, and fill the rest later. Not being able to save what they have entered already discourages them from continuing to use the app or even returning to it later. So be very careful about what and how many fields are marked as required fields.

5. Respond to device orientation change.

While users didn't try or expect this with all our views, there did seem to be an expectation for the app to support this on the graph views. They expected the graph to be zoomed in and centered on device orientation change with all other elements not getting screen space. Returning to the original orientation should then return the user to the screen with the smaller graph and the rest of the view elements. Again a to do item which would be cool to have.

Well, now we all know when making other apps of some expectations and behaviors to keep in mind to ensure a wonderful user experience!

Wednesday, June 16, 2010

Iphone - The WOW factor

About a few weeks ago our little project got lucky, and received some designer time! Our design hero put together some screen shots at first, and then sent us the images and specifications that we would need. It was amazing how polished our application started to look as soon as we started to add in the changes! We were completely WOWED with the end result! See for yourself:

Images of Main Screen Before.





Images of Main Screen After.





Now a few discoveries about adding background images, specifying table and cell backgrounds, separators and text formatting.

1. Image as background

You can use an image as the background for a UIView by adding the following code in the view controller's viewDidLoad:

self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"imgname.png"]];

colorWithPatternImage is a really powerful method and can be used to set images as colors for tables, cells, labels etc.

2. Specify a color not available in the interface builder

The interface builder comes with a small selection of colors (you can add more libraries though), if you don't find the color you want, you can specify any color pro-grammatically using the UIColor class. The following example uses the color #DB3F61, and calls colorWithRed, which takes in the Red, Green, Blue and alpha values. The RGB values for #DB3F61 are RGB(219,63,97), each value is divided by 255 in order to use colorWithRed:

[UIColor colorWithRed:219.0f/255.0f green:63.0f/255.0f blue:97.0f/255.0f alpha:1.0f];

You can assign this UIColor to backgrounds, and separators etc. In the following code I've applied it to the separator line defined for tables.

self.table.separatorColor = [UIColor colorWithRed:219.0f/255.0f green:63.0f/255.0f blue:97.0f/255.0f alpha:1.0f];

3. Programmatic formatting of text

If you are creating textual elements on the fly and need the text to be formatted like the rest of the application, you can do it! Below is the example of a label, with text color, shadow size and font specified. Notice that the background color for the label is set to clearColor, this is a predefined color in the UIColor class. The shadow of the text is set to whiteColor. Other defined colors are red, orange, brown etc. The color of the label text is set to color #663300 (RGB(102,51,0)), using the colorWithRed method.

CGRect frame = CGRectMake(0, 0, 400, 44);
UILabel *label = [[[UILabel alloc] initWithFrame:frame] autorelease];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:20.0];
label.text = @"This is a label";
label.shadowColor = [UIColor whiteColor];
label.textAlignment = UITextAlignmentCenter;
label.shadowOffset = CGSizeMake(0,1);
label.textColor = [UIColor colorWithRed:102.0f/255.0f green:51.0f/255.0f blue:0.0f/255.0f alpha:1.0f];

4. Grouped tables, selected row issue

When using a UITableView, and setting the style to Grouped. You'll notice that when the top or bottom cell is selected, the grey or blue is outside of the rounded corners. Also the separators disappear for any selected cell. The workaround
for this issue is to always set the cell's background color for selected and unselected. In the view controller make sure you have a reference to the cell and in the viewDidLoad add the following code:

self.myCell.backgroundColor = [UIColor colorWithRed:219.0f/255.0f green:63.0f/255.0f blue:97.0f/255.0f alpha:1.0f];

This will set the cell's regular color. Now for selected cell color use the table's didSelectRowAtIndexPath, and for the selected row set the cell's background to a different color using the same code as above. Remember to set all the other cells back to regular cell color, and for each cell in the interface builder set the Selection property to none.

Monday, May 31, 2010

Iphone - View Controllers

View controllers are one of the most fundamental building blocks of Iphone applications. How you implement the view controllers in you application determines how information is displayed to the user over multiple screens, or even within the limited space of one screen. They allow you to manage the showing and hiding of information within one screen as well as switching back and forth between screens. This article is a general overview of view controllers and has special focus on the Navigation View Controller.

There are three types of view controllers:
- Custom View Controller
- Container View Controller
- Modal View Controller

Custom View Controllers are controller objects that manage the content of one screen. Most applications will have several screens that display different information, each of these can have its own view controller that manages the presentation of data for that particular screen only.

A Container View Controller on the other hand controls other View Controllers. These are used to define navigation between several different views. A Navigation View Controller and Tab Bar View Controller are examples of Container View Controllers.

The diagram below shows an example interface with three different views that the user can navigate back and forth between, as well as a portion of the screen being used to navigate between four other views.
There are several ways the diagram's flow could be achieved in an application. Lets say we decide to go down the following scenario:

  • Each of the 7 views gets its own custom view controller.
  • Implement a main navigation controller using UINavigationController class provided by the system. This allows us to go back and forth between the three main views.
  • For the four views, that only change a potion of the screen, we have two different options: Implement a UITabBar class in the central view, that switches between the four views or display the Toolbar that is defined within the UINavigationController class. Note that we cannot use the UITabBarController class at this point since the programming guideline prohibits incorporating a UITabBarController into a UINavigationController. However, the guideline does allow having a UINavigationController within a UITabBarController.
The UINavigationViewController is an amazing class that maintains track of a navigation stack. It contains several views that help define a navigation interface: Navigation Bar, Navigation View, Custom Content and the hidden by default Navigation Toolbar. The content of the Navigation bar and Toolbar can be customized however these views do not change. The only view that changes is the Custom Content view. This view always shows the view of the view controller that is at the top of the navigation stack.

The Navigation Bar already has a default back button defined, which displays the name of the previous view's title. If the previous view has no title then the button displays "back" by default. The behavior for this button is already defined and clicking it changes the view to the previous view. Very convenient. Sadly, if the previous view had a title the button says the title of the page and you cannot simply change the text to say "back" or any other custom text. You actually have to define a custom UIBarButtonItem and assign it to the leftBarButtonItem property of the Navigation Bar. This also means that you have to define the behavior of the button as well. The middle of the Navigation Bar generally displays the view title. You can specify a custom title by setting the titleView Property of the Navigation Bar. The right side of the Navigation Bar by default displays nothing unless the rightBarButtonItem property has been set to a custom UIBarButtonItem. The rightBarButtonItem property is often used to specify a next button or a cancel button, all you have to do is put the next view on top of the navigation stack for the controller to know which view to load.

For navigating between the four sub views we used the UITabBar class. The UITabBar class allows you to define two or more tab items, clicking on which changes the selected view. The issue to note here is that placing a view within a view required a lot of fine tuning sizing wise. Even if the views properties for auto sizing are set they didn't always render correctly within each other and we had to specify size in code. Even though we were successful with this avenue, in the end it was easier and cleaner to repeat in each of the four sub views the content of the central view that was common to them and switch the whole of the central with one of these four when a Tab Bar Item was clicked.

I hope you found this introduction / summary helpful. Choosing the path that best suits your application is very important and can have many challenges: unavailable options, rules and regulations, time for fine tuning etc. This is a decision that could determine how much re-work or re-design you may have to do later on in the project.

References and recommended reading:

Thursday, May 20, 2010

Supporting navigation with the trackball

Let's talk about using the trackball in android applications.

First of all I was surprised when noticed that focus (orange background) is not visible on ListView's items. During testing application I noticed that ListView items gets focus in reality, because if we click with the trackball on item appropriate event would be handled. However, we can't see focus that is why I started investigation. Finally it was found out that it is because of background
of ListView's items. If we need to see focus we must have background color's alpha parameter 0(ex. Color.argb(0,255,255,255), hex colors). But in that case we wouldn't have real colors(colors would be darker, ex. white would be gray). That is why we have to remove background color and use default black background. And also I want to mention another limitation of ListView. It's not possible to define items which must be focusable, because ListView is doing that itself.

The second thing that shocked me was that we can't see focus on ImageView item. In our "Edit Profile" page we have a lot of elements and have a method to define sequence of focused items. The focus works correctly for all elements, but ImageView is an exception. Investigation shows that it is a known issue that is why I have to put ImageView in another view, implement selector for that view and give orange background to it when it is focused.

Third I want to speak about behavior of the trackball under tabs. Let's go through an example.We have one activity which is responsible for drawing TabHost. Under each tab we have another activity. We need to be able to reach and interact with all items on all tabs using just the trackball. With our implementation it means that we have to navigate through items in different activities which, in my point of view, is not possible.That is why for now with the trackball we can only move slider and go from one tab to another.For example we need to set a focus on tab. As soon as activity under tab is loaded focus automatically will go to appropriate element under tab.That is why if we need to navigate through tabs we must first of all go up with the trackball then change tab.

That's all for now about strange behavior of focus when using the trackball.

Monday, May 10, 2010

Managing Experimentation - Part 2

As a follow up to my first post about managing experimentation I would like to cover an interesting aspect of this project: progression tracking.

There are several ways to track progression, some subjectives and some objectives. The most pleasing one to me is a subjective one about having "working software" this is not part of the agile manifesto for nothing, in delivering quality software you need to focus on having working software at all time and sooner than later. In the case of the IPhone implementation we did have working software very early on, it was not doing much but it was working and we could see new code coming in daily. This is an important proof that the project is moving on and it makes it easy to observe if a team is heading in the right direction or not.

Another interesting objective aspect I have been watching for is new tasks creation. While this is a matter of worry (from an estimation and profitability stand point) it is a very positive sign that the team has taken ownership of their project. By constantly creating new tasks a team is showing that they are in control of the workload of the project and that they are taking actions towards ensuring that there are no loose ends.

See for yourself:



The red line is showing tasks creation while the green is showing tasks resolutions.

As you can clearly see the team has been creating as many tasks as they have been resolving since the initial task creation initiative. And this pretty much from day one. This is very positive.

Last but not least, from an objective stand point is the rate of code submission to the repository. Actually... to the code review board. Macadamian has been performing code reviews since its birth day, in doing so it is easy to track at what pace the code come in.

I have not looked at the evolution of the #KLOC but I can confirm that the team has submitted about a patch a day. While this is a little low for a team of 4, since many of us on this team were new to the IPhone programming environment this seems to be a quite decent rate.

Friday, May 7, 2010

Chart Control for Windows Phone 7

The experiences that we've gone through on Windows Phone 7 so far have been very astonishing. Loads of controls are absent from .NET Compact. You have to find a workaround for anything that's not there. This makes life bitter.
Here are a few limitations to outline. They are not encompassed with something general, just a list of what I faced so far:
  • no local database support (as already mentioned in this and this blogs)
  • no TabControl, no DatePicker (the complete list can be found on msdn)
  • no IComparer (the common IComparer is supported, but for templates it's not)
  • in usual WPF there is Button.Children, but here we don't have it
  • no ChartControl (about them we've talked on those two pages)
OK, enough of disappointments now. Here is the good part. Macadamian developed a Chart Control which you can pick up for free. The chart looks like the one in the screenshot below.


Don't pay specific attention to that outrageous pile of letters called "Parandzem". That's an Armenian name (by the way that's a female name) that I left to appear on the phone. The rest are the "Baby Weight Tracker" application left-offs, and the chart of course.

You can download the dll of the chart here.

In the coming days another control will be available to fetch - DatePicker. Stay tuned!




Thursday, April 29, 2010

New Windows Phone Developer Tools?

The news told me that a new release of Windows Phone Developer Tools has been released recently. To not copy all the lines down here of what's new in this release, here is the short and simple page to see it.
It's always nice to move on with newer stuff, isn't it? At least it is for me, so I immediately downloaded the installer from here to see what's in there. And.... boom! The screen that I get tells me it's time to go to bed:


Requires removing all my environment to proceed. Disappointment!
So I decided I should wait until I can update the tools on my machine and not install them from scratch. All in all we're busy people and uninstalling and reinstalling a whole bunch of environment (furthermore if that's going to happen once a month) does not sound very attractive.

Tuesday, April 27, 2010

Calculation of percentile and projecting


Hi everyone. I'm going to post about how to calculate percentiles for infants and how to calculate projecting.

Percentile Data Files with LMS Values. How to calculate measurement, z-score and percentile

Data used to produce the United States Growth Charts smoothed percentile curves are contained in 3 Excel data files representing the 3 different growth curves for infants (weight-for-age, length-for-age, head circumference-for-age). The file and corresponding chart names are below. These data remain unchanged from the initial release on May 30, 2000 of the growth charts.
  1. WTAGEINF [XLS - 34 KB]
    Weight-for-age charts, birth to 36 months, LMS parameters and selected smoothed weight percentiles in kilograms, by sex and age

  2. LENAGEINF [XLS - 67 KB]
    Length-for-age charts, birth to 36 months, LMS parameters and selected smoothed recumbent length percentiles in centimeters, by sex and age

    Errata: The selected percentile values for length for age have been updated to correspond exactly to the published LMS values. The 50th percentile values have not changed and the outer percentiles differ only at or beyond the second decimal place. There is no visibly perceptible difference in the graphs of the growth curves compared to those published in 2000. Thus, no changes to printed graphical growth charts are needed.
    percentiles in kilograms, by sex and recumbent length (in centimeters)

  3. HCAGEINF [XLS - 34 KB]
    Head circumference-for-age charts, birth to 36 months, LMS parameters and selected smoothed head circumference percentiles in centimeters, by sex and age

These files contain the L, M and S parameters needed to generate exact percentiles and z-scores along with the percentile values for the 3rd, 5th, 10th, 25th, 50th, 75th, 90th, 95th and 97th percentiles by sex (1=male; 2=female) and single month of age. Age is listed at the half month point for the entire month; for example, 1.5 months represents 1.0-1.99 months or 1.0 month up to but not including 2.0 months of age.

The LMS parameters are the median (M), the generalized coefficient of variation (S) and the power in the Box-Cox transformation (L). To obtain the value (X) of a given physical measurement at a particular z-score, use the following equation:
X = M (1 + LSZ)**(1/L),  L != 0

or

X = M exp(SZ), L == 0

** indicates an exponent, such that M(1+LSZ)**(1/L) means raising (1+LSZ) to the (1/L)th power and then multiplying the M; exp(X) is the exponentiation function, e to the power X. Z is the z-score that corresponds to the percentile. Z-scores correspond exactly to percentiles, e.g., z-scores of -1.881, -1.645, -1.282, -0.674, 0, 0.674, 1.036, 1.282, 1.645 and 1.881 correspond to the 3rd, 5th, 10th, 25th, 50th, 75th, 85th, 90th, 95th and 97th percentiles, respectively.

For example, to obtain the 5th percentile of weight-for-age for a 9-month-old male, we would look up the L, M and S values from the WTAGEINF table, which are L=-0.1600954, M=9.476500305, and S=0.11218624. For the 5th percentile, we would use Z=-1.645. Using the equation above, we calculate that the 5th percentile is 7.90 kg.

To obtain the z-score (Z) for a given measurement (X), use the following equation:
((X/M)**L) - 1
Z = ------------------, L != 0
LS

or

Z = ln(X/M)/S, L == 0

where X is the physical measurement (e.g. weight, length or head circumference) and L, M and S are the values from the appropriate table corresponding to the age in months of the child (or length/stature). (X/M)**L means raising the quantity (X/M) to the Lth power.

For example, to obtain the weight-for-age z-score of a 9-month-old male who weighs 9.7 kg, we would look up the L, M and S values from the WTAGEINF table, which are L=-0.1600954, M=9.476500305, and S=0.11218624. Using the equation above, we calculate that the z-score for this child is 0.207. This z-score corresponds to the 58th percentile.

Alex and I found a class which has methods to calculate cumulative distribution and inverse cumulative distribution. Now we are using that class in the Android application. It has 2 simple methods which uses only log, sqrt and exp functions to calculate percentile and z-score, so it can be used in iPhone and Windows Phone 7 as well.

Below is the java code for that class.

/**
* This class contains routines to calculate the normal cumulative distribution function (CDF) and its inverse.
*/

public class CDFNormal {

    /**
     * This method calculates the normal cdf inverse function.
     *
     *@param percentile
     *            p must lie between 0 and 1. inverseCumulativeProbability returns the normal cdf inverse evaluated at
     *            percentile.
     */

    public static double inverseCumulativeProbability(double percentile) {
        if (percentile < 0 || percentile > 1) {
            throw new IllegalArgumentException("p should lie in [0, 1]");
        }
        double arg, t, t2, t3, xnum, xden, qinvp, pc;

        final double[] c = { 2.515517, .802853, .010328 };

        final double[] d = { 1.432788, .189269, .001308 };

        if (percentile <= 0.5) {
            arg = -2.0 * Math.log(percentile);
            t = Math.sqrt(arg);
            t2 = t * t;
            t3 = t2 * t;

            xnum = c[0] + c[1] * t + c[2] * t2;
            xden = 1.0 + d[0] * t + d[1] * t2 + d[2] * t3;
            qinvp = t - xnum / xden;

            return -qinvp;
        } else {
            pc = 1.0 - percentile;
            arg = -2.0 * Math.log(pc);
            t = Math.sqrt(arg);
            t2 = t * t;
            t3 = t2 * t;

            xnum = c[0] + c[1] * t + c[2] * t2;
            xden = 1.0 + d[0] * t + d[1] * t2 + d[2] * t3;

            return t - xnum / xden;
        }
    }


    /**
     * This method calculates the normal cumulative distribution function.
     * <p>
     * It is based upon algorithm 5666 for the error function, from:
     * </p>
     *
     * <pre>
     *       Hart, J.F. et al, 'Computer Approximations', Wiley 1968
     * </pre>
     *
     * @param zScore
     *            The method returns the value of the normal cumulative distribution function at zScore.
     */

    public static double cumulativeProbability(double zScore) {
        double zabs;
        double p;
        double expntl, pdf;

        final double p0 = 220.2068679123761;
        final double p1 = 221.2135961699311;
        final double p2 = 112.0792914978709;
        final double p3 = 33.91286607838300;
        final double p4 = 6.373962203531650;
        final double p5 = 0.7003830644436881;
        final double p6 = 0.3526249659989109E-1;

        final double q0 = 440.4137358247522;
        final double q1 = 793.8265125199484;
        final double q2 = 637.3336333788311;
        final double q3 = 296.5642487796737;
        final double q4 = 86.78073220294608;
        final double q5 = 16.06417757920695;
        final double q6 = 1.755667163182642;
        final double q7 = 0.8838834764831844E-1;

        final double cutoff = 7.071;
        final double root2pi = 2.506628274631001;

        zabs = Math.abs(zScore);

        // |z| > 37
        if (zScore > 37) {
            return 1;
        }
        if (zScore < -37) {
            return 0;
        }

        // |z| <= 37.
        expntl = Math.exp(-0.5 * zabs * zabs);
        pdf = expntl / root2pi;

        // |z| < cutoff = 10/sqrt(2).
        if (zabs < cutoff) {
            p = expntl * ((((((p6 * zabs + p5) * zabs + p4) * zabs + p3) * zabs + p2) * zabs + p1) * zabs + p0) / (((((((q7 * zabs + q6) * zabs + q5) * zabs + q4) * zabs + q3) * zabs + q2) * zabs + q1) * zabs + q0);
        } else {
            p = pdf / (zabs + 1.0 / (zabs + 2.0 / (zabs + 3.0 / (zabs + 4.0 / (zabs + 0.65)))));
        }

        return (zScore < 0 ? p : 1 - p);
    }
}

How to calculate projecting

In the Android application we are using the following scheme to calculate the projecting:
  • Get percentiles for last measurements (if there is no, use 55)

  • If 1 < percentile < 99, calculate projecting using this percentile

  • There might be problems when percentile < 1 or percentile > 99, so we calculate measurement using 1 or 99 percentile respectively, and then add/subtract necessary value.

For example, if baby's weight is 12kg which percentile is great than 99 and measurement for 99 percentile is 10 we calculate the measurement using 99 percentile (e.g. measurement = 15kg) and then add 20% to it (15kg + 20% = 18kg).

Saturday, April 24, 2010

Managing Experimentation

At Macadamian we are very good at managing expectations. While the expectations in the context of this project are very clear from a deliverable stand point, they are not so clear from a project management stand point.

Well... they are clear in a way since we do not treat that project any differently than any customer projects but since this project is internal it carries some "attributes" we do not always have the freedom to play with... for example:

Innovation & Creativity
We are not always sought for our innovations abilities. Sad reality. This is not the case here, let's innovate and be creative!

Experimentation
For obvious reasons, a service company continuously works at mitigating risks. In this case we allow ourselves some freedom and expect experimentation to take place.

Agilefullness
While most projects we work on are leveraging one form or another of the Agile methodologies (to varying extent) this project is fully agile - at least for the iPhone flavor in which I am participating. As a matter of fact, I am only taking part to the scrums and the team has been beautifully self managing itself. Kudos to you guys!

In retrospective, these are common themes in a product company. A product company must innovate and be creative, it is doing so via experimentation and it expects its people to take ownership and highly collaborate.

The message from me at this point from a product management stand point is this: get your team engaged in the project give them ownership and empower them to take the right decision. Doing so you might very well be giving them the ingredients required for success.

Next week I intend to provide some progression metrics.

Stay tuned!

Friday, April 23, 2010

Creating web-based iPhone applications (Part I)



First off, this is my first blog post here so I wanted to say 'hi' to everyone. I look forward to working with you all.

This is the first part of what I hope to turn into a three part series about creating web-based iPhone applications. In this part, I'll show how to set up jQTouch and create a very basic webpage that looks and behaves like a native iPhone application.

Much of my experience, at least at developing GUI applications, is on the web. While I'd never developed native iPhone applications before starting at Macadamian, I did toy around with creating an iPhone front-end to a web application. It turns out you can go a long way with this approach, and I think it may be useful on this project for mockups.

The first software I want to introduce is jQTouch, an extension to the jQuery library which adds CSS and Javascript to make webpages that behave like native iPhone applications. It's pretty fancy. Let's get started.

First, download jQTouch from here and extract it somewhere a web server can find it. Then, create an "index.html" in that directory, and put this in it:


<!DOCTYPE html>
<html>
<head>
<title>jQTouch test page</title>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript"> google.load("jquery", "1.3.2"); </script>
<script src="jqtouch/jqtouch.min.js" type="application/x-javascript" charset="utf-8"></script>
<style type="text/css" media="screen">@import "jqtouch/jqtouch.min.css";</style>
<style type="text/css" media="screen">@import "themes/apple/theme.min.css";</style>

<script type="text/javascript">
var jQT = new $.jQTouch({
icon: 'jqtouch.png',
statusBar: 'black-translucent',
preloadImages: [
'themes/apple/img/backButton.png',
'themes/apple/img/toolButton.png',
'themes/apple/img/toolbar.png',
'themes/apple/img/pinstripes.png',
]
});
</script>
</head>

<body class="fullscreen">
<div id="home">
<div class="toolbar">
<h1>Page 1</h1>
</div>

<ul>
<li>
<a href="#world">Hello</a>
</li>
</ul>
</div>

<div id="world">
<div class="toolbar">
<h1>Page 2</h1>
</div>

<ul>
<li>
<a href="#home">World</a>
</li>
</ul>
</div>
</body>
</html>

Everything in the head tag is boilerplate that loads jQuery from Google's JSAPI servers, then loads the CSS and Javascript for jQTouch and the "Apple" theme. It also initializes jQTouch and preloads some images so they are displayed immediately.

(Notice the doctype at the top: that's means it's an HTML5 page. That'll become important in the next part. We're living in the future.)

The important parts are the top-level div tags in the body. Each one is a screen. When the page is loaded, the first one is displayed. jQTouch adds some magic to handle clicks on links to anchors in the page, so that linking to anchors will change to a screen with that ID. For example, linking to "#foobar" displays the div with id="foobar". That way, the entire UI is in one HTML file and there is no load time to change screens.

If you load up this page in your web browser, you should see something like this:
It looks a little strange with the black bar at the bottom on a desktop browser (like Chrome here), because it's sized for an iPhone screen. Clicking on the "Hello" will change to another page with a "World" button. Clicking the "World" button returns you to the first page. In Webkit browsers like Safari (or Mobile Safari, like on an iPhone or iPod Touch) it will also have a sliding transition.

In Mobile Safari you can also click the "+" in the bottom toolbar to add it to the home screen. In addition to making it easier to get back to later, this gets rid of the Safari chrome.

That's the end of Part I. I've just scratched the surface of what jQTouch can do, but I hope it gives you a feel for what it can do. In the next part, I'll show how to make forms to take input from the user, how to application accessible even with no internet connection, and how to store data offline on the device.

Tuesday, April 20, 2010

Custom Cells for Iphone Table View

Lets say you've added a nice new View XIB file, and thrown on a UITableView using the Interface Builder's Library tool.
And now you want to create a custom cell, how do you go about it? After scouring through several blogs and sites I couldn't quite figure out how to create just a custom cell:

I always ended up adding a new View XIB file, grabbing the UITableViewCell from the Interface Builder Library, dropping it in and getting this:

That's one massive cell and not very useful. So, this is how you really do it and its so simple you'll wonder why you didn't immediately get it yourself.
1. Add a new View XIB file, lets call it CustomCell.
2. In the Interface Builder in the window titled CustomCell.xib notice that by default a UIView has been added.
3. Select the UIView that was added by default and hit delete.
4. Now grab UITableViewCell from the Library and drop it into the CustomCell.xib window,
just like you would in the View Window.

5. Voila! You now have just a UITableViewCell and can customize it as you please.

Jake's blog post about SubViews and Table Views and the following reference cover how to implement the code to populate and handle these custom cells:
http://www.e-string.com/content/custom-uitableviewcells-interface-builder

Monday, April 19, 2010

Drawing charts in the Windows Phone 7 using Silverlight's graphical API, part 2

Besides drawing chart graphs, axes and grid lines we may need to show several values of X and Y coordinates and descriptions for the concrete charts - legends. It means that in general we must be able to draw text. In Silverlight there are neither DrawText nor DrawString methods which are familiar to Net developers. Instead we must create TextBlock element, set its Text property and place the element on the needed position.

A few words about elements positioning in Silverlight. XAML includes the concept of attached properties – properties that may apply to several elements but are defined in a different class. In Silverlight attached properties are frequently used to control layout. Different layout containers have different properties to control position of the element within them. For example if we place an element in a Grid we need to choose the cell in the grid, but when we place an element in a Canvas we must set Top and Left properties. Attached properties can be assigned both in XAML and in the code. In XAML the syntax is the following: AttachedPropertyProvider.PropertyName. For example:

<Canvas>
<TextBlock name ="tbTitle" Canvas.Left = "20"
Canvas.Top = "45"></TextBlock>
</Canvas>.

In the code it is not possible to use the syntax of ordinary properties for attached properties. If we want to work with an attached property's value in the code its owner type (obviously not the type on which this property applies, like elements) must implement accessor methods in the form GetPropertyName and SetPropertyName. Continuing our example we shall write:

Canvas.SetLeft(tbTitle, 20);
Canvas.SetTop(tbTitle, 45);


And finally, there are two more properties of the TextBlock element which can affect the position of a Text - Margin and Padding.
The Margin is the space between the TextBlock and adjacent object(s), which may be also a container. The Padding is the space between the text itself and the outer edges of the TextBlock. The type of the both properties is Thickness structure which have Left, Top, Right and Bottom members. In XAML, we can specify Thickness values in several ways. If you specify four Double values, these represent the Left, Top, Right and Bottom sides, respectively, of the bounding rectangle. if you specify two values, these represent the Left, Top values, and also applies the same values to Right and Bottom such that the resulting Thickness is isometric horizontally and isometric vertically. You can also supply a single value, which applies a uniform value to all four sides of the bounding rectangle. Note that although a format that specifies three values does not cause a parser error, the first value is used for both the left and right value, and any third value is ignored.
Values assigned from code do not have any behavior that can extrapolate values. If you set the value for Left, you do not automatically establish the same value for Right. All Thickness properties must be set discretely in code, although the Thickness(Double) constructor provides a way to set an initial uniform value.

Graphing Challenges for Android


Hello Everyone, here I’ll be blogging about using Google Image
Charts in Android phone. Let’s get acquainted with Google Image 
Charts. The Google Chart API lets you dynamically generate 
charts with a URL string. You can embed these charts on your 
WebView or download the image for local or offline use. It
returns a PNG image of a chart in response to a URL GET or
POST request.There are a lot of types of charts and you can
specify its size,colors,labels and other properties. Let’s 
create a simple chart.

1.Decide on a chart type.
  Chart type is specified by the "cht" parameter.

2.Choose a data format and decide whether your data must be
  scaled to fit your chart.
  Data is specified using the "chd" parameter

3.Specify the chart size.
  Chart size is specified using the "chs" parameter.

4.Add additional parameters.
  You can find some of possible parameters below.

  chxr  -  specifies the range of values that appear on 
           each axis independently
  chds  -  specifies parameters to scale the numeric
           value displayed
  chg   -  specifies solid or dotted grid lines
  chco  -  specifies the colors of a specific series
  chf   -  specifies fill colors and styles for the 
           chart data are and/or the whole chart
           background
  chxl  -  specifies string axis labels on any axis
  chm   –  specfies graphical markers for data points
           on a chart

5.Build your URL String.
  The URL start with http://chart.apis.google.com/chart?
  and is followed by all required and optional parameters.

6.Use GET or POST to get image.
  URL-s  are limited to 2k in length, so if you have
  more data you should consider using POST.

Friday, April 16, 2010

Using Subviews and Table Views in the IPhone

Coming from C# and ASP.Net I've always made UI's easier by taking big complex UI's and breaking them down into manageable, often reusable, chunks. You have some tab on your app that you suddenly want to turn into a dialog? Sure, np: Drag, Drop, Done. You want to add another custom data field editor somewhere? Sure, np: Drag, Drop, Done. Wait, what? you want to have 50 custom data field editors on the same page!? I'll have to go and manually rename the fields for each one to make sure they don't cause conflicts, wow, thats going to be horible to debug... or not: Drag, Drop, Done.

This pattern has worked very well for me in the past. Yes you spend a bit of extra time up front, but I've found you always get it back when you have to make changes, or do maintence.

Enter Xcode. My first week's expirence has shown me that "Drag, Drop, Done" and XCode don't mix. Doesn't mean it's not doable, just takes a bit more more effort, and we can't do it all in one step from the Interface Builder.

Step 1 - Divide and Conquer
This step is common regardless of what language or platform you're aiming for. Take your UI mockups (you do have mockups, right?) and group the controls. As a general rule of thumb group items to minimize the cost of adding things later. it usually works out as group first by common purpose, then by proximity, but there may be exceptions. Lets suppose we have a dialog that lets the user select a few specific files and perform an action on them. We can group the controls pertaining to a single file, and then drop a control for each instance of files we need to have in our dialog. We could also have grouped the controls by function, all the buttons, all the labels, etc, but that wouldn't have helped us because we'd still need to edit multiple places to add an extra control later or do maintence.

Step 2 - Create the Xib File and Controller for our custom controller
In the project, add a new file. UI Controller (with Xib). Use the interface builder to make the control look the way we want it. Edit the controller files to give the control specific behavior like we would normally.

Step 3 - Adding Placeholders for our custom control
In Xcode open the interface (.h file) and implementatio (.m file) for the controller for the window/view that will be holding our custom control. We need to manually add a field to reference our custom control's placeholder.

.h file
{
//Add our private fields
MyCustomControl* customControllController;
IBOutlet UIView* CustomControlPlaceHolder;
}
//Add public properties
@property UIView* CustomControlPlaceHolder;

.m file
@synthesize CustomControlPlaceHolder;

Now open the xib file for the window/view that will be holding our custom control in the Interface Builder. From the library window, drag a new View over and adjust size to fit. This blank view is a placeholder that will get replaced at run time with our custom control. Right click on the controller/File's Owner icon and create a link from the placeholder field we created in the controller and the view object we added in the interface builder.


Step 4 - Write code to load our custom control at run time
The code to actually load the control can be done in the AppDelegate (if its a top level control) or can be implemented in the parents controller function, AwakeFromNib, to do it when the parent view is being loaded.
customControlController = [[MyCustomControl alloc] initWithNibName:"MyCustomControl" bundle:nil]
[ParentViewControl.CustomControlPlaceHolder addSubView:customControlController.view];
make sure to release the custom control when the app exits to prevent memory leaks
[customControlController release]

You may be tempted to use autorelease here, but I'd recommend avoiding it. We're creating our view inside an event, and events maintain their own autorelease pools. If you autorelease your view, you may encounter weird errors later on.

Custom Table Views
For tables the process is the same, except that we need more code to handle the table specific parts, and the code for loading the nib files is slightly different. Also instead of dragging a View to our custom control, we'll want to drag a table cell view to our custom control and you should explicitly give it an identifier in the inspector.
Here are the two function you _must_ implement in order to get basic tables working. The names are specific and cant be changed.
//this is where we load our cell's view
- (UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:NSIndexPath*) path
{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"MyCustomTableCell"];
if (cell == nil)
{
MyCustomTableCellController* newCell = [MyCustomTableCellController alloc];
[[NSBundle mainBundle] loadNibNamed:"MyCustomTableCell" owner:newCell options:nil];
//Figure out how to release this later, can't use autorelease
cell = newCell.customCellPlaceHolder;
}
return cell;
}

//return the number of rows to display
- (NSInteger) tableView:(UITableView*) tableView numberOfRowsInSection:(NSInteger) section
{return 42;}


You will probably find you'll want more control. Check out UITableViewDataSource Protocol and
UITableViewDelegate Protocol for a list of optional functions you can implement to have more control over the table

Tada
Ok so it's not done, but it works! Yay.

What's Next?
Next I have to figure out how to load the specific data inside my table cells. I'm thinking I'll look for a function that gets called when a cell is created/dequeued similar to how AwakeFromNib is called when a control is loaded and use that to switch the display to the model indicated by the NSIndexPath... Another thing I have to figure out is how to merge the table with my actual data so that I can do that :)

Viewing your control at design time
Unfortunetly I haven't found an easy way to "view" our control at design time. If you _need_ this functionality try looking into making a custom Interface Builder Plugin, this is beyond my needs though so I won't be covering this anytime soon.

References
  • http://stackoverflow.com/questions/798950/is-the-main-m-really-the-place-where-the-autorelease-pool-of-the-main-run-loop-i
  • http://stackoverflow.com/questions/1264296/iphone-subview-design-uiview-vs-uiviewcontroller
  • http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
  • http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDataSource_Protocol/Reference/Reference.html
  • http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html

Thursday, April 15, 2010

Around the Iphone in 80 days.. or more..

Hello Everyone, I'm Narcis and I'll be blogging about my first iPhone development experience building a Hello World application for the iPhone.  You have to start small.

When I'm starting to learn a new language or framework what gets me pumped up is to see some UI eye candy, real out-of-the-box stuff. And as you might guess with the iPhone there is a lot of this with the UI controls.  My first steps were to drag a button and a textbox from the interface builder and see a message box popped-up with the TexBox's text when the button is pressed.

Code. Build. Run. Wide neophyte eyes on the awesome iPhone emulator - Apples really done a good job here. I clicked the textbox control I just made - sweet keyboard and bang! I cannot escape the keyboard. I clicked the return button like a thousand times and got myself thinking.. wow.. I just got started and there's a major Bug.

.. or was it? As it turns out ..

What you have to do is implement the return button functionality. Which after some thinking it makes sense - this is the first real paradigm shift away from languages like .Net.  First you must set the text input traits attribute: Return Key to Done on the text field in the Inspector (Attributes Tab). When the user taps the Done button, a "did end on exist" event will be generated. At that time you need to tell the text field to give up control so that the keyboard will go away. In order to give up control, you need to add and action method to your controller class.

Example:

- (IBAction) textFieldDoneEditing:(id)sender
{
[sender resignFirstResponder];
}


When the emulator appears click the text field, type something, and then tap the Done button and the keyboard disappears. Alright! But what about the numeric keypad? Where is the Done button on that one? Well, crud! Not all keyboard layouts feature a Done button. So what's the solution for that numeric keypads?

The answer is probably going to surprise you because of its simplicity. You need to create an invisible button that sits behind everything else and does nothing except tell our text fields to yield first responder status when it detects a touch. It's perfectly alright to call resignFirstResponder on a control that is not the first responder. So you can call it on all your view's text fields without having to check which one is the first Responder(if any).

I know this is a but awkward but.. it's that's the way it is. There are probably some other ways to do it (which you are welcome to comment about them) but this how I've seen it on a couple of forums and some books.

My next post will be about some slick animations done on iPhone when you change the view.

Side note: Add the Date Picker Control - even if you don't do anything with it at first - it's just so damn cool.

Wednesday, April 14, 2010

Drawing charts in the Windows Phone 7 using Silverlight's graphical API

There is a set of visualization controls in the Silverlight Control Toolkit 4 and Chart control among them. I looked through the Silverlight’s documentation, Microsoft’s sites, Microsoft’s developers’ blogs, and nowhere it was mentioned whether these controls can be used in windows phone 7 or not. We tried on all computers in the team – it was impossible. We even couldn’t add anyone of these controls to the toolbox. But Silverlight’s graphical API is available for phone applications, it is easy to use it, so I work on creating custom component for charts. The simplest way to draw 2-D graphical content in a Silverlight ui is to use classes, derived from shape abstract class: Line, Polyline, Ellipse, Rectangle, and Polygon. Polyline class is suitable for our task. The more simple Line class just draws a straight line between two points, we can draw axes and gridlines with it. But Polyline combines a collection of points and this is what we need for chart. All these classes are UIElement, so we can place Polyline in any of layout containers and we can define our chart in two ways: using XAML and programmatically. Here is an example of the first approach:

<canvas><polyline stroke="Red" strokethickness="2" points="10,150 30,140 50,160 70,130 90,170 110,120 130,180 150,110 170,190 190,100"></polyline></canvas>

This markup will create chart’s line at design time so we don’t need to run the application with emulator to see the result.

It can be useful in some cases, but we must be able to create charts at run time based on user’s action. In the C# code we can add items to Points collection of the Polyline. We have two options.
The first one is good for cases when we know in advance the number of charts to be shown, so we can create as many Polyline elements as needed at design time:

<canvas><polyline name="ChartLine" stroke="Red" strokethickness="2"></polyline></canvas>

But now we must define names (ChartLine in the example) for them they will be used in the C# code, where we can create chart by adding Point objects to Polyline’s Points collection:

ChartLine.Points.Add(new Point(50, 330));
ChartLine.Points.Add(new Point(100, 270));
ChartLine.Points.Add(new Point(150, 200));
ChartLine.Points.Add(new Point(200, 130));
ChartLine.Points.Add(new Point(250, 110));
ChartLine.Points.Add(new Point(300, 40));

Next option is to create Polyline element at run time, define points as in the previous example and finally add the Polyline object
to the layout container’s Children collection:

Polyline ChartLine = new Polyline();
ChartLine.Stroke = new SolidColorBrush(Colors.Green);
ChartLine.Points.Add(new Point(50, 330));
......................
_Canvas.Children.Add(ChartLine);



Now a bit of information about line's appearance.
In order to draw dashed line we can use StrokeDashArray. It is a collection of Double values that indicate the pattern of dashes and gaps that is used to outline shapes. Here is its usage in XAML and C#:

<polyline stroke="Red" strokethickness="1" strokedasharray="5 2" name="ChartLine" points="10,150 30,140 50,160 70,130 "></polyline>

DoubleCollection DashArray = new DoubleCollection();
DashArray.Add(5);
DashArray.Add(2);
ChartLine.StrokeDashArray = DashArray;





To be continued.

Serialization and IsolatedStorage as a data persistency approach for Windows Phone 7

So, We don't have a local db support. What we can do to accomplish a workaround for that ?
First thing I've thought about was Serialization. We can create our objects, Specify them as Serialized and Save them either in binary format (using BinaryFormatter- to store binary data such images) or XML format (using SoapFormatter).
Looking into Windows Phone Application References, you will see that System.Runtime.Serialization is supported. add that and then import into your code class.
  • See that we can't achieve this approach because we don't have:
    1. BinaryFormatter and SoapFormatter
    2. ISerializable interface
Ok, let's try creating POCOS and saving them using IsolatedStorage.
  • add the reference then import System.Runtime.Serialization
  • Define the POCO, like this
    [DataContract]
    public class MyObject
    {
    [DataMember]
    public int P1 {get; set;}

    [DataMember]
    public MyObject2 O1 {get; set;}
    ...........
    }
  • Remember to define MyObject2 as a POCO again
  • after defining all your POCOS, create a Serializer class and try to Save data using IsolatedStorageFile and IsolatedStorageFileStream).
  • Well, I've created a Test UI and this worked for me, but... again, The Emulator didn't persist the data after reloading it.I'm still not sure what's the reason for that, and seems like WP7 Emulator doesn't have an SD card option like Andriod.
The next thing I'm going to try is the creation of a class library for this code and then trying to incorporate it, Or the use of XML and XML Parsing.

Windows Phone 7 and Local Database Support

In this post I want to talk about the experiment and the effort I've done investigating the support of local database on a Window Phone 7.
  • First of all, I thought about using SQL Server Compact, since this was supported in Windows Phone 6.5. But, I didn't find any way to accomplish that.
  • Researching the web, I've faced the first frustration: Windows Phone 7 Doesn't support Local databases. Microsoft intends to adopt cloud services approach and push everything towards Windows Azure and SQL Azure !
  • Still, I didn't give up and looked and researched if there are any possible approaches.
  • One of the things I've found is the use of csharp-sqlite solution developed by noah.hart.
    http://sviluppomobile.blogspot.com/2010/03/sqlite-for-wp-7-series-proof-of-concept.html
  • I've tried using that, but... The Emulator was not persisting data.I've lost the data after I've started the emulator. The data was persistent only when the emulator was running (we know that we can keep the emulator running, change the code and deploy again and our changes will be reflected to the emulator without restarting it).
  • I'm not sure, if this is reflected again to a real Windows Phone 7 device, since I didn't try that in reality.
  • I did another try. I've tried to use SQLite. You can find it here:
    http://sourceforge.net/projects/sqlite-dotnet2/files/
  • After the installation, try the following:
    Run Visual Studio 2010 Professional
    View the Server Explorer.Create a new database and name the file.
    1. Note: If you run Visual Studio 2010 Express you won't find the Server Explorer there! (Another proof of : "We do not support local db" )
    Create a new project (windows phone application using Silverlight)
    click on the references > Add Reference
    Notice that in the .Net tab you don't have any reference to System.Data (again ?)
    Browse tab > Navigate to SQLite.Net and add System.Data.SQLite.dll from the bin folder
    Check that the new reference is added.
    Now let's try to write some code in MainPage.xaml.cs.
    import both System.Data and System.Data.SQLite.
    now try using SQLiteConnection object.. WOW... It's there... I'm not getting errors.
    Now Build... and you will get this:
    1. Error 1 The type 'System.Data.Common.DbConnection' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
    2. some resources assumed that adding the reference in the CompactFramework folder will fix this. Tried that, but it's still the same.
    3. I've also added the references from GAC (Global Assembly Cache).. Still the same ! :(
    4. Tried the same SQLite reference with a Windows Form Application. Worked !
    Conclusion: I think for now, SQLite is not supported for Windows Phone Applications development.
  • Next thing came to my mind is Serialization, POCOS, IsolatedStorage. Those were mentioned as an alternative approach for local data persistence on WP7. I'll talk about them in the next post.





Windows Phone 7 Developement-Installation and Setup Problems

In this section I want to talk about the difficulties I passed through when I started Windows Phone 7 Development.
  • First, I needed to install Phone development tools as stated on the development site.
    http://developer.windowsphone.com/Default.aspx
  • The tools are located at:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=2338b5d1-79d8-46af-b828-380b0f854203&displaylang=en
  • I faced the first surprise: Those tools are working and running on only Windows 7 Operating System. No Support for XP.My PC's OS was Windows XP.
  • I Decided to create a virtual machine for this purpose. Second note: You Need VM Ware 7. older versions don't support Windows 7.
  • After preparing my VM, I was able to download and install the Developer tools, which included Microsoft Visual Studio 2010 Express (for phone development) + an Emulator.
  • Creating and working with Visual Studio was fine, but...The Emulator refused to work in any way ! It starts loading but hanging after a while and giving an error such: "can't establish a connection" and when you turn it off, you see an error in Visual Studio stating that: "Deployment error on line 0" !
  • At first, I've thought that could be a memory problem, so I've added a new RAM to my pc. but nothing has changed.
  • Then moved to install VM Tools and Visual Studio 2010 full Professional Edition. again, with no hope.
  • I've done a research about this.And, as stated by some people and developers: "The Emulator is not supported on a VM" or "The Emulator is implemented like a VM, so it would be a VM inside a VM and won't work".
  • I've done my last try.I Installed Windows 7 Locally on my PC. But, the Installation didn't complete.My PC was refusing to accept Windows 7, It was a hardware compatibility problem!.
  • Then I Moved the VM to another PC, and here I faced a surprise ! The Emulator was working without any changes. So, the things which were said about the Emulator and The VM working together are not absolutely right !
  • My final advice: Be sure that your MotherBoard, Processor , and Display card are compatible with Windows 7. In that Case your emulator should work locally and on a VM.

IPhone: Graph drawing?

My favorite playthings are drawing on screen and optimizations. So I was the one who did the graph drawing research for the iPhone project.There are several graphing components on the internet available, but all are more generalized than we need.
We don't have GraphKit available on the iPhone, so I think it is the best to work with our own component. It took two days to write the code for it, it's easily used, and it has all the features we need.
As far as I know, there is no curve drawing trough arbitrary points on the iPhone, so one must write his own algorithm for this.

Calculating all points for the curve isn't a good idea, because it consumes lots of processor power, so I've chosen to create segments of lines - more segments, the curve is smoother.
Ok, segments, but how to get new point on the curve to draw these segments?
And here comes the math part - Lagrange Polynomial (you will love this):where N is the number of points we already have.
It's not the best interpolation (best would be natural cubic spline) - we have the start and end points fixed, otherwise the curve ends would fly off fast from the screen with this formula

The drawing itself is based on Quartz2D. If you have the right math formula, the rest is easy. Rock on!

iPhone: Core Data or SQLite3?

I've been studying SQLite access from Objective C in one of these days. As you may know already, there are two native ways to access SQLite database.
Let's see their advantages and drawbacks:
  1. SQLite native commands
    • ANSI C functions to direct access the database
    • dev should write it's own data access module and DAOs
    • SQL scripts can be ported from the Android project
    • queries can be hand optimized
    • have to learn the nitpicks too (for example there may be query timeouts, in this case the request should be resent), mid learning difficulty
    • reinvent the wheel by reimplementing Model and DAOs
    • available on all iPhone OS versions
    • there are 3rd party frameworks available, but they're overkill for a small application
  2. Core Data framework, provided by Apple
    • native Obj C objects, but without direct access to the database, instead it has graphic data designer and it's pretty well optimized
    • has high level managed objects, you can work directly with them when using your data
    • whole database has to be recreated from a scratch
    • fast for small applications, small queries
    • easy to learn
    • available in iPhone OS 3.0 and above
The access modes cannot be mixed.

We have chosen Core Data for our application, because it's all we need, it has steep learning curve.
Which would you choose for your application?

Tuesday, April 13, 2010

Windows Phone 7 Overview

So here we go, Windows Phone 7 and all the appealing environment that comes with it - Windows 7, Visual Studio 2010, .NET Framework 4, Silverlight 4, Expression Blend 4, and what not! Don't think that this is optional and I chose all those, it's just the prerequisites for a Windows Phone 7. I love it.

The Windows Phone Developers can be a good start point for you. Actually, what you have to do for quick development start up is just download the developer tools from Microsoft here and kick it off! This is a little 3MB download file which then brings up over a 200MB of download. Initially I didn't know what this kit includes in all, so I installed Visual Studio 2010 RC, knowing it is required for WP7. But afterward it turned out that the kit brings Visual Studio 2010 Express with it. So now I have two VS2010-s on my machine (conscience won't let me remove either of them).

Now we're all set up to play with Windows Phone 7. What you need to know is that there are lots of fundamental changes compared to previous versions of Windows Mobiles - no local database support, limitations regarding controls (no TabControl for example), only 2 technologies can be used, either Slverlight or XNA (depending on what you're targeting), only C# is supported as a programming language.

So we may say that Windows Phone 7 is a completely new world and a great exposure on behalf of Microsoft.
Whoever disagrees is invited for a nice chess game and a discussion around the board ;) (kidding)

Monday, April 12, 2010

*Something* .... has gone wrong.... somewhere...

2010-04-12 Day 5

As of last week it seemed that I really had the core concepts down so I decided to take my hello world project and minimize it to the smallest working size possible so I could repeat what I'd learned in a non-hello world project. Unfortunetly at some point *something* changed. I know the source code and header files are not modified because I didn't modify them, but the xib and other project files... I'm not sure. Before on friday afternoon the touch handler was working consistently, now the touch handler is failing consistently just like it was before I restarted from scratch the first time. Even deleting the elements, readding and rebinding them does not fix the error. Once the error is there, it stays there.

I recreated my hello world project from scratch -again- and this time took a snapshot of the files while it was working to compare with the broken project. The broken project xib's files seem to be missing some references inside common nodes, also the broken file has multiple copies of the objects. I'm not sure how it happened but I think the Interface Builder got confused somehow while I was using it. Note to self, copy working files often when using Interface Builder.

I've also made another change today, instead of loading the project off the local drive on the mac, I've set up a symbolic link to a network share on my actual computer. This means that I'm no longer forced to try and figure out how to do ridiculously common tasks like comparing two files with stupidly unfriendly new and different mac tools. In order to make this work I had to change the default build directory to a local folder. Right Click on the project in XCode -> getInfo. "Place build products in > Custom Location" (pick any local folder).

-Update-
Just in case anyone is curious, the problems with interface builder happened before I switched to using network shares.