Filed under Recipes

Today I've tried to update iPhoto 9 to 9.2 in order to get iCloud support. Mac OS's build in "Software update" didn't show me any updates so I checked online if anyone else was experiencing the same problem.

I found some interesting articles here and here describing the same problem I had.

Unfortunately no suggested answers fixed my problem. I even manually downloaded the update from Apple's website to no avail.

The manual update gave me an error that my iPhoto version was too old!?

Before doing a complete reinstall of iLife I figured out a possible reason the update wasn't showing up. I had previously copied my iLife applications into a folder called "iLife '11" to tidy things up.

As a last resort I moved all the apps inside that folder back into the main applications folder. I then again ran Software update and to my suprise it showed me all the updates updates for my iLife suite!

I never knew moving applications to sub folders inside the applications folder was such a 'bad' idea..

— Written on the 17th of October 2011, filed under Recipes.

A really specific error I — nonetheless — wanted to share..

After installing the iOS5 beta 3 last night I got the following build error while compiling Tanis: error: Second argument to 'va_arg' is of non-POD type 'id'.

My code looks something like this:

@interface NSMutableArray (variadicMethodExample)

- (void) appendObjects:(id) firstObject, ...; 
// This method takes a nil-terminated list of objects.

@end

@implementation NSMutableArray (variadicMethodExample)

- (void) appendObjects:(id) firstObject, ...
{
        id eachObject;
        va_list argumentList;
        if (firstObject) // The first argument isn't part of the varargs list,
        {                                   // so we'll handle it separately.
                [self addObject: firstObject];
                va_start(argumentList, firstObject); // Start scanning for arguments after firstObject.

                while (eachObject = va_arg(argumentList, id)) // As many times as we can get an argument of type "id"

                [self addObject: eachObject]; // that isn't nil, add it to self's contents.

                va_end(argumentList);

        }
}
@end

Apple told me it's a bug in the compiler. They will likely address it in a future seed. In the mean time I've used this workaround to temporarily fix my error:

void *x = va_arg(argumentList, void*);
id y = (__bridge id)x;

The idea is to 'bridge' the argument back to a id type. Nasty, I know, but it's suggested by one of Apple's own developers.

— Written on the 12th of July 2011, filed under Recipes.

For my current project I've created a subclass of Loren Brichter's ABTableViewCel which custom draws a gradient background and text inside a UITableViewCell.

I've found out though that cells would not redraw or resize when the UI rotates from portrait to landscape mode.

By default a UIView will stretch it's contents instead of redrawing. You can control this with the contentMode property of a UIView. When assigning UIViewContentModeRedraw to contentMode a UIView will redraw on events like rotation.

Apple developer manual:

Normal geometry changes do not require redrawing the view. Therefore, if you alter the appearance of a view and want to force it to redraw, send setNeedsDisplay or setNeedsDisplayInRect: to the view. You can also set the contentMode to UIViewContentModeRedraw to invoke the drawRect: method when the bounds change; otherwise, the view is scaled and clipped without redrawing the content.

@implementation ABTableViewCell

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier
{
        if(self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier])
        {
                contentView = [[ABTableViewCellView alloc] initWithFrame:CGRectZero];
                contentView.opaque = YES;

                // This is the one:
                contentView.contentMode = UIViewContentModeRedraw; 

                [self addSubview:contentView];
                [contentView release];
        }
        return self;
}
— Written on the 5th of September 2010, filed under Recipes.

Yet another fix for a bizarre error. A so called NSInternalInconsistencyException was thrown when I loaded a NIB (Interface Builder) file.

The exception message told me that The NIB data is invalid.

Xcode and Interface builder didn't gave me any warnings or errors. After searching the web I couldn't find a solution, so I started to investigate my NIB file.

Along with iPhone OS 4.0 comes an improved version of Xcode and Interface Builder. The Bedrijven App we're creating uses the new iAd framework. When inspecting the Document window of the NIB that caused the exception I saw that the Ad Bannerview" was inside my UITableView.

This didn't gave any warnings or errors, but did cause a runtime error.

So before you waste any time on this..

Ad views cannot be directly inside a UITableView!

If you want an ADBannerView inside a UITableView place it inside a UITableViewCell.

— Written on the 5th of September 2010, filed under Recipes.

The other day I received the following exception while debugging an iPhone app.

Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.)

mi_cmd_stack_list_frames: Not enough frames in stack.

It turns out these kind of error occur when using library and framework classes when they are not available in the running version of iOS.

I got it when running a iOS 4.0 version of a backwards compatible app on a 3.13 iOS iPhone (1st gen).

So if you receive this error, check to see all your code is backwards compatible!

— Written on the 4th of September 2010, filed under Recipes.

In my fight with Obj-c another small problem struck me yesterday. I received a EXC_BAD_ACCESS exception when running a seemingly straightforward code.

NSError *error;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error: &error];

if(error != nil)
{                
        NSString * message = [NSString stringWithFormat: @"Something horrible went wrong: %@", error];
        NSLog(@"%@", message);
{

As you can see I declare a NSError variable that might contain a value after calling executeFetchRequest.

Normally these errors occur when released objects are being accesed. This however, was not the case.

After a bit of googling I wasn't able to find a real awnser, so I tried the following.

NSError *error = nil;

NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error: &error];

if(error != nil)
{                
        NSString * message = [NSString stringWithFormat: @"Something horrible went wrong: %@", error];

        NSLog(@"%@", message);
}

As you can see the only difference is the assignment of nil to NSError object.

This actually fixed the problem. It's still unclear to me why this actually works.

— Written on the 3rd of September 2010, filed under Recipes.

I just wanted to share the most straight forward method I found to detect if a UITouch occurred inside a UIView.

The following sample expects a UIVIew thats been connected with Interface builder.

// Inside your @implementation of a UIViewController 
// add the following method

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
        UITouch *touch = [touches anyObject];

        if(touch.view == self.myView)
        {
                // Bingo, the view is touched!
        }
}
— Written on the 2nd of September 2010, filed under Recipes.

Debugging some vague CoreData error can be tricky. In order to see the raw SQL in the console you can enable CoreData SQL debugging by adding an argument to your application.

  • Open Xcode and your project
  • From the main menu choose "Project" > "Edit active executable"
  • Select the arguments tab
  • Add the argument: -com.apple.CoreData.SQLDebug 1

Apple developer documentation

— Written on the 1st of September 2010, filed under Recipes.

Ever wanted to trace / log a WCF client message when using a custom binding? Well I faced this dilemma and found a "good enough" solution.

When tracing or logging a WCF client one can use build in features. However, when you are using a 'custom binding' implementation this is isn't (always) possible.

You are basically depending upon the implementation of the binding. In my case it lacked the ability to trace or log messages.

In order to see what was being send I first tried Fiddler but that didn't work since the custom adapter seemed to ignore any proxy configuration I threw at it.

My solution then was to use Wireshark (kudos to Johan de Vries). A freeware application that logs all activity on your LAN card. Simply run the program and watch out for messages that are send. Copying the message can be done by 'right clicking' the data bit, and select 'copy bytes as text'.

— Written on the 29th of September 2009, filed under Recipes.

Today I found out that changing the showsScopeBar property of the UISearchBar didn't automagically resize the content area.

After looking a bit further in the iPhone SDK api reference I found out that this effect is easily created by calling the sizeToFit method.

Short example:

// show
searchBar.showsScopeBar = YES;
[searchBar sizeToFit];
 
// hide
searchBar.showsScopeBar = NO;
[searchBar sizeToFit];

Hope this saves someone some time :-)

— Written on the 21st of June 2009, filed under Recipes.