question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Arrays in plist files can not be adjusted with edit-config

See original GitHub issue

Bug Report

Problem

What is expected to happen?

When you want to have device-specific orientation options, like only portrait on phone, but allow landscape on iPad, you’d want to use edit-config to adjust your .plist accordingly.

What does actually happen?

When you use edit-config to make adjustments not covered by the preference for orientation, they will not be persisted to the .plist for your iOS project.

Information

Possibly related to https://github.com/apache/cordova-common/commit/9c6cda3db766c3daa87e8e4f8cc65e818a9e6dfc (https://issues.apache.org/jira/browse/CB-13496)

The edit-config directives would be:

<edit-config file="*-Info.plist" mode="overwrite" target="UISupportedInterfaceOrientations">
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
	</array>
</edit-config>
<edit-config file="*-Info.plist" mode="overwrite" target="UISupportedInterfaceOrientations~ipad">
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</edit-config>

The result will be (regardless of the configuration details above):

<key>UISupportedInterfaceOrientations</key>
<array>
  <string>UIInterfaceOrientationPortrait</string>
  <string>UIInterfaceOrientationLandscapeLeft</string>
  <string>UIInterfaceOrientationLandscapeRight</string>
  <string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
  <string>UIInterfaceOrientationPortrait</string>
  <string>UIInterfaceOrientationLandscapeLeft</string>
  <string>UIInterfaceOrientationPortraitUpsideDown</string>
  <string>UIInterfaceOrientationLandscapeRight</string>
</array>

Only using <preference name="Orientation" value="foo" /> has an effect on the issue.

When you change the key UISupportedInterfaceOrientations to any other string, it will be persisted to the .plist correctly.

When you remove the UISupportedInterfaceOrientations directives from the template .plist, the final result is as expected.

Command or Code

oliver@oliver-home MINGW64 ~
$ cordova create ios-orientation-bug
$ cd ios-orientation-bug/
$ cordova platform add ios

Then add the above edit-config directives to the newly created config.xml and cordova prepare.

Environment, Platform, Device

Reproduced in builds on OSX and Windows.

Version information

9.0.0 (cordova-lib@9.0.1) cordova-ios@5.0.1

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:3
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
raphinessecommented, Dec 2, 2019

Thanks for this detailed issue report. I can reproduce the behavior described by you and after some code reading, I unfortunately have to confirm that what you want to do is indeed not possible with edit-config or config-file tags at the moment. Below I will provide more details on my findings and a possible workaround.

First off, edit-config is for editing attributes only. To quote the docs (emphasis mine):

Instead of appending new children to an XML document tree, edit-config makes modifications to attributes of XML elements.

So what you are trying to do above is not supposed to work. Deletion of tags is not supported using Cordova’s built-in config editing mechanism. Neither for plist nor for any other XML files.

The reason I am making this distinction here, is that plist files are handled separately from other XML files. If you look at the linked code, you will realize that the mode of the config change is completely disregarded for plist files. In fact, all changes to a plist file are handled by this code which only does merges. Either of objects or of arrays. That explains the results you are seeing.

This special treatment of plist files seems to make sense given the fact that, due to their specific structure, we could do very little of use with them if we would apply the default rules for other XML files. However, I could not find this special treatment to be documented anywhere (did I miss it?). Furthermore I clearly see the limitations of the current editing capabilities – for plist files as well as for other XML files.

As a workaround, the following after_prepare hook should be able to do what you want:

const fs = require('fs');
const path = require('path');
const plist = require('plist');

module.exports = ({ opts: { projectRoot, platforms } }) => {
    if (!platforms.includes('ios')) return;

    const projectName = 'HelloCordova';
    const platformPath = path.join(projectRoot, 'platforms/ios');
    const infoPlistPath = path.join(platformPath, projectName, `${projectName}-Info.plist`);

    const infoPlist = plist.parse(fs.readFileSync(infoPlistPath, 'utf8'));

    infoPlist.UISupportedInterfaceOrientations = [
        'UIInterfaceOrientationPortrait',
        'UIInterfaceOrientationPortraitUpsideDown',
    ];

    infoPlist['UISupportedInterfaceOrientations~ipad'] = [
        'UIInterfaceOrientationPortrait',
        'UIInterfaceOrientationLandscapeLeft',
        'UIInterfaceOrientationPortraitUpsideDown',
        'UIInterfaceOrientationLandscapeRight',
    ];

    fs.writeFileSync(infoPlistPath, plist.build(infoPlist, { indent: '\t' }));
}

So what do we take away from this issue? My suggestions would be:

  • The behavior for plist files needs to be documented (if it is indeed not documented yet)
  • It would be nice to at least have a warning if using edit-config/mode with plist files
  • We need better config editing capabilities

Any additions?

PS: I don’t think any of the issues linked from here are actually related to this issue.

1reaction
oliversalzburgcommented, Dec 3, 2019

.build/overwritePlistContent.js:

#!/usr/bin/env node
const fs    = require( "fs" );
const path  = require( "path" );
const plist = require( "plist" );

const projectName  = "FairManager"
const plistChanges = {
	"UISupportedInterfaceOrientations" : [
		"UIInterfaceOrientationPortrait",
		"UIInterfaceOrientationPortraitUpsideDown"
	],
	"UISupportedInterfaceOrientations~ipad" : [
		"UIInterfaceOrientationPortrait",
		"UIInterfaceOrientationLandscapeLeft",
		"UIInterfaceOrientationPortraitUpsideDown",
		"UIInterfaceOrientationLandscapeRight"
	]
}

module.exports = context => {
	const plistPath = path.resolve( context.opts.projectRoot, "platforms", "ios", projectName, `${projectName}-Info.plist` );

	if( !fs.existsSync( plistPath ) ) {
		console.log( `'${plistPath}' does not exist. Overriding device orientations is skipped.` );
		return;
	}

	const plistContent = plist.parse( fs.readFileSync( plistPath, "utf-8" ) );

	console.log( `Adding desired device orientations to '${plistPath}'...` );
	const plistData = Object.assign( {}, plistContent, plistChanges );
	fs.writeFileSync( plistPath, plist.build( plistData, {
		indent : "\t",
		offset : -1
	} ), "utf-8" );
}

In config.xml: <hook src=".build/overwritePlistContent.js" type="after_prepare" />

Read more comments on GitHub >

github_iconTop Results From Across the Web

Add entry to iOS .plist file via Cordova config.xml
I am using Cordova 3.3.1-0.42 (I know it is not the latest). I have already made my project and all is fine, I...
Read more >
Monaca how to set properties in info.plist through config.xml
I have added the line in config.xml audio But its off no help. ... There is no way to get hold of the...
Read more >
Plugin.xml reference documentation - Apache Cordova
The file to be modified, and the path relative to the root of the Cordova project. If the specified file does not exist,...
Read more >
WKWebView asks "would like to use your current location" not ...
In my case, I was working in a Cordova Project and all I had to do was add this to the project .plist...
Read more >
cordova-custom-config-ka - npm package - Snyk
Cordova/Phonegap plugin to update platform configuration files ... If buildType is not specified or set to "none", the plugin will look in ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found