akofman / cordova-plugin-add-swift-support

:hammer: Swiftify your Cordova app !
MIT License
117 stars 110 forks source link

App Store: invalid swift support #4

Closed genox closed 8 years ago

genox commented 8 years ago

Hi

Got this message after uploading with application loader:

Invalid Swift Support - The SwiftSupport folder is missing. Rebuild your app using the current public (GM) version of Xcode and resubmit it.


I don't know how to fix this error. I'm using ionic package service to manage and build the app. Editing project properties is not possible this way.

Any hints would be greatly appreciated. Thanks!

akofman commented 8 years ago

Hello :)

I'm not an expert of ionic, but I guess it uses xcode to build your app and maybe you don't have the last version of xcode. Did you try to update it recently ? What version do you have ?

genox commented 8 years ago

Hey there,

Well it's a bit more complicated than that. Ionic is providing a cloud build service. Not sure which version they are using. But when I generate an Xcode project for local builds, Xcode complains about the Swift Syntax the plugin is using (old syntax version) and doesn't build at all. (ed: the syntax of the plugin needing swift support, not yours)

I'm trying to include this plugin: https://github.com/becvert/cordova-plugin-zeroconf with Swift support added by yours. Swift - well I can't say I ever really got into it, but so far it JustWorked(tm). Everything except submitting to the app store.

It's always the details. :)

akofman commented 8 years ago

Hmmm, and when you say it worked, it doesn't work since when ?

akofman commented 8 years ago

Ok everything works except submitting, I didn't read well. And even if you get errors from xcode for your local build you managed to deploy on a device ? Or is it just warnings ?

genox commented 8 years ago

That's the thing: It's the first time I tried to submit this app to the App Store.

While the plugin does what it is supposed to do, submitting fails. It never stopped working functionally. Hard to pinpoint any particular reason other than the message I get from Apple.

Am 06.06.2016 um 17:24 schrieb Alexis Kofman notifications@github.com:

Hmmm, and when you say it worked, it doesn't work since when ?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

akofman commented 8 years ago

Weird ... Could you check if the EMBEDDED_CONTENT_CONTAINS_SWIFT flag is well configured to YES ?

genox commented 8 years ago

I never built it locally prior to when I got the error from Apple. That's when I tried local builds and got a build error. Now my guess is that ionic uses an old Xcode version. That's why it builds but apple complains about versions. I posted an issue over there as well.

But I can't figure out what the swift syntax error is that Xcode complains about. Don't know enough about swift and Xcode. Looks like an issue to drop over at the zeroconf plugin.

It probably has nothing to do with your plugin. :)

Am 06.06.2016 um 17:44 schrieb Alexis Kofman notifications@github.com:

Ok everything works except submitting, I didn't read well. And even of you get errors from xcode for your local build you managed to deploy on a device ? Or is it just warnings ?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

genox commented 8 years ago

I have to contact the ionic people. I can't access the full build log, only when it fails. The build doesn't fail however...

Could be that their build processor handles some things different than Cordova does locally.

Am 06.06.2016 um 17:47 schrieb Alexis Kofman notifications@github.com:

Weird ... Could you check if the EMBEDDED_CONTENT_CONTAINS_SWIFT flag is well configured to YES ?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

akofman commented 8 years ago

I don't think so. I think this is just a wrapper of Cordova commands for this part. I will try later to test this plugin and check if I find something. What version of ionic are you using ?

genox commented 8 years ago

I use Ionic current CLI.

Here's the first few outputs of a local build using cordova build:

cordova build ios --device --release Reading build config file: Building project : ......xcodeproj Configuration : Release Platform : device Build settings from command line: ARCHS = armv7 arm64 CONFIGURATION_BUILD_DIR = .../cordova/platforms/ios/build/device SDKROOT = iphoneos9.3 SHARED_PRECOMPS_DIR =..../cordova/platforms/ios/build/sharedpch VALID_ARCHS = armv7 arm64

Build settings from configuration file '..../cordova/platforms/ios/cordova/build-release.xcconfig': CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES CODE_SIGN_IDENTITY = iPhone Distribution ENABLE_BITCODE = NO HEADER_SEARCH_PATHS = "$(TARGET_BUILD_DIR)/usr/local/lib/include" "$(OBJROOT)/UninstalledProducts/include" "$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include" "$(BUILT_PRODUCTS_DIR)" IPHONEOS_DEPLOYMENT_TARGET = 8.0 OTHER_LDFLAGS = -ObjC PROVISIONING_PROFILE = 189625ed-6c03-41bc-8179-5dba9f2f2e85 SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h TARGETED_DEVICE_FAMILY = 1,2

Should EMBEDDED_CONTENT_CONTAINS_SWIFT be part of this settings list?

$ cordova --version 6.2.0 $ ionic --version 1.7.15

genox commented 8 years ago

When I look at the xcode project file after running "cordova build ios --device --release", I see that the settings haven't been picked up correctly:

Embedded Content Contains Swift Code :: No

Bridging header seems to be correct, tho.

akofman commented 8 years ago

Yep it should be configured to YES, looks like you pointed the issue.

genox commented 8 years ago

I finally managed to build an IPA that is accepted by the App Store and was able to distribute it using Test Flight. Now the app crashes 500ms after loading, not reproduceable on the simulators, nor with the debug profiles. No crash logs. Once I remove everything Swift related, the App works with binaries signed for distribution even on Test Flight.

Not sure where to go from here other than to skip Swift alltogether for now. It seems to be a classy YMMV.

akofman commented 8 years ago

Wow, so it crashes only from TestFlight ??

mhartington commented 8 years ago

Just chiming in, what seems to be the issue?

genox commented 8 years ago

I need to tackle this in a reproduceable way since the problem literally could be anything.

Yes, in fact debug release (debug key, provisioning) always work.

Here's what I observed:

1) current Cordova does not set EMBEDDED_CONTENT_CONTAINS_SWIFT to yes, even locally, when running a build. Why this still allows the debug release to work - I don't know.

2) without this flag set, the build doesn't pass the automated testing on iTunes connect and I get an email telling me to install a newer Xcode version.

3) if it's not set locally, it won't be set on a remote build service like ionic IO or phone gap either. That's the or origin of why I'm here I the first place :-)

4) setting the flag to yes locally and building locally works, as well as submitting to iTunes connect and passing the tests. But once deployed on a device and opened, it insta-crashes.

5) the swift zeroconf plugin causes Xcode to mention that it has outdated syntax. But if declining an auto-update of the code, it compiles just fine. Auto updating the code doesn't work tho - who would have thought..

So there's many different factors and it's hard to pinpoint anything specific.

Which leads me to believe that this might have also something to do with code signing or the deployment target version. if I remember correctly, there's a difference in the way that a distribution release has to bundle and sign binaries depending on the deployment target of 8.0 vs 9.0.

genox commented 8 years ago

Sorry, should not be closed. 2 buttons: 50:50 chance of FAIL. :-P

genox commented 8 years ago

Reopening

genox commented 8 years ago

The method you use to add the EMBEDDED_CONTENT_CONTAINS_SWIFT flag should save the flag to build.xcconfig, correct?

But the settings never end up there. Not only the changes from within your plugin, but also config.xml changes are not updating this file.

For example, when I set the build deployment-target to 9.0 in config.xml and the device-family to handset and run "cordova prepare", the build.xcconfig doesn't pick up the new value, neither do build-debug.xcconfig or any of the other .xcconfig files, nor xcodeproj. Deployment target is still 8.0 ("IPHONEOS_DEPLOYMENT_TARGET = 8.0") and device family is still both handset and tablet ("TARGETED_DEVICE_FAMILY = 1,2").

So basically, every build is running with cordova's default settings.

genox commented 8 years ago

I opened a ticket over at Cordova about preferences in config.xml not being picked up. Not sure if this is related, tho.

https://issues.apache.org/jira/browse/CB-11399

akofman commented 8 years ago

Ok maybe this plugin is not really applied in your case. You should have some logs after adding your platform :

Importing your-Bridging-Header.h into /path/to/your/app/Bridging-Header.h
Update IOS build setting EMBEDDED_CONTENT_CONTAINS_SWIFT to: YES

Could you just test the last version (1.1.0) I published this morning. Now the hook is applied after the project is prepared and not after adding the platform. Maybe it causes some issues in your case. Concerning your config.xml updates, could you show me your whole file in order to check ?

genox commented 8 years ago

Actually, I got a build working just now and was able to deploy it via TestFlight and it doesn't crash. I didn't use cordova-plugin-add-swift-support and I had to use XCode>Product>Archive.

When I use build target 8.0, the app gets accepted but crashes on the device. Only works with 9.0. And 9.0 distribution targets can not be built using "cordova build ios --device --release" since cordova doesn't know about teamID etc which is required for signing those binaries. This puts Cordova + Swift between a rock and a hard place.

Also, for some reason a debug build does in fact work when built using cordova, even though the cordova libraries are not bundled when using xcodebuild (which is what cordova uses) inside the IPA.

In regards to the config.xml file, I just have these that should make a difference but don't:

    <preference name="target-device" value="handset"/>
    <preference name="deployment-target" value="9.0"/>

But according to the docs, this should work fine.

akofman commented 8 years ago

Sounds crazy.

The deployment target setting specifies the lowest operating system version that your app can run on. So configuring it to 9 you can't launch your app on an ios 8 device anymore. It's too bad. Really weird you cannot reproduce this issue from your local env.

genox commented 8 years ago

Hi Alexis,

Here's the ouput I get from a local "cordova build ios --device --release":

Reading build config file:
Building project  : /Users/os/_code/cp6/cordova/platforms/ios/NEEO.xcodeproj
    Configuration : Release
    Platform      : device
Build settings from command line:
    ARCHS = armv7 arm64
    CONFIGURATION_BUILD_DIR = /Users/os/_code/cp6/cordova/platforms/ios/build/device
    SDKROOT = iphoneos9.3
    SHARED_PRECOMPS_DIR = /Users/os/_code/cp6/cordova/platforms/ios/build/sharedpch
    VALID_ARCHS = armv7 arm64

Build settings from configuration file '/Users/os/_code/cp6/cordova/platforms/ios/cordova/build-release.xcconfig':
    CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES
    CODE_SIGN_IDENTITY = iPhone Distribution
    ENABLE_BITCODE = NO
    HEADER_SEARCH_PATHS = "$(TARGET_BUILD_DIR)/usr/local/lib/include" "$(OBJROOT)/UninstalledProducts/include" "$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include" "$(BUILT_PRODUCTS_DIR)"
    IPHONEOS_DEPLOYMENT_TARGET = 8.0
    OTHER_LDFLAGS = -ObjC
    PROVISIONING_PROFILE = 189625ed-6c03-41bc-8179-5dba9f2f2e85
    SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h
    TARGETED_DEVICE_FAMILY = 1,2

As you can see the settings from your plugin have not been applied and cordova doesn't take into account config.xml settings.

The resulting IPA file from cordova's build (using CLI build tools from xcode) does not contain the swift libraries. It should be at least 3-4MB bigger.

When I run the same build within Xcode GUI ("Archive") and check project settings to include the necessary options, the resulting IPA is larger (including swift libraries) and passes the automated iTunes Connect checks.

This seems to be really related to a) cordova hooks not firing and config.xml settings beign ignored anyways, b) xcode build tools not including swift libraries when building from CLI.

BTW: cordova adds SWIFT_OBJC_BRIDGING_HEADER by default now in build.xcconfig

Can your changes be run pre-build instead of after installing the plugin? Is there such a hook in cordova? ionic platform seems to not run the hooks either due to the way they handle app state / configs.

akofman commented 8 years ago

Hello @genox,

I did some updates around hooks in the last version 1.3.1, could you have a try ?

genox commented 8 years ago

I removed the plugins, both cordova-plugin-zeroconf and cordova-plugin-add-swift-support and readded zeroconf which nows links yours as a dependency.

Output is:

mbnox:cordova os$ cordova plugin add cordova-plugin-zeroconf
Fetching plugin "cordova-plugin-zeroconf" via npm
Installing "cordova-plugin-zeroconf" for android
Fetching plugin "https://github.com/akofman/cordova-plugin-add-swift-support" via git clone
Repository "https://github.com/akofman/cordova-plugin-add-swift-support" checked out to git ref "master".
Installing "cordova-plugin-add-swift-support" for android
Installing "cordova-plugin-zeroconf" for ios
Installing "cordova-plugin-add-swift-support" for ios

I only get

Update IOS build setting SWIFT_OBJC_BRIDGING_HEADER to: "$(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h" "$(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h"
Importing ZeroConf-Bridging-Header.h into /Users/os/_code/cp6/cordova/platforms/ios/NEEO/Bridging-Header.h
Update IOS build setting EMBEDDED_CONTENT_CONTAINS_SWIFT to: YES

When completely resetting the project ("ionic state reset"), which essentially deletes all platforms and plugins and reinstalls based on it's package.json definitions.

However, after resetting the project, when I start a CLI build, config options are still missing, even with the output present like above:

mbnox:cordova os$ cordova build ios --device --release
Reading build config file:
Building project  : /Users/os/_code/cp6/cordova/platforms/ios/NEEO.xcodeproj
    Configuration : Release
    Platform      : device
Build settings from command line:
    ARCHS = armv7 arm64
    CONFIGURATION_BUILD_DIR = /Users/os/_code/cp6/cordova/platforms/ios/build/device
    SDKROOT = iphoneos9.3
    SHARED_PRECOMPS_DIR = /Users/os/_code/cp6/cordova/platforms/ios/build/sharedpch
    VALID_ARCHS = armv7 arm64

Build settings from configuration file '/Users/os/_code/cp6/cordova/platforms/ios/cordova/build-release.xcconfig':
    CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES
    CODE_SIGN_IDENTITY = iPhone Distribution
    ENABLE_BITCODE = NO
    HEADER_SEARCH_PATHS = "$(TARGET_BUILD_DIR)/usr/local/lib/include" "$(OBJROOT)/UninstalledProducts/include" "$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include" "$(BUILT_PRODUCTS_DIR)"
    IPHONEOS_DEPLOYMENT_TARGET = 8.0
    OTHER_LDFLAGS = -ObjC
    PROVISIONING_PROFILE = 189625ed-6c03-41bc-8179-5dba9f2f2e85
    SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h
    TARGETED_DEVICE_FAMILY = 1,2

However, there are new lines in build.xcconfig:

// (CB-10072) (default from cordova)
SWIFT_OBJC_BRIDGING_HEADER = $(PROJECT_DIR)/$(PROJECT_NAME)/Bridging-Header.h

EMBEDDED_CODE_CONTAINS_SWIFT = YES
LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks

But they are not being picked up on "cordova build ios --device --release". I suspect that this is a cordova issue.

Here's all the bridging header files in the project:

mbnox:cordova os$ find . -name "*-Header.h"
./platforms/ios/NEEO/Bridging-Header.h
./platforms/ios/NEEO/Plugins/cordova-plugin-zeroconf/ZeroConf-Bridging-Header.h
./plugins/cordova-plugin-zeroconf/src/ios/ZeroConf-Bridging-Header.h

First one includes the plugin's header:

#import <Cordova/CDV.h>
#import "ZeroConf-Bridging-Header.h"
mbnox:cordova os$ cordova --version
6.2.0

mbnox:cordova os$ xcodebuild -version
Xcode 7.3.1
Build version 7D1014

mbnox:cordova os$ ionic --version
1.7.15
becvert commented 8 years ago

Hello. Please allow me to may drop a few words...

This plugin writes the config options into project.pbxproj not build.xcconfig file. I believe only cordova cli uses build.xcconfig (and configuration-level files such as build-release.xcconfig...). and build.xcconfig only overrides project.pbxproj options I think.

if the next lines are missing from the log output of the cli build it does probably not matter:

EMBEDDED_CODE_CONTAINS_SWIFT = YES
LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks 

by the way, when I add these new lines to build.xcconfig they are present in the output of cordova build ios --device --release

For me, as far as I can tell, this plugin does its job.

The issue is with the CLI and maybe codesigning... I do have a codesign issue with copySwiftLibs running cordova build ios --device --release locally

genox commented 8 years ago

Unfortunately I'm not able to pinpoint any specifics. All I know is that debug releases work and can be built locally and on build platforms such as ionic. But release builds only work when "archived" via Xcode. Xcode picks up the changes build config either via project file or the .xcconfig (the plugin only writes to xcconfig IIRC), so it's not the plugins fault.

I can certainly live with this and I by no means blame this plugin for it but since the whole thing is one huge process involving multiple moving parts, someone with a similar problem evidently will end up here first because the symptom points to it.

So we will see, I guess.

akofman commented 8 years ago

Closing since I think #13 fixes this.