52

We are having the same issue found here, here, here and here

Basically we upgraded to xcode 6.1 and our build are getting the "ResourceRules.plist: cannot read resources" error.

We have a Jenkins server that does our ios builds for us. We are using the Xcode plugin on Jenkins to do the actual build and signing. Any thoughts on how we can make this change without manually opening xcode and doing this solution found on the other answers:

Click on your project > Targets > Select your target > Build Settings >

Code Signing Resource Rules Path

and add :

$(SDKROOT)/ResourceRules.plist

I'm very new to Xcode and iOS build in general. I have found the project.pbxproj file inside the Unity-iPhone.xcodeproj file. It looks like this contains the build settings under the /* Begin XCBuildConfiguration section */ section it lists what looks like similar build properties foundin Xcode, however I do not see anything like "Code Signing Resource Rules Path".

Does anyone have experience manually editing this file? Is that a bad idea in general?

Thanks

Community
  • 1
  • 1
Tim
  • 1,191
  • 1
  • 11
  • 11
  • 1
    possible duplicate of [XCode 6.1 error while building IPA using TestFlight app](http://stackoverflow.com/questions/26497863/xcode-6-1-error-while-building-ipa-using-testflight-app) – Peter Oct 23 '14 at 11:45
  • 1
    The accepted fix in that thread requires the ability to edit the xcode project via the gui. It appears that this issue is with Unity built xcode projects running through a Jenkins based CI solution. This means that the xcode projects are auto generated and auto built without the chance or desire for manual manipulation of the xcode project. – jpelletier Oct 23 '14 at 14:26
  • Yes, @jpelletier it is with a Unity built xcode project that is then built through command line, we never manually open the project up. – Tim Oct 23 '14 at 15:49
  • @PeterMetz I referenced that same thread in my original post, however as jpelletier pointed out, those require manual intervention of opening the project, we never do that. – Tim Oct 23 '14 at 15:51
  • @Tim I'm sorry, my bad! Should've read the question more carefully. – Peter Oct 25 '14 at 11:29

6 Answers6

67

If you're using Jenkins with the XCode plugin, you can modify the 'Code Signing Resource Rules Path' variable by adding:

"CODE_SIGN_RESOURCE_RULES_PATH=$(SDKROOT)/ResourceRules.plist" 

to the

'Custom xcodebuild arguments' setting for the XCode plugin.

This fix does not require the XCode GUI.

apxcode
  • 7,696
  • 7
  • 30
  • 41
nick
  • 786
  • 6
  • 7
  • Thanks nick That was too easy, not sure how I didn't see that. Worked great! I am sure @martinmose script would have worked, just saw this before I tried it. Also for anyone else using Unity, I had a third option I was going to try using their [XcodeAPI](https://bitbucket.org/Unity-Technologies/xcodeapi) to change it. – Tim Oct 23 '14 at 18:30
  • 3
    Unfortunately, if you are using Yosemite, the above is obsolete. See http://stackoverflow.com/questions/26497863/xcode-6-1-error-while-building-ipa/26674605#26674605 – skitheo Aug 18 '15 at 22:27
  • Works but not recommended. See the link for the fix : http://cutting.io/posts/packaging-ios-apps-from-the-command-line/ – amir Jul 13 '16 at 14:27
  • This is broken again on XCode 8.0. Does anyone have any fixes for this? – C0D3 Sep 19 '16 at 20:48
  • Hi @c0d3Junk13 , any luck in integration with xcode 8, I have similar issue. – Burhan Mughal Nov 04 '16 at 11:16
  • Hi @BurhanMughal, we turned of automatic code signing on our build machine which is under the General tab of the project in Xcode 8. – C0D3 Nov 04 '16 at 13:58
  • @c0d3Junk13 Got the Solution but not the one you are proposing :) I had already turned off automatic signing. But What actually work was to manually go to PackageApplication and removing/commenting the ResourceRules.plist line. Anyway thanks for your reply :) – Burhan Mughal Nov 04 '16 at 14:22
  • Ah ok glad, I was a bit out of context to be honest. – C0D3 Nov 04 '16 at 14:56
13

I encountered the same problem. Nicks solution does work, but is requiring additional dependencies. You don't need the heavy-handed npm xcode module for this. Just add a line to this file: $PROJECT_ROOT/platforms/ios/cordova/build.xcconfig

CODE_SIGN_RESOURCE_RULES_PATH=$(SDKROOT)/ResourceRules.plist

Note that before XCode 6.1.1, this needed to be specified as "$(SDKROOT)/ResourceRules.plist" (notice the quotes).

If you are running this inside automated build systems such as Jenkins and wont't/can't use any XCode GUI, just create a small Cordova hook, leveraging npm's fs.appendFile, at this location: $PROJECT_ROOT/hooks/before_build/ios_resourcerules.js (make sure it has chmod +x)

#! /usr/local/bin/node
var fs = require("fs");

fs.appendFileSync('build.xcconfig', '\nCODE_SIGN_RESOURCE_RULES_PATH =  $(SDKROOT)/ResourceRules.plist', function (err) {
 if (err) throw err;
  console.log('CODE_SIGN_RESOURCE_RULES_PATH added to Cordova iOS build configuration.');
});

This will might be merged in an upcoming Cordova release, so the hook will become unnecessary (i'm creating a see this PR for Cordova-iOS).

In case the above JavaScript snippet fails to execute due to a "wrong argument" failure, replace the file's content as follows:

#!/bin/bash

if [ ! -f ./build.xcconfig ]; then
  echo "[ERROR] hook befor_build/ios_resourcerules.sh cannot execute, ./build/xcconfig not found in $PWD"
  exit 1
fi

echo '// (CB-7872) Solution for XCode 6.1 signing errors related to resource envelope format deprecation' >> ./build.xcconfig
echo 'CODE_SIGN_RESOURCE_RULES_PATH=$(SDKROOT)/ResourceRules.plist' >> ./build.xcconfig
echo 'CODE_SIGN_RESOURCE_RULES_PATH added to Cordova iOS build configuration.'
miraculixx
  • 10,034
  • 2
  • 41
  • 60
sidneys
  • 399
  • 2
  • 5
  • For what it's worth, cordova requires the xcode module, so you'll likely already have it around, though I too am not a fan of the module. – shortstuffsushi Oct 30 '14 at 16:50
  • With your code you'll see an error "Bad arguments". Because you use the synchronous function fs.appendFileSync with a callback. To use the callback, use fs.appendFile instead. – efusien Dec 01 '14 at 23:10
  • 2
    Awesome thank you! This worked for me (editing the build.xcconfig file). I only had to make one minor change removing the quotes from "$(SDKROOT)/ResourceRules.plist" – jarbot Dec 04 '14 at 22:48
  • Is the Cordova bug fix working for anyone? Like @jarbot, I had to remove the quotes from the line that Cordova had added to the build.xcconfig file. – Nick Spacek Jan 16 '15 at 14:46
  • @nick's solution worked great for us without needing any additional dependancies. I'm confused as to where npm or Cordova enter into the question, though… – lagweezle Feb 02 '15 at 20:07
5

If you want to get really crazy, you can directly update PackageApplication.

# In /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication
my @codesign_args = ("/usr/bin/codesign", "--force", "--preserve-metadata=identifier,entitlements,resource-rules",
                     "--sign", $opt{sign},
                     "--resource-rules=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/ResourceRules.plist");
# OLD:               "--resource-rules=$destApp/ResourceRules.plist");

I was already hacking this script to accept a keychain arg, so it made sense for me. Note I'm not using the Xcode Jenkins plugin -- I'm using Jenkins but running all the build commands from a script.

Ben Flynn
  • 18,524
  • 20
  • 97
  • 142
4

After the new release of XCode 7 on 23rd Sept 2015, Apple started rejecting any application that is using CODE_SIGN_RESOURCE_RULES_PATH, making the Jenkins build automatically rejected. However, setting CODE_SIGN_RESOURCE_RULES_PATH=$(SDKROOT)/ResourceRules.plist into the Custom xcodebuild arguments causes a build failure.

This answer resolved the issue: https://stackoverflow.com/a/32762413/5373468

This is clearly a bug that Apple forgot to fix a while ago, as this article is also highlighting: http://cutting.io/posts/packaging-ios-apps-from-the-command-line/

Community
  • 1
  • 1
Renaud Tilte
  • 66
  • 1
  • 3
1

I had EXACTLY the same problem, as you have. We are building our iOS app on Jenkins, so we couldn't manually set "Code Signing Resource Rules Path".

I have wrote a small NodeJS file which does the job for me (see the code below).

The script use a nice NodeJS package called xcode which helps me with the parsing of the xcode.xcodeproj file.

I don't know if you are using Cordova/Phonegap or what you are using, but if you are can just copy the code and make a Cordova hook. If not I'm sure you can execute the file from Jenkins, with some small changes.

Anyways, I hope this script will help you:

#!/usr/bin/env node

var CODE_SIGN_RESOURCE_RULES_PATH = '"$(SDKROOT)/ResourceRules.plist"';

var fs = require("fs");
var path = require("path");
var xcode = require('xcode');
var projectRoot = process.argv[2];

function getProjectName(protoPath) {
    var cordovaConfigPath = path.join(protoPath, 'www', 'config.xml');
    var content = fs.readFileSync(cordovaConfigPath, 'utf-8');

    return /<name>([\s\S]*)<\/name>/mi.exec(content)[1].trim();
}

function run(projectRoot) {
    var projectName = getProjectName(projectRoot);
    var xcodeProjectName = projectName + '.xcodeproj';
    var xcodeProjectPath = path.join(projectRoot, 'platforms', 'ios', xcodeProjectName, 'project.pbxproj');
    var xcodeProject;

    if (!fs.existsSync(xcodeProjectPath)) {
        return;
    }

    xcodeProject = xcode.project(xcodeProjectPath);

    console.log('Setting Code Sign Resource Rules Path for ' + projectName + ' to: [' + CODE_SIGN_RESOURCE_RULES_PATH + '] ...');
    xcodeProject.parse(function(error){
        if(error){
            console.log('An error occured during parsing of [' + xcodeProjectPath + ']: ' + JSON.stringify(error));
        }else{
            var configurations = nonComments(xcodeProject.pbxXCBuildConfigurationSection());
            for (config in configurations) {
                var buildSettings = configurations[config].buildSettings;

                buildSettings['CODE_SIGN_RESOURCE_RULES_PATH'] = CODE_SIGN_RESOURCE_RULES_PATH;
            }

            fs.writeFileSync(xcodeProjectPath, xcodeProject.writeSync(), 'utf-8');

            console.log('[' + xcodeProjectPath + '] now has Code Signing Resource Rules Path set to:[' + CODE_SIGN_RESOURCE_RULES_PATH + '] ...');
        }
    });
}

var COMMENT_KEY = /_comment$/;
function nonComments(obj) {
    var keys = Object.keys(obj),
        newObj = {}, i = 0;

    for (i; i < keys.length; i++) {
        if (!COMMENT_KEY.test(keys[i])) {
            newObj[keys[i]] = obj[keys[i]];
        }
    }

    return newObj;
}

run(projectRoot);
martinmose
  • 443
  • 8
  • 12
  • We are actually using Unity3D, everything is written in C#. I can run a postprocess script once the Unity build is complete. That would happen after the xcode project is generated, but before it is compiled into the app. I may be able to fairly easily change your nodejs script to C# and just kick it off after the Unity build is done. I'll give it a shot and if it works mark yours as the answer. Thanks for the script! – Tim Oct 23 '14 at 15:53
  • matinmose thanks for the script! @Tim, can you post your c# script once you write it please? – Kaan Yy Dec 03 '14 at 08:11
1

We are using Unity + Jenkins for auto builds.

You can achieve with post process cs scripts; however; for quick (and dirty fix) you can apply following bash command after Unity but before xcode:

sed -i '' 's/CONFIGURATION_BUILD_DIR/CODE_SIGN_RESOURCE_RULES_PATH = "\$(SDKROOT)\/ResourceRules\.plist";\'$'\n                CONFIGURATION_BUILD_DIR/g' /Users/admin/Jenkins/workspace/PROJECTNAME/Build/PROJECTNAME/Unity-iPhone.xcodeproj/project.pbxproj
Kaan Yy
  • 471
  • 6
  • 9