Unity Android build

Hi, Hope you all doing great.

We are currently trying to build an Android version of the SpecklePlayground and curious to learn how the current implementation of the project can be detached from the SpeckleManagerConnector.

I would imagine we need to take advantage of the “Personal Access Tokens”. Are there any pointers or instructions to follow?

Many thanks in advance.

1 Like

I am interested as well. Have similar question but for iOS builds.
I would assume same answer will apply.


I’m very interested in enabling Android and IOS development with the Speckle Unity connector, as this is something we don’t do a great job currently of supporting.

You are quite correct, the best way to approach this currently, is through personal access tokens. These can be generated from your profile page.

Within Unity, you will notice that our Receiver and Sender components can be initialised optionally with an Account object. - speckle-unity/Receiver.cs at main · specklesystems/speckle-unity · GitHub

Normally this account is fetched from the AccountsManager.
But it is possible to simply create one manually, with an auth token specified.

      string token = "REPLACE WITH TOKEN";
      string serverUrl = "https://speckle.xyz";
      var account = new Account()
        token = token,
        serverInfo = new ServerInfo() {url = serverUrl},

I’ve given this a quick test for the Receiver component (on windows), and it appears to work fine.

But there may be a few other places where we have forgotten to expose that Account parameter.

I’ve gone and tracked this issue on our GitHub Support for Android/IOS platforms · Issue #68 · specklesystems/speckle-unity · GitHub
I have some time next week to take a look, and see what’s needed to get an Android build working. I’ll keep you updated with my progress :grin:


Not sure if this has changed, but something to keep in mind regarding mobile support


Hi all, I’ve done some testing of our Unity connector on android.
I’ve made some progress, but have run into a bit of a blocker.

The good news is, I’ve managed to get a build working nicely, There were a couple dll conflicts that were easy enough to solve. And I’ve tested a build of the Speckle Playground project on my Samsung S8+ and Quest 2.

The bad news is, I’m having trouble receiving objects. :scream:
I’m running into issues with async functions never starting (a problem we’ve faced before)

It looks like there might be differences between how UnitySynchronizationContext behaves on android :cry:

@haitheredavid How far did you get implementing UniTask in your own project?
perhaps that could solve the async issue on android.

@Jedd I’ve actually ditched the UniTasks for any send / receive calls. The package declares there is no overhead or allocation needed for converting a Task to UniTasks but whenever I did the conversion with something like Operations.Receive it would clog up all my CPU’s. I came to the conclusion that I would only use unitask for unity based methods.

I don’t recall having any issues with unity and awaitable calls when building to android, but I wouldn’t be surprised if there is some sort of catch. Were you able to send objects? Would be curious to know where the operation breaks, I suspect it might have to do with some sort of HTTP call.

1 Like


Thanks for looking into this. We have made some progress our end as well. We did manage to build and read streams on Android.

Unfortunately, we’ve run into another issue. Send and receive operations throw a “IOException: Read-only file system”.

Have you encountered that before? any ideas how to solve this?

1 Like

Correction… Send operations actually getting executed correctly. The above error is thrown on Receive operations only!

1 Like


I can explain why this error might be happening, suggest a few quick and dirty fixes, and then perhaps discuss some more long term fixes to this issue.

This issue appears to be related to SQLite transports.
This is the transport we use (by default) to cache objects on your local machine (Local Transport).

You can read more about what Transports are here, but in a nut shell, transport is an interface to a data store (of speckle objects). We have a few different transports for different needs (server ones for interfacing with a server, and local ones (memory, disk, SQLite).

Clearly, from your error, SQLite transports aren’t working nicely (maybe because they are looking for a database file in windows appdata directory.)

It’s not too surprising that this doesn’t work with Android, so I imagine this is what you are running into.

A quick and dirty fix, would be to specify your own localTransport when calling Operations.Receive. That way, it won’t try and use the “default” SQLite one.

        var transport = new ServerTransport(Client.Account, StreamId);
        var localCache = new MemoryTransport();
        var @base = await Operations.Receive(
          remoteTransport: transport,
          localTransport: localCache,
          onErrorAction: OnErrorAction,
          onProgressAction: OnProgressAction,
          onTotalChildrenCountKnown: OnTotalChildrenCountKnown,
          disposeTransports: true

Although, recreating a new memory transport for every receive operation is quite wasteful, and pointless as a cache. So you may want to consider making that localCache a field so it gets reused.

However, this isn’t an ideal situation.

I can think of a few better options we could explore:

  1. Get SQlite transports working on android
  2. If SQLite transports flat-out don’t work on android, then they shouldn’t be the default local transport for android (duh!)
  3. Provide a way to explicitly specify “no cache”, e.g. implement a “null”/“non” transport.

Hopefully with my “quick and dirty” suggestion, you are able to get something working.
I will continue some tests my end.
Please do let me know if you have any difficulties, this exploratory feedback is super valuable to us, and hopefully will allow us to support non-desktop platforms going forward.