Can xcodebuild manage automatic signing? - ios

SUMMARY:
If you open a project in Xcode 8 with "Automatically manage signing" enabled and a new bundle ID, it will automatically create and download a provisioning profile for it. But how can I make the same thing happen with xcodebuild, so I can use it on a remote build server?
DETAILS:
I'm trying to build a Cordova app on a Mac. Cordova configures the Xcode project to use "Automatically manage signing", so I'm trying to use that.
I change the bundle ID often, so I want Cordova to be able to build it with a new bundle ID, that hasn't been used before.
But when I run cordova build ios --release --device --buildConfig build.json, I get a return code 65 and the following error:
Check dependencies
No profiles for 'com.my.bundle.id' were found: Xcode couldn't find a provisioning profile matching 'com.my.bundle.id'.
Code signing is required for product type 'Application' in SDK 'iOS 10.3'
** ARCHIVE FAILED **
The following build commands failed:
Check dependencies
(1 failure)
Error: Error code 65 for command: xcodebuild with args: -xcconfig,/cordova-project/platforms/ios/cordova/build-debug.xcconfig,-workspace,MyApp.xcworkspace,-scheme,MyApp,-configuration,Debug,-destination,generic/platform=iOS,-archivePath,MyApp.xcarchive,archive,CONFIGURATION_BUILD_DIR=/cordova-project/platforms/ios/build/device,SHARED_PRECOMPS_DIR=/cordova-project/platforms/ios/build/sharedpch
(I can manually run that xcodebuild command and get the same error, so it's probably not a Cordova issue.)
My build.json file looks like this:
{
"ios": {
"debug": {
"codeSignIdentity": "iPhone Developer",
"developmentTeam": "MY_TEAM_ID",
"packageType": "development"
},
"release": {
"codeSignIdentity": "iPhone Developer",
"developmentTeam": "MY_TEAM_ID",
"packageType": "enterprise"
}
}
}
I'm using cordova 7.0.1, cordova-ios 4.4.0, Xcode 8.3.3, and MacOS 10.12.5. I have an Apple Enterprise account.
WHAT I TRIED:
If I open the generated project in Xcode, it fixes the automatic signing, and from then on I can run cordova successfully with that bundle ID. But if I try to run it with a different bundle ID, it will fail again.
I tried using security unlock-keychain ~/Library/Keychains/login.keychain-db first, since that's worked in the past, but it didn't help.
I also tried opening my private signing key in Keychain Access and setting it to "Allow all applications to access this item", without any luck.
I get the same error regardless of whether I pass --debug or --release to cordova.

This isn't directly supported in Xcode 8. In Xcode 9, however, you can pass -allowProvisioningUpdates to xcodebuild and automatic signing will work just as in the Xcode UI, without needing any additional tools.
e.g. cordova run ios --buildFlag="-allowProvisioningUpdates"

Answer is yes. What I used and what I can confirm is working and it is great:
https://fastlane.tools/
You can set up everything to be automatic:
Signing keys
Taking screenshots
Uploading on iTunes
and many other things
In background it is using xcodebuild command line. I was skeptic that something like this is possible, but just set up, start and enjoy.

For Automatically manage signing you can use Fastlane. It's easy to install and setup.
For using it on a remote build server - you can use Jenkins.
Here example. You need to setup Jenkins with Fastlane to your remote machine. Than Jenkins will check your repository thread or just by you command to it. After it Jenkins run Fastlane on remote build server. And Fastlane will create all certificate and other setup that you write in Fastfile.
If you have only one deploy certificate, you can use Fastlane service called Match
Easily sync your certificates and profiles across your team using Git
or just send and setup it locally.
Hope it helps you, good luck!
Here example for beta deploy (for me work with Xcode 9):
desc "Build devFoo and upload it to Fabric"
lane :uploadToFabric do
cocoapods
cert(
development: true,
output_path: "./fastlane"
)
sigh(
development: true,
output_path: "./fastlane"
)
clear_derived_data
gym(
scheme: "Foo",
configuration: "Debug",
clean: true,
output_directory: "./fastlane",
)
crashlytics(
api_token: "foofoofoofoo",
build_secret: "foofoofoofoo",
emails: ["foo#foo.com"],
notifications: true
)
slack(
message: "New build for test successfully deployed in Fabric",
success: true
)
end
Here example for release deploy:
desc "Build and upload it to the AppStore and TestFlight"
lane :uploadToAppStore do
cocoapods
cert(
development: false,
output_path: "./fastlane"
)
sigh(
development: false,
app_identifier: "foofoo",
output_path: "./fastlane"
)
clear_derived_data
gym(
scheme: "Foo",
configuration: "Release",
clean: false,
output_directory: "./fastlane",
)
deliver(
force: true,
app_identifier: "foo",
skip_metadata: true,
skip_screenshots: true,
submit_for_review: false,
skip_binary_upload: false
)
slack(
message: "New build successfully deployed to AppStore",
success: true
)
upload_symbols_to_crashlytics(dsym_path: "./fastlane/foo.app.dSYM.zip")
slack(
message: "dSYM symbolication files uploaded to Crashlytics",
success: true
)

You can do it using fastlane.
https://fastlane.tools/
cert : Fetch or generate the latest available code signing identity
sigh : Generates a provisioning profile. Stores the profile in the current folder
ps : If you are running it from a CI server (for example jenkins) you need then to unlock login keychain :
security unlock-keychain -p PASSWORD /Users/YOUR-USER/Library/Keychains/login.keychain
Example within the fastfile :
cert(
development: true,
)
sigh(
development: true,
app_identifier: "YOUR_APP_IDENTIFIER"
)
Here's an example of a basic Fastfile :
fastlane_version "2.27.0"
default_platform :ios
platform :ios do
lane :beta do
cert
sigh
gym
end
error do |lane, exception|
puts "Got an error! #{exception.error_info.to_s}"
end
end

There is no way to manage signing automatically using xcodebuild. You must either use third parties like Fastlane as mentioned before or use manual code signing as mentioned here.

As some other answers have already mentioned, what you are looking for is a release automation tool called Fastlane. https://fastlane.tools/
If you are not familiar with it, I believe best place to get started would be raywenderlich's fastlane tutorial.
https://www.raywenderlich.com/136168/fastlane-tutorial-getting-started-2

Notice: This answer assumes that bundle ID and provisioning profiles are created manually. Only build process can be automated using this method.
Yes that is possible even without using third party tools. you should be comfortable using script file or a make file. I'm using 2 lines of code in a makefile on Mac Mini at work. And that gives us either ad-hoc or appstore version ready for upload according to our configuration.
make sure your project has enabled automatic configuration.
make sure on your remote mac that all singing certificates and provisioning are downloaded. for this case, I always, for the first building, open Xcode and build & export on my remote machine. If that works then nothing is missing. But make sure that you always allow access to the singing certificate. Xcode also asks this for the first the build. Otherwise a popup will show up on your remote server and waits till someone allows access to the signing certificate.
you need a plist file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>teamID</key>
<string>MY_TEAM_ID_XXYY</string> //put your iPhone distribution team ID. in my case developer team ID is different than my distribution team ID. just wondering.
<key>method</key>
<string>app-store</string> // for appstore upload or use <string>ad-hoc</string> for ad-hoc
<key>uploadSymbols</key>
<true/>
<key>uploadBitcode</key>
<true/>
</dict>
</plist>
You should save plist configuration somewhere accessible, e.g., as options.plist
just a reminder: make sure that you have your ad-hoc/distribution provisioning profile on your remote Mac.
xcodebuild will create an archive then we can export .app. In your make file or script file use these lines:
4.1. First we create the archive file.
xcodebuild archive -derivedDataPath build/ -project myProject.xcodeproj -scheme myScheme -archivePath build/ios/myProject.xcarchive
derivedDataPath parameter is just a folder that can be deleted later after building the app. you know how much junk is produced in derived data.
project name is your project name, and scheme name is right after play|stop button in Xcode. You must choose an archive name and path for the next step.
4.2 After your archive has been built successfully, use this code to create the app:
xcodebuild -exportArchive -archivePath build/ios/myProject.xcarchive -exportPath build/ios/ -exportOptionsPlist build/ios/options.plist
Here you use the archive name and path that was used in previous step. exportOptionsPlist needs to know the path and name for your plist configuration that we created in step 3.
And that's it! You can run these commands in a terminal window it will build your app as well. You can put these 2 line in a script file / makefile and use variables for project name, path and options.plist, Then you can use that to build all of your apps.
PS: If anything is unclear please let me know and I will add more explanation.

As far as my understanding and recent readings, the answer to OP's question:
"Can xcodebuild manage automatic signing?" is "YES" but not as per the OP's expectations in lines of "when you haven't created the app ID or provisioning profile yet, and you want to create it automatically the way Xcode does"
As per this informative blog on xcode8 and automatic code signing, it clearly states that :
"If you want to create for example an App Store signed IPA, on the Mac you have to have both a Wildcard, Team / Development AND the App Store distribution certificates and provisioning profiles!"
Hence, the app ID and provisioning profile wont be auto created. Fastlane may be a workaround to this problem but i guess that is not the OP's expectation. Hope it makes sense.

If you are archiving the xCode project with xcodebuild and you have xCode 9 installed you can provide the following FLAGS to the compilation command:
CODE_SIGN_STYLE="Manual" \
DEVELOPMENT_TEAM="" \
It will set the automatic signing to false and the development team to empty. You can set the values you need. For instance:
xcodebuild \
-scheme "your_scheme" \
-sdk iphoneos \
-archivePath "/Users/youruser/Developer/Jenkins/Home/customWorkspace/folder/platforms/ios/build/device/yourproject.xcarchive" \
-configuration Release \
-allowProvisioningUpdates \
CONFIGURATION_BUILD_DIR="/Users/youruser/Developer/Jenkins/Home/customWorkspace/folder/platforms/ios/build/device" \
CODE_SIGN_IDENTITY="your code sign identity" \
PROVISIONING_PROFILE="your provisioning profile" \
CODE_SIGN_STYLE="Manual" \
DEVELOPMENT_TEAM="" \
archive
Then you can create the ipa with -exportArchive and it will create the ipa as you need

Related

Codemagic iOS Flutter deploy fails on archive

I have a question where and how to add allowProvisioningUpdates in Xcode? My Codemagic account is connected with App Store Connect, bundle id and app are also created.
Build process fails on the app archive, but Xcode build is successfully done.
Can I somehow add allowProvisioningUpdates to this command?
Execute "xcodebuild -workspace /Users/builder/clone/ios/Runner.xcworkspace -scheme Runner -config Release -archivePath build/ios/xcarchive/Runner_1pxkp9aq.xcarchive archive COMPILER_INDEX_STORE_ENABLE=NO"
Every time build process returns me this message after fail:
Error: No profiles for 'com.xxx.xxx' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'com.xxx.xxx'. Automatic signing is disabled and unable to generate a profile. To enable automatic signing, pass -allowProvisioningUpdates to xcodebuild. (in target 'Runner' from project 'Runner')
Do you have some suggestions, on how to resolve this?
Thanks.
The error itself is probably actually unrelated, and adding the flag will not change much.
If you're using .yaml and are trying to set up automatic code signing I would encourage you to add xcode-project use-profiles before your build step.
For automatic .yaml code signing with Flutter iOS the workflow should include:
a) keychain initialize
b) app-store-connect fetch-signing-files "your.bundle.id" --type IOS_APP_STORE --create
If you wish to use development certificate then IOS_APP_DEVELOPMENT as type.
d) keychain add-certificates
e) xcode-project use-profiles
f) flutter build ios
g) xcode-project build-ipa --workspace "ios/Runner.xcworkspace" --scheme "Runner" (change to your workspace and scheme)
In addition you should implement versioning, if you do not want to do it manually for each build.
If you're not using automatic code signing, then you will need to upload your provisioning profile and the process will be a bit different. But the process is somewhat similar, you can take a look at the documentation: https://docs.codemagic.io/code-signing-yaml/signing-ios/

Xcode signing using Jenkins

I am trying to sign and archive my Unity application with Jenkins. I have the Xcode jenkins plugin installed and everything seems to run well except for a strange problem.
During the xcodebuild phase, when the archive should be signed, I get the following error:
error: No signing certificate "iOS Development" found: No "iOS
Development" signing certificate matching team ID "QF6V2M666X" with a
private key was found. (in target 'Unity-iPhone')
Now the problem is that I am not trying to build for development, but for production. I have a production provisioning profile used, which is pointing the production certificate. The team id is the production team id (changed here for security reasons). Here is another part of the build output:
Going to invoke xcodebuild:, scheme: Unity-iPhone, sdk: DEFAULT,
project: DEFAULT, configuration: Release, clean: NO, archive:YES,
consolelog:YES, symRoot: DEFAULT, buildDir: DEFAULT,
developmentTeamID: QF6V2M666X
[sr-ios] $ /usr/bin/xcodebuild -scheme
Unity-iPhone -configuration Release archive -archivePath
When I open the project in Xcode, I can see that for some reason Xcode selects "IOSDeveloper" in the code signing identities part and not "IOSDistribution" (or the actual certificate in the provisioning profile):
I don't know if this can be changed from Jenkins, but I think Xcode should pick this up from the provisioning profile.
So I managed to find the problem and solve it, here is the solution for others.
In Unity 2018 they added a new option to the iOS player settings, in the "Other settings" section, called IOS Provisioning Profile->Profile type:
This option is used to select the signing identity. I guess you can use "Automatic" but in my case, since I am using Jenkins, I am setting it on a build script like this:
PlayerSettings.iOS.iOSManualProvisioningProfileType =
ProvisioningProfileType.Distribution;
When this option is set, xcode is able to sign the app correctly for distribution.

Fastlane cannot find provisioning profile on Bitrise

I'm building an iOS app locally using Fastlane, without any problems.
I'm using match with a separate repo, to keep track of certificates and provisioning profiles.
Locally it works fine.
On Bitrise, however, I get this error:
[05:23:16]: All required keys, certificates and provisioning profiles are installed 🙌
[05:23:16]: Setting Provisioning Profile type to 'app-store'
[05:23:16]: -----------------------
[05:23:16]: --- Step: build_app ---
[05:23:16]: -----------------------
[05:23:16]: $ xcodebuild -list -workspace Myapp.xcworkspace -configuration Debug
[05:23:17]: $ xcodebuild -showBuildSettings -workspace Myapp.xcworkspace -scheme Myapp -configuration Debug
[05:23:20]: Couldn't automatically detect the provisioning profile mapping
[05:23:20]: Since Xcode 9 you need to provide an explicit mapping of what
[05:23:20]: provisioning profile to use for each target of your app
[05:23:20]: No such file or directory # rb_sysopen - /Users/vagrant/git/Pods/Target Support Files/Pods-Myapp/Pods-Myapp.debug.xcconfig
[05:23:20]: Detected provisioning profile mapping: {:"com.myapp.myapp"=>"match AppStore com.myapp.myapp"}
I tried explicitly mapping the provisioning profile in my Fastfile:
lane :beta do
clear_derived_data
increment_build_number
match(app_identifier: "com.myapp.myapp", type: "appstore", clone_branch_directly: true)
build_app(
workspace: "Myapp.xcworkspace",
scheme: "Myapp",
configuration: "Debug",
export_options: {
method: "app-store",
provisioningProfiles: {
"com.myapp.myapp" => "match AppStore com.myapp.myapp"
}
}
)
upload_to_testflight(skip_waiting_for_build_processing: true)
end
Any idea what I need to resolve this?
Part 1: Resolving this and understanding what is happening
In order to reproduce locally / resolve this, I would suggest to disable automatic signing. This way, you will be much closer to your CI/CD configuration. You might locally have access to certificates that allow you to make it work locally. Disabling automatic code signing will show you exactly which certificates your XCode is using. In order to achieve that, you can use the disable_automatic_code_signing command.
disable_automatic_code_signing(
path: "demo-project/demo/demo.xcodeproj"
)
Once this is done, you can go in your local XCode see what profile it is using. This is the first step. I would also suggest to remove all local provisioning profiles from your library. (Much more Closer to Bitrise configuration that does not have any loaded profiles once you start a flow).
The following commands will achieve that:
cd ~/Library/MobileDevice/Provisioning\ Profiles
rm -fr *
Once this is done, it is very likely that it will not allow you to export an archive using the target (and configuration) you want. Hopefully, it will fail locally the same way it is failing remotely. From then you can go in your XCode to see the different provisioning profiles that were downloaded with match and figure out why it is not able to automatically resolve it.
Part 2: an educated guess on what is happening and how to resolve it
My suspicion is that you are trying to code sign with an iPhone Developer code sign identity but the match command you are using retrieves a distribution certificate (iOS Distribution signing identity).
Using automatic signing, XCode is looking for provisioning profiles that match your target and configuration. It attempts to find an iOS Developer certificate, but this is not what you are fetching using match.
A simple solution to this problem (if this is the problem) would be to change the sign identity method before and after you build_app. You can achieve it like this:
automatic_code_signing(
path: "demo.xcodeproj",
code_sign_identity: "iPhone Distribution"
)
Or directly inside your build_app / gym with the code_sign_identity parameter:
build_app(
workspace: "Myapp.xcworkspace",
scheme: "Myapp",
configuration: "Debug",
codesigning_identity: "iPhone Distribution" # or iPhone Developer
)
Since you are using Bitrise, why not use their integrations which can take care of code signing and deployment automatically? I recently moved from Fastlane steps to Bitrise steps. See my answer here: https://stackoverflow.com/a/60836343/1271474

iOS build not showing up for testflight beta testing

I am building the IPA (via fastlane with a distribution profile). The entitlements show beta-reports-active=1:
Upload with the AppLoader is successful - but it's not showing up for testing:
The build shows up under "Activity" though - but showing "Missing Beta Entitlements"
Looking into the build details on iTunes Connect the entitlements seem to be really missing the beta entitlements:
Anyone a clue what I am missing?
The problem was fastlane gym (in my case) creating an IPA that was invalid. I ditched it and are now building through xcodebuild without problems.
Both Payload/*.app/embedded.mobileprovision and codesign -d --entitlements :- Payload/*.app need to have beta-reports-active = 1 set.
That wasn't always the case with gym. See the github issue explaining the details
Without use_legacy_build_api: true gym also has trouble picking the right provisioning profile.
I was having a similar issue, although I think it's the exact same one.
When uploading an app using Pilot or Application Loader, I was able to select the app for external testing, but not for internal testing.
Solution
Use an adhoc distribution provisioning profile.
I've created the following lane to publish an app for internal testing:
lane :internal do |options|
unlock_keychain(path: 'login')
cert(
username: options[:username],
output_path: './fastlane/certs'
)
provisioning_profile = sigh(
username: options[:username],
adhoc: true
)
FileUtils.mkdir_p('www')
sh("cordova build ios --release --device -- --provisioningProfile=#{provisioning_profile}")
pilot(
username: options[:username],
distribute_external: false,
ipa: 'platforms/ios/build/device/<app_name>.ipa'
)
end
Note: Pilot raised an error, but I was still able to select the app for internal testing in iTunes Connect manually.

Issue with building and signing an iOS app with a configurable bundle identifier to support multiple build configurations

I am trying to build multiple concurrent builds of my app (one for mocking environment, one for development environment, one for testing environment, one for production release).
I have gotten very far in getting this working, but am having issues with the codesigning of an app with a auto-generated bundle identifier (one running off a variable).
WHAT I HAVE DONE SO FAR
I am using xCode 4.6.3 using an adhoc provisioning profile.
To attempt to get this to work, I am setting my bundle identifier in the info plist file to somewhat running off a variable - so the app can be signed in different ways.
E.g. my actual bundle identifiers are:
UXXXXXX.au.com.blah.MOCK
UXXXXXX.au.com.blah.DEV
UXXXXXX.au.com.blah.TEST
UXXXXXX.au.com.blah.PROD
Therefore my bundle identifier in my info plist has been configured as "UXXXXXX.au.com.blah.${BUNDLE_SUFFIX}"
Now to allow me to build the app differently for each build, I did the following:
I have 4 different bundle identifiers with 4 different provisioning profiles assigned to those bundle identifiers
To begin with i added a new configuration called "MOCK" (I will add the others in later)
Then under the project build settings I added a BUNDLE_SUFFIX user defined variable to my project and set it to MOCK for the MOCK configuration (I will add the others in later). This is used to set the bundle identifier for a build that uses the MOCK configuration.
Then under the project build settings, selected my MOCK provisioning profile for the MOCK configuration in build settings
I notice if i go to the summary view on my app target it displays the bundle id as UXXXXXX.au.com.blah.MOCK with the 'MOCK' part being in grey font - so it has picked up the bundle suffix variable
Then i created a new scheme called MOCK to use MOCK configuration for 'Profile' and 'Archive'. I left defaults for the rest (uses DEBUG).
So now I can run an xcodebuild and use scheme MOCK to do a MOCK specific build that will use the MOCK configuration to set the bundle identifier to .MOCK and set my provisoning profile to use _MOCK profile.
So i then run a jenkins build which does an xcodebuild and xcrun (which will call codesign).
This is my xcodebuild command:
/usr/bin/xcodebuild -scheme MOCK -sdk iphoneos -project MyApp.xcodeproj -configuration MOCK clean build "CONFIGURATION_BUILD_DIR=/Users/CI/Documents/workspace/build3" ONLY_ACTIVE_ARCH=NO DEPLOY_ENVIRONMENT=MOCK "CODE_SIGN_IDENTITY=iPhone Distribution: My Company" "PROVISIONING_PROFILE=XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
This is my xcrun command:
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "/Users/Shared/Jenkins/Home/jobs/MyApp.app" -o "/Users/Shared/Jenkins/Home/jobs/MyApp/workspace/build/MyApp-0.9.5.0.ipa" --embed "/Users/Shared/Jenkins/Home/Library/MobileDevice/Provisioning Profiles/20130816_Distribution_MOCK.mobileprovision" --sign "iPhone Distribution: My Company"
NOTE: I specifically sign the app with the MOCK provisioning profile, as I worked out that I cannot sign the app with a .* profile, as the app uses push notifications and if I build the app with a .* and then re-sign the app with the proper profile, my embedded.mobileprovision profile gets updated, but the actual executable within the .app file never gets updated. And this causes push notifications to never get to the device. So what i need to get working is the ability to build and sign an app from command line with the app having a bundle id that is populated dynamically using a variable. And I cannot seem to get this working.
THE RESULTS
The xcodebuild runs successfully and works perfectly. The app appears to be built and signed properly as .MOCK and using the _MOCK provisioning profile!
BUT! The generating of the IPA file has an issue, I have an issue with the codesign.
Notice, that I built the app without any code signing entitlements. codesign gives me this error:
warning: Application failed codesign verification. The signature was invalid, contains disallowed entitlements, or it was not signed with an iPhone Distribution Certificate. (-19011)
Executable=/Users/CI/Documents/workspace/build3/MyApp.app/MyApp
codesign_wrapper-4.1: using Apple CA for profile evaluation
Illegal entitlement key/value pair: application-identifier, UXXXXXX.au.com.blah.
AssertMacros: filter_entitlements(entitlements_whitelist, entitlements_requested, allowable_entitlements), file: codesign_wrapper.c, line: 932
- (null
Notice that it has not picked up the bundle_suffix. Also when i view the MyApp.xcent file that codesign references, I notice it has UXXXXXX.au.com.blah. in it. It has not picked up the value of the bundle_suffix!
So then, what i tried is to create an entitlements.plist file for my MOCK build configuration and add a link to the file under 'code signing entitlements' for MOCK configuration under the build settings. But now i get a different error, and its rather disturbing:
/usr/bin/codesign --force --sign 5XXXXXXXXXXXXXXXXXXX2c --resource-rules=/Users/CI/Documents/workspace/build3/MyApp.app/ResourceRules.plist --entitlements /Users/CI/Library/Developer/Xcode/DerivedData/MyApp-fasiktlyysoxjpgalujkfjpyiyeo/Build/Intermediates/MyApp.build/MOCK-iphoneos/MyApp.build/MyApp.xcent /Users/CI/Documents/workspace/build3/MyApp.app
Validate /Users/CI/Documents/workspace/build3/MyApp.app
cd /Users/Shared/Jenkins/Home/jobs/MyApp-MOCK-HourlyBuilds/workspace
setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin"
setenv PRODUCT_TYPE com.apple.product-type.application
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/Validation /Users/CI/Documents/workspace/build3/MyApp.app
warning: This bundle is invalid. The application-identifier entitlement is not formatted correctly; it should contain your 10-character App ID Seed, followed by a dot, followed by your bundle identifier: UXXXXXXXX.au.com.amp.blah.MOCK (-19054)
Unable to validate your application. - (null)
This time is has actually picked up the proper bundle identifier!! It says MOCK it it. But it is complaining that this bundle is invalid... but it looks perfectly valid to me!! Why is it not working?
This is my entitlements.plist file that I manually created and added to the project (and reference in 'code signing entitlements'):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>UXXXXXXXXXXX.au.com.amp.blah.MOCK</string>
<key>aps-environment</key>
<string>production</string>
<key>get-task-allow</key>
<false/>
<key>keychain-access-groups</key>
<array>
<string>UXXXXXXXXXXX.au.com.amp.blah.MOCK</string>
</array>
</dict>
</plist>
Any help would be greatly appeciated, many thanks!
P.S. I know that a way to get around this issue would be to create a different Target for each of my builds. But i dont really want this, as it is a pain maintaining multiple Targets. I really wanted to try and get away with this without having multiple Targets if I can.
P.S.S. I know another way to get around this issue is to sign the app initially with a .* provisioning profile and then resign the app after with the proper profile, however this does not work for me. As the executable file within .app still keeps references to the .* provisioning profile. And thus push notifications can never be picked up by this device. I get the “no valid 'aps-environment' entitlement string found for application” error.
I am running a similar setup for my iOS builds via Jenkins, with the goal of allowing side-by-side installation of the app (production, staging, qa, dev) and ran into the same problem as you.
In the end, I stumbled upon this answer and modified it to include the .xcent file which is part of the xcodebuild (check build output for the path) for the --entitlements flag. This means you do not have to manually create the entitlements file, but can use the exact one xcodebuild produces for you.
I too was using xcrun PackageApplication, but this does NOT support entitlements so re-signing using this tool would lose the entitlements.
So, after running xcodebuild I use plistbuddy to modify my info.plist file to update the settings bundle, etc. (this may not be required for you) and I unpack the ipa, copy the profile and info.plist into the unpacked payload, re-sign and re-pack:
pushd ${SCRIPT_DIR}
unzip "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa"
rm -r "Payload/${PROJECT_NAME}.app/_CodeSignature" "Payload/${PROJECT_NAME}.app/CodeResources" 2> /dev/null | true
cp "${PROFILE}" "Payload/${PROJECT_NAME}.app/embedded.mobileprovision"
cp "${BUILD_DIR}/${BUILD_TARGET}-iphoneos/${PROJECT_NAME}.app/Info.plist" "Payload/Yappem.app/Info.plist"
/usr/bin/codesign -f -s "${CODE_SIGN_IDENTITY}" --resource-rules "Payload/${PROJECT_NAME}.app/ResourceRules.plist" --entitlements "${XCENT_FILE}" "Payload/${PROJECT_NAME}.app"
if [ $? != 0 ]; then
echo Error Signing Project
exit 1
fi
rm "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa"
zip -qr "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa" Payload
popd

Resources