Making Network Calls in iOS

A very common task of any developer is to write a web services class. In this post I will present a very common pattern for organizing and incorporating network calls into iOS apps.

To give a quick overview, we will be creating a singleton web services class. This basically means we will make a new class that stores all the methods for making network requests, and that the same allocation of this class in memory will be accessible across all views in the app. If you want to learn more about this design pattern, look at my other post.

So, lets create this class. In Xcode, create a new objective c file that subclasses from NSObject.

The header file will look like this:


// WebServices.h
// DC_magazine
//
// Created by Andrew Rauh on 6/4/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface WebServices : NSObject

@property (strong, nonatomic) NSMutableArray *blogPosts;
@property (strong, nonatomic) NSMutableArray *titles;
@property (strong, nonatomic) NSMutableDictionary *selectedPost;

- (void) grabDataAndParse;
- (void) buildTitleArray;
+(id) sharedInstance;

And here is the implementation file. (.m)

</pre>
//
// WebServices.m
// DC_magazine
//
// Created by Andrew Rauh on 6/4/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "WebServices.h"

@implementation WebServices
@synthesize blogPosts, titles,selectedPost, ;

+(id)sharedInstance
{
 static id sharedInstance = nil;
 if (sharedInstance == nil) {
 sharedInstance = [[self alloc] init];
 }
 return sharedInstance;
}

-(void)grabDataAndParse
{
 selectedPost = [[NSMutableDictionary alloc]init];
 NSURLRequest *main = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://dcfaithinaction.org/?json=get_recent_posts"]]];

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 dispatch_async(queue, ^{
 NSURLResponse *response = nil;
 NSError *error = nil;

 NSData *data = [NSURLConnection sendSynchronousRequest:main
 returningResponse:&response
 error:&error];
 NSString *json = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
 id parsedObject = nil;
 NSError *parseError = nil;
 if (json != nil && [json isKindOfClass:[NSString class]] && [json length] > 0) {
 parsedObject = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSASCIIStringEncoding]
 options:0
 error:&parseError];
 }
 if ([parsedObject isKindOfClass:[NSDictionary class]]) {
 NSDictionary *parsedDictionary = (NSDictionary *)parsedObject;

 NSArray *posts = [parsedDictionary objectForKey:@"posts"];
 blogPosts =[NSMutableArray arrayWithArray:posts];
 [self buildTitleArray];
 }
 });
}
- (void)buildTitleArray
{
 titles = [[NSMutableArray alloc] init ];

 for (NSDictionary *dict in blogPosts) {
 [titles addObject:[dict objectForKey:@"title"]];
 //NSLog(@"%@", [dict objectForKey:@"title"]);
 }
}

@end
<pre>

In this case, I used NSURLConnection with an asynchronous block to make the actual network call. After you make the call, you get NSData back. You then treat this as a generic objective-c object, and see if it is either a dictionary or an array. Once you figure out what data type the object you got back from the server is, cast it to that type of object and start iterating over its elements, and extract the needed data.

The reason this network call must be made asynchronously is pretty simple. On iOS, there is a main thread, where all of the UI code is run. If we put this networking code on that same thread, then all of the UI on the devices would completely freeze until we got the needed data back from the server.

Advertisements

Large Social Networks are Doing Mobile Wrong.

Yesterday I had the chance to talk to a Twitter iOS engineer. Although this was part of my interview process, there was some time at the end of the call to discuss whatever I wished to. So, I went ahead and asked why they trashed a pretty fantastic iPad optimized version of Twitter to resort to a strange, stretched out iPhone version of Twitter for all iOS devices.

He responded with this:

  1. It was a struggle to maintain two separate implementations of the same app. Obviously Twitter wants to be able to offer the same great features in all of its apps, and it was very hard to consistently ship  the same features for the two different apps.
  2. New users who are less tech savvy were complaining about how confusing different apps were for Twitter.
  3. We want the ability to define what Twitter is more. Before we sort of let people use it for whatever they wanted, and now as new users join who are less familiar with tech, they want to know what they are signing up for .

This sounds very, very similar to the facebook mobile engineers who defended the use of html5 webviews in the iOS app until recently.

This way of thinking is just wrong for mobile.

The iPad and iPhone are different devices. The same applies for android tablets and phones. Tablets are not phones. With the extra screen space, there is an amazing amount of creative potential for developers+designers+product people.

Although it is easier for engineers to not worry about two separate code repos for the different apps, the end product takes a MASSIVE hit. The entire reason the iPad exists is to allow for a great way to interact with data with the large multitouch screen. If you really think that taking an app interface designed for a screen a 3rd or 4th of the size and just stretching it to fit is the best way for you to allow your consumers to interact with your service, then you are flat out wrong.

Yes, I realize this is not as efficient or logical as shipping a moderately nice app for all devices, but larger social networks need to realize that sometimes sacrificing business logic will produce a much better experience for end users and perhaps also result in happier engineers who are allowed to have more creative freedom in their products/products.

 

A few thoughts on school, startups, and life.

This is a post I have been wanting to write for awhile and am now actually putting it into action!

First up, is school worth it? Why not just drop out and move to SF and work?

Well. This is my approach. School can teach you several very, very important lessons. School humbles you. Sometimes the startup culture can make you delusional in terms of how talented you are, your friends are, and how “genius” you really are. On the other hand, school puts you on a playing field with incredibly talented, competitive people. I have never had to work this hard for my classes and grades before. I hate it sometimes, but at the same time it is forcing me to learn to work incredibly hard and intensely focus.

When you get into a class with 500+ other talented, focused CS majors, it is terrifying, and inspiring. These people are all very intelligent, and it is up to you to perform as well and (hopefully) better than them. It is totally up to you. If you slack off, you know that there is going to be a majority of students who dont, and will kick your butt on the next exam. You need to rise to the challenge and realize sometimes things are not just easy and placed in front of you, instead you need to work very hard for them.

Define yourself. Never just be another Engineering, LS&A, or Music student. Stand out. Find your passions and make school work for you. For me, I really want to learn more about CS and the concepts behind it, but at the same time I need to advance my understanding of business, design, and many other¬†disciplines. You¬†shouldn’t¬†necessarily fit the stock template for undergrad computer science engineering, or whatever program you are placed into.

One thing I did not expect coming to college for a technical degree was that I miss my english, literature, history, and other liberal arts classes. Sometimes, something from AP Gov or AP Lit would inspire a train of thought in my head that lead to a cool idea for a side project or app. When you only have technical classes, I personally feel less creative and less enlightened in certain areas. While I do really value getting an amazing amount of technical depth into Computer Science type stuff, I do miss the blend of that science with liberal arts. I think the connection of those two disciplines makes you a better thinker.

So, what do I think of the Startup World?

I love it. But. You can only appreciate the startup culture and world after seeing the real world. The startup culture is not really that realistic at times. Maybe your idea really isn’t that great. Maybe you don’t need 2 million dollars to build an app and pay rent in downtown SF. Maybe you should actually have a business plan before you raise 10 million dollars. I love the freedom to innovate, but if you don’t have the background of critical thinking introduced in school, you can never really take full advantage of the amazing opportunities offered out in the Bay Area. That being said, I plan to do my own startup one day. The “unrealistic” aspects of Silicon Valley are also what allows such cool things to be created.

Thoughts on Life.

Although it may not really seem like that much time, I have learned a ton since starting college. From the small things (like learning that actually cleaning your room, doing laundry, and successfully cooking make you feel better) to much broader things. College teaches you to intensely work and focus. There is something tremendously valuable about learning how to take content and master it.

When you have classes or challenges that seem very difficult, don’t be afraid to attack it. I knew coming into this year one of my EECS classes would be challenging. But, I am determined to do well. This means making it my top priority over everything else.

Again. Define yourself before others define you. Don’t let others tell you what is morally right or wrong, Don’t let others tell you what you should be interested in, or care about. And most importantly, don’t let others define your personality, style, and approach to life. And, if you are not at a point in your life where you feel comfortable defining yourself, then surround yourself with people you consider “better” than yourself in whatever ways you want. You will become like them. Or better.

Thank you, California.

Goodbye California. You were awesome.

Thank you Kleiner Perkins and Path for hosting and teaching me. Nothing can describe how much I have learned from this entire experience.
I met so many awesome people this summer, and was able to hang out with a ton of friends.

Path – You were awesome. I was able to learn about the true value of a building a high quality product. Path provided a window into a culture that sits at the intersection of art (design) and engineering (server + iOS). When these two disciples are mixed correctly and have the right leadership, beautiful things are built. Path is that product. Even though I still like dot syntax for Objective-C…

Kleiner Perkins – The connections you provided for us were simply incredible. All of the various tech talks and events were tons of fun. Thank you so much Andy Chen for this experience. Being able to spend time with tech legends was awesome.

To Randy, Alice, Joao, Aki, and Arash: You guys were a ton of fun. You were all very smart and great to work with. I hope we get a chance to work together soon.

Thanks to everyone at Teens in Tech. I really enjoyed speaking! Hopefully those listening actually enjoyed my rambling.

 

Finally, it was awesome being able to hang out with so many friends from school + online out here.

Goodbye summer.

Now. Sophomore year…

Just a few thoughts from this summer.

So, I finally made it out here for a summer. This summer I had the awesome chance to work for Path, and be a part of the Kleiner Perkins Engineering Fellowship. I learned more about myself than I ever would have expected to. This summer was one of many firsts for me. It was the first time I had ever traveled alone. It was the first time I was fully responsible for myself financially, emotionally, and physically. I loved it. It was my first time living in the heart of city. (It was the first time for many other things as well such as eating octopus and seaweed salad…)

There is no better way to learn your true beliefs, thoughts, and values than to force yourself into a completely new environment surrounded by strange people you have never met. When you have no outside forces acting upon you or telling you what to do. (i.e. family or parents or friends) you have the freedom to make up your own mind. This is an awesome and incredibly powerful thing. You have the freedom to do nothing all day, or you have the freedom  to do something that is amazing and useful.

I used this summer to learn, grow, and learn more about who I am. This happened through exploring the awesome city of San Francisco and California in general, spending time with tons of friends who visited and live out here, and spending time walking and thinking. I have found a deep motivation to be as successful as the people I had a chance to meet this summer, and as a result my relationships with friends, family, and my girlfriend have matured. I have a more developed perspective on the work I do, and education.  I value learning from people who really, really know what they are doing. At the same time, I have learned to not waste time being annoyed or bothered by people who are out to bring you down, or lie about their true beliefs and abilities.

More than anything else, I have learned you have the complete ability to build the kind of life you want to have. Just because you were born into a horrible background, or were raised in certain way should mean nothing. While it may impact your opinions, you are just as influential on life as those who had a privileged background or powerful parents. Build the life you want, and form the relationships and friendships you want. You can make things work they way you want them to with the right effort and focus.

Keep things in perspective. Coming out here has also taught me this. Certain things that may seem really important one day really aren’t. Others, which may seem useless now, are critical later on. I am still figuring out all of these things, but I can say I learned a ton of them and the difference between the two this summer.

I have learned to value “down time.” Having time to just reflect and think is CRITICAL. Without it, you forget how much value things have. You lose sight of valuable friendships, incredible experiences, and huge choices.

How to easily pass data between Views in iOS

When I first started developing for iOS, one huge problem I encountered was how to easily pass and keep data between view controllers without having to save the data to a database of some sort and/or use nsuserdefaults. One way of doing this easily would be using a shared instance of a class that contains the information you want to save.

Here is a link to my github repo of the code: https://github.com/andrewrauh/SharedInstanceDemo

Basically, you add a method called shared instance to your class that will “store” the information. In this case a class called DataStorageController will be used to hold the values entered on the first screen and pass them to the third view we see.

The method we use to do this shared instance is this:


+(id) sharedInstance 
{
    static id sharedInstance = nil;
        if (sharedInstance == nil) {
            sharedInstance = [[self alloc] init];
            }
   return sharedInstance;
}

//and when you allocate a new instance in another view controller do this

DataStorageController *dataClass = [DataStorageController sharedInstance];

Basic Model-View-Controller flow for iOS

So, one important thing to learn in iOS as well as in any language are some core concepts of software design. This would be the model view controller pattern.

In terms of an iOS project, a good way to think of how this could be implemented would be in a calculator application. The model of this project would store the methods that process the number, i.e. a method to add, a method to substract, a method that divides, and a method that multiples, etc.

For the sake of this application, lets assume each of the methods has an input of two doubles and returns a double as well. Essentially, our model will contain all the methods that do any action to the numbers in the calculator.

In our view controller, we will then make an instance of our model class. This will allow us to use all the instance methods we created in our model class in view controller class. Essentially, we want to pass the values from our view into the methods stored in our model.
Here is the header file:

 

//
//  CalculatorModel.h
//  ModelCalculator
//
//  Created by Andrew Rauh on 5/12/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface CalculatorModel : NSObject

- (double) addNumbers: (double) numberToAdd1 :(double) numberToAdd2;

- (double) subNumbers: (double) numberToSubtract1 :(double) numberToSubtract2;

@end

And here is the implementation file. (.m)


//
//  CalculatorModel.m
//  ModelCalculator
//
//  Created by Andrew Rauh on 5/12/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "CalculatorModel.h"

@implementation CalculatorModel

- (double) addNumbers: (double) numberToAdd1 :(double) numberToAdd2
{
    return (numberToAdd1+numberToAdd2);
}

- (double) subNumbers: (double) numberToSubtract1 :(double) numberToSubtract2
{
    return numberToSubtract1-numberToSubtract2;
}

@end

Now, we need to make an instance of this model class in our main view controller. So, do this:




//
//  ViewController.h
//  ModelCalculator
//
//  Created by Andrew Rauh on 5/12/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "CalculatorModel.h"

@interface ViewController : UIViewController {
    
    UIButton *button1;
    CalculatorModel *calculatorModel;
    
}


@property (nonatomic, strong) UIButton *button1;
@property (nonatomic, retain) CalculatorModel *calculatorModel;


@end


And finally, we will actually use and access these methods in our implementation file.

//
//  ViewController.m
//  ModelCalculator
//
//  Created by Andrew Rauh on 5/12/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize button1, calculatorModel;



- (void)viewDidLoad
{
    [super viewDidLoad];
    calculatorModel = [[CalculatorModel alloc] init];
    
    
    
    //Then you could pass in values from your view into the model methods. 
    //in this case I am just passing two arbitrary values into the method to test it. 
    [calculatorModel addNumbers:3.4455 :5.3];
    NSLog(@"%f",[calculatorModel addNumbers:3.4455 :5.3] );
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

I realize this is exceptionally simple, but hopefully it showed the basics of this development pattern for iOS!