PIXEL
DOCK

I like the smell of Swift in the morning…

Localizable.strings error: “The data couldn’t be read because it isn’t in the correct format”

Posted: | Author: | Filed under: Objective-C, Swift, Xcode | 6 Comments »

I added some new keys to my Localized.strings files:

"HOME_TEAM" = "Home team"
"AWAY_TEAM" = "Away team"

Then I got this error from Xcode:

Read failed: The data couldn't be read because it isn't in the correct format

It took me a minute but when I found what caused the error I had to smile. I simply forgot the semicolons at the end of each line:

"HOME_TEAM" = "Home team";
"AWAY_TEAM" = "Away team";

Those poor semicolons! Coding in Swift really makes you forget they even existed in the first place 😉

OCMock: signature declares ‘q’ but value is ‘i’

Posted: | Author: | Filed under: Objective-C | Tags: | No Comments »

When writing a test for a class using OCMock I ran into the following error message:

error: -[PXDItemsListView testListView] : failed: caught "NSInvalidArgumentException", "Return value does not match method signature; signature declares 'q' but value is 'i'."

The code that was causing this error was this:

OCMStub([self.dataSourceMock numberOfItems]).andReturn(4);

Which is a stub of the data source’s method:

- (NSInteger)numberOfItems;

And you do not get this error when you implement this method like this:

- (NSInteger)numberOfItems {
   return 4;
}

So why does the stubbing of this method create this error?

The reason is, that the implemented method does know it’s return type, so the 4 will automatically be typed to NSInteger. Which means that it will be of type int on 32-bit architectures and of type long on 64-bit architectures.

OCMock on the other hand has no idea what the return type of the 4 should be. It just sees the 4 and assumes that it is of type int. Regardless of the architecture. So when running this this on a 64-bit device you will get this error, because the stubbed method is supposed to return a long.

The fix for this is quite easy. You just have to be clear about the type of the value that your stub should return:

OCMStub([self.dataSourceMock numberOfTeasers]).andReturn((NSInteger)4);

Actually this is explicitly written down in the OCMock reference: “For methods that return primitive values it is important to use the right type of value.”

But, hey, who reads the f***ing manual, right?

Use the Nil Coalescing Operator in Swift to assign default values to properties

Posted: | Author: | Filed under: iOS, Objective-C, Swift | No Comments »

One of the new operators that comes with Swift is the Nil Coalescing Operator. In the documentation it is explained as: The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil.

This operator already exited in C but for Objective-C developers it is kind of new (more about that at the bottom of this post).

With this operator assigning values to a property with a fallback to a default value becomes really concise:

Instead of doing this:

func setupBackgroundColor(color: UIColor?) {
   if (color != nil) {
      backgroundColor = color
   } else {
      backgroundColor = UIColor.whiteColor()
   }
}

You can simply do this:

func setupBackgroundColor(color: UIColor?) {
        backgroundColor = color ?? UIColor.whiteColor()
}

Pretty cool, isn’t it?

Actually something like this was already possible with Objective C:

- (void)setupBackgroundColor:(UIColor *)color {
   self.backgroundColor = color ? : [UIColor whiteColor];
}

How to remove an option from a NS_OPTIONS bitmask

Posted: | Author: | Filed under: Objective-C | No Comments »

I really like the NS_OPTIONS macro. I think it is a neat and tidy way to store multiple boolean values in one bitmask.

So for example if you have a car object that stores the features a customer ordered for his new car you could define something like:

typedef NS_OPTIONS(NSInteger, Feature) {
    FeatureNavigationSystem = (1 << 0),
    FeatureHeatedSteeringWheel = (1 << 1),
    FeatureParkDistanceControl = (1 << 2),
    FeatureSunRoof = (1 << 3),
    FeatureConvertible = (1 << 4)
};

Now you can store the features that a customer selected in one NSInteger (or in this case 'Feature') value using the bitwise OR operator (|):

Feature selectedFeatures = FeatureNavigationSystem | FeatureParkDistanceControl;

To check if a customer has selected a certain feature you use the bitwise AND operarator (&):

if (selectedFeatures &= FeatureNavgiationSystem) {
    // user has selected navigation system
}

Now there might be a situation where you want to remove a feature from the bitmask of selected options. In my simple example that might be the case when a user selects the option FeatureConvertible. If the customers does that, you might want to make sure that the feature FeatureSunRoof is not selected (because obviously a convertible does not have a roof).

So you want to remove the option FeatureSunRoof from the selected options while leaving the rest of the selected options as they were. This is where our friend the bitwise NOT operator (~) comes into play:

selectedOptions &= ~FeatureSunRoof

This removes the FeatureSunRoof from the selectedFeatures bitmask.

“Collection was mutated while being enumerated” during CoreData operation on background thread

Posted: | Author: | Filed under: iOS, Objective-C | Tags: , , | 7 Comments »

During my current project I had to move a time consuming CoreData operation to a background thread to avoid a frozen UI. After reading some horror stories about using CoreData on a background thread I was actually surprised how straight forward it was. I used Apple’s sample code ThreadedCoreData as a guidance. When I tested my changes everything went smooth. Until I started to touch my app’s UI while the background process was running. Suddenly the app crashed and the following exception was thrown:

*** Terminating app due to uncaught exception 'NSGenericException',
reason: '*** Collection <__NSCFSet: 0x1f0ec200> was mutated while
being enumerated.'

The exception was being thrown on the background thread during a call to

[NSManagedObjectContext executeFetchRequest:error:]

What happened?

In Apple’s example code the CoreData operations happen inside the main method of a custom subclass of NSOperation. That subclass is initialized using a custom initWithData: method and then added to a NSOperationQueue.

When doing CoreData operations on a background thread it is important that the background thread uses it’s own instance of NSManagedObjectContext. And this NSManagedObjectContext has to be instantiated on the background thread.

And that was the problem.

In Apple’s example the NSManagedObjectContext for the background thread is instantiated in the custom initWithData: method of the custom ParseOperation class. But that method is called on the main thread when instantiating a new ParseOperation object before adding it to the NSOperationQueue. So the NSManagedObjectContext instance is created on the main thread!

The solution was quite simple:

After moving the code that instantiates the NSManagedObjectContext from the initWithData: method (called from the main thread) to the main method (called from the background thread), the problem vanished and the code run smoothly.

So, when using CoreData in a background thread make sure that the background thread has it’s own NSManagedObjectContext instance that was created on the background thread!

A little category to get an NSDictionary from an NSString containing a plist

Posted: | Author: | Filed under: iOS, Objective-C | Tags: , , | 2 Comments »

I really like the plist format. Being able to transform a plist file into a NSDictionary with one line of code really appeals to the lazy guy in me. So when our backend developer asked me what my preferred format for server responses would be, I told him to send his responses in plist format. That’s when I came across a little problem: When accessing the response body of the request, all I got was a NSString. The string contained the plist, but it was still a string and not the usual XML structure that you normally get when you open a plist file.

I found a way to parse a NSString into a NSDictionary on StackOverflow (thanks to Peter N Lewis for his answer).

So I decided to write a little category to extend NSDictionary so that it can initialize a NSDictionary with a plist NSString:

@interface NSDictionary (DictionaryWithString)
   + (NSDictionary *)dictionaryWithString:(NSString *)string;
@end

#import "NSDictionary+DictionaryWithString.h"

@implementation NSDictionary (DictionaryWithString)

+ (NSDictionary *)dictionaryWithString:(NSString *)string {
   NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
   NSString *error;
   NSPropertyListFormat format;
   NSDictionary *dict = [NSPropertyListSerialization 
      propertyListFromData:data 
      mutabilityOption:NSPropertyListImmutable 
      format:&format 
      errorDescription:&error];
   if(!dict){
      NSLog(@"ERROR: could not parse NSString: %@",error);
      [error release];
   }
   return dict;
}

@end

Feel free to use it in your own projects.

How to compare two NSDecimalNumber values

Posted: | Author: | Filed under: iOS, Objective-C | Tags: , , | No Comments »

Recently I had to use NSDecimalNumber objects to avoid the rounding errors that come with float values. While comparing two float values is as easy as it gets comparing two NSDecimalNumbers works a bit different:

NSDecimalNumber is a subclass of NSNumber so you have to use NSNumber’s compare: method to compare the values:

NSDecimalNumber *number1 = [NSDecimalNumber numberWithFloat:0.1];
NSDecimalNumber *number2 = [NSDecimalNumber numberWithFloat:0.2];

// check if number1 is less than number2
if ([number1 compare:number2] == NSOrderedAscending {
   NSLog(@"number1 is less than number2")
}

Set the height of a UIWebView to the height of it’s HTML content

Posted: | Author: | Filed under: iOS, Objective-C | Tags: , | 19 Comments »

Sometimes you need to know the height of a html document that is loaded into a UIWebView. For example if you want to set the height of the UIWebView to the height of its content.

The logical way would be this:

1. add a Javascript function to the HTML that returns the height of the document.
2. add the call to this Javascript function to the UIWebViewDelegate’s method webViewDidFinishLoad:

This sounds easy, but if you look at the results you’ll realize that the values for the document height are not correct and pretty random.

The problem is: webViewDidFinishLoad: get’s called when the HTML is fully loaded BUT it still has to be fully rendered before you can determine its height!

So the call comes too early. You could delay the call but that’s not the way to go here as this is still unreliable and you want the height as soon as possible.

The solution is to revert the process. Instead of Objective-C asking the Javascript for the height, have the Javascript call Objective-C as soon as it knows the height of the document.

Here’s how to do it:

1. Add a Javascript function to the HTML document

Add this function either to the head or the body of your HTML

This function gets called as soon as the HTML document is fully rendered. It puts the height into an URL and sends a request with this URL.
If you are asking yourself why I use “ready://” instead of “http://”: I do this because sending a request is the only way, how the Javascript inside a UIWebView can send messages to the UIWebViewDelegate. So this is not a “real” HTTP Request. Instead you can use the URL scheme to make things easier on the Objective-C part (as you will see in step 2).

2. Intercept the request in the UIWebView’s delegate

A UIWebViewDelegate has a method, that get’s called everytime the HTML inside the UIWebView sends a request. Here’s what to do in this method:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { 
  NSURL *url = [request URL]; 
  if (navigationType == UIWebViewNavigationTypeOther) { 
    if ([[url scheme] isEqualToString:@"ready"]) { 
      float contentHeight = [[url host] floatValue]; 
      CGRect fr = webview.frame; 
      fr.size = CGSizeMake(webview.frame.size.width, contentHeight); 
      webview.frame = fr; 
      return NO; 
    } 
  }
  return YES; 
}

Here you can see why I used the custom URL scheme “ready”. It makes it easy to identify my request. The URL that the javascript requested has the format “ready://1200” meaning that the HTML content is 1200px high. So I use the scheme “ready” to identify my request and the “host” part of the URL to sent the actual height. Then it’s easy to set the height of the UIWebView to the height of the HTML document’s content.

Return NO to stop the UIWebView from trying to load the request. Don’t forget to return YES for all other requests or the HTML content won’t even get loaded into the UIWebView in the first place.

UIColor+colorWithHex: a category to get an UIColor from a hexadecimal integer value or string

Posted: | Author: | Filed under: iOS, Objective-C | 5 Comments »

I always find it really cumbersome to instantiate an UIColor object from a hexadecimal color value. To make life a bit easier I wrote this category for the UIColor class:

@interface UIColor (ColorWithHex) 

+(UIColor*)colorWithHexValue:(uint)hexValue andAlpha:(float)alpha;
+(UIColor*)colorWithHexString:(NSString *)hexString andAlpha:(float)alpha;

@end

@implementation UIColor (ColorWithHex)

+(UIColor*)colorWithHexValue:(uint)hexValue andAlpha:(float)alpha {
    return [UIColor  
                colorWithRed:((float)((hexValue & 0xFF0000) >> 16))/255.0 
                green:((float)((hexValue & 0xFF00) >> 8))/255.0 
                blue:((float)(hexValue & 0xFF))/255.0 
                alpha:alpha];
}

+(UIColor*)colorWithHexString:(NSString*)hexString andAlpha:(float)alpha {
    UIColor *col;
    hexString = [hexString stringByReplacingOccurrencesOfString:@"#" 
                           withString:@"0x"];
    uint hexValue;
    if ([[NSScanner scannerWithString:hexString] scanHexInt:&hexValue]) {
        col = [self colorWithHexValue:hexValue andAlpha:alpha];
    } else {
        // invalid hex string         
        col = [self blackColor];
    }
    return col;
}

@end

Because I often need to convert a hex string (e.g. from a parsed XML file) to an UIColor I added 2 methods to this category. You can now get an UIColor from a hexadecimal uint value or an NSString that can have the 3 following formats: “0xFFFFFF“, “#FFFFFF” or “FFFFFF“.

Just add this category to your project and you can use it like this:

UIColor *col1 = [UIColor colorWithHexValue:0xFFFFFF andAlpha:1.0];
UIColor *col2 = [UIColor colorWithHexString:@"0xFFFFFF" andAlpha:1.0];

You can download the category here.

Feel free to use it.

Xcode: Dividing long NSString constants over multiple lines

Posted: | Author: | Filed under: Objective-C, Xcode | Tags: | No Comments »

Just a little Objective-C “trick” to make long NSString constants a little bit more readable in your Code:

To break a part of the long string to a new line you have to wrap it in quotation marks. The compiler will then put it back together to one long string.

So instead of doing this:

NSString *htmlStr = @"PageTitle

Hello World

";

You could do this:

NSString *htmlStr = @""
                       ""
                          "PageTitle"
                       ""
                       ""
                          "

Hello World

" "" "";

Of course the cleanest thing to do would be to separate the html code completely from your Objective-C code by putting it into a separate HTML file and load that into a string. But hey, who wants to be perferct all the time?