Esri / arcgis-maps-sdk-swift-toolkit

Mapping components that will simplify your Swift app development with the ArcGIS Maps SDK for Swift.
https://developers.arcgis.com/swift
Apache License 2.0
29 stars 9 forks source link

Scalebar - unexpected exception #802

Open mmoosbac94 opened 4 months ago

mmoosbac94 commented 4 months ago

Hello everybody,

we currently have the issue, that there often occurs an exception when using Scalebar:

"onChange(of: Optional) action tried to update multiple times per frame."

In stacktrace we can see that the exception is thrown in Scalebar.swift:

Scalebar.swift

.onChange(of: spatialReference) { viewModel.update($0) }
.onChange(of: unitsPerPoint) { viewModel.update($0) }
.onChange(of: viewpoint) {
    viewModel.update($0) --> Issue here
    viewModel.updateScale()
    if settings.autoHide {
        withAnimation {
            opacity = 1
        }
        withAnimation(.default.delay(settings.autoHideDelay)) {
            opacity = .zero
        }
    }
}

ScalebarViewModel.swift

func update(_ viewpoint: Viewpoint?) {
    self.viewpoint = viewpoint
    if !initialScaleWasCalculated { updateScale() } --> Issue here
}

Generally its working correctly, and we have implemented it as shown in the example. But this exception occurs. Do you know this behaviour or do you have any idea why this happens?

Thank you Marvin

dfeinzimer commented 4 months ago

Hi @mmoosbac94, thank you for reporting. We'll take a look into the issue.

In the meantime, are there any steps/user-interactions you've found that reliably reproduce the exception?

Edit: I've slightly refactored the indentation in your code snippets for readability.

dfeinzimer commented 4 months ago

@mmoosbac94 I've also noticed that from the code you've included, it looks like you may be using version 200.3.0 or possibly even earlier.

The problematic area you've indicated above was refactored as of release 200.4.0. If you're in a position to test 200.4.0 - please check to see if you're still able to reproduce this issue. Thank you!

mmoosbac94 commented 4 months ago

@dfeinzimer Thanks for the quick reply!

We are using the newest release 200.4.0. But the issue still persist.

dfeinzimer commented 3 months ago

@mmoosbac94 I haven't had luck reproducing the issue so far. Would you please provide a few additional details, including:

Thanks!

mhdostal commented 3 months ago

.onChange(of: viewpoint) contains viewModel.updateScale() as does the func update(_ viewpoint: Viewpoint?) method (updateScale()). I wonder if it's getting called twice and that's causing the issue. Also, is there just one "onChange(of: Optional) action tried to update multiple times per frame." in the log or multiple?

mmoosbac94 commented 3 months ago

@dfeinzimer Thanks for trying it out. The details are:

                Scalebar(
                    maxWidth: maxWidth,
                    spatialReference: spatialReference,
                    unitsPerPoint: unitsPerPoint,
                    viewpoint: mapContentViewModel.viewpoint
                )
                .padding(30)
            }

spatialReference + unitsPerPoint are @State viewpoint is @Published

But it sounds interesting what @mhdostal said. Could that be possible and causing the issue? Every third try or so I get the exception: onChange(of: Optional) action tried to update multiple times per frame. once. And I can see in stacktrace that the exception is thrown in viewModel.update($0) and update(_ viewpoint: Viewpoint?) -> updateScale() from scalebar.

dfeinzimer commented 3 months ago

Hi @mmoosbac94, even when testing with an iOS 17.5.1 device, I'm not able to reproduce the issue. That said, there are a few things I'd like to try.

I've prepared two separate branches. If possible, please try both to see if either of them resolve the issue:

mmoosbac94 commented 3 months ago

Hi @dfeinzimer, I tried both of your branches.

dfeinzimer commented 3 months ago

Hi @mmoosbac94, thank you for your feedback. I've identified a potential crashing condition. Please test once more with a third branch: "bug/802/c".

If that branch still presents the issue, please consider providing a minimum reproducible example, including the definition of mapContentViewModel which holds viewpoint.

Thanks!

mmoosbac94 commented 3 months ago

Hi @dfeinzimer. Thanks for your changes. It seems that with these changes the app does not crash anymore!

But sometimes I can still see the exception "onChange(of: Optional) action tried to update multiple times per frame.", but without a crash.

dfeinzimer commented 3 months ago

@mmoosbac94 Great to hear this fixes the crash. This patch will likely make it into 200.5 which should be available very soon.

As for the "onChange" warning you're still seeing; is there any clear indication which onChange modifier is emitting it? Is it definitely also coming out of onChange(of: viewpoint) in Scalebar.swift, or possibly somewhere else?

mmoosbac94 commented 3 months ago

@dfeinzimer Sounds good. Thank you very much again for your effort!

As I could see in stacktrace its definitely coming out of onChange(of: viewpoint) in Scalebar.swift.

dfeinzimer commented 3 months ago

@mmoosbac94 Thank you for that information. We'll continue to investigate the warning.

In the meantime, the crash fix is available in 200.5.0 as of today.