dcariola / XCodeEditor-for-Unity

XCode 4 project editor for Unity3D postprocess.
MIT License
217 stars 101 forks source link

An element with the same key already exists in the Dictionary<TKey, TValue> #1

Open frarees opened 11 years ago

frarees commented 11 years ago

After a standard build using XCodeEditor, it keeps throwing me messages like this: An element with the same key already exists in the Dictionary<TKey, TValue>

This happens on the parser. It seems it's reading the same key twice or more.

dcariola commented 11 years ago

It looks like there's a duplicate element somewhere. Give me some more info to reproduce.

frarees commented 11 years ago

Cannot reproduce it right now cause I'm getting violation exceptions all the time.

Reproduce steps:

Do a fresh build (no CMD+B, no Build & Run, create the Xcode project in a new folder). It says:

IOException: Sharing violation on path /Users/frarees/Desktop/sandbox/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 /Applications/buildAgent/work/3df08680c6f85295/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.StreamWriter..ctor (System.String path, Boolean append, System.Text.Encoding encoding, Int32 bufferSize) (at /Applications/buildAgent/work/3df08680c6f85295/mcs/class/corlib/System.IO/StreamWriter.cs:124)
System.IO.StreamWriter..ctor (System.String path, Boolean append)
(wrapper remoting-invoke-with-check) System.IO.StreamWriter:.ctor (string,bool)
System.IO.File.CreateText (System.String path) (at /Applications/buildAgent/work/3df08680c6f85295/mcs/class/corlib/System.IO/File.cs:159)
UnityEditor.XCodeEditor.XCProject.Save () (at Assets/Editor/XCodeEditor/XCProject.cs:958)
XCodePostProcess.OnPostProcessBuild (BuildTarget target, System.String path) (at Assets/Editor/XCodePostProcess.cs:21)
UnityEditor.HostView:OnGUI()

Then, I do an append, to try again, over the same folder. It doesn't work of couse cause the project is broken. Then, I do a build again over the same folder (replace), and the violation problem occurs again.

The post build script I'm using is:

using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

public static class XCodePostProcess
{
    [PostProcessBuild]
    public static void OnPostProcessBuild( BuildTarget target, string path )
    {
        if (target == BuildTarget.iPhone) {
            // Create a new project object from build target
            UnityEditor.XCodeEditor.XCProject project = new UnityEditor.XCodeEditor.XCProject( path );

            // Find and run through all projmods files to patch the project
            var files = System.IO.Directory.GetFiles( Application.dataPath, "*.projmods", System.IO.SearchOption.AllDirectories );

            foreach( var file in files )
                project.ApplyMod( file );

            // Save
            project.Save();
        }
    }
}
frarees commented 11 years ago

Any progress on this?

HenryStrattonFW commented 9 years ago

For anyone who finds this after all this time. This issue is with the PBX parser. Around line 182 (approx) There is the case statement for DICTIONARY_ASSIGN_TOKEN

this case by default simply adds to the dictionary regardless of the key's use. In our use we have simply modified this to do a standard "If exists then set value , else add value" pattern. However for your own uses you may want to flag this up to the user with the values or whatever to have a more hands on resolution of the conflict.

nacho4d commented 9 years ago

I am facing exactly the same issue here. I received once An element with the same key already exists in the Dictionary<TKey, TValue> but it is not reproducible all the times. I am sure my xcode project file has some duplicated keys but I am not sure what are those keys.

This helped a bit http://stackoverflow.com/questions/23836364/ioexception-sharing-violation-on-path-on-building-a-unity-project-on-mac-os-x

It would be nice that XcodeEditor-for-Unity checks the existance of an object associated to a key. If the object is the same, then just skip. Otherwise print a debug log warning of throw an exception