Mapsui: iOS broke between beta37 and beta38

Created on 2 Apr 2020  路  33Comments  路  Source: Mapsui/Mapsui

I get a blank, frozen map. Works fine on beta37 and below. I thought the Skia dependency might be related (beta37 used preview17, beta38 uses preview39), but I rolled back to beta37 with preview39 and it works just fine.

bug 馃悰 needs-testing 馃И

All 33 comments

beta37 works fine with Skia preview45, as well. Something going on in Mapsui itself.

Thanks for the details. I did not test anything on iOS lately. Will check.

Do you use iOS Forms? or plain iOS?

@tonyfonager You do not have a problem with iOS right? What could be the difference?

@spaddlewit Did you also try 2.0.0-rc.1?

@pauldendulk I am running on 2.0.0-rc.1 right now, and it works without any issues on both iOS and Android

And that is a Xamarin.Forms project!

Yes, I'm using Xamarin.Forms.
My base layer is also an mbtiles layer. What's yours, @tonyfonager ?

Yes, I tried 2.0.0-rc.1. They all act the same post-beta37.

wow, thanks for the fast responses.

I currently have disabled my mbtiles layer, and use the built in OSM map provider while testing.

Map.Layers.Add(OpenStreetMap.CreateTileLayer());

There could be issues with the mbtiles packages. Did some updates and they are very confusing.

@pauldendulk I could try testing with mbtiles file again, but I am running on a modified version of BruTiles, so it might not give the expected result ...

I'll also note that UWP, other than my previous PopAsync bug, works fine on 2.0.0-rc1. So it's something that changed iOS-side in beta38...

Alright, some more results from testing.. in beta38..
I loaded an online tile service instead of mbtiles-
If I navigate to another screen, then navigate back, I noticed that the map flashed for a quick moment in a greyish-blue color.. if I hold down my finger and pan around, it starts drawing the map, but it looks to be using the farthest-zoomed-out tile zoom level, while being zoomed in closer than what that tile level would normally be displayed at.
When I lift my finger and stop panning the map, it disappears again.

We are using 2.0.0-rc.1 since 5 days now in our testing. Testing primary on iOS and we only use custom mbtiles, we don't encounter any issue at all. Which version of BruTile.MbTiles are you using?

v2.1.2. Using the latest versions of everything. :(

Except for Xamarin.Forms itself, we also use the latest of everything. Xamarin.Forms is currently on 4.5.0.495 in our latest TestFlight build.

Did you try to delete the _bin_ and obj folders (maybe also _.vs_ and the _.user_ files)? Is your XCode (also the installed components + Emulators) and your Visual Studio for Mac (Stable not Beta Channel) up2date?

Yep yep, and yep.
Playing around some more -- rather than using my subclass of Mapsui.Forms.UI.MapView, I created a basic MapView and added it to the XF UI.. and it worked.

So there's something in my subclass that's mucking things up, that used to work <= beta37. It could be some older code that I used with very early versions of Mapsui to get it to 'cooperate'. I'll continue to play around and report back.

Got it!

Here's a reproducible sample project. Sorry it's not all bundled up into a nice VS solution, I know the iOS projects contain certificate information and stuff that my employer would be pretty upset about if any info got out:

`
public class MainPage : ContentPage
{
MapView mv;

    public MainPage() : base()
    {
        mv = new MapView();
        mv.HorizontalOptions = LayoutOptions.FillAndExpand;
        mv.VerticalOptions = LayoutOptions.FillAndExpand;
        mv.IsVisible = false; // Remove this line, and all of a sudden it works!

        this.Content = mv;

        this.Appearing += MainPage_Appearing;
    }

    private void MainPage_Appearing(object sender, EventArgs e)
    {
        this.Appearing -= MainPage_Appearing;

        mv.Map.Layers.Add(Mapsui.Utilities.OpenStreetMap.CreateTileLayer());

        mv.IsVisible = true;
    }
}

`

To explain WHY I'm doing this, I have a lot of data to load & parse before I display the map. So I create the map with IsVisible = false;, load everything, then display the map after the data is done loading. Apparently this doesn't work on iOS >= beta38.

How about a mv.Refresh()?

You can simply replace the Bundle ID by search & replace if you don't want to show it. There is no certificate information in any of this projects because the signing is done by XCode afterwards (and XCode only uses the Bundle ID and searches for a matching certificate on the connected developer account).

That the rendering process isn't done when IsVisible = false, is something that I would expect. So if at all it was bugged before (you dont want so spent resources on not visible stuff). If you have to load data asynchronously you should consider some sort of a loading indicator like a popup with a ActivityIndicator. But to be honest, I don't see the reason todo so. One of my apps using a nearly 1GB mbtiles file plus 6000 marks on the map and even that is able to load without a delay on a iPhone 4S from 2011.

No, mv.Refresh() doesn't fix the issue. Also, if you PushAsync to another page and then PopAsync back, you get the weird zoomed-out, non-tile-fetching experience I described above.

Suggested things like ActivityIndicator aside (I'm loading much more data on the screen than just map layers), this problem doesn't occur on UWP. Behavior should be consistent across platforms.

I wanted to test your problem today but did not get around to it. It took all my time to update, my mac, my ipad, xcode, the ios project, the nuget packages. Perhaps next week.

I understand. The mac workflow drives me crazy, too. I'm keeping IsVisible = true for now.

I experience the same issue, just updated recently to the last version 2.0.0-rc2 and at first i thought
the map was fully blank but then I witnessed a part of the map rendering for one sec in a corner and then disappearing again.

I'm using the MapView (for xamarin.forms) (from my understanding, it is encapsulating a MapControl(that descend from SKGLView) with a few layers, I do use the MapView's "Pin" feature with some svg pins)

tile layer : new TileLayer(KnownTileSources.Create());

I cannot really use @spaddlewit workaround because the maps (i have two of them) are in "tabs" (custom tab implementation using a grid, I am not using the xamarin forms TabPage),
the MapViews are initially hidden and are basically shown/hidden each time the user change tab.
The IsVisible property is never directly set on the MapView , rather on a ContentView ancestor (there is more that just the MapView in the "tab")

Up to now I was using the beta-34 version,
I wanted to update to the last version because I was experimenting these iOS crashes that are supposedly fixed in the latest SkiaSharp (1.68.2-preview.50)
( #865) (more likely to happen when having multiple skia gl views from what i understood)

I will try to create a minimal repro ASAP.

I think there may be other issues with the latest version (either mapsui or skiasharp)
because I encoutered this crash (android): https://gist.github.com/tmijieux/9d9e89b387070f977418014d4f235d44 but I cannot tell if this is related to the current issue
I was able to reproduce it twice rather easily, but not trivially either, some tab/map manipulations needs to be done. I will try to confirm, and make a minimal repro of this one too and probably open another issue.

Repro here : https://github.com/tmijieux/MapsuiRepro

Note that if we remove that line

https://github.com/tmijieux/MapsuiRepro/blob/1216c617823b238f57ad9c65b89a79ae8065b6c1/ReproMapsui/ReproMapsui/Tabs/TabMap.xaml.cs#L8

i.e if the contentview is visible when it is added to the view tree it seems to not cause the problem... Even if it is hidden after with IsVisible=false et reshown latter.
My guess is that the problem come from a missing initialization that is performed only
at the moment when the view is rendered for the first time after being added into the view tree and it is skipped if the view is not visible and never re-attempted later.

After playing with the different views / switching tab / tapping the screen everywhere
it eventually crashed :
https://gist.github.com/tmijieux/8495c6e9502ef3d3f1af26a710b02ea8

EDIT: it will crash easily on android too but it may be another crash, it looks like it crashes when i zoomed out : maybe it's the same as in #862, also looks a lot like #885

@tmijieux Thanks for the info. Mapsui rc.2 uses a skiasharp version with crashes on Android (did not test on iOS). This has been fixed in the git repo and we are waiting for the next release. The problem in this issue is probably in Mapsui. It could best be tested with rc.1.

I tried to reproduce this problem and I can. It seems, that the problem is, that the scale factor isn't calculated correct. I found, that the map is drawn in the top left corner with, in my case, a scale of 0.006.

So the question is, which is the right event to set the pixel density after the MapView is visible and before drawing the content. Any suggestions?

I have to step through the code 馃檨

Ok, when the MapControl is getting visible, the CanvasSize.Width is 2 and then we get a PixelDensity of 0.0067 and don't see anything of the tiles. Up to now I couldn't reproduce this with the normal SKGLView. And in the moment debugging with VS 2019, Mac and iPhone is horrible. The connection is lost each 2 minutes :-(. Have to look into this later.

we got the same problem, we had to downgrade to version 37 :(

@felipechavez @tmijieux @spaddlewit This should be fixed with @charlenni's fix in rc.5 that has just been released.

tested in iOS and Android with the latest release, and it's working perfectly: D @pauldendulk

No further reports. Assumed fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JesrigPineda picture JesrigPineda  路  4Comments

kisslori picture kisslori  路  8Comments

Wil69 picture Wil69  路  5Comments

JesrigPineda picture JesrigPineda  路  5Comments

lukaszpitulski picture lukaszpitulski  路  3Comments