Skip to content

iOS Fabric View template doesn't work when published and installed into a new app #788

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

Closed
2 tasks done
Zach-Dean-Attractions-io opened this issue Mar 11, 2025 · 10 comments · Fixed by #801
Closed
2 tasks done
Assignees
Labels
bug Something isn't working

Comments

@Zach-Dean-Attractions-io
Copy link

Zach-Dean-Attractions-io commented Mar 11, 2025

Description

I have created a Fabric View template using npx create-react-native-library@latest FabricNativeComponent with npm package name fabric-native-component. If I run the example iOS app then I see a green square as expected.

I've then published this app to a local registry npm publish --registry http://localhost:4873/ and then created a new React Native app (running version 0.78.0 of React Native) using npx @react-native-community/cli@latest init App_v_0_78_0.

I've then installed the package npm install fabric-native-component --registry http://localhost:4873/ into this app and modified the App.tsx file to be the same as the example app included in the library template.

import { View, StyleSheet } from 'react-native';
import { FabricNativeComponentView } from 'fabric-native-component';

export default function App() {
  return (
    <View style={styles.container}>
      <FabricNativeComponentView color="#32a852" style={styles.box} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    width: 60,
    height: 60,
    marginVertical: 20,
  },
});

I then ran bundle install && bundle exec pod install within the apps ios directory. Building this app is successful but the app crashes immediately with the error

Exception	NSException *	"-[UIView setColor:]: unrecognized selector sent to instance 0x15f956000"	0x00006000030927f0

One difference I see comparing the ios directories is that the Podfile in the example app included in the library template includes

pre_install do |installer|
    system("cd ../../ && npx bob build --target codegen")
  end

However, I tried adding the following code into the Podfile of the new app but it didn't seem to fix the issue. (Although I thought that codegen was ran when publishing the library)

pre_install do |installer|
    system("cd ../node_modules/fabric-native-component && npx bob build --target codegen")
  end

Do you know how to resolve this issue?

As a side note in the file /ios/FabricNativeComponentView.mm the return type for the function hexStringToColor is missing I believe.

Packages

  • create-react-native-library
  • react-native-builder-bob

Selected options

Fabric View

Link to repro

N/A

Environment

System:
  OS: macOS 15.0.1
  CPU: (11) arm64 Apple M3 Pro
  Memory: 377.56 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 23.7.0
    path: /opt/homebrew/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.9.2
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2025.02.17.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods: Not Found
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK:
    API Levels:
      - "28"
      - "31"
      - "33"
      - "34"
      - "35"
    Build Tools:
      - 28.0.3
      - 30.0.2
      - 30.0.3
      - 33.0.1
      - 34.0.0
      - 35.0.0
      - 35.0.1
    System Images:
      - android-21 | Google APIs ARM 64 v8a
      - android-23 | Google APIs ARM 64 v8a
      - android-25 | Google APIs ARM 64 v8a
      - android-26 | Google APIs ARM 64 v8a
      - android-28 | ARM 64 v8a
      - android-28 | Google APIs ARM 64 v8a
      - android-30 | Google APIs ARM 64 v8a
      - android-31 | Google Play ARM 64 v8a
      - android-32 | Google APIs ARM 64 v8a
      - android-33 | Google APIs ARM 64 v8a
      - android-34 | Google APIs ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23726.103.2422.13016713
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.14
    path: /usr/bin/javac
  Ruby:
    version: 3.4.2
    path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 19.0.0
    wanted: 19.0.0
  react-native:
    installed: 0.78.0
    wanted: 0.78.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true
@Zach-Dean-Attractions-io Zach-Dean-Attractions-io added the bug Something isn't working label Mar 11, 2025
@Zach-Dean-Attractions-io
Copy link
Author

Zach-Dean-Attractions-io commented Mar 12, 2025

I have found the bug. The issue is within the the ...ViewManager.mm file, in this library it will be named FabricNativeComponentViewManager.mm.

The issue is with the code:

RCT_EXPORT_VIEW_PROPERTY(color, NSString)

Since a UIView does not have a property called color (it should be backgroundColor). To solve this I have made the following change:

+ #import <React/RCTConvert.h>

- RCT_EXPORT_VIEW_PROPERTY(color, NSString)
+ RCT_CUSTOM_VIEW_PROPERTY(color, UIColor, UIView)
+{
+  if (json) {
+      [view setBackgroundColor:[RCTConvert UIColor:json]];
+    } else {
+      [view setBackgroundColor:nil];
+    }
+}

When publishing the library with this change it works in a standalone app.

However, this raises another question. It's my understanding that the ...ViewManager.mm file is used in the legacy architecture and not in the new architecture. This must be why the example app included in the library works as expected without changing this file as it is correctly using the new architecture. The standalone app I created is running version 0.78.0 of React Native in which the new architecture should be enabled by default and so the standalone app should not be falling into this section of code.

Do you know why the library isn't picking up the new architecture in a standalone app (or do I have an error in my understanding here)? (I'll try investigate this some more)

Update:

I added a log statement into the view constructors in the legacy and new architecture files. When running the example app included in the library the new architecture constructor is used. However, when running the standalone app in Xcode the code does fall into the legacy constructor. Prior to the log statement there is this error

Codegen didn't run for FabricNativeComponentView. This will be an error in the future. Make sure you are using @react-native/babel-preset when building your JavaScript code.', { [Component Stack] name: 'Component Stack' }

@dcangulo
Copy link
Contributor

I added NSLog in the functions of ..ViewManager.mm and ..View.mm.

When running on the example app, only ..View.mm functions print the logs, but if it's on a standalone app, only ..ViewManager.mm functions print the logs.

@Zach-Dean-Attractions-io
Copy link
Author

Hi,

I managed to fix this issue by removing the exports block from the package.json file and adding a types block. Details can be found in this discussion.

Whether this is a good fix or not I am not sure but it at least gets to the root of the problem.

-"exports": {
-  ".": {
-    "import": {
-      "types": "./lib/typescript/module/src/index.d.ts",
-      "default": "./lib/module/index.js"
-    },
-    "require": {
-      "types": "./lib/typescript/commonjs/src/index.d.ts",
-      "default": "./lib/commonjs/index.js"
-    }
-  }
-},
+ "types": "./lib/typescript/commonjs/src/index.d.ts",

@satya164
Copy link
Member

satya164 commented Mar 27, 2025

@Zach-Dean-Attractions-io

Codegen didn't run for FabricNativeComponentView. This will be an error in the future. Make sure you are using @react-native/babel-preset when building your JavaScript code.', { [Component Stack] name: 'Component Stack' }

Can you check by updating react-native-builder-bob to the latest version?

Hi,

I managed to fix this issue by removing the exports block from the package.json file and adding a types block. Details can be found in this discussion.

Is this with includeGeneratedCode: true? If it's without, then adding package.json to exports should be enough: https://callstack.github.io/react-native-builder-bob/faq#how-to-opt-out-of-shipping-codegen-generated-code

@Zach-Dean-Attractions-io
Copy link
Author

Zach-Dean-Attractions-io commented Mar 27, 2025

Hi @satya164

Yes it is with includesGeneratedCode: true as I'm using the library project generated as is. The discussion includes a sample repo. The issue is with this line of code here, the library can not be resolved. I needed to remove the exports so that the library could be correctly resolved. I think the example app works as it's being linked as a relative import here in the catch statement, but I haven't tested that theory and could be wrong.

@satya164
Copy link
Member

@Zach-Dean-Attractions-io can you check if it works without removing the exports block and adding package.json to exports instead?

"exports": {
  // …
+ "./package.json": "./package.json"
},

@Zach-Dean-Attractions-io
Copy link
Author

Zach-Dean-Attractions-io commented Mar 27, 2025

Hi @satya164

Yes you are correct. With my exports block as

"exports": {
    ".": {
      "import": {
        "types": "./lib/typescript/module/src/index.d.ts",
        "default": "./lib/module/index.js"
      },
      "require": {
        "types": "./lib/typescript/commonjs/src/index.d.ts",
        "default": "./lib/commonjs/index.js"
      }
    },
+   "./package.json": "./package.json"
  }

Then publishing the generated library and installing it into a standalone app works as expected.

@satya164
Copy link
Member

@Zach-Dean-Attractions-io thanks! then I'll add this to the template and publish a new version.

satya164 added a commit that referenced this issue Mar 27, 2025
fixes #788
github-merge-queue bot pushed a commit that referenced this issue Mar 27, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@Zach-Dean-Attractions-io
Copy link
Author

Thanks @satya164 for your support, it is much appreciated. Also like the addition of ios.componentProvider section in the codegenConfig block. Thank you!

@satya164
Copy link
Member

Thanks @Zach-Dean-Attractions-io ! Let me know if you find any issues in the latest version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants