How to configure ejected application to work offline?

I’ve ejected application to use with ExpoKit, because I need to ship it with bundled audio resources. But I cannot find a way to make it actually bundle everything together.
I’ve tried these steps:

  1. Changing schema to Release. Does not work on its own. I got error when launching on device. From other answer I see that it was expected.
  2. Running exp publish. It allowed to launch app on device. But if I launch app in offline, it says that there was a problem loading app.
  3. Looking at how regular RN projects looks like. They have main.jsbundle. But I don’t see anything like that in project created by Expo.

Unfortunately I could not find any additional information on the internet. It says that after ejecting I should be able to use project as if I would use regular RN project, but I cannot figure out this bundle stuff. :frowning:

1 Like

hi @rtemchenko, afaik ejected offline applications are supported by ios but not yet supported on android

@quinlanj I am building it for iOS. :frowning:
Can I somehow at least include assets in ejected app, so that on Android js is still loaded from the internet, but audios are retrieved locally?
Also is there a way to use ExpoKit modules with RN default build system? I have whole Audio player written using Expo. But that’s basically all that I use Expo for. Unfortunately I am not in a position to rewrite it to some other Audio player framework. :frowning:

You can use assets the same way as in a raw React Native app: Images · React Native

What exactly do you mean by RN default build system? You’ll need to use XDE or exp to publish your app with ExpoKit right now.

@jesse I will try the trick with assets. But still I did not figure out how to embed js bundle in app instead of expo servers.
By default RN system I meant the one you get by react-native init. Where RCTBridge is set up in app delegate with js bundle URL.
I also see that Expo uses bundle url to load bundle. So technically it should be possible to have an URL that points to local bundle and embed that bundle instead of pushing it to the server.
Actually I added flag “isRemoteJSEnabled” in different places, and now I see in log: “JS downloads are not allowed. Local resource will be used if it exists.” And “No cache exists for this resource: kernel.ios.bundle”. So I guess I am on the right way but I missed configuration step somewhere.

Where RCTBridge is set up in app delegate with js bundle URL

That’s not possible right now with detached Expo. We definitely want to make this more configurable, but just haven’t had time to build that yet.

@jesse I actually found sources of evil. For bundle to work it should be renamed to kernel.ios.bundle. shell-app.bundle is not used. For offline attachments to work monkey patching is required.

Overriding kernel.ios.bundle is a bad idea and has high risk of leading to unexpected behavior. I don’t recommend that.

@ben shell-app.bundle is not picked up for some reason. I did not dig much why is that. But behaviour is consistent, kernel.ios.bundle is requested all the time because manager for such bundle is used.
I totally agree that it is not good, and I don’t recommend it to anybody in normal project. But for my project it works, because future upgrades or maintenance are not required.

@ben any other method to solve this issue?. I ask for many times in expo forums. thks

actually it work for me! I also set isRemoteJSEnabled=NO in EXShell.plist.

Afaik its not currently possible to bundle assets in standalone apps. This should be supported with Expo 23 or later.

https://docs.expo.io/versions/latest/introduction/why-not-expo.html

I upgraded to expo 25.0.0. Detached, set isRemoteJSEnabled=NO in EXShell.plist, and got the same error. I thought offline app is supported in late versions of Expo. How do I solve this? I got this error on iOS.

1 Like

Any update on that?

Hi. I just tested with expo 32.0.0 and ejected a fresh project to expokit. It doesn’t start offline either. My app.json:

"updates": {
  "fallbackToCacheTimeout": 0,
  "enabled": false
},