Bug 10737 - Duplicate view controllers created upon synchronization
Summary: Duplicate view controllers created upon synchronization
Alias: None
Product: Xamarin Studio
Classification: Desktop
Component: Text Editor ()
Version: 4.0.5
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Jeffrey Stedfast
Depends on:
Reported: 2013-02-27 11:39 UTC by Allie Miller
Modified: 2013-06-04 11:41 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Shows how the view controllers are normally (26.73 KB, image/png)
2013-02-27 12:07 UTC, Matt Cuda
Shows view controllers scattered into the root after sync with XCode (74.32 KB, image/png)
2013-02-27 12:08 UTC, Matt Cuda
Here is the massive amount of errors it generates (27.49 KB, image/png)
2013-02-28 09:46 UTC, Matt Cuda
Error List (342.78 KB, image/png)
2013-02-28 09:54 UTC, Matt Cuda
Sync Error 5-30-2013 (56.95 KB, image/png)
2013-05-30 10:41 UTC, Matt Cuda
Error Log 5-3002013 (24.79 KB, application/octet-stream)
2013-05-30 11:28 UTC, Matt Cuda
Another log from 5-30 (38.19 KB, application/octet-stream)
2013-05-30 11:28 UTC, Matt Cuda
Failed when adding an image to the root. (55.29 KB, image/png)
2013-06-04 11:23 UTC, Matt Cuda
Log file showing error when adding a .png file to the root of my project (55.33 KB, application/octet-stream)
2013-06-04 11:25 UTC, Matt Cuda

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Allie Miller 2013-02-27 11:39:22 UTC
When using Xamarin.Studio, during synchronization with the iOS project in xCode, something goes wrong and duplicate view controller classes are placed into the root of the project. In my case I have a folder called "ViewControllers" where all my view controllers reside ([Project Root]/ViewControllers/). This can be very annoying because if you have a ton of view controllers it will duplicate every one of them.

This also happened in MonoTouch/MonoDevelop previously.

The only way to remedy the problem is to manually go and delete all the duplicates. Incidentally, the duplicates don't have the same code behind, rather they are just a class sub. This causes a ton of compile errors so I have to manually delete them.
Comment 1 Matt Cuda 2013-02-27 12:07:46 UTC
Created attachment 3501 [details]
Shows how the view controllers are normally
Comment 2 Matt Cuda 2013-02-27 12:08:27 UTC
Created attachment 3502 [details]
Shows view controllers scattered into the root after sync with XCode
Comment 3 Matt Cuda 2013-02-27 12:10:15 UTC
Note this may happen after trying to remove a duplicate or misnamed property on the XCode side, but I am not sure since it seems so random.
Comment 4 Matt Cuda 2013-02-28 09:42:43 UTC
I happened again this morning.   I did delete several old controllers this morning and I received several "Communication errors" with Xamarin Studio while trying to interface with XCode.  This is also a Storyboard project if that helps.

Since this happens on other machines, my gut feeling is that this is not an install related issue.  My other gut feeling is that this might be due to nesting of folders, then the folders don't get pushed to Xcode properly, so Xamarin throws them into the root of the project.  Just some theories at this point, nothing solid to go on.
Comment 5 Matt Cuda 2013-02-28 09:46:53 UTC
Created attachment 3510 [details]
Here is the massive amount of errors it generates

This only gets worse as the project gets bigger.
Comment 6 Matt Cuda 2013-02-28 09:49:51 UTC
Here is an example of the stub it generates behind the Bogus View Controllers.

// This file has been autogenerated from parsing an Objective-C header file added in Xcode.

using System;

using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace iECDDatasource
	public partial class MenuViewController : UIViewController
		public MenuViewController (IntPtr handle) : base (handle)
Comment 7 Matt Cuda 2013-02-28 09:54:27 UTC
Created attachment 3511 [details]
Error List

So here are the actual compile errors which as you would expect just tell me the controllers are already defined elsewhere.
Comment 8 Jeffrey Stedfast 2013-02-28 14:18:44 UTC
The stub classes are generated based on header files that it finds in the Xcode project when it can't find the corresponding C# classes in the MonoTouch project.

It will also generate class stubs for classes defined in the storyboard files.

Can you walk me through what you did exactly? I need to know:

1. when did you delete the c# classes? before opening Xcode? or after?
2. were there header files for the deleted classes in the Xcode project?
3. are there any references to these classes in the storyboard files?
Comment 9 Matt Cuda 2013-02-28 14:30:11 UTC
1. I would have to say after but I can't be entirely sure.  One of the problems is that you don't know anything bad happened until you go to compile.

2. I deleted from Xamarin Studio, and the existing xcode window was open but I did not check to see if the files were in the xcode project.  There is also the possibility this is happening when I delete the .xib files from Xamarin studio. I do this because it is a storyboard project.

3. The view controllers in the storyboard do reference these files but they referrence the view controllers nested in the "View Controllers" folder in Xamarin Studio.  In other words, I select the view controller in the drop down in Xcode for each view controller in the storyboard. Remember that these bogus controllers are all actual controllers but they are copies.

So it sounds like that for whatever reason X-Studio is not walking the folders to see if there are already viewcontrollers with those names and that those names are found in xcode under the same "groups"  In other words it should never replicate back from XCode what doesn't exist in Xamarin first.
Comment 10 Jeffrey Stedfast 2013-02-28 14:40:28 UTC
When it syncs classes back from Xcode, it doesn't walk the folder tree of the MonoTouch project looking for files of the same name (because it can't rely on that). What it does is use the type system (the same one used for "Go To Definition", etc) to check if the class exists in the C# project, and, if not, creates a new stub.

Anyway, #2 is my biggest suspect right now. I don't think we aggressively sync back to Xcode when files are deleted. I think there's another bug report about that... so this is probably the cause.

IOW, I suspect this is the scenario:

You launch Xcode on a .xib or storyboard, switch back to Xamarin Studio and then delete some classes before switching back to Xcode again. If Xamarin Studio didn't delete the .h files for the classes that got deleted, then you'll still have them in the Xcode project...

When you switch back to Xamarin Studio again, it'll find those .h files and not be able to map them to any existing C# classes (because you deleted them) and so it'll think they are new and generate C# stubs for them.

Anyway, this is just a theory at this point.
Comment 11 Matt Cuda 2013-02-28 14:43:11 UTC
This might be relevent but here are the steps I take to create view

1.  Right Click on the folder I want the controllers in (Xamarin Studio)
2.  Select "Add New File"
3.  Specify the name of the controller and add it.
4.  Delete the .xib file that is generated automatically (sometimes it errors
out here or doesn't delete the .xib at all)
5.  An instance of XCode may or may not be running at this time.
6.  Double click on my MainStoryBoard.storyboard file in Xamarin Studio
7.  Find the already created View Controller in my storyboard within XCode.
8.  Click on the View Controller in XCode
9.  Go to the "Properties" docked to the right side of the XCode window.
10. Find my new ViewController created in step 3 above and select it in the
custom class drop down.
11. Navigate back to Xamarin studio and the two environments sync.

Other things that may happen here...

I might name the new controller something bad so I delete and recreate it
Comment 12 Matt Cuda 2013-02-28 14:44:40 UTC
Jeff, one thing more to note here.  It isn't just the deleted files that show up in the root of my project.  It is about every controller in my project that is copied to the root of my Xamarin project.

So as the project grows it only gets worse.
Comment 13 Jeffrey Stedfast 2013-02-28 14:45:17 UTC
Ah, thanks for clarifying that.
Comment 14 Jeffrey Stedfast 2013-03-04 16:30:21 UTC

When you rename your classes in Xamarin Studio, are you editing the .designer.cs file that goes along with it to update the [Register] attribute? If not, I think that's the problem...

When you edit your .storyboard in Xcode and select a class you want to use, you are probably typing the name of the class you want (but for which no classes in Xamarin Studio are registered as), and so when you switch back to Xamarin Studio, it detects that none of your classes are registered as "PendingRTMViewController" so creates one.

We should probably make sure you don't already have a class named the same, but we've been using the name given in the [Register] attribute because that's the name that gets registered with the Objective-C runtime and is therefore the one that gets used by the storyboard.
Comment 15 Jeffrey Stedfast 2013-03-04 19:43:14 UTC
I've committed a fix to the logic that parses through .storyboard files when syncing back from Xcode to double-check that a class by that name doesn't already exist with the wrong [Register] attribute. If it does exist, Xamarin Studio will now prompt the user to see if they would like to update the [Register] attribute (and updates it for them if they say "Yes").
Comment 16 Jeffrey Stedfast 2013-03-05 14:34:57 UTC
I've uploaded a custom build with my fixes (no QA has been done) that you are free to try out:

Comment 17 Matt Cuda 2013-05-09 09:34:40 UTC
This bug remains a problem and is not fixed.  Synchronization errors still occur on a fairly regular basis.

The latest problem related with synchronization, in addition to the above, is some files vanish from the project and have to be manually added back in.  This has caused me to b embarrassed in meetings twice from runtime failures because the xib files had mysteriously been removed from the project.

Additionally, and at random times, images will vanish from the project and have to be re-added.
Comment 18 Jeffrey Stedfast 2013-05-09 15:51:06 UTC
I think that Xamarin Studio 4.0.5 will fix the removed files issues - someone else reported that issue and I fixed it for him.

I've also made more fixes related to your original bug that made it into 4.0.5.

Any chance you could test it out?

Comment 19 Matt Cuda 2013-05-16 08:24:28 UTC
The error happened yesterday and it prompted me with the new messagebox.  I answered the message box telling it to keep my current view controllers, but this appeared to break the synchronization badly.  Now when I add a button or view to the view controller in XCode, the new control is not synched back to to Xamarin Studio.

I tried to close both environments and reopen but this did not fix the issue. Right now I have to manually add the controls on the xamarin side.  This is in version 4.0.5 using storyboards.

I hate to whine but this is really causing me some serious headaches.
Comment 20 Jeffrey Stedfast 2013-05-29 16:07:03 UTC
Next time this happens, can you get me the Xcode4Sync.log file from ~/Library/Logs/XamarinStudio-4.0/? Thanks.
Comment 21 Matt Cuda 2013-05-30 10:39:07 UTC
I'll try to paste any synch errors I get to this ticket.
Comment 22 Matt Cuda 2013-05-30 10:41:58 UTC
Created attachment 4043 [details]
Sync Error 5-30-2013
Comment 23 Matt Cuda 2013-05-30 10:43:42 UTC
I have no logs for Xamarin in /Libarary/Logs/
Comment 24 Jeffrey Stedfast 2013-05-30 11:18:15 UTC
The dialog screenshot suggests a bug in the Types database for your project. I'll have Mike look into this.

The logs aren't in /Library/Logs, they are in ~/Library/Logs (~ means your home directory).

So probably something like /Users/matt/Library/Logs/XamarinStudio-4.0/Xcode4Sync.log
Comment 25 Matt Cuda 2013-05-30 11:28:23 UTC
Created attachment 4044 [details]
Error Log 5-3002013
Comment 26 Matt Cuda 2013-05-30 11:28:55 UTC
Created attachment 4045 [details]
Another log from 5-30
Comment 27 Jeffrey Stedfast 2013-05-30 11:33:46 UTC
awesome, thanks matt
Comment 28 Jeffrey Stedfast 2013-05-30 11:54:02 UTC
Mike: it seems the problem is that the DOM we get from the TypeSystemService is incomplete or something. Can you look into this? Our users keep running into this issue.
Comment 29 Mike Krüger 2013-05-31 00:36:54 UTC
Jeff: If you can give me a reproduction case.

The type system service listens to:

project.FileAddedToProject event - if you add something ensure that this is running.

If you modify a file (rewrite it) - you need to issue a FileService.FileChanged event.

When both is done the type system service should work.

If you need immediately a new compilation you need to manually reparse the file with TypeSystemService.ParseFile (fileName) - that'll block the current thread but will update the project content.
Comment 30 Jeffrey Stedfast 2013-05-31 08:41:35 UTC
Unfortunately I don't have a reproduction case and myself have never been able to reproduce this.

The Xcode syncing code never does anything to inhibit emissions of FileAddedToProject, so that's not the problem.

The Xcode syncing logic also calls FileService.FileChanged() on all files that are changed when syncing back from Xcode.

We never manually parse any C# files, we just ask the TypeSystemService for the current state.
Comment 31 Jeffrey Stedfast 2013-05-31 12:36:32 UTC
ok, found some places where the Xcode syncing code didn't call FileService.NotifyFileChanged() where it maybe should have.
Comment 32 Matt Cuda 2013-06-04 11:22:21 UTC
It happened again this morning but this time when adding a new image to the root of the project.  I put a screenshot and debug file above.  I am using alpha version 4.1.3
Comment 33 Matt Cuda 2013-06-04 11:23:30 UTC
Created attachment 4063 [details]
Failed when adding an image to the root.
Comment 34 Matt Cuda 2013-06-04 11:25:31 UTC
Created attachment 4064 [details]
Log file showing error when adding a .png file to the root of my project
Comment 35 Matt Cuda 2013-06-04 11:36:24 UTC
The only way you are probably going to recreate this, is to create a very large and diverse project which would typically be found in enterprise business apps.  Once you do this, you need to make sure you are only using xCode with storyboards.  At that point you might have a chance to make it happen.  I think just looking at the code is a hail Mary attempt at finding the solution.  It happens to me about twice a week.
Comment 36 Jeffrey Stedfast 2013-06-04 11:41:38 UTC
Hi Matt,

Could you give this a try? https://files.xamarin.com/~jeff/XamarinStudio-d3111042052c0ca64d44a95f2615a7f00db5cd20.dmg

That's a 4.0.x release with the fixes I've implemented for this bug. I'm not sure if my patches have been merged into the 4.1.x branch yet, but I'll merge them up if they aren't.