Null Reference Exception in XCode but not in Unity

Greetings good people.

In XCode, my app give me the following exception “NullReferenceException: Object reference not set to an instance of an object.” I traced it to a piece of code that reads data from an SQLite database. In the Unity editor the code works fine with no such error. I tried playing around with the file path but that seems to make no difference.

This is the method that is flagged in XCode - note that this is how it appears in C#:

void OnRequestDataForAppStartUp()
    {
        UserInformation userInformation = GetUserInformation();
        SendDataForAppStartUpEvent?.Invoke(userInformation);
    }

The code that returns UserInformation will return a working object even if the data is not accessed, so it will not be a null object.

As I said, everything works in Unity so I am trying to figure out what is wrong.

Any ideas? Any help would be appreciated.

Thanks

Some notes on how to fix a NullReferenceException error in Unity3D

  • also known as: Unassigned Reference Exception
  • also known as: Missing Reference Exception

http://plbm.com/?p=221

The basic steps outlined above are:

  • Identify what is null
  • Identify why it is null
  • Fix that.

Expect to see this error a LOT. It’s easily the most common thing to do when working. Learn how to fix it rapidly. It’s easy. See the above link for more tips.

It works fine in Unity3d with no errors whatsoever. It’s when the app runs on the iPhone that I get this error.

Still have to apply the above steps, but now you need to look in the XCode log window (or for Android use adb logcat) to see what the null reference is. It may also be helpful to attach the debugger and see the crash directly.

Thanks. I am following the steps you suggested and that’s how I found the information in XCode.

Specifically, the error in XCode is:

NullReferenceException: Object reference not set to an instance of an object.

at DataManager.OnRequestDataForAppStartUp () [0x00000] in <00000000000000000000000000000000>:0

at ManagerControllerApplication+RequestDataForAppStartUp.Invoke () [0x00000] in <00000000000000000000000000000000>:0

at ManagerStartup+RequestDataForAppStartUp.Invoke () [0x00000] in <00000000000000000000000000000000>:0

I am going to have to figure out how to debug in XCode since I only know how to build it from Unity and run it on the iPhone via XCode.

Thanks again.

Do you have any of those classes in your app? What if you build a trivial app with a blank scene? Do you get the error? Does it run on Android? Does it run for PC? WebGL?

Also, this smells like it might be related to the new user data permissions in iOS 14, but only if it’s not your stuff above.

I have all of those classes in my app. I will try a trivial app with a blank scene. Thanks for that suggestion.

I have only tested it on the iPhone thus far.

I will look into the iOS 14 issue you mentioned.

Actually it works pretty good:

https://discussions.unity.com/t/714123

you need to do some things like turn on development mode (tickbox in editor build settings) and leave xcode open, but it’s purrrty nice.

Thanks. I will try this immediately!

Look for anything being loaded with System.IO methods… none of those will work on iOS unless the target asset is contained in your StreamingAsset folder and you do the right mungling of the path first. Google has the deets.

Ok. Thanks. I will check to make sure I am not using System.IO

I have tried the paths. One time I changed the application path and it said it could not open the file. However, I changed it back then it no longer gave me the could not open file error, but it gave me the current error.

Generally speaking, with the exception of the StreamingAssets, absolutely nothing contained in your Assets folder can be opened with standard file IO, even though you might get it going fine in the editor.

Gotta use Unity to reach for that stuff always… The reason: Unity mungles your assets into a format optimal for the target build, and many other reasons related to closed-ecosystem constraints.

Good to know.

Another cause of this is using the Shader.Find() stuff… if you don’t have an instance of the shader you’re looking for referenced SOMEWHERE in your project, Unity will not include it in the build, even if you ask for it.

So I checked. I am using System.IO but it’s in an unrelated class that is not even loaded and it is not even in the first scene that loads. The scene with that class that uses System.IO does not even load until the user requests it. The class that is throwing the error is simply trying to load the home screen and is in the first scene that loads.

You’ll find it… just keep simplifying and chopping stuff out until you do! Cue chainsaw emoji…

Welp…I fixed the Null Reference error. Now I am just dealing with the SQLite error. It says it can’t open the file.

At least that’s progress.

1 Like

Now that you have identified the ACTUAL issue, it just so happens that I have direct experience with this problem!

Basically what I found is that on Android, and possibly on iOS (I don’t recall), the SQLite package could NOT open the database even when it was present in the StreamingAssets folder and I gave it the correct path.

The solution was to simply stream it all out of StreamingAssets and write it to Application.persistentDataPath, then pass that path to SQLite.

The downside was that the apparent installed size of our app went up by the amount of the database, and in our case it was only 6mb or so, so not huge.

Are you saying to copy it out of the Streaming Assets location and write it to the persistent path location then use that location? Would I have to check to see if it was copied each time I run the app? I am on iOS btw.

Thanks also. This information is very helpful.

I just looked up the code and at the time (3+ years ago) we only did it for Android. I think it worked fine on iOS with the correct Streaming Assets path.

Are you using the correct runtime Streaming Assets path? It’s actually conditional on the target platform. Here’s my shim for making both path and URI:

using UnityEngine;

public static class StreamingAssetsPath
{
    public static string StreamingAssetPathForWWW()
    {
        #if UNITY_EDITOR || UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
        return "file://" + Application.dataPath + "/StreamingAssets/";
        #endif
        #if UNITY_ANDROID
        return "jar:file://" + Application.dataPath + "!/assets/";
        #endif
        #if UNITY_IOS
        return "file://" + Application.dataPath + "/Raw/";
        #endif
        throw new System.NotImplementedException( "Check the ifdefs above.");
    }
    public static string StreamingAssetPathForFileOpen()
    {
        #if !UNITY_EDITOR && UNITY_ANDROID
        throw new System.NotImplementedException( "You cannot open files on Android. Must use WWW");
        #endif

        Debug.Log( "Application.streamingAssetsPath:" + Application.streamingAssetsPath);
        return Application.streamingAssetsPath + "/";
    }
}