A try on iOS

New experiences in iOS Application development

Objective – C

To get in touch with iOS development I started watching the Stanford University iOS videos. This language and its framework has a very steep learning curve, so at the beginning I didn’t understand much. With the video tutorials and the material from Apple itself I was able to create a ‘Hello World’ Application and then step by step build the HSRMenu Application. This approach allows it to gain more knowledge by time but has a huge drawback. The software design was not created at the beginning, so a lot of refactoring had to be done.

Xcode

To develop native applications for iPhone you need Xcode, the IDE is provided by Apple. The basic features are self-explanatory and similar to other IDEs. One important feature I decided to use is ‘Storyboard’. With this you can design your application user interface and connect parts to your code. It gives you a feeling of how the app should behave and what it will look like. Also you can get an overview of what should be implemented in code.

The Connection

In iOS 5 an above receiving a JSON over HTTP is built right in. Create a NSURL from a NSString and then create a NSURLRequest. To this request you can assign a delegate (in this case the object itself) which should handle all callbacks from the request.

[objc] - (void)initJsonConnection { NSString *urlString = [[NSString alloc] initWithFormat:@"http://florian.bentele.me/HSRMenu/api.php?day=%d", currentday]; NSURL* apiurl = [NSURL URLWithString:urlString]; NSURLRequest* request = [NSURLRequest requestWithURL:apiurl]; (void) [[NSURLConnection alloc] initWithRequest:request delegate:self]; }[/objc]

The callback methodes are the following

[objc]- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)jsondata
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
[/objc]

All this methodes are self-explanatory, for further information about this, please see Apples Reference

The Keychain

In Order to save the username and password to access the HSR Badge API, I decided to solve this problem with Apple’s Keychain for iOS. In this way the password is stored encrypted and other applications can not access it. Apple has a reference implementation of the keychain utilities. In the code you only need to store the username and password:

Store items to keychain

[objc]KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"HSRMenuLogin" accessGroup:nil];
[keychain setObject:pass forKey:CFBridgingRelease(kSecValueData)];
[keychain setObject:user forKey:CFBridgingRelease(kSecAttrAccount)];
[/objc]
(accessGroup is set to nil, so it runs in the iOS simulator)

Read from keychain

[objc]KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"HSRMenuLogin" accessGroup:nil];
uiuser.text = [keychain objectForKey:CFBridgingRelease(kSecAttrAccount)];
uipass.text = [keychain objectForKey:CFBridgingRelease(kSecValueData)];[/objc]

Pull-to-refresh

When the app starts it tries to load new data automatically. If no internet connection is available an error occures. Whenever the user feels to, one can simply pull to refresh the data, this works throughout the application, in singlemenu view, in menu overview and in badge saldo view.

PTR is using a library so it is compatible in iOS 4 and above, Apples implementation is only available for devices with iOS 6 and above.

The library is public available on Github. In this app it is used as demonstrated in the example code.

[objc]- (void)dropViewDidBeginRefreshing:(ODRefreshControl *)refreshControl
{
[self initJsonConnection];
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[refreshControl endRefreshing];
});
}[/objc]

Star Rating

To give the users the ability to rate a menu, I decided to create a star rating view for each menu and provide the average rating to each menu.

I tried different ways and checked out how others have implemented rating but wasn’t happy at all. Finally I came across DLStarRating. A customizable star rating view which fits my needs.

[objc]DLStarRatingControl *ratingControl = [[DLStarRatingControl alloc] initWithFrame:CGRectMake(85, 50, 220, 70) andStars:5 isFractional:NO];[/objc]

And when the user tabs/creates a new rating for a certain menu, the delegate calls the methode:

[objc]-(void)newRating:(DLStarRatingControl *)control :(float)rating {
// calling the rating services here
}[/objc]

Lessons learned

As noted in the intro, starting an iOS project with no experience in Objective-C is quite challenging. Learning the language and the framework while developing a real world application was possible but also time consuming. The architecture grew with each iteration and had to be adjusted over time. * create project overview and design architecture as soon as possible

One other thing I experienced was, that there are many frameworks out there. If you have a specific need, someone probably already has a solution for this. In my example the rating. I developed two different versions until I came across the DLStarRating library. At this point I had to decide which solution I would use, and the library won. * use frameworks and libraries if possible and meaningful

Another thing I would recommend is read a lot. There are a lot of tutorials and a very good documentation available online. Check out other iOS apps to see how others solved a problem. This gives you new ideas and keeps you open minded. * read a lot: tutorials, books and Apple’s developer library