Xamarin Navigation Problem

Julien_PerezJulien_Perez Member ✭✭

Hello everyone, so I got a problem when I want to push a ZXingScannerPage for scan a QRCode. This is my code :

        MainPage = new NavigationPage(new MainPage());

        var scanPage = new ZXingScannerPage();
        await MainPage.Navigation.PushAsync(scanPage, true);
        scanPage.OnScanResult += (result) =>
        {
            scanPage.IsScanning = false;
            Device.BeginInvokeOnMainThread(() =>
            {
                QrCodeScanned = JsonConvert.DeserializeObject<QRCode>(result.Text);
            });
        };

So basically this code work on Android, but not on iOS. And when i switch the PushAsync method to the PushModalAsync method it's work on iOS but no more on Android.

Someone have a idea to correct this error pls?
Thank for your time and answers.

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    If you know what works on each OS what's the problem?
    Use the call that works for each OS.

  • Julien_PerezJulien_Perez Member ✭✭

    @ClintStLaurent said:
    If you know what works on each OS what's the problem?
    Use the call that works for each OS.

    It's a solution, but if I need to do that at every push or pop it's will produce a huge amount of redundant code and I want to avoid this and understand why I get this error. Normally this 2 methods should work fine on each OS

  • JohnHardmanJohnHardman GBUniversity mod

    @Julien_Perez said:
    Hello everyone, so I got a problem when I want to push a ZXingScannerPage for scan a QRCode. This is my code :

            MainPage = new NavigationPage(new MainPage());
      
            var scanPage = new ZXingScannerPage();
            await MainPage.Navigation.PushAsync(scanPage, true);
            scanPage.OnScanResult += (result) =>
            {
                scanPage.IsScanning = false;
                Device.BeginInvokeOnMainThread(() =>
                {
                    QrCodeScanned = JsonConvert.DeserializeObject<QRCode>(result.Text);
                });
            };
    

    So basically this code work on Android, but not on iOS. And when i switch the PushAsync method to the PushModalAsync method it's work on iOS but no more on Android.

    I don't use ZX but, from the many previous threads on the subject, I suspect the OnScanResult handler may be called from a thread other than the UI thread. If that is the case, depending on how you use the IsScanning property, you may need to put the scanPage.IsScanning = false; inside the Device.BeginInvokeOnMainThread block.

    Also, your code is structured very strangely. You should be wiring up the OnScanResult handler in the OnAppearing method of ZXingScannerPage, and unwiring it again in the OnDisappearing method of ZXingScannerPage.

    Similarly, the PushAsync of the ZXingScannerPage instance would normally be done somewhere in MainPage, .

    Currently, whilst you have hierarchical navigation going on, all of the logic is flattened into wherever you are setting MainPage.

  • Julien_PerezJulien_Perez Member ✭✭

    @JohnHardman said:

    @Julien_Perez said:
    Hello everyone, so I got a problem when I want to push a ZXingScannerPage for scan a QRCode. This is my code :

            MainPage = new NavigationPage(new MainPage());
        
            var scanPage = new ZXingScannerPage();
            await MainPage.Navigation.PushAsync(scanPage, true);
            scanPage.OnScanResult += (result) =>
            {
                scanPage.IsScanning = false;
                Device.BeginInvokeOnMainThread(() =>
                {
                    QrCodeScanned = JsonConvert.DeserializeObject<QRCode>(result.Text);
                });
            };
    

    So basically this code work on Android, but not on iOS. And when i switch the PushAsync method to the PushModalAsync method it's work on iOS but no more on Android.

    I don't use ZX but, from the many previous threads on the subject, I suspect the OnScanResult handler may be called from a thread other than the UI thread. If that is the case, depending on how you use the IsScanning property, you may need to put the scanPage.IsScanning = false; inside the Device.BeginInvokeOnMainThread block.

    Also, your code is structured very strangely. You should be wiring up the OnScanResult handler in the OnAppearing method of ZXingScannerPage, and unwiring it again in the OnDisappearing method of ZXingScannerPage.

    Similarly, the PushAsync of the ZXingScannerPage instance would normally be done somewhere in MainPage, .

    Currently, whilst you have hierarchical navigation going on, all of the logic is flattened into wherever you are setting MainPage.

    Ok so severals things here :

    1: I will try to put the scanPage.IsScanning = false; inside the Device.BeginInvokeOnMainThread block like you say, maybe it's better.

    2: For your idea about OnAppearing and OnDisappearing of the ZXingScannerPage it's wrong. The ZXingScannerPage have a delegate who is Invoke when the QRCode is correcly scanned, and we get the result automatically. So I need to keep the delegate, it's that way the plugin is used.

    3: For your advise where I should make the push in MainPage, I don't want to that way (in fact my boss don't want that way), i need to make the QRCode's scan in the very beginning of the app. I just set the MainPage for avoir a null exception

  • JohnHardmanJohnHardman GBUniversity mod
    edited May 14

    @Julien_Perez said:
    2: For your idea about OnAppearing and OnDisappearing of the ZXingScannerPage it's wrong.

    Not wrong. You might prefer to unwire the handler using NavigationPage.Popped, but otherwise it's fine.

    @Julien_Perez said:
    3: For your advise where I should make the push in MainPage, I don't want to that way (in fact my boss don't want that way), i need to make the QRCode's scan in the very beginning of the app. I just set the MainPage for avoir a null exception

    Do you ever show the MainPage or is it always hidden behind ZXingScannerPage? If it's always hidden, get rid of it. If there is some particular reason that you want a dummy page before pushing the ZXingScannerPage, there is no reason that the ZXingScannerPage could not be pushed from the OnAppearing of the MainPage rather than your current flattened way of doing things (basically, by flattening things, you are breaking encapsulation, a key tenet of OOD/OOP).

    But having said that, it's your code, so it's your choice (or your boss's choice) :-)

Sign In or Register to comment.