Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined symbol: _CustomWebViewCls #47217

Closed
BraveEvidence opened this issue Oct 26, 2024 · 5 comments
Closed

Undefined symbol: _CustomWebViewCls #47217

BraveEvidence opened this issue Oct 26, 2024 · 5 comments
Labels
Component: WebView Related to the WebView component.

Comments

@BraveEvidence
Copy link

Description

I created a project using react native community template. I followed all the steps mentioned in the Native components doc to create a fabric component and for iOS I get error saying

Undefined symbol: _CustomWebViewCls

Steps to reproduce

Create project using react native community template

Run mkdir -p myapp/{specs,android/app/src/main/java/com/webview}

In myapp/specs/WebViewNativeComponent.ts

import type {HostComponent, ViewProps} from 'react-native';
import type {BubblingEventHandler} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';

type WebViewScriptLoadedEvent = {
  result: 'success' | 'error';
};

export interface NativeProps extends ViewProps {
  sourceURL?: string;
  onScriptLoaded?: BubblingEventHandler<WebViewScriptLoadedEvent> | null;
}

export default codegenNativeComponent<NativeProps>(
  'CustomWebView',
) as HostComponent<NativeProps>;

In package.json add

 "codegenConfig": {
     "name": "AppSpec",
     "type": "components",
     "jsSrcsDir": "specs",
     "android": {
       "javaPackageName": "com.webview"
     }
   },

Then run following commands

cd ios
bundle install
bundle exec pods install

Open myapp.xcworkspace from iOS folder in Xcode

Create Group called WebView

Create RCTWebView.mm & RCTWebView.h

In RCTWebView.h add

#import <React/RCTViewComponentView.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface RCTWebView : RCTViewComponentView

// You would declare native methods you'd want to access from the view here

@end

NS_ASSUME_NONNULL_END



In RCTWebView.mm add

#import "RCTWebView.h"

#import <react/renderer/components/AppSpec/ComponentDescriptors.h>
#import <react/renderer/components/AppSpec/EventEmitters.h>
#import <react/renderer/components/AppSpec/Props.h>
#import <react/renderer/components/AppSpec/RCTComponentViewHelpers.h>
#import <WebKit/WebKit.h>


using namespace facebook::react;

@interface RCTWebView () <RCTCustomWebViewViewProtocol, WKNavigationDelegate>
@end

@implementation RCTWebView {
  NSURL * _sourceURL;
  WKWebView * _webView;
}

-(instancetype)init
{
  if(self = [super init]) {
    _webView = [WKWebView new];
    _webView.navigationDelegate = self;
    [self addSubview:_webView];
  }
  return self;
}

- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
  const auto &oldViewProps = *std::static_pointer_cast<CustomWebViewProps const>(_props);
  const auto &newViewProps = *std::static_pointer_cast<CustomWebViewProps const>(props);

  // Handle your props here
  if (oldViewProps.sourceURL != newViewProps.sourceURL) {
    NSString *urlString = [NSString stringWithCString:newViewProps.sourceURL.c_str() encoding:NSUTF8StringEncoding];
    _sourceURL = [NSURL URLWithString:urlString];
    if ([self urlIsValid:newViewProps.sourceURL]) {
      [_webView loadRequest:[NSURLRequest requestWithURL:_sourceURL]];
    }
  }

  [super updateProps:props oldProps:oldProps];
}

-(void)layoutSubviews
{
  [super layoutSubviews];
  _webView.frame = self.bounds;

}

#pragma mark - WKNavigationDelegate

-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
  CustomWebViewEventEmitter::OnScriptLoaded result = CustomWebViewEventEmitter::OnScriptLoaded{CustomWebViewEventEmitter::OnScriptLoadedResult::Success};
  self.eventEmitter.onScriptLoaded(result);
}

- (BOOL)urlIsValid:(std::string)propString
{
  if (propString.length() > 0 && !_sourceURL) {
    CustomWebViewEventEmitter::OnScriptLoaded result = CustomWebViewEventEmitter::OnScriptLoaded{CustomWebViewEventEmitter::OnScriptLoadedResult::Error};

    self.eventEmitter.onScriptLoaded(result);
    return NO;
  }
  return YES;
}

// Event emitter convenience method
- (const CustomWebViewEventEmitter &)eventEmitter
{
  return static_cast<const CustomWebViewEventEmitter &>(*_eventEmitter);
}

+ (ComponentDescriptorProvider)componentDescriptorProvider
{
  return concreteComponentDescriptorProvider<CustomWebViewComponentDescriptor>();
}

Class<RCTComponentViewProtocol> WebViewCls(void)
{
  return RCTWebView.class;
}

@end

I also added Webkit.framework like below
Screenshot 2024-10-26 at 7 01 03 PM

In AppDelegate.mm file added

#import "RCTWebView.h"

- (NSDictionary<NSString *,Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
  NSMutableDictionary * dictionary = [super thirdPartyFabricComponents].mutableCopy;
  dictionary[@"CustomWebView"] = [RCTWebView class];
  return dictionary;
}

React Native Version

0.76.0

Affected Platforms

Runtime - iOS

Output of npx react-native info

info Fetching system and libraries information...
System:
  OS: macOS 14.6.1
  CPU: (8) x64 Apple M1
  Memory: 47.60 MB / 8.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.17.0
    path: /usr/local/bin/node
  Yarn:
    version: 1.22.19
    path: /usr/local/bin/yarn
  npm:
    version: 10.8.2
    path: /usr/local/bin/npm
  Watchman:
    version: 2024.10.21.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/transformhub/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.0
      - iOS 18.0
      - macOS 15.0
      - tvOS 18.0
      - visionOS 2.0
      - watchOS 11.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.1 AI-241.19072.14.2412.12360217
  Xcode:
    version: 16.0/16A242d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.9
    path: /usr/bin/javac
  Ruby:
    version: 3.3.0
    path: /Users/transformhub/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

ld: warning: ignoring duplicate libraries: '-lc++'
ld: warning: Could not find or use auto-linked framework 'CoreAudioTypes': framework 'CoreAudioTypes' not found
Undefined symbols for architecture arm64:
  "_CustomWebViewCls", referenced from:
      _RCTThirdPartyFabricComponentsProvider in libReact-RCTFabric.a[41](RCTThirdPartyFabricComponentsProvider.o)
ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

Reproducer

https://github.com/BraveEvidence/ReactNative76Fabric

Screenshots and Videos

Screenshot 2024-10-26 at 5 41 37 PM
@react-native-bot react-native-bot added the Component: WebView Related to the WebView component. label Oct 26, 2024
@cipolleschi
Copy link
Contributor

Hi @BraveEvidence, thanks for the issue. There is a warning box explaining what's going on.

Screenshot 2024-10-27 at 16 14 15

This error will be fixed with 0.76.1

@BraveEvidence
Copy link
Author

I just tried with React native 0.76.1 and the issue still exists, check my repo

@erudel
Copy link

erudel commented Nov 8, 2024

I was running into the same issue. What did the trick for me was adding the following line in the component implementation (the .mm file):

#import "RCTFabricComponentsPlugins.h"

This is missing in the guide to create native components (https://reactnative.dev/docs/fabric-native-components-introduction) but it's present when you create a library following this guide: https://reactnative.dev/docs/the-new-architecture/create-module-library.

@BraveEvidence
Copy link
Author

Actually there are lot of issues and this video helped me resolve all issues

@cipolleschi
Copy link
Contributor

they wil be fixed in 0.76.2. We forgot a pick in .1 and the other fix had a typo. :sad:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: WebView Related to the WebView component.
Projects
None yet
Development

No branches or pull requests

5 participants