Keith Rome: Creating a Secondary (bottom) iOS Toolbar in Xamarin Forms

Xamarin Forms is a really great platform for mobile app development – we have used it on several apps now and had much better results than when trying to use the native SDK’s directly. Every now and then though you run up against a roadblock with the default renderer implementations where some feature (perhaps a key feature of your app) simply does not work the way it should. Secondary toolbars on iOS are one of those. I recently spent a couple of days trying to coax this feature into working properly before finally finding a solution (many other folks seemed to have simply given up on it).

What is a secondary toolbar?

Xamarin Forms supports the notion of Page-level toolbars. These are represented by the Page.ToolbarItems collection, and each ToolbarItem represents a clickable button that is hosted within the toolbar. In fact, there are two toolbars – the main “primary” toolbar that fills the right end of the navigation bar at the top of your screen, and also a “secondary” toolbar. You can only fit a few (two or three at most) toolbar items on the primary toolbar, and the rest are generally expected to go into the secondary toolbar. On Android this is done by adding an expansion button to the far right end of the primary toolbar which drops down a vertical menu containing the secondary toolbar items.… Read more

John Miller: Skype style animations with Xamarin.Forms

The newest version of the Skype for iOS app has a lot of neat eye candy in it. I love all the animations it uses throughout the experience. If you are not familiar with what I am talking about, take a quick look at Brian Lovin’s Design Details blog on Skype. I wanted to try and recreate some of these animations in a Xamarin.Forms app, but I wasn’t sure how to go about it. A quick search brought up this post by Arkadiusz Holko. It’s not a perfect recreation, but it’s a pretty good start!

Arkadiusz put his solution on GitHub, so I decided to see what I could learn from that and port it to a Xamarin.Forms project. My goal was to not use custom renderers and make everything in shared code. Here is a list of things I figured would be needed:

  • Some way to animate a view with an easing function that looks similar
  • Access to a drawing API to draw some paths on a view
  • All of this would need to be shared code / cross-platform

Not too bad, right?

Wrong

Ok, so it’s not so bad. Xamarin.Forms already has some lovely animation routines for doing all sorts of cool stuff. There are also some easing functions already available to us. The Easing.SpringOut method looked like what I wanted, and the LayoutTo() method will move my view around just fine. The next problem is the drawing API. Without custom renderers, I didn’t find a great way to do custom drawing on a Xamarin.Forms.ContentView. Fortunately, someone else already solved this for me. I came across Christian Falch’s NControl library. Listen to this:

The library contains the NControlView class where real custom cross-platform drawing can be performed without the need for native implementations thanks to the NGraphics library.

My Reaction

I quickly followed along and had something pretty similar going in my Forms app.

Animation 1

The next big issue here is that the side view (green) is moving in sync with the center (red) view. This is not what we want. The reason this is happening is because the easing functions are identical. We need some way to control the coefficients of the easing methods so we can change the elasticity of the animation.

Easing

Instead of passing the built in Easing.SpringOut, we can instead create a custom easing function. The Easing class has an overload that takes a Func<double, double>. The only criteria is that when given 0, the function returns 0, and when given 1, it will return 1. Here is what I ended up with:

new Easing((x) => {  
    return ((x - 1) * (x - 1) * (( sidecoeff + 1 ) * (x - 1) + sidecoeff) + 1);
})

see here for the original BackEaseOut method used. Simplification explained here

And the result after some tweaking.

Animation 2

The Bezier

I made use of the NControl library so that I could draw a bezier curve from these control points. I ended up with something like this:

public override void Draw (NGraphics.ICanvas canvas, NGraphics.Rect rect)  
{
    base.Draw (canvas, rect);

    double yOffset = 20;
    double width = rect.Width;
    double height = rect.Height;

    var points = new PathOp[] {
        new MoveTo(0, yOffset - delta),
        new CurveTo(new NGraphics.Point(width / 2, yOffset + delta),
        new NGraphics.Point(width / 2, yOffset + delta), 
        new NGraphics.Point(width, yOffset - delta)),
        new LineTo(width, height),
        new LineTo(0, height)
    };

    canvas.DrawPath(points, null, new SolidBrush(new NGraphics.Color(0, 0.722, 1, 1)));
}

Arkadiusz’s post talks about using CADisplayLink to get a calback for each frame of the animation where the curve can be updated. I did not find a great place to do something similar in shared code, so I put it in the custom easing method which I figured is called similarly.

_sideHelperView.LayoutTo(position, _animationDuration, new Easing((x) => {  
    UpdateCurve();
    return ((x - 1) * (x - 1) * (( sidecoeff + 1 ) * (x - 1) + sidecoeff) + 1);
}));

The UpdateCurve() method simply calculates the delta of the side and center helper views and calls Invalidate() on the actual NControlView being drawn. This means that each time the easing method is called, the view will be invalidated and cause the curve to be updated each step of the animation. The end result is pretty good.

Animation 3Animation 3 Android

On my device testing, the animation was smooth on both Android and iOS. There is plenty of room for optimizations and eye candy! Also, if you have not already, I encourage you to stop by Arkadiusz’s GitHub page and take a look at the work he’s done.

Xamarin: Simplified Office Integration with the O365 Unified API

The world of Office 365 APIs is immense, with a plethora of capabilities that enable developers to access Office 365 and add rich functionality to their mobile apps, all from shared code. In fact, we’ve already covered several Office 365 topics, including integration of SharePoint Online, Outlook(Mail), and OneDrive, as well as authentication . To consume […]

The post Simplified Office Integration with the O365 Unified API appeared first on Xamarin Blog.

Xamarin: Join Xamarin at the Jenkins User Conference

We’re headed to our first Jenkins User Conference in Santa Clara, CA from September 2-3, and we’d love to see you there. We’ll have members from the Xamarin team available to answer your questions, discuss your apps and projects, and show you what’s new in Xamarin Test Cloud. The Jenkins User Conference is the world’s […]

The post Join Xamarin at the Jenkins User Conference appeared first on Xamarin Blog.

Xamarin: Upcoming Xamarin University Guest Lectures

Whether you’ve had previous experience with Xamarin or are completely new to C# or mobile development, Xamarin University offers an extensive course library that caters to developers of all levels. The program offers live, interactive, lab-based classes taught by Xamarin mobile experts from around the world, at all hours of the day. In addition to […]

The post Upcoming Xamarin University Guest Lectures appeared first on Xamarin Blog.

Greg Shackles: Caviar is Cavalier About Privacy

The “on-demand economy” is everywhere these days. With the tap of a screen you can summon a taxi or have food delivered from your favorite restaurant. Often these services even provide you with real-time updates on the location of the car or courier so you know exactly when they’ll be showing up. From a user’s perspective this is awesome, but there are pretty big privacy implications at play here for both users of the service as well as those working for them.

To that point, I’d like to discuss some glaring privacy issues I found when using Caviar, a courier service that focuses on delivering food from local restaurants.

TL;DR – if you’re a courier for Caviar or a user of Caviar, you should request that they fix these issues as soon as possible.

Courier Tracking

Back on July 11 I ordered a delivery through Caviar. Once the courier was en route to my house the page started updating to show their location. Like most developers, I cracked open the browser developer tools to see how they were doing it. Were they using web sockets? Long polling? It’s always interesting to see how different companies set up their solutions for this sort of thing. For anyone curious, they’re actually using a less-exciting method of just doing occasional full page refreshes via a meta tag.

On each page load Caviar is dropping the coordinates of the courier into JavaScript variables, along with my coordinates, and then showing those on a map. Simple enough. After the delivery came the map reverted to just showing my location, but I noticed something very alarming: the variables for the courier’s location were continuing to get updated long after the delivery was made. In fact, simply flipping a variable named out_for_delivery from false to true as the page was loading would result in the courier’s current location being displayed nicely on the map.

For posterity, I’ve published a gist containing the relevant snippet of code responsible for this. There’s not a whole lot going on there, but it’s a good example of why you should never completely rely on client-side security rules.

Once I realized this was not resolving itself, I contacted Caviar’s support to let them know about the issue. The next day I got a response saying that their engineers would be looking into the problem. Awesome! Problem solved, right?

Fast forward to today, and if I pull up the order status page for that July 11 order it still has moving courier coordinates being dropped onto the page. I also placed another order a couple nights back that now exhibits the same behavior, so it’s definitely still an issue.

This is a huge privacy violation for Caviar’s couriers. As a user of the service I should not be able to have any knowledge of the courier’s location outside of the context of my own delivery. As soon as my delivery is complete, the page should no longer need to be updated with any information about the courier. Instead, if I wanted to I could continue tracking that courier indefinitely. I could mine the data for delivery patterns, pickup and dropoff locations, working hours, and probably even deduce where the courier lives based on where the location settles after hours. This is not information I have any right to, nor is it something I even want to know, so I did nothing of the sort but that doesn’t change the fact that it was still there for the taking.

Security by Good Samaritans is not a good long-term strategy.

Insecure Order Status Pages

One other thing I noticed in using Caviar is a privacy issue for both users and couriers. As is the case with basically every system out there, there’s a standardized URL for checking on your order status in the form of /orders/{order-id}. This is the same page discussed in the previous section that exposed the courier’s location. In addition to that, it also has my full name, address, and even telephone number.

There’s one problem here: the page is public. You don’t need to be authenticated to view order details and get access to all of this personal information. I have a small sample size here, but the order ID seems to be 8 characters long and a case-sensitive mix of letters, numbers, and underscores. Anyone that comes across the right combination of these characters can easily access all of this data. It’s not hard to imagine a brute force attach on this URL to try generating valid order IDs and harvesting private information. Just as before, this is not information I even want to have, so I did not make any attempts to exploit the weakness.

In Closing

None of this is meant to disparage Caviar, or imply that any privacy violations observed here were intentional or malicious. As a user I’ve had good experiences in using their service. I had hoped that contacting their support would result in these issues being resolved, and now hope that publishing this will accomplish that. If you’re a user or a courier for them, I strongly advise that you contact them to get this patched up.

I also want to highlight the importance of privacy in general with services like these, especially given their continued rise to ubiquity. The burden of responsibility falls to us as software engineers to make privacy and security a top priority. When users trust us with sensitive information, it’s on us to do the best we can to protect it and use it responsibly. We can do better.

Xamarin: Xamarin Events in September

Xamarin is back in session with tons of new workshops, seminars, Dev Days, user groups, and conferences happening this September all over the world! Get involved this month in events near you: Seattle Mobile .NET Developers  Seattle, WA: September 1st What’s new in C# 6 and F# 4! with James Montemagno and Xamarin MVP, Frank […]

The post Xamarin Events in September appeared first on Xamarin Blog.

Adam J Wolf: Weekly Xamarin Newsletter Issue #55

Easily Automate Your Xamarin.Forms Apps James Montemagno, from Xamarin Inc., tries to knock the tedium out of testing. Episode 28: Behind the Scenes of Xamarin.Forms with Jason Smith Greg Shackles and Jon Dick talk with the legend Jason Smith from Xamarin. Rapid Mobile App Prototyping with Xamarin.Forms Krystin Stutesman, from Xamarin Inc., shows off some […]

The post Weekly Xamarin Newsletter Issue #55 appeared first on Syntax is my UI.

Johan Karlsson: Extending the ListView to make it clickable

The problem

The ListView is a fantastic control to use in Xamarin Forms. It has one big drawback, however and that is that if you navigate away from a selected item in the list and then navigate back, the same item is still selected and nothing happens when you tap it again.

The solution

We want to add a new command to the ListView and we start by adding a new class that inherits from the original ListView control. I usually create a folder called “Controls” in the Forms PCL and put stuff I want to use in the XAML in there.

   public class ListView : Xamarin.Forms.ListView
    {
        public static BindableProperty ItemClickCommandProperty = 
            BindableProperty.Create<ListView, ICommand>(x => x.ItemClickCommand, null);

        public ListView()
        {
            this.ItemTapped += this.OnItemTapped;
        }

        public ICommand ItemClickCommand
        {
            get { return (ICommand)this.GetValue(ItemClickCommandProperty); }
            set { this.SetValue(ItemClickCommandProperty, value); }
        }

        private void OnItemTapped(object sender, ItemTappedEventArgs e)
        {
            if (e.Item != null && this.ItemClickCommand != null && this.ItemClickCommand.CanExecute(e))
            {
                this.ItemClickCommand.Execute(e.Item);
            }

            this.SelectedItem = null;
        }
    }

The key here is the ItemClickCommand property. This will be the command that gets executed when we tap on an item. We also listen to the OnItemTapped event and the magic goes here by simply setting the SelectedItem to null again, allowing for the item to be tapped again.

Enter a ViewModel

Since MVVM is the way to go we need a view model. We are omitting the INotifyPropertyChanged stuff to keep it simple. What we have is an ObservableCollection of Duck objects that simple has a property called Name. We also define a command where we put the code that we want to execute when an item is tapped. In this case we navigate to a new page that simply displays the name of the duck. In the real world you should use IoC and also create a view model for the Duck view.
    // INotifyPropertyChanged implementation omitted  use fody!
    public class MainViewModel
    {
        public MainViewModel()
        {
            Ducks = new ObservableCollection<Duck>()
            {
                    new Duck() { Name = Bob },
                    new Duck() { Name = Tommy },
                    new Duck() { Name = Donald }
            };
        }

        public INavigation Navigation { get; set; }

        public ObservableCollection<Duck> Ducks
        {
            get;
            set;
        }

        public Command<Duck> DuckSelected
        {
            get
            {
                return new Command<Duck>(async (d) =>
                    {
                        var duckView = new DuckView();
                        duckView.LoadData(d);
                        await Navigation.PushAsync(duckView);
                    });
            }
        }

    }

    public class Duck
    {
        public string Name { get; set; }
    }


And the View 

This binds it all together. We assign the source of items from our view model as well as the command that we want to execute when an item is clicked.
xml version=1.0 encoding=UTF8?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms 
             xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml
             xmlns:local=clrnamespace:FancyList.Controls;assembly=FancyList
             x:Class=FancyList.MainView Padding=20>
    <ContentPage.Content>
        <local:ListView ItemsSource={Binding Ducks} ItemClickCommand={Binding DuckSelected}>
            <ListView.ItemTemplate>
                <DataTemplate>
                      <ViewCell>
                        <ViewCell.View>
                              <Label Text={Binding Name} />
                          </ViewCell.View>
                      </ViewCell>
                </DataTemplate>
             </ListView.ItemTemplate>     
        </local:ListView>

    </ContentPage.Content>
</ContentPage>


Code behind

We also need to set the BindingContext in the code behind for the view. There are several navigation patterns out there and in this sample we take the easy path by simply passing in the Navigation object from the page (view) itself.
    public partial class MainView : ContentPage
    {
        public MainView()
        {
            InitializeComponent();

            var viewModel = new MainViewModel();
            viewModel.Navigation = this.Navigation;

            BindingContext = viewModel;
        }
    }


Summary

It’s easy to extend controls in Xamarin Forms. This sample does however omit a lot of good practices like IoC and Fody. 

Resources