Tuesday 19 March 2013

Improve your skills with github and stackoverflow

     I learned iOS one year ago,  started with one famous iOS book  iOS Programming: The Big Nerd Ranch Guide. For an entire year, I'm from an newbie to one that can develop some easy apps, but I think I encounter a bottleneck, I don't know how to improve my skills about iOS, even I develop another app, almost will copy some old things from Previous project, there's no new skills learned.

Fortunately, I found some ways to improve my skills, it's reading code and reading questions.

1.    Learning from Github

There are many open source projects hosted in the Github,  there is no secret in front of you.
Recently I learned one project QuickDialog,  it's used to help you create the forms with multiple text fields, or with thousands items.
It has one function, that can load the json file, and create the view according to the json file, make me understand how magic about the NSClassFromString.

When you init the root element with the json file,  it would parse the json file to the NSDictionary, and use the valueForKey(), get the value of the key, then use the NSClassFromString to construct the class which you type in the json file.

   "sections": [
                 {   "title":"password form", "footer":"You first use this app, please set your password.",
            "elements": [
                {   "type":"QEntryElement", "title":"Password","placeholder":"Password", "secureTextEntry":true, "bind":"textValue:password","key":"password"},
                {   "type":"QEntryElement", "title":"Confirm Password", "placeholder":"Password", "secureTextEntry":true, "bind":"textValue:confirmedPassword"}
                        ]
        },

when it found the "type" key, it will use  NSClassFromString  to construct the QEntryElement instance put in the root element tree.
these primary code about using the dictionary to constrcu the element.
    QSection *sect = nil;
    if ([obj valueForKey:[NSString stringWithFormat:@"type"]]!=nil){
        sect = [[NSClassFromString([obj valueForKey:[NSString stringWithFormat:@"type"]]) alloc] init];
    } else {
        sect = [[QSection alloc] init];
    }
    [self updateObject:sect withPropertiesFrom:obj];
    [root addSection:sect];
    for (id element in (NSArray *)[obj valueForKey:[NSString stringWithFormat:@"elements"]]){
       [sect addElement:[self buildElementWithObject:element] ];
    }


maybe before you used NSClassFromString to construct the class in the dynamic, but this is also awesome, it make me know the basic knowledge to config something or plug-in something from files.

Another skill (Key-Value Observing) from the project Kal,
In the Kal, there's  the KalLogic class holds the data about selected date and previous month and following month and so on.
It's the core datasource of the KalView which contains multiple subviews, so how it solve problem when view A changed, view B should change  according to view A in the KalView.

It use the Key-Value Observing, the KalView addObserver about the objects changed,  like the KalLogic changed the date, then KalView
Observing these change, then update the some subviews's frame and shown content of subvirew.

[logic addObserver:self forKeyPath:@"selectedMonthNameAndYear" options:NSKeyValueObservingOptionNew context:NULL];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (object == gridView && [keyPath isEqualToString:@"frame"]) {
        CGFloat gridBottom = gridView.top + gridView.height;
        CGRect frame = tableView.frame;
        frame.origin.y = gridBottom;
        frame.size.height = tableView.superview.height - gridBottom;
        tableView.frame = frame;
        shadowView.top = gridBottom;
       
    } else if ([keyPath isEqualToString:@"selectedMonthNameAndYear"]) {
        NSDate * date = [change objectForKey:NSKeyValueChangeNewKey];
        [self.delegate updateYearDate:date];
   }
}

The KalLogic also have something we should learn:
implementing a class method that follows the naming convention keyPathsForValuesAffecting<Key>, where <Key> is the name of the attribute (first letter capitalized) that is dependent on the values.

+ (NSSet *)keyPathsForValuesAffectingSelectedMonthNameAndYear
{
    return [NSSet setWithObjects:@"baseDate", nil];
}

- (NSDate *)selectedMonthNameAndYear;
{
    return self.baseDate;
}


So when the baseDate changed, then the observer for the key path is @"selectedMonthNameAndYear" will be notified, and from the apple document, this methods normally allow you want to be notified when value A or Value B changed, like

+ (NSSet *)keyPathsForValuesAffectingFullName {

    return [NSSet setWithObjects:@"lastName", @"firstName", nil];

}


An application observing the fullName property must be notified when either the firstName or lastName properties change, as they affect the value of the property.

2.    Learning from Stack overflow

The core idea about learning from Stack overflow is answer question and read question,
These are my methods about Learning,
a.    First  you must see the votes about your interesting topic,  you can know something lost in your knowledge,
Like  me I learned  how to migrate to iPhone 5 app,    check the iOS version, one answer is so awesome, has a very nice marco

b.    After read so many question, maybe you want to answer someone, so you can answer the newest or unanswered question now.

Not Only iOS, I think many programming skill could use these two methods(read code and read questions) to improve,  If you have another
Methods, please tell me, I will be very appreciate.