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

[ios] FontAwesome5 does not import properly with SDK 51 #28693

Closed
anthonyn60 opened this issue May 8, 2024 · 30 comments · Fixed by #28747
Closed

[ios] FontAwesome5 does not import properly with SDK 51 #28693

anthonyn60 opened this issue May 8, 2024 · 30 comments · Fixed by #28747

Comments

@anthonyn60
Copy link

Minimal reproducible example

https://github.com/anthonyn60/font-repro

What platform(s) does this occur on?

iOS

Did you reproduce this issue in a development build?

Yes

Summary

Fonts and icons don't load when imported from FontAwesome5. The font falls back to the default, while the icon will show a square with a question mark in it.

Screenshot 2024-05-08 at 4 40 49 PM

Environment

expo-env-info 1.2.0 environment info:
System:
OS: macOS 14.4.1
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 21.6.1 - ~/.nvm/versions/node/v21.6.1/bin/node
Yarn: 1.22.21 - ~/.nvm/versions/node/v21.6.1/bin/yarn
npm: 10.6.0 - ~/.nvm/versions/node/v21.6.1/bin/npm
Watchman: 2024.01.22.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.15.2 - /opt/homebrew/opt/rbenv/shims/pod
SDKs:
iOS SDK:
Platforms: DriverKit 23.4, iOS 17.4, macOS 14.4, tvOS 17.4, visionOS 1.1, watchOS 10.4
IDEs:
Android Studio: 2022.3 AI-223.8836.35.2231.10671973
Xcode: 15.3/15E204a - /usr/bin/xcodebuild
npmPackages:
expo: ~51.0.0 => 51.0.0
expo-router: ~3.5.10 => 3.5.10
react: 18.2.0 => 18.2.0
react-dom: 18.2.0 => 18.2.0
react-native: 0.74.1 => 0.74.1
react-native-web: ~0.19.10 => 0.19.11
npmGlobalPackages:
eas-cli: 7.8.2
Expo Workflow: managed

Expo Doctor Diagnostics

Anthonys-MacBook-Pro-2:font-repro anthonynguyen$ npx expo-doctor@latest

font-repro@1.0.0 npx
expo-doctor

(node:93133) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
✔ Check Expo config for common issues
✔ Check package.json for common issues
✔ Check dependencies for packages that should not be installed directly
✔ Check for issues with metro config
✔ Check for common project setup issues
✔ Check npm/ yarn versions
✔ Check Expo config (app.json/ app.config.js) schema
✔ Check for legacy global CLI installed locally
✔ Check that native modules do not use incompatible support packages
✔ Check that packages match versions required by installed Expo SDK
✔ Check that native modules use compatible support package versions for installed Expo SDK
✔ Check native tooling versions

Didn't find any issues with the project!

@anthonyn60 anthonyn60 added the needs validation Issue needs to be validated label May 8, 2024
@expo-bot expo-bot added needs review Issue is ready to be reviewed by a maintainer and removed needs validation Issue needs to be validated labels May 8, 2024
@joonaathaan
Copy link

Same issue as well, sdk 51

@brentvatne
Copy link
Member

brentvatne commented May 9, 2024

i don't see any code related to FontAwesome5 in the repo you shared. ah nevermind i found it. github search was weird.

nonetheless, i tried to reproduce this myself and it worked as expected

image
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { FontAwesome5 } from '@expo/vector-icons';
import { useFonts } from 'expo-font';

export default function App() {
  const [loaded] = useFonts({
    ...FontAwesome5.font,
  });

  if (!loaded) {
    return;
  }

  return (
    <View style={styles.container}>
      <FontAwesome5 name="laugh-wink" size={150} color="black" />
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

can you share a minimal version like the one above that reproduces the issue?

@anthonyn60
Copy link
Author

@brentvatne so I got your example working and am able to render the icons directly. I also was able to render the icon directly in my repro repo on the homepage.

However, there might be something going on with it handling dynamic props? The tab bar icon component still doesn't want to show the proper icon.

If it helps at all, the repro repo is the exact create expo app boilerplate on SDK 51 but swaps out the Ionicons icon pack for FontAwesome5.

@expo-bot
Copy link
Collaborator

expo-bot commented May 9, 2024

Thank you for filing this issue!
This comment acknowledges we believe this may be a bug and there’s enough information to investigate it.
However, we can’t promise any sort of timeline for resolution. We prioritize issues based on severity, breadth of impact, and alignment with our roadmap. If you’d like to help move it more quickly, you can continue to investigate it more deeply and/or you can open a pull request that fixes the cause.

@github-actions github-actions bot removed the needs review Issue is ready to be reviewed by a maintainer label May 9, 2024
@brentvatne brentvatne assigned Simek and tsapeta and unassigned Simek May 9, 2024
@pavelbabenko
Copy link

Same issue
Some of icons are rendered correctly, but some not.
I found that when I switch to FontAwesome6, most of icons work correctly, but not 100%.

@efstathiosntonas
Copy link

efstathiosntonas commented May 9, 2024

@efstathiosntonas
Copy link

efstathiosntonas commented May 9, 2024

@brentvatne It seems that it works fine but it doesn't. If you send the app to the background and bring it back to foreground you will get the question mark icons. In my case I have to play around in my app and at some point the bug appears.

Test case:

  1. Open app
  2. Put app in background
  3. Open app again
  4. Navigate to a different page -> question mark shows up instead of icon

I use react-native-vector-icons@10.1.0 in a bare react-native app using expo@51, FontAwesome6 Pro.

@efstathiosntonas
Copy link

efstathiosntonas commented May 9, 2024

@brentvatne after some investigation it seems that caching the .ttf breaks it.

If I remove this code everything works as it should:

function cacheFonts(fonts: any[]) {
  return fonts.map((font) => Font.loadAsync(font));
}

/* Load icons and fonts prior rendering the app */
async function loadResourcesAndDataAsync() {
  try {
    const fontAssets = cacheFonts([
      {
        "FontAwesome6Pro-Regular": require("../assets/fonts/FontAwesome6_Pro_Regular.ttf"),
        "FontAwesome6Pro-Light": require("../assets/fonts/FontAwesome6_Pro_Light.ttf"),
        "FontAwesome6Pro-Solid": require("../assets/fonts/FontAwesome6_Pro_Solid.ttf")
      }
    ]);

    await Promise.allSettled([...fontAssets]);
  } catch (e) {
    console.log(e);
  }
}

funny thing is that if I bring the snippet back and fast refresh the icons are showing emojis among question marks

@efstathiosntonas
Copy link

efstathiosntonas commented May 9, 2024

reverting this PR fixes the issue:

expo-font+12.0.4.patch

diff --git a/node_modules/expo-font/ios/FontFamilyAliasManager.swift b/node_modules/expo-font/ios/FontFamilyAliasManager.swift
index 126d577..c86c1fa 100644
--- a/node_modules/expo-font/ios/FontFamilyAliasManager.swift
+++ b/node_modules/expo-font/ios/FontFamilyAliasManager.swift
@@ -53,21 +53,13 @@ private func maybeSwizzleUIFont() {
   if hasSwizzled {
     return
   }
-  let originalFontNamesMethod = class_getClassMethod(UIFont.self, #selector(UIFont.fontNames(forFamilyName:)))
-  let newFontNamesMethod = class_getClassMethod(UIFont.self, #selector(UIFont._expo_fontNames(forFamilyName:)))
+  let originalMethod = class_getClassMethod(UIFont.self, #selector(UIFont.fontNames(forFamilyName:)))
+  let newMethod = class_getClassMethod(UIFont.self, #selector(UIFont._expo_fontNames(forFamilyName:)))
 
-  if let originalFontNamesMethod, let newFontNamesMethod {
-    method_exchangeImplementations(originalFontNamesMethod, newFontNamesMethod)
+  if let originalMethod, let newMethod {
+    method_exchangeImplementations(originalMethod, newMethod)
   } else {
     log.error("expo-font is unable to swizzle `UIFont.fontNames(forFamilyName:)`")
   }
-  let originalInitMethod = class_getClassMethod(UIFont.self, #selector(UIFont.init(name:size:)))
-  let newInitMethod = class_getClassMethod(UIFont.self, #selector(UIFont._expo_init(name:size:)))
-
-  if let originalInitMethod, let newInitMethod {
-    method_exchangeImplementations(originalInitMethod, newInitMethod)
-  } else {
-    log.error("expo-font is unable to swizzle `UIFont.init(name:size:)`")
-  }
   hasSwizzled = true
 }
diff --git a/node_modules/expo-font/ios/UIFont+FontFamilyAlias.swift b/node_modules/expo-font/ios/UIFont+FontFamilyAlias.swift
index 5d3f077..c70e108 100644
--- a/node_modules/expo-font/ios/UIFont+FontFamilyAlias.swift
+++ b/node_modules/expo-font/ios/UIFont+FontFamilyAlias.swift
@@ -15,13 +15,4 @@ public extension UIFont {
     }
     return fontNames
   }
-  @objc
-  static dynamic func _expo_init(name fontName: String, size fontSize: CGFloat) -> UIFont? {
-    let font = UIFont._expo_init(name: fontName, size: fontSize)
-
-    if let aliasedFamilyName = FontFamilyAliasManager.familyName(forAlias: fontName) {
-      return UIFont._expo_init(name: aliasedFamilyName, size: fontSize)
-    }
-    return font
-  }
 }

@tsapeta
Copy link
Member

tsapeta commented May 9, 2024

After some investigation, I also found out that loading only one font from FontAwesome5 works fine, i.e. this works

useFonts({
  'FontAwesome5Free-Solid': FontAwesome5.font['FontAwesome5Free-Solid'],
});

but this doesn't

useFonts({
  ...FontAwesome5.font,
});

The latter also tries to use some other variants like FontAwesome5Free-Brand, FontAwesome5Free-Regular, FontAwesome5Free-Light.

@tsapeta
Copy link
Member

tsapeta commented May 9, 2024

Quick update: we gave this issue a high priority and are investigating it intensively, but the problem looks a bit more complex than we thought initially 😅

@efstathiosntonas
Copy link

@tsapeta thank you! keep it up

@tsapeta
Copy link
Member

tsapeta commented May 10, 2024

I published the fix in expo-font@12.0.5 🎉 Please let me know if that solved the problem entirely in your projects 🙂

Note: this fix will only work in development builds / release builds currently. We'll roll out it out to Expo Go in the coming days.

@pavelbabenko
Copy link

Note: to update expo-font to 12.0.5 you should run yarn add expo-font@next for now

@brentvatne brentvatne reopened this May 11, 2024
@brentvatne
Copy link
Member

a new version of Expo Go with this fix is available for the iOS simulator, it'll be installed automatically when you launch your app to it through Expo CLI. the new version is waiting in review on the App Store, but you can get it from TestFlight external beta if you like: https://testflight.apple.com/join/GZJxxfUU

@fpinatares
Copy link

Thank you @tsapeta @brentvatne!!! Icons are back!! ❤️

@anthonyn60
Copy link
Author

Thank you for the fix!

@anthonyn60
Copy link
Author

As a heads up (an aside): Expo Go is still being a little funny with imported fonts (i.e. handling boldness when it's a bold and non-bold font imported) but it works fine in my development build.

@brentvatne
Copy link
Member

@anthonyn60 - can you share a minimal reproducible example of that?

@csulit

This comment was marked as off-topic.

@brentvatne
Copy link
Member

brentvatne commented May 12, 2024

@csulit - please share a minimal reproducible example and create a new issue, that appears to be something different than the topic of this issue

@brentvatne brentvatne changed the title FontAwesome5 does not import properly with SDK 51 [ios] FontAwesome5 does not import properly with SDK 51 May 12, 2024
@anthonyn60
Copy link
Author

Feel free to dismiss what I've mentioned as it's technically inside of some Tamagui classes I've been using and I'm unable to isolate it at this point

Setting boldness using a font style class works fine for me as well on both Expo Go and a development build

@csulit
Copy link

csulit commented May 13, 2024

@csulit - please share a minimal reproducible example and create a new issue, that appears to be something different than the topic of this issue

No significant changes were made to my source code. I used yarn to create my project with the expo-router template.

No problem when using the development build but we need expo go.

  const [loaded, error] = useFonts({
    SpaceMono: require('@/assets/fonts/SpaceMono-Regular.ttf'),
    PoppinsRegular: require('@/assets/fonts/Poppins-Regular.ttf'),
    PoppinsMedium: require('@/assets/fonts/Poppins-Medium.ttf'),
    PoppinsSemiBold: require('@/assets/fonts/Poppins-SemiBold.ttf'),
    PoppinsBold: require('@/assets/fonts/Poppins-Bold.ttf'),
    PoppinsExtraBold: require('@/assets/fonts/Poppins-ExtraBold.ttf'),
    ...FontAwesome.font,
  });
"expo-font": "^12.0.5",
"expo": "~51.0.2",
"react-native": "0.74.1",

FontAwesome5 importing from FontAwesome6?
image

@brentvatne
Copy link
Member

@csulit - did you perhaps not import FontAwesome5 properly? which version of @expo/vector-icons are you using? please share a project with a minimal reproducible example to reproduce that warning.

No problem when using the development build but we need expo go.

as already mentioned in this thread:

a new version of Expo Go with this fix is available for the iOS simulator, it'll be installed automatically when you launch your app to it through Expo CLI. the new version is waiting in review on the App Store, but you can get it from TestFlight external beta if you like: https://testflight.apple.com/join/GZJxxfUU

@csulit
Copy link

csulit commented May 13, 2024

@csulit - did you perhaps not import FontAwesome5 properly? which version of @expo/vector-icons are you using? please share a project with a minimal reproducible example to reproduce that warning.

No problem when using the development build but we need expo go.

as already mentioned in this thread:

a new version of Expo Go with this fix is available for the iOS simulator, it'll be installed automatically when you launch your app to it through Expo CLI. the new version is waiting in review on the App Store, but you can get it from TestFlight external beta if you like: https://testflight.apple.com/join/GZJxxfUU

This is when I try to import FontAwesome5 by pressing control + space. Instead of pointing to FontAwesome5, it points to FontAwesome6. I am not sure if that makes sense.

"@expo/vector-icons": "^14.0.2",

image

@csulit
Copy link

csulit commented May 13, 2024

@csulit - did you perhaps not import FontAwesome5 properly? which version of @expo/vector-icons are you using? please share a project with a minimal reproducible example to reproduce that warning.

No problem when using the development build but we need expo go.

as already mentioned in this thread:

a new version of Expo Go with this fix is available for the iOS simulator, it'll be installed automatically when you launch your app to it through Expo CLI. the new version is waiting in review on the App Store, but you can get it from TestFlight external beta if you like: https://testflight.apple.com/join/GZJxxfUU

This is when I try to import FontAwesome5 by pressing control + space. Instead of pointing to FontAwesome5, it points to FontAwesome6. I am not sure if that makes sense.

"@expo/vector-icons": "^14.0.2",

image

Ooops after upgrading from 14.0.0 to 14.0.2 import issue was fixed. Kindly disregard @brentvatne thank you

@efstathiosntonas
Copy link

efstathiosntonas commented May 13, 2024

@brentvatne I'm using these versions on bare react-native:

    "expo-font": "12.0.5",
    "expo": "51.0.4",
    "expo-asset": "10.0.6",
    "expo-modules-core": "1.12.10",
    "react-native-vector-icons": "10.1.0"

And when the app is going to foreground from background I get a crash:

Screenshot 2024-05-13 at 15 11 22

Screenshot 2024-05-13 at 15 14 46

Let me know if you want any additional traces.

edit: When I downgrade to expo-font: "12.0.4" with this patch everything is back to normal.

@tsapeta
Copy link
Member

tsapeta commented May 13, 2024

@efstathiosntonas I'm not able to reproduce it, can you provide a repro? Also, for me the patch you posted before doesn't solve the original problem 😅

@brentvatne
Copy link
Member

An updated version of Expo Go is now available on the App Store, version 2.31.5. This includes the expo-font fix from #28747 and resolves this issue.

@efstathiosntonas
Copy link

efstathiosntonas commented May 14, 2024

@tsapeta @brentvatne

I just realized that it crashes when I use this in App.tsx: (in expo-font@12.0.5)

import * as Font from "expo-font";

function cacheFonts(fonts: any[]) {
  return fonts.map((font) => Font.loadAsync(font));
}

/* Load fonts prior rendering the app */
async function loadResourcesAndDataAsync() {
  try {
    const fontAssets = cacheFonts([
      {
        "FontAwesome6Pro-Regular": require("../assets/fonts/FontAwesome6_Pro_Regular.ttf"),
        "FontAwesome6Pro-Light": require("../assets/fonts/FontAwesome6_Pro_Light.ttf"),
        "FontAwesome6Pro-Solid": require("../assets/fonts/FontAwesome6_Pro_Solid.ttf")
      }
    ]);

    await Promise.allSettled([...fontAssets]);
  } catch (e) {
    notify(e, "error", "error while loading resources on initialize app");
    console.log(e);
  }
}
  useAsync(async () => {
    await loadResourcesAndDataAsync().catch();
  }, []);

If I comment out await loadResourcesAndDataAsync().catch(); then it won't crash.

edit: tried to create a reproducer and it won't crash, there's something else happening and can't spot it. I will just remove font caching for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants