xamarin

Xamarin Native, Xamarin Forms and native mobile

I hear many misunderstandings of what Xamarin is and how it differs from native mobile.

There are two flavours of Xamarin: Xamarin Native and Xamarin Forms. They are very different.

The first offers a native mobile experience with the UI written in the native language for the device type. Therefore an understanding of the native tooling, languages, OSs and devices is required to do this type of mobile development. The advantage here is that Xamarin Native developers typically know native development but can also work across both iOS and Android in their respective native languages.

The second is an abstraction, does not have access to all native features and has more shared code between the device types than Xamarin Native. Forms is more suited to prototypes and line of business apps rather than consumer apps.

For an excellent overview of what Xamarin Native and Xamarin forms are and how they differ from native mobile, have a quick read of this:

https://www.altexsoft.com/blog/mobile/the-good-and-the-bad-of-xamarin-mobile-development/

 

Using the iOS AVFoundation sdk in Xamarin to take a picture and save to the image gallery

Using the AVFoundation you can capture still images from your app, convert to a CIImage, obtain a mutable copy of its metadata (you can add custom properties), then save to the device's image gallery:

 

async void TakePhotoButtonTapped(UIButton sender)
{
var videoConnection = stillImageOutput.ConnectionFromMediaType(AVMediaType.Video);

var sampleBuffer = await stillImageOutput.CaptureStillImageTaskAsync(videoConnection);

var jpegImageAsNsData = AVCaptureStillImageOutput.JpegStillToNSData(sampleBuffer);

var image = CIImage.FromData(jpegImageAsNsData);

var metaData = image.Properties.Dictionary.MutableCopy() as NSMutableDictionary;

var library = new ALAssetsLibrary();

library.WriteImageToSavedPhotosAlbum(jpegImageAsNsData, metaData, (assetUrl, error) => 
{
Console.WriteLine ("assetUrl:"+assetUrl);
});

}

Moving the video seek bar in Xamarin UITest

Do you have videos in your app? Would you like to test the workflow surrounding your video using Xamarin UITest? Don't want to slow down your UI tests waiting for the video to play? Then just fastforward through the video play:

public class VerifyVideoCommand
    {
        readonly IApp _app;
        readonly IWelcomeScreen _welcomeScreen;

        public VerifyVideoCommand ()
        {
            _app = FeatureContext.Current.Get<IApp> ("App");
            _welcomeScreen = FeatureContext.Current.Get<IWelcomeScreen> (ScreenNames.WelcomeScreen);
        }

        public void Execute ()
        {
            //Tap the videoView to show the seekbar
            _app.WaitForElement (_welcomeScreen.VideoView, timeout: TimeConstants.TwentySeconds);
            _app.Tap (_welcomeScreen.VideoView);

            //Move the seekbar
            _app.Tap (_welcomeScreen.VideoView);
            _app.WaitForElement(_welcomeScreen.VideoSeekBar, timeout: TimeConstants.TwentySeconds);
            var slider = _app.Query (_welcomeScreen.VideoSeekBar).First ();
            _app.TapCoordinates (slider.Rect.Width, slider.Rect.CenterY);
        }
    }

Using AIDL files in Xamarin

 

If you ever need to use inter process communication you have the option of using AIDL (Android Interface Definition Language). To do so, import your AIDL file(s) into your Xamarin solution. Define your class that will call the service described by the aidl file. Init an intent to bind to the Service. Then implement a ServiceConnection class that inherits from java.lang.Object and implements IServiceConnection.


using System;
using Android.Content;
using Aidlservice;
using Android.OS;
using Android.App;

namespace AidlExample
{
    public class MyClass
    {

        IWoyouService woyouService;
        WoyouServiceConnection serviceConn;

        public void Init(Context context)
        {
            serviceConn = new WoyouServiceConnection();

            var intent = new Intent();
            intent.SetPackage("aidlservice");

            intent.SetAction("aidlservice.IWoyouService");
            context.StartService(intent);
            context.BindService(intent, serviceConn, Bind.AutoCreate);
        }

        public void DoSomething(String msg, ICallback callback)
        {
            woyouService = serviceConn.GetService();

            if (woyouService != null)
            {
                try
                {
                    woyouService.MyMethod(msg, callback);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.Print(string.Format("Error: {0}", ex.Message));
                }
            }
        }
    }

    public class WoyouServiceConnection : Java.Lang.Object, IServiceConnection
    {
        public new void Dispose()
        {
            base.Dispose();
        }

        public IWoyouService GetService()
        {
            return woyouService;
        }

        IWoyouService woyouService = null;

        public void OnServiceDisconnected(ComponentName name)
        {
            woyouService = null;
        }        

        public void OnServiceConnected(ComponentName name, IBinder service)
        {
            woyouService = IWoyouServiceStub.AsInterface(service);
        }
    }

}
 

And remember to set the build action of the AIDL files to AndroidInterfaceDescription