I'm having trouble accessing my web service from Unity if it is not running on port 80. This is the C# code that I'm using in Unity
private void RunSimulation()
{
string url = #"http://192.168.1.116:9000/simulate";
WWW goServer = new WWW(url);
}
On 192.168.1.116, I have a program written in go that is listening on port 9000. I can easily reach this URL from a web browser and I will get my expected result.
When I try this in Unity, if I examine the contents of my goServer variable, I will see the message
System.Security.Exception: No valid crossdomain policy available to allow access
There is a crossdomain policy file. It is located at /var/www/html/crossdomain.xml Is has the following contents:
<allow-access-from domain="*" to-ports="*" secure="false"/>
<site-control permitted-cross-domain-policies="all"/>
This file existed before and there were .php programs that were able to successfully be called. I added the to-ports"*" to try to get it to work, but no luck.
I have tried having my go server listen on port 80. When I do this, I am able to connect from Unity. Any idea?
(The input sanitizer is defeating me and I can't figure out how to post without the input form telling me that my links are not allowed, so I'm going to omit 192.168.1.116:9000)
I was not getting anything at serverurl.com:9000/crossdomain.xml
So I put some code into my go server to respond to this request and return a response with headers Access-Control-Allow-Origin, Access-Control-Allow-Headers, and Access-Control-Allow-Credentials.
I set the ENABLE_CROSSDOMAIN_LOGGING environment variable. I see this in the log file plus a bunch more
Determining crossdomain.xml location for request: /simulate?asdfa=sadfsa
About to parse url: /simulate?asdfa=sadfsa
Determining crossdomain.xml location for request:/simulate?asdfa=sadfsa
About to parse url: /crossdomain.xml
About to parse url: /simulate?asdfa=sadfsa
Determining crossdomain.xml location for request: /simulate?asdfa=sadfsa
Download had OK statuscode
Received the following crossdomain.xml
----------
----------
received policy
BuildFlashPolicy caught an exception while parsing
/crossdomain.xml: Policy can't be constructed from empty stream.
ArgumentException: Policy can't be constructed from empty stream.
at MonoForks.System.Windows.Browser.Net.FlashCrossDomainPolicy.FromStream (System.IO.Stream originalStream) [0x00000] in :0
at MonoForks.System.Windows.Browser.Net.CrossDomainPolicyManager.BuildFlashPolicy (Boolean statuscodeOK, MonoForks.System.Uri uri, System.IO.Stream responsestream, System.Collections.Generic.Dictionary`2 responseheaders) [0x00000] in :0
UnityEngine.WWW:get_assetBundle()
PlayEditorMain:RunSimulation() (at Assets\Scripts\Play Editor Scripts\Menu Scripts\PlayEditorMain.cs:526)
PlayEditorMain:ButtonPressed(GameObject) (at Assets\Scripts\Play Editor Scripts\Menu Scripts\PlayEditorMain.cs:261)
MainMenuButton:OnClick() (at Assets\Scripts\Play Editor Scripts\Menu Buttons\MainMenuButton.cs:23)
UnityEngine.GameObject:SendMessage(String, Object, SendMessageOptions)
UICamera:Notify(GameObject, String, Object) (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:765)
UICamera:ProcessTouch(Boolean, Boolean) (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:1435)
UICamera:ProcessMouse() (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:1063)
UICamera:Update() (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:909)
(Filename: Assets/Scripts/Play Editor Scripts/Menu Scripts/PlayEditorMain.cs Line: 526)
Unable to determine the audio type from the URL (/simulate?asdfa=sadfsa) . Please specify the type.
UnityEngine.WWW:GetAudioClip(Boolean, Boolean, AudioType)
UnityEngine.WWW:GetAudioClip(Boolean, Boolean) (at C:\BuildAgent\work\d63dfc6385190b60\artifacts\EditorGenerated\Utils.cs:308)
UnityEngine.WWW:GetAudioClip(Boolean) (at C:\BuildAgent\work\d63dfc6385190b60\artifacts\EditorGenerated\Utils.cs:301)
UnityEngine.WWW:get_audioClip() (at C:\BuildAgent\work\d63dfc6385190b60\artifacts\EditorGenerated\Utils.cs:293)
PlayEditorMain:RunSimulation() (at Assets\Scripts\Play Editor Scripts\Menu Scripts\PlayEditorMain.cs:526)
PlayEditorMain:ButtonPressed(GameObject) (at Assets\Scripts\Play Editor Scripts\Menu Scripts\PlayEditorMain.cs:261)
MainMenuButton:OnClick() (at Assets\Scripts\Play Editor Scripts\Menu Buttons\MainMenuButton.cs:23)
UnityEngine.GameObject:SendMessage(String, Object, SendMessageOptions)
UICamera:Notify(GameObject, String, Object) (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:765)
UICamera:ProcessTouch(Boolean, Boolean) (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:1435)
UICamera:ProcessMouse() (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:1063)
UICamera:Update() (at Assets\3rd Party\NGUI\Scripts\UI\UICamera.cs:909)
[C:/BuildAgent/work/d63dfc6385190b60/Runtime/Audio/AudioClip.cpp line 118]
(Filename: Assets/Scripts/Play Editor Scripts/Menu Scripts/PlayEditorMain.cs Line: 526)
So I think I am now returning the correct headers, but I'm thinking that I also need to return the contents in the body. I'm thinking that I'll just return the same contents that the crossdomain.xml file I get when I query it on port 80.
I know that the crossdomain.xml endpoint on my server is being hit. If I understand what the logfile that unity is outputting, the problem might just be that the body is empty and I have an empty stream.
No proxy needed, unity has logging crossdomain stuff built in: take a look at the the debuging section of the unity3d manual on the security sandbox and turn on crossdomain debugging with ENABLE_CROSSDOMAIN_LOGGING. Then look for the results in the logs.
Just to be sure, a crossdomain file is reachable at http://192.168.1.116:9000/crossdomain.xml?
What I had to do was implement my own version of the crossdomain.xml endpoint. It currently looks like this.
func crossdomain(res http.ResponseWriter, req *http.Request) {
log.Println("At the top of crossdomain")
if origin := req.Header.Get("Origin"); origin != "" {
res.Header().Set("Access-Control-Allow-Origin", origin)
}
res.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
res.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token")
res.Header().Set("Access-Control-Allow-Credentials", "true")
body := "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">" +
"<cross-domain-policy>" +
"<site-control permitted-cross-domain-policies=\"all\"/>" +
"<allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\"/>" +
"<allow-access-from domain=\"*\" to-ports=\"*\"/>" +
"<allow-access-from domain=\"*\"/>" +
"<allow-http-request-headers-from domain=\"*\" to-ports=\"*\"/>" +
"<allow-http-request-headers-from domain=\"*\"/>" +
"<site-control permitted-cross-domain-policies=\"all\"/>" +
"</cross-domain-policy>"
io.WriteString(res,body)
}
func main() {
http.HandleFunc("/simulate", simulate)
http.HandleFunc("/crossdomain.xml", crossdomain)
listenErr := http.ListenAndServe(":9000", nil)
}
Related
I'm using Unity 2019.3.6f1. I have created a simple DLL for connecting to Azure and uploading a file. However, when I call this DLL to attemp connecting to the Azure blob storage I get the following stack trace:
NotImplementedException: The method or operation is not implemented.
System.Net.Http.HttpClientHandler.get_MaxConnectionsPerServer () (at
<7ebf3529ba0e4558a5fa1bc982aa8605>:0)
Azure.Core.Pipeline.ServicePointHelpers.SetLimits
(System.Net.Http.HttpMessageHandler messageHandler) (at
:0)
Azure.Core.Pipeline.HttpClientTransport.CreateDefaultClient () (at
:0)
Azure.Core.Pipeline.HttpClientTransport..ctor () (at
:0)
Azure.Core.Pipeline.HttpClientTransport..cctor () (at
:0) Rethrow as
TypeInitializationException: The type initializer for
'Azure.Core.Pipeline.HttpClientTransport' threw an exception.
Azure.Core.ClientOptions..ctor () (at
:0)
Azure.Storage.Blobs.BlobClientOptions..ctor
(Azure.Storage.Blobs.BlobClientOptions+ServiceVersion version) (at
:0)
Azure.Storage.Blobs.BlobServiceClient..ctor (System.String
connectionString, Azure.Storage.Blobs.BlobClientOptions options) (at
:0)
Azure.Storage.Blobs.BlobServiceClient..ctor (System.String
connectionString) (at :0)
Cineon.UnityToAzureConnection+d__1.MoveNext () (at
<5252723c79f94a8cb77bb25e3b9f0396>:0)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at
<437ba245d8404784b9fbab9b439ac908>:0)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_0
(System.Object state) (at <437ba245d8404784b9fbab9b439ac908>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at
:0)
UnityEngine.UnitySynchronizationContext:ExecuteTasks()
Here is my DLL code (in line with this Microsoft quickstart guide):
public class UnityToAzureConnection
{
private readonly static string m_connectionString = "CENSORED";
public static async void CreateConnection(string _path, string _fileName)
{
BlobServiceClient blobServiceClient = new BlobServiceClient(m_connectionString);
BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync("imagetest");
BlobClient blobClient = containerClient.GetBlobClient(_fileName);
using (FileStream _fs = File.Open(Path.Combine(_path, _fileName), FileMode.Open))
{
await blobClient.UploadAsync(_fs, true);
}
}
}
I simply call this DLL's CreateConnection method and pass in my "Application.dataPath" and a filename. However, I then get the above exception.
I have pulled all other needed DLL's from the project build folder into the plugin folder, so am unsure why this is occuring.
Any assistance would be greatly appreciated.
Please note that I am just starting to move out of my comfort zone here, so I'm hoping that my post is to StackOverflow's standard of questions.
[P.S.] Obviously "CENSORED" isn't my actual connection string, just keeping sensitive info hidden.
UPDATE 29/05/2021 I have confirmed that my connection code DOES work when used in a simple .net console app (however, I did have to adjust the containername to be all lowercase). This error only occurs in Unity. Again, any and all help would be appreciated.
As I mentioned here, try it once.
If you have a lower version of Unity, Azure.Core ver. 1.19.0 may be better.
https://forum.unity.com/threads/attempting-to-connec-to-azure-blobs-results-in-notimplementedexception.1117705/
I have experienced the same exception in BlobServiceClient constructor in my mobile project.
The problem was in the version of Azure.Storage.Blobs package. I used the most recent version 12.12.0, and it caused the exception.
When I downgraded Azure.Storage.Blobs package to 12.9.1 all things worked fine.
I'm trying to apply the MongoDB with this unity tutorial MongoDB bought mLab, so the signing into mongoDB is done via mongoDB atlas. And they only support MongoDB 3.6 and later.
I've created a cluster with AWS (similarly to the GUI mLab has),
On "Overview" tab hit the "CONNECT" button. Out of the three options: "Connect with the Mongo Shell" / "Connect Your Application" / "Connect with MongoDB Compass" - Connect Your Application looked the most relevant to the code you've provided.
In: "Connect Your Application" you need to choose a driver: I chose C# / .NET (because this is a C# project), version 2.5 or later.
Got "Connection string": mongodb+srv://user_name:<password>#testmp-pkump.mongodb.net/test?retryWrites=true
Few things:
The project name is not "test" (as it says here, right before the retryWrites = true): mongodb+srv://:#testmp-pkump.mongodb.net/test?retryWrites=true
I've passed this link to the code under: private const string MONGO_URI , and for user name I write the user I've added to the cluster, and for the password, I write the password I've added to the user in the cluster. - and not the user I've used to create the MongoDB account
Running the "Server" scene resolves with an error: =
ArgumentException: Invalid keyword 'mongodb+srv://:#serverclientmp-
1oqao.gcp.mongodb.net/test?retrywrites'.
MongoDB.Driver.MongoConnectionStringBuilder.set_Item (System.String
keyword, System.Object value)
System.Data.Common.DbConnectionStringBuilder.ParseConnectionStringNonOdbc
(System.String connectionString)
System.Data.Common.DbConnectionStringBuilder.ParseConnectionString
(System.String connectionString)
System.Data.Common.DbConnectionStringBuilder.set_ConnectionString
(System.String value) MongoDB.Driver.MongoConnectionStringBuilder..ctor
(System.String connectionString)
MongoDB.Driver.MongoClient.ParseConnectionString (System.String
connectionString) MongoDB.Driver.MongoClient..ctor (System.String
connectionString) Mongo.Init () (at Assets/Scripts/Database/Mongo.cs:16)
Server.Init () (at Assets/Scripts/Server.cs:40) Server.Start () (at
Assets/Scripts/Server.cs:28)
I've tried to change the API Compatibility Level to .NET 4.x and the following error came:
ArgumentException: Invalid option 'retryWrites'.
Parameter name: url
MongoDB.Driver.MongoUrlBuilder.Parse (System.String url) (at
<6da29fc855c44d33ad78b3e27475ff27>:0)
MongoDB.Driver.MongoUrlBuilder..ctor (System.String url) (at
<6da29fc855c44d33ad78b3e27475ff27>:0)
MongoDB.Driver.MongoUrl..ctor (System.String url) (at
<6da29fc855c44d33ad78b3e27475ff27>:0)
MongoDB.Driver.MongoClient.ParseConnectionString (System.String
connectionString) (at <6da29fc855c44d33ad78b3e27475ff27>:0)
MongoDB.Driver.MongoClient..ctor (System.String connectionString) (at
<6da29fc855c44d33ad78b3e27475ff27>:0)
Mongo.Init () (at Assets/Script/Database/Mongo.cs:15)
Server.Init () (at Assets/Script/Server.cs:38)
Server.Start () (at Assets/Script/Server.cs:27)
I would like to know what I need to add to my scripts to make it work or if this tutorial is outdated and a new approach needs to be done.
Thanks
I know I am 8 months too late but, I have recently began working with MongoDB in Unity and I don't know if this will help but the short answer is I'm not sure. But I managed to connect to my remote and local db, so I'll explain how I did it below.
The Long answer:
I did not watch the tutorial video you followed but i setup my connections with these dll files (I am assuming you also created a Plugins folder for them). As for the "tutorial", I simply followed this quick start guide and this one. Everything else API related I just read the documentation.
I'm using MongoDB v4.2.1
I'm using Unity 2019.3
I'm using API compatibility .Net Standard 2.0
I'm using the admin user on the cluster. I don't know what your case is but I remember the documentation says that your user should have read and write privileges, so check that maybe.
Finally, I had an error when I first tried to connect to the remote DB, but maybe because I have my code wrapped around a try catch block, it didn't produce the error you provided but rather this:
Unable to authenticate using sasl protocol mechanism SCRAM-SHA-1 mongo c# driver
Which occurred because I forgot to take the angle brackets out of the code and had this instead - <password> - yes I left my password wrapped around the brackets, rookie mistake lol.
Here's how I connected to my Atlas cluster:
private const string remoteDB = "mongodb+srv://user_name:<password>#mycluster.mongodb.net/test?retryWrites=true";
static MongoClient newClient = new MongoClient(remoteDB);
internal Database()//This is a constructor, I'm not using MonoBehaviour
{
db = newClient.GetDatabase(DATABASE_NAME);
lbCollection = db.GetCollection<BsonDocument>(lbColl);
gameStateCollection = db.GetCollection<BsonDocument>(gameStateColl);
}
internal static async Task TestConnection()
{
try
{
await GetDBNames();
}
catch (Exception e)
{
Debug.Log("<color=red> Error</color> found while testing db connection:");
Debug.Log(e.Message);
}
}
private static async Task<List<string>> GetDBNames()
{
List<string> dbNames = new List<string>();
var dbs = await newClient.ListDatabaseNamesAsync();
dbNames = dbs.ToList();
if (dbNames.Count > 0)
{
Debug.Log($"Databases in {nameof(dbNames)}: ");
for (int i = 0; i < dbNames.Count; i++)
{
Debug.Log($"{dbNames[i]}");
}
return dbNames;
}
Debug.Log($"<color=red>{nameof(GetDBNames)}</color> Returning null. No Dbs found.");
return null;
}
We are developing an application in unity with the aim to deploy to android and are using firebase to facilitate user login and real time database.
We are using the real time database to store the location and information about specific objects and synchronize them across all players. The database also stores the individual data about each user. Our implementation has a single parent object called GenericInterface which has all of the shared code between the PlayerInterface and BuildingInterface which extend GenericInterface.
GenericInterface has the initialization code for our firebase implemention:
Auth = FirebaseAuth.DefaultInstance;
// Set this before calling into the realtime database.
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl(/*DB Url*/);
//set up restricted access.
// Set these values before calling into the realtime database.
FirebaseApp.DefaultInstance.SetEditorP12FileName(/* P12 filename */);
FirebaseApp.DefaultInstance.SetEditorServiceAccountEmail(/*AccountEmail*/);
FirebaseApp.DefaultInstance.SetEditorP12Password(/*Password*/);
// Get the root reference location of the database
Reference = FirebaseDatabase.DefaultInstance.RootReference;
This Reference is then used by PlayerInterface and BuildingInterface to load data through listeners, for example in the PlayerInterface:
var path = string.Format("players/{0}", pid);
Reference = FirebaseDatabase.DefaultInstance.GetReference(path);
Reference.ValueChanged += HandleValueChanged;
Where pid is the player's Id.
The project (apart from player login) works as intended when launched and run in the unity editor with buildings being fetched and displayed correctly by the BuildingInterface. However when building and running on either an AVD or Android Phone, none are displayed and a adb.exe logcat -s Unity shows the following error:
DBInterfaces.Abstract.GenericInterface`1:_start() (at [...]\Assets\Scripts\Firebase\Interfaces\Abstract\GenericInterface.cs:24)
DBInterfaces.Abstract.GenericInterface`1:.ctor() (at [...]\Assets\Scripts\Firebase\Interfaces\Abstract\GenericInterface.cs:18)
DBInterfaces.BuildingInterface:.ctor() (at E:\Users\Documen
InitializationException: Exception of type 'Firebase.InitializationException' was thrown.
at Firebase.Auth.FirebaseAuth+<GetAuth>c__AnonStorey1.<>m__0 () [0x00000] in <filename unknown>:0
at Firebase.FirebaseApp.TranslateDllNotFoundException (System.Action closureToExecute) [0x00000] in <filename unknown>:0
[Trimmed long file path for clarity]
Line 24 of GenericInterface Corresponds to Auth = FirebaseAuth.DefaultInstance;
We have been working on this for the better part of the week and haven't found any potential solutions.
I have a completed game working properly in Android and is published on Play store already. Now I wanted to submit it on iTunes. As soon as I started building the same project for iOS, I got this strange Error -
IOException: Sharing violation on path /Users/abhi/Projects/Unity/XCode Proj/Hammer Inc/Unity-iPhone.xcodeproj/project.pbxproj
System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/FileStream.cs:320)
System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share)
(wrapper remoting-invoke-with-check) System.IO.FileStream:.ctor (string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)
System.IO.File.OpenRead (System.String path) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/File.cs:363)
System.IO.StreamReader..ctor (System.String path, System.Text.Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/StreamReader.cs:167)
System.IO.StreamReader..ctor (System.String path)
(wrapper remoting-invoke-with-check) System.IO.StreamReader:.ctor (string)
System.IO.File.OpenText (System.String path) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/File.cs:368)
System.IO.File.ReadAllLines (System.String path) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/File.cs:560)
AdColonyPostProcessBuild.updateXcodeProject (System.String pbxProjectFilePath, System.String thirdPartyFrameworkDirectoryPath, .Framework[] frameworksToAdd) (at Assets/Editor/AdColonyPostProcessBuild.cs:356)
AdColonyPostProcessBuild.OnPostProcessBuild (BuildTarget target, System.String path) (at Assets/Editor/AdColonyPostProcessBuild.cs:340)
UnityEditor.HostView:OnGUI()
I got this error, after I was having some trouble with GPG Plugin and as mentioned here, I deleted the files and folders related to Google Play gaming, since I planned to use Game Center in iOS.
I am currently using Native-X, Adcolony, Revmob in the same project (I know that's too much, but that was due to an experiment on choosing proper network). I am not sure which of the plugin is causing conflicts.
I tried removing the AdColonyPostProcessBuild.cs file, but it gave the following error -
KeyNotFoundException: The given key was not present in the dictionary.
System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (.TKey
key) (at
/Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/
corlib/System.Collections.Generic/Dictionary.cs:150)
UnityEditor.XCodeEditor.PBXResolver.ResolveName (System.String guid) (at
Assets/Editor/iOS/PBX Editor/PBXParser.cs:49)
UnityEditor.XCodeEditor.PBXResolver.ResolveName (System.String guid) (at
Assets/Editor/iOS/PBX Editor/PBXParser.cs:53)
UnityEditor.XCodeEditor.PBXParser.GUIDComment (System.String guid,
System.Text.StringBuilder builder) (at Assets/Editor/iOS/PBX
Editor/PBXParser.cs:218)
UnityEditor.XCodeEditor.PBXParser.SerializeString (System.String
aString, System.Text.StringBuilder builder, Boolean useQuotes, Boolean
readable) (at Assets/Editor/iOS/PBX Editor/PBXParser.cs:546)
UnityEditor.XCodeEditor.PBXParser.SerializeDictionary
(System.Collections.Generic.Dictionary`2 dictionary,
System.Text.StringBuilder builder, Boolean readable, Int32 indent) (at
Assets/Editor/iOS/PBX Editor/PBXParser.cs:481)
UnityEditor.XCodeEditor.PBXParser.SerializeValue (System.Object value,
System.Text.StringBuilder builder, Boolean readable, Int32 indent) (at
Assets/Editor/iOS/PBX Editor/PBXParser.cs:439)
UnityEditor.XCodeEditor.PBXParser.SerializeDictionary
(System.Collections.Generic.Dictionary`2 dictionary,
System.Text.StringBuilder builder, Boolean readable, Int32 indent) (at
Assets/Editor/iOS/PBX Editor/PBXParser.cs:489)
UnityEditor.XCodeEditor.PBXParser.SerializeValue (System.Object value,
System.Text.StringBuilder builder, Boolean readable, Int32 indent) (at
Assets/Editor/iOS/PBX Editor/PBXParser.cs:439)
UnityEditor.XCodeEditor.PBXParser.Encode
(UnityEditor.XCodeEditor.PBXDictionary pbxData, Boolean readable) (at
Assets/Editor/iOS/PBX Editor/PBXParser.cs:177)
UnityEditor.XCodeEditor.XCProject.CreateNewProject
(UnityEditor.XCodeEditor.PBXDictionary result, System.String path) (at
Assets/Editor/iOS/XCProject.cs:620)
UnityEditor.XCodeEditor.XCProject.Save () (at
Assets/Editor/iOS/XCProject.cs:645) XCodePostProcess.OnPostProcessBuild
(BuildTarget target, System.String path) (at
Assets/Editor/iOS/XCodePostProcess.cs:35) UnityEditor.HostView:OnGUI()
Did anyone faced this issue before and found any solution? I don't want to delete every SDK from the project and start building it again.
I see you have a couple of issues. That sounds like a bummer. But, I would definitely like to help.
What's Happening:
Regarding the first error that you've provided it looks like it's having an issue reading the pbxproj file that Unity creates for the iOS build process.
Typically, when building for iOS, Unity will create a .pbxproj file in conjunction with the rest of the XCode items and then place that in the target build directory you specify. After that it triggers any post process build logic that has been hooked in by the developer.
AdColony's AdColonyPostProcessBuild.cs file is generally intended to be run last out of the post process build logic, because we rely on parsing the .pbxproj file itself, and then adding the information in line by line. The reason we prefer to do this last is because there exist current solutions to this problem that don't necessarily facilitate all the configurations we need, but other developers use it.
The first error looks like it's an access violation issue with the AdColonyPostProcessBuild not being able to access the .pbxproj file, so it can read in all of the lines. Because of this it's throwing an IOException seen here:
IOException: Sharing violation on path /Users/abhi/Projects/Unity/XCode Proj/Hammer Inc/Unity-iPhone.xcodeproj/project.pbxproj
and
System.IO.File.ReadAllLines (System.String path) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.IO/File.cs:560)
AdColonyPostProcessBuild.updateXcodeProject (System.String pbxProjectFilePath, System.String thirdPartyFrameworkDirectoryPath, .Framework[] frameworksToAdd) (at Assets/Editor/AdColonyPostProcessBuild.cs:356)
This brings me to my next point.
The second error that you've listed is something that arises out of an alternative post process build logic called "XCode Editor For Unity".
You can find it here:
https://github.com/dcariola/XCodeEditor-for-Unity
This solution is a C# implementation of a solution known as mod_pbxproj, and other developers have opted for this solution. However, when using it in conjunction with AdColony it will typically break if the XCode Editor For Unity is performed after the AdColonyPostProcessBuild.cs is run.
This is because some of the information used for the XCode Editor For Unity parsing has been duplicated and is being read in twice, when AdColonyPostProcessBuild.cs is run.
AdColony has configured our post process logic to run last, relying on the ability to parse the information after the XCode Editor For Unity has been run.
The Suggested Solution
The information you've provided has been very helpful, but it's hard to say for certain why these may be arising.
What will facilitate this process is if you could list any other plug-ins you're using that have a post process build applied for iOS builds AND if you can also provide any indications of their priority or order of occurrence on build.
Following that, the line numbers I see in your error output appear a bit inconsistent with the current version of the AdColonyPostProcessBuild.cs file in our current available package.
I would first suggest going to this link, downloading the current package, and re-importing the AdColonyPostProcessBuild.cs
https://github.com/AdColony/AdColony-Unity-SDK
If that doesn't resolve the issue, I would then open up the AdColonyPostProcessBuild.cs file and change its priority to be lower, preferably to be the last post process build item to run. You can do this by changing the number '200' on line 302, to a great number, like '1000'.
If this doesn't resolve your problem I will need to know more about your environment configuration like other plug-ins you are using, and deviations you've made from the default AdColonyPostProcessBuild.cs file.
Regards!
AdColony Support
This problem arose for me because I was using the Facebook SDK with Adcolony's SDK. The Facebook code leaves a streamReader open which produces the error when the Adcolony script is run. Change lines in Assets\Facebook\Editor\iOS\third_party\XCodeEditor-for-Unity\XCProject.cs
from (lines 76-77):
projectFileInfo = new FileInfo(Path.Combine(this.filePath, "project.pbxproj"));
string contents = projectFileInfo.OpenText().ReadToEnd();
to:
projectFileInfo = new FileInfo(Path.Combine(this.filePath, "project.pbxproj"));
StreamReader sr = projectFileInfo.OpenText();
string contents = sr.ReadToEnd();
sr.Close();
(credit to the answer here: "IOException: Sharing violation on path" on building a Unity project on Mac OS X with Facebook Unity SDK 5.1)
If I run this code on the device, it returns "got it":
if (Directory.Exists (NSBundle.MainBundle.BundlePath + "/ARCSDev")) {
Console.WriteLine ("got it");
} else {
Console.WriteLine ("can't find it");
}
Which means the directory is in the main bundle.
I need to use that file in this method call:
private void generateChart (int chartNumber, string palette)
{
string filePath = NSBundle.MainBundle.BundlePath + "/ARCSDev";
Console.WriteLine("Filepath - " + filePath);
Loader loader = new Loader (filePath);
loader.LoadChart (Convert.ToString (chartNumber));
The above code works fine on the simulator, but not on the device.
I get the following stack trace when the error occurs on the device:
System.InvalidOperationException: Operation is not valid due to the current state of the object
at System.Linq.Enumerable.Max[TileIndexRecord] (IEnumerable`1 source, System.Func`2 selector) [0x00000] in <filename unknown>:0
at MyCompany.Data.Arcs.Loader.ExtractWriteableBitmap (MyCompany.Data.Arcs.Records.RGBPaletteRecord rgbPalette, Double dpi, MyCompany.Data.Arcs.Raschts.ChartIndexFile indexFile, MyCompany.Data.Arcs.Raschts.RasterChartFile chartFile) [0x00000] in /Users/me/Desktop/ARCSViewer/ARCSViewer/Loader.cs:571
at MyCompany.Data.Arcs.Loader.GetHiResImage (MyCompany.Data.Arcs.Records.RGBPaletteRecord rgbPalette) [0x00000] in /Users/me/Desktop/ARCSViewer/ARCSViewer/Loader.cs:362
at ARCSViewer.SecondViewController.generateChart (Int32 chartNumber, System.String palette) [0x0004e] in /Users/me/Desktop/ARCSViewer/ARCSViewer/SecondViewController.cs:118
at ARCSViewer.SecondViewController.ViewDidAppear (Boolean animated) [0x00007] in /Users/me/Desktop/ARCSViewer/ARCSViewer/SecondViewController.cs:84
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at ARCSViewer.Application.Main (System.String[] args) [0x00000] in /Users/me/Desktop/ARCSViewer/ARCSViewer/Main.cs:17
The directory contains unix executable files and radiance files.
Can anyone explain whats going on? The file is definitely in the right place (the bundle) as I've tested the code that checks for existence with other files that I know to be there as well..
It might be an issue of case sensitivity, the simulator is case-insensitive while the device is case sensitive. Check your files to see if you're accessing all of them with the right case (i.e. not only the directory).
The permissions on the devices are very different (far more restricted) from the simulator. There's a lot of place you do not have access for various reasons (e.g. changing some files would break the application digital signature which would disallow your application from running anymore).
Also if your application does not follow Apple guidelines on where (and when) to store data your application will be rejected (if you target the appstore).
There's a nice article from Xamarin on how to work with the iOS file system.
I solved the problem, several parts of my application use code like below:
fs = new FileStream(fileName, FileMode.Open);
I needed to change every occurrence of FileStream() to the following:
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
As my files are in the bundle and don't need to make use of write operations, this limits the file stream to only read operations and allowed the files to be read in properly.