Pages

Monday, 23 November 2020

Enable scroll on page when keyboard displayed

 You can also manually scroll your page using below code

void EntryKeyboardHandle_Focused(object sender, Xamarin.Forms.FocusEventArgs e)
        {
            Device.BeginInvokeOnMainThread(async () =>
            {
                var height = SignupGrid.Height;
                await MainScroll.ScrollToAsync(0, height, true);
            });
        }

You need to put your grid or stacklayout in scroll view and put focus event on entry.

Focused="EntryKeyboardHandle_Focused"
Please also read More ....

Tuesday, 10 November 2020

Glide

Glide is a fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.

Glide supports fetching, decoding, and displaying video stills, images, and animated GIFs. 

Glide includes a flexible API that allows developers to plug in to almost any network stack. By default Glide uses a custom HttpUrlConnection based stack, but also includes utility libraries plug in to Google's Volley project or Square's OkHttp library instead.

Glide's primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image.

glidex.forms

A library containing a Xamarin.Forms IImageViewHandler to speed up images on Android. Based on Glide. Just add Android.Glide.Forms.Init(this); after Xamarin.Forms.Forms.Init();




Google recommends Glide for simplifying the complexity of managing Android.Graphics.Bitmap within your apps.

glidex.forms is small library we can use to improve Xamarin.Forms image performance on Android by taking a dependency on Glide. 

How do I use glidex.forms?

To set this library up in your existing project, merely:

  • Add the glidex.forms NuGet package
  • Add this one liner after your app's Forms.Init call:
Xamarin.Forms.Forms.Init (this, bundle);
//This forces the custom renderers to be used
Android.Glide.Forms.Init (this);
LoadApplication (new App ());

How do I know my app is using Glide?

On first use, you may want to enable debug logging:

Android.Glide.Forms.Init (this, debug: true);

glidex.forms will print out log messages in your device log as to what is happening under the hood.

If you want to customize how Glide is used in your app, currently your option is to implement your own IImageViewHandler. See the GlideExtensions class for details.

Youtube GUIDE



Github LINK 

Monday, 9 November 2020

OTP Verification and Validation Using Twilio

OTP verification combines a user login—including a Password—with physical access to a smartphone or landline telephone to verify authorized access to an Account. A user can begin to log into a secured service by entering an ID and password, but then must receive a one-time code (OTC) or one-time password (OTP) via SMS texting or a voice telephone call using a phone number associated with the account. Entering this additional one-time credential constitutes the second step of verification or the second factor of authentication, with the idea that only someone who knows the correct account password and who physically possesses the required object (Mobile Phone and the associated Phone Number) can gain access to the account.OTP verification are very much essential for 2 Factor authentication which adds extra layer of security.


Step 1 : Sign Up with Twilio
https://www.twilio.com/
Notes :
1. You have to enable Twilio Trail Number
2. You have to copy the AccountSID and AUTH Token and paste it inside your project.

SDK : https://www.twilio.com/docs/libraries/csharp-dotnet/details

MainPage.Xaml


<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="TwilioDemo.MainPage">
    <StackLayout VerticalOptions="CenterAndExpand" Margin="20,0">
     <Entry Placeholder="Please enter OTP" x:Name="MyOtp"/>
      <Button Text="Login" Clicked="Button_Clicked"/>
    </StackLayout>
</ContentPage>

MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Xamarin.Forms;

namespace TwilioDemo
{ // Learn more about making custom code visible in the Xamarin.Forms previewer // by visiting https://aka.ms/xamarinforms-previewer [DesignTimeVisible(false)] public partial class MainPage : ContentPage { string MyrecentOTP; public MainPage() { InitializeComponent(); const string accountSid = "xxxx"; // Your Account SId const string authToken = "xxxxxx"; // Your Account AuthToken TwilioClient.Init(accountSid, authToken); Random generator = new Random(); String randomotp = generator.Next(0, 9999).ToString("D4"); var message = MessageResource.Create( body: "Your new OTP is ?" + randomotp, from: new Twilio.Types.PhoneNumber("+12052368532"), //This is my Trail Number https://www.twilio.com/console to: new Twilio.Types.PhoneNumber("+91739712333") //Add your phone number here ); Console.WriteLine(message.Sid); MyrecentOTP = randomotp; } void Button_Clicked(System.Object sender, System.EventArgs e) { if(MyOtp.Text == MyrecentOTP) { //Go to dashboard } else { App.Current.MainPage.DisplayAlert("Alert","Otp verification Error","Ok"); } } } }

Note :
1.Add countries where you want to give access to.
2.Verify the user phone number [Only on the trail account]
3.ProgrammableSMS>Settings>GeoPermissions
4.Verifying the phone number[Trail Account Only]

Sunday, 8 November 2020

Passing Data to Server - POST using QuaryString - How to Handle this In Xamarin Forms

Sometime we get in situation that we have to pass data in URL String and method is Created as POST. So in Xamarin How we send this,Check below scenario.

Ex:

http://serveraddress.in/v1/test/cart/add?userID=39964949d-d5-44ff-967169-4ec6b725e121fg&productID=0c0d65a239-e352-4a6e-98b5-0a55a0327aa4&size=L&quantity=1

Then above method is created as POST and We are Passing into Parameter so how we handle this in Xamarin Forms.

Methods:

public async Task AddProductToCart(string userID, string productID, string size, string quantity)
{
        var url = Configuration.Instance.MyDomainAPIUri;

        var data = "?userID=" + userID + "&productID=" + productID + "&size=" + size + "&quantity=" + quantity;

        var stringContent = new StringContent(data, UnicodeEncoding.UTF8, "application/json");


                using (var client = new HttpClient())
                {
                        await AddHeaders(client, false);

                        using (var response = await client.PostAsync(url+data, stringContent))
                                    {
                                        if (response.StatusCode == System.Net.HttpStatusCode.OK)
                                                        {
                                                                try
                                                                   {
                                                                    var properties = await response.Content.ReadAsStringAsync();
                                                                    return properties;
                                                                    }
                                                                catch (Exception ex)
                                                                    {
                                                                    return null;
                                                                    }
                                                            }
                                           else
                                                        {

                                                            return null;
                                                        }

                                           } // INNER USING
                        } // OUTER USING
}

Live Broad cast TV inside Xamarin forms application.

 Step 1 :

At first we are going to get API Key and API Code from streamvideoproviders

https://www.streamingvideoprovider.com/



Step 2 : Click on Web TV -> Click on AddMedia.


Additional Note : Web TV plays your playlist videos live 24×7. You can also select live stream and use OBS studio (mac) and play a live stream video directly to Xamarin Forms App.

Step 4: It’s time to get API credentials from streamingvideoprovider. Click on Settings> You will find API key and API Code on Right side. Don’t forget to click on save.


That’s all with streamingvideoprovider. We will be using API key and Code inside our Xamarin forms apps.

Plugins to be installed on all projects: Plugin.MediaManager.Forms
1. https://github.com/Baseflow/XamarinMediaManager

Step 1 : So at first we will try to check video player working on stable condition or not for both android and iOS.

1. On Android
Call from MainActivity: CrossMediaManager.Current.Init(this);
2.On Other platforms
Call from AppDelegate, etc: CrossMediaManager.Current.Init();
3. Add this line of code on Xamarin Forms APP on any pages of XF.
[ <mm:VideoView VerticalOptions=”FillAndExpand” Source=”http://yourwebsite\videos\test.3gpp” /> ]
This VideoView inherits from namespace :
xmlns:mm=”clr-namespace:MediaManager.Forms;assembly=MediaManager.Forms”

Note : If you are using http request on the Xamarin forms app. Then you have to enable App Transport Security on iOS and Http clear text on Android. 
iOS : https://docs.microsoft.com/en-us/xamarin/ios/app-fundamentals/ats 

Android 




That’s all 


Then you can run your 1st video on the Xamarin Forms Project for both android and iOS: 

Now it’s time to integrate the Platform independent code inside our XF .net shared project.

Full Source Code Link



Xamarin Forms Upper and Lower Case

Xamarin Forms 4.8 release has provided us some recent hidden features.

One of them is Text Transform feature.


Which has 4 properties :
1. Default
2. None
3. Upper Case
4. Lower Case.

Ex: 

 <StackLayout Spacing="20" VerticalOptions="CenterAndExpand">

     <Label HorizontalTextAlignment="Center" TextTransform="Lowercase" Text="This is Lower Case implementation of label" TextColor="Black"/>

     <Label HorizontalTextAlignment="Center" TextTransform="Uppercase" Text="This is Upper Case implementation of label" TextColor="Black"/>

    </StackLayout>


Tuesday, 3 November 2020

Show/Hide Views in RunTime in Xamarin Forms

When developing UI a common use case is to hide/show a View according to a certain condition, when thinking on how to do this the first thing that comes to mind is to add an IsVisible property and just hide/show it according to a condition but doing that has performance implications since hiding an element does not remove it from the UI, which means that if you have 10 views you will have all of them loaded in memory even when not visible.


Project Structure 


Code 

App.xaml

<?xml version="1.0" encoding="utf-8"?>

<Application xmlns="http://xamarin.com/schemas/2014/forms"

             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

             x:Class="HideShowXF.App">

    <Application.Resources>

        <ResourceDictionary>

            <Style x:Key="ButtonStyle" TargetType="Button">

                <Setter Property="BackgroundColor" Value="#2196F3" />

                <Setter Property="VerticalOptions" Value="Start" />

                <Setter Property="HeightRequest" Value="50" />

                <Setter Property="TextColor" Value="White" />

                <Setter Property="HorizontalOptions" Value="FillAndExpand" />

            </Style>


            <Style x:Key="ButtonDisabledStyle" TargetType="Button">

                <Setter Property="TextColor" Value="#2196F3" />

                <Setter Property="VerticalOptions" Value="Start" />

                <Setter Property="HeightRequest" Value="50" />

                <Setter Property="BackgroundColor" Value="White" />

                <Setter Property="BorderColor" Value="#2196F3" />

                <Setter Property="BorderWidth" Value="2" />

                <Setter Property="HorizontalOptions" Value="FillAndExpand" />

            </Style>

        </ResourceDictionary>

    </Application.Resources>

</Application>


App.xaml.cs

using HideShowXF.Views;

using Xamarin.Forms;


namespace HideShowXF

{

    public partial class App : Application

    {

        public App()

        {

            InitializeComponent();


            MainPage = new MainPageCarousel();

        }


        protected override void OnStart()

        {

        }


        protected override void OnSleep()

        {

        }


        protected override void OnResume()

        {

        }

    }

}

MainPageCarousel.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HideShowXF.Views.MainPageCarousel"
             xmlns:local="clr-namespace:HideShowXF.Views.CarouselViews.Templates">
    <ContentPage.Resources>
      <ResourceDictionary>
        <local:CarouselDataTemplateSelector x:Key="CarouselDataTemplateSelector"/>
      </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <Grid Padding="20"
              ColumnDefinitions="*, *"
              RowDefinitions="Auto, *">

        <Button Text="Tab1"
                Style="{StaticResource ButtonDisabledStyle}"
                Grid.Row="0"
                Grid.Column="0"
                Command="{Binding SelectItemCommand}"
                CommandParameter="0">
            <Button.Triggers>
                         <DataTrigger TargetType="Button"
                                      Binding="{Binding PositionSelected}"
                                      Value="0">
                    <Setter Property="Style" Value="{StaticResource ButtonStyle}" />
                </DataTrigger>
             </Button.Triggers>
        </Button>

        <Button Text="Tab2"
                Style="{StaticResource ButtonDisabledStyle}"
                Grid.Row="0"
                Grid.Column="1"
                Command="{Binding SelectItemCommand}"
                CommandParameter="1">
             <Button.Triggers>
                         <DataTrigger TargetType="Button"
                                      Binding="{Binding PositionSelected}"
                                      Value="1">
                    <Setter Property="Style" Value="{StaticResource ButtonStyle}" />
                </DataTrigger>
             </Button.Triggers>
        </Button>

       <CarouselView Grid.Column="0"
                     Grid.ColumnSpan="2"
                     Grid.Row="1"
                     ItemTemplate="{StaticResource CarouselDataTemplateSelector}"
                     IsSwipeEnabled="False"
                     IsScrollAnimated="False"
                     Position="{Binding PositionSelected}">
           <CarouselView.ItemsSource>
              <x:Array Type="{x:Type x:String}">
                <x:String>1</x:String>
                <x:String>2</x:String>
              </x:Array>
           </CarouselView.ItemsSource>
        </CarouselView>
    </Grid>
    </ContentPage.Content>
</ContentPage>

MainPageCarousel.xaml.cs

using Xamarin.Forms;

namespace HideShowXF.Views
{
    public partial class MainPageCarousel : ContentPage
    {
        public MainPageCarousel()
        {
            InitializeComponent();
            BindingContext = new MainPageViewModel();
        }
    }
}

MainPageViewModel.cs

using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;

namespace HideShowXF
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        public ICommand SelectItemCommand { get => new Command<string>((param) => PositionSelected = int.Parse(param)); }

        public int _positionSelected = 0;

        public int PositionSelected
        {
            set
            {
                if (_positionSelected != value)
                {
                    _positionSelected = value;

                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PositionSelected)));
                }
            }
            get => _positionSelected;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
CarouselDataTemplateSelector.cs

using Xamarin.Forms;

namespace HideShowXF.Views.CarouselViews.Templates
{
    public class CarouselDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate Tab1 { get; set; }
        public DataTemplate Tab2 { get; set; }

        public CarouselDataTemplateSelector()
        {
            Tab1 = new DataTemplate(typeof(Tab1View));
            Tab2 = new DataTemplate(typeof(Tab2View));
        }

        protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        {
            var position = $"{item}";

            if(position == "1")
                 return Tab1;

                return Tab2;
        }
    }
}

Tab1View.xaml

<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HideShowXF.Views.CarouselViews.Tab1View"
             BackgroundColor="Red"
             VerticalOptions="FillAndExpand"/>

Cs File :Tab1View.xaml.cs
namespace HideShowXF.Views.CarouselViews
{
    public partial class Tab1View 
    {
        public Tab1View()
        {
            InitializeComponent();
        }
    }
}

Tab2View.xaml
<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HideShowXF.Views.CarouselViews.Tab2View"
             BackgroundColor="Yellow"
             VerticalOptions="FillAndExpand"/>

Tab2View.xaml.cs

namespace HideShowXF.Views.CarouselViews
{
    public partial class Tab2View 
    {
        public Tab2View()
        {
            InitializeComponent();
        }
    }
}

MainPageControlTemplate.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HideShowXF.MainPageControlTemplate"
             xmlns:View="clr-namespace:HideShowXF.Views.Templates"
             ControlTemplate="{DynamicResource Tab1View}">
    <ContentPage.Triggers>
           <DataTrigger TargetType="ContentPage"
                        Binding="{Binding PositionSelected}"
                        Value="2">
            <Setter Property="ControlTemplate" Value="{DynamicResource Tab2View}" />
        </DataTrigger>
    </ContentPage.Triggers>
    <ContentPage.Resources>
        <ResourceDictionary>
            <ControlTemplate x:Key="Tab1View">
                 <View:Tab1View />
            </ControlTemplate>
             <ControlTemplate x:Key="Tab2View">
                 <View:Tab2View />
            </ControlTemplate>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Padding="20"
                 Orientation="Horizontal">

        <Button Text="Tab1"
                Style="{StaticResource ButtonDisabledStyle}"
                Command="{Binding SelectItemCommand}"
                CommandParameter="1">
            <Button.Triggers>
                         <DataTrigger TargetType="Button"
                                      Binding="{Binding PositionSelected}"
                                      Value="1">
                    <Setter Property="Style" Value="{StaticResource ButtonStyle}" />
                </DataTrigger>
             </Button.Triggers>
        </Button>

        <Button Text="Tab2"
                Style="{StaticResource ButtonDisabledStyle}"
                Command="{Binding SelectItemCommand}"
                CommandParameter="2">
             <Button.Triggers>
                         <DataTrigger TargetType="Button"
                                      Binding="{Binding PositionSelected}"
                                      Value="2">
                    <Setter Property="Style" Value="{StaticResource ButtonStyle}" />
                </DataTrigger>
             </Button.Triggers>
        </Button>
    </StackLayout>
</ContentPage>

Cs File MainPageControlTemplate.cs

using System;
using System.Collections.Generic;

using Xamarin.Forms;

namespace HideShowXF
{
    public partial class MainPageControlTemplate : ContentPage
    {
        public MainPageControlTemplate()
        {
            InitializeComponent();
        }
    }
}

Full Source code : Link

Monday, 2 November 2020

Implement Secure Storage In Your Xamarin.Forms

Sensitive Data

If you want to save credentials — or any other sensitive data — on your mobile smart device in your Xamarin / Xamarin.Forms project you better take no risk and use the safest way possible.

Implementing secure storage in your Xamarin.forms app can be done as close to the native OS as possible.

Native Storage

But the safest way to actually save the sensitive data on your device is using the mobile platform’s NATIVE secure way of storing such information.

That means that you need to use the Keychain services in iOS, and the KeyStore class in Android to make sure the data is stored and encrypted accordingly.

These are just the best options as two big enterprises (Apple behind iOS, Google behind Android) have been working on things like security and have chosen to implement some kind of storage space that can be utilized by mobile apps to safely write down key-value pairs of information.


Key-Value Only

To be clear: they REALLY ARE intended for key-value pairs of information.

The native storage isn’t intended for big data chunks like binary data, video content or other stuff. For those, you’ll need to provide your own encrypted solutions and data-storage implementations.

Luckily, for us Xamarin developers, cross-platform abstracted plugins are available for integrating this in your shared code (whether it is a shared library or project).

Xamarin.Auth


“Xamarin.Auth” is the name of the first cross-platform save storage plugin and using it to save key-value data is a safe way to go.
The plugin is created by Xamarin and updated on a regular basis.

It helps you to save (key-value based) information via its abstracted cross-platform functions.
It will use the native storage of iOS and Android as indicated before and it has been used a lot by developers.

This isn’t a plugin purely for storage, though. And that might be a thing for some developers. As the name “.Auth” indicates, it is focussed on authorization and not purely on storage.

You’ll find the plugin here: Xamarin.Auth on GitHub

And A GitHub Recipe for Xamarin.Forms over here: Xamarin.Auth Recipe

Starter Issues When Implementing Xamarin.Auth

But when you’re creating a new iOS app version, there is one issue that often appears to be surfacing as soon as you want to actually save values to the secure storage.

The SaveAsync Error

“SaveAsync error = error = Could not save account to KeyChain: MissingEntitlement\nAdd Empty Entitlements.plist

File / New file / iOS / Entitlements.plist

SecKeyChain.Add returned : MissingEntitlement\n1. Add Keychain Access Groups to the Entitlements file.

Turn on the Keychain Sharing switch in the Capabilities section in the app.”

The error when building and trying to run the project on the iOS simulator

When you’ve followed the plugin steps, there are two problems preventing you from running this smoothly for now. What follows below are the two fixes needed to get Xamarin.Auth working for your solution.

Step One: Enable Keychain Usage

You need to enable the app to use the keychain as follows:

  1. In Visual Studio for Mac, double click Entitlements.plist in your file inspector
  2. scroll down to the Keychain item and select “Enable Keychain”
  3. this will add the “Keychain Access Groups” value to the plist.

This was an easy one to fix, right?

Step Two: Entitlements Not Found On The Simulator

The Entitlements.plist is present when you create a Xamarin.Forms application, and can be found in the .iOS project’s root.

The problem, however, is that by default, this entitlement file isn’t included into the simulator build target.

And we need the simulator to run and check how our app operates at the simplest level, at least. It would ruin the workflow for thousands of Xamarin developers if there wouldn’t be a way around it, right?

The steps to fix this are as follows:

  1. In Visual Studio for Mac, double click the .iOS project
  2. Select iOS Bundle Signing
  3. Verify that you’ve selected the Debug Configuration for the iPhoneSimulator platform
  4. Set the value Entitlements.plist as value for the Custom Entitlements input field




Now, your entitlements file will be packed together with the debug build for iPhone Simulator targets and work as expected.

There is a comment for a related issue in the GitHub repo indicating you should add an environment variable named “ENTITLEMENTS_REQUIRED” with the value “yes” in order for the project to generate the entitlement file without packing the one already in your project.

This might be because the original entitlements file might be packed with more sensitive stuff which you don’t want to be saved on your harddisk and in simulator versions all over the place. I’m still checking into this option though.

Xamarin Essentials: Secure Storage



Xamarin Essentials is a packaged set of tools, that evolved out of the cross-platform​ needs of Xamarin developers. If you will, it’s a bouquet of plugins that have been optimized to use the same API interfacing, enjoy great documentation and seems to be the better implementation.

You can check out the formal Microsoft documentation here:
Xamarin Essentials: Secure Storage documentation

As it appears, it uses the same principles for safe storage as the Xamarin.Auth plugin.

As indicated, Xamarin Essentials is a package bundle that bears a lot of functionality. One of those pieces is Secure Storage.

One Plugin BUT Linker Safe

Although the Essentials package comes as ONE NuGet package, it is implemented Linker Safe. What that means for the size of your application?

The repo’s FAQ page explains it the best:

We built Essentials to be Linker Safe, which means if you only use ONE feature that is the ONLY feature that will be added to your app. The rest will be linked away and even works with Link All Assemblies.

Encryption Included

One advantage that was immediately visible in the documentation and code for this secure storage implementation is that it is also stored encrypted and utilizes a secure way to ensure you need to unlock the device and/or enter the application to get to the stored value.


There you have it. Two ways to make sure that passwords, tokens or other small pieces of sensitive data can be securely stored on the device.

Keep in mind that, in the end, nothing digital is un-hackable. But saving data using the native mobile platform’s best practices is the minimum effort that a mobile developer should implement.

Helpful Link1  Link2  Link3 Link4 Link5