Question

Part of the plugin.xml

<!-- ios -->
<platform name="ios">

    <config-file target="config.xml" parent="/*">
        <feature name="MyPlugin">
            <param name="ios-package" value="MyPlugin"/>
        </feature>
    </config-file>

    <!--this need to be added to the .plist file-->
    <config-file target="*-Info.plist" parent="UIBackgroundModes">
        <array>
            <string>location</string>
        </array>
    </config-file>

    <header-file src="src/ios/MyPlugin.h" />
    <source-file src="src/ios/MyPlugin.m" />
</platform>

Left side is Before install my plugin, right side is After:

Difference

As you can see before:

<key>NSMainNibFile</key>
<string></string>
<key>NSMainNibFile~ipad</key>
<string></string>

And after

<key>NSMainNibFile</key>
<string>

    </string>
<key>NSMainNibFile~ipad</key>
<string>

    </string>

What a big difference! If I delete those whitespaces, which I don't know from where they came from than I don't have crash after startup!

ios 6 simulator output ( but is same on the device too)

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/myusername/Library/Application Support/iPhone Simulator/6.0/Applications/F4FDE3C4-D7A8-440F-866D-D0DECD79E2F5/My.app> (loaded)' with name '

    ''
*** First throw call stack:
(0xea012 0x2848e7e 0xe9deb 0x540fac 0x54298d 0x324ceb 0x325002 0x323ed6 0x335315 0x33624b 0x327cf8 0x367adf9 0x367aad0 0x5fbf5 0x5f962 0x90bb6 0x8ff44 0x8fe1b 0x3237da 0x32565c 0x1fe3c 0x1fd9d)
libc++abi.dylib: terminate called throwing an exception
(lldb) 

I think it is a bug in Cordova / Phonegap, but that doesn't make my boss happy. How to solve this? The .plist is re-generated each time at launch from command line, so can't manually edit.

Can't find documentation, only this and I don't know why is added my location 4 times, if I wrote only 1 time.

Edit: After install my plugin from command line (but not compile or run) the plist looks like this:

<key>NSMainNibFile</key>
<string>

</string>
<key>NSMainNibFile~ipad</key>
<string>

</string>
<key>UIBackgroundModes</key>
<array>
  <string>location</string>
</array>


$ phonegap build ios 


<key>NSMainNibFile</key>
<string>

</string>
<key>NSMainNibFile~ipad</key>
<string>

</string>
<key>UIBackgroundModes</key>
<array>
  <string>location</string>
  <string>location</string>
</array>

-observe: there is a row with location added!

$ phonegap run ios
[phonegap] detecting iOS SDK environment...
[phonegap] using the local environment
[phonegap] compiling iOS...
[phonegap] successfully compiled iOS app
[phonegap] trying to install app onto device
[phonegap] no device was found
[phonegap] trying to install app onto emulator
[phonegap] successfully installed onto emulator

The plist will be cleared 2 times: those will be cleared 2x, finally it will be added again. Now the plist looks like this:

<key>NSMainNibFile</key>
<string>

</string>
<key>NSMainNibFile~ipad</key>
<string>

</string>
<key>UIBackgroundModes</key>
<array>
  <string>location</string>
  <string>location</string>
  <string>location</string>
  <string>location</string>
  <string>location</string>
</array>

Edit2:

cordova prepare

RANDOMLY clears the <string></string> white spaces AND always add <string>location</string> to UIBackgroundModes array !

Was it helpful?

Solution

Yes, this does appear to be a bug in Cordova's handling of plugins' configuration settings for plist files.

The duplicate array entries are annoying, but shouldn't break the build or affect the app. However the whitespace added to the NSMainNibFile* settings does cause XCode to fail to build with the NSInternalInconsistencyException error message you saw.

Until this is fixed I am working around it using the following hook script - placed in .cordova/hooks/after_platform_add/patch_plist.sh:

#!/bin/bash
if pushd platforms/ios 2>/dev/null ; then   # iOS-specific actions...
    # Patch *-Info.plist
    PROJNAME=$(echo *.xcodeproj|sed -e 's/\..*//')
    sed -i '' '/<key>NSMainNibFile<\/key>/,/<\/string>/d' $PROJNAME/*-Info.plist
    sed -i '' '/<key>NSMainNibFile~ipad<\/key>/,/<\/string>/d' $PROJNAME/*-Info.plist
    popd
fi

This removes those settings from the plist completely, as they aren't needed. Removing them prevents Cordova from adding them back in a broken state after a prepare.

The script needs to be made executable:

chmod a+x .cordova/hooks/after_platform_add/patch_plist.sh

This should run after each platform add command, when the plist is generated - so you need to run the following commands afterwards to regenerate it and apply the patch:

cordova platform rm ios -d
cordova platform add ios -d

OTHER TIPS

it's not a good solution, but what I've found works to prevent the duplication until it's fixed in plugman is the following:

<!-- clobber old array value in .plist -->
<config-file target="*-Info.plist" parent="UIBackgroundModes">
    <string>CLOBBER</string>
</config-file>

<!-- replace clobbered value with proper array in .plist -->
<config-file target="*-Info.plist" parent="UIBackgroundModes">
    <array>
        <string>location</string>
    </array>
</config-file>

ie, clobber the node with a single-dimensional node, then re-clobber it with the proper array.

just add these lines into config.xml

<platform name="ios">
    <config-file platform="ios" target="*-Info.plist" parent="NSMainNibFile">
        <string></string>
    </config-file>
</platform>
<platform name="ios">
    <config-file platform="ios" target="*-Info.plist" parent="NSMainNibFile~ipad">
        <string></string>
    </config-file>
</platform>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top