Example to use it with expo go
Closed this issue · 8 comments
Sometimes we just want to use expo go to debut other parts of app, here is how to do it
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
import type { useShareIntent as IUseShareIntent } from 'expo-share-intent';
import { useEffect } from 'react';
import { useRegisterProxy } from 'react-native-postmessage-cat';
import { nativeService } from '.';
import { NativeServiceIPCDescriptor } from './descriptor';
export function useNativeService() {
const [webViewReference, onMessageReference] = useRegisterProxy(nativeService, NativeServiceIPCDescriptor);
return [webViewReference, onMessageReference] as const;
}
export function useRequestNativePermissions() {
useEffect(() => {
void (async () => {
await nativeService.requestCameraPermission();
await nativeService.requestMicrophonePermission();
})();
}, []);
}
export function useRegisterReceivingShareIntent() {
/** If you get error on development:
* ```
* Error: Cannot find native module 'ExpoShareIntentModule', js engine: hermes
* Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called., js engine: hermes
* ```
*
* Comment out this import will work.
*
* Also comment out all code inside `useRegisterReceivingShareIntent`.
*/
if (process.env.NODE_ENV === 'development') {
return;
}
const { useShareIntent } = require('expo-share-intent') as { useShareIntent: typeof IUseShareIntent };
/* eslint-disable react-hooks/rules-of-hooks */
const { hasShareIntent, shareIntent, resetShareIntent, error } = useShareIntent({
debug: true,
});
useEffect(() => {
if (error !== undefined) {
console.log(
`Failed to get ShareIntent, This is normal if you are using Expo Go for dev. To debug sharing feature, create a dev build "pnpm start:devClient" instead. ${error}`,
);
}
void (async () => {
try {
if (hasShareIntent) {
await nativeService.receivingShareIntent(shareIntent);
resetShareIntent();
}
} catch (error) {
console.log(
`Failed to registerReceivingShareIntent, This is normal if you are using Expo Go for dev. To debug sharing feature, create a dev build "pnpm start:devClient" instead. ${
(error as Error).message
}`,
);
}
})();
}, [hasShareIntent, shareIntent, resetShareIntent, error]);
}
and start it with
"android": "cross-env NODE_ENV=development expo start --go --android",
It was easier when this lib also export non-hook api, but I find it is possible to workaround it today, so share with anyone with same problem.
wow !
thanks for sharing your example, sounds a bit complex but it's a good start :)
wondering if i can add something like that in a futur version :
useShareIntent({
disabled: true,
});
Notice that my previous code that use expo-share-intent
was:
import { ShareIntent } from 'expo-share-intent';
/// ...
if (process.env.NODE_ENV === 'development') {
return;
}
ReceiveSharingIntent.getReceivedFiles(
async (
files: ISharedFile[],
) => {
// ...
If I early return, just before actually calling the imperactive api, it was safe.
But in this version it still throw error when import the hook
import { useShareIntent } from 'expo-share-intent';
// ...
if (process.env.NODE_ENV === 'development') {
return;
}
/* eslint-disable react-hooks/rules-of-hooks */
const { hasShareIntent, shareIntent, resetShareIntent, error } = useShareIntent({
debug: true,
});
Still throw the error Error: Cannot find native module 'ExpoShareIntentModule', js engine: hermes
! So my workaround above use require
inline.
Anyway this workaround does work, just for people googled here, closing this issue.
I haven't get sharing work yet, because expo's dev client is not working, and they don't want to fix it expo/expo#27536
🤔 By the way, ReceiveSharingIntent.getReceivedFiles
should not be used with this package, make sure you removed expo-config-plugin-ios-share-extension
and react-native-receive-sharing-intent
.
Thanks, I know that, I was just post old code to illustrate that old package can import and then conditionally block execution. But the new package is different.
You can now simply disabled share intent to run it into expo go (v1.2.0
and v0.4.0
)
For example :
const { shareIntent } = useShareIntent({ disabled: process.env.NODE_ENV === 'development'})
<ShareIntentProvider options={{ disabled: process.env.NODE_ENV === 'development'}}>
<App />
</ShareIntentProvider>
Many thanks, this is convenient.
Hi, I'm trying to use this new disabled
option, but I can't get it to work. I downloaded the repo and modified expo-router
example by just adding disabled: true
in _layout.tsx
:
export default function Layout() {
const router = useRouter();
return (
<ShareIntentProvider
options={{
disabled: true,
debug: true,
resetOnBackground: true,
onResetShareIntent: () =>
// used when app going in background and when the reset button is pressed
router.replace({
pathname: "/",
}),
}}
>
<Slot />
</ShareIntentProvider>
);
}
When running the code using expo start
I get:
ERROR TypeError: Cannot read property 'useState' of null
This error is located at:
in ShareIntentProvider (created by Layout)
in Layout
in Unknown (created by Route())
in Suspense (created by Route())
in Route (created by Route())
in Route() (created by ContextNavigator)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by wrapper)
in wrapper (created by ContextNavigator)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by ContextNavigator)
in ContextNavigator (created by ExpoRoot)
in ExpoRoot (created by App)
in App (created by ErrorOverlay)
in ErrorToastContainer (created by ErrorOverlay)
in ErrorOverlay (created by withDevTools(ErrorOverlay))
in withDevTools(ErrorOverlay)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent), js engine: hermes
Also it complains about the rule of hooks violation.
I tried to use the package in my project with disabled: true
but it also doesn't work. That's why I tried with the example.
Is this example correct at the moment? Do I do something wrong?
Btw, thank you very much for this package and updates to it!