Agile Developer, Berlin, Germany

25.11.2008

Howto retrieve the current language for Mac OS X

Filed under: macosx, programming — pegolon @ 12:59

I have a client who needs localizations for several languages. To retrieve the current language I used

NSString * localeString = [[NSLocale currentLocale] localeIdentifier];
NSString * language = [[[localeString componentsSeparatedByString:@"_"] objectAtIndex:0] uppercaseString];

Most of the time the content of localeString represented the settings in the system preference pane. But if I set English as the first language and Finland as the region in Formats it returns “fi_FI” as the localeString, but uses the Finnish nib files.

Preference pane Language

Preference pange Formats

To get the languages in the order from the preference pane “Language” one has to use the following code:

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* language = [[languages objectAtIndex:0] uppercaseString];

The variable language contains now “EN” as expected.

15.11.2008

Using UITableViewCell with InterfaceBuilder

Filed under: iphone, programming — pegolon @ 20:37

The code examples for the iPhone SDK show only how to construct your table cells programatically. If you want to use InterfaceBuilder to make a proper layout which might also be resizable etc. you can use this ViewFactory to handle the creation and reusage of your table cells.

First create a new empty Interface Builder file. Design all the UITableViewCells you want, but they must be root objects so they can be found by the ViewFactory. Each cell MUST have its “identifier” field set. It is in fact its reuseIdentifier required to make a proper recycling of your cell possible.

bild-1

Now create the ViewFactory, the header ViewFactory.h

@interface ViewFactory : NSObject {
    NSMutableDictionary * viewTemplateStore;
}

- (id) initWithNib: (NSString*)aNibName;

- (UITableViewCell*)cellOfKind: (NSString*)theCellKind forTable: (UITableView*)aTableView;

@end

and the implementation ViewFactory.m

#import "ViewFactory.h"

@implementation ViewFactory

- (id) initWithNib: (NSString*)aNibName
{
    if (self == [super init]) {
        viewTemplateStore = [[NSMutableDictionary alloc] init];
        NSArray * templates = [[NSBundle mainBundle] loadNibNamed:aNibName owner:self options:nil];
        for (id template in templates) {
            if ([template isKindOfClass:[UITableViewCell class]]) {
                UITableViewCell * cellTemplate = (UITableViewCell *)template;
                NSString * key = cellTemplate.reuseIdentifier;
                if (key) {
                    [viewTemplateStore setObject:[NSKeyedArchiver
                                                  archivedDataWithRootObject:template]
                                          forKey:key];
                } else {
                    @throw [NSException exceptionWithName:@"Unknown cell"
                                                   reason:@"Cell has no reuseIdentifier"
                                                 userInfo:nil];
                }
            }
        }
    }

    return self;
}

- (void) dealloc
{
    [viewTemplateStore release];
    [super dealloc];
}

- (UITableViewCell*)cellOfKind: (NSString*)theCellKind forTable: (UITableView*)aTableView
{
    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:theCellKind];

    if (!cell) {
        NSData * cellData = [viewTemplateStore objectForKey:theCellKind];
        if (cellData) {
            cell = [NSKeyedUnarchiver unarchiveObjectWithData:cellData];
        } else {
            NSLog(@"Don't know nothing about cell of kind %@", theCellKind);
        }
    }

    return cell;
}

@end

You have to make the ViewFactory instance available for your TableViews as a Singleton.

Whenever you want to fill you table cell in your UITableViewDataSource put this line in your method

- (UITableViewCell *)tableView: (UITableView *)aTableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
   UITableViewCell * cell = [viewFactory cellOfKind:@"news" forTable:aTableView];
   // Access the views using [cell viewWithTag:X] in the old way
   return cell;
}

where “news” in this example is the value of the reuseIdentifier.

Internally I store each instance of the UITableViewCells as a template in a NSData archived format and make it accessible via its reuseIdentifier. So whenever cellOfKind:forTable: is called it looks into the reuseQueue of the given table if there is already an old table cell which can be reused or if it needs to instantiate a new one using the archived template to create the new table view cell.

This technique is much more flexible if you are using tables and I hope you will have fun using it.

03.11.2008

Quick iPhone Dev Tip: Creating an UIColor with just one RGB value

Filed under: iphone, programming — pegolon @ 11:39

Are you also tired of splitting that long RGB value into red, green and blue and converting them to a format that UIColor understands? I was, so I wrote a macro that converts the value on compile time and returns an UIColor autorelease object with the correct values:

#define UIColorFromRGB(rgbValue) [UIColor \
 colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

In your code you can use it like this:

UIColor myGreen = UIColorFromRGB(0x00FF00);

Put this in your global header referenced from <project_name>_Prefix.pch and you can use it everywhere in your project without importing it excplicitly.

09.10.2008

My first iPhone App has been released!

Filed under: iphone, programming — pegolon @ 9:48

Yesterday evening I got a mail from Apple that they released my iPhone App WeFind. It took them 8 days (submitted on 30th September) to test it.

It’s a news aggregator which collects its data from our newssite Newsexpress. In the next version there will be other search engines included and many more features are already in the pipeline.

The direct AppStore link is here. Its only available in Germany, Switzerland and Austria since its based on German newspapers.

I am very excited.

News Aggregator

News Aggregator

30.09.2008

Founded a new chapter of CocoaHeads in Berlin

Filed under: iphone, programming — pegolon @ 0:24

After listening to this nice podcast I decided to start a new chapter of CocoaHeads in Berlin.

The google group for discussion is here.

Now I have to find a nice and decent place for the meetings…

20.07.2008

A much better language speed comparison

Filed under: programming — pegolon @ 9:08

Dhananjay Nene made a very good comparsion of all major languages (C++ / Java / Python / Ruby/ Jython / JRuby / Groovy) including source code. This is a much better and more detailed view on a specific computing problem. My quick performance comparison was discussed very heavily since it doesn’t count the language specific criteria very well.

18.03.2008

Using (Native)Windows with AIR

Filed under: air, flex, programming — pegolon @ 11:16

If you want to use windows in AIR with custom chrome (especially transparent) you have to consider some drawbacks. First you cannot use NativeWindow if you want to use Flex components from the mx.* namespace. There is a separate Window class in the AIR package which encapsulates a NativeWindow. To get your own content inside this window you can create a separate MXML file like this:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Window xmlns:mx=”http://www.adobe.com/2006/mxml”
width=”200″ height=”100″
transparent=”true” systemChrome=”none” type=”normal”
showStatusBar=”false” showTitleBar=”false” showFlexChrome=”false”>
<PlaceYourContentHere/>
</mx:Window>

This will display a transparent window without any controls and header on the screen.

Whenever you want to create and display the window use:

var myWindow:MyWindow = new MyWindow
myWindow.open()

If you want to change the position of the window you have to use its nativeWindow property:

// Center window

myWindow.nativeWindow.x = (Capabilities.screenResolutionX – myWindow.width) / 2
myWindow.nativeWindow.y = (Capabilities.screenResolutionY – myWindow.height) / 2

I used to use the NativeWindow class for transparent windows since AIR beta 1. To get Flex-Containers in it I initialized them in the main application window, removed them there and added them to stage of the NativeWindow. This worked fine until I used controls like ComboBox or ColorPicker which relied on the PopupManager. The popup window didn’t occur until I found that it was opened in the main application window at the position of the initial component.

18.02.2008

My favorite monospaced font for coding of the month

Filed under: flex, programming — pegolon @ 15:29

I am constantly overthinking my editor font for coding. Using Java and Eclipse I was able to use a anti-proportional font because of the automatic code formatting. Unfortunately in Flexbuilder there is no such thing as automatic code formatting. Much worse the editor ignores sometimes, that I don’t want to use tabs at all and mixes tabs and spaces. So I had to switch back to a monospaced font and found this one in the web: http://www.ghostscript.com/~raph/type/myfonts/inconsolata.html Its under the Open Font License which feels rather unrestricted. 

24.01.2008

Quick Ruby vs. Groovy performance comparison

Filed under: programming — pegolon @ 12:24
Tags: ,

I was just wondering how Ruby and Groovy are comparing in performance with each other so I wrote a quick line in both languages and ran it in irb / GroovyConsole.

Ruby:

start=Time.new;y=0;(1..2000000).each { |x| y=x };Time.new - start

Groovy:

def test=System.currentTimeMillis();(1..2000000).each { x -> y=x };System.currentTimeMillis() - test

The Ruby code is being interpreted, the Groovy one is being compiled into Java Bytecode and then executed.

Ruby: 456 – 529 ms
Groovy: 1812 – 1885 ms

If you change the line inside the closure to “y+=1″ you get these results:

Ruby: 674 – 785 ms
Groovy: 4210 – 4465 ms

In Ruby there is no “++” operator, but in Groovy it seems to be faster than “+=1″:

Groovy: 3298 – 3338 ms

Conclusion: it is not very surprising, that a language which is being developed over almost 15 years (Ruby) is better optimised than one which is just 5 years old. I guess if we wait a couple of years Groovy will become a serious competitor to Ruby, but note however that Ruby gets a JIT in version 1.9 so the advance will become much greater.

23.01.2008

Strange Flex/AIR error

Filed under: air, flex, programming — pegolon @ 14:14

If you get this error:

Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found. 

There is likely a Loader.load() call which cannot find the file. You should add an event listener like this

loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError)  

Next Page »

Blog at WordPress.com.