Nativescript-cli: iOS Archive Export unexpected behavior when using AdHoc or AppStore provisioning

Created on 31 Jul 2017  Â·  12Comments  Â·  Source: NativeScript/nativescript-cli

From Xcode 8.3+ the way IPA is built changed.
The generation of the IPA is a two step process now:

  1. xcodebuild archive
  2. xcodebuild 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:

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:
https://github.com/NativeScript/nativescript-cli/blob/1955028ac3ded6a012813476f08d0f4f0d89dddd/lib/services/ios-project-service.ts#L259-L263
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:
https://github.com/NativeScript/nativescript-cli/blob/1955028ac3ded6a012813476f08d0f4f0d89dddd/lib/services/ios-project-service.ts#L212-L229
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.

ios code signing

Most helpful comment

Hi,
@PeterStaev @sis0k0 @tjvantoll @pkoleva @etabakov
Please lead the discussion of similar issues to here.

All 12 comments

Hi,
@PeterStaev @sis0k0 @tjvantoll @pkoleva @etabakov
Please lead the discussion of similar issues to here.

@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 to development and users can change that when running tns build ios to the above mentioned options supported by xcodebuild

I definitely agree that we should avoid tns archive and tns export.

And I also agree with @PeterStaev. If I’m using a distribution provisioning profile, then I’m definitely going to want a method of app-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 method in your Info.plist, and it’s really really frustrating to run into problems like this when you’re ready to get your apps in the stores.

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.

@PanayotCankov , isn't it possible first to build the .app file, then extract the embedded.mobileprovision file from it, parse it using the other tool, find what type of provisioning was used and then use the correct parameter when invoking xcodebuild to archive & export the .ipa?

@tjvantoll I disagree with the view that distribution profiles should be presumed to use the app-store method, everyone has different use cases. It's ok as a default, but it shouldn't be forced/hardcoded.

We can read the method from exportOptions.plist no?

p.s. This would be a really good time to implement #2679. We don't want to go through something like this again, my iOS builds have literally stopped because of this.

@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.

We have implemented the --provision so you can manage development provisioning profiles and certificates during development with the CLI. For distribution tns publish ios is 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 ios was intended for this exact reason - create a truly naive project that can then be used with Xcode for debugging, published using Xcode, xcodebuild can 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 using tns build. Doesn't Xcode or fastlane work after tns prepare ios --release?

@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.

@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.

@rosen-vladimirov @PeterStaev Edit: Took this for a spin and it works great, except that --copy-to does not copy the IPA when using --for-device

@vbresults I can not reproduce issue with --copy-to on 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?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NickIliev picture NickIliev  Â·  3Comments

farfromrefug picture farfromrefug  Â·  3Comments

ZMW9 picture ZMW9  Â·  3Comments

NickIliev picture NickIliev  Â·  3Comments

erjdriver picture erjdriver  Â·  3Comments