NSInternalInconsistencyException – reason: ‘Could not load NIB in bundle’

Is it ambiguous ? Well at the outset it seems to be.

After a swag of updates (iOS 6, Xcode, OSX 10.8.2 ::modem has officially asked for time off now::) I opened an existing client project that was working previously. This project was used during a prototyping session with the client, so why does it break now ?

The error:
2012-09-21 07:42:07.257 Stenhouse Workshop[3017:c07] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Could not load NIB in bundle: ‘NSBundle /Users/paulusher 1/Library/Application Support/iPhone Simulator/6.0/Applications/B1F4C9E9-EAB6-4AD8-96D6-D82EDD9E6E48/Stenhouse Workshop.app (loaded)’ with name ‘WorksheetViewController”
*** First throw call stack:
(0x1c99012 0x10d6e7e 0x1c98deb 0x239fac 0xfee37 0xff418 0xff648 0xff882 0x10b235 0x30a3d2 0x1084f3 0x108777 0x96d933f 0x1087b7 0x25ee 0x10ea705 0x21920 0x218b8 0xe2671 0xe2bcf 0xe1d38 0x5133f 0x51552 0x2f3aa 0x20cf8 0x1bf4df9 0x1bf4ad0 0x1c0ebf5 0x1c0e962 0x1c3fbb6 0x1c3ef44 0x1c3ee1b 0x1bf37e3 0x1bf3668 0x1e65c 0x1e7d 0x1da5)
libc++abi.dylib: terminate called throwing an exception

Googling this type of thing will send you on a wild goose chase, the NSInternalConsistancyException seems to cover a lot of ground.

Because of the number of upgrades that had taken place I decided to start by doing a ‘clean’ on the project,when that failed, reseting the content on the iOS Simulator, still nothing, (insert head banging here). I checked all the connections, made sure no objects had been removed leaving bad things behind. There were some ‘warnings’ on the project, pointing at deprecated color options on my grids. So dutifully, I changed the selection to something that was current, did another clean and build but the app still crashed.

I then noticed the smallest difference, the NIB name was “WorksheetViewController” and the code was calling “WorkSheetViewController”. It seems the issue of the Simulator correcting these behind the scenes has been fixed (see the note here on Simulator black magic)

After a quick alteration of the NIB name the project was useable again. So while technically it was not anything specific to the OS changes that broke the project, it was changes in Xcode and the Simulator. Of course the app would have crashed on the device anyway, so at least we were spared that pain.

What would have been nice to see was an error message something like- reason: ‘Could not load NIB in bundle: NIB File Not Found’.

icon dimensions (0 x 0) don’t meet the size requirements

Welcome to Apple World:

Submit – Fail, Submit – Fail, Submit – Fail

It certainly was not the first iOS App I had tried to submit, yet here I am, seeing the same ambiguous error:

iPhone/iPod Touch: icon.png: icon dimensions (0 x 0) don’t meet the size requirements. The icon file must be 57×57 pixels, in .png format

I mean, how can it tell me a file that clearly exists, shows in Preview as 57×57 and compiles without error is now 0x0 ??

1 hour and 1 minute, thank you Apple.

So finally the iPhone module – Key Elements (part of the new Set Professional range) is ready to go. The final step is to upload for Apple’s tick of approval and its in the AppStore. As with any submission we go through a simple set of checklists

[x] – Code Review
[x] – Clean
[x] – Compile (error free)
[x] – Artwork
[x] – – – Lo-Res
[x] – – – Hi-Res
[x] – – – AppStore
[x] – AppStore theme
[x] – Provisioning profile
[x] – App Submission Prep
[ ] – Upload binary

Each time an upload would take place I would see the same message, it talks of my icon file being the wrong size, but here is what we know so far;

1. You cannot set the icon file inside xCode without it being correct size (applies to both standard and hi-res image)
2. The plist file clearly shows the icon files are present and correct
3. Remove entry from pList, remove file and reset doesn’t work
4. Recreation of the icon file (just in case it had some weird corruption) still didn’t address it

Now we are really clutching at straws. Enter the google search. Having read a number of posts I came across an obscure entry http://nano-art.blogspot.com.au/2010/08/icon-dimensions-0-x-0-dont-meet-size.html Now all that is left is finding the entry in xCode 4.

So, it is hidden under the Packaging section of Build Settings.

The Culprit

Questions I still cannot answer:
1. How did it get set to YES
2. Why the Application uploader can’t tell me a real message

Strangely (well not strange really, just damn frustrating), after the flag is set to “NO”, the whole process was completed in less than 5 minutes.

system.invalidoperationexception clr20r3

Ok, enough is enough. How do you fix a problem that cannot be defined?

Let me backtrack a little. I new version of insQuote data converter was deployed today. The setup program ran flawlessly, the DLL’s were put in place and the pretty icon was placed on the desktop. The same procedure that has been repeated by thousands of people with software since the dawn of msi_exec !

Launch the program, up comes the cool looking splash and WHAM! “This program has stopped working!” – no handled (or un-handled) exception, no calling of my error traps, just an unceremonious crash.

Cool, lets check the event log, nothing but a clr20r3 system.invalidoperation message. So what now?

Basic checklist

– are the DLL’s required the ones we shipped ? YES
– are all sub-dependant DLL’s present ? YES
– are there any UAC issues ? NO
– is the .Net framework installed correctly (client profile vs extended) ? YES
– are there any pending Windows Updates that could be causing the problem ? NO (but install the pending 28 anyway)
– has anyone in Google land had a similar problem ? YES – wow, lots of unanswered posts

Now whats next ? the error is unhelpful, we have been through the basics and so its time to approach it a little differently. The application in question uses a couple of third party components (see this post on preferred components) so maybe the issue is directly related…

I created a new vanilla project, .Net 4.0 and tested on the rogue machine. All good. So now introduce the DevExpress UI controls, deploy and test. All good. Now add in the ComponentOne Flexigrid, deploy and test. All good. That leaves only one left to test – SQLite.Net.

After installing the SQLite.Net package the mysterious problem went away.

So it turns out we know the following

– the error is directly related to a missing dependancy
– the error reporting for such events is abismal

The next step was to work out what caused the problem. After some more research it turns out to be Visual C++ 2010.

Sandboxing – writing outside the box

Ok, Apple announced that “as of March, 2012 all apps submitted to the Mac App Store must implement sandboxing”, and since we were preparing the release of our new Set Professional desk top app, it would be a great time to introduce it. Little did I realise that I would spend all afternoon tracking down a ‘bug’ that was without error.

SetPro allows access to Dropbox, the first time through the process you are prompted for the application folder, then the .setpro file is saved, and through the wonders of modern technologies synchronised to the cloud.

Subsequent running of the program would simply remember the Dropbox folder location and save the file directly. Or so I thought. No amount of testing, checking NSURL configurations, , would see the file being written to the folder. Go through the process again, set the folder location and hey presto, re-test and failure.

The only difference between success and failure was the use of an NSOpenPanel, even if the NSURL filepath was being set manually.

Enter the Sandbox… The entitlements file was set to use Sandboxing, with read/write access set, but that does not enable me to save directly to any folder, so why is it hit and miss ?

Entitlements with Read/Write enabled

I found an obscure post, that mentions if you present the user with a NSOpenPanel or NSSavePanel then you can save to the URL contained in the panel; HOWEVER, if you have not presented the user this option then you are unable to save outside your Sandbox.

Even Sandboxed Apps can access things

The frustrating part about this whole exercise is that no errors are generated, no exceptions raised, no messages passed through XCode, just the frustration that your file is not saved.

Ambiguous errors: NSInternalInconsistencyException mutating method

Terminating app due to uncaught exception

‘NSInternalInconsistencyException’, reason: ‘*** -[NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object’

Ok, so what does it actually mean and why am I getting this on a NSMutableArray…?

The error is not so much ‘ambiguous’ as downright misleading. My code clearly shows I am working with a mutable array;

NSMutableArray *items = [docket objectForKey:@"Times"];
[times setValue:startLabel.text forKey:@"Stop"];
[times setValue:[NSNumber numberWithFloat:diff] forKey:@"Total"];
[items replaceObjectAtIndex:[items count]-1 withObject:times];

So why the error? And why not the first time I run the app?

The answer is in the that last sentence, obviously when the object is constructed all is well, but later on (subsequent runs) the object has changed from mutable to non-mutable.

Normally that would occur when assigning an array to a mutable array, but in this case there is nowhere that stands out.

Enter the .pList !

We are storing the record in a plist file, which seems when you serialise a NSMutableArray it becomes an NSArray. Therefore when you read it back it is coming in as a non-mutable object.

NSMutableArray *items = [[NSMutableArray init] alloc];
[docket setValue:items ForKey:@"Times"];

however when it is read back;

NSMutableArray *items = [docket objectForKey:@"Times"];

it is changing the NSMutable to NSArray.

To make matters worse, this only crashes on the device, not on the simulator! Annoying.

The solution:

Ensure we type cast the NSArray into NSMutableArray when reading the value from the dictionary in the first place.

NSMutableArray *items = [[NSMutableArray alloc] initWithArray:[docket objectForKey:@"Times"]];

Another problem solved, and a happy client !

Ambiguous errors: oledbconnection DB_SEC_E_AUTH_FAILED

A client rang to say they are having problems with a small program I wrote. It has worked for a few months – no problem, then out of the blue they started receiving an error “DB_SEC_E_AUTH_FAILED”. Initially thoughts were security changes or user permissions, so time was spent looking into server changes. (This was a Terminal Services environment). During the last week some 14 updates had been pushed out:

Figure: Installed Updates

Was it possible one of these was a culprit. Interestingly, another piece of our legacy software could still access the database, indicating the issue was related to the .NET application. It was time to trace some code.

The starting point was to log the filename passed into the connection method. Deploy. Test.

The result was simple. The filename passed in was BLANK ! So I immediately went to the registry, found the offending entry, and sure enough no filename. When this minor issue was corrected amazingly, everything went right back to working.

So the lessons learned:

1. Don’t forget to check the basics BEFORE you take any notice of the error
2. Add to knowledge base that Security and Authentication errors happen when you pass NO filename into a OleDBConnetion method.

Needless to say, we don’t know what caused the registry to be cleaned, the history of this particular server (which I do not administer) is another story for another day !