Displaying a loading indicator for UIWebView using UIActivityIndicatorView

Posted by Filip Ekberg on December 1 2010 4 Comments

More and more apps today uses only the native application as a shell around their web-based application to get their app into App Store. A drawback with doing this is that you might get really annoying load times and you have to decide where to put the “wait for the data”-scene.

In my opinion you have two alternatives

  • Either you load all data in the App Delegate and have the Default.png shown untill all data is downloaded
  • Or you can start the loading in the App Delegate and not wait for it to finish and display a loading indicator once the application finished loading.

I’ve evaluated both of these methods and find that the second one enhanced the feeling of the application, no one accepts to wait for 5 seconds before an application is somewhat interactive.

Therefore I’ll show how to add a Loading indicator using the UIActivityIndicatorView.

You need to declare the UIActivityIndicatorView in your header file so it is accessable from all delegate methods.

UIActivityIndicatorView *loadingIndicator;

Then you need to initiate a UIActivityIndicatorView like this:

loadingIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(145, 190, 20,20)];
[loadingIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[loadingIndicator setHidesWhenStopped:YES];

The first line allocates the resources for a UIActivityIndicatorView and the initializes it and puts it in the center of the screen, this is in landscape mode.

After that we set the style to gray and tell it to dissapear when we stop the animation. You can choose between three different color-schemes for this indicator. Check the apple developer reference for more information about that.

Now you are ready to add the loading indicator to you web view like this:

[webView addSubview:loadingIndicator];

I take for granted that you have a web view that’s called webView and that it has webView.delegate = self;. So that you can use the delegate methods to start and stop the loading indicator animation.

Now we are at the final step of the journey to get a loading indicator to our web view in the -(void)webViewDidStartLoad:(UIWebView *)webView delegate method we add the following:

[loadingIndicator startAnimating];

This will start the spinning loader inside the Web View, now to remove it, go to your delegate method for -(void)webViewDidFinishLoad:(UIWebView *)webView and add the following:

[loadingIndicator stopAnimating];

And you are all set! Now you should have a loading animation that displays a spinning wheel as long as the data loads.

Vote on HN

A work around to the memory leaks in NSXMLParser

Posted by Filip Ekberg on November 30 2010 7 Comments

Lately I’ve experimenting a bit with parsing XML in Objective-C and discovered something that I’d like to share with you all.

First of all, consider the following “standard” way of downloading an XML and parsing it

NSXMLParser *parser = [[NSXMLParser alloc]
            initWithContentsOfURL: [NSURL
            URLWithString:@"http://some-xml-url.com/my.xml"]];

You would think that this line of code is Solid, all it’s supposed to do is download the content, release the temporary resources for fetching data and store the final content for the parsing later on. However somewhere in the process there’s a resource that isn’t cleaned up properly and you will get a memory warning the “Build and Analyze” method wont find it but when you run the application with a Performance tool looking for leaks you will end up getting something like this:

Leaked Object
Malloc 512 Bytes

Responsible Frame
allocateCollectableUnscannedStorage

Leaked Object
NSConcreteMapTable

Responsible Frame
+[NSMapTable alloc]

I tried a lot of suggestions to fix this issue some of them being to set the sharedURLCache to 0 like this:

[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];

These alone did not solve the problem, so on the quest to find a proper work around I came up with this solution:

[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];

NSData *xml = [NSData
        dataWithContentsOfURL: [NSURL
        URLWithString:@"http://some-xml-url.com/my.xml"]];

NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xml];;

And that did it, after this I no longer received any memory warnings.

Vote on HN

Function pointers in C and Python and their possible usage

Posted by Filip Ekberg on November 30 2009 Leave a Comment

Function pointers? you might ask yourself, well this little trick gets handy sometimes, I will provide an example of a practical use in a later post on the next euler solution. Might actually do it in C too just to prove that C is still neat.

So to kick this off, what are function pointers? Well for those deep down the rabbit hole ( .NET guys that is ), might not really have a clue on the matter, and others might dissaggree and now exactly what it is. So just to keep the air clear here, function pointers are “pointers” that direct you to a function, easy huh?

Well, you probably got as much from just reading the phrase but, it’s not really rocket science. If you are familiar with references or reference types, such as Strings and Objects, you know that there are different types of memory in which your program operates. When you create an Object you store your data on a shared memory place. There are shared memory and program reserved memory ( the stack! ). So you might want to look at this as a “reference” to a function.

So when would this be nessecary? Imagine the scenario where you might want to performe some calculation but you don’t know what type of API the end user which will end up using your API have. Let’s say that the method “square” ( x^x ) would not be defined. So you might end up having to use function pointers, where you ask the user to suppy the function for calculating square of x.

In Python the Square function for x^x will look like this

def square(i):
        result = i;
        for x in range(i-1):
                result *= i

        return result

In C it will look like this

int square(int i)
{
        int result = i;
        int x = 1;

        for ( x = 1; x < i; x++ )
        {
                result *= i;
        }

        return result;
}

Now these two look fairly similar don’t they? Well sure, the only real difference is the dialekt right? It’s just programming. So let’s get to the cool parts. In python, we would solve this problem easy, since it’s not a strongly typed language everything could be a function, right. So let’s check the decleration for calculate.

But before we check that out, let’s just make it clear that our Usage will be somewhat like, give me a function that calculates square of a+b, this means, the result should be (a+b)^(a+b).

So this is the function decleration in Python

def calculate(func, a, b)

Not that hard, right? Well, keep in mind that Python is a “modern” language, it’s more of a scripting language.

Check this out and notice the fairly big difference

int calculate(int (*func)(int c), int a, int b)

If you are not familiar with pointers I would suggest you dig down the archive on my blog and check out the chapters about that. So what this really does in C is that you tell the compiler that, okay this function takes a pointer to something that will look like this, and you write the declaration of the function again. So, in this case you really need to know what it looks like. With standard parameter values in Python you could acheive some really cool things without knowing the decleration of the function.

Now we’ve seen how to Create the methods, taking arguments that are functions, how about using them inside your code?

Check this C example of the whole Calculate function

int calculate(int (*func)(int c), int a, int b)
{
        return (*func)(a+b);
}

And in Python the following will look like this

def calculate(func, a, b):
        return func(a+b);

There is a notable difference here, but I can honestly say that I like the C-style.

Try out the python version!

#!/usr/bin/python

def square(i):
        result = i;
        for x in range(i-1):
                result *= i

        return result

def calculate(func, a, b):
        return func(a+b);

def main():
        print calculate(square, 1, 1)

if __name__ == "__main__":
    main()

Happy Coding!

Vote on HN