Disclaimer: this is an automatic aggregator which pulls feeds and comments from many blogs of contributors that have contributed to the Mono project. The contents of these blog entries do not necessarily reflect Xamarin's position.

February 22

Building Your First macOS App

When developers think of building Xamarin apps for Apple devices, they often think of iPhone and iPad, but you can also build apps for macOS. While not exactly the same as its iOS counterpart, there are many transferable skills for iOS developers looking to build apps for macOS. With Xamarin.Mac, developers can create great macOS apps with the simplicity of C#.

In this blog post, you’ll learn how to create your first macOS app in C#: a Pomodoro timer to keep us productive.

Getting Started

Building apps for macOS starts just like any other application, with File > New. Note that you’ll need to have Xamarin.Mac installed on your macOS device; building macOS apps from Visual Studio is unsupported.

File > New Solution > Mac > App > Cocoa App

Next we need to enter the app name; we’ll call this “Pomodoro.”

The Dock Item and Extension options are customizable, but for now we’ll leave them unchecked and with the blank / default values. We’ll visit these in a later blog post.

We now have our basic macOS app! You can test it by running the app from the top-left of Xamarin Studio. Unlike Xamarin.iOS, there is no need to choose a target to run the app on, since the app will run right on your Mac. You should see something like this:

Building a User Interface

Now that we have a basic macOS app, it’s time to build out our user interface; a blank app isn’t very useful!

Xamarin.Mac uses Xcode’s Interface Builder to develop UIs. Just like iOS, macOS interfaces are built using storyboards. Storyboard support on macOS was introduced in 10.10 (Yosemite). For the sake of simplicity, we’ll concentrate on macOS 10.10 and higher. If your application needs to support 10.9 or lower, you’ll need to use .xib files, which you can read more about in our working with .xib files guide.

In the solution explorer, double-click Main.storyboard. Xcode will open automatically with a “stub” project and your storyboard will open in Interface Builder.

The first thing we see is our blank UI. Notice that there’s a menu bar within the storyboard; you can use this to customize the menu bar for your app. For now, let’s leave the menu as it is.

Adding objects to our interface is somewhat similar to using the iOS designer in Xamarin Studio. On the bottom-right of the Interface Builder window, you’ll see the toolbox. You can view the available objects by selecting the icon “Show the Object library,” as shown here:

Screen Shot 2017-02-21 at 19.14.15

We can simply drag and drop the views on the view controller. To start with, let’s make an interface like the one below, which consists of a label and a button.

First, find the Label object and then drag and drop the object into our View Controller.

We can do the same for the Push Button.



To edit the label and title for the button, you can either double-click to edit the text, or, in the Attributes Inspector in the top right, find the “Title” and edit it there.

Now that we have our user interface created, it’s time to configure actions and outlets to work with the user interface in code. To do this, we need switch to the Assistant Editor, so at the top right of the main Xcode window, click the icon that looks like two overlapping circles. This should automatically bring up a file called “ViewController.h”. If it doesn’t, then, at the top of the new editor pane, click on “Automatic” and choose Manual > Pomodoro > Pomodoro > ViewController.h. Xcode should now look like this:

Setting up actions and outlets in the header file (the .h file) will allow us to reference them from our Xamarin project. To run code when the button is clicked, we need to set up an action and to reference the label from our Xamarin project, we need to set up an outlet.

Hold down the Control key, then click and drag from the button to the line beneath the final closing brace in the right editor. In the pop-up window, change the Connection to Outlet and the name to TimerLabel and hit connect:

This will automatically populate the header file with the correct definition for the outlet:

@property (nonatomic, retain) IBOutlet NSTextField *TimerLabel;

Repeat the same steps for the button, this time naming it StartStopButton.

Now we need to add the action for the button. Hold down the Control key, then click and drag as before. This time, in the pop-up window, change the Connection to Action and the name to StartStopButtonClicked and hit connect:

Once complete, you should have the following definitions:

@property (nonatomic, retain) IBOutlet NSButton *StartStopButton;
@property (nonatomic, retain) IBOutlet NSTextField *TimerLabel;
- (IBAction)StartStopButtonClicked:(id)sender;

For now, that’s all we need to do with Xcode, so you can switch back to Xamarin Studio and the changes will be synced automatically.

Adding Behavior to the UI

Back in Xamarin Studio, open the ViewController.cs file. We can now add the code for the button we set up in Xcode.

Add the following properties:

Timer MainTimer;
int TimeLeft = 1500; // 1500 seconds in 25 minutes

Then, in ViewDidLoad add the following code:

// Fire the timer once a second
MainTimer = new Timer(1000);
MainTimer.Elapsed += (sender, e) => {
    TimeLeft--;
    // Format the remaining time nicely for the label
    TimeSpan time = TimeSpan.FromSeconds(TimeLeft);
    string timeString = time.ToString(@"mm\:ss");
    InvokeOnMainThread(() => {
        //We want to interact with the UI from a different thread,
        // so we must invoke this change on the main thread
        TimerLabel.StringValue = timeString;
    });
    // If 25 minutes have passed
    if (TimeLeft == 0)
    {
        // Stop the timer and reset
        MainTimer.Stop();
        TimeLeft = 1500;
        InvokeOnMainThread(() => {
            // Reset the UI
            TimerLabel.StringValue = "25:00";
            StartStopButton.Title = "Start";
            NSAlert alert = new NSAlert();
            // Set the style and message text
            alert.AlertStyle = NSAlertStyle.Informational;
            alert.MessageText = "25 Minutes elapsed! Take a 5 minute break.";
            // Display the NSAlert from the current view
            alert.BeginSheet(View.Window);
        });
    }
};

Finally, we need the code that will trigger when the button is clicked (we set up the action for this earlier):

partial void StartStopButtonClicked(NSObject sender)
{
    // If the timer is running, we want to stop it,
    // otherwise we want to start it
    if (MainTimer.Enabled)
    {
        MainTimer.Stop();
        StartStopButton.Title = "Start";
    }
    else
    {
        MainTimer.Start();
        StartStopButton.Title = "Stop";
    }
}

Now we have a basic Pomodoro timer! When the app is run, you can click the button to start the countdown timer:



Once 25 minutes has elapsed, an alert will be shown:



Summary

Building apps with Xamarin.Mac is a great way to build powerful apps for macOS that harness the power of C#. In this blog post, we created a basic Pomodoro timer application for macOS. If you want to learn more about Xamarin.Mac, check out the Xamarin.Mac documentation and get involved in discussions on the forum! The completed code for this blog post can be found on my GitHub.

The post Building Your First macOS App appeared first on Xamarin Blog.

February 17

Mobile Center Webinar Recordings | Mobile Center for Xamarin Developers and Continuous Delivery

If you would like to sign up for the remaining webinars in the Mobile Center series, you may do so here.

Mobile Center for Xamarin Developers

 
James Montemagno shows how Xamarin developers can fully automate their Android and iOS release pipelines, including builds, tests, and beta distribution. He also discusses how to integrate the Mobile Center SDK into your apps to track how they—and your users—behave in the wild.

During the webinar recording, you’ll see how to:

  • Build your apps automatically with every pull request
  • Test apps on thousands of real-world devices and 400+ configurations
  • Seamlessly distribute passing builds to beta testers
  • Monitor production apps for crashes and bugs to prioritize fixes
  • Collect mobile analytics and understand your users
  • Connect to a cloud backend, adding critical cloud services, like offline data sync, tabular storage, and user authentication, and scaling on-demand

 

 

Continuous Delivery | Building a Development Pipeline in Mobile Center

 
Simina Pasat and Joshua Weber show you how Mobile Center simplifies your entire mobile development pipeline, from build to distribution, so you can focus on building better apps for your customers.

Mobile Center builds your app after every code check-in, streamlines your team’s workflow, and automatically tests and distributes passing builds to your distribution groups.

In this webinar recording, you’ll learn how to:

  • Automatically build your app after each check-in
  • Distribute builds to beta testers or collaborators for real testing and fast feedback
  • Increase visibility across your team members, including easily viewing commits and integrating with repos
  • Iterate and continuously improve your apps, rapidly developing, testing, and shipping new features

 


If you would like to sign up for the remaining webinars in the Mobile Center series, you may do so here.

The post Mobile Center Webinar Recordings | Mobile Center for Xamarin Developers and Continuous Delivery appeared first on Xamarin Blog.

February 16

Join Us for Round 2 of Xamarin University Presents: Getting Started with Xamarin

Xamarin University Shield LogoWe just finished our inaugural “Xamarin University Presents” webinar series, and we can’t wait to do it again! Thousands of developers joined us for five demo-packed sessions, getting best practices and step-by-step guidance from Xamarin University’s team of mobile experts.

Starting Thursday, March 2, we’ll begin the series over again from the beginning, and we invite you to join us to learn how to build fully native Android, iOS, and Windows apps with Xamarin for Visual Studio. If you missed any sessions last month, want to revisit topics, or request help from the Xamarin University team, don’t miss the next air dates where you’ll be able to ask your questions live during the webinar.

All sessions are free and open to anyone, so make sure to register today!

Register

  • Thursday, March 2, 9am PT | Intro to Xamarin for Visual Studio: Native iOS, Android, and Windows apps in C#: Xamarin University Guest Lecturer James Montemagno will show you how to create, debug, test and deploy apps for iOS, Android and Windows while maximizing the shared code between all platforms.
  • Thursday, March 9, 9 am PT | Building your First Xamarin.Forms App: Adrian Stevens, Xamarin University curriculum manager, will walk you through building your first Xamarin.Forms application, including using a common set of controls to define a fully native UI for Android, iOS, and Windows.
  • Thursday, March 16, 9am PT | Building Your First Android App: Xamarin University professor Judy McNeil will show you how to design native Android UIs with the Android Designer, add behavior, and deploy apps to Android emulators and devices – straight from Visual Studio.
  • Thursday, March 23, 9 am PT | Building Your First iOS App: Chris van Wyk, another expert Xamarin University professor, will dive into a typical Xamarin.iOS project, explore the MVC architecture, create screens with the Visual Studio iOS Designer, and test Xamarin.iOS apps on a simulator and real devices.
  • Thursday, March 30, 9 am PT | Connected Mobile Apps with Microsoft Azure: James Montemagno will teach you how to integrate various Azure App services into your Xamarin apps, including: cloud data storage, offline sync, push notifications, user authentication, and data and intelligence.

Sign up for one or all of the webinars, bring your questions, and get the expert guidance and best practices you need to take your C# skills mobile.

 

The post Join Us for Round 2 of Xamarin University Presents: Getting Started with Xamarin appeared first on Xamarin Blog.

February 15

Consumable In-App Purchases

If you are building a game or application with content that needs to be purchased multiple times, you’ll need to integrate consumable in-app purchases (IAPs) into your application. In my previous IAP blog post, I covered the basics of setting up your app for IAP transactions, adding the IAP items to Google Play and iTunes Connect, and introduced you to the In-App Billing Plugin for Xamarin that greatly simplifies the process of adding IAP to your application’s code. Today, we’ll take a look at consumables and how they offer a slight tweak to the development process.

The idea of a consumable is that they are items that are used up over the course of the application’s life, and therefore can be purchased multiple times. Examples of these are in-game currency, such as our monkey credits shown above, extra health, and one-time services, such as transcriptions.

Setting Up Consumables

Google doesn’t make a true distinction between a non-consumable and a consumable, only the API differs between them. For iOS, Apple requires developers to specify this information up front when creating the IAP in iTunes connect.

Consumables

The idea here is that when we make the request to the iTunes server, this selection will trigger the correct flow during the purchase.

Purchasing and Consuming

For both iOS and Android, we’ll want to make sure that we have the In-App Billing Plugin installed in all projects in our solution via NuGet. iOS and Android each handle consumables a little bit differently, so we’ll start with iOS, which has a very similar flow to the non-consumables that we discussed earlier.

This diagram shows the steps to making the purchase; we must:

  1. Request our payment in the Queue.
  2. Send the request to the server.
  3. iTunes processes and returns.
  4. Process receipt in app.
  5. Display purchase information in app.

If this diagram looks familiar, it’s because it’s the same exact flow as non-consumables. Thus, all we have to do is call the PurchaseAsync method and our consumable is purchased and ready to go! Since we marked the IAP as a consumable, we can continue to buy the product over and over.

try
{
    var productId = "mysku";
    var connected = await CrossInAppBilling.Current.ConnectAsync();
    if (!connected)
    {
        //Couldn't connect to billing, could be offline, alert user
        return;
    }
    //try to purchase item
    var purchase = await CrossInAppBilling.Current.PurchaseAsync(productId, ItemType.InAppPurchase, "apppayload");
    if(purchase == null)
    {
        //Not purchased, alert the user
    }
    else
    {
        //Purchased, save this information
        var id = purchase.Id;
        var token = purchase.PurchaseToken;
        var state = purchase.State;
    }
}
catch (Exception ex)
{
    //Something bad has occurred, alert user
}
finally
{
    //Disconnect, it is okay if we never connected
    await CrossInAppBilling.Current.DisconnectAsync();
}

For Android, there’s one additional step in the process. We must first call the above code to actually purchase the consumable item, however, Google’s implementation of consumables integrates the scenario where the user may buy a consumable and actually use it in the future, such as buying coins, but cashing them in for goods later in the game. This means that we can’t purchase the consumable item again until we actually finalize the purchase and “Consume” it. For this, the plugin has an additional method, ConsumePurchaseAsync, that takes in specific purchase information. If this method is called on iOS, it will simply return null. We can use the Device Info Plugin to only call ConsumePurchaseAsync on Android after we have the purchase:

// Called after we have a successful purchase or later on (must call ConnectAsync() ahead of time):
if(CrossDeviceInfo.Current.Platform == Platform.Android)
{
     var consumedItem = await CrossInAppBilling.Current.ConsumePurchaseAsync(purchase.ProductId, purchase.PurchaseToken);
    if(consumedItem != null)
    {
        // Item has been consumed
    }
}

Learn More

There’s a lot more to IAPs, including subscriptions and product information that are exposed in the In-App Billing Plugins APIs. You can find out more about this in the README file on the GitHub project. The same documentation also walks you through a full set up, testing, and trouble shooting guide to integrating In-App Purchases. In addition, I highly recommend reading through full documentation on In-App Purchases for iOS and Android.

The post Consumable In-App Purchases appeared first on Xamarin Blog.

February 14

Realtime Databases with the Realm Mobile Platform

This is a special guest post from the Realm team, written by Andy Dent.

Andy Dent is a C# developer at Realm, working virtually in Copenhagen from the sunny state of Western Australia. When not sweating over code he can be found sweating at kung fu and online at andydent.name.

Today, Realm is announcing a couple of really neat things for Xamarin users, including the 1.0 release of the Realm Mobile Database, and support for Xamarin on the Realm Mobile Platform. With these tools, we wanted to show you how quickly you could make a collaborative app that syncs in realtime, while maybe having a little fun along the way, so we’ll be rewriting the RealmDraw app in Xamarin.

Xamarin introduced Skia Sharp in February 2016 so it was a natural choice when we needed a vector drawing library for our RealmDraw sample. The challenge had already been laid down by the Realm Cocoa Team showing how cool a shared drawing app can be with Realm. We wanted a Xamarin app to match that would also show how easily code can be shared across Android and iOS.

This tutorial shows how to build a simple freehand drawing app using SkiaSharp and then, with the aid of the Realm Mobile Platform (RMP), make it a shared drawing app. It assumes a reasonable familiarity with Xamarin Studio to build a Xamarin app.



Setting Up a Realm Object Server on Azure

Before we get into the app development, here’s a quick guide to setting up a Development server on Azure, mostly following the standard Microsoft guides. We will use the Ubuntu version of the server.

  • Follow the “Create a Linux VM on Azure using the Portal” documentation to create an instance of Ubuntu Server 16.04 LTS.
  • Follow the “Opening ports to a VM in Azure using the Azure portal” guide and allow through port 9080. Note that you do not need to create a new Network Security Group as one has already been created with your server – you will see it contains a definition for port 22 which is why you can use SSH to connect.
  • Use SSH to connect to your server so you have a terminal session.
  • Now we use the steps from Install the Realm Object Server below to install and start the Realm Object Server.

# Download the Realm Object Server repository from PackageCloud
curl -s https://packagecloud.io/install/repositories/realm/realm/script.deb.sh | sudo bash
# Update repositories (may not be necessary on a new server)
sudo apt-get update
# Install the Realm Object Server
sudo apt-get install realm-object-server-developer
# Enable and start the service
sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server

Setup with SkiaSharp

Our tutorial starts with some hardcoded drawing to prove your SkiaSharp installation works, then moves on to how to draw in response to touches, and concludes by integrating Realm. For more background on SkiaSharp, see the Xamarin blog post on SkiaSharp.

There is not yet a simple way to capture complex touch events, within Xamarin Forms, so this tutorial code uses native UI projects. That keeps things a little simpler so you can focus on the drawing code and particularly sharing drawing with RMP.

  • Start with a new Single View project for iOS and Android. We will use a Shared project for the common code.
  • Add the NuGet SkiaSharp.Views. That will also add SkiaSharp.
  • Now clean up each project to remove the template UI and add a SkiaCanvas
  • .

iOS Configuration

  • Open the Main.Storyboard with the visual editor.
  • Remove the UIButton.
  • Select the main view. In the Properties Widget panel change the Name to Canvas and the Class to SKCanvasView.
  • How to Add SkiaSharp to the Storyboard

  • Open ViewController.cs, and remove the Button logic in ViewDidLoad.
  • Add using statements for SkiaSharp and SkiaSharp.Views.iOS.
  • Add an OnPainting method and set it up in ViewDidLoad so your entire file looks like this:

    using System;
    using SkiaSharp;
    using SkiaSharp.Views.iOS;
    using UIKit;
    namespace RealmDrawLite.iOS
    {
        public partial class ViewController : UIViewController
        {
            public ViewController(IntPtr handle) : base(handle)
            {
            }
            public override void ViewDidLoad()
            {
                base.ViewDidLoad();
                Canvas.PaintSurface += OnPainting;
            }
            protected void OnPainting(object sender, SKPaintSurfaceEventArgs e)
            {
                var canvas = e.Surface.Canvas;
                canvas.Clear(SKColors.White);
                var circleFill = new SKPaint {Color = SKColors.Blue};
                canvas.DrawCircle(100, 100, 40, circleFill);
            }
        }
    }

You can now build and run the iOS program and you should see a blue circle drawn on an otherwise white screen.

Android Configuration

To edit the AXML file in Android, for these simple changes, editing the layout files in text format will be easier – you can right-click on them in Xamarin Studio and choose Open With – Source Code Editor.

  • Open the Main.axml file under the Resource/layout directory.
  • Replace the line Button android:id="@+id/myButton” … with
    <SkiaSharp.Views.Android.SKCanvasView android:id="@+id/canvas" android:layout_width="match_parent" android:layout_height="match_parent" />
  • In MainActivity.cs, add using SkiaSharp; and using SkiaSharp.Views.Android;.
  • Remove the standard Button setup in OnCreate.
  • Add an `OnStart` method to create the SKCanvasView so your MainActivity.cs looks like:

    using Android.App;
    using Android.OS;
    using SkiaSharp;
    using SkiaSharp.Views.Android;
    namespace RealmDrawLite.Droid
    {
        [Activity(Label = "RealmDrawLite", MainLauncher = true, Icon = "@mipmap/icon")]
        public class MainActivity : Activity
        {
            protected override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
                SetContentView(Resource.Layout.Main);
            }
            protected override void OnStart()
            {
                base.OnStart();
                var canvas = FindViewById(Resource.Id.canvas);
                canvas.PaintSurface += OnPainting;
            }
            protected void OnPainting(object sender, SKPaintSurfaceEventArgs e)
            {
                var canvas = e.Surface.Canvas;
                canvas.Clear(SKColors.White);
                var circleFill = new SKPaint {Color = SKColors.Blue};
                canvas.DrawCircle(100, 100, 40, circleFill);
            }
        }
    }

You can now build and run that and similarly see SkiaSharp working to draw a blue circle on white background.

Adding Touches to Draw

The app we’re building isn’t a shape vector drawing app but is more like a whiteboard – it tracks your touches and draws straight lines between them. The faster you draw, the more jagged your drawing will become. An Apple Pencil on an iPad Pro makes a fine test environment.

iOS Draw with Touches

All the changes are in ViewController.cs, adding fields to track the path we are building and compensate for device scaling:

private SKPath _path;
private float _devScale;  // usually 2.0 except iPhone 6+, non-retina iPad Mini
public ViewController(IntPtr handle) : base(handle)
{
    _devScale = (float)UIScreen.MainScreen.Scale;
}

The painting method now draws a path we have built:

protected void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
    if (_path != null)
    {
        var canvas = e.Surface.Canvas;
        var paint = new SKPaint {
            Color = SKColors.Blue,
            Style = SKPaintStyle.Stroke,
            StrokeWidth = 10
        };
        canvas.DrawPath(_path, paint);
    }
}

To build the path, we need to respond to touch events by scaling points and adding lines:

protected SKPoint CG2SKPoint(CoreGraphics.CGPoint p)
{
    return new SKPoint { X = _devScale * (float)p.X, Y = _devScale * (float)p.Y };
}
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
    base.TouchesBegan(touches, evt);
    _path = null;
    var touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        _path = new SKPath();
        _path.MoveTo(CG2SKPoint(touch.LocationInView(View)));
    }
}
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
    base.TouchesMoved(touches, evt);
    var touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        _path.LineTo(CG2SKPoint(touch.LocationInView(View)));
        View.SetNeedsDisplay();
    }
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
    base.TouchesEnded(touches, evt);
    var touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        _path.LineTo(CG2SKPoint(touch.LocationInView(View)));
        View.SetNeedsDisplay();
    }
}

Android Draw with Touches

All the changes are in MainActivity.cs, adding fields to remember the main view and track the path we are building:

private SKPath _path;
private SKCanvasView _canvasView;
protected override void OnStart()
{
    base.OnStart();
    _canvasView = FindViewById(Resource.Id.canvas);
    _canvasView.PaintSurface += OnPainting;
    _canvasView.Touch += OnTouch;
}

The Painting method now only clears at the start, and otherwise draws the path we have built:

protected void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
    var canvas = e.Surface.Canvas;
    if (_path == null)
        canvas.Clear(SKColors.White);
    else
    {
        var paint = new SKPaint { Color = SKColors.Blue, Style = SKPaintStyle.Stroke, StrokeWidth = 10 };
        canvas.DrawPath(_path, paint);
    }
}

To build the path up, we track Touch events:

private void OnTouch(object sender, View.TouchEventArgs touchEventArgs)
{
    float fx = touchEventArgs.Event.GetX();
    float fy = touchEventArgs.Event.GetY();
    switch (touchEventArgs.Event.Action & MotionEventActions.Mask)
    {
        case MotionEventActions.Down:
            _path = new SKPath();
            _path.MoveTo(fx, fy);
            break;
        case MotionEventActions.Move:
            _path.LineTo(fx, fy);
            _canvasView.Invalidate();
            break;
     }
}

Remembering Points With Realm

Instead of drawing lines immediately as you touch the screen, we are now going to save them in a local Realm. This means you can quit the application and come back to it later with your drawing being loaded from disk.

Rather than just recording the points in order, we will group them into _Paths_ which are a continuous stroke. This is useful for changing colors and will be essential when we start sharing drawings.

Adding Realm

To begin, you need to add the Realm NuGet package to your iOS and Android projects. This will also add Realm.Database, Fody and a number of support System packages. It looks like a lot but many of them are only used at build time and don’t bulk out your app.

We will use two simple classes to track the drawing.

public class DrawPoint : RealmObject
    {
        public double X { get; set; }
        public double Y { get; set; }
    }
    public class DrawPath : RealmObject
    {
        public string Color { get; set; }
        public IList Points { get; }
    }

More of the logic now becomes shared – we’re getting more code sharing by stripping logic from the individual UI projects.

Here’s the LiteDrawer.cs entire file. You can see how drawing logic from the touch methods above has now been moved into DrawPaths and DrawAPath which work solely from the saved data in the Realm. These methods cleanly separate the Drawing action from the Input methods that record points.

We do still have a current _drawPath field which is used to remember the path to which points are being added. This could be retrieved from the Realm every time but keeping track of it in memory helps provide responsive drawing.

using System;
using SkiaSharp;
using Realms;
namespace RealmDrawLite
{
    public class LiteDrawer
    {
        private Realm _realm;
        private DrawPath _drawPath;
        public LiteDrawer()
        {
            // Realm.DeleteRealm(new RealmConfiguration("FabScribbles"));      //  Uncomment this line to start fresh
            _realm = Realm.GetInstance("FabScribbles"); // local Realm
        }
        public void DrawPaths(SKCanvas canvas)
        {
            using (var paint = new SKPaint { Style = SKPaintStyle.Stroke, StrokeWidth = 10 })
            {
                canvas.Clear(SKColors.White);
                foreach (var drawPath in _realm.All())
                    DrawAPath(canvas, paint, drawPath);
            }
        }
        private void DrawAPath(SKCanvas canvas, SKPaint paint, DrawPath drawPath)
        {
            using (var path = new SKPath())
            {
                SKColor pathColor;
                SKColor.TryParse(drawPath.Color, out pathColor);
                paint.Color = pathColor;  // change the current drawing color to this path
                var isFirst = true;
                foreach (var point in drawPath.Points)
                {
                    if (isFirst)
                    {
                        isFirst = false;
                        path.MoveTo(point.X, point.Y);
                    }
                    else
                        path.LineTo(point.X, point.Y);
                }
                canvas.DrawPath(path, paint);
            }
        }
        public void StartDrawing(SKPoint pt)
        {
            _realm?.Write(() =>
            {
                _drawPath = new DrawPath
                {
                    Color = SKColors.Teal.ToString(),
                    Points = { new DrawPoint { X = pt.X, Y = pt.Y } }
                };
                _realm.Add(_drawPath);
            });
        }
        public void AddPoint(SKPoint pt)
        {
            _realm?.Write(() =>
            {
                _drawPath.Points.Add(new DrawPoint { X = pt.X, Y = pt.Y });
            });
        }
        public void StopDrawing(SKPoint pt)
        {
            _realm?.Write(() =>
            {
                _drawPath.Points.Add(new DrawPoint { X = pt.X, Y = pt.Y });
            });
            _drawPath = null;
        }
    }
}

Did you notice a couple of little Realm idioms in there? You can read more about them in the main Realm docs. Most of the Realm SDK uses standard C# collection interfaces and LINQ so you don’t notice when you are using it. The main things to remember are:

  • All updates, adding or modifying data are wrapped in a _realm.Write().
  • Use `All` to iterate through all objects of a given class, eg: foreach (var drawPath in _realm.All()).
  • Iterating through the path’s related points is normal C# foreach (var point in drawPath.Points).

When you build and run this stage of the sample, you will see your drawings continuously accumulate. Quit the app and next time you launch, all your saved scribbles from before immediately draw. Realm is so fast we’re also cheating a bit and just doing these database operations on the UI thread.

iOS Draw With Realm

The ViewController.cs now becomes much more of a Controller just forwarding events to our LiteDrawer.

Start by replacing the local _path field with a LiteDrawer instead.

private LiteDrawer _drawer;
        public override void ViewDidLoad()
        {
            ...
            _drawer = new LiteDrawer();

The OnPainting method is just a forwarder:

protected void OnPainting(object sender, SKPaintSurfaceEventArgs e)
        {
            _drawer.DrawPaths(e.Surface.Canvas);
        }

The Touches methods now call the Drawer to add data:

protected SKPoint CG2SKPoint(CoreGraphics.CGPoint p)
        {
            return new SKPoint { X = _devScale * (float)p.X, Y = _devScale * (float)p.Y };
        }
        public override void TouchesBegan(NSSet touches, UIEvent evt)
        {
            base.TouchesBegan(touches, evt);
            var touch = touches.AnyObject as UITouch;
            if (touch != null)
                _drawer.StartDrawing(CG2SKPoint(touch.LocationInView(View)));
        }
        public override void TouchesMoved(NSSet touches, UIEvent evt)
        {
            base.TouchesMoved(touches, evt);
            var touch = touches.AnyObject as UITouch;
            if (touch != null)
            {
                _drawer.AddPoint(CG2SKPoint(touch.LocationInView(View)));
                View.SetNeedsDisplay();
            }
        }
        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            base.TouchesEnded(touches, evt);
            var touch = touches.AnyObject as UITouch;
            if (touch != null)
            {
                _drawer.StopDrawing(CG2SKPoint(touch.LocationInView(View)));
                View.SetNeedsDisplay();
            }
        }

Android Draw With Realm

Similar trimming of the Android MainActivity.cs has it forwarding events to the Drawer:

protected override void OnStart()
        {
            ...
            _drawer = new LiteDrawer();
        }
        protected void OnPainting(object sender, SKPaintSurfaceEventArgs e)
        {
            _drawer.DrawPaths(e.Surface.Canvas);
        }
        private void OnTouch(object sender, View.TouchEventArgs touchEventArgs)
        {
            var touchPoint = new SKPoint {
                X = touchEventArgs.Event.GetX(),
                Y = touchEventArgs.Event.GetY()};
            switch (touchEventArgs.Event.Action & MotionEventActions.Mask)
            {
                case MotionEventActions.Down:
                    _drawer.StartDrawing(touchPoint);
                    break;
                case MotionEventActions.Move:
                    _drawer.AddPoint(touchPoint);
                    _canvasView.Invalidate();
                break;
                case MotionEventActions.Up:
                    _drawer.StopDrawing(touchPoint);
                    _canvasView.Invalidate();
                break;
            }
        }

Sharing Your Drawings With Realm Mobile Platform

The steps from using a local Realm to synchronised are very small.

  • You need to know where the server is – for now we use a fixed address.
  • Your client app needs to be authenticated to the server, we will cheat and specify a hardcoded address with username/password.
  • Drawing must be triggered by the Realm being updated, not by local touches.
  • Connecting to the Server

    The field _realm is no longer set in the LiteDrawer constructor but has to be created after a series of authentication steps. You can see below the use of Credentials.UsernamePassword – see our Authentication Documents for other methods.

    Instead of a local Realm named _SharedScribbles_ we refer to it on the server as an address passed into new SyncConfiguration(user, new Uri($"realm://{serverIP}/~/SharedScribbles"));.

    private IDisposable _notificationToken;
            private IQueryable _allPaths;
            public async void LoginToServerAsync(string username, string password, string serverIP)
            {
                User user = null;
                try
                {
                    user = User.Current;  // if still logged in from last session
                }
                catch (Exception) { }
                try
                {
                    if (user == null)
                    {
                        var credentials = Credentials.UsernamePassword(username, password, createUser: false);
                        user = await User.LoginAsync(credentials, new Uri($"http://{serverIP}"));
                    }
                    var config = new SyncConfiguration(user, new Uri($"realm://{serverIP}/~/SharedScribbles"));
                    _realm = Realm.GetInstance(config);
                }
                catch (Exception)
                {
                    return;
                }
                if (user != null)
                {
                    _allPaths = _realm.All() ;
                    _notificationToken = _allPaths.SubscribeForNotifications((sender, changes, error) =>
                    {
                        RefreshOnRealmUpdate();
                    });
                }
            }

    Reacting to Changes

    Just at the end of LoginToServerAsync above, you can see how we save a live query result _allPaths and subscribe to be notified when it is changed. We retain the _notificationToken as a field of LiteDrawer because otherwise, garbage collection would cause notifications to cease.

    We are only subscribing to the DrawPath objects. Both this app and others sharing the same server will be adding or updating paths, as they draw. In this unsophisticated version, we just redraw everything each time someone adds a single point, somewhere. That means our refresh method doesn’t need to care about the details of what has been changed.

    Remember in the purely local version, refreshing the screen was driven from the _outside inwards_ – a touch event in the GUI code caused a refresh. To trigger those refreshes from the shared code in `LiteDrawer`, it has a property set by the calling app:

    internal Action RefreshOnRealmUpdate { get; set; } = () => { };`

    As a fun experiment, you can directly open the SharedScribbles Realm on the server with the Realm Browser (running on MacOS). If you delete a DrawPath, it will vanish from all the devices. If you edit its color, they all redraw with that path in a different color.

    Same Code for Local as Shared Realms

    The important thing about the changes to LiteDrawer above are what we didn’t change. There was no need to change any of the code writing paths and points into the Realm because they just work the same way. Once a synchronized Realm is opened, it acts like just another Realm. From the point of view of your application code, there’s no difference between a background thread doing some updates and shared data arriving from the Realm Object Server.

    iOS Draw With RMP

    As you probably expect, the ViewController.cs changes very little. Most importantly, we set the `_drawer.RefreshOnRealmUpdate` and then pass in credentials to login.

    public override void ViewDidLoad()
            {
                ...
                _drawer = new LiteDrawer();
                _drawer.RefreshOnRealmUpdate = () =>    {  View?.SetNeedsDisplay();  };
                _drawer.LoginToServerAsync("foo@foo.com", "bar", "192.168.0.51:9080");
            }

    The only other changes are removing the two View?.SetNeedsDisplay(); from TouchesMoved and TouchesEnded. Those two calls effectively moved into the _drawer.RefreshOnRealmUpdate.

    Android Draw With RMP

    Exactly the same changes occur in Android’s MainActivity.cs – move the refresh calls from OnTouch and login.

    protected override void OnStart()
            {
                ...
                _drawer = new LiteDrawer();
                _drawer.RefreshOnRealmUpdate = () =>   {  _canvasView.Invalidate();   };
                _drawer.LoginToServerAsync("foo@foo.com", "bar", "192.168.0.51:9080");
            }

    The Final Point

    This article, and the sample code, is like an inverted triangle. Most of the work initially went into the GUI, being able to track touches and draw in response. Adding Realm to manage the data was little more work than adding a couple of classes to manage those data structure, and shifting from immediate drawing to using saved data to draw.

    The final, big step of making your drawings shared live was just a case of connecting to a server and changing how you trigger a screen refresh. Go create — we can’t wait to see what you’ll make with Realm and Xamarin.

    Source Code

    To help you get started and to check progress along the way, the source for this tutorial has been saved in a series of archives:

    1. Empty app with just SkiaSharp added to draw a basic blue circle. Archive
    2. Touches added to immediately scribble. Archive
    3. Your drawing stored in Realm so it’s now persistent. Archive
    4. Full shared drawing with Realm Mobile Platform. Archive

    Full Version Source

    The main RealmDraw sample is also available for Xamarin, along with other frameworks and includes a number of additional features:

    • Shake the device to clear
    • Enter login credentials, with error-handling
    • Optional Active Directory authentication
    • Change colors by tapping different pencils
    • Smooth drawing with various drawing optimizations, treating the immediate drawing separately from server updates
    • Normalise drawings to device scale so they draw fully on all tablets and phones
    • Properly cleanup notification tokens and other event handlers
    • Local persist settings including the last color used.

    The post Realtime Databases with the Realm Mobile Platform appeared first on Xamarin Blog.

February 13

Bring Stunning Animations to Your Apps with Lottie

This is a special guest post on Lottie by Airbnb, written by Martijn van Dijk.

Martijn works at Xablu as a Xamarin consultant. You can find him on Twitter at @mhvdijk and on Github at @Martijn00.

Animations are always a delight to have in our apps, but they can also be very difficult to create. Taking an animation that a designer has created and turning it into platform-specific code is both tedious and prone to error. Lottie is a mobile animations library created by Airbnb for iOS and Android that parses Adobe After Effects animations (exported as JSON) and renders them using native animation APIs. With Lottie, for the first time designers can create and ship beautiful animations without an engineer painstakingly recreating it by hand. Since it is backed by JSON, the animations are extremely small in size, but can be large in complexity! Animations can be played, resized, looped, sped up, slowed down, and even interactively scrubbed.

Because it’s so easy to integrate fancy animations, but also to update and maintain them, we’ve begun using Lottie for animations in all my mobile apps. Lottie has several features built into its API to make it more versatile and efficient. It supports loading JSON files over the network, has an optional caching mechanism, and animations can be driven by gestures. In this blog post, you’ll learn how to use the Lottie animation framework to create beautiful animations for iOS, Android, even Xamarin.Forms apps!

Lottie is an animation framework from AirBnb.

Adding Beautiful Animations with Lottie

Before we get to the code, first we have to create our animation. Lottie functions using JSON exported from Adobe After Effects and translates this into native animations for us. To begin, create an animation in Adobe After Effects. Next, use the bodymovin plugin for After Effects to export the animation as JSON. This will serve as the backing store for the animations that Lottie will load from code.

Now it’s time to add the animations to our mobile apps. Lottie for Xamarin is distributed via NuGet. To use Lottie in your apps, simply add the iOS, Android, or Xamarin.Forms version of the Lottie package to your project(s).

Android

Lottie supports Jellybean (API 16) and above. The simplest way to use it is with LottieAnimationView:

Alternatively, you can load the animation programmatically from a JSON located in the Assets directory:

LottieAnimationView animationView = FindViewById(Resource.Id.animation_view);
animationView.SetAnimation("hello-world.json");
animationView.Loop = true;

iOS

Create an animation from code with the LAAnimationView, add the animation to the view, and call PlayWithCompletion:

LAAnimationView animation = LAAnimationView.AnimationNamed("LottieLogo1");
this.View.AddSubview(animation);
animation.PlayWithCompletion((animationFinished) => {
  // Do Something
});

You can also load it programmatically (locally or over the network) from a NSUrl:

LAAnimationView animation = new LAAnimationView(new NSUrl(url));
this.View.AddSubview(animation);

Xamarin.Forms

Lottie has an API available for Xamarin.Forms too, with it’s own XAML markup:

Download the Sample App

To view examples of prebuilt animations, download the Lottie sample app from GitHub or get it directly from the Google Play Store.

It won’t be too long before you are creating delightful animations for your users with Lottie!

Example of Lottie animation framework in the AirBnb app.

Learn More

There’s a lot more to Lottie and binding native libraries for Xamarin. You can find out more about Lottie for Xamarin in the README file on GitHub. For more information, troubleshooting, and samples on creating bindings, look at the Android and iOS documentation. Join me in the open source effort and contribute on Github!

The post Bring Stunning Animations to Your Apps with Lottie appeared first on Xamarin Blog.

February 10

Mobile Center Webinar Recordings | Ship Mobile Apps Faster and Give Your Apps an Instant Cloud Backend

If you would like to sign up for the remaining webinars in the Mobile Center series, you may do so here.

Mobile Center | Ship Mobile Apps Faster

 
In this webinar, Thomas Dohmke and Piyush Joshi explain how Mobile Center simplifies mobile development, bringing together all the cloud and mobile lifecycle services you need to deliver better apps in less time, with a walk through the product—the next generation of Xamarin Test Cloud, HockeyApp, and Azure Mobile Engagement—showing you how you how to automatically build, test, distribute, and monitor apps and add backend cloud services to scale to millions of users.

In this recording, you’ll learn how to:

  • Automate your entire mobile development pipeline, from continuous build to continuous deployment
  • Automatically test your apps on real devices and kick off tests with each code commit
  • Distribute to beta testers for early feedback and QA
  • Integrate crashes and user behavior analytics to see real users’ production experiences
  • Easily add a cloud backend, including: social authentication and structured data storage

 

 

Mobile Center | Give Your Apps an Instant Cloud Backend

 
Adrian Hall and Joe Mellin show you how Mobile Center makes it easy to add powerful cloud services, including user authentication, offline sync, and more, to your mobile apps.

Mobile Center brings scalability, security, data, and turnkey mobile features to developers everywhere. No matter what programming language you use, you’ll leave ready to integrate with essential mobile capabilities, scale on demand, and keep your users engaged.

During the webinar, you’ll learn how to:

  • Create your first Easy Table and connect your app to cloud or on-premises data
  • Configure user authentication from social and enterprise systems
  • Build your first cloud-connected app that distributes to your beta testers on every commit

 


If you would like to sign up for the remaining webinars in the Mobile Center series, you may do so here.

The post Mobile Center Webinar Recordings | Ship Mobile Apps Faster and Give Your Apps an Instant Cloud Backend appeared first on Xamarin Blog.

February 9

Building Android Apps with Entity Framework

Data is a big part of any application development and mobile apps are no exception; the way we handle data as developers is one of the many important decisions we must make for our mobile apps. From key-value stores to SQLite, there are many options available, but one that .NET developers are often especially familiar with is the Entity Framework.

Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects and eliminates the need for more of the data-access code that developers usually need to write. Entity Framework is great, but was difficult to use in mobile development projects—until Entity Framework Core came along. Entity Framework Core is a lightweight, extensible, cross-platform version of Entity Framework data access technology.

What is Entity Framework Core?

Entity Framework Core (EF Core) introduces many new features and improvements when compared to full-scale Entity Framework, but is a completely brand new codebase that’s optimized for cross-platform applications. If you have experience with Entity Framework, you’ll find EF Core very familiar. Even though it doesn’t have all of the same features, many will show up in future releases (such as lazy loading and connection resiliency). Because EF Core is .NET Standard-compatible, we can now use it with Xamarin.Android.

Due to it’s ease-of-use, EF Core has been one of my favorite projects for quite some time. The challenge has always been, “how can I use the Entity Framework in my Xamarin apps?” In this blog post, I’ll show you how to do just that by building an Android app with a backing Entity Framework Core database.

Getting Started

Creating the .NET Standard Library

To get started, let’s create a .NET Standard library. .NET Standard is a formal specification of the .NET APIs that are intended to be available on all .NET runtimes, similar to Portable Class Libraries. This library is where we’ll place all of our shared application code, including our Entity Framework Core logic.

Create a new solution and add a Portable Class Library (PCL) to that solution.

1

Since this isn’t a .NET Standard (netstandard) library, we can convert it by right-clicking the project and navigating to the Properties:

12.28.2016-12.19

According to NuGet, the requirements of the Microsoft.EntityFrameworkCore and Microsoft.EntityFramworkCore.Sqlite packages specify that the library needs to target netstandard 1.3. We can change the target in the same place:

12.28.2016-12.21

We then need to add the Entity Framework packages to our project. Right-click the References folder, select Manage NuGet Packages…, and install the Microsoft.EntityFrameworkCore and Microsoft.EntityFramworkCore.Sqlite packages.

Great! Now we’re ready to start diving into some Entity Framework code.

Defining the DbContext

If you’ve used Entity Framework before, you’ll be very familiar with how we define a DbContext and our underlying Models that define our database schema.

Let’s start with a simple data model that we’ll call Cat.

using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
...
    public class Cat
    {
        [Key]
        public int CatId { get; set; }
        public string Name { get; set; }
        public int MeowsPerSecond { get; set; }
    }

Next, let’s ensure that our Cat class is part of our DbContext by defining a new context called CatContext.

using Microsoft.EntityFrameworkCore;
...
    public class CatContext : DbContext
    {
        public DbSet Cats { get; set; }
        private string DatabasePath { get; set; }
        public CatContext()
        {
        }
        public CatContext(string databasePath)
        {
            DatabasePath = databasePath;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite($"Filename={DatabasePath}");
        }
    }

Using Entity Framework Core with Xamarin.Android

Getting Started

Now that we have our database configured in our .NET Standard library with EF Core, let’s create an Android project to connect to this database from. Right-click the solution, click Add Project, and select Single-View App (Android).

12.28.2016-12.22

Just like before, we need to add the
Microsoft.EntityFrameworkCore and Microsoft.EntityFramworkCore.Sqlite NuGet packages to our Android project.

Implementing the Context

First, we need to make sure our Xamarin.Android project is referencing our .NET Standard library. In the Android project, right-click the References folder, select Add Reference…, and then select the library we created at the beginning of this blog post. Click OK to save this reference.

12.28.2016-13.01

Now that we have that, let’s implement our MainActivity.cs with some Entity Framework code!

using System.IO;
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using EntityFrameworkWithXamarin;
using EntityFrameworkWithXamarin.Core;
using System.Collections.Generic;
...
  [Activity(Label = "EntityFrameworkWithXamarin.Droid", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
      {
        int count = 1;
        protected async override void OnCreate(Bundle bundle)
        {
          base.OnCreate(bundle);
          // Set our view from the "main" layout resource
          SetContentView(Resource.Layout.Main);
          // Get our button from the layout resource,
          // and attach an event to it
          Button button = FindViewById

And now add the TextView1 to our Resources > Layout > Main.axml to which we’re referring in our MainActivity.

<?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      >
  <Button
      android:id="@+id/MyButton"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="@string/Hello"
      />
  <TextView
      android:id="@+id/TextView1"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      />
  </LinearLayout>

Next, let’s set our Android project as the startup project and run it in the emulator! Whoops, looks like we’ll get an error:

Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Cats'.

Generating an EF Core Migration

We’re missing a core Entity Framework feature called Migrations that creates our database schema. At the moment, there isn’t a great way to generate Entity Framework Migrations from within a Xamarin.Android project or the .NET Standard library. Let’s use a quick workaround by creating a new netcore Console Application so we can generate Migrations.

12.28.2016-13.56

To generate our Migrations, add the Microsoft.EntityFrameworkCore.Tools.DotNet, Microsoft.EntityFrameworkCore.Design, and Microsoft.EntityFrameworkCore NuGet packages to this project so we can use the command line to generate our Migrations.

Note: Microsoft.EntityFrameworkCore.Tools.DotNet is currently prerelease and as such you’ll need to enable the Include prerelease checkbox in the NuGet Package Manager if you haven’t already.

We now need to move our Cat and CatContext over to ensure there’s a DbContext it can generate Migrations for. Now we can generate a schema for our context. Let’s use the new dotnet tooling to do this. Open up a new console in our current Console App directory:

12.28.2016-14.03

Generate a Migration by running:

dotnet ef migrations add Initial

which will generate the following:

12.28.2016-14.11

Now we need to take the initial migrations generated in the Migrations folder of our project and move them over to our .NET Standard library.

Note: You can simply change the namespaces of these two generated files to the name of your netstandard namespace.

Putting it All Together

Run the Xamarin.Android project again and we’re now using Entity Framework Core successfully from our Android application to store data!

12.28.2016-14.16

We can take a closer look at the SQLite file that gets generated by using an emulator and opening up the Android Device Monitor. Looking in the data/data/files folder, we’ll see our Cats.db that we created.

12.28.2016-14.19

We can open this file in any SQLite explorer by selecting the file, clicking Pull a file from the device, and saving it locally, seen below using DB Browser for SQLite.

sqlbrowser

Wrapping Up

In this blog post, we used Entity Framework Core to generate a database we can use from within a Xamarin.Android application. For more information, check out the Entity Framework Core documentation. You can grab my full source code for building Android applications with Entity Framework by going to my GitHub.

The post Building Android Apps with Entity Framework appeared first on Xamarin Blog.

Monologue

Monologue is a window into the world, work, and lives of the community members and developers that make up the Mono Project, which is a free cross-platform development environment used primarily on Linux.

If you would rather follow Monologue using a newsreader, we provide the following feed:

RSS 2.0 Feed

Monologue is powered by Mono and the Monologue software.

Bloggers