Start a new topic
Solved

Xamarin Forms and Wikitude

Xamarin Forms and Wikitude


Hi everyone,

I'm trying to create a Xamarin Forms project for Android and iOS with the Wikitude Xamarin Component.

I have problems getting it to run and I need a starting point. The example here (https://github.com/Wikitude/wikitude-xamarin) does not cover the use of Xamarin forms.

I think I have to create a custom PageRenderer for the ArchitectView? How would I go about this?

Any help greatly appreciated!

Robert

Hi Robert,
Right now we do not have any example on how to use our Component with Xamarin Forms as we don't offer the missing glue code to use our Component within a Xamarin Forms application.

You're right, you would need to implement your own PageRenderer like it's described here.

Best regards,

Andreas

Thanks!

I'm half way into writing a custom ViewRenderer for the ArchitectView for Android.

namespace Wikitude
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new ArchitectViewPage();
        }
    }
}

I can't access the StartupConfiguration class in the portable code part of the project. So I created the properties in the custom control and get the values in the platform specific custom renderer.

namespace Wikitude
{
    public class FormsArchitectView : View
    {
        #region Bindable Properties
        public static readonly BindableProperty LicenseKeyProperty =
            BindableProperty.Create(
            propertyName: "LicenseKey",
            returnType: typeof(string),
            declaringType: typeof(FormsArchitectView),
            defaultValue: default(string));

        public static readonly BindableProperty FeatureProperty =
            BindableProperty.Create(
            propertyName: "Features",
            returnType: typeof(int),
            declaringType: typeof(FormsArchitectView),
            defaultValue: default(int));

        public static readonly BindableProperty WorldUrlProperty =
            BindableProperty.Create(
            propertyName: "WorldURL",
            returnType: typeof(string),
            declaringType: typeof(FormsArchitectView),
            defaultValue: default(string));
        #endregion

        #region Properties
        public string LicenseKey
        {
            get { return (string)GetValue(LicenseKeyProperty); }
            set { SetValue(LicenseKeyProperty, value); }
        }

        public int Feature
        {
            get { return (int)GetValue(FeatureProperty); }
            set { SetValue(FeatureProperty, value); }
        }

        public string WorldUrl
        {
            get { return (string)GetValue(WorldUrlProperty); }
            set { SetValue(WorldUrlProperty, value); }
        }
        #endregion

    }


The ArchitectViewPage simply creates a new FormsArchitectView and fills it with values.

namespace Wikitude
{
    public class ArchitectViewPage : ContentPage
    {
        FormsArchitectView architectView;

        private const string SAMPLE_WORLD_URL = "...";
        public const string WIKITUDE_SDK_KEY = "...";

        public ArchitectViewPage()
        {
            architectView = new FormsArchitectView
            {
                LicenseKey = WIKITUDE_SDK_KEY,
                WorldUrl = SAMPLE_WORLD_URL,
                Feature = 2,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand
            };
            Content = architectView;
        }
    }



namespace Wikitude.Droid
{
    public class ArchitectViewRenderer : ViewRenderer<Wikitude.FormsArchitectView, Wikitude.Architect.ArchitectView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Wikitude.FormsArchitectView> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                var architectView = new ArchitectView(Forms.Context);
                SetNativeControl(architectView);
            }

            if (e.OldElement != null)
            {
                
            }

            if (e.NewElement != null)
            {
                var startupConfiguration = new StartupConfiguration(Element.LicenseKey, Element.Feature);
                architectView.OnCreate(startupConfiguration);
            }
        }
    }
}

But I'm stuck. At the moment the app crashes directly after start. Where do I call architectView.OnCreate(startupConfiguration), architectView.OnPostCreate(), and architectView.Load(SAMPLE_WORLD_URL)?

Any help would be greatly appreciated.

Robert

Anyone?

Hi Robert,
onCreate and onPostCreate are Android application lifecycle methods. You usually call the Wikitude SDK equivalents in the corresponding Android Activity subclass. I'm not sure where to call them in a Xamarin Form ViewRenderer. You can try to call onPostCreate right after onCreate.

Load can be called as soon as you know the Architect World URL. You can try to call it right after onCreate/onPostCreate.

Best regards,

Andreas

I've now reached a state where the app does not crash. The app shows the Wikitude logo, and then the camera image.
For some unknown reason it does not load the world located in "Assets/samples/1_Client$Recognition_1_Image$On$Target/index.html".

There's no error message when calling architectView.load except a log stating " ImeThread is not enabled."

Hi Robert,
The Architect World path that you pass is correct? You can implement the 'ArchitectView.ArchitectWorldLoadedListener' to get a callback in case the Wikitude SDK is unable to load the Architect World from a given URL.

The console log you posted is not from the Wikitdue SDK.

Best regards,

Andreas

Thanks!

I implemented the listener an it reports that the world was loaded.

I can see the camera image, but it does not show any HTML content, or 3d models.

I get a few logs like:

called unimplemented OpenGL ES API
<core_glHint:84>: GL_INVALID_ENUM
Cannot call determinedVisibility() - never saw a connection for the pid: 21425

I am not sure if that has anything to do with that. There might be problems with the ArchitectWebView and the Open GL rendering in Xamarin Forms?

Hi Robert,
The logs are not directly related to the Wikitude SDK. You find them in our example application as well.

If you don't see any html element, I still guess that the world is not loaded correctly. You could try to attach the device to the Chrome JS debugger and see if there is actually something loaded.

Maybe there are some lifecycle methods missing or called to early, but If you see the camera this already seems fine. 

You could try to load any other .html file just to see if our SDK is able to load the web page from the given url.

Best regards,

Andreas

Awesome! Congratulations!

Thank you!

I had to set the build action for the sample assets to "Android Asset". When I copied and pasted the world from the sample project to my project, it had set it to "None" instead.



Now it works nicely! Thanks a lot!

Hey, Robert. I'm trying to accomplish the same task as you. Could you, please, explain how did you handle this issue about calling OnCreate and OnPostCreate methods of ArchitectView from ViewRenderer? I simply call them one after another and all I get is loaded Wikitude control, but without any image from camera, only black screen with html/js controls in it. Thanks in advance.

Hi Robert,

 

Your integration of Wikitude in Xamarin.Forms looks really good !

Can you share the last update of your code please ?

I think it will help a lot of people like me.

Thanks.
Hey,

I made a simple example project Wikitude Example for Xamarin.Forms
with the current SDK samples from Wikitude.

Markus


 

Login or Signup to post a comment