libPhoneNumber-iOS Metadata From plist Not Properly Unarchived | unarchiveData is nil

Google has developed libphonenumber, a comprehensive library for phone number formatting and validation for international numbers.

GitHub user iziz has been so kind to port it to an iOS library, you can find the latest revision on the project’s GitHub page.

For a client that requires sign-up via mobile number, I wanted to use the library to validate and format input, but always got issues that my phone number was invalid – although it wasn’t.

After digging through the code, I realised the number would never have been considered valid, since all the necessary metadata, that is provided via a plist file, couldn’t be loaded, the NSDictionary retrieved via NSKeyedUnarchiver was always nil.

After googling I found this issue on the project page. Another frustrated user suggested that NSKeyedunarchiver has a bug, which took me on to wrong paths for a while.

Suddenly, I noticed everything worked fine in the simulator, once it had occurred to to try the code there.

Comparing variable values from the simulator and on device, I’d seen the amount of bytes loaded from the file in the two environments differed!
Simulator: 180085 bytes
Device: 496050 bytes

And then it hit me! I had placed the NBPhoneNumberMetadata.plist into the Resources folder, but in order to make it work, it has to lie under Supporting Files.
Move the plist, do a clean and rebuild, and you’ll be all happy happy! :-)
Now the loaded data has the correct byte size and validation works like a charm.

I’ve also changed the bundle I retrieve it from to be mainBundle instead some bundle variable, not sure if it makes a difference, but here’s the code that used to fail and now works with my changes.

NBPhoneNumberUtil.m:

- (NSDictionary*)loadMetadata:(NSString*)name
{
    NSDictionary *unarchiveData = nil;
    
    @try {
	NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:@"plist"];
        NSData *fileData = [NSData dataWithContentsOfFile:filePath];
        unarchiveData = [NSKeyedUnarchiver unarchiveObjectWithData:fileData];
    
    } @catch (NSException *exception) {
        return unarchiveData;
    }
    
    return unarchiveData;
}