Bug 30020 - Map tiles and location does not load on ipad in iphone app
Summary: Map tiles and location does not load on ipad in iphone app
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: XI 8.10
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2015-05-13 05:08 UTC by m.tzagkarakis
Modified: 2015-05-13 09:45 UTC (History)
2 users (show)

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

screenshot of the problem (1.16 MB, image/png)
2015-05-13 05:08 UTC, m.tzagkarakis

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 m.tzagkarakis 2015-05-13 05:08:03 UTC
Created attachment 11181 [details]
screenshot of the problem

I am using an iPad 4 to debug an iPhone app I am writing and I am using xamarin.iOS 8.10 and the latest xamarin studio (5.9) on a macbook pro with OS X Yosemite 10.10.3

The attached screenshot shows perfectly whats happening the app stays there for a long time. The normal behaviour (on the iPhone and on the simulators) is the map to zoom in to predefined span and mapcenter (user location)
Sometime if I zoom out/in some tiles are loaded but not all of them (the whole screen). Furthermore, sometimes (but not consistently) I get the following error in the debugger: 

unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow (with some other details)

I have a stable internet connection.
Comment 1 Sebastien Pouliot 2015-05-13 08:28:31 UTC
The description is not complete enough to see what could be wrong.

Please provide a test case (best) with some additional information, e.g. iOS versions used on every devices/simulator, is the iPad 4 the only device that fails (or is that every iPad)...
Comment 2 m.tzagkarakis 2015-05-13 08:42:31 UTC
I just restarted the ipad and everything seems to work now. I really do not what happened. The ipad uns ios 8.3.

There is still a remaining issue that an exception is thrown when I set a delegate to the map but it is temporarily fixed by setting the UIApplication.CheckForEventAndDelegateMismatches property to false.
Comment 3 Sebastien Pouliot 2015-05-13 08:55:18 UTC
Are you using Xamarin.Forms ? There's a known issue about Maps/Delegates (see forums).

If not can you give us a test case where this happens ? because it either indicates an error in your code (or a bug in our events) and both would be bad. Thanks!
Comment 4 m.tzagkarakis 2015-05-13 09:09:37 UTC
No I am using xamarin.ios if I comment on UIApplication.CheckForEventAndDelegateMismatches the following exception occurs

Event registration is overwriting existing delegate. Either just use events or your own delegate: Snappcar_iOSCLient_Xamarin.MapDelegate MapKit.MKMapView+_MKMapViewDelegate

I have an empty contructor so the first code being executed is on viewDidLoad method which is exactly like this

base.ViewDidLoad ()
mapView = new MKMapView (new CGRect (0f, 0f, UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height - mainScreenController.TabBar.Frame.Height));
mapView.ShowsUserLocation = true;
mapView.Delegate = mapDelegate; 

then I have two event handlers one for the DidUpdateUserLocation and one for the MapLoaded if I remove these events I get no exception. But if either of these are there the exception mentioned above occurs.

mapView.DidUpdateUserLocation += (object sender, MKUserLocationEventArgs e) => {...};
mapView.MapLoaded += (object sender, EventArgs e) => {...};
Comment 5 m.tzagkarakis 2015-05-13 09:18:28 UTC
so it is either setting a mapdelegate or one of the above events. Otherwise the exception occurs.
Comment 6 Sebastien Pouliot 2015-05-13 09:24:35 UTC
That's the normal case (i.e. a bug in your application). You can NOT use both a delegate, e.g.

> mapView.Delegate = mapDelegate; 

and set events on the same instance.

The reason is that C# events supports (something that does not exists in ObjC) requires the use of a custom delegate. So when you add events, e.g. 

> mapView.MapLoaded += (object sender, EventArgs e) => {...};

You're effectively replacing the `mapDelegate` that you set earlier (with the delegate that provide events support) and  `mapDelegate` code will never be called. 

This is the reason why (recent) XI are throwing this exception, so you can fix your code to either only use events or only use the delegate.
Comment 7 m.tzagkarakis 2015-05-13 09:37:16 UTC
But what is the correct way of keeping the desired functionality? I use the delegate for setting custom annotations and the events for other functions.
Because not if I set the property IApplication.CheckForEventAndDelegateMismatches to false I can keep the custom annotations and both events executed perfectly.

So I guess one of the ways to do it is overriding DidUpdateUserLocation and MapLoadde in MKMapViewDelegate.

Thanks for your time and help.
Comment 8 Sebastien Pouliot 2015-05-13 09:45:22 UTC
> executed perfectly.

It's possible some things will work, it depends on when the MapView will call the delegate. E.g. if it calls the delegate (for annotations) before you set the events then things _can_ be fine.

However we have seen different versions of iOS calling delegates in different orders. That creates subtle, hard to debug issues, in applications that can affect you in the future. Since the call order are not documented, nor guaranteed to be stable by Apple you better play it safe :-)

More details about this in:

> So I guess one of the ways to do it is overriding DidUpdateUserLocation and
> MapLoadde in MKMapViewDelegate.

Yes, that's a correct way to do it, i.e. there will be a single (yours) delegate for the map.