söndag 11 september 2011

Quizer video!

Recorded a short video where I demonstrate Quizer:


Quizer Video 1 from Olof Dahlbom on Vimeo.

One week of PHP-Pain

This past week i've been struggling with PHP. I knew even before going into the week that this would mean pain. My PHP skills are extremely limited and I honestly think the language is a pain to work with. The biggest problem for me is the lack of debugging methods in PHP. I love breakpoints and console outputs for debugging, none of the above is possible when you send code from the iPhone to a PHP-script.

What I wanted to do is to send my JSON-Quiz from "Quizer" (The app I'm working on) to the server. And then parse it into the database. After a weeks struggle that is now working. You can create a Quiz from the phone and load a quiz from the server to the phone. What's left now in this process is to debug the app so it won't crash when the request takes longer time then usual (3G networks can be so slow at HTTP-requests.)

The week ended on a double-happy-note when I arrived home this friday and meet my new best friend, MacBook Air:



MacBook Air "13


The computer is wonderful to work with, and it's so thin and light it's amazing.. I only hope the 4gb RAM will be enough for my use.

This is the PHP script for Quizer if anyone wonders how it turned out (I know it's an easy one.. when you know PHP):

//Code on!

måndag 5 september 2011

MacBook Air

Today there is not much programming going on. But I just had to tell you that I've now ordered a REAL mac! For some time now I've been using an old HP NC6400 with Mac OS X Lion installed on it. Yesterday I took the step and ordered a MacBook Air 13"!

This is my current computer:

MacBook Fail 13"




Yesterday I posted a pic on Ludvig.. this made my other friends extremely jealous so here's a pic of them as well!

Agent Eel & Android!
//Code on!

söndag 4 september 2011

Update on threading

In a previous post ("Safe threading") I talked about threading, and using the method performselectoronmainthread. This method is great for "fast-jumping" from your own thread to the applications main-thread. After using the method for a while I however realized that the method is very constricted. This resulted in a thread on StackOverflow where I asked if there is any smarter ways to jump in and out of threads. I got a great response to the question that really made my threading easier:




Well, you're already using dispatch_async. Then you should just use
     dispatch_async(dispatch_get_main_queue(),^ { ... } );
from inside your background thread to perform things on the main thread. For example,
     if ([self testServerMethod])
        {
            dispatch_async(dispatch_get_main_queue(),^ {
               [self showMessageBoxWithString: @"Server is working!"];
               [self threadedUIActivityRemover:nil];
            } );
        }else ...


This way of calling 
dispatch_get_main_queue()



And then performing UIKit-related stuff is really smooth and much more versatile then performselectoronmainthread. 

So, that's an update to the hole Threading-colundrum. Now on to new things. 
I'm still writing on Quizer as much as I can. And it's slowly starting to take form. Next week I hope to have time to tackle the main logics of the game itself. And thats really something I'm looking forward to. 
To be able to run the app 24/7 I've invested in a small NAS that run Apache and MySql. It will be fun to see how it will handle high traffic-load etc. I'll come back to you regarding that when I'm testing the app in a few weeks!
Today I'm in school programming with my friend Ludvig. He's not the most inspired programmer today.. but after all it's sunday.. 
Ludvig at work!
//Code on!

fredag 26 augusti 2011

Hide a slow network connection

Downloading to the device can be painfully slow. Even fast 3g connections lags when it comes to response times compared to wired networks (It's not all about mb/s). This mean that you have to take this in consideration while designing a Client-Server application for the phone.

Threading is the answer to this. Do your network fetches in the background and you "might" be able to deliver a feeling of responsiveness to the user. Many apps do this by showing an UIAvtivityIndicatorView while downloading information, like this:



This is a great way of telling your clients, Hey!, I'm working here!.. but it will require your client to wait..

You can however solve this neater in many situations by performing background tasks while the user is scrolling though your UI, that does not require the data being downloaded. If you for e.g. know that the user soon will come to a screen that requires downloaded data, Start downloading it sooner rather then later. of course you can argue about the increased network use and battery drainage, but it all comes down to your decision as an developer.

Today I did one of these sneaky background downloads in this interface:


This interface has the button "Choose category from list". This list is being fetched from the server. 
I could have solved this by presenting an UIActivityIndicatorView either when loading this ViewController or when loading the UIPickerview that popes up when you click the button.
Instead I solved it by disabling the button itself and giving it the .text property "Downloading list..."
until the list is downloaded. This way the user can roam around the interface and not be prompted to wait, while still knowing that a download is being performed.

Think about how your user will use your application, and try to be one step ahead at all times!

Code on! 





torsdag 25 augusti 2011

Need faster protocol declaration!

Apple!
It takes forever to define a protocol in objective C!
Please build a function (outside of IB) that let's you "Define new protocol".

This is how you do it today:
First you have to define the protocol in the class that is going to do callbacks to it's delegate.


@protocol CreateGameProtocol <NSObject>

-(void)userDidCancelCreationOfGame;

@end

This is put above the @interface declaration in the .h file.
Then you have to create a property for the delegate in the property section of the same .h file:

@property (weak, nonatomic) id<CreateGameProtocol> delegate;

Remember to put Weak and not strong there! Why? you do not want the to have a retain from the subclass to it's owner. Only one should own the other!

then you have to implement the protocol in the delegate class:

@interface GameViewController : UIViewController<CreateGameProtocol>

Just put the name of the protocol in "less-then, greeter then"-signs.
Remember to import the .h file of the subclass in the delegate for it to "see" the protocol!

then you have to define the callback method in the delegate .h file.

#pragma mark -
#pragma mark Protocol Methods
-(void)userDidCancelCreationOfGame;

Then you have to call the method from the subclass .m file.

    [delegate userDidCancelCreationOfGame];

And of course assign the property of "delegate" to self when you create the subclass in the delegate-class:

        
    createGameViewController.delegate = self;



That is what I call a hassle for something that easy....
I'm lucky there is ctrl-v ctrl-c in these situations!






onsdag 24 augusti 2011

Safe threading!

The importance of threading safely has become clear when working on SC. At many times my background treads has come in touch with UIKIT (Not thread-safe) and crashed. if you e.g.. want to check a value against the server and display different ViewController's depending on the result, you cant't do this on the background thread.

This is my way of doing that (Might be better ways out there):


dispatch_queue_t loginThread = dispatch_queue_create("Login-thread", NULL);
    dispatch_async(loginThread, ^{
    
        NSArray *arrayWithUsernameAndPassword = [NSArray arrayWithObjects:userName, password, nil];
        
    if([dataParser loginOnServer:[self requestActiveServerData] withUsername:userName andPassword:password])
    {
        [self performSelectorOnMainThread:@selector(threadReturnLogin:) withObject:arrayWithUsernameAndPassword waitUntilDone:YES];
    }else
    {
//Should be a rejection here!
    }

    });
    

    dispatch_release(loginThread);
    




     [self performSelectorOnMainThread:@selector(threadReturnLogin:) withObject:arrayWithUsernameAndPassword waitUntilDone:YES];


is the solution to the UIKIT problem. This executes the function on the main thread instead of the custom one!


Happy coding!