RevenueCat / react-native-purchases

React Native in-app purchases and subscriptions made easy. Support for iOS and Android.
https://www.revenuecat.com
MIT License
766 stars 84 forks source link

Unable to build PurchasesHybridCommon #200

Closed CouplenessTech closed 3 years ago

CouplenessTech commented 3 years ago

Describe the bug

Production build of the app fails with the following error:

could not build Objective-C module 'PurchasesHybridCommon'

with the underlying error:

/ios/Pods/PurchasesHybridCommon/ios/PurchasesHybridCommon/PurchasesHybridCommon/RCPurchases+HybridAdditions.h:12:12: error: declaration of 'RCPurchases' must be imported from module 'Purchases' before it is required

Context Platform: Azure DevOps Hosted Pool (macos-10.15) SDK: react-native-purchases@4.0.0 (latest) Software: XCode 12.2

Details Building using the command line: /xcodebuild -sdk iphoneos -configuration Release -workspace /ios/XX.xcworkspace -scheme XX build CODE_SIGN_STYLE=Manual CODE_SIGN_IDENTITY=iPhone Distribution: XX (XX) PROVISIONING_PROFILE=XX PROVISIONING_PROFILE_SPECIFIER=

aboedo commented 3 years ago

hi! thanks for reporting.

The problem seems to be when installing the pod. I've seen some weird behavior with cocoapods when there's some leftover cached data... Could you try:

And seeing if that fixes it, or the error message changes?

CouplenessTech commented 3 years ago

Hi, thanks for quick response.

Yes the build server is currently cleaning the cache. Although the error message says "declaration of 'RCPurchases' must be imported from module 'Purchases' before it is required" which indicates an actual error in the SDK. Still hoping cleaning the pod cache will resolve the issue though.

aboedo commented 3 years ago

I've seen that error before and it could be related to a few things, sometimes caching, sometimes having Enable Modules set to NO, or messing with the framework search paths, which would all make the module Purchases not available for lookup when compiling. If cleaning up the cache does not solve it, it might be related to something else, but very likely a linking issue. Out of curiosity, does this also happen when building locally? Are you building Release or Debug?

CouplenessTech commented 3 years ago

Cleaning the cache did not help on the build server. It builds locally with Debug build and XCode 12.3 but not Release and Xcode 12.2. The build server was able to build the app before upgrading the RevenueCat SDK, which was the only change, upgrade from 3.4.2 to 4.0.0.

Not familiar with Enable Modules but we are using other modules than react-native-purchases.

tarouboy commented 3 years ago

+1 couldn't build / archive after upgrading to Xcode Version 12.3 Error: Declaration of 'RCPurchases' must be imported from module 'Purchases'

Update: Able to build after pod cache clean --all but not able to Archive. I have to re-install the whole package, clean the build folder then finally able to archive.

CouplenessTech commented 3 years ago

Still unable to build, which hinders us from enabling the new purchase flow SCA (new EU legislation), major issue.

Have tried multiple things, including:

Still the same error.

@tarouboy what did you do to make it work?

@aboedo any thoughts?

aboedo commented 3 years ago

@CouplenessTech I haven't been able to reproduce yet, I'm not sure exactly how to do it. A couple of clarifications in the meantime: This shouldn't stop you from being compatible with SCA:

As for root causes for this:

Since it was working for you on 3.4.2, maybe re-enabling static linking for the pod would help.

i.e.:

use_frameworks! :linkage => :static
...
pod 'RNPurchases', :path => '../node_modules/react-native-purchases'

Let me know if that helps!

CouplenessTech commented 3 years ago

RevenueCat SDK 3.4.2 only returns Unknown Error when SCA is initiated, therefore we cannot know if there actually was an unknown error or that the user have initiated SCA. Purchases.purchasePackage(...) does not give any information of pending or cancelled, only throws the Unknown Error.

Our users are unable to complete SCA. They accept everything during the bank webpage authentication but no subscription is registered within RevenueCat, looking at the RevenueCat dashboard, and no app subscription is registered on the users Apple ID / Google account.

We do not use use_frameworks! and haven't had the need for declaring any pods in the Podfile, except a couple from react-native-permissions, the rest are auto-linked. Here is our Podfile:

$deployment_target = '10.0'
platform :ios, $deployment_target
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'Coupleness' do
  config = use_native_modules!
  use_react_native!(:path => config["reactNativePath"])

  permissions_path = '../node_modules/react-native-permissions/ios'
  pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts.podspec"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary.podspec"

  def set_deployment_target_for_all_pods(installer)
    installer.pods_project.targets.each do |t|
      t.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $deployment_target
      end
    end
  end

  target 'CouplenessTests' do
    inherit! :complete
    # Pods for testing
  end

  use_native_modules!

  # Enables Flipper and forces correct version of pods
  use_flipper!
  post_install do |installer|
    flipper_post_install(installer)
    set_deployment_target_for_all_pods(installer)
  end
end

As a part of React Natives own upgrade guide, we removed use_frameworks! long ago. Currently we are using React Native 0.63.3. Do you still suggest that we add both use_frameworks! and pod 'RNPurchases', :path => '../node_modules/react-native-purchases'?

aboedo commented 3 years ago

I'm a bit confused about the podfile... Do you have the plugin installed through cocoapods or through the manual install path? I'm asking because I don't see an entry for RNPurchases, but I assumed you had RNPurchases installed through cocoapods, which may have been a wrong assumption

CouplenessTech commented 3 years ago

We followed your installation guide a few months ago. use_native_modules! enables auto-linking, thus we do not need to specify every pod in the podfile, React Native takes care of it. We are using several other Pods, including AppsFlyerFramework and RNPermissions etc. Every plugin is installed using standard npm i [plugin] and rare cases need some extra config, e.g. react-native-permissions needed the three lines shown in the podfile above.

CouplenessTech commented 3 years ago

Using Cocoapods: 1.10.0 (from podfile.lock)

CouplenessTech commented 3 years ago

I tried adding pod 'RNPurchases', :path => '../node_modules/react-native-purchases', no change in error message.

I tried adding both use_frameworks! :linkage => :static and pod 'RNPurchases', :path => '../node_modules/react-native-purchases', resulted in multiple new errors, here comes some of them:

2021-01-12T17:45:10.9968880Z Build system information 2021-01-12T17:45:10.9986540Z warning: Multiple targets match implicit dependency for linker flags '-framework DoubleConversion'. Consider adding an explicit dependency on the intended target to resolve this ambiguity. (in target 'Coupleness' from project 'Coupleness') 2021-01-12T17:45:10.9988300Z 2021-01-12T17:45:10.9989000Z Build system information 2021-01-12T17:45:10.9990580Z warning: Multiple targets match implicit dependency for linker flags '-framework folly'. Consider adding an explicit dependency on the intended target to resolve this ambiguity. (in target 'Coupleness' from project 'Coupleness') 2021-01-12T17:45:10.9991620Z 2021-01-12T17:45:10.9992220Z Build system information 2021-01-12T17:45:10.9993790Z warning: Multiple targets match implicit dependency for linker flags '-framework glog'. Consider adding an explicit dependency on the intended target to resolve this ambiguity. (in target 'Coupleness' from project 'Coupleness') 2021-01-12T17:45:10.9994790Z 2021-01-12T17:45:11.0235940Z error: ReactCommon does not support provisioning profiles. ReactCommon does not support provisioning profiles, but provisioning profile beta has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'ReactCommon' from project 'Pods') 2021-01-12T17:45:11.0240330Z error: PurchasesCoreSwift does not support provisioning profiles. PurchasesCoreSwift does not support provisioning profiles, but provisioning profile beta has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'PurchasesCoreSwift' from project 'Pods') 2021-01-12T17:45:11.0250350Z error: libwebp does not support provisioning profiles. libwebp does not support provisioning profiles, but provisioning profile beta has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'libwebp' from project 'Pods') 2021-01-12T17:45:11.0256200Z error: ReactNativeWebPFormat does not support provisioning profiles. ReactNativeWebPFormat does not support provisioning profiles, but provisioning profile beta has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'ReactNativeWebPFormat' from project 'Pods') 2021-01-12T17:45:11.0266380Z error: React-RCTImage does not support provisioning profiles. React-RCTImage does not support provisioning profiles, but provisioning profile beta has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'React-RCTImage' from project 'Pods') 2021-01-12T17:45:11.0272770Z error: RNInAppReviewIOS does not support provisioning profiles. RNInAppReviewIOS does not support provisioning profiles, but provisioning profile beta has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'RNInAppReviewIOS' from project 'Pods')

CouplenessTech commented 3 years ago

@aboedo What did you find confusing about the podfile? something you thought were missing? something new/unknown?

aboedo commented 3 years ago

@CouplenessTech thanks for the answers, I was just confused because I wasn't sure whether you were using cocoapods or manual install and forgot to ask.

yeah, it looks like some of the other frameworks have some issues when doing static linking. This seems kinda similar to #198, maybe the solutions there help (they involve setting use_modular_headers!, but disabling it for problematic pods via adding modular_headers: false to them).

I'm sorry about the installation issues, there are a lot of configurations from different developers and it's often tricky to find which solutions work for each app. The 4.0.0 changes were done because the React dependency didn't compile correctly under some configurations on Xcode 12, and it led us to realize that we actually need to be using React-Core, which comes with its own restrictions when it comes to compilation.

CouplenessTech commented 3 years ago

@aboedo Well I'm glad you're trying to help out.

I've queued up three new builds, one with use_modular_headers!, one with pod 'React-Core', :path => '../node_modules/react-native/', :modular_headers => true and a third with pod 'RNPurchases', :path => '../node_modules/react-native-purchases', :inhibit_warnings => true, :modular_headers => false, all taken from the issue you linked. Hopefully one of them will work.

aboedo commented 3 years ago

@CouplenessTech awesome! keep me posted!

CouplenessTech commented 3 years ago

@aboedo I will

CouplenessTech commented 3 years ago

@aboedo All three failed.

use_modular_headers! generated a new error:

/ios/Pods/Headers/Public/glog/glog/logging.h:512:1: fatal error: import of module 'glog.glog.log_severity' appears within namespace 'google'

But no improvement, as far as I know.

The other two builds generated the old error.

declaration of 'RCPurchases' must be imported from module 'Purchases' before it is required

aboedo commented 3 years ago

@CouplenessTech for the error with use_modular_headers!, you can disable the setting for problematic pods by setting :modular_headers => false for them. In my testing, I had issues with glog, DoubleConversion and folly, which I solved by doing:

pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec', :modular_headers => false
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec', :modular_headers => false
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec', :modular_headers => false
CouplenessTech commented 3 years ago

@aboedo okey I'll try that, those three are the only ones we have in /node_modules/react-native/third-party-podspecs

CouplenessTech commented 3 years ago

@aboedo back to the original error

CouplenessTech commented 3 years ago

@aboedo Maybe this warning tell you something?

/ios/Pods/PurchasesHybridCommon/ios/PurchasesHybridCommon/PurchasesHybridCommon/RCPurchaserInfo+HybridAdditions.h:6:2: warning: missing submodule 'Purchases.Purchases'

aboedo commented 3 years ago

@CouplenessTech thanks for the update. the warning matches the error messages: it looks like what's happening is that for some reason, the PurchasesHybridCommon can't find the Purchases module, which it depends on.

I'm still not entirely sure what's going on, but I'm going to try a few things to see if I can reproduce and figure this out. I think this might either be an issue with the framework search paths, with the creation of modules / module headers, or something related.

aboedo commented 3 years ago

@CouplenessTech update:

I just tried installing the sdk again with a brand new app, and it worked, generating the following Podfile:

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '10.0'

target 'AwesomeProject' do
  config = use_native_modules!

  use_react_native!(:path => config["reactNativePath"])

  pod 'RNPurchases', :path => '../node_modules/react-native-purchases'

  target 'AwesomeProjectTests' do
    inherit! :complete
    # Pods for testing
  end

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  use_flipper!
  post_install do |installer|
    flipper_post_install(installer)
  end
end

target 'AwesomeProject-tvOS' do
  # Pods for AwesomeProject-tvOS

  target 'AwesomeProject-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

I also tried generating a new plugin, to make sure that we were setting dependencies correctly, and they match the ones in our plugin.

After that, I tried yet another project, using npm i react-native-purchases (without --save), and I was able to reproduce your error 🎉

So it seems like the current version of the plugin isn't compatible with auto-linking.

I'm going to work on fixing that, but in the meantime, could you try removing the plugin and re-installing via:

npm uninstall react-native-purchases
npm install --save react-native-purchases
npx react-native link react-native-purchases

?

This fixed the issues on my test project.

If that doesn't solve it immediately, you can also cd into ios and manually pod install just to make sure that everything is up-to-date

CouplenessTech commented 3 years ago

@aboedo Great that you managed to recreate the issue. I already tried to reinstall the package, and link it, but I'll try your set of commands anyways

CouplenessTech commented 3 years ago

Tried yours and a few different versions of your commands, all failed, same old error

aboedo commented 3 years ago

I'm pretty confused by this... do the pods get installed correctly? Do they show up in the Pods project? Specifically PurchasesCoreSwift, Purchases and PurchasesHybridCommon

image
CouplenessTech commented 3 years ago

Yes the show up in the Pods project.

Have also run pod update [name] on each of the four PurchasesCoreSwift, Purchases, PurchasesHybridCommon and RNPurchases but didn't have any effect.

Running npx react-native link react-native-purchases said that iOS was already linked, even if I first ran:

  1. npm uninstall react-native-purchases
  2. Removed pod 'RNPurchases', :path => '../node_modules/react-native-purchases' from podfile
  3. pod update (which outputs that purchases has been removed)
  4. npm i react-native-purchases
  5. pod install
  6. pod update Purchases
  7. pod update PurchasesCoreSwift
  8. pod update PurchasesHybridCommon
  9. pod update RNPurchases
aboedo commented 3 years ago
CouplenessTech commented 3 years ago
  1. Yes Enable Modules is set to YES
  2. Not that I'm aware of, anything you had in mind that could do that?
  3. The --save argument for npm install is deprecated since v5 and now no longer part of the official docs. But yes I have tried to add the pod to podfile.
  4. Yes it is, was 10.0 but have also tried 12.0 as that was a solution for somebody else.
  5. XCode outputs about 100.000 lines during build but no I have not found anything else that might be relevant

I tried degrading back to react-native-purchases@3.4.2 and it builds, which indicates that it's probably something wrong with 4.0.0.

aboedo commented 3 years ago

does 3.4.3 also build? there are some changes in that one as well that might be related.

for 2., I've seen some build systems that override settings. For example Flutter adds some extra steps that modify the search paths, so for that one we had to explicitly re-add the frameworks so the search paths.

CouplenessTech commented 3 years ago

I have not tried 3.4.3 but I will.

Framework Search Paths are not configured, was not necessary for 3.4.2 and auto-linking. I'll try adding $(PROJECT_DIR)/../node_modules/react-native-purchases/ios to all configurations, taken from your manual installation guide.

CouplenessTech commented 3 years ago

Upgraded to 4.0.0 and added Framework Search Paths, same error as before. 3.4.3 is queued on the build server...

CouplenessTech commented 3 years ago

3.4.3 did not build, same error as 4.0.0

aboedo commented 3 years ago

@CouplenessTech Interesting, thanks for the update!

I think that might actually help narrow down the problem.

The main difference between 3.4.2 and 3.4.3 in terms of compilation and linking is that 3.4.2 forced the usage of static frameworks, whereas 3.4.3 uses dynamic by default. In static frameworks, linking happens statically in an earlier stage, so there might be an issue either with linker flags that the framework needs but aren't set (like -ObjC, -all_load), with the framework search paths not being set correctly, or something related.

It'd be really hard for me to figure this out without actually testing the project, since these settings are very specific, however, you can force 3.4.2 behavior in other versions of the SDK by setting in your Podfile:

use_frameworks! :linkage => :static

This might force you to set use_modular_headers! as well for React-Core to work. If this causes the modular_headers error that was mentioned earlier in this thread, then that can be fixed by disabling modular_headers individually on the problem pods, like DoubleConversion,glog,Folly`.

Hope this helps!

CouplenessTech commented 3 years ago

Tried them separately before and now together, same error

  use_frameworks! :linkage => :static
  use_modular_headers!
  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec', :modular_headers => false
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec', :modular_headers => false
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec', :modular_headers => false

Because of the build script specifying provisioning profile, I also needed to add the following:

  # Stop Cocoapods from signing frameworks
  # REF: https://stackoverflow.com/a/55750843/14454546
  def disable_provisioning_profile_for_pods(installer)
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
        config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
        config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
      end
    end
  end

and call it in post_install but still does not work, got errors with Flipper (use_frameworks and Flipper are not compatible), I'll try disabling Flipper and see how that goes, but I should not need to do that.

aboedo commented 3 years ago

getting the same error with those changes is really unexpected, I'd at least have expected a new error. any chance that something is getting cached in a way that prevents the changes from being correctly reflected?

CouplenessTech commented 3 years ago

The issue remains. Cleared several caches multiple times during the troubleshooting. @aboedo have you made any progress?

aboedo commented 3 years ago

@CouplenessTech I have still not been able to reproduce the issue (other than when I tried not doing --save). I'm hitting a bit of a wall when trying to find other ways to reproduce it.

could you provide some repro steps? does this happen on a new project for you? do the issues only happen on CI? could you provide some more info, regarding:

CouplenessTech commented 3 years ago

@aboedo Sorry for the delay. I have already provided you with rn version, podfile and cocoapods version, scroll up through this issue. The build server is now testing a new project and also the old project where RevenueCat got stripped all together and then reinstalled according to your docs (with --save even though it is deprecated). Time will tell if any of those builds succeeds, I'll get back to you on that.

iduuck commented 3 years ago

Unfortunately I have the same error. Overtook the project from another dev, but the previous developer didn't had any problems before. Also → Only happening in Release. Perhaps some sort of Build Settings?

EricWiener commented 3 years ago

Also having this issue when trying to archive a release build. Able to build no problem. Just the archiving is an issue.

Here's the relevant info from my Podfile:

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'XXX' do:
    platform :ios, '10.0'
    config = use_native_modules!

    use_react_native!(:path => config["reactNativePath"])

    pod 'RNPurchases', :path => '../node_modules/react-native-purchases', :inhibit_warnings => true, :modular_headers => false
end
aboedo commented 3 years ago

what error message are you seeing when archiving?

EricWiener commented 3 years ago

@aboedo the exact same one described by @CouplenessTech in the original post

CouplenessTech commented 3 years ago

Many tries later, still same error, even for new react native projects

aboedo commented 3 years ago

hey everyone, I'm still working on this, I'm having a hard time reproducing locally since it archives correctly for me on new projects. I can archive and even validate for App Store correctly. I'll keep trying things to reproduce, but if you have solid steps that reproduce this for you, please let me know because it'd help a ton in getting a fix in.

aboedo commented 3 years ago

it looks like react-native updated React-Core for Xcode 12 compatibility in react-native release 0.63.4, back in November. https://github.com/facebook/react-native/commit/6e08f84719c47985e80123c72686d7a1c89b72ed

Could you try upgrading to see if it solves it? If it does, it'd explain a lot, since we switched to the React-Core dependency rather recently. @CouplenessTech @iDuuck @EricWiener

aboedo commented 3 years ago

This would be with react-native-purchases >= 4.0.0

aboedo commented 3 years ago

you may have to remove flipper for it to work, I had to comment from my podfile since there are some issues with its Podspec

CouplenessTech commented 3 years ago

@aboedo Good that you are still working on this. We use React Native 0.63.3 and our Azure build server uses XCode 12.3, which was the latest at the time of configuration, but now they have made 12.4 available. I shall try a build with XCode 12.4.