appodeal / react-native-appodeal

Official React Native package that adds Appodeal SDK support to your react-native application.
https://appodeal.com
59 stars 37 forks source link

iOS installation Issue #36

Closed BenjErgizerBunny closed 4 years ago

BenjErgizerBunny commented 4 years ago

Has anyone encountered this error?

After following the installation guide for iOS, I get this when trying to build the app on iOS

clang: error: linker command failed with exit code 1 (use -v to see invocation)

I followed the instructions in the README, including the instructions on Appodeal's website for iOS SDK 2.6.4 but it seems that all of the AppDelegate.m files I'm looking at in the react-native-appodeal examples are using Flipper. Am I receiving this error because I'm not using Flipper?

Enviornment "react-native": "0.61.5" "react-native-appodeal": "^2.6.4"

AppDelegate.m

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Firebase.h>
#import "RNSplashScreen.h"
#import <CodePush/CodePush.h>
#import <Appodeal/Appodeal.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"wwdbbenji"
                                            initialProperties:nil];

  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  if ([FIRApp defaultApp] == nil) {
  [FIRApp configure];
  }
  [RNSplashScreen show];
  [Appodeal initializeWithApiKey:@"XXXXX" types:AppodealAdTypeBanner hasConsent:true];
  return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [CodePush bundleURL];
#endif
}

@end

Podfile

platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

def appodeal
  pod 'APDAdColonyAdapter', '2.6.4.1'
  pod 'APDAmazonAdsAdapter', '2.6.4.1'
  pod 'APDAppLovinAdapter', '2.6.4.1'
  pod 'APDAppodealAdExchangeAdapter', '2.6.4.1'
  pod 'APDChartboostAdapter', '2.6.4.1'
  pod 'APDFacebookAudienceAdapter', '2.6.4.1'
  pod 'APDInMobiAdapter', '2.6.4.1'
  pod 'APDInnerActiveAdapter', '2.6.4.1'
  pod 'APDIronSourceAdapter', '2.6.4.1'
  pod 'APDMintegralAdapter', '2.6.4.1'
  pod 'APDMyTargetAdapter', '2.6.4.1'
  pod 'APDOguryAdapter', '2.6.4.1'
  pod 'APDOpenXAdapter', '2.6.4.1'
  pod 'APDPubnativeAdapter', '2.6.4.1'
  pod 'APDSmaatoAdapter', '2.6.4.1'
  pod 'APDStartAppAdapter', '2.6.4.1'
  pod 'APDTapjoyAdapter', '2.6.4.1'
  pod 'APDUnityAdapter', '2.6.4.1'
  pod 'APDVungleAdapter', '2.6.4.1'
  pod 'APDYandexAdapter', '2.6.4.1'
end

target 'wwdbbenji' do
  # Pods for wwdbbenji
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
  appodeal

  target 'wwdbbenjiTests' do
    inherit! :search_paths
    # Pods for testing
  end

  use_native_modules!
  use_frameworks!
end

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

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

end
staskochkin commented 4 years ago

@BenjErgizerBunny Hi, Appodeal requires to use use_framework! in Podfile, but Flipper pod can't be installed when this flag was set. I see that plugin pod is not included in your project Podfile. Please add

def appodeal 
  pod 'RNAppodeal', :path => '../node_modules/react-native-appodeal'
  pod 'APDAdColonyAdapter', '2.6.4.1'
# All adapters pods
end

Also you import:

#import <Firebase.h>
#import <CodePush/CodePush.h>

In your AppDelegate.m but there are no such dependencies in Podfile. If you installed Firebase manually it can conflict with Appodeal Ad Mob adapter and can be reason of compilation errors. Because both libs has dependencies on same modules. You can reintegrate Firebase through CocoaPods to avoid conflicts.

p.s. You don't need to import and call methods of Appodeal in AppDelegate.m file. You can initialise Appodeal in JS sources

BenjErgizerBunny commented 4 years ago

Thanks @staskochkin! I removed the Appodeal code from AppDelegate.m and modified my Podfile but I'm still having issues.

I included a summary below. If you have any other suggestions that would be amazing!

I notice the example is using Folly and use_framework! which the README says cannot be used together but Folly is required for React Native.

I'm getting this error now when trying to launch it:

clang: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **

The following build commands failed:
        Ld /Users/benjilightstone/Library/Developer/Xcode/DerivedData/wwdbbenji-csfqislgyeidvxfglrcuxtdopnxw/Build/Products/Debug-iphonesimulator/wwdbbenji.app/wwdbbenji normal x86_64
(1 failure)

Here's my podfile now:

platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

def appodeal
  pod 'RNAppodeal', :path => '../node_modules/react-native-appodeal'
  pod 'APDAdColonyAdapter', '2.6.4.1'
# All adapters pods
  pod 'APDAmazonAdsAdapter', '2.6.4.1'
  pod 'APDAppLovinAdapter', '2.6.4.1'
  pod 'APDAppodealAdExchangeAdapter', '2.6.4.1'
  pod 'APDChartboostAdapter', '2.6.4.1'
  pod 'APDFacebookAudienceAdapter', '2.6.4.1'
  pod 'APDInMobiAdapter', '2.6.4.1'
  pod 'APDInnerActiveAdapter', '2.6.4.1'
  pod 'APDIronSourceAdapter', '2.6.4.1'
  pod 'APDMintegralAdapter', '2.6.4.1'
  pod 'APDMyTargetAdapter', '2.6.4.1'
  pod 'APDOguryAdapter', '2.6.4.1'
  pod 'APDOpenXAdapter', '2.6.4.1'
  pod 'APDPubnativeAdapter', '2.6.4.1'
  pod 'APDSmaatoAdapter', '2.6.4.1'
  pod 'APDStartAppAdapter', '2.6.4.1'
  pod 'APDTapjoyAdapter', '2.6.4.1'
  pod 'APDUnityAdapter', '2.6.4.1'
  pod 'APDVungleAdapter', '2.6.4.1'
  pod 'APDYandexAdapter', '2.6.4.1'
end

target 'wwdbbenji' do
  # Pods for wwdbbenji
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  appodeal

  target 'wwdbbenjiTests' do
    inherit! :search_paths
    # Pods for testing
  end

  use_native_modules!
  use_frameworks!
end

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

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

end
staskochkin commented 4 years ago

Thanks @BenjErgizerBunny. Appodeal hasn't conflicts with Folly but can't work with Flipper. It was a mistake in README and I fix it in this commit. In demo app we have this preprocessor macro, to avoid compile time errors when Flipper is not linked with project.

#if DEBUG && __has_include(<FlipperKit/FlipperClient.h>)
#define FLIPPER 1
#endif

We need more detailed report to suggest anything. Please, try to build app target in Xcode, than go to Report Navigator (left panel) select failed build and export report. It should contains more info about this linker error.

BenjErgizerBunny commented 4 years ago

Thanks so much for the advice @staskochkin !

I attached the report I exported from Xcode when the build failed. Also, I don't think I. mentioned but I'm adding react-native-appodeal to my existing project and not using the example as my base project. I'm also not using Flipper.

Thanks again for all your help, I really appreciate because I'm really stumped!

Build target wwdbbenji_2020-06-05T12-13-35.txt

BenjErgizerBunny commented 4 years ago

I managed to get the app to launch, but it errors out while launching and gets stuck having just loaded the background of the app and another else. This is the error I get when I build with Xcode.

Has anyone seen anything like this before?

It seems to be an error in the RNAppodealBannerView.m file

Screen Shot 2020-06-06 at 3 50 38 PM
staskochkin commented 4 years ago

Hi @BenjErgizerBunny. Did you solve compilation issue by adding swift file into project? Runtime issue seems to be related to trying to use AppodealBanner without/before Appodeal was initialised. Please, check that Appodeal was initialised before you trying to add AppodealBanner in hierarchy. For example you can use this approach. If you are not planning to use Consent Manager you can just call initialise method.

Also please pay attention that for current version you need to add synthetic delay. (this is mentioned in #37).

import React from 'react';
import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  StatusBar,
} from 'react-native';

import {
  Colors
} from 'react-native/Libraries/NewAppScreen';

import {
  Appodeal,
  AppodealAdType,
  AppodealBanner,
  AppodealConsentStatus,
} from 'react-native-appodeal';

const synchroniseConsent = (appKey) => {
  return new Promise((resolve, _) => {
    Appodeal.synchroniseConsent(appKey, (consent, _) => {
      console.log("Consent is synchronised")
      resolve({
        appKey: appKey,
        consent: consent !== AppodealConsentStatus.NON_PERSONALIZED
      })
    });
  })
}

const initializeAppodeal = (params) => {
  return new Promise((resolve, _) => {
    console.log("Initialise Appodeal");
    Appodeal.initialize(params.appKey, AppodealAdType.BANNER, params.consent);
    setTimeout(() => resolve(), 1000);
  });
}

const App: () => React$Node = () => {
  const [visible, setVisible] = React.useState(false);

  React.useEffect(() => {
    synchroniseConsent("YOUR APP KEY HERE")
    .then((params) => initializeAppodeal(params))
    .then(() => setVisible(true))
  }, []);

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <ScrollView
          style={styles.scrollView}>
          {visible ?
            <AppodealBanner
              adSize='phone'
              style={styles.banner}
            /> : null}
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  scrollView: {
    backgroundColor: Colors.lighter,
  },
  banner: {
    height: 50,
    width: '100%',
    alignContent: 'stretch'
  }
});

export default App;
BenjErgizerBunny commented 4 years ago

I did fix the complication issue by creating a swift file! I was also having the issue you mentioned that the Banner was trying to load before Appodeal was initialized and it would cause the app not to render so I followed your approach and it works perfectly now. Thanks so much for all of your help @staskochkin , I really appreciate it! I couldn't have gotten it working without you!