Repository navigation
Description
From Xcode 8.3+ the way IPA is built changed.
The generation of the IPA is a two step process now:
xcodebuild archivexcodebuild export
Archive
This makes an archive folder that has app, debug symbols, etc. It has all the artefacts necessary to export for Development, Ad-Hoc or App Store distribution. The app is signed with the certificate and provisioning profiles set in the .xcconfig or in the xcodeproj (using the --provision option).
Export
This takes the archive and exports IPA for Development, Ad-Hoc or AppStore. During the export, the app is often resigned with a distribution certificate and an ad-hoc or AppStore distribution provisioning profile.
Problems
Currently the CLI does archive then export for development when tns build|run is issued. This leads to underwhelming results when developers try to publish at the store or export for ad-hoc using tns build. Why? During the export session the xcodebuild command accepts an -exportOptionsPlist that can contain keys listed in xcodebuild --help. Most importantly the: method : String:
Describes how Xcode should export the archive. Available options: app-store, package, ad-hoc, enterprise, development, and developer-id. The list of options varies based on the type of archive. Defaults to development.
The default is "development", for exportOptionsPlist currently the app/App_Resources/Info.plist is currently provided (IMO incorrectly) and it has no method key, so development is used as fallback. When the developers configure the .xcconfig to use Ad-Hoc or AppStore provisioning profile, the export is still performed as development, the result IPA is then incorrectly set to still use development settings such as entitlements.
Here are the related issues to exactly this problem:
- Build in release mode for iOS doesn't seem to set the production mode for APN #2888
- iOS Archive does not respect release flag #2999
(perhaps incorrectly?) tries to provide distribution certificate for archive, while archive should be performed with development certificate and export should sign with distribution certificate - Unable to tns publish ios #2922
Signes multitarget app with the AppStore distribution, there is a bug in old Ruby and Cocoapods that leads to this - Build in release mode for iOS doesn't seem to set the production mode for APN #2888
Building with --release as mentioned still exports with method: development - Web pack issues when build in release mode #2716
- EXPORT FAILED xcode 8.3 #2702
Similar to 2922 - resolved by ruby and cocoapods update but also the missing exportOptionsPlist is noted in warnings
We have discussed internally that adding tns archive + tns export would diverge too much from the current and Android build commands, also people shouldn't care how the build is implemented internally.
Here are some clues how this can be addressed:
The export during tns build ios is done here:
nativescript-cli/lib/services/ios-project-service.ts
Lines 259 to 263 in 1955028
| let args = ["-exportArchive", | |
| "-archivePath", archivePath, | |
| "-exportPath", exportPath, | |
| "-exportOptionsPlist", platformData.configurationFilePath | |
| ]; |
It incorrectly gets the app/App_Resources/Info.plist as exportOptionsPlist. Instead such export.plist files should be generated somewhere in the platforms/ios/build similar to the exportArchive that is currently used only for distribution:
nativescript-cli/lib/services/ios-project-service.ts
Lines 212 to 229 in 1955028
| let plistTemplate = `<?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> | |
| `; | |
| if (options && options.teamID) { | |
| plistTemplate += ` <key>teamID</key> | |
| <string>${options.teamID}</string> | |
| `; | |
| } | |
| plistTemplate += ` <key>method</key> | |
| <string>app-store</string> | |
| <key>uploadBitcode</key> | |
| <false/> | |
| <key>uploadSymbols</key> | |
| <false/> | |
| </dict> | |
| </plist>`; |
The method - Ad-Hoc or AppStore distribution that should be used during
tns build ios should either be provided through an option, or inferred from the provisioning profile used during the build.
Activity
PanayotCankov commentedon Jul 31, 2017
Hi,
@PeterStaev @sis0k0 @tjvantoll @pkoleva @etabakov
Please lead the discussion of similar issues to here.
PeterStaev commentedon Jul 31, 2017
@PanayotCankov , if possible, I think the best solution is to use the type of the provision profile that is being used. This way users will not have to duplicate settings and keep them in sync.
If reading the profile and detecting the type automatically from the provision profile is not possible, then I guess a new iOS specific option could be added (for example
--export-for) that defaults todevelopmentand users can change that when runningtns build iosto the above mentioned options supported byxcodebuildtjvantoll commentedon Jul 31, 2017
I definitely agree that we should avoid
tns archiveandtns export.And I also agree with @PeterStaev. If I’m using a distribution provisioning profile, then I’m definitely going to want a
methodofapp-store.Overall, I just want to make sure that whatever way forward we pick that we document the steps well. Right now there’s nothing on the {N} docs about providing a
methodin yourInfo.plist, and it’s really really frustrating to run into problems like this when you’re ready to get your apps in the stores.PanayotCankov commentedon Jul 31, 2017
We do have implemented a way to read a provisioning profile by id, or all provisioning profiles and find one by identifier. The logic is kept in https://github.com/NativeScript/ios-mobileprovision-finder so it doesn't mess badly with the rest of the services in the CLI. If the provision is specified using --provision or it is stored in the xcodeproj it should be easy to find its type.
If the provision is stored in .xcconfig we currently parse some possible options for provision but with the [config=debug] filters for example we still fail.
PeterStaev commentedon Aug 1, 2017
@PanayotCankov , isn't it possible first to build the
.appfile, then extract theembedded.mobileprovisionfile from it, parse it using the other tool, find what type of provisioning was used and then use the correct parameter when invokingxcodebuildto archive & export the.ipa?tjvantoll commentedon Aug 1, 2017
@vbresults Fair point. I trust the judgement of everyone else in this thread far more than I do myself as I don’t have a ton of iOS deployment experience.
My goal here is simplicity. We already have an eclectic set of flags that I personally only use for distribution builds—
--release,--for-device,--provision—and I’d hate to see that list grow. Most NativeScript users don’t want a lot of options, they just want to know how to get their apps in the stores.PanayotCankov commentedon Aug 1, 2017
We have implemented the
--provisionso you can manage development provisioning profiles and certificates during development with the CLI. For distributiontns publish iosis used internally to publish to the store. I don't think we can support every possible scenario in the CLI and the extra effort to support updates after native tooling won't be rewarding enough.tns prepare ioswas intended for this exact reason - create a truly naive project that can then be used with Xcode for debugging, published using Xcode,xcodebuildcan be applied on it as well as the fastlane should be possible to export ipa for ad-hoc distribution. I don't know why developers even try to extract ipa for ad-hoc distribution usingtns build. Doesn't Xcode or fastlane work aftertns prepare ios --release?PeterStaev commentedon Aug 1, 2017
@PanayotCankov I disagree on your point that users should use XCode to generate the IPA. You could say the same for the Android - why have all the
-key-*options when users can open the prepared project in Android Studio and manage the signing/apk generation there.I'm expecting if I use the CLI to build a project to also be able to use the CLI to generate an IPA ready to upload - either to the App Store, or to users using AdHoc / Enterprise provisioning.
PanayotCankov commentedon Aug 2, 2017
@PeterStaev - I used "could", not "must". Users can use the native project. As in if the CLI doesn't support something yet, users should be able to (not blocked by things I'd consider bugs) use other tools to complete their work.
On the other hand I already explained what could be the fix for building ad-hoc and App Store distribution IPAs.
Lets lock the discussion for a while. I think we are on the same page. It is up to planning now.
fixes NativeScript#3020
fixes #3020
Fix IPA export (#3036)
dtopuzov commentedon Aug 14, 2017
@vbresults I can not reproduce issue with
--copy-toon my machine.Can you specify exact command you run, Xcode version and provide logs of
--copy-to?Does it works if you build without
--provision?Update production with master to update the setup scripts (#3112)