SQLite read-only exception on iOS
Hi, my Unity project for Android and iOS uses a SQLite DB; on Android all is ok but on iOS I've a read-only exception when I run the app via Xcode:
Mono.Data.Sqlite.SqliteException: Attempt to write a read-only database
I use this code to write in the DB:
public static bool InsertInto(string tableName, String Column, String Value) {
string query = "INSERT INTO " + tableName + " (" + Column +") VALUES (" + Value + ")";
try {
dbcmd = dbcon.CreateCommand();
dbcmd.Prepare();
dbcmd.CommandText = query;
reader = dbcmd.ExecuteReader();
}
catch (Exception exception) {
Debug.LogError (exception);
return false;
}
return true;
}
To open the DB:
public static void OpenDB(string p) {
string filepath = "";
#if UNITY_EDITOR
filepath = string.Format(@"Assets/StreamingAssets/{0}", p);
#elif UNITY_ANDROID
filepath = Application.persistentDataPath + "/" + p;
if(!File.Exists(filepath)) {
Debug.LogWarning("File \"" + filepath + "\" does not exist. Attempting to create from \"" + Application.dataPath + "!/assets/" + p);
WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + p);
while(!loadDB.isDone) {}
File.WriteAllBytes(filepath, loadDB.bytes);
}
#elif UNITY_IOS
filepath = Path.Combine(UnityEngine.Application.streamingAssetsPath, p);
#endif
connection = "URI=file:" + filepath;
try {
dbcon = new SqliteConnection(connection);
dbcon.Open();
} catch (Exception exception) {
GUITxt = exception.Message + "\n" + exception.StackTrace;
Debug.LogError(exception.Message + "\n" + exception.StackTrace);
}
}
Some idea?
Thank you!
[EDIT]
I SOLVED!
Take a look at: link text
The problem is that the strea$$anonymous$$gAssetsPath is readonly so we have to copy the SQLite db file in the app Data Container, in the folder Documents, i.e. the persistentDataPath from Unity point of view. This way we could read and write the db, otherwise, if we leave it in strea$$anonymous$$gAssetsPath, we can only read.
So the correct code to open db is:
public static void OpenDB(string p) { string filepath = "";
#if UNITY_EDITOR
filepath = string.Format(@"Assets/Strea$$anonymous$$gAssets/{0}", p);
#elif UNITY_ANDROID
filepath = Path.Combine(Application.persistentDataPath,p);
if(!File.Exists(filepath)) {
Debug.LogWarning("File \"" + filepath + "\" does not exist. Attempting to create from \"" + Application.dataPath + "!/assets/" + p);
WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + p);
while(!loadDB.isDone) {}
File.WriteAllBytes(filepath, loadDB.bytes);
}
#elif UNITY_IOS
filepath = Path.Combine(Application.persistentDataPath,p);
if(!File.Exists(filepath)) {
Debug.LogWarning("File \"" + filepath + "\" does not exist. Attempting to create from \"" + Path.Combine(UnityEngine.Application.strea$$anonymous$$gAssetsPath, p));
try {
System.IO.File.Copy ((Path.Combine(UnityEngine.Application.strea$$anonymous$$gAssetsPath, p)), filepath, true);
} catch (Exception exception) {
Debug.Log ("*** FILECOPY ERROR ***");
Debug.LogError(exception.$$anonymous$$essage + "\n" + exception.StackTrace);
}
}
#endif
I hope this can help the community!
Answer by AbyssEnt · Apr 10, 2018 at 05:35 PM
Hello, I'll presume you have fixed this by now, however if you have not, and for anyone experiencing a similar issue, it is most likely because your database is stored in a read only environment.
On iOS, you will need to move the database to a different part of the device storage, I'll recommend somewhere within the documents folder for now, but it is up to you. You can use File.Move(source, dest) to copy the database.
Yes, I solved as showed above, in [EDIT] comment. Thank you.
$$anonymous$$
@AbyssEnt I saved my SQLite DB in Strea$$anonymous$$gAssets folder. when I build the app I'll find the DB in Raw folder on my iPhone. Where have I to move it to make it readable? Thanks
if (File.Exists(Application.persistentDataPath + "/Players.db") == false) { File.Copy(Application.strea$$anonymous$$gAssetsPath + "/Players.db", Application.persistentDataPath + "/Players.db"); }
This should work for you. Change your DB name of course, and set the DB path to then be persisitentdata
You can use this method to open db in Unity Editor, Android and iOS devices; the string parameter 'p' is the name of the SQLite database (Players.db, in your case).
public static void OpenDB(string p) {
string filepath = "";
#if UNITY_EDITOR
filepath = string.Format(@"Assets/Strea$$anonymous$$gAssets/{0}", p);
#elif UNITY_ANDROID
filepath = Path.Combine(Application.persistentDataPath,p);
if(!File.Exists(filepath)) {
Debug.LogWarning("File \"" + filepath + "\" does not exist. Attempting to create from \"" + Application.dataPath + "!/assets/" + p);
WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + p);
while(!loadDB.isDone) {}
File.WriteAllBytes(filepath, loadDB.bytes);
}
#elif UNITY_IOS
filepath = Path.Combine(Application.persistentDataPath,p);
if(!File.Exists(filepath)) {
Debug.LogWarning("File \"" + filepath + "\" does not exist. Attempting to create from \"" + Path.Combine(UnityEngine.Application.strea$$anonymous$$gAssetsPath, p));
try {
System.IO.File.Copy ((Path.Combine(UnityEngine.Application.strea$$anonymous$$gAssetsPath, p)), filepath, true);
} catch (Exception exception) {
Debug.Log ("*** FILECOPY ERROR ***");
Debug.LogError(exception.$$anonymous$$essage + "\n" + exception.StackTrace);
}
}
#endif
I hope you find it useful!
Your answer

Follow this Question
Related Questions
iOS can't connect to SQLite DB 1 Answer
Got unwanted motion blur on fast moving object (Only iOS) 0 Answers
Can't find shader on iOS - GpuProgram creation error: shader program type is unrecognised. 2 Answers
running error: dyld: Symbol not found: __ZN14Il2CppIUnknown3IIDE unity5 to xcode8.0 0 Answers