Using the Pre-export Method to call external services asynchronously

Hi,

Before the Unity build starts we need to perform a couple of backend calls (a GET and a POST).

Given that the script is not a MonoBehaviour, we can’t use Coroutines. I also tried loop through an IEnumerator, but the script execution would not wait. I then tried using async/await with UnityWebRequest with Task.Yield(), but again, it does not wait and goes on to start the build before the request finishes. It’s important for the GET request to respond before I continue the execution.

Is there a way to call an external API in the Pre-export Method and wait for the response?

An alternative I’m about to explore is to instead do the same logic in the Pre-build script instead. Is that a good alternative?

Thanks for the help!

I did a similar thing and posted a solution here ( PreExport delay for web request ). Unfortunately there doesn’t appear to be any type of async behaviour possible on these methods (happy to be proven wrong though!).

Thanks for the reply!

Indeed, that’s pretty much our use case. We were trying to avoid dangerous while loop as much as we could, and it turns out, after many days of experimentation, I finally got to something fruitful through the use of a pre-build shell script.

Basically, I do some CURL requests:

#!/bin/bash

echo "### PRE EXPORT TASK"

bundleVersionString=$( grep 'bundleVersion' ProjectSettings/ProjectSettings.asset )
IFS=': ' read -r -a array <<< "$bundleVersionString"
bundleVersion=${array[1]}

echo "### bundleVersion: $bundleVersion"

# Save latest build info from Uluweb into uluwebGetLatestBuildResponse.json
curl --header "Content-type: application/json" "${ULUWEB_ENDPOINT}/latest?platform=${PLATFORM}&version=${bundleVersion}" -o uluwebGetLatestBuildResponse.json

# Save builds from Unity Cloud Builds into unityCloudBuildsResponse.json
curl --header "Content-type: application/json" --header "Authorization: Basic ${UNITY_CLOUD_BUILD_API_KEY}" "https://build-api.cloud.unity3d.com/api/v1/orgs/260056/projects/${CLOUD_BUILD_PROJECT}/buildtargets/${BUILD_TARGET_ID}/builds" -o unityCloudBuildsResponse.json

With the responses from the GET requests saved in a json file, we then read the file in the pre-export method in C#:

var reader = new StreamReader("uluwebGetLatestBuildResponse.json");
var uluwebGetResponse = Deserialize<UluwebGetLatestBuildResponse>(reader.ReadToEnd());
reader.Close();
PlayerSettings.iOS.buildNumber = uluwebGetResponse.success ? uluwebGetResponse.data.buildNumber.ToString() : "1";

reader = new StreamReader("unityCloudBuildsResponse.json");
var cloudBuildResponse = Deserialize<UnityCloudBuildResponse[ ]>(reader.ReadToEnd());
reader.Close();

This works since the pre-build shell script always gets called before the pre-export method.

So, for anyone stuck with the same problem, that should work.

1 Like

That’s good to know you can do curl commands in the pre-build shell script, might come in handy.

I’m a little confused what you’re trying to do with it though, are you just trying to get a version number? In the cloud build PreExport commands you get a cloud build manifest which has lots of useful data.

public static void PreExport( UnityEngine.CloudBuild.BuildManifestObject manifest )
{
        string build = manifest.GetValue( "buildNumber" , null );
}

The above example gets the cloud build number which is handy to use as the build number for iOS/Android. You can also get things like the source control commit ID etc… (Unity Build Automation) The file is also copied to your resources folder and you can load it during gameplay to display things on the pause screen.

Good call, that certainly simplifies getting the right build number. So I’m down to one to our backend to do something similar to what you explained in the other thread with the external service. Thanks!

1 Like