6

I'm using CodePush to deploy the js bundle and a couple of resources to my react-native iOS app. Instead of using the react-native bundler to collect all the static images from my project I have a build step that just copies a folder called "static" into release/assets. But beside the "static" folder I als have other folders in release/assets that contain images and videos wich are use dynamically in the app via uri (e.g. { uri: 'assets/images/myImage.jpg' }). When building the app in XCode I just include the assets folder in the package.

From the CodePush documentation I gather that deploying the release folder should update all my assets. But it doesn't.

I downloaded the xcappdata via XCode and there you can see, that CodePush downloaded everything and stored it in /Library/Application Support/CodePush/[id]/release. But it still doesn't show up in the app.

Any ideas? Do I misunderstand the functionality of CodePush?

HoldOffHunger
  • 10,963
  • 6
  • 53
  • 100
d-vine
  • 4,397
  • 2
  • 22
  • 25

1 Answers1

9

As you've seen, when you release a directory to the CodePush server via the CLI, it will round trip the entire contents of it to end-user's devices when they perform an update check/synchronization. That said, just because a file is in that update doesn't mean it will be useable unfortunately.

The behavior that you're seeing is actually a limitation of the way that the Image component resolves URIs in React Native. If you use the assets system to specify the "source" property (via a require("image.png") call), it will look for that file relative to the currently running JS bundle. This is how CodePush allows updating images, because as long as our plugin places the "assets" folder next to the JS bundle file on disk, the <Image> component will naturally find them.

However, when you specify an object with a URI (as you're doing) as the value of the "source" property, the Image component looks for that file relative to the binary on disk, and therefore, it will never look for it where it was placed by CodePush when you update them.

Because of this, CodePush only supports updating images which are loading via the require syntax. I'll make sure to update our docs to clarify that. Apologies for the confusion!

Mr Lister
  • 42,557
  • 14
  • 95
  • 136
Jonathan Carter
  • 1,009
  • 9
  • 16
  • Thanks Jonathan. Your answer gave me an idea. If I could determine the path of the current bundle at runtime I could build the appropriate URI. But I also have another question. You said "it will round trip the entire contents". Does it mean the client has two download all the media files in the package every single time? In your doc's you say something about differential updates. Does this include all assets or just the static ones. And if so, how do you determine a dirty cache / changed file? – d-vine Feb 07 '16 at 04:00
  • Yeah apologies, the server would still generate a diff update and send only the changed files to the client. So if you only changed a single static image and did a CodePush release, users would only download that single file, despite the fact that it wouldn't be usable. – Jonathan Carter Feb 07 '16 at 04:32
  • Is there a way to obtain the path of the current JS bundle via the API? If not then this is a feature request. One could then very easily do e.g. { path: codePush.getBundlePath(), uri: 'assets/images/myImage.jpg' } – d-vine Feb 07 '16 at 15:31
  • It isn't a documented API, but on iOS you could call [CodePushPackage getCurrentPackageFolderPath] in Obj-C to get the folder of the latest update, which would include your updated assets. We don't expose this to JS currently though, so you'd have to bridge it yourself. We could add an item to the backlog to do this if it would be valuable. Maybe open a bug on GitHub? I'd be interested to understand why you aren't using the RN assets system to handle your images, since we're currently not thinking of optimizing support for static images, so it would be great to know if we're missing a scenario – Jonathan Carter Feb 07 '16 at 17:55
  • Thanks. I'll give getCurrentPackageFolderPath a shot. The nature of the assets is more dynamic. Their URIs are generated from data at runtime. I'm trying to (ab)use CodePush as a kind of an asset pre-loader until I have the time to build a truly dynamic pre-loader and cache. – d-vine Feb 07 '16 at 22:13
  • Ah Ok cool. We can definitely bridge this data through to JS if that would help this scenario. Ping me at joncart@microsoft.com if you want to discuss this further. I want to make sure you're unblocked! – Jonathan Carter Feb 07 '16 at 23:01
  • This was a couple of years ago – @JonathanCarter do you know if there's been any progress on this? We also have a use-case where we have an assets folder and build image urls dynamically (aka "static" file reference) – chichilatte Nov 02 '18 at 15:08