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#:
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.
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.
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.
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.
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.
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.
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 + "/";
}
}