Xamarin Forms and FingerPrint (iOS and Android only)

In this post I explain how to use Finger Print in your app. This app is working only in iOS or Android.

Add NuGet

In your solution, you have to add a package called Plugin.Fingerprint.

XamarinForms Fingerprint Nuget

Only for Android, in your Droid project add another package called Plugin.CurrentActivity. Also, you have to add a permission for fingerprint (and one specific for Samsung).

<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission 
       android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />

Implementation

Now we implement in our PCL project the request for fingerprint. First of all we have to check if a device supports fingerprints. If yes, we show the typical dialog.

XamarinForms Finferprint Dialog

Now I added a button in the XAML and its name is buttonFingerPrint. For it in the code behind, I added a Clicked event. Then In the new function, I'm checking is the device supports fingerprint.

var result = await CrossFingerprint.Current.IsAvailableAsync(true);

The function IsAvailableAsync as true as parameter but it is useful only for iOS to have a code in return. If the device supports fingerprint, I'll show a dialog request with this code:

if (result) {
    var auth = await CrossFingerprint.Current
               .AuthenticateAsync("Authenticate access to fingerprint");
    if (auth.Authenticated) {
        await DisplayAlert("Whoooowhooo!", "Authentication is done!", "Ok");
    }
    else {
        await DisplayAlert("Something wrong", 
                           "There is a problem with your finger", "Ok");
    }
}
else {
    await DisplayAlert("Finger print not available", 
                       "You can't use your finger for using this app", "Ok");
}

Testing on an emulator

iOS

If you test your project in an iOS device, be careful to allow to use Touch ID from Hardware menu with Toggle Enrolled State. When you want to test your virtual finger, select Matching Touch.

XamarinForms Fingerprint iOS Emulator

Android

Let's go to the Android emulator. You need to set up fingerprint under Settings. From your Terminal call (5554 is the default port of an Android emulator but it can be different in your computer)

telnet 127.0.0.1 5554

Then you have to copy an auth token from an hidden file called .emulator_console_auth_token in your profile. In the terminal execute

auth <yourcode>

Now open Settings > Security > Fingerprint and follow the instruction. When you have to recognise your finder, come back to the terminal and type

finger touch 1

Then you can continue with the wizard.

Now you can execute your app. When your app ask your fingerprint, come back to the Terminal and type again

finger touch 1

Android is always easy to use! You find my solution on GitHub.

Happy coding!

Xamarin, Android and starting a service at device boot

In my previous post called Xamarin: how to Start an Application at Device Boot in Android, I explained how you can change your Android Xamarin's project to launch your app at the device boot.

It is a good start but my problem was a bit more complex. I want to create a background service to track the geolocation of a device. I googled a lot to find a solution without a great success. Then I started to implement my code with some tests. Finally, I found a good way and I'm sharing with you it.

Create a Broadcast Receiver

What is a Broadcast Receiver

A broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work.

How to implement a Broadcast Receiver

I show you now two implementations of it:

  • BootReceiver: this receiver is responsible to do something when a device starts. For that, we have to allow the app to read this event. In your AndroidManifest.xml you must add a permission called RECEIVE_BOOT_COMPLETED.
  • AirplaneModeReceiver: this receiver filters only the broadcast for ActionAirplaneModeChanged.

I start to show you the second one because it is more simple.

	[BroadcastReceiver]
    [IntentFilter(new[] { Android.Content.Intent.ActionAirplaneModeChanged })]
	public class AirplaneModeReceiver : BroadcastReceiver
	{
		private static readonly string TAG = typeof(AirplaneModeReceiver).FullName;

		public override void OnReceive(Context context, Intent intent)
		{
			Log.WriteLine(LogPriority.Debug, TAG, "AirplaneModeReceiver OnReceive Mode " + 
                          isAirplaneModeOn(context));
		}

		private static bool isAirplaneModeOn(Context context)
		{
			var airplane = Android.Provider.Settings.Global.GetInt(context.ContentResolver, 
                           Android.Provider.Settings.Global.AirplaneModeOn);
			return airplane != 0;
		}
	}

Although you can find a lot of posts where people said that you have to declare your broadcast in the AndroidManifest, I discover if I add the broadcast in the AndroidManifest, the broadcast won't work.

This is the first broadcast. Basically when a user taps on AirPlaneMode, this broadcast receives the status with isAirplaneModeOn function and writes this change in the logs.

BootReceiver is more interesting. When a device is booting, this broadcast starts a service to track the position. Also, in my code you find TimeService: I use this service to check if the service is starting properly and the notification is working and updating.

    [BroadcastReceiver]
    [IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
    public class BootReceiver : BroadcastReceiver
    {
        private static readonly string TAG = typeof(BootReceiver).FullName;

        public override void OnReceive(Context context, Intent intent)
        {
            Log.WriteLine(LogPriority.Debug, TAG, "BootReceiver OnReceive");

            Intent i = new Intent(context, typeof(GPSService));
            i.AddFlags(ActivityFlags.NewTask);
            context.StartService(i);
            Log.WriteLine(LogPriority.Debug, TAG, 
                          "BootReceiver OnReceive LocationService started");

			i = new Intent(context, typeof(TimerService));
			i.AddFlags(ActivityFlags.NewTask);
			context.StartService(i);
			Log.WriteLine(LogPriority.Debug, TAG, 
                          "BootReceiver OnReceive TimerService started");
		}
    }

The interesting part of this code is when I start a service. Basically, I define a new Intent with the type of service I want to call, then I start the service with the context.

Although you find a lot of posts on line, the right way to define a service in your AndroidManifest is the following:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="pro.wordbank.app.locationtest">
	<uses-sdk android:minSdkVersion="15" />
	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
	<uses-permission android:name="android.permission.INTERNET" />
	<application android:label="LocationTest">
		<service android:name=".TimerService" />
        <service android:name=".LocationService" />
	</application>
</manifest>

I have publish a complete solution of that on GitHub. Happy coding!

Xamarin: how to Start an Application at Device Bootup in Android

This tutorial will explain to stat an application while the Android device boot-up. For this, we need to  listen to the BOOT_COMPLETED action and react to it.

BOOT_COMPLETED is a Broadcast Action that is broadcast once, after the system has finished booting. You can listen to this action by creating a BroadcastReceiver that then starts your launch Activity when it receives an intent with the BOOT_COMPLETED action.

Add this permission to your manifest

In your Android.Manifest you must add thi permission:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

 

BackgroundTest-AndroidManifest

Then open this file and add the following rows under Application:

    <receiver android:name=".BootReceiver" android:enabled="true" 
              android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    </receiver>

In this example, we will create a new BroadcastReceiver called BootReceiver.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace BackgroundTest.Droid.BackgroundServices
{
    public class BootReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            Intent i = new Intent(context, typeof(MainActivity));
            i.AddFlags(ActivityFlags.NewTask);
            context.StartActivity(i);
        }
    }
}

Install the application, and then restart the device. You can see the application will start after the device restarts. An implementation of background services starting with Activity, it explains here.

Source code on GitHub.

Happy coding!

C# and multicultural IsDate() and ToDate()

C# does not provide IsDate() function. Sometimes in your developer environment region settings are different from the live environment. In my case, I don’t know what region settings there are in my company servers.

For this reason, I created a function to check is a string is a date in a culture and to convert a string to a date.

/// 
/// Determines whether the specified text is date.
/// 
/// The text.
/// 
/// true if the specified text is date; 
/// otherwise, false.
/// 
public static bool IsDate(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        DateTime result = DateTime.MinValue;
        foreach (CultureInfo cultureInfo in 
                 CultureInfo.GetCultures(CultureTypes.AllCultures))
        {
            try
            {
                if (DateTime.TryParse(text, cultureInfo, 
                                      DateTimeStyles.None, 
                                      out result))
                    return true;
            }
            catch (Exception ex) { }
        }
    }

    return false;
}

/// 
/// To the date.
/// 
/// The text.
/// System.Nullable<DateTime>.
public static DateTime? ToDate(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        DateTime result = DateTime.MinValue;
        foreach (CultureInfo cultureInfo in 
                 CultureInfo.GetCultures(CultureTypes.AllCultures))
        {
            try
            {
                if (DateTime.TryParse(text, cultureInfo, 
                                      DateTimeStyles.None, 
                                      out result))
                    return result;
            }
            catch (Exception ex) { }
        }
    }

    return null;
}

Happy coding!

Render in MVC a link with image and text

Hi guys, I want in MVC to render a text with an image as an ActionLink. For creating a simple anchor tag, we use Html.ActionLink() helper which generates anchor tag for us.

If you want to create something a bit more complicated, you must create you own component. For this reason, I created the following code. It allows you to create an anchor with an image and a text.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace PSC.MVC.Helpers
{
    public static class CustomHtmlHelpers
    {
        /// 
        /// Enum ImageAndText
        /// 
        public enum ImageAndText
        {
            /// 
            /// Image on the left, text on the right
            /// 
            ImageOnTheLeft,

            /// 
            /// Text on the left, image on the right
            /// 
            ImageOnTheRight
        }

        /// 
        /// Images the action link.
        /// 
        /// The HTML helper.
        /// The link text.
        /// The action.
        /// The controller.
        /// The route values.
        /// The HTML attributes.
        /// The image source.
        /// The alternate text.
        /// The text style.
        /// The image style.
        /// The image position.
        /// IHtmlString.
        public static IHtmlString ImageActionLink(
               this HtmlHelper htmlHelper, string linkText, string action, 
               string controller, object routeValues, object htmlAttributes, 
               string imageSrc, string alternateText = "", 
               string textStyle = "", string imageStyle = "", 
               ImageAndText imagePosition = ImageAndText.ImageOnTheLeft)
        {
            var urlHelper = new UrlHelper(
                    htmlHelper.ViewContext.RequestContext);

            // create the image
            var img = new TagBuilder("img");
            img.Attributes.Add("src", 
                    VirtualPathUtility.ToAbsolute(imageSrc));
            if (!string.IsNullOrEmpty(alternateText))
                img.Attributes.Add("alt", alternateText.Trim());
            if (!string.IsNullOrEmpty(imageStyle))
                img.Attributes.Add("style", imageStyle);

            // create a render for the image and the text
            string render = "";
            if (imagePosition == ImageAndText.ImageOnTheLeft)
                render = img.ToString(TagRenderMode.SelfClosing) + linkText;
            else
                render = linkText + img.ToString(TagRenderMode.SelfClosing);

            // create the anchor with image and text
            var anchor = new TagBuilder("a") {
                InnerHtml = render
            };
            if (!string.IsNullOrEmpty(textStyle))
                anchor.AddCssClass(textStyle);

            // add reference to the anchor
            anchor.Attributes["href"] = urlHelper.Action(action, 
                                                         controller, 
                                                         routeValues);
            anchor.MergeAttributes(new RouteValueDictionary(htmlAttributes));

            return MvcHtmlString.Create(anchor.ToString());
        }
    }
}

In your MVC code you have to add:

@using PSC.MVC.Helpers;

and then you can call your component:
@Html.ImageActionLink("Your text", "Index", "Home", null, null, 
                      "~/Content/images/img.png", "Logo", "navbar-brand", 
                      "width: 40px;")

A Simple Speedtest Application for Xamarin

In my previous post I described how to check your connection in a C# project. I should have the same function in a PCL project for Xamarin. Based on my project, I created this function:
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace PSC.Xamarin.Connection
{
	/// 
	/// Speed test.
	/// 
	public class SpeedTest
	{
		public double SecondsForOneMb { get; set; } = 0;
		public double KbSeconds { get; set; } = 0;

		/// 
		/// Starts the test to download a file from an url.
		/// Read SecondsForOneMb and KbSeconds for the result
		/// 
		public async Task StartTest()
		{
			string url = 
            "http://puresourcecode.com/file.axd?file=/SpeedTest/1024kb.txt";
			HttpClient client = new HttpClient();

			// get current tickcount 
			double starttime = Environment.TickCount;

			// download file from the specified URL, 
			// and save it to C:\speedtest.txt
			// in your project change the path of the following line
			var httpResponse = await client.GetAsync(url);
			byte[] dataBuffer = 
                   await httpResponse.Content.ReadAsByteArrayAsync();

			// get current tickcount
			double endtime = Environment.TickCount;

			// how many seconds did it take?
			// we are calculating this by subtracting starttime from
			// endtime and dividing by 1000 (since the tickcount is in 
			// miliseconds 1000 ms = 1 sec)
			SecondsForOneMb = Math.Floor(endtime - starttime) / 1000;

			// calculate download rate in kb per sec.
			// this is done by dividing 1024 by the number of seconds it
			// took to download the file (1024 bytes = 1 kilobyte)
			KbSeconds = Math.Round(1024 / SecondsForOneMb);
		}
	}
}

Happy coding!

A Simple Speedtest Application

The purpose of this code is the detect how slow is your connection downloading a file from a site. First of all, you have to create a file with a known size: for that you can use fsutil in the prompt (see another post in this blog for info).

When yo do put your file in a webserver (or you can use my url), we can create the code to check the connection speed.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace SpeedTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "A simple speed test connection for your app";

            // the URL to download a file from
            Uri URL = new Uri(
            "http://puresourcecode.com/file.axd?file=/SpeedTest/1024kb.txt"
            );
            WebClient wc = new WebClient();

            Console.WriteLine("Simple speedtest");
            Console.WriteLine("----------------");
            Console.WriteLine("Will test your download rate. " + 
                              "Press any key to begin.");
            Console.ReadKey();

            Console.WriteLine("\nDownloading file: 1024kb.txt...");
            Console.WriteLine("From http://puresourcecode.com");
            Console.WriteLine("Note: This file will automatically " + 
                              "be deleted after the test.");

            // get current tickcount 
            double starttime = Environment.TickCount;

            // download file from the specified URL, 
            // and save it to C:\speedtest.txt
            // in your project change the path of the following line
            wc.DownloadFile(URL, @"C:\speedtest.txt");

            // get current tickcount
            double endtime = Environment.TickCount;

            // how many seconds did it take?
            // we are calculating this by subtracting starttime from
            // endtime and dividing by 1000 (since the tickcount is in 
            // miliseconds 1000 ms = 1 sec)
            double secs = Math.Floor(endtime - starttime) / 1000;

            // calculate download rate in kb per sec.
            // this is done by dividing 1024 by the number of seconds it
            // took to download the file (1024 bytes = 1 kilobyte)
            double kbsec = Math.Round(1024 / secs);

            Console.WriteLine("\nCompleted. Statistics:\n");

            Console.WriteLine("1mb download: \t{0} secs", secs);
            Console.WriteLine("Download rate: \t{0} kb/sec", kbsec);

            Console.WriteLine("\nPress any key to exit...");
            Console.Read();
            Console.WriteLine("Deleting file...");
            try
            {
                // delete downloaded file
                System.IO.File.Delete(@"C:\speedtest.txt");
                Console.WriteLine("Done.");
            }
            catch
            {
                Console.WriteLine("Couldn't delete download file.");
                Console.WriteLine("To delete the file yourself.");
                Console.ReadKey();
            }
        }

    }
}

Happy coding!

$.ajax No 'Access-Control-Allow-Origin' header is present on the requested resource with WebAPI

I want to get data from a WebAPI with jquery

        $("#btnSend").click(function () {
            $("#sending").show();
            $.ajax({
                type: 'GET',
                url: '/Report/SendEmail?quote=18',
                crossDomain: true,
                success: function (msg) {
                    if (msg == 'True') {
                        alert('Email sent to the client');
                    }
                    $("#sending").hide();
                },
                error: function (request, status, error) {
                    $("#sending").hide();
                }
            });
        });

and it produce

‘No Access-Control-Allow-Origin' header is present on the requested resource error.

The solution is to add in the result of the WebAPI the following code:

            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST");
            Response.Headers.Add("Access-Control-Allow-Headers", "accept, authority");
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");

Happy coding!

Xamarin Forms and Google Mobile Ads for iOS

If you have a new Xamarin Project and you want to add an advertising, the simple way it is to use Google Admob. This implementation is only for Android and iOS.

One of the first things people think about when developing for a new platform / using a new technology is monetization; and in my case the question is: how easy is it to integrate AdMob? For Xamarin Forms the answer would be: “It depends” – it depends on luck & on the complexity of what you want to achieve; but I will detail this as we move along.

The first thing you need to do is add the required components to your projects. For this walktrough I will be using Visual Studio but it should be relatively the same when using Xamarin Studio. Here, things go separate ways for each of the platforms:

  • for Android – add the Google Play Services component
  • for iOS – add the AdMob component
  • for Windows Phone – download the SDK from here and add it as a reference

By now, you Android project should no longer be building & you should be receiving a COMPILETODALVIK : UNEXPECTED TOP-LEVEL error. To fix that, go into your Droid project properties, select the Android Options tab and then under Advanced modify the value for the Java Max Heap Size to 1G. Your project should now build without any errors.

Next, inside your shared / PCL project add a new Content View and call it AdMobView. Remove the code generated inside it’s constructor & it should look like this:

public class AdMobView : ContentView
{
    public AdMobView() { }
}

Add this new view to your page. In XAML you can do it like this:

<controls:AdMobView WidthRequest="320" HeightRequest="50" />

Make sure NOTHING interferes with the control. By nothing I mean – overlapping controls, page padding, control margins / spacing, etc. If you have something overlapping the ad control, ads will not display & you won’t receive an error, so be careful.

Android

Add a new class called AdMobRenderer with the code below. Make sure to keep the ExportRenderer attribute above the namespace, otherwise the magic won’t happen.

using WordBankEasy.Droid.Renderers;
using WordBankEasy.Views.AdMob;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]

namespace WordBankEasy.Droid.Renderers {
    public class AdMobRenderer : ViewRenderer<AdMobView, Android.Gms.Ads.AdView> {
        protected override void OnElementChanged(ElementChangedEventArgs<AdMobView> e) {
            base.OnElementChanged(e);

            if (Control == null) {
                var ad = new Android.Gms.Ads.AdView(Forms.Context);
                ad.AdSize = Android.Gms.Ads.AdSize.Banner;
                ad.AdUnitId = "ca-app-pub-4381168884554284/2250461656";

                var requestbuilder = new Android.Gms.Ads.AdRequest.Builder();
                ad.LoadAd(requestbuilder.Build());

                SetNativeControl(ad);
            }
        }
    }
}

Next, you need to modify your AndroidManifest.xml file to add the AdActivity & required permissions for displaying ads: ACCESS_NETWORK_STATE, INTERNET; just like in the example below (see also http://puresourcecode.com/dotnet/post/Android-required-permissions).

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-sdk android:minSdkVersion="15" />
    <application>
    <activity android:name="com.google.android.gms.ads.AdActivity" 
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" />
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

That’s it. Your Android build should now display ads inside the AdMobView content view.

iOS

This, I haven’t got the chance to test yet as I don’t have a Mac around but people say it works, so I’ve added it for reference. Same as before, just add a new class called AdMobRenderer and copy-paste the code below but before you have to add a component.

In your iOS project click on “Components” (as in the picture)

Components

and click on “Get More Components…”. Then search admob and install it.

Google-Admob-Xamarin

using Xamarin.Forms;
using CoreGraphics;
using Xamarin.Forms.Platform.iOS;
using UIKit;
using WordBankEasy.Views.AdMob;
using WordBankEasy.iOS.Renderers;
using Google.MobileAds;

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]
namespace WordBankEasy.iOS.Renderers {
    public class AdMobRenderer : ViewRenderer {
        const string AdmobID = "ca-app-pub-4381168884554284/5843056458";

        BannerView adView;
        bool viewOnScreen;

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e) {
            base.OnElementChanged(e);

            if (e.NewElement == null)
                return;

            if (e.OldElement == null) {
                adView = new BannerView(size: AdSizeCons.Banner, origin: new CGPoint(-10, 0)) {
                    AdUnitID = AdmobID,
                    RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
                };

                adView.AdReceived += (sender, args) => {
                    if (!viewOnScreen) this.AddSubview(adView);
                    viewOnScreen = true;
                };

                adView.LoadRequest(Request.GetDefaultRequest());
                base.SetNativeControl(adView);
            }
        }
    }
}

Here you can receive an strange error like:

Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[AppDelegate window]: unrecognized selector sent to instance 0x7ffee9cdd4d0

Native stack trace:

0 CoreFoundation 0x000000010a12ed85 __exceptionPreprocess + 165

1 libobjc.A.dylib 0x000000010a5e3deb objc_exception_throw + 48

2 CoreFoundation 0x000000010a137d3d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205

3 CoreFoundation 0x000000010a07db17 forwarding + 487

4 CoreFoundation 0x000000010a07d8a8 _CF_forwarding_prep_0 + 120

5 WordBankEasyiOS 0x0000000100bc65e4 GADiTunesMetadataForFileAtPath + 4181

6 WordBankEasyiOS 0x0000000100c2d484 hasRequiredParams + 10260

7 WordBankEasyiOS 0x0000000100bc5f06 GADiTunesMetadataForFileAtPath + 2423

8 WordBankEasyiOS 0x0000000100bc1c35 GADCategories_NSURL_GADNSURLUtilities + 4438

9 WordBankEasyiOS 0x0000000100c00fde GADDispatchAsyncSafeMainQueue + 45

10 libobjc.A.dylib 0x000000010a5e4bff _class_initialize + 679

11 libobjc.A.dylib 0x000000010a5eacc5 lookUpImpOrForward + 176

12 libobjc.A.dylib 0x000000010a5f98bb objc_msgSend + 187

13 WordBankEasyiOS 0x0000000100bbe0ff GADCategories_DFPBannerView_CustomRenderedAd + 18074

14 WordBankEasyiOS 0x0000000100bbe382 GADCategories_DFPBannerView_CustomRenderedAd + 18717

15 WordBankEasyiOS 0x0000000100bbe527 GADCategories_DFPBannerView_CustomRenderedAd + 19138

16 ??? 0x000000011d368a0e 0x0 + 4785080846

17 ??? 0x000000011d36843b 0x0 + 4785079355

18 ??? 0x000000011d364d88 0x0 + 4785065352

19 ??? 0x000000011c51bbd6 0x0 + 4770085846

20 ??? 0x000000011c51b138 0x0 + 4770083128

21 ??? 0x000000011c51b138 0x0 + 4770083128

22 ??? 0x000000011c51b138 0x0 + 4770083128

Don't worry! I received the same error and I spend a lot of time to understand and fix it. There is a workaround that seems working fine.

In your iOS project, open AppDelegate.cs and add this code:

/// <summary>
/// Gets the window.
/// </summary>
/// <returns>UIWindow.</returns>
[Export("window")]
public UIWindow GetWindow() {
   return UIApplication.SharedApplication.Windows[0];
}

A complete example of this class is:

using System;
using System.Collections.Generic;
using System.Linq;

using Foundation;
using ImageCircle.Forms.Plugin.iOS;
using UIKit;

namespace WordBankEasy.iOS {
    // The UIApplicationDelegate for the application. This class is responsible for launching the 
    // User Interface of the application, as well as listening (and optionally responding) to 
    // application events from iOS.
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate {
        //
        // This method is invoked when the application has loaded and is ready to run. In this 
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
            global::Xamarin.Forms.Forms.Init();

            ImageCircleRenderer.Init();

            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }

        /// <summary>
        /// Gets the window.
        /// </summary>
        /// <returns>UIWindow.</returns>
        [Export("window")]
        public UIWindow GetWindow() {
            return UIApplication.SharedApplication.Windows[0];
        }
    }
}

After that you can start you app and see you advertising without problem. For now :)

Happy coding!

How to update the data in listview in Xamarin.Forms?

First you add a new class as a ViewModel like:

public class RoomViewModel : BaseViewModel
{
   [here following code]
}

If you don't have BaseViewModel try to download from nuget Refractored.MvvmHelpers. Then in your class define an observable collection like

  public ObservableCollection<RoomRecommandation> _roomSuggestionList = 
               new ObservableCollection<RoomRecommandation>();
  
  public ObservableCollection<RoomRecommandation> Recommendations
  {
     get { return _roomSuggestionList; }
  }

In your ContentPage add a listview like:

<ListView ItemsSource="{Binding Recommendations}">
 <ListView.ItemTemplate>
   <DataTemplate>
     <ViewCell>
       <Grid Padding="10" RowSpacing="10" ColumnSpacing="10">
         <Grid.RowDefinitions>
           <RowDefinition Height="" />
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
           <ColumnDefinition Width="Auto" />
           <ColumnDefinition Width="" />
           <ColumnDefinition Width="Auto" />
         </Grid.ColumnDefinitions>
         <controls:CircleImage Grid.Column="0" BorderColor="#DDD3CB" 
                               BorderThickness="3" WidthRequest="66"
                               HorizontalOptions="CenterAndExpand" 
                               VerticalOptions="CenterAndExpand" 
                               Aspect="AspectFill" 
                               Source="{Binding Image}" />
         <Label Grid.Column="1" Text="{Binding Description}" 
                               VerticalOptions="Start" />
         <Label Grid.Column="2" Text="{Binding Price, StringFormat='£{0}'"
                               FontSize="Small" VerticalOptions="Start" />
        </Grid>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
 </ListView>

Then in your ContentPage code:

  RoomViewModel vm = null;
  public RoomPage ()
  {
      InitializeComponent ();
      LoadData();
  }

  public void LoadData()
  {
      if (vm == null)
      {
          vm = new RoomViewModel();
          BindingContext = vm;
      }
  }

Happy coding!

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  September 2017  >>
MonTueWedThuFriSatSun
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar

Month List