SDK 29 build failure: No visible @interface for EXModuleRegistryProvider


#1

I have an app running successfully on the iOS simulator, SDK28 with all the appropriate versioning and configs.

After upgrading to 29, the Xcode build fails with the following error: No visible @interface for ‘EXModuleRegistryProvider’ declares the selector ‘init WithSingletonModuleClasses’.

Here are my diagnostics

 Expo CLI 2.10.1 environment info:
    System:
      OS: macOS 10.14.3
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.15.1 - /usr/local/bin/node
      Yarn: 1.13.0 - /usr/local/bin/yarn
      npm: 6.4.1 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.3 AI-182.5107.16.33.5264788
      Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
    npmPackages:
      expo: ^29.0.0 => 29.0.1 
      react: 16.3.1 => 16.3.1 
      react-native: https://github.com/expo/react-native/archive/sdk-29.0.0.tar.gz => 0.55.4 
      react-navigation: ~2.9.3 => 2.9.3 
    npmGlobalPackages:
      expo-cli: 2.10.1

Since this seems like an issue with the native code, here’s my podfile, which is a copy of this (provided in the upgrade guide) with some changes to reflect my project name and a few minor changes in the paths and the case of some of the package names to resolve known issues.

platform :ios, '9.0'

target 'ping' do
  pod 'ExpoKit',
    :git => "http://github.com/expo/expo.git",
    :tag => "ios/2.7.8",
    :subspecs => [
      "Core"
    ],
    :inhibit_warnings => true
  pod 'EXGL',
    :path => "../node_modules/expo-gl/ios",
    :inhibit_warnings => true
  pod 'EXCore',
    :path => "../node_modules/expo-core/ios",
    :inhibit_warnings => true
  pod 'EXCamera',
    :path => "../node_modules/expo-camera/ios",
    :inhibit_warnings => true
  pod 'EXSensors',
    :path => "../node_modules/expo-sensors/ios",
    :inhibit_warnings => true
  pod 'EXConstants',
    :path => "../node_modules/expo-constants/ios",
    :inhibit_warnings => true
  pod 'EXFileSystem',
    :path => "../node_modules/expo-file-system/ios",
    :inhibit_warnings => true
  pod 'EXPermissions',
    :path => "../node_modules/expo-permissions/ios",
    :inhibit_warnings => true
  pod 'EXCameraInterface',
    :path => "../node_modules/expo-camera-interface/ios",
    :inhibit_warnings => true
  pod 'EXSensorsInterface',
    :path => "../node_modules/expo-sensors-interface/ios",
    :inhibit_warnings => true
  pod 'EXConstantsInterface',
    :path => "../node_modules/expo-constants-interface/ios",
    :inhibit_warnings => true
  pod 'EXReactNativeAdapter',
    :path => "../node_modules/expo-react-native-adapter/ios",
    :inhibit_warnings => true
  pod 'EXFileSystemInterface',
    :path => "../node_modules/expo-file-system-interface/ios",
    :inhibit_warnings => true
  pod 'EXPermissionsInterface',
    :path => "../node_modules/expo-permissions-interface/ios",
    :inhibit_warnings => true
  pod 'EXFaceDetectorInterface',
    :path => "../node_modules/expo-face-detector-interface/ios",
    :inhibit_warnings => true
  pod 'EXSMS',
    :path => "../node_modules/expo-sms/ios",
    :inhibit_warnings => true
  pod 'EXGL-CPP',
    :path => "../node_modules/expo-gl-cpp/cpp",
    :inhibit_warnings => true

  pod 'React',
    :path => "../node_modules/react-native",
    :inhibit_warnings => true,
    :subspecs => [
      "Core",
      "ART",
      "RCTActionSheet",
      "RCTAnimation",
      "RCTCameraRoll",
      "RCTGeolocation",
      "RCTImage",
      "RCTNetwork",
      "RCTText",
      "RCTVibration",
      "RCTWebSocket",
      "DevSupport",
      "CxxBridge"
    ]
  pod 'yoga',
    :path => "../node_modules/react-native/ReactCommon/yoga",
    :inhibit_warnings => true
  pod 'DoubleConversion',
    :podspec => "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec",
    :inhibit_warnings => true
  pod 'Folly',
    :podspec => "../node_modules/react-native/third-party-podspecs/Folly.podspec",
    :inhibit_warnings => true
  pod 'glog',
    :podspec => "../node_modules/react-native/third-party-podspecs/glog.podspec",
    :inhibit_warnings => true


  post_install do |installer|
    installer.pods_project.main_group.tab_width = '2';
    installer.pods_project.main_group.indent_width = '2';

    installer.pod_targets.each do |target|

    if target.pod_name == 'expokit'
      target.native_target.build_configurations.each do |config|
        config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
        config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'EX_DETACHED=1'
        
        # needed for GoogleMaps 2.x
        config.build_settings['FRAMEWORK_SEARCH_PATHS'] ||= []
        config.build_settings['FRAMEWORK_SEARCH_PATHS'] << '${PODS_ROOT}/GoogleMaps/Base/Frameworks'
        config.build_settings['FRAMEWORK_SEARCH_PATHS'] << '${PODS_ROOT}/GoogleMaps/Maps/Frameworks'
      end
    end


    if ['amplitude-ios','analytics','appauth','branch','cocoalumberjack','fbsdkcorekit','fbsdkloginkit','fbsdksharekit','gpuimage','jkbiginteger2'].include? target.pod_name
      target.native_target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
      end
    end
    # Can't specify this in the React podspec because we need
    # to use those podspecs for detached projects which don't reference ExponentCPP.
    if target.pod_name.start_with?('react')
      target.native_target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
        config.build_settings['HEADER_SEARCH_PATHS'] ||= ['$(inherited)']
      end
    end
    # Build React Native with RCT_DEV enabled
    next unless target.pod_name == 'react'
    target.native_target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'RCT_DEV=1'
    end

    end
  end
end

I have reinstalled node modules and pods, and can’t seem to come across any solutions to this issue on github or the forums.

Not sure what to do for next steps, any help is very much appreciated!


#2

After some additional digging, it looks like EXVersionManager.m is attempting to call initWithSingletonModuleClasses from EXModuleRegistryProvider. However, EXModuleRegistryProvider declares initWithSingletonModules (note the lack of “Classes” at the end). Fixed this by updating the declaration to match what EXVersionManager expects. This issue occurs in SDK29 only, resolved in 30.