May 23, 2015 9:43 GMT

Apple Watch Is A Needful Thing

Needful Things is the name of a book by Stephen King (who I happen to think is America’s most underrated author, and best storyteller, but that is another matter).  I’ve co-opted his title to mean those things that seem absurdly unnecessary (but desirable), and which worm themselves into your life, so much so that you know already that if it breaks you will run out and buy another.  My own history of needful things includes

  • Wireless phones
  • DVRs
  • iPhones, 3,4,5,6

And now the Apple Watch.  I loved my Pebble, but honey the affair is over, sorry to see you go, but there  is a new love in my life.

The Apple Watch

The Apple Watch has all the hallmarks of a great Apple product

  • The essential is easy, everything else is possible
  • It is beautiful
  • It is smarter than anything else in its category
  • It is expensive

Continued here.

May 22, 2015 5:48 GMT

Case Study: Development Time Slashed by 50% for Leading Transport Company

mrw-logoMRW is Spain’s leading national and international express transport company. Powered by 10,000 people linked to the brand in over 1,300 franchises and 64 logistical platforms in Spain, Portugal, Andorra, Gibraltar, and Venezuela, MRW handles an average of 40 million parcel deliveries per year and ships to more than 200 countries and over 10,000 online stores.
 
A mission critical element of the company’s success is the MRWMobile app that supports 2,500 concurrent users in the field by helping them with process optimization, including delivery coordination. MRWMobile was developed by the company’s Portugal-based partner Moving2u, and after the successful creation of MRWMobile 3 for Windows, MRW wanted to expand to Android.
 
MRW app on HTC OneThe app is used in the field for a range of functions, including proof of picking up deliveries in real time, receiving new work orders, and for rescheduling order pick ups and deliveries—all while using secure communications and local data encryption. To support these functions, the app needs to support a range of capabilities, including offline work, local storage, push sync, multi-threading, barcode scanning, photos, and signature capture. The app also incorporates geolocation, multilingual support, multiple user profiles, mobile payment, printing, document scanning, and internal communications with messages and tasks.
 
The magnitude of requirements coupled with budget and conflicting project roadblocks created time-to-market challenges. “Without Xamarin, it would have taken at least twice as long to have the full feature set of the app built and tested,” says Alberto Silva, R&D Manager at Moving2u.
 
“Xamarin is the right approach for any serious Android, iOS, or mobile cross-platform app development,” Alberto adds. “Even if you don’t plan to go cross-platform, the productivity of Xamarin in producing an app for a single platform in C# is unmatched.”
 

View the Case Study
 

The post Case Study: Development Time Slashed by 50% for Leading Transport Company appeared first on Xamarin Blog.

May 22, 2015 5:28 GMT

Sitecore SDK for Xamarin

Sitecore is a high-end CMS. Putting data from its databases onto a phone is suddenly very easy.  Sitecore and Xamarin recently announced the Sitecore SDK for Xamarin. This post will run through an application that handles an implicit relationship to retrieve data.

The primary relationship we’ll look at comes from two tables.  One has the GUIDs of all the currently available jobs, the other ties those guids to the name of each job.  Note that the GUIDs are in one long string.

By experimentation we learn that the job objects we’ll get from the database have a number of fields we won’t need, and three we will.  We thus create our model class as follows

Continued here

May 22, 2015 1:30 GMT

Weekly Xamarin Newsletter Issue #41

RSVP for Xamarin’s WWDC 2015 party
Joseph Hill, from Xamarin Inc., invites us all to the WWDC 2015 Party.

Material Designer for Xamarin Forms
Jonathan Yates uses some GUI innovation and adds some design to his Xamarin.Forms app.

The Xamarin.Forms Chef
I (Adam) wrap up the recipes into a Xamarin.Forms cookbook.

Community Contributions You Won’t Want to Miss
Joseph Hill, from Xamarin Inc., shows off some of the community’s contributions.

Native Performance with Xamarin.Forms ListView and Xaml Cells
George Cook, from Twin Technologies Inc., dares to dream about fast Xaml ViewCells.

Xamarins on Film: New Video Resources
Joseph Hill, from Xamarin Inc., highlights Xamarin team members appearing on video.

FormsPresenters: Setting Up MvvmCross with Xamarin.Forms
Marcos Cobeña Morián makes more improvements to his plug-in.

Get Started with HomeKit
Michael James, from Xamarin Inc., gets you up and running with HomeKit and Xamarin.

Xamarin.Forms CarouselPage Recipe
I (Adam) show off my hot sauce addiction with this Xamarin.Forms carousel of flavors.

Editing Markdown in Xamarin Studio
James Montemagno, from Xamarin Inc., shows off a Markdown view add-in for Xamarin Studio.

 

Don't miss out! Subscribe Today

Do you blog about Xamarin? Get your blog in the newsletter. Email me at adam [at] adamjwolf.com.

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

May 22, 2015 9:49 GMT

SelectionChanged for a Panorama control in WP8.0

A small tip that might save you an hour or two. Observe that this is not using databinding.

Really short version


Wrap content in a PanoramaItem to get the SelectionChanged event to fire.

Somewhat longer version, but still short


If you programmatically create a Panorama control in, let's say a custom renderer for WP8.0 (silverlight) when using forms, wrap any content in an PanoramaItem if you want events to fire.

Not working


            var root = new Panorama();
      root.SelectionChanged += (s, a) => { Debug.WriteLine("Will not fire"); };
      root.Items.Add(new System.Windows.Controls.Image()
            {
                Source = new BitmapImage(new Uri(""))

            });

Working


            var root = new Panorama();
       root.SelectionChanged += (s, a) => { Debug.WriteLine("Will fire"); };
       root.Items.Add(
       new PanoramaItem()
           {
               Content = new System.Windows.Controls.Image()
               {
                   Source = new BitmapImage(new Uri(""))
               }
        });


That's all...

By the way, if you are using data binding and not getting it to work, this stackoverflow post might help: http://stackoverflow.com/questions/14260701/

May 22, 2015 4:00 GMT

Improvements coming to Xamarin Google Play Services

Google Play Services is a rapidly evolving library that Google has been using to combat fragmentation on the platform, and ensure their developers have access to great new API’s without having to worry about what Android version their users are actually on.

The rate at which this library has evolved recently has been especially challenging for us to keep pace with in getting bindings out for Xamarin.Android, but, rest assured, we are committed to bringing out a great Google Play Services experience in your Xamarin apps. Here are some of the improvements we’ve been making that are now available as pre-release!

Latest and Greatest

Google has rapidly iterated in the last few revisions. We went from 6.5 to 7.0 to 7.3 very quickly, and we’re happy to say we’re shipping the latest and greatest and expect to keep a better track record going forward on getting the latest out quickly!

NOTE: As of this post, the improvements are available on NuGet as 24.0.0-rc1 versioned pacakges.

NuGet what you Want

We’ve now split up Google Play Services into many NuGet packages to match the changes Google made to split them up into many .jar files. Using NuGet we’re able to manage the dependencies between all of the packages. For example, all packages depend on the Google Play Services - Base package, while others such as Location depend on Maps as well.

You can now grab only the packages you need in your app without bringing in everything else. This should help keep your app size down as Google continues to expand Play Services adding more and more features and API’s.

Finally, the old Google Play Services - All package has been kept around to help make the transition easier. It now depends on all of the individual NuGet packages.

Breaking Changes, Nicer Naming

In the process of binding libraries to make them more C# friendly, we often run into cases where casing is different between java and C#. For example, in java, we have cast.Cast which in C# translates into Cast.Cast. Since we cannot have a class named the same as its namespace in C#, this presents a problem. Traditionally we have renamed the class, for example to Cast.CastClass. This isn’t always very discoverable or nice to look at.

We’ve now decided to change the namespaces instead of renaming the conflicting classes. All namespaces now have Sdk appended to them, so we now have CastSdk.Cast for instance. This should be much more consistent and discoverable going foward.

The other area where this is a problem is with fields in java. For instance, Fitness.FITNESS_API and Fitness.FitnessApi in java both transform into Fitness.FitnessApi in a C# binding by default. To avoid conflicts and bring consistency across the bindings, we’ve decided to keep the java naming conventions in the C# binding.

You’ll now use the upper-cased Fitness.FITNESS_API fields to specify an Api to add in your IGoogleApiClient.AddApi (..) calls, whereas you’ll use the lower-cased Fitness.FitnessApi fields to actually invoke methods of the given Api.

Happier C# Developers

Our binding tooling generally does a good job at making java libraries more C#-ified. Google Play Services has a number of cases that are less friendly to our tooling and often this has created a sub-par developer experience from a C# perspective.

We’re continuing to work at improving this story in Google Play Services, and there are a couple of changes that should make life better:

IPendingResult.AsAsync

A very common pattern in Google Play Services is to make use of the interface IPendingResult. This is sort of like a Task - it’s a promise or a future. You can .Await() it in a blocking manner (though you must do so off the UI thread), or you can .SetResultCallback (IResultCallback) which means you need to pass in an implementation of the interface which usually means creating an implementor class with some Actions or Events to make the code a bit less ugly (since we don’t have anonymous classes in C#).

You now have more options with IPendingIntent instances through some extension methods:

1
2
3
4
5
6
7
8
9
// 1. Turn it into a Task with the desired result type
var result = await SomeMethodReturningPendingIntent (...)
  .AsAsync<TypeOfStatus> ()

// 2. Pass in an Action<T> to the callback
SomeMethodReturningPendingIntent (...)
  .SetResultCallback<TypeOfStatus> (result => {
      // ...
  });

Helper Implementor Classes

There’s still a lot of areas that require you pass in some sort of class implementing a listener type of interface. ILocationListener is a good example. Instead of having to build your own class which implements this simple interface, we’ve added a class LocationListener which implements ILocationListener and exposes an event for you. Nothing earth-shattering here, but hopefully it saves you from writing the same boiler plate code over and over.

You can expect more implementation classes like this going forward.

GoogleApiClientBuilder

The first place you’ll probably notice the heavy use of interfaces is in the GoogleApiClientBuilder. The .AddConnectionCallbacks (..) and .AddOnConnectionFailedListener (..) methods both require instances of interface implementations as parameters. You can still call these methods like normal, but now there’s extension methods allowing you to pass Action’s into them as appropriate. Again, this is code you could easily write, but shouldn’t have to.

Less p0, p1, p2

This has always been a bit of an eye-sore, to see poorly named parameters. We’ve made some improvements in our tooling that are going to continue to help get better parameter names. We’ve started trying some of these techniques out already in Google Play Services!

Feedback?

I don’t always get to explore all of the API’s inside Google Play Services on a day to day basis, so I’m not always aware of where the pain points are.

I’m very open to feedback if there’s other areas you’d like to see some C# improvements to like we’ve started.

Please don’t be shy, mention me on twitter with any suggestions you have!

May 21, 2015 7:20 GMT

RSVP for Xamarin’s WWDC 2015 Party

Join the Xamarin team for a party celebrating WWDC at Roe Restaurant on Tuesday, June 9th, from 6:00 – 9:00pm. Just two blocks from Moscone you’ll find great conversation with your fellow mobile developers, drinks, and appetizers. We’d love for you to join us to talk about your apps and projects and the latest news from Apple.

WWDC 2015 Logo

When: Tuesday, June 9th, 6pm-9pm
Where: Roe Restaurant, 651 Howard St, San Francisco, CA, 94105

RSVP

Even if you’re not attending WWDC, all of our Bay Area friends are welcome!

You can make the most of your time in town for WWDC week by scheduling dedicated time with a member of our team.

We hope to see you there!

The post RSVP for Xamarin’s WWDC 2015 Party appeared first on Xamarin Blog.

May 21, 2015 11:40 GMT

FormsPresenters: Setting Up MvvmCross with Xamarin.Forms

During the last months, we have made some improvements to the FormsPresenters plug-in taken from real-world projects we are working on with our customers, at Plain Concepts. Since we did not have some NuGet packages to make an easy install of the scaffolding needed, we dedicated some effort to add a small documentation to the GitHub repository it-self, so everyone can easily set-up MvvmCross on their Xamarin.Forms projects.

The first step is to clone the entire repo. locally, and build the MvvmCross submodule. Apart from here, the rest of the steps are done within the FormsPresenters directory. You will find four different projects inside: Core one, which handles the common logic among every supported platform (Android, iOS and Windows Phone); and one project per supported platform, which basically contains the final Presenters.

Read the entire article…


May 21, 2015 6:57 GMT

Windows Phone Emulator is unable to set the VHD on the virtual machine

This Thursday morning could have started better. I'm in the middle of a month long process to hand over one of our projects to a customers internal dev department when this suddenly happens...


What the... I just have the WP stuff left to document.

I have changed, nothing? And suddenly there is a digital signature verification failure. My first google adventures tell me to reinstall my OS. Not gonna happen. That will send me back into the stone age again.

I tried the following so far:
  • Another emulator
  • Deleted all the emulators from Hyper-V manager
  • Tried to create a new virtual machine from scratch, same error
  • Created a disk manually and tried to attach it
  • Restarted Hyper-V
  • Restarted Windows
Things blew up...

Stressfactor: 60%...

Restart doesn't help, next up is Startup repair that also failed. Restore from a restore point... Didn't work... Refresh my PC? Looks that way... 

Summary of my experience

I'm buying a large external drive later on today to make more frequent backups to. Happy thoughts...



May 20, 2015 9:08 GMT

Get Started with HomeKit

Next month sees the launch of several highly anticipated HomeKit accessories, which were debuted earlier this year at CES. With HomeKit-enabled accessories finally coming to market, it’s time to create iOS apps that utilize Apple’s home automation APIs.

homekit

HomeKit is designed to bring an end to individual apps for smart home accessories. Gone are the days where you will be switching between apps to set up a perfect movie night scene; instead you’ll have one app, which communicates to all of your accessories using HomeKit.

HomeKit has a couple of core concepts that form the basis for the entire API. The general idea of HomeKit is that you interact with a Home, which has Rooms, which have Acessories, which have states. In order to get started, you’ll need to create a Home Manager. The Home Manager is your entry point to HomeKit – it keeps a common database of Accessories and allows you to manage your Home(s). It also notifies you of changes, which makes it easy to deal with changes to the HomeKit configuration from other HomeKit-enabled apps.

General Setup Tips

If you’re looking to test these APIs, it’s worth noting that you’ll need access to a physical iOS device running iOS 8 at a minimum. HomeKit doesn’t currently work within the iOS Simulator and the exception thrown doesn’t hint towards this. Because you’re running on the device, you’ll need to make sure you’ve set the entitlements for the project to allow for HomeKit. You’ll probably also want to grab a copy of Apple’s Hardware IO Tools for Xcode. The Hardware IO Tools for Xcode allow you to simulate HomeKit-enabled devices for testing your app. You can fetch this from the Apple Developer Center if you’re an existing member.

Creating a Home

To create a Home, we must first create an instance of the Home Manager.

var homeManager = new HomeKit.HMHomeManager();

Once we’ve done this, we can go ahead and add a Home to the homeManager object.

homeManager.AddHome("Guildford", (HomeKit.HMHome home, NSError error) =>
{
    if (error != null)
    {
        // Adding the home failed. Check the error object for why!           
    }
    else
    {
        // Successfully added home!
    }
});

All Homes within your HomeKit configuration must have a unique name, so if we have two homes in the same city, it might be worth finding another naming convention. Homes must be uniquely named because we will be able to interact with them using Siri once Apple fully enables HomeKit (hopefully later this year). For example, we’ll be able to say, “Hey Siri, turn my lights off in Guildford,” and like magic, all of the lights in your Home in Guildford will be switched off.

Once you’ve added a Home, the DidUpdateHomes event will be raised. This allows other apps to ensure they’ve processed any new Homes that have been added to the database. We can subscribe to the event with the following API.

homeManager.DidUpdateHomes += (sender, args) =>
{     
	foreach (var home in homeManager.Homes)     
	{         
	    var alert = new UIAlertView("Home...", home.Name, null, "OK");  
	}
};

Creating a Room

A Home also contains Rooms, each of which has a list of Accessories that are unique to that particular Room. Much like the Home, a Room can notify you about any changes and must also be uniquely named. This again allows you to interact with the Room using Siri. The API for creating a Room is almost identical to creating a Home.

home.AddRoom("Kitchen", (HMRoom room, NSError error) =>
{     
	if (error != null)     
	{         
	    //unable to add room. Check error for why     
	}     
	else     
	{         
	    //Success     
	}
});

Accessories

Accessories are where HomeKit starts to become a little more interesting. Accessories correspond to physical devices and must be assigned to a Room. They have a device state which allows you to query them. For example, you can query the intensity of a light fixture or the temperature of a thermostat. As you’ve probably already guessed, Accessories must be uniquely named, but this time only within the Home where they reside. Accessories will also notify you of changes to the state so you don’t have to constantly query them to ensure your app is up to date; one common event that you can be notified of is when the device is reachable.

accessory.DidUpdateReachability += (o, eventArgs) =>
{                         
	if (accessory.Reachable == true)                         
	{                             
	    //we can communicate with the accessory                         
	}                         
	else                         
	{                             
	    //the accessory is out of range, turned off, etc                    
	}                     
};

A few of the more interesting aspects of Accessories are Services and Characteristics. A Service represents a specific piece of device functionality. For instance, Apple gives the example that a garage door accessory may have a light and a switch Service. Users wouldn’t ever create Services or Characteristics as these are supplied by the accessory manufacturer, but it’s your job as a developer to make sure they can interact with the Services.

Action Sets and Triggers

Actions are by far my favorite feature of HomeKit. Actions and triggers allow you to control multiple Accessories at once. For example, when I go to bed I like to turn the lights off and turn my fan on. I can program this action with HomeKit to set the state of the Accessories and then use triggers to call the action. I personally have an iBeacon stuck to the underside of my nightstand which could detect my proximity and then call my action set for sleeping. As with almost every aspect of HomeKit, each action set has a unique name within the Home that can be recognized by Siri.

Conclusion

I’m extremely excited about the prospect of HomeKit evolving into the go-to solution for home automation. With HomeKit-enabled accessories finally coming to market, there’s never been a better time to create an iOS app that utilizes Apple’s home automation APIs.

To start integrating HomeKit into your apps today, check out our HomeKitIntro sample, which will give you everything you need to build amazing home automation apps with HomeKit.

The post Get Started with HomeKit appeared first on Xamarin Blog.

May 20, 2015 5:05 GMT

Lighting up Native Platform Features in Xamarin Forms – Part 2

In the previous post I implemented a custom attached property to be used in Xamarin Forms XAML when a built-in accessory view is desired on a table cell. In this follow-up we will continue and build out the iOS renderer that is responsible for actually enabling the feature in our running application.

What about Android and Windows Phone – won’t they be affected too? That’s the beauty of the Xamarin Forms rendering model – it is up to each platform to decide how to natively implement the controls described in XAML markup. In this case, we have extended the existing XAML (not replaced it), and so the Android and Windows Phone renderers will simply just ignore the extensions unless we customize the renderers for those platforms as well.

Badge-Xamarin

TableView Rendering

Note: The following information comes through decompilation and inspection of the iOS renderers found in Xamarin.Forms.Platform.iOS (this assembly can be found in your Xamarin.iOS installation, or in your debug/bin output folder after compiling a Xamarin Forms project for iOS). I used JetBrains dotPeek to decompile the source from that assembly file.

The process of mapping a XAML TableView or ListView to a native UITableView/UITableViewSource and the various Xamarin Forms cell types to UITableViewCell objects is performed by a fairly complex orchestra of intertwined classes in the default iOS rendering system.… Read more

May 20, 2015 12:00 GMT

The Xamarin.Forms Chef

Over the past 9 months I’ve been on a journey to learn all that I could about Xamarin and Xamarin.Forms. My Xamarin.Forms recipe series was a way to giving back to the community that has helped me and to hopefully help others that come after me.

When this journey started, I didn’t know how many recipes I would write. After the 7th one, I thought the collection could be useful and not just to me. With 15 of them under my apron, I am now officially calling it a cookbook.

A Confession

Pastry ChefIn another life, I was a classically train pasty chef. Yep, I wore a chef coat and hat every day. Being a chef taught me the value of recipes and bringing that value to Xamarin.Forms has been a lot of fun. Much more fun than standing in front of 400 degree ovens during a Phoenix summer, with the kitchen temperature in the high 90’s.

I can’t tell you just how many times while working on a Xamarin.Forms project that I’ve look up my own blog post just to remember how to do something. Just like when you’re in the kitchen at home or at the restaurant it’s always nice to be able to look up a measurement or baking time on a recipe card.

The Xamarin.Forms Cookbook

I don’t know how many more recipes will be added to the cookbook. With all the major Xamarin.Forms pages and controls covered, I don’t see many more in the future. Don’t worry, if Xamarin adds more controls or pages, I’ll do a second edition to the cookbook.

The post The Xamarin.Forms Chef appeared first on Syntax is my UI.

May 19, 2015 8:03 GMT

Lighting up Native Platform Features in Xamarin Forms – Part 1

In my last few posts I introduced a simple app that lets you browse the various built-in font variations supported by Xamarin Forms. If you recall, the application adopted a “stack navigation” design, which is quite common in mobile applications. However, there is one small flaw with our implementation so far – on the iOS platform it is customary to indicate that a ListView/TableView cell can be used to “drill down” into the navigation stack by including a “disclosure accessory” on the far right end of each cell. This accessory can be seen in the iOS Settings app below (the small chevron icons in the right margin of each cell):

image

Disclosure Indicators in the iOS System Settings App

Now, we could simply change our cell templates to add a custom image aligned to the right edge – but that wouldn’t be 100% correct. A Xamarin Forms TableView or ListView maps to the native UITableView, and if you review the iOS programming guide for Table Views you can see that there is built-in support for these that is provided by the operating system. These built-in icons can vary from one version of iOS to the next, and by using them (instead of custom icons) we can be assured that our application will continue to look correct as the platform evolves.… Read more

May 19, 2015 9:06 GMT

Xamarins on Film: New Video Resources

The Xamarin team is popping up everywhere; from conferences and user groups to Xamarin Dev Days, odds are high that you can find a member of our team at an event near you. If, however, you we haven’t made it to your neck of the woods, observing a Xamarin on film can be just as fascinating and educational. For your viewing pleasure, and to teach you about a wide variety of mobile C# topics, we present footage from some recent sightings below.

Building Multi-Device Apps with Xamarin and Office 365 APIs

Have you been curious about how to integrate your Xamarin apps with Azure Active Directory and utilize the brand new Office 365 APIs? Look no further than James Montemagno’s session at this years Microsoft Build conference on how to integrate all of these services from a shared C# business logic backend.

Cross-Platform App Development with .NET, C#, and Xamarin

Xamarin Developer Evangelist Mike James recently spoke at the Technical Summit in Berlin, providing a complete overview of how to build native cross-platform apps with C# and Xamarin.

Tendulkar Explains

If you’re just getting started, you can learn the basics of Xamarin and mobile app development one step at a time by following along with Xamarin Developer Evangelist Mayur Tendulkar in his new, ongoing series, tendulkar-uvāca (Tendulkar Explains). The first episode, below, covers how to set up your development environment.

Developing Cross-Platform 2D Games in C# with CocosSharp

13cc9fce-3d69-4b8e-8bc5-35580ff98e33 If you haven’t been following James Montemagno’s appearances on Visual Studio Toolbox, then you’re in for a treat! Officially setting the record for most appearances, his latest visit takes a look at cross-platform 2D games with CocosSharp.

Real-Time Monitoring of Mobile Apps with Xamarin Insights

13cc9fce-3d69-4b8e-8bc5-35580ff98e33In his 8th appearance on Visual Studio Toolbox, James joins Robert Green to discuss monitoring your apps in real time with Xamarin Insights.

Live Events

If you’d like to catch a Xamarin talk in person, check out our upcoming events here.

The post Xamarins on Film: New Video Resources appeared first on Xamarin Blog.

May 18, 2015 6:34 GMT

Join Xamarin at Twilio Signal

Join Xamarin at Twilio Signal, a developer conference in San Francisco, CA on May 19-20, 2015 covering communications, composability, iOS and Android, WebRTC, and much more. Key members of the Xamarin team will be available to answer your questions, discuss your apps and projects, and show you what’s new across our products.

Twilio Signal Conference Logo

Xamarin Developer Evangelist James Montemagno will also be be presenting C# and Twilio-powered iOS and Android experiences on Wednesday, May 20 at 1:45 pm, covering how to leverage the Twilio Mobile Client native SDK for iOS and Android from C# to create a rich communication experience in your mobile apps.

We’ll be in the Community Hall, so stop by with your questions or just to say hello. If you’re not already registered, limited tickets remain, and you can use promo code “Xamaringuest” for 20% off registration. We look forward to seeing you there!

The post Join Xamarin at Twilio Signal appeared first on Xamarin Blog.

May 18, 2015 12:00 GMT

Xamarin.Forms CarouselPage Recipe

Xamarin.Forms CarouselPage

The Xamarin.Forms CarouselPage has a bad reputation. Its reputation is partly due to how it’s misused and partly its own fault.

Xamarin.Forms Misuse

Misuse comes in many forms but its main form is loading the carousel up and expecting it to perform miracles. My advice, use it sparingly. Performance issues is its Achilles heel.

In the last Xamarin.Forms “In Anger” post, I used the Xamarin.Forms CarouselPage to hold my hot sauce collection. My personal collection contains 5 sauces. That’s right 5, not 25 or 50, just 5.

“Use Xamarin.Forms CarouselPage in moderation and hot sauce with abandon.”

The CarouselPage like the MasterDetailPage and the TabbedPage contains a collection of content pages. Unlike these other pages, the CarouselPage will display them like cards in a deck of playing cards. With each swipe the next card or page will be displayed.

Familiar to Some

The UI of the Xamarin.Forms CarouselPage should feel pretty familiar to those who rock a Windows Phone. For Apple and Android users, it’s not exactly foreign but also not very familiar. Tinder uses should feel right at home.

The Code

public Page GetMainPage ()
{
var sauces = new List<Sauce> () {
	new Sauce () {
		Name = "Original Red Sauce",
		Tagline = "Our most versatile sauce. Put it on anything you like!",
		FileName = "Tabasco.png",
		Heat = "2,500 - 5,000",
		Ingredients = "distilled vinegar, red pepper, salt."
	},
	new Sauce () { 
		Name = "Green Jalapeno Sauce", 
		Tagline = "Genuine Jalapeno flavor. Not too hot, not too mild.",
		FileName = "Jalapeno.png",
		Heat = "600 - 1,200",
		Ingredients = "distilled vinegar, jalapeño pepper, water, salt."
	},
	new Sauce () { 
		Name = "Chipotle Sauce", 
		Tagline = "A rich, smokey flavor that's not too fiery hot.", 
		FileName = "Chipotle.png",
		Heat = "1,500 - 2,500",
		Ingredients = "chipotle pepper, vinegar, water, salt, sugar, onion powder, garlic powder, spices, red pepper, salt."
	},
	new Sauce () { 
		Name = "Habanero Sauce", 
		Tagline = "Our hottest sauce. A fruity, Jamaican-style blend.", 
		FileName = "Habanero.png",
		Heat = "7,000 - 10,000",
		Ingredients = "vinegar, habanero pepper, cane sugar, salt, tomato paste, tamarind, papaya, spices, garlic."
	},
	new Sauce () { 
		Name = "Garlic Pepper Sauce", 
		Tagline = "Mild 3-pepper blend infused with savory garlic.", 
		FileName = "Garlic.png",
		Heat = "1,200 - 2,400",
		Ingredients = "red pepper, distilled vinegar, water, salt, garlic."
	},
};

return new CarouselPage {
	Children = { 
		new SaucePage (sauces [0]),
		new SaucePage (sauces [1]),
		new SaucePage (sauces [2]),
		new SaucePage (sauces [3]),
		new SaucePage (sauces [4])
	}
};

The code is simple, just create a few content pages and add it the carousel’s children. Once added to the deck, the pages will be displayed in a first in first out manner. Sorry, looping from the last card back to the first card is not supported at this time.

Even with the CarouselPage’s issues I really like how it looks. How about you?

The Xamarin.Forms Cookbook Series

Still hungry for more Xamarin.Forms? Try these other recipes from the Xamarin.Forms Cookbook Series.

The post Xamarin.Forms CarouselPage Recipe appeared first on Syntax is my UI.

May 17, 2015 12:00 GMT

Bootstrapping Cross Platform MSBuild with XBuild and NuGet

I have to admit I’m a fan of MSBuild. Not necessarily a fan of the file format, but of the feature set. At work, I’ve encountered now and then inconsistencies and missing features in XBuild that I just had to work around (the most annoying one being the lack of inline code tasks!). Well, no more!

One of the core uses of MSBuild for me is the CI (and full product) build script. It allows me to have a single build script that can be run localy as well as on a build server and produce identical results. This is invaluable. It can do so much more than just build! I can make it calculate product version information from git commit information, download and install dependencies, push tags and upload releases and what-not.

Since the xplat branch of MSBuild (or any other, for that matter ;)) hasn’t been released officially, I just built it on Windows and Mac and bundled both versions as the MSBuild NuGet, since it’s working pretty awesomely already for me.

Now bootstrapping it on the Mac/*nix is really simple:

  • Install MSBuild NuGet
  • Invoke MSBuild with Mono, passing the actual MSBuild project (i.e. build.proj)

Since this is only needed on the Mac, we don’t need any fancy conditionals in the build project or anything. This is how it looks like currently:

<Project ToolsVersion="4.0" DefaultTargets="Build"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Target Name="Build">

        <!-- Restore potentially build-time packages that are restored by build.cmd on Windows -->
        <Exec Command="nuget install packages.config -excludeversion -outputdirectory packages" Condition="Exists('packages.config')" />

        <!-- Install MSBuild nuget package if necessary -->
        <Exec Command="nuget install MSBuild -excludeversion -outputdirectory packages" Condition="!Exists('packages/MSBuild/tools/Unix/MSBuild.exe')" />

        <!-- Finally build with MSBuild the build.proj itself -->
        <Exec Command="mono packages/MSBuild/tools/Unix/MSBuild.exe build.proj" />

    </Target>

</Project>

Of course if you need to be able to invoke different targets and pass properties, it’s not that trivial, but for bootstrapping a CI server that runs on *nix and get it going, you don’t need anything other than that. You could additionally make it so that the xbuild project receives a Targets property which you pass on to MSBuild to tell what targets to build soo.

I’ve added this approach to my default build script I use, which can be installed simply with:

nuget install build -excludeversion

This will give you a top-level build folder with all you need for this, plus build.proj, xbuild.proj and an empty solution sample. It also implements the Ultimate Cross Platform NuGet Restore.

May 16, 2015 2:55 GMT

Editing Markdown in Xamarin Studio

 I can’t help myself I really love Xamarin Studio. Don’t get me wrong I still love Visual Studio for everything that it does, but with Xamarin Studio 5.9 the best mobile focused IDE just keeps getting better. However, did you know that you don’t have to wait for new releases of Xamarin Studio to get new features? Xamarin Studio has an entire ecosystem of awesome plugins to extend the IDE and I just stumbled upon one that solves one of my common issues, which is the ability to edit and preview Markdown. I love markdown for its simplicity and I often have to edit readme.md files for GitHub and the Markdown Viewer makes everything LOVELY! So here is how you get it:

Installing and Using The Add-in

To get started all you need to do is go to the Xamarin Studio Add-in Manager.

You will need to turn on the alpha channel under the Gallery tab by selecting Manage Repositories:

Then turn on Alpha Channel, Hit Close, and then Refresh the list.

You will now see the Markdown Viewer available under IDE extensions:

With the add-in installed now simply add your readme.md or any other .md file to the solution level. Double clicking the file will bring you into a markdown editor. 

On the bottom you will see a Source/Markdown viewer toggle similar to the Xamarin.Android designer. Simply toggle to see your markdown rendered in realtime!

Enjoy the awesome markdown experience!

May 15, 2015 1:08 GMT

Weekly Xamarin Newsletter Issue #40

Demystifying Xamarin Forms AbsoluteLayout and RelativeLayout positioning
Jonathan Yates puts us straight on AbsoluteLayout and RelativeLayout.

Xamarin Podcast
We’re back! This week, we talk 1 Million Developers, Build announcements, and more!

Crafting 5 Star iOS Experiences With Animations
Michael James, from Xamarin Inc. adds some subtle animation for an immersive experience.

Blurred Image Renderer for Xamarin.Forms
Adam Kemp makes images blurry on Xamarin.Forms on purpose.

RSVP for Xamarin’s Google I/O 2015 Party
Joseph Hill, from Xamarin Inc., invites us all to a party to kick off Google I/O!

Aka Awesome Refactored
Matthew Soucoup upgrades a Xamarin.Forms app to use the Akavache.

Xamarin.Forms in Anger – Hot Sauce
I (Adam) get a little mad and put hot sauce all over my Xamarin.Forms.

A Scalable Introduction to Vector Drawables
Jérémie Laval, from Xamarin Inc., introduces a new Android Lollipop feature vector drawables.

Xamarin.Forms xforms-kickstarter News

Using the Xamarin Forms InputTransparent Property
Mitch Milam gets transparent and starts to ignore touches for more votes.

FreshMvvm – A Mvvm Framework designed for Xamarin.Forms
Michael Ridland’s introduces us to his new MVVM framework for Xamarin.Forms.

FreshMvvm Quick Start Guide
Michael Ridland post will get you up and running on his new MVVM framework.

Xamarin: Xamarin.Studio 5.9 Enhancements
Craig Dunn, from Xamarin Inc., shows off the new fancy features of Xamarin Studio 5.9.

9 Months of the Weekly Xamarin Newsletter
I (Adam) can’t believe that I have been doing this for 9 months.

Taming The Android Activity, Part 2
Adam Kemp follows up with a second post on the Android Activity.

Xamarin.Forms Pages: MasterDetailPage
Paulo Ortins is at it again and this time he tackles the Master Detail Page in Xamarin.Forms.

Xamarin Components Directory Configuration
Matt Ward will get your components sorted out in this new post.

Android Tips: Hello AppCompatActivity, Goodbye ActionBarActivity
James Montemagno, from Xamarin Inc., touches on what’s new in 22.1 of AppCompat.

Xamarin Plugins
Mark Trinder goes through what a plugin is and how to make them.

 

Don't miss out! Subscribe Today

Do you blog about Xamarin? Get your blog in the newsletter. Email me at adam [at] adamjwolf.com.

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

May 15, 2015 4:56 GMT

Community Contributions You Won’t Want to Miss

Xamarin developers not only love building amazing mobile apps in C#, they also love helping the developer community at large. Whether through building great open-source libraries, components, and plugins or sharing their experience in forums, blog posts, and podcasts, our community consistently steps up to make development with Xamarin a pleasure. The links below will take you to some of our favorite content from our community over the past few weeks.

Podcasts

Great Community Posts

Tools & Frameworks

Xamarin.Forms

Thanks to these developers for sharing their knowledge and insight with the rest of the Xamarin community! If you have an article or blog post about developing with Xamarin that you’d like to share, please let us know by tweeting at @XamarinHQ.

The post Community Contributions You Won’t Want to Miss appeared first on Xamarin Blog.

May 14, 2015 4:00 GMT

Crafting 5 Star iOS Experiences With Animations

When I think about the iPhone apps I use the most, they all have one thing in common: they use custom animations to enhance the user experience. Custom animations provide an immersive experience, which can add a whole new element of enjoyment to your user experience.

iOS is jam-packed with beautiful and subtle animations, visible from the moment you unlock the phone. Subtlety is the key to delivering the best experience, as Apple is very clear that developers should avoid animations that seem excessive or gratuitous.

Original keynote design

With over 1.2 million apps on the iOS app store alone, if you want your app to get noticed, it needs to stand out from the crowd. The easiest way to do this is with a unique user interface that goes beyond the generic built-in controls and animations.

In this blog, I’m going to show you how you can easily prototype and add custom animations to your iOS apps. Before we get started on the technical details, it’s worth discussing a tip used by some of the best mobile app designers.

Prototype in Keynote or PowerPoint

It’s no secret that to create something that appears simple often requires a large amount of iteration to refine it to its simplest form. This is definitely the case when it comes to UI design and animation design. Many UX designers will use tools like Keynote or PowerPoint, which include built-in animations, for prototyping. During this part of the design process, you are free from thinking about the complexities of the implementation and can focus on the desired result. It’s a step in the design process I highly recommend to everyone who is creating custom animations and transitions. Below is an animation movie exported from Keynote, which you can use to compare to the final animation.

keynote designed animation
Implementation

Once you’ve designed your animations, you’ll need to start implementing them. Rest assured, though, as iOS has a fantastic animation API that makes the experiences very straight forward. You’ll most likely be reusing many of the animations you create across your app, which Apple actually recommends in the iOS human interface guidelines.

The implementation for your views rely on Apple’s Core Animation framework. This framework consists of a number of extremely powerful APIs that cater to different requirements. For example, you can create block, key frame, explicit, and implicit animations with Core Animation. Another option is to animate your views using UIKit, which is an approach I use a lot in Dutch Spelling.

For example, I change the position of a button as well as changing its visibility over .2 seconds.

 //Move button Asynchronously and fade out
 AnimateAsync(0.2, () =>
 {
     button.Frame = CalculatePosition(_buttonsUsedInAnswer.IndexOf(button));
     button.Alpha = 0.0f;
});

The snippet above deals with the button animation; below is a video of the animation running on a the device.

final animation
Another example from Dutch Spelling is shrinking views over time. I use this to draw attention to other visual elements within the UI.

//Shrink WordView Asynchronously and then set font.
public void ShrinkWord()
{
    var transform = CGAffineTransform.MakeIdentity();
    transform.Scale(1f, 1f);
    UIView.AnimateAsync(0.6, () =>
    {
        _word.Transform = transform;
        _title.TextColor = "3C3C3C".ToUIColor();
    });
    _word.Font = UIFont.FromName("Raleway-Regular", 32);
}

Further Reading

You can find more examples to help you get started building your own 5-star app animations in our Core Animation documentation here.

The post Crafting 5 Star iOS Experiences With Animations appeared first on Xamarin Blog.

May 14, 2015 4:24 GMT

Blurred Image Renderer for Xamarin.Forms

In response to a recent Xamarin forum post I spent some time building a custom Xamarin.Forms renderer for a blurred image on iOS and Android. Read on to learn how I did it.

The Problem

The request was to have a blurred image view on Android. Since this is Xamarin.Forms we may as well do it for iOS as well1. The ideal is to have a drop-in replacement for the Image view.

The end results look like this:

Android ScreenshotiOS Screenshot

Custom Image View

The first step is to create a custom subclass of the Image view class. We don't need any new properties so it's this easy:

public class BlurredImage : Image
{
}

iOS Renderer Implementation

I started out by trying a UIVisualEffectView. This is very easy to use, fast, and supports blurring any views (even dynamic ones), but it turned out not to match the desired results. It was too blurred, and also lightened or darkened the results. Not quite what we were after.

After some googling I came across this StackOverflow post that explains how to blur an image using CoreImage. That was exactly what I wanted. I just had to translate it to C#. Fortunately that's pretty easy. Here's the result:

private class BlurredImageView : UIImageView
{
public override UIImage Image
{
get { return base.Image; }
set
{
// This may take up to a second so don't block the UI thread.
Task.Run(() =>
{
using (var context = CIContext.Create())
using (var inputImage = CIImage.FromCGImage(value.CGImage))
using (var filter = new CIGaussianBlur() { Image = inputImage, Radius = 5 })
using (var resultImage = context.CreateCGImage(filter.OutputImage, inputImage.Extent))
{
InvokeOnMainThread(() => base.Image = new UIImage(resultImage));
}
});
}
}
}

I use this simple subclass of UIImageView in a simple subclass of the default ImageRenderer like so:

public class BlurredImageRenderer : ImageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
if (Control == null)
{
SetNativeControl(new BlurredImageView
{
ContentMode = UIViewContentMode.ScaleAspectFit,
ClipsToBounds = true
});
}

base.OnElementChanged(e);
}

// ... BlurredImageView class goes here
}

Android Renderer Implementation

For Android the core blurring routine came from this Xamarin recipe, which was found by the forum member making the request. That's easy enough to use, but unfortunately I hit a snag. The default ImageRenderer on Android is really poorly suited for subclassing. It uses an internal custom ImageView subclass, which means the trick I used in iOS for blurring the image as it's applied to the view won't work. Instead I had to basically copy all of the default code.

This is a good time to mention a trick that I've been using to learn how Xamarin.Forms works: The Xamarin Studio Assembly Browser. You can get to it by either using "Go to Declaration" on a class that's in Xamarin.Forms (or some other external assembly) or by finding an assembly in your project's list of references and double-clicking it. Once in the Assembly Browser I always immediately change the "Visibility" dropdown to "All Members" and the "Language" dropdown to "C#". Then I can basically see all of the source code (decompiled) of Xamarin.Forms. Using this technique you can learn a huge amount about how things work under the hood, diagnose bugs, find workarounds, etc.

In this case I needed to know how to reimplement my own version of the ImageRenderer class and insert my own step to blur the image. For that I just basically copied the whole thing.

Of course it's not quite that easy. The base implementation used some internal code that I don't have access to. First, the FormsImageView, which does some kind of optimization for skipping invalidation in some situations. For that I just had to make my own BlurredImageView that does the same thing and update code as necessary to use my view.

Next I had to deal with loading images. As I discovered in this post the actual classes involved in loading platform-specific image from an ImageSource are all public, but the nice convenience method for finding the right implementation and doing the load is internal. Therefore I had to write a quick implementation myself, much like the iOS implementation I had written:

IImageSourceHandler handler;

if (imageSource is FileImageSource)
{
handler = new FileImageSourceHandler();
}
else if (imageSource is StreamImageSource)
{
handler = new StreamImagesourceHandler(); // sic
}
else if (imageSource is UriImageSource)
{
handler = new ImageLoaderSourceHandler(); // sic
}
else
{
throw new NotImplementedException();
}

var originalBitmap = await handler.LoadImageAsync(imageSource, context);

Now I can load an image, but I still want to blur it. For that I just added to the above method:

var blurredBitmap = await Task.Run(() => CreateBlurredImage(originalBitmap, 25));
return blurredBitmap;

And the CreateBlurredImage method comes from the Xamarin recipe:

private Bitmap CreateBlurredImage(Bitmap originalBitmap, int radius)
{
// Create another bitmap that will hold the results of the filter.
Bitmap blurredBitmap;
blurredBitmap = Bitmap.CreateBitmap(originalBitmap);

// Create the Renderscript instance that will do the work.
RenderScript rs = RenderScript.Create(Context);

// Allocate memory for Renderscript to work with
Allocation input = Allocation.CreateFromBitmap(rs, originalBitmap, Allocation.MipmapControl.MipmapFull, AllocationUsage.Script);
Allocation output = Allocation.CreateTyped(rs, input.Type);

// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.Create(rs, Android.Renderscripts.Element.U8_4(rs));
script.SetInput(input);

// Set the blur radius
script.SetRadius(radius);

// Start Renderscript working.
script.ForEach(output);

// Copy the output to the blurred bitmap
output.CopyTo(blurredBitmap);

return blurredBitmap;
}

The next problem was the use of an internal field of the Image class for setting an otherwise read-only property: the IsLoading property. The only workaround for this, unfortunately, is reflection. For that I added this code:

private static FieldInfo _isLoadingPropertyKeyFieldInfo;

private static FieldInfo IsLoadingPropertyKeyFieldInfo
{
get
{
if (_isLoadingPropertyKeyFieldInfo == null)
{
_isLoadingPropertyKeyFieldInfo = typeof(Image).GetField("IsLoadingPropertyKey", BindingFlags.Static | BindingFlags.NonPublic);
}
return _isLoadingPropertyKeyFieldInfo;
}
}

private void SetIsLoading(bool value)
{
var fieldInfo = IsLoadingPropertyKeyFieldInfo;
((IElementController)base.Element).SetValueFromRenderer((BindablePropertyKey)fieldInfo.GetValue(null), value);
}

With that code in place I just had to do some simple substitutions to make the rest of the code compile and run. The rest of the code isn't all that interested so I've left it out, but for the complete source see the GitHub project.

Caveats

The Android implementation is brittle because it duplicates code from the base implementation, and it uses reflection.

That's it! Check out the GitHub project. Enjoy!


  1. I don't know how to do it for Windows Phone or WinRT, but pull requests are welcome! 

May 13, 2015 4:33 GMT

RSVP for Xamarin’s Google I/O 2015 Party

Join the Xamarin team on May 27th at Southside Spirit House from 7-10pm to kick off Google I/O!

Google I/O

Spend the night before Google I/O with the Xamarin Team and fellow mobile developers and check out the Xamarin Test Cloud wall in person to see how easy mobile testing can be.

Xamarin Test Cloud Wall

When: Wednesday, May 27th, 7pm–10pm
Where: Southside Spirit House, 575 Howard St, San Francisco, CA, 94105

RSVP

In the Bay Area but not attending Google I/O? Stop by anyway! You and your friends are welcome. Make the most of your time at Google I/O and schedule dedicated time with the Xamarin team while you’re in town for the conference. We’d love to meet you, learn about your apps and discuss ways we can help.

The post RSVP for Xamarin’s Google I/O 2015 Party appeared first on Xamarin Blog.

May 13, 2015 1:03 GMT

Aka Awesome Refactored

In the last post we talked about Akavache and frankly how awesome it is. In this post we’re going to take a simple Xamarin Forms application which uses a “home grown” caching mechanism and refactor it into one which uses Akavache. We’ll see how much simpler and more elegant Akavache makes our code and also check out some design considerations for using Akavache along the way.

Why Refactor?

We already have a working application, why even bother refactoring in the first place? Plain and simply, why should we reinvent the wheel? If we can swap out our (probably buggy) code for a framework which has been tested by the community, has more features, and has been thought out and designed for the sole purpose of caching – we’d be dumb not to use it.

Plus when integrated, Akavache makes our code cleaner and more reliable … and who doesn’t like that?

What We’re Refactoring

The quick overview:
In the Cold Hard Data Caching post, we wrote a Xamarin Forms application that downloaded questions from StackOverflow tagged with the keyword Xamarin and displayed those questions in a ListView. Tapping on a question displayed another page with either the answer or a ‘no answer found’ placeholder. We used a homegrown caching mechanism in the previous version and we’ll be upgrading to Akavache.

The detailed specs:

  • Xamarin Forms app
  • Show a ListView of dates for the last 14 days
  • Tapping on a day shows a ListView of questions from StackOverflow from that day tagged with “Xamarin”
  • Questions should be cached when downloaded
  • Stack Overflow should be queried for any new questions asked for a given day since the last time the cache was updated
  • Expire questions from cache in 7 days
  • Show date and time when question was downloaded from StackOverflow
  • When question row tapped: download, cache and display an answer on new screen. There will only ever be a single answer per question, so if an answer is found in cache, no need to check internet

Let’s Refactor!

If you’d like to follow along with the code, you can find the 2 solutions on GitHub here:

Before refactoring: StackCache
After refactoring: AkaAwesome

First let’s prep our existing project to use Akavache.

  1. While not required, we can get rid of the SQLite.Net references. Obviously you would only do this if you’re not using SQLite.NET elsewhere in your app.
  2. Next, we can remove any classes whose specific purpose is to perform SQLite database management. Such as a class which inherits from a SQLiteConnection object or manages the connection. Also, any platform specific code which sets things such as the location of the database file can be removed as well.
  3. Finally we’re going to add Akavache via NuGet. If you remember from the last post, first we want to add the Akavache.SQLite3 package, and then the Akavache package, in order for the dependencies to resolve properly.

Now let’s look at actually doing the refactoring. Our app is made up of 3 pages:

  1. Page with ListView of dates from previous 2 weeks
  2. Page with ListView of questions from each of those dates
  3. Page with a given answer’s detail for each of those questions

There’s no caching involved in the first screen, no refactoring there. But there’s definitely some with the next 2 screens. Let’s look at the easier of the two first.

Answer Detail Screen Refactor

This page receives an integer representing the Question’s Id, and then uses that to either load it from the cache, or download it from StackOverflow.

The original method to load/display the answer looks like this:

protected async Task LoadAnswer (int questionId)
{   
    AnswerInfo currentAnswer = null;

    // 1. Load from the database
    currentAnswer = await App.StackDataManager.Database.GetAnswerForQuestion (questionId);

    if (currentAnswer != null) {
        _theAnswer.AnswerID = currentAnswer.AnswerID;
        _theAnswer.QuestionID = currentAnswer.QuestionID;
        _theAnswer.AnswerBody = currentAnswer.AnswerBody;
    } else {
        // 2. No database record... Load answer from the web            
        var answerAPI = new StackOverflowService ();

        var downloadedAnswer = await answerAPI.GetAnswerForQuestion (questionId);

        if (downloadedAnswer != null) {             
            _theAnswer.AnswerID = downloadedAnswer.AnswerID;
            _theAnswer.QuestionID = downloadedAnswer.QuestionID;
            _theAnswer.AnswerBody = downloadedAnswer.AnswerBody;

            // 3. Save the answer for next time
            await App.StackDataManager.Database.SaveAnswer (_theAnswer);

        } else {                    
            _theAnswer.AnswerBody = "No answer found";
        }
    }
}

To truly show how much code there is involved here, below are the 2 database functions invoked to support the caching:

public async Task<AnswerInfo>GetAnswerForQuestion (int questionId)
{
    return await Table<AnswerInfo> ().Where (ai => ai.QuestionID == questionId).FirstOrDefaultAsync ().ConfigureAwait (false);
}

public async Task SaveAnswer (AnswerInfo answer)
{
    int answerId = answer.AnswerID;

    var dbRecord = await Table<AnswerInfo> ()
        .Where (ai => ai.AnswerID == answerId)
        .FirstOrDefaultAsync ().ConfigureAwait (false);

    if (dbRecord == null)
        await InsertAsync (answer).ConfigureAwait (false);
    else
        await UpdateAsync (answer).ConfigureAwait (false);
}

That’s a fair amount of code, and a fair amount of room to introduce bugs … Let’s add some Akavache awesomeness to make it a whole lot more succinct.

Design Considerations

Since Akavache is a key/value store – we first must consider what we want to use for our key and what we want to use for our value.

In this case that’s pretty straight forward. The answer retrieval from StackOverflow is based on passing in a QuestionId, it only makes sense to use that as our key. Likewise, the value portion is straight forward as well, we’ll just put the AnswerInfo object that we’re displaying in there.

Next we have to figure out which of the functions that Akavache provides that we’ll want to make use of.

GetOrFetchLatest
seems like an ideal candidate here. That function will either pull the object out of the cache, or execute a passed in function whose responsibility it is to return an object. Akavache will then put that object into the cache with the corresponding key originally passed int.

Let’s take a look at our refactored code:

protected async Task LoadAnswer (int questionId)
{   
    AnswerInfo currentAnswer = await BlobCache.LocalMachine.GetOrFetchObject<AnswerInfo>(
        _questionId.ToString(),
        async() => await new StackOverflowService().GetAnswerForQuestion(questionId),
        DateTime.Now.AddDays(7)
    );
        
    if (currentAnswer != null) {
        _theAnswer.AnswerID = currentAnswer.AnswerID;
        _theAnswer.QuestionID = currentAnswer.QuestionID;
        _theAnswer.AnswerBody = currentAnswer.AnswerBody;
    } else {
        // Nothing found on the web or in the cache - so invalidate the cache - don't want null stored
        await BlobCache.LocalMachine.InvalidateObject<AnswerInfo> (_questionId.ToString ());

        _theAnswer.AnswerBody = "No answer found on StackOverflow or in cache";
    }               
}

That’s it. All of our original code is refactored just into those couple of lines. The database CRUD operations and invocation of the API to download the StackOverflow answer is taken care of by Akavache in lines 4-8. The rest of the function just takes care of display.

One thing to note is that we immediately call

InvalidateObject
if the answer from StackOverflow API comes back as null. This deletes the key/value pair from the cache. This way we don’t store a null value with the key in the cache, thus making sure the key doesn’t exist in the cache and we always invoke the passed in function.

Question List Screen Refactor

This page receives a date value which it then uses to query the cache or StackOverflow for the questions asked on that date.

In addition, on this page we’re also always downloading the questions from a given day and adding “new” questions to the display and also to the cache. This way if the user views the questions at noon, and then again at 7 PM, they’ll get all the questions asked in the interim.

The original function to load and display the questions:

protected async Task LoadQuestions ()
{
    _displayQuestions.Clear ();

    // 1. Get rid of anything too old for the cache
    await App.StackDataManager.Database.DeleteQuestionsAndAnswers ();

    // 2. Load up cached questions from the database
    var databaseQuestions = await App.StackDataManager.Database.GetQuestions (_dateToDisplay);

    foreach (var item in databaseQuestions) {
        _displayQuestions.Add (item);
    }

    try {
        // 4. Load up new questions from web
        var questionAPI = new StackOverflowService ();
        var downloadedQuestions = await questionAPI.GetQuestions (_dateToDisplay);

        // 5. See which questions are new from web and only add those to the display and cache
        foreach (var question in downloadedQuestions) {
            if (_displayQuestions.Contains (question) == false) {
                _displayQuestions.Insert (0, question);

                // 6. Save the new question to the cache
                await App.StackDataManager.Database.SaveQuestion (question);
            }
        }

    } catch (NoInternetException) {
        await HandleException ();
    }
}

The database functions which provide the caching:

public async Task<IList<QuestionInfo>>GetQuestions (DateTime dateToDisplay)
{
    var topDate = dateToDisplay.AddDays (1);

    return await Table<QuestionInfo> ().Where (qi => 
        qi.InsertDate > dateToDisplay &&
        qi.InsertDate < topDate
    ).ToListAsync ().ConfigureAwait (false);            
}

public async Task SaveQuestion (QuestionInfo question)
{
    int questionId = question.QuestionID;

    var dbRecord = await Table<QuestionInfo> ()
        .Where (qi => qi.QuestionID == questionId)
        .FirstOrDefaultAsync ().ConfigureAwait (false);

    if (dbRecord == null) {
        question.InsertDate = DateTime.Now;
        await InsertAsync (question).ConfigureAwait (false);
    } else {
        question.InsertDate = dbRecord.InsertDate;
        await UpdateAsync (question).ConfigureAwait (false);
    }
}

public async Task DeleteQuestionsAndAnswers ()
{
    DateTime cutOff = DateTime.Now.AddDays (-7);

    var oldQuestions = await Table<QuestionInfo> ().Where (qi => qi.InsertDate < cutOff).ToListAsync ().ConfigureAwait (false);

    foreach (var item in oldQuestions) {
        var questionId = item.QuestionID;

        var oldAnswers = await Table<AnswerInfo> ().Where (ai => ai.QuestionID == questionId).ToListAsync ().ConfigureAwait (false);

        foreach (var oa in oldAnswers) {
            var answerId = oa.AnswerID;
            await DeleteAsync<AnswerInfo> (answerId);
        }

        await DeleteAsync<QuestionInfo> (questionId);
    }
}

Wow – that’s a lot of code … and a lot of places for bugs to creep in! Let’s sprinkle some Akavache awesomeness on it!

Design Considerations

Again we need to decide on what we’re going to use for our key/value pair. Since the page is getting a date in the constructor, it seems natural to use that as the key. In this case, we’re going to use the Ticks value of date.

As for the value – again straight forward. We’re displaying a list of QuestionInfo objects, may as well store a

List<QuestionInfo>
as the value!

Since we need to not only grab data from the cache if it exists, but also always retrieve the latest data and add it to the cache, we should use the

GetAndFetchLatest
function.

If you remember from the previous post, this function will return anything in the cache matching the passed in key. It also always executes the passed in function to get the latest data. It will then update the cache and return that updated data. That means this function can return more than once, so we cannot

await
it, rather we’ll have to employ the
Subscribe
function.

All of the code above refactors into the following:

protected void LoadQuestions ()
{           
    BlobCache.LocalMachine.GetAndFetchLatest<IList<QuestionInfo>> (
        _dateToDisplay.Ticks.ToString (),
        async () => await new StackOverflowService ().GetQuestions (_dateToDisplay),
        null,
        _dateToDisplay.AddDays (7)
    ).Catch (Observable.Return (new List<QuestionInfo> ())).Subscribe (
        returnedQuestions => {
            Device.BeginInvokeOnMainThread (() => DisplayQuestions (returnedQuestions));
        }
    );          
}

private void DisplayQuestions (IList<QuestionInfo> questions)
{
    foreach (var item in questions) {
        if (!_displayQuestions.Contains (item)) {
            _displayQuestions.Insert (0, item);
        }
    }
}

Seriously, that’s all there is. All of the plumbing to implement caching from the first example has been whittled down to just a couple of lines.

The

Subscribe
function gets called every time the underlying observable collection (in this case a list of QuestionInfo objects) gets updated. From there, we update the UI.

Database, function to invoke StackOverflow, error handling, UI updating – all together.

Talk about elegant!

Conclusion

When we implement caching in our applications, we have to write a lot of code to implement it that has nothing to do with the core functionality of our application. That could introduce a lot of bugs. However, by using a framework such as Akavache to perform the caching for us, we are able to reduce the amount of code significantly and also reduce the possibility of bugs significantly as well. Not only that – our code becomes much more succinct and elegant as well.

May 13, 2015 12:00 GMT

Xamarin.Forms in Anger – Hot Sauce

Call me a cheater, I deserve it, especially for this post. Yes, this UI is made from plain, out of the box, Xamarin.Forms. Without looking at the code, can you tell how I did it?

Let me give you a hint. The UI is made of a CarouselPage, ContentPages, RelativeLayouts, StackLayouts, Images, Labels and nothing else. Still stumped? Well, the secret is in the sauce. Come on, I had to use that one!

HoSauceUI

The secret sauce is a specially designed overlay image. The center of the image is 100% transparent. Shadows and gradients make the transparent center actually look like a white card placed above the blue background. This illusion tricks your eye into believing that anything placed underneath the overlay is actually on top of the card. Don’t you just love shadows!

 

Overlay

 

The trickiest bit of this overlay technique comes from small size devices. Larger phones work well but small phones like the iPhone 4s can be a challenge. The limited real-estate and the need for scrolling can make this large single card UI difficult. Breaking the overlay up into top and bottom images can help.

A couple of people have asked me if I could create a card like UI in Xamarin.Forms. I know this is not exactly what they had in mind but it is a powerful technique in negative or subtractive thinking. It’s only with the removing of the center was I able to get the desired outcome. Normally I think about adding elements to the UI so this example was a bit of a stretch for me.

The Code

There is nothing really new in the code. It’s pretty pedestrian. It’s so simple you might want to try it out inside other controls. Like a ListView.

public SaucePage (Sauce sauce)
{
	var layout = new RelativeLayout ();

	var overlay = new Image () {
		Aspect = Aspect.AspectFill,
		Source = new FileImageSource () { File = "Overlay.png" }
	};

	var picture = new Image () {
		Aspect = Aspect.AspectFill,
		Source = new FileImageSource () { File = sauce.FileName }
	};

	var name = new Label () {
		Text = sauce.Name, 
		FontSize = 30, 
		TextColor = Color.FromHex ("#FF6600"),
		FontFamily = Device.OnPlatform ("HelveticaNeue-Medium", "sans-serif", "")
	};

	var tagline = new Label () { Text = sauce.Tagline };

	var scovilleLabel = new Label () {
		Text = "SCOVILLE UNITS:", 
		FontSize = 15, 
		TextColor = Color.FromHex ("#B7A19B"),
		FontFamily = Device.OnPlatform ("HelveticaNeue-CondensedBlack", "sans-serif-condensed", "")
	};

	var scoville = new Label () {
		Text = sauce.Heat, 
		FontSize = 20, 
		FontFamily = Device.OnPlatform ("HelveticaNeue", "sans-serif", "")
	};

	var details = new StackLayout () {
		Spacing = 10,
		Padding = new Thickness (50, 10),
		HorizontalOptions = LayoutOptions.StartAndExpand,
		Children = {
			name,
			tagline,
			scovilleLabel,
			scoville,
		}
	};

	layout.Children.Add (
		picture,
		Constraint.Constant (0),
		Constraint.Constant (0),
		Constraint.RelativeToParent ((parent) => {
			return parent.Width;
		}),
		Constraint.RelativeToParent ((parent) => {
			return parent.Height * .5;
		})
	);

	layout.Children.Add (
		details,
		Constraint.Constant (0),
		Constraint.RelativeToParent ((parent) => {
			return parent.Height * .5;
		}),
		Constraint.RelativeToParent ((parent) => {
			return parent.Width;
		}),
		Constraint.RelativeToParent ((parent) => {
			return parent.Height;
		})
	);

	layout.Children.Add (
		overlay,
		Constraint.Constant (0),
		Constraint.Constant (0),
		Constraint.RelativeToParent ((parent) => {
			return parent.Width;
		}),
		Constraint.RelativeToParent ((parent) => {
			return parent.Height;
		})
	);

	Content = layout;
}

I hope you enjoyed this tricky Xamarin.Forms in Anger post. Rounding up all the hot sauce images and colors was a lot of fun. The Tabasco website deserves all the credit. Till next time, grab the code from GitHub and try some hot sauce for yourself. I suggest putting it on burritos.

Xamarin.Forms in Anger Series

Can Xamarin.Forms produce good looking cross-platform UI from a single codebase? Each “In Anger” blog post will tackle a single page of a beautifully designed iOS or Android application. My job will be to reproduce the design in Xamarin.Forms as faithfully as possible. InAnger-Strip-6

The post Xamarin.Forms in Anger – Hot Sauce appeared first on Syntax is my UI.

May 13, 2015 12:38 GMT

Coffee. It's pretty damn good for you

(Photo: nitro cold brew from Espresso Workshop in Britomart)

Huge meta-analysis. 1.2 million people, 35-odd studies.

But it’s way past time that we stopped viewing coffee as something we all need to cut back on. It’s a completely reasonable addition to a healthy diet, with more potential benefits seen in research than almost any other beverage we’re consuming. It’s time we started treating it as such.

Note, however, they are talking about straight, black coffee - ☕️. No added milk or sugar.

Of course, everything I’m saying here concerns coffee — black coffee. I am not talking about the mostly milk and sugar coffee-based beverages that lots of people consume. These could include, but aren’t limited to, things like a McDonald’s large mocha (500 calories, 17 grams of fat, 72 grams of carbohydrates), a Starbucks Venti White Chocolate Mocha (580 calories, 22 grams of fat, 79 grams of carbs), and a Large Dunkin’ Donuts frozen caramel coffee Coolatta (670 calories, 8 grams of fat, 144 grams of carbs).

So:

  • Reduced stroke
  • Lower risk of heart failure
  • Lower general risk of cancer, especially liver.
  • Speaking of the liver: it's great, if you have liver disease - Hep C or cirrhosis.
  • Lower risk of Parkinsons and general cognitive decline.
  • Lower risk of Type 2 Diabetes - even if you just drink decaf.

The studies say "2-6 cups of coffee" is the sweet spot, which according to Google is around 200 to 600mg of caffeine - or around 3-8 espresso', which is quite a bit by even my standards.

So, time for a ☕️ then?


Yes, I just wanted to use the ☕️ emoji a bit :) Appears I can't use it in the title of the post tho - shows up in some places but not others.

May 12, 2015 6:59 GMT

A Scalable Introduction to Vector Drawables

lollipopAmong the many novelties brought to Android in 5.0 Lollipop, vector drawables are one of my favorite additions. They manage to both solve one of the oldest Android pain points (wide range of screen densities) and also pave the way for much better interactions in our apps.

Introduction to Vector Drawables

What exactly are vector drawables? As their name implies, vector drawables are based on vector graphics, as opposed to raster graphics.

Developers should already be familiar with raster graphics in the assortment of PNG, JPEG, and other image files that populate your Android apps.

android-rasterizationRaster graphics describe (in some encoded form) the actual color value of each pixel of an image, whereas vector graphics contain the recipe, via a series of draw commands, to create the desired result.

To display that recipe on a screen, the system converts it back at run-time to the same pixel data that it would have gotten from a bitmap file through a process called rasterization.

With Android Lollipop, the recipes that make vector drawables are directly written in an XML format very much like their older cousins, shape drawables.

Both vector drawables and shape drawables share the same core benefit of being rendered on-demand by the system, and thus always at the right resolution. As such, contrary to other bitmap-based images, they don’t need to have extra variations based on screen-densities.

Indeed, where the world was happily spread between LDPI, MDPI and HDPI a few years ago, today we just don’t know how many ‘x’ will be able to fit in front of ‘HDPI’ (at the time of this writing we have reached XXXHDPI).

Additionally, like any other drawable, vector drawables are natively understood by the Android toolchain, which makes their use as seamless as feasible (i.e. you can reference them in layouts, styles, acquire them through Resources.GetDrawable, etc.).

But let’s see an example of what a vector drawable looks like in all its XML glory:

<?xml version="1.0" encoding="utf-8" ?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
	android:height="96dp"
	android:width="96dp"
	android:viewportHeight="48"
	android:viewportWidth="48" >
	<group>
		<path
			android:fillColor="@color/black_primary"
			android:pathData="M12 36l17-12-17-12v24zm20-24v24h4V12h-4z" />
	</group>
</vector>

This example draws this well known media player action icon:

Skip Next

The format of the XML file is voluntarily modeled after another existing vector graphics file format (of which it shares the same path expression syntax): SVG.

This means that you can fairly easily reuse any SVG you might have (or that your graphic editor can produce) by massaging it into an Android vector drawable.

Motion with Animated Vector Drawables

Because vector drawables describe a recipe of what you want displayed on the screen, it’s very easy to modify this recipe on the fly to provide a wide range of effects, including animated vector drawables (represented by the AnimatedVectorDrawable type).

If you look back at the XML source of the media player icon, you may have noticed that our path element is actually contained inside another element called a group.

For the sake of displaying the vector drawable, this is not a very interesting element. But if you look at the following list of valid XML attributes that can be set on a group element, you should see something emerging: rotation, scaleX, scaleY, translateX, translateY.

Indeed, you probably recognized that those are the same attributes we use to manipulate our View instances when animating them.

Animated vector drawables are actually more of a meta-type, bridging several other pieces together much like state-list drawables (and like the latter, they are also drawables themselves).

Animated vector drawables are declared using the <animated-vector/> element:

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
	android:drawable="@drawable/bluetooth_loading_vector" >
	<target
		android:name="circleGroup"
		android:animation="@anim/circle_expand" />
	<target
		android:name="circlePath"
		android:animation="@anim/circle_path" />
</animated-vector>

The first thing you need to tie in is which vector drawable the animated version is going to use as a base, which is set in the android:drawable attribute at the top level.

The rest of the file contains several different <target/> elements. These set up which animations are run and which part of the vector drawable they run.

Using animated vector drawables and a widget like ProgressBar means you can quickly and easily build rich spinners like this one:



Powerful Transitions

When I sat down at I/O last year and saw the introduction of Material design, I was highly skeptical of animated transitions.

James and discussed this during our Material Design session at Xamarin Evolve 2014. At the time of the talk, the only facility we had been given to do animated transitions was through keyframe animations, which are incredibly clunky to maintain.

Thankfully, the introduction of vector drawables, along with the addition of a specialized evaluator allowing path morphing, changed all of this.

The new evaluator is able to understand the path definition used by a vector drawable and create intermediary versions of it. This means that given two specific paths for a vector drawable, we can use an object animator to not only animate transformations or styles as outlined above, but also the actual pathData of the vector itself.

Now before you get too excited, it’s not a miracle evaluator. There are two very strong requirements for it to work properly:

  • The path command list needs to be of the same size
  • Each command in that list needs to be of the same type

Basically, the evaluator treats the path data as an array of floats extracted from each command parameter and uses that to interpolate different paths in between.

Thanks to this and the new animation aware AnimatedStateListDrawable class, it’s very easy to create nice state transitions like this play/pause interaction:



The transition is defined in an XML file much like a traditional state list drawable, with the addition of a section declaring the motion that happens between the various state changes:

<animated-selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="true">
    <item
        android:drawable="@drawable/ic_pause"
        android:state_checked="true"
        android:id="@+id/pause_state" />
    <item
        android:drawable="@drawable/ic_play"
        android:id="@+id/play_state" />
	<transition android:fromId="@id/play_state" android:toId="@id/pause_state" android:reversible="true">
		<animated-vector android:drawable="@drawable/ic_play">
			<target android:name="d" android:animation="@anim/play_pause" />
		</animated-vector>
	</transition>
</animated-selector>

Since the framework also keeps track of the animation running for you, you don’t have to worry that any form of lifecycle animation will be scheduled or canceled automatically.

Using the same transition facilities, you can also build more complicated interactions involving a stage-like approach like this one:



Compatibility Considerations

As of now, vector drawables are still a Lollipop-specific feature. However, there have been signs that the support library will soon add support for vector drawables, likely announced in time for this year’s Google I/O conference.

It’s not clear if the more advanced animations capabilities will be supported, but basic rendering will still allow developers to use a scalable image format across most API levels, which is a great start.

Further Reading

I kept this blog short to give a very broad overview of what vector drawables are and how they can be used. For more information (including more details on how all of these new pieces fit together), I encourage you to read my previous posts on the subject:



Yep, you can even do cats

The post A Scalable Introduction to Vector Drawables appeared first on Xamarin Blog.

May 12, 2015 10:42 GMT

FreshMvvm Quick Start Guide

FreshMvvm is designed to be easy and simple. So getting started is also fairly simple.

Step 1. Start new project

Start a new Xamarin.Forms Project using Portable Class Libraries.

Step 2. Obtain FreshMvvm from Nuget

Obtain FreshMvvm from Nuget by searching for FreshMvvm, make sure to do this on your Xamarin.Forms PCL project.

Step 3. Create QuoteList Page

Once you’ve got the packages you can then create your first Page and PageModel. In the Xamarin.Forms PCL project, let’s create a QuoteListPage.xaml and corresponding QuoteListPageModel.cs.

QuoteListPage.xaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<BasePage xmlns="http://xamarin.com/schemas/2014/forms" 
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        x:Class="FreshMvvmSampleApp.QuoteListPage">
    <BasePage.Content>
        <ListView ItemsSource="{Binding Quotes}" SelectedItem="{Binding SelectedQuote}"  >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding Total}" Detail="{Binding CustomerName}"></TextCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </BasePage.Content>
</BasePage>

QuoteListPageModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[ImplementPropertyChanged] // uses fody for property changed
public class QuoteListPageModel : FreshBasePageModel
{
    IDatabaseService _databaseService;
 
    public QuoteListPageModel (IDatabaseService databaseService) // injected from IOC
    {
        _databaseService = databaseService;
    }
 
    public ObservableCollection<Quote> Quotes { get; set; }
 
    public override void Init (object initData)
    {
        Quotes = new ObservableCollection<Quote> (_databaseService.GetQuotes ());
    }
 
    // Methods are automatically wired up to page
    protected override void ViewIsAppearing (object sender, System.EventArgs e)
    {
        CoreMethods.DisplayAlert ("Page is appearing", "", "Ok");
        base.ViewIsAppearing (sender, e);
    }
 
    protected override void ViewIsDisappearing (object sender, System.EventArgs e)
    {
        base.ViewIsDisappearing (sender, e);
    }
 
    // This is called when a page id pop'd
    public override void ReverseInit (object value)
    {
        var newContact = value as Quote;
        if (!Quotes.Contains (newContact)) {
            Quotes.Add (newContact);
        }
    }
 
    public Command AddQuote {
        get {
            return new Command (async () => {
                await CoreMethods.PushPageModel<QuotePageModel> ();
            });
        }
    }
 
    Quote _selectedQuote;
 
    public Quote SelectedQuote {
        get {
            return _selectedQuote;
        }
        set {
            _selectedQuote = value;
            if (value != null)
                QuoteSelected.Execute (value);
        }
    }
 
    public Command<Quote> QuoteSelected {
        get {
            return new Command<Quote> (async (quote) => {
                await CoreMethods.PushPageModel<QuotePageModel> (quote);
            });
        }
    }

Step 4. Create Quote Page

We will also need a page which shows the details of a quote. So we can create a QuotePage.xaml and a corresponding QuotePageModel.cs.

QuotePage.xaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<BasePage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="FreshMvvmSampleApp.QuotePage">
    <BasePage.Content>
        <StackLayout Padding="15">
            <Label Text="Quote Amount" ></Label>
            <Entry Text="{Binding Quote.Total}"></Entry>
            <Label Text="Customer Name" ></Label>
            <Entry Text="{Binding Quote.CustomerName}"></Entry>
            <Button Text="Save" Command="{Binding SaveCommand}"></Button>
            <BoxView HeightRequest="30"></BoxView>
            <Button Text="Test Modal" Command="{Binding TestModal}"></Button>
        </StackLayout>
    </BasePage.Content>
</BasePage>

QuotePageModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[ImplementPropertyChanged]
public class QuotePageModel : FreshBasePageModel
{
    IDatabaseService _databaseService;
 
    public Quote Quote { get; set; }
 
    public QuotePageModel (IDatabaseService databaseService)
    {
        _databaseService = databaseService;
    }
 
    public override void Init (object initData)
    {           
        Quote = initData as Quote;
        if (Quote == null)
            Quote = new Quote ();
    }
 
    public Command SaveCommand {
        get {
            return new Command (async () => {
                _databaseService.UpdateQuote (Quote);
                await CoreMethods.PopPageModel ();
            });
        }
    }
 
    public Command TestModal {
        get {
            return new Command (async () => {
                await CoreMethods.PushPageModel<ModalPageModel> (null, true);
            });
        }
    }
}

 Step 5. Setup Navigation

You have the options of using a built-in navigation or implement your own.

With the built in navigation items you have the options of:

  1. FreshNavigationContainer – Which is a basic navigation with push and pop

  2. FreshMasterDetailNavigationContainer – Use for a master detail style app

  3. FreshTabbedNavigationContainer – User for a tabbed style app

  4. For some thing more complex you can implement IFreshNavigationService

In this sample we can use a tabbed style app. In your Xamarin.Forms PCL open your App.cs and in the constructor add the following code.

1
2
3
4
5
var tabbedNavigation = new FreshTabbedNavigationContainer ();
 
tabbedNavigation.AddTab<ContactListPageModel> ("Contacts", null);
 
MainPage = tabbedNavigation;

And that’s it, we now have made the first steps to implementing FreshMvvm. If you wanted a different Navigation style then you could use one of the other types of built in Navigation or even implement your own.

The great sample project similar to this can be found in the sample directory on the project.

https://github.com/rid00z/FreshMvvm

 

The post FreshMvvm Quick Start Guide appeared first on Michael Ridland.

May 11, 2015 7:43 GMT

Xamarin.Studio 5.9 Enhancements

Our latest release of Xamarin Studio includes many great new features, including a new wizard to walk you through creating projects, a new publishing workflow to simplify publishing, archiving, and code signing, fancy new debugger visualizers, support for C# 6, and much more!

New Project Dialog

The File > New experience has been completely redesigned to make it easier to find the right template for your app, and easier to configure the various options available in each template.

The wizard walks you through platform selection, language selection (such as F#), Android API levels, and platform support in Xamarin.Forms. It’s also easier to add a WatchKit or Android Wear app to your solution.

Debugger Visualizers

The debugging experience is even more interactive with a number of new visualizers for various types including strings, points, sizes, rectangles, colors, map locations, images, bézier curves, and more. Hover over an instance during debugging and click the “eye” icon to preview:

visualizers

C# 6

Even though C# 6 support isn’t “officially” in Visual Studio until 2015 is released, you can already use C# 6 features in Xamarin apps. Here are a couple of examples of the new syntax:

// Null-Conditional operator
var mip = name?.Substring(' ');
// Auto-Property initializer
public DateTime TimeStamp { get; } = DateTime.UtcNow;
// nameof
throw new ArgumentException ("Not found",nameof(Key));
// Expression Bodied properties and methods
public string Fullname => string.Format ("{0} {1}", fname, lname);
public override string ToString() => string.Format("{0}, {1}", lname, fname)
// String interpolation
var Fullname = string.Format ($"{fname} {lname}");

You can also use the new dictionary initializer syntax, exception filters, async/await in the catch block, and static using statements.

To learn more about new C# 6 features check out this video by Mads Torgersen, Language PM for C#:

Sketches

If you haven’t played with Sketches before, now is the time to give it a try with these great new features.

Sketches1

It’s much easier to add resources like images to your Sketch, and Xamarin.Forms support is also improved. Follow along with our Sketches walkthrough to give it a try.

New Publishing Workflow

There is now a more consistent approach for publishing apps across iOS, Android, and Mac projects. Select Archive for Publishing for the project to create a binary in the archive list.

Once the binary has been created choose Sign and Distribute… then follow the publishing steps, which are customized for each platform.

publish-distribution (1)

And much more…

You’ll notice lots of other changes too, like the new Mac-native title bar, the Packages folder always appearing in the Solution Explorer, configurable Components location, lots of iOS Designer improvements, and the Release Notes are available from the Help menu instead of popping up automatically after installation!

You can discuss these new features in the Xamarin Studio forum, and be sure to read through the full release notes in the Xamarin developer portal.

The post Xamarin.Studio 5.9 Enhancements appeared first on Xamarin Blog.

May 11, 2015 12:52 GMT

FreshMvvm – A Mvvm Framework designed for Xamarin.Forms

Now available via Nuget FreshMvvm is a Mvvm framework that’s designed specifically for Xamarin.Forms. The reason I say it’s designed for Xamarin.Forms is because it plays on Xamarin.Forms strengths and fills in ONLY the missing parts. It has a requirement for Xamarin.Forms and therefore is smart and can do thing such as wiring up the BindingContext and Page events.

Some of the feature for FreshMvvm include:

  • PageModel to PageModel Navigation

  • Automatic wiring of BindingContext

  • Automatic wiring of Page events (eg appearing)

  • Basic methods on PageModel (init, reverseinit)

  • Built in IOC Container

  • PageModel Constructor Injection

  • Basic methods available in Model, like Alert

  • Built in Navigation containers for SimpleNavigation, Tabbed and MasterDetail

How does it compare to other Mvvm options?

  • It’s super light and super simple

  • It’s specifically designed for Xamarin.Forms, nothing else does this currently

  • Designed to be easy to learn and develop (great when your not ready for RxUI)

  • Uses a Convention over Configuration

The Story

I was part-way into a Xamarin Traditional application when Xamarin.Forms was released. I wanted to move the project onto Xamarin.Forms but on that project I was using MvvmCross. At that time MvvmCross had no support for Xamarin.Forms, so I had the option of 1) adapting MvvmCross, 2) finding an alternative or 3) rolling my own Mvvm. The best part about MvvmCross was it’s two-way databinding to the native iOS/Android controls but since Xamarin.Forms already had the Databinding builtin, that wasn’t useful and the size with MvvmCross was an overhead when I didn’t require it. I also wasn’t able to find an alternative that I could easily move to. So that I could keep it simple and flexible, I ended up rolling my own Mvvm.

It’s grown up from this post on rolling your own Mvvm for Xamarin.Forms. I try hard to keep the simplicity of rolling your own Mvvm for Xamarin.Forms.

It was never a plan to create a framework but after presenting my Mvvm solution at a few events, I found many people wanted it and seemed to be really interested in it. Also considering I’ve been using this Framework in all my projects from the start of Xamarin.Forms I know that it works, so I created FreshMvvm and that’s how it was born.

Conventions

This Framework, while simple, is also powerful and uses a Convention over Configuration style.

Note Different to standard naming conventions, FreshMvvm uses Page and PageModel instead of View and ViewModel, this is inline with Xamarin.Forms using Pages

  • A Page must have a corresponding PageModel, with naming important so a QuotePageModel must have a QuotePage The BindingContext on the page will be automatically set with the Model

  • A PageModel can have a Init method that takes a object

  • A PageModel can have a ReverseInit method that also take a object and is called when a model is poped with a object

  • PageModel can have dependancies automatically injected into the Constructor

Navigation

The Primary form of Navigation in FreshMvvm is PageModel to PageModel, this essentially means our views have no idea of Navigation.

So to Navigate between PageModels use:

1
await CoreMethods.PushPageModel<QuotePageModel>(); // Pushes on navigation stack
1
await CoreMethods.PushPageModel<QuotePageModel>(null, true); // Pushes a Modal

The engine for Navigation in FreshMvvm is done via a simple interface, with methods for Push and Pop. Essentially these methods can control the Navigation of the application in any way they like.

1
2
3
4
5
public interface IFreshNavigationService
{
   Task PushPage(Page page, FreshBasePageModel model, bool modal = false);
   Task PopPage(bool modal = false);
}

This is what you as a consumer will need to implement, and then register in the IOC Container.

Within the PushPage and PopPage you can do any type of navigation that you like, this can from a simple navigation to a advanced nested navigation.

The Framework contains some built in Navigation containers for the different types of Navigation.

Basic Navigation – Built In

1
2
3
4
5
var page = FreshBasePageModel.ResolvePageModel<MainMenuPageModel> ();
 
var basicNavContainer = new FreshNavigationContainer (page);
 
MainPage = basicNavContainer;

Master Detail – Built In

1
2
3
4
5
6
7
8
9
var masterDetailNav = new FreshMasterDetailNavigationContainer ();
 
masterDetailNav.Init ("Menu");
 
masterDetailNav.AddPage<ContactListPageModel> ("Contacts", null);
 
masterDetailNav.AddPage<QuoteListPageModel> ("Pages", null);
 
MainPage = masterDetailNav;

Tabbed Navigation – Built In

1
2
3
4
5
6
7
var tabbedNavigation = new FreshTabbedNavigationContainer ();
 
tabbedNavigation.AddTab<ContactListPageModel> ("Contacts", null);
 
tabbedNavigation.AddTab<QuoteListPageModel> ("Pages", null);
 
MainPage = tabbedNavigation;

Implementing Custom Navigation

It’s possible to setup any type of Navigation by implementing IFreshNavigationService.There’s a sample of this in Sample Application named CustomImplementedNav.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/// <summary>
/// This is a sample custom implemented Navigation. It combines a MasterDetail and a TabbedPage.
/// </summary>
public class CustomImplementedNav : Xamarin.Forms.MasterDetailPage, IFreshNavigationService
{
    FreshTabbedNavigationContainer _tabbedNavigationPage;
    Page _contactsPage, _quotesPage;
 
    public CustomImplementedNav ()
    {   
        SetupTabbedPage ();
        CreateMenuPage ("Menu");
        RegisterNavigation ();
    }
 
    void SetupTabbedPage()
    {
        _tabbedNavigationPage = new FreshTabbedNavigationContainer ();
        _contactsPage = _tabbedNavigationPage.AddTab<ContactListPageModel> ("Contacts", null);
        _quotesPage = _tabbedNavigationPage.AddTab<QuoteListPageModel> ("Quotes", null);
        this.Detail = _tabbedNavigationPage;
    }
 
    protected void RegisterNavigation()
    {
        FreshIOC.Container.Register<IFreshNavigationService> (this);
    }
 
    protected void CreateMenuPage(string menuPageTitle)
    {
        var _menuPage = new ContentPage ();
        _menuPage.Title = menuPageTitle;
        var listView = new ListView();
 
        listView.ItemsSource = new string[] { "Contacts", "Quotes", "Modal Demo" };
 
        listView.ItemSelected += async (sender, args) =>
        {
 
            switch ((string)args.SelectedItem) {
            case "Contacts":
                _tabbedNavigationPage.CurrentPage = _contactsPage;
                break;
            case "Quotes":
                _tabbedNavigationPage.CurrentPage = _quotesPage;
                break;
            case "Modal Demo":
                var modalPage = FreshPageModelResolver.ResolvePageModel<ModalPageModel>();
                await PushPage(modalPage, null, true);
                break;
            default:
            break;
            }
 
            IsPresented = false;
        };
 
        _menuPage.Content = listView;
 
        Master = new NavigationPage(_menuPage) { Title = "Menu" };
    }
 
    public virtual async Task PushPage (Xamarin.Forms.Page page, FreshBasePageModel model, bool modal = false)
    {
        if (modal)
            await Navigation.PushModalAsync (new NavigationPage(page));
        else
            await ((NavigationPage)_tabbedNavigationPage.CurrentPage).PushAsync (page); 
    }
 
    public virtual async Task PopPage (bool modal = false)
    {
        if (modal)
            await Navigation.PopModalAsync ();
        else
            await ((NavigationPage)_tabbedNavigationPage.CurrentPage).PopAsync (); 
    }
}

Inversion of Control (IOC)

So that you don’t need to include your own IOC container, FreshMvvm comes with a IOC container built in. It’s using TinyIOC underneith, but with different naming to avoid conflicts.

To Register services in the container use Register:

1
FreshIOC.Container.Register<IDatabaseService, DatabaseService> ();

To obtain a service use Resolve:

1
FreshIOC.Container.Resolve<IDatabaseService> ();

*This is also what drives constructor injection.

PageModel – Constructor Injection

When PageModels are pushed services that are in the IOC container can be pushed into the Constructor.

1
2
3
4
5
6
7
8
public class ContactListPageModel : FreshBasePageModel
{
    IDatabaseService _databaseService;
 
    public ContactListPageModel (IDatabaseService databaseService)
    {
        _databaseService = databaseService;
    }

PageModel Important Methods

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// <summary>
/// The previous page model, that's automatically filled, on push
/// </summary>
public FreshBasePageModel PreviousPageModel { get; set; }
 
/// <summary>
/// A reference to the current page, that's automatically filled, on push
/// </summary>
public Page CurrentPage { get; set; }
/// <summary>
/// Core methods are basic built in methods for the App including Pushing, Pop and Alert
/// </summary>
public IPageModelCoreMethods CoreMethods { get; set; }
 
/// <summary>
/// This method is called when a page is Pop'd, it also allows for data to be returned.
/// </summary>
/// <param name="returndData">This data that's returned from </param>
public virtual void ReverseInit(object returndData) { }
 
/// <summary>
/// This method is called when the PageModel is loaded, the initData is the data that's sent from pagemodel before
 
/// </summary>
/// <param name="initData">Data that's sent to this PageModel from the pusher</param>
public virtual void Init(object initData) { }
 
/// <summary>
/// This method is called when the view is disappearing.
/// </summary>
protected virtual void ViewIsDisappearing (object sender, EventArgs e)
{
 
}
 
/// <summary>
/// This methods is called when the View is appearing
/// </summary>
protected virtual void ViewIsAppearing (object sender, EventArgs e)
{
}

The CoreMethods

Each PageModel has a property called ‘CoreMethods’ which is automatically filled when a PageModel is pushed, it’s the basic functions that most apps need like Alerts, Pushing, Poping etc.

1
2
3
4
5
6
7
8
9
10
public interface IPageModelCoreMethods
{
   Task DisplayAlert (string title, string message, string cancel);
   Task<string> DisplayActionSheet (string title, string cancel, string destruction, params string[] buttons);
   Task<bool> DisplayAlert (string title, string message, string accept, string cancel);
   Task PushPageModel<T>(object data, bool modal = false) where T : FreshBasePageModel;
   Task PopPageModel(bool modal = false);
   Task PopPageModel(object data, bool modal = false);
   Task PushPageModel<T>() where T : FreshBasePageModel;
}

 

Sample PageModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
[ImplementPropertyChanged] // Use Fody for Property Changed Notifications
public class QuoteListPageModel : FreshBasePageModel
{
   IDatabaseService _databaseService;
 
   //These are automatically filled via Constructor Injection IOC
   public QuoteListPageModel (IDatabaseService databaseService)
   {
       _databaseService = databaseService;
   }
 
   public ObservableCollection<Quote> Quotes { get; set; }
 
   public override void Init (object initData)
   {
       Quotes = new ObservableCollection<Quote> (_databaseService.GetQuotes ());
   }
 
   //The Framework support standard functions list appeaing and disappearing
   protected override void ViewIsAppearing (object sender, System.EventArgs e)
   {
       CoreMethods.DisplayAlert ("Page is appearing", "", "Ok");
       base.ViewIsAppearing (sender, e);
   }
 
   protected override void ViewIsDisappearing (object sender, System.EventArgs e)
   {
       base.ViewIsDisappearing (sender, e);
   }
 
   //This is called when a pushed Page returns to this Page
   public override void ReverseInit (object value)
   {
       var newContact = value as Quote;
 
       if (!Quotes.Contains (newContact)) {
           Quotes.Add (newContact);
       }
   }
 
   public Command AddQuote {
       get {
           return new Command (async () => {
               //Push A Page Model
 
               await CoreMethods.PushPageModel<QuotePageModel> ();
           });
       }
   }
 
   Quote _selectedQuote;
   public Quote SelectedQuote {
       get {
           return _selectedQuote;
       }
       set {
           _selectedQuote = value;
           if (value != null)
               QuoteSelected.Execute (value);
       }
   }
 
   public Command<Quote> QuoteSelected {
       get {
           return new Command<Quote> (async (quote) => {
               await CoreMethods.PushPageModel<QuotePageModel> (quote);
           });
       }
   }
}
 
So please take a look at it on <a href="https://github.com/rid00z/FreshMvvm">github</a> or nuget. 
 
If you have any questions please contact me via <a href="http://www.michaelridland.com">http://www.michaelridland.com</a>. 
 
Thanks
 
Michael

The post FreshMvvm – A Mvvm Framework designed for Xamarin.Forms appeared first on Michael Ridland.

May 11, 2015 12:00 GMT

9 Months of the Weekly Xamarin Newsletter

Hello everyone. I want to give you an update on how the Weekly Xamarin newsletter was going after more than 9 months. The newsletter is in good condition and with 39 issues under my belt, it’s only going to get better.

Subscribers

Good news, the Weekly Xamarin Newsletter has passed the 900 subscriber mark last week. I want to thank all the subscribers and the authors for making the Weekly Xamarin newsletter possible.

Weekly Xamarin Newsletter

Overview

The newsletter has an average of over 60% open rate for each newsletter issue, which is very good. The newsletter also has a high 20 to 30 click rate as well. The click rate is almost double the industry average.

Xamarin Weekly newsletter overview

Quality

Due to the large numbers of Xamarin blog posts each week, I’ve had to become more selective of what goes in the newsletter. I don’t want the newsletter turning into a list of everything; that’s what Google is for. Like I have said from the start, if it’s about Xamarin and awesome, it goes in the newsletter.

What makes an awesome post

  1. The topic should be about Xamarin and mobile development
  2. Posts should be 300 words or longer
  3. If writing about UI, please use images
  4. Use code blocks or let readers download project files

Now that I’ve said that, please tell me if your awesome Xamarin blog post didn’t make it into the newsletter. I’m human, not perfect, and I do make mistakes. Just this past newsletter, I missed a great post. The author emailed me and after apologizing I added the post to the top of next week’s newsletter.

What’s Next?

The next thing for the newsletter will be issue #40. Beyond next week and the weeks that follow, I have no plans of changing the newsletter. I also have no plans at this time on selling ads or taking on sponsorships.

PS: I’ll be on vacation next week. But don’t worry. Your Weekly Xamarin Newsletter will be delivered on time, early Friday morning.

The post 9 Months of the Weekly Xamarin Newsletter appeared first on Syntax is my UI.

May 10, 2015 8:21 GMT

Taming The Android Activity, Part 2

In part one of this series I covered how to use a Fragment to maintain state through configuration changes. In part two I will cover how to launch a new Activity (in-process or not) and wait for its results using C#'s async/await feature.

Starting Activities

As mentioned in part one, the Activity is designed to let applications reuse pieces of other applications. For instance, if you need to let the user pick a photo then you can construct an Intent object that describes what you want to do (pick a photo), and the OS will find an Activity for one of the installed applications that can satisfy that request. The other Activity may be in another application, but the Intent allows you to send it information about what you want, and then later it can send back the results (through another Intent).

The way the API works is you call StartActivity (a method in Activity) and give it either an Intent object or a Type (which will be used to construct an Intent). When you do that the OS will find the proper Activity, create it (possibly in another process), and then show it the user. Once that Activity is finished (either by the user pressing the back button or the Activity calling Finish()) then your original Activity will resume.

However, that's only for a simple case: launching a new Activity and ignoring any results. If you actually wanted to get information back from the other Activity then you need to instead call StartActivityForResult. This method is just like StartActivity, but it also takes an int that can be used to identify the request. Then you have to override the OnActivityResult method, which will give you back the request identifier along with a ResultCode and an Intent (for extra information). That basically looks like this:

private const int ImagePickerRequestCode = 1000;

private void LaunchOtherActivity()
{
var intent = new Intent(Intent.ActionGetContent);
intent.SetType("image/*");
StartActivityForResult(intent, ImagePickerRequestCode);
}

public override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (requestCode == ImagePickerRequestCode && resultCode == Result.Ok)
{
// Get the image from data
}
}

The Problem

There are several problems with this, and the root of all of them is that all results for any Activity you launch must go through OnActivityResult. This means that any time you launch an Activity and want results you have to put some code in that function to handle the results. This is why you need the annoying int requestCode argument: that is the only way to identify which Activity you were launching so that you know what to do with the results. Now you have to be sure that each type of Activity that you launch in this way uses a different number, which is annoying.

Another problem is that this splits up your code. You start the Activity in one place, and then you handle the results elsewhere. There's no callback or anything that connects the two. You just have to know to go find that other function to see how the results are handled.

The worst problem is that this makes it very difficult to properly decouple responsibilities between views. What if you want to launch another Activity from a view inside a popup? You still have to handle the results in the Activity itself, and then you somehow have to get the results back to the view inside the popup.

This was my motivation for finding a better way. When you write a large application in Android you might have many different kinds of activities that you want to launch and then gather the results from, and forcing all of that code to go through a single function makes it very difficult to maintain.

Imagine a Better Way

Before we start trying to implement anything let's first think about what we want the API to look like (always a good first step to avoid APIs like this).

Obviously launching a new Activity and getting results is an asynchronous operation so we're going to have some kind of asynchronous API. We could do that with callbacks, which would be a huge improvement, but C# has an awesome feature that makes this even better: async/await. Using that feature we could imagine an API that looks like this:

var intent = new Android.Content.Intent(Android.Content.Intent.ActionGetContent);
intent.SetType("image/*");
var result = await StartActivityForResultAsync(intent);
if (result.ResultCode == Result.Ok)
{
// Get the image from data
}

This looks awesome. There's no request code, and all of the code is in one place. Best of all, there's not even a callback. This code reads like normal synchronous code.

Gathering Requirements

Now that we know what we want the API to look like let's think about what we need to accomplish it. One of the benefits of the work we did in part one of this series is that each Activity (and also each Fragment) in our application shares a base class. That provides us with an opportunity to put some bookkeeping in the base class that can help us achieve our goal. Based on the API we have to start with, and the API we are trying to build, we need to keep track of this information:

  1. A request code for each launched Activity. To avoid requiring the caller to give us one we also need to somehow come up with new unique request codes automatically.
  2. A TaskCompletionSource that can be used to provide the results asynchronously to the caller (via its Task property).
  3. A mapping between the request codes and the TaskCompletionSources.

Based on this we can start to see an implementation forming. We can use an auto-incrementing request code (starting at some arbitrary value), and we can use a Dictionary to map between the request codes and the TaskCompletionSources.

While we're at it we will also solve another challenge that we often face when dealing with these Activity results: OnActivityResult is called before OnResume, which in some cases may be too early to actually deal with the results. Since we're already handling sending the results back asynchronously we can fix this by also delaying the results until after OnResume, which is far more useful.

Implementation

In the spirit of keeping as much logic in the Fragment instead of the Activity we will be putting this API in the FragmentBase class that we created in part one of this series. This is also important because we don't want to lose the bookkeeping information if there is a configuration change (like if the user rotates the device after you start the new Activity but before you get the results).

Our FragmentActivity class will be the same as before, but we will add some new code to the FragmentBase class. First, we need an interface for the results returned by our async method:

/// <summary>
/// The information returned by an Activity started with StartActivityForResultAsync.
/// </summary>
public interface IAsyncActivityResult
{
/// <summary>
/// The result code returned by the activity.
/// </summary>
Result ResultCode { get; }

/// <summary>
/// The data returned by the activity.
/// </summary>
Intent Data { get; }
}

Now we need to add our new methods to the FragmentBase class. I have omitted the parts that were unchanged for brevity.

/// <summary>
/// The base class for top-level fragments in Android. These are the fragments which maintain the view hierarchy and state for each top-level
/// Activity. These fragments all use RetainInstance = true to allow them to maintain state across configuration changes (i.e.,
/// when the device rotates we reuse the fragments). Activity classes are basically just dumb containers for these fragments.
/// </summary>
public abstract class FragmentBase : Fragment
{
// This is an arbitrary number to use as an initial request code for StartActivityForResultAsync.
// It just needs to be high enough to avoid collisions with direct calls to StartActivityForResult, which typically would be 0, 1, 2...
private const int FirstAsyncActivityRequestCode = 1000;

// This is static so that they are unique across all implementations of FragmentBase.
// This is important for the fragment initializer overloads of StartActivityForResultAsync.
private static int _nextAsyncActivityRequestCode = FirstAsyncActivityRequestCode;
private readonly Dictionary<int, AsyncActivityResult> _pendingAsyncActivities = new Dictionary<int, AsyncActivityResult>();
private readonly List<AsyncActivityResult> _finishedAsyncActivityResults = new List<AsyncActivityResult>();

#region Async Activity API

public Task<IAsyncActivityResult> StartActivityForResultAsync<TActivity>(CancellationToken cancellationToken = default(CancellationToken))
{
return StartActivityForResultAsyncCore(requestCode => Activity.StartActivityForResult(typeof(TActivity), requestCode), cancellationToken);
}

public Task<IAsyncActivityResult> StartActivityForResultAsync(Intent intent, CancellationToken cancellationToken = default(CancellationToken))
{
return StartActivityForResultAsyncCore(requestCode => Activity.StartActivityForResult(intent, requestCode), cancellationToken);
}

public override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
AsyncActivityResult result;
if (_pendingAsyncActivities.TryGetValue(requestCode, out result))
{
result.SetResult(resultCode, data);
_pendingAsyncActivities.Remove(requestCode);
_finishedAsyncActivityResults.Add(result);
}

base.OnActivityResult(requestCode, resultCode, data);
}

public override void OnResume()
{
base.OnResume();

FlushPendingAsyncActivityResults();
}

private Task<IAsyncActivityResult> StartActivityForResultAsyncCore(Action<int> startActivity, CancellationToken cancellationToken)
{
var asyncActivityResult = SetupAsyncActivity();
startActivity(asyncActivityResult.RequestCode);

if (cancellationToken.CanBeCanceled)
{
cancellationToken.Register(() =>
{
Activity.FinishActivity(asyncActivityResult.RequestCode);
});
}

return asyncActivityResult.Task;
}

private void FlushPendingAsyncActivityResults()
{
foreach (var result in _finishedAsyncActivityResults)
{
result.Complete();
}
_finishedAsyncActivityResults.Clear();
}

private AsyncActivityResult SetupAsyncActivity()
{
var requestCode = _nextAsyncActivityRequestCode++;
var result = new AsyncActivityResult(requestCode);
_pendingAsyncActivities.Add(requestCode, result);

return result;
}

private class AsyncActivityResult : IAsyncActivityResult
{
private readonly TaskCompletionSource<IAsyncActivityResult> _taskCompletionSource = new TaskCompletionSource<IAsyncActivityResult>();

public int RequestCode { get; private set; }

public Result ResultCode { get; private set; }

public Intent Data { get; private set; }

public Task<IAsyncActivityResult> Task { get { return _taskCompletionSource.Task; } }

public AsyncActivityResult(int requestCode)
{
RequestCode = requestCode;
}

public void SetResult(Result resultCode, Intent data)
{
ResultCode = resultCode;
Data = data;
}

public void Complete()
{
_taskCompletionSource.SetResult(this);
}
}

#endregion
}

Now let's take a quick tour and see how this all works. First, there are two overloads of StartActivityForResultAsync. One takes a type of Activity as a generic argument because it's very common to want to start a new Activity in-process and just refer to it by its type. The other one takes an Intent, which is more flexible. You will typically use this variant for out-of-process activities.

These methods also take an optional CancellationToken, which can be used to cancel the launched Activity. If the token is cancelled then the code that is waiting on the async result will get a ResultCode that indicates that it was cancelled.

Both of those methods call into the same core routine that sets up the bookkeeping. It is responsible for creating the object that tracks the results and returning the Task that we can wait on.

Once the Activity has been started we return the Task object to the caller, and then we wait for a call to OnActivityResult. The OnActivityResult method is forward to the Fragment automatically.1 In OnActivityResult we check to see if the request code is one that is in our Dictionary of pending async activities. If it is then we record the ResultCode and the Intent, add it to a list of finished results, and then remove the item from our Dictionary. Later we will get a call to OnResume, which just goes through the list of finished results and calls the Complete method. That is the method that actually pushes the results into the TaskCompletionSource (by calling SetResult), which unblocks anything waiting on the Task.

And that's it. Now we have enough to start a new Activity and wait for its result in a single, small function. I have posted a full version of the code with a small example app on GitHub.

Summary

So far in the first two parts of this series I have covered how to preserve state across configuration changes and how to simplify the process of starting new activities and waiting for their results. With those two challenges solved we can avoid a lot of ugly boilerplate code. However, there is still one significant source of tedious boilerplate code: communicating between these activities still has to be done through Intent objects. In the next part of this series I will extend this code even further to allow for directly accessing the new Fragment object for in-process activities.


  1. In the original version of this article I claimed incorrectly that the OnActivityResult method did not exist in the Fragment class in the Android SDK. This is incorrect. The OnNewIntent and OnAttachedToWindow methods don't exist on Fragment, and we added those and forwarded them from the our FragmentActivity class, but OnActivityResult is built in. 

May 10, 2015 10:00 GMT

Xamarin Components Directory Configuration

One of the new features introduced in Xamarin Studio 5.9 is the ability to configure the directory where Xamarin Components are installed to when they are added to a project.

By default, when a Component from the Xamarin Component store is added to a project, the Component is installed to a Components directory inside the solution’s directory.

Default Components directory for a solution

The project will have references added that refer to assemblies inside this Components directory.

<Reference Include="Microsoft.WindowsAzure.Mobile.Ext">
  <HintPath>..\Components\azure-mobile-services-1.3.1\lib\android\Microsoft.WindowsAzure.Mobile.Ext.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Mobile">
  <HintPath>..\Components\azure-mobile-services-1.3.1\lib\android\Microsoft.WindowsAzure.Mobile.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
  <HintPath>..\Components\azure-mobile-services-1.3.1\lib\android\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Extensions">
  <HintPath>..\Components\azure-mobile-services-1.3.1\lib\android\System.Net.Http.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Primitives">
  <HintPath>..\Components\azure-mobile-services-1.3.1\lib\android\System.Net.Http.Primitives.dll</HintPath>
</Reference>

If a project is shared between multiple solutions then Xamarin Studio can have multiple different Components directories, one for each solution. This can cause Xamarin Studio to modify the hint paths in the project file to use a different Components directory depending on which solution was opened.

A simple way to reproduce this problem is to create one solution with a project that has a Component, then create another solution in a different directory, and add the same project to this new solution. The Component will be downloaded again into the Components directory relative to the new solution and the assembly references in the project file will be modified to use this new Components location.

Now let us take a look at how to solve this problem by configuring the Components directory.

Configuring the Components Directory

To configure the Components directory used by a project you can use a components.config file, as shown below.

<config>
  <add key="cachePath" value="..\Components" />
</config>

The path specified in the components.config file can be a full path or a relative path. If it is a relative path then it is relative to the directory containing the components.config file.

The path in the components.config file will be normalized so it contains the correct directory separators on non-Windows operating systems, so you can use either a forward slash or a backslash in the path.

Now let us take a look at how Xamarin Studio finds this components.config file.

Xamarin Studio, when a solution is opened, will check for a components.config file in several locations based on the solution’s directory. If we have a solution in the directory /Users/matt/Projects/MyAndroidApp/ then the full set of locations checked is as follows:

  1. /Users/matt/Projects/MyAndroidApp/.components/components.config
  2. /Users/matt/Projects/MyAndroidApp/components.config
  3. /Users/matt/Projects/components.config
  4. /Users/matt/components.config
  5. /Users/components.config
  6. /components.config
  7. ~/Preferences/Xamarin/Components/components.config

Note that on Windows the last location checked is:

%AppData%\Xamarin\Components\components.config

If you put the components.config file in a directory that is a parent of multiple solutions then all the solutions can use this common components.config file.

If the components.config file is missing or cannot be read then the default Components directory is used, which is inside the solution’s directory.

If there is an error whilst reading the components.config file then the error will be logged by Xamarin Studio and the default Components directory will be used.

The Components directory to be used is cached when the solution is loaded so changes made to the components.config file require the solution to be closed and re-opened before Xamarin Studio will use the new settings.

To help diagnose problems when configuring the Components directory Xamarin Studio will log information in the Components.log file. The Components.log file can be found by selecting Open Log Directory from Xamarin Studio’s Help menu. Two examples taken from the Components.log file are shown below. The first example shows the message logged when a components.config file cannot be found.

[2015-05-10 11:00:29.0] DEBUG: No components.config file found. Using default path. Files checked: /Users/matt/Projects/MyAndroidApp/.components/components.config
/Users/matt/Projects/MyAndroidApp/components.config
/Users/matt/Projects/components.config
/Users/matt/components.config
/Users/components.config
/components.config
/Users/matt/Library/Preferences/Xamarin/Components/components.config

The next example shows the message logged when a components.config file is found.

[2015-05-10 11:10:24.1] DEBUG: Using custom components cache path '/Users/matt/Projects/MyAndroidApp/Components'. components.config file found at '/Users/matt/Projects/MyAndroidApp/components.config'.

Component Restore

The latest version of xamarin-component.exe also supports using the configured Components directory. Its restore command will restore the Components to the directory as specified in the components.config file.

mono xamarin-component.exe restore path/to/solution.sln

xamarin-component.exe will look for the components.config file in the same directories as Xamarin Studio.

Comparison with NuGet

NuGet has similar behaviour to Components in Xamarin Studio. All NuGet packages are downloaded to a packages directory inside the solution directory by default. To override this behaviour you can create a NuGet.Config file. The NuGet.Config file allows the packages directory to be configured through a repositoryPath setting.

<config>
  <add key="repositoryPath" value="../../packages" />
</config>

NuGet will look for this NuGet.Config file in several places. Assuming the solution directory is /Users/matt/Projects/MyAndroidApp/ the NuGet.Config file will be looked for in the locations as shown below:

  1. /Users/matt/Projects/MyAndroidApp/.nuget/NuGet.Config
  2. /Users/matt/Projects/MyAndroidApp/NuGet.Config
  3. /Users/matt/Projects/NuGet.Config
  4. /Users/matt/NuGet.Config
  5. /Users/NuGet.Config
  6. /NuGet.config
  7. ~/.config/NuGet/NuGet.Config (Windows: %AppData%\NuGet\NuGet.Config)
May 08, 2015 12:00 GMT

Weekly Xamarin Newsletter Issue #39

Cross Platform Animations Using Xamarin Forms
Mark Arteaga shows us how to do some animations using Xamarin.Forms.

Champion San Jose Earthquakes Win with Xamarin.Forms and Xamarin Insights
Jo Ann Buckner, from Xamarin Inc., shares a customer success story.

Supercharging Xamarin Forms with Custom Renderers, Part 5
Jeff Prosise has another excellent post on extending Xamarin.Forms.

BDD Tests with Xamarin.UITest and SpecFlow
Rob Gibbens, from Xamarin Inc., uses BDD, tests and specs to write the right code.

Xamarin.Forms Grid Recipe
I (Adam) use the Xamarin.Forms Grid for the first time. See how I did.

Akavache is AKA Awesome!
Matthew Soucoup, from Code Mill Technologies, is impressed with Akavache. See why.

Generating Android Color Palettes Super Fast with Rev 22.1
James Montemagno, from Xamarin Inc., gets his color on with Android palettes.

How to: Handoff to a Xamarin iPhone app from Apple Watch
Larry O’Brien shows you how to make a good handoff to apple watch.

Xamarin Forms: PCL vs. Shared Project
Ken uses real world experience to decide which is better, PCL or Shared.

Adam J Wolf: Xamarin.Forms in Anger – HeatMap
I (Adam) turn up the heat and get angry at Xamarin.Forms.

Sara Silva – Xamarin Workshop Guide

10. MoveItemTemplate to Resource
11. Create a LoginView

NuGet Support in Xamarin Studio 5.9
Matt Ward, from Xamarin Inc., updates us on NuGet support in Xamarin Studio.

Xamarin.Forms: from zero to hero – part 2
Gerald Versluis says good bye to Kansas with Xamarin.Forms.

Xamarin.iOS, the garbage collector and me
Just Krumelur shares his hard fought knowledge on garbage collecting.

Finding Nemo – Implementing Xamarin.Forms SearchBar
Gerald Versluis finds Nemo by using the SearchBar.

 

Don't miss out! Subscribe Today

Do you blog about Xamarin? Get your blog in the newsletter. Email me at adam [at] adamjwolf.com.

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

May 07, 2015 4:00 GMT

How to: Handoff to a Xamarin iPhone app from Apple Watch

# How to: Handoff to a Xamarin iPhone app from Apple Watch

There are two ways to activate the parent (aka container) app from an Apple Watch app. You can either directly activate the container app using WKInterfaceController.OpenParentApplication or you can use Handoff.

Using Handoff is a little more complex, so I thought I’d write a quick little how-to. There are a few different Handoff scenarios, but perhaps the most common for the  Watch is: “On my watch I want to begin a task that I complete later on my iPhone.” So, for instance, some task that requires either more data-entry than is appropriate for the watch or some capabilities not available on the watch.

I want to keep the focus on the APIs, so instead of a real-world sample, I’m going to create a minimal example: a button on the Watch activates handoff and a status label on the phone app is updated when the user activity is continued on the phone.

As always, we have a single Solution with 3 projects: the parent App, the Watch extension, and the Watch App.

Napkin 10 05-06-15, 4.21.12 PM

Every handoff activity has a unique identifier. By convention, this is a domain-reversed string such as: com.xamarin.HandOffDemo.verb.

To trigger the Handoff behavior, the watch extension calls the WKInterfaceController.UpdateUserActivity method, with its first argument set equal to this identifier:

partial void ActivateHandoffClicked (WatchKit.WKInterfaceButton sender)
{
    var userInfo = NSDictionary.FromObjectAndKey(new NSString(“value”), new NSString(“key”));
    this.UpdateUserActivity(“com.xamarin.HandOffDemo.verb”, userInfo, null);
}

The third argument is a NSUrl object that can be used for Handoff tasks that should be handled by Safari. But in our case, we’re handing the userInfo dictionary containing the very complex data associated with our handoff.

Your parent app registers its interest in this type of handoff within its info.plist. In the parent app info.plist, add a new array called NSUserActivityTypes and add to it a string with value com.xamarin.HandOffDemo.verb

Napkin 11 05-06-15, 4.29.20 PM

It’s possible that an app could be interested in certain handoffs, but not always be in a position to actually handle them. That logic can be placed in an override of the UIApplicationDelegate.WillContinueUserActivity method:

public override bool WillContinueUserActivity (UIApplication application, string userActivityType)
{
    //Yeah, we can handle it
    return true;
}

Assuming that we return true from that method, the next step is to override the UIApplicationDelegate.ContinueUserActivity method:

An architectural issue that needs to be addressed is that this Handoff re-entry point is in the UIApplicationDelegate object, which of course does not have an associated user interface. There are several ways to handle this, but as a fan of reactive programming, I think the proper design is to create either an IObservable sequence or a more traditional C# event, which is what I do here:

public event EventHandler HandoffOccurred = delegate {};

public override bool ContinueUserActivity (UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
    HandoffOccurred?.Invoke (this, userActivity.UserInfo);

    return true;
}

The third parameter, completionHandler used if you have references to custom UIResponder objects that should handle the user activity. In the case, you put those references in a NSArray and pass them to completionHandler, which will cause each of their ContinueUserActivity methods to be called. (Update: Apple would probably prefer this technique to my event, but I am not sure if it’s necessary, and it requires the UIApplicationDelegate to maintain a reference to the subscribing UIResponder, so you either have an ugly dependency or you have to implement some kind of Observer / Subscriber pattern. So I still would suggest an event or IObservable as the better solution.)

In the parent app’s main UIViewController class, I have:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    //Configure user experience for Handoff
    var myAppDel = (AppDelegate) UIApplication.SharedApplication.Delegate;
    myAppDel.HandoffOccurred += HandoffOccurred;
}

public void HandoffOccurred(object sender, NSDictionary userInfo)
{
    InvokeOnMainThread( () =&gt; statusLabel.Text = userInfo[“key”].ToString() );
}

And that’s all there is to it. Obviously, a real use-case would involve building a more complex NSDictionary holding the context of the watch interaction and a similarly complex handler in the parent app.

Now, when the Handoff is activated from the Apple Watch, my iPhone lock screen shows the icon of the parent app in the lower-left corner. If I drag that up, the parent app opens, the re-entry process begins, with UIApplicationDelegate.WillContinueUserActivity and UIApplicationDelegate.ContinueUserActivity.

May 06, 2015 12:28 GMT

Top 10 Tips for Building an Apple Watch App

Unless you’ve been living under a rock then you already know about the Apple Watch, have ordered one or your wearing one right now. At the moment I’ve been getting my head around how WatchKit apps will work for my the apps of my clients. The truth be told is that not all apps need a WatchKit component, but many do.

After using an Apple Watch in real, one thing I noticed was the inability to edit calendar events, huh? You can add them but you can’t edit them. Actually in regards to most of the built in apps, there isn’t alot of editing operations. After a lengthy conversation with a product manager at Apple, Apple see’s the Watch primarily being used for super super short intervals, 3-5 seconds. Quickly reading an email or replying to a text message. So essentially we need to keep this in mind when we develop any Watch Apps.

1. Re-think your design from the ground app, don’t just take your Phone app and the images from that app and display it on the watch.

2. Five-Ten Seconds is the amount of time you should keep a users attention, anything more and they should pull their phone out.

3. Bluetooth is slow, and even slower on the device. You need to keep everything lean, compress images, keep images the exact size and no bigger, only update items that have changed (if you even need to). Do you need to upload images or can you use text?

4. Keep is simple, only show the exact data a user needs. If for example your using TripAdvisor, what does the user need to see? The rating, the name and address maybe one more thing, no need to overload the screen you’ve only got 5 seconds anyway.

5. The watch is slow and your app needs to be fast. Lazy-Load for fast startup and then background pre-load where possible, cache where possible, show splash/loading screens. Also another reason to use less content in your apps.

6. Use hand off, this is essential, if you’ve given a user a notification and they jump into your watch app it’s likely they might want to continue the action in further detail on their device. An example would be a user looking at a email and might want to reply on the phone, when the user opens their phone then it must deep link into the mail app with the email open (it already does this btw). This is all available to you as a developer via the WKInterfaceController.

7. Let the iPhone do the work. Communication between your iPhone app and watch app is simple, so don’t be afraid to pass tasks/operations back to the phone.

8. Use dictation – User input is a keystone of useful applications, so while you’ve only got a ‘short time’ with the user it’s still possible to get some input.

9. You only have 10 UI elements in Total, but they can be deeply nested and can be used to create advanced views.

10. Get a Watch and use it. You can’t expect that you’ll be able to create a good user experience unless you live the same user experience. As the saying goes eat your own dog food.

The Apple watch is only a first release product, it’s just a given that the apps and device aren’t going to be overly refined but it’s definitely a glimpse into the future. Oh and FYI it’s not called a iWatch, it’s not, so please don’t call it a iWatch.

Please drop me an email if you have any questions or queries about the Apple Watch, I’m always keen to help people.

Thanks

Michael

 

 

The post Top 10 Tips for Building an Apple Watch App appeared first on Michael Ridland.

May 06, 2015 12:00 GMT

Xamarin.Forms Grid Recipe

In a recent “In Anger” post, I used the Xamarin.Forms Grid control to recreate the mobile Google Analytics page view heat map. The map shows when users frequent this blog. Using the Xamarin.Forms Grid made recreating the UI a snap.

Xamarin.Forms Grid

Xamarin.Forms Grid

The Grid control should look and feel very similar to fellow Silverlight developers. You might recognize the Row and Column definitions as well as the Add method.

Row Definitions

The RowDefinitions Collection property houses the configuration and settings for each row in the Grid.  Each definition has a height property which sets the height of the row. The height can be a constant like 100 or a GridLength value.

Column Definitions

The ColumnDefinition Collection is similar to the RowDefinitions. Each definition controls the width of the column. Just like the rows each column has a width property that can be a constant or a GridLength value.

For the HeatMap post, I used the GridUnitType of Auto for the rows and Star for the columns.

Xamarin.Forms.GridUnitType Enumeration

Member Name Descriptions
Absolute Interpret the GridLength.Value property value as the number of device-specific units.
Auto Ignore the GridLength.Value property value and choose a size that fits the children of the row or column.
Star Interpret the GridLength.Value property value as a proportional weight, to be laid out after rows and columns with GridUnitType.Absolute or GridUnitType.Auto are accounted for.

Xamarin.Forms.Grid.Children.Add

Last, but definitely not least, is the Add method for the grids’ children. You have a few choices on how you add children to this collection.

First you can just add a view. This view will be added to the first row and column of the grid.

heatMap.Children.Add (new BoxView);

Second, you can add a view and give it the left and top location within the grid. Remember rows and columns start at zero.

heatMap.Children.Add (new BoxView (), 1 , 1);

Lastly, you can give it the view and its left, right, top and bottom locations. The last one is useful for when you want a view to span more than one column or row. In this example, we are placing a BoxView into the second row and column and having it span two rows and columns.

heatMap.Children.Add (new BoxView (), 1, 2, 1, 2);

I’ve really just scratched the surface of the Xamarin.Forms Grid. Without the Grid control this UI would have been very difficult to recreate. With the control, it took me an hour. I spent a little time after that fiddling with the GridUnitType for the rows and columns.

The Xamarin.Forms Cookbook Series

Still hungry for more Xamarin.Forms? Try these other recipes from the Xamarin.Forms Cookbook Series.

The post Xamarin.Forms Grid Recipe appeared first on Syntax is my UI.

May 05, 2015 7:04 GMT

Summer Camp with Mobile Developers

The events in our lives happen in a sequence in time, but in their significance to ourselves they find their own order: the continuous thread of revelation. - Eudora Welty

We at XHackers strongly believe in this and this summer, we are happy to add two more events to your life, helping you to learn more about Xamarin. We are bringing in some exciting sessions to both the meetups.

Recently at Microsoft //build, there were a series of announcements and one among them is Windows 10 and "Universal App Development". So here's your chance to learn more about it from none other than the team at Microsoft Bangalore.

On May 9th - learn how to start Building & Running your Apps over a Billion devices - with Universal Windows Apps by Abhishek Narian, Technical Evangelist, Microsoft.

There are multiple ways to share your business logic code - you can use PCL, Shared Library, or even File Linking. However, there could be instances when your UI is less complicated, and you wish to maintain a single UI codebase. Learn more about how to build native UIs for iOS, Android and Windows from a single, shared C# codebase.

Join Nish Anil, Developer Evangelist, Xamarin on building a simple Weather app using Xamarin.Forms.

Xamarin.Forms

In continuation to our previous meetup on wearables, we have added one more talk on
Programming Microsoft Band : The Xamarin way by Vidyasagar, Microsoft MVP - XBox.

To be part of this Cross platform learning experience -

RSVP Now

The second event is on May 23rd and this time its at Neudesic Bangalore

Here;s the detailed agenda for this event:

Session 1: Introduction to Xamarin

Session 2: Integrating azure mobile services with Xamarin app (Duration 1 hr)

  • Azure Mobile Service overview

  • Getting started with Xamarin and Azure Mobile Services

  • Covering following scenarios:

    • Store data

    • Offline data sync and handle conflicts

    • Authenticate user

    • Add push notification to your app

Speaker: Sanjeev Dhawala, Senior Consultant, Neudesic

Session 3: Explore Xamarin Test cloud with Xamarin Store App (Duration 1 hr)

  • Overview of Xamarin.UITest to automate the execution of existing iOS and Android apps.

  • Explore the creation of acceptance, behavior and regression tests and how the Xamarin.UITest tooling can be used to speed up the development of your acceptance tests.

  • Finally, we will learn how to deploy the apps + UI Tests up to Test Cloud for complete coverage across devices, OS versions and form factors using Xamarin Store App.

Speaker: Srinivasu Amjuri, Senior consultant, Neudesic (QA Practice)

Session 4: Introduction to Wearable App Design & Development (Apple and Android)

Introduction to wearable app design and development with Xamarin platform.

Speaker: Vidyasagar M S C, Microsoft MVP

To take part -

RSVP Now

Please note: The Venue for both the events are different. Make sure make necessary travel arrangements for the same.

See you there!

Cheers
Xhackers Core Team
core@xhackers.co

May 04, 2015 7:01 GMT

Generating Android Color Palettes Super Fast with Rev 22.1

Google went on a spree a few weeks back updating all of their support libraries to rev 22.1. If you haven’t read about all the changes be sure to read through the official Android Developer’s blog for a full breakdown. The most drastic change to the support libraries was to v7 AppCompat with the new AppCompatActivity, but there were several other enhancement to the libraries including one of my favorite Palette. If you don’t remember what palette is, it allows you to sample a color palette from any bitmap to theme your application. Here is a simple example of the before and after:

With rev 22.1, available as a NuGet package for your Xamarin.Android applications, the speed in which palettes are now generated are now 5 to 10 times faster! Here are some stats from Chris Banes’ blog:

After you update your NuGets to the latest version (currently 22.1.1.1 as of May 2nd 2015), you may notice that your old Palette methods were deprecated. This is because Google has replaced the older Palette.Generate and Palette.GenerateAsync methods with the tried and true Builder pattern. This will feel very familiar if you have worked with AlertDialogs or Notifications. It is basically a way of chaining property setters in a row (kind of linq style) since java doesn’t really have getters for properties that you could construct. So here is our old code:

In the latter method call the “this” is your current implementation of  Palette.IPaletteAsyncListener, which will get a callback when the generate has been completed and the new way of generating a palette uses this same interface implementation, but looks a bit different:

Updating to the latest NuGet packages will have some drastic improvements in speed as you saw in Chris’ chart because according to Chris Banes: “In this release, we went back to some old-style optimizations for the colour quantization. Things like less object allocations, more appropriate data structures and a reduction in algorithmic complexity. “

There you have it! You can grab a sample from our Xamarin.Android samples gallery. Now go make things beautiful.

May 04, 2015 3:12 GMT

BDD Tests with Xamarin.UITest and SpecFlow

Sample code is available at my Github repo

Writing applications, whether desktop, web, or mobile, is expensive. Developer time is a very limited commodity; one that we have to be careful not to waste. Two very common ways to waste developer time include writing code twice in order to fix what was broken the first time, and writing code that never should have been written in the first place.

Unit testing can help us deal with the issue of not shipping broken code. We should have a full suite of unit tests focused on the method level of our code. These unit tests should be lightning fast, run constantly, and verify that the code we wrote works the way that we expect it to.

Unit tests are invaluable, and I'm a huge fan of them, but they don't necessarily help us avoid writing the wrong code. As developers, every line of code that we write should be driven by an actual business requirement. These requirements are defined by the developers, the product managers, executives, possibly some users, and other important stakeholders working together. This communication between people is extremely important to writing the correct application and features from the start. It doesn't matter how wonderfully our code is executing if it's the wrong code. Typically, these requirements are written down in something like a Microsoft Word document, and passed around between all of the interested parties. The problem with this approach, though, is that it is very, very easy for these documents to be written once, and then become out of date or ignored as the development process begins. What we would really like is for our requirements to written in such a way that they are readable and understandable by all stakeholders, but also have them actually execute against our application in the same way that unit tests are executable.

Behavior Driven Development

This is where Behavior-driven development, or "BDD", comes in.

"Behavior-driven development combines the general techniques and principles of TDD with ideas from domain-driven design and object-oriented analysis and design to provide software development and management teams with shared tools and a shared process to collaborate on software development.

Behavior-driven development borrows the concept of the ubiquitous language from domain driven design. A ubiquitous language is a (semi-)formal language that is shared by all members of a software development team — both software developers and non-technical personnel."

Wikipedia

The main purpose of BDD is to facilitate the communication of an application's requirements between the stakeholders. We can write our software specifications in an easily readable and understandable syntax called Gherkin, which can also be used to create executable tests.

For this example, I'm going to use the Xamarin TaskyPro sample application. You can download the source code and run the application yourself, if you'd like. A precompiled binary is included in my sample.

Here you can see an example of defining the user-centric feature to add a new task to the TaskyPro list. Notice that this specification is easily understandable by developers and non-developers alike.

Feature: Adding a task  
  I want to be able to quickly add a task

  Scenario: Add a task
    Given I am on the Home screen
    When I add a new task called "Get Milk"
    And I save the task
    Then I should see the "Get Milk" task in the list

Unlike unit tests, these tests generally concentrate on exercising the full running application. In our case, this will mean running an iOS or Android application on a simulator/emulator or on a physical device.

Cucumber and Calabash

When testing mobile apps, there is an existing solution that brings BDD and Gherkin to iOS and Android testing. This is the open source project named Calabash. Calabash uses the Ruby based framework named Cucumber to execute the acceptance tests defined from our specifications.

Xamarin.UITest

Xamarin.UITest is a very similar framework to Calabash, except it allows us to write our tests using C# and execute them using one of the common .Net unit testing frameworks, typically NUnit.

Xamarin.UITest gives us the means to write tests which interact with and verify the running iOS and Android applications, much like Calabash, but it does so in a much more developer oriented way.

The same test as above, written in Xamarin.UITest, would look like this.

app.Tap (c => c.Class("UIButton").Marked ("Add"));  
app.EnterText (c => c.Class ("UITextField").Index (0), "Get Milk");  
app.EnterText (c => c.Class ("UITextField").Index (1), "Make sure to get the milk!");  
app.Tap (c => c.Class("UIButton").Marked ("Save"));  

While this obviously achieves our goal of having automated acceptance tests, it doesn't help very much with our goal of improving communication among all the stakeholders. Developers are very comfortable reading code, but managers, QA, executives, users, and other stakeholders are not. What's missing from Xamarin.UITest is the Gherkin language.

SpecFlow

SpecFlow fills that void and allows us to write our specifications as Features and Steps written using Gherkin. SpecFlow then enables us to write the definition of those steps as C# code.

We can combine SpecFlow and Xamarin.UITest to give us all the benefits of BDD and Gherkin while using the C# language that we know and love.

Create the test project

SpecFlow has a Visual Studio extension available which adds some templates and integration with the VS IDE. In Xamarin Studio, there is a SpecFlow addin available. The template will be installed in Other > Miscellaneous > General > SpecFlow NUnit Library Project

This will create a new class library with the NUnit and SpecFlow Nuget packages already added. Be sure to update the Nuget packages when you first create the project.

Add Xamarin.UITest

Next, we need to add the Xamarin.UITest Nuget package to the project.

Once the Xamarin.UITest Nuget package has been added, the Unit Test window in Xamarin Studio will show a new section titled "Test Apps". We'll use this shortly.

Cross platform tests

If we had used the Xamarin.UITest template when we first created our test project, instead of the SpecFlow template, we would have had a project containing two files; AppInitializer.cs and Tests.cs. The AppInitializer class is a static helper class that will return an appropriate IApp instance configured for the currently executing platform.

public class AppInitializer  
{
    public static IApp StartApp (Platform platform)
    {
        if (platform == Platform.Android) {
            return ConfigureApp
                .Android
                .StartApp ();
        }

        return ConfigureApp
            .iOS
            .StartApp ();
    }
}

The Tests class is where our NUnit tests would be defined. Notice the parameter to the [TestFixture()] attribute, which is where we can specify which platforms to run this set of tests on.

[TestFixture (Platform.Android)]
[TestFixture (Platform.iOS)]
public class Tests  
{
    IApp app;
    Platform platform;

    public Tests (Platform platform)
    {
        this.platform = platform;
    }

    [SetUp]
    public void BeforeEachTest ()
    {
        app = AppInitializer.StartApp (platform);
    }

    [Test]
    public void AppLaunches ()
    {
        app.Screenshot ("First screen.");
    }
}

Add test apps

When configuring our IApp instance, we will need to specify where the Xamarin.UITest framework can find the binary applications to install and run. In the AppInitializer class, we actually have two different ways to specify the path to these apps.

First, we could simply pass the path to the binary to the appropriate platform specific method, either ApkFile for Android, or AppBundle for iOS. This allows us to execute acceptance tests against any compiled Android or iOS application, even ones written in Java or Objective-C/Swift (along with Xamarin.iOS and Xamarin.Android, of course).

public static IApp StartApp (Platform platform, string iOSSimulator)  
{
    if (platform == Platform.Android) {
        return ConfigureApp
            .Android
            .ApkFile ("../com.xamarin.samples.taskydroidnew.exampleapp.apk")
            .StartApp ();

    } else if (platform == Platform.iOS) {
        return ConfigureApp
            .iOS
            .AppBundle ("../TaskyiOS.app")
            .StartApp ();
    }
}

Alternatively, as of Xamarin Studio 5.9, if we have the source code projects loaded in Xamarin Studio along with our test project, we can use the new Test Apps feature to point the test project at the source code project.

Once the test project knows about the source projects, the configuration no longer needs the path specified, and we can remove the ApkFile and AppBundle methods.

public static IApp StartApp (Platform platform, string iOSSimulator)  
{
    if (platform == Platform.Android) {
        return ConfigureApp
            .Android
            .StartApp ();

    } else if (platform == Platform.iOS) {
        return ConfigureApp
            .iOS
            .StartApp ();
    }
}

Adding features

At this point, the test project is ready to start defining our features. The first feature for our TaskyPro application will be Add a Task. Features in SpecFlow are defined using a feature file. We can add one of these to our test project using the built in Xamarin Studio template.

You can delete the contents of this file, and replace it with the business defined specification for our application.

Feature: Adding a task  
  I want to be able to quickly add a task

  Scenario: Add a task
    Given I am on the Home screen
    When I add a new task called "Get Milk"
    And I save the task
    Then I should see the "Get Milk" task in the list

When the project is saved and built, SpecFlow will read this feature file and create a partial C# class which can execute our test.

[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.0.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Adding a task")]
public partial class AddingATaskFeature  
{
  // .....
}

If there are any additions or customizations that we want to make to this class, we can implement the other part of the partial class (AddingATaskFeature.cs) and do it there.

public partial class AddingATaskFeature : FeatureBase  
{
  public AddingATaskFeature (Platform platform, string iOSSimulator) : base(platform, iOSSimulator)
  {
  }
}

Customizing the steps

You may ask "What magic lets the computer know what I mean by 'When I add a new task...' ?". Well, it's not magic, it's the magic of C#! Each SpecFlow step that you write needs to have a corresponding method defined in a C# class somewhere. The class needs to have a [Binding] attribute, and the methods will have either a [Given], [When], or [Then] attribute with a Regular Expression that will match the step defined in the feature file.

using TechTalk.SpecFlow;  
using Xamarin.UITest;

[Binding]
public class CommonSteps  
{
    readonly IApp app;

    [When (@"I add a new task called ""(.*)""")]
    public void WhenIAddANewTaskCalled (string taskName)
    {
        // Test code defined here ...
    }

    // More methods defined here ...
}

Each method will then use the Xamarin.UITest framework to exercise and test the app.

[When (@"I add a new task called ""(.*)""")]
public void WhenIAddANewTaskCalled (string taskName)  
{
  app.WaitForElement (c => c.Marked("Add Task"));
  app.Tap (c => c.Marked("Add Task"));
  app.Screenshot ("When I add a new task called '" + taskName + "'");
  app.WaitForElement (c => c.Marked("txtName"));
  app.EnterText (c => c.Marked("txtName"), taskName);
  app.Screenshot ("When I add a new task called '" + taskName + "'");
}

Cross Platform tests (part 2)

As you can see, our tests end up just being C# code. As with all code, we should try to not repeat ourselves. We want to write these test steps once and have them executed on both iOS and Android. The TaskyPro application presents a problem though. When the application was written, the various controls on the two platforms did not end up with the same text or the same name/id. This means that code which uses hard coded names in the Xamarin.UITest query selectors work on one platform and fail on the other.

app.EnterText (c => c.Marked("txtName"), taskName);  

To get around this, we first will define an interface for the "screen" in the app that we'll be testing. The interface has properties for each control on the screen that we want access to.

public interface IAddTaskScreen  
{
  Func<AppQuery, AppQuery> nameEntry { get; }
  Func<AppQuery, AppQuery> saveButton { get; }
  Func<AppQuery, AppQuery> deleteButton { get; }
}

Then, we create implementations of this interface for each platform, with the appropriate query selector.

Android

public class AndroidAddTaskScreen : IAddTaskScreen  
{
  public Func<AppQuery, AppQuery> nameEntry { get; } = new Func<AppQuery, AppQuery> (c => c.Marked("txtName"));
  public Func<AppQuery, AppQuery> saveButton { get; } = new Func<AppQuery, AppQuery> (c => c.Marked("btnSave"));
  public Func<AppQuery, AppQuery> deleteButton { get; } = new Func<AppQuery, AppQuery> (c => c.Marked("btnCancelDelete"));
}

iOS

public class iOSAddTaskScreen : IAddTaskScreen  
{
  public Func<AppQuery, AppQuery> nameEntry { get; } = new Func<AppQuery, AppQuery> (c => c.Marked("Name"));
  public Func<AppQuery, AppQuery> saveButton { get; } = new Func<AppQuery, AppQuery> (c => c.Marked("Save"));
  public Func<AppQuery, AppQuery> deleteButton { get; } = new Func<AppQuery, AppQuery> (c => c.Marked("Delete"));
}    

Depending on the current platform, as defined in the [TestFixture] attribute, we can add the correct screen definition to SpecFlow's FeatureContext object from the AppInitializer class. Note that I also defined some ScreenName constants in order to get nice IntelliSense.

public static void InitializeScreens(Platform platform)  
{
    if (platform == Platform.iOS) {
        FeatureContext.Current.Add (ScreenNames.Home, new iOSHomeScreen ());
        FeatureContext.Current.Add (ScreenNames.AddTask, new iOSAddTaskScreen ());
    } else if (platform == Platform.Android) {
        FeatureContext.Current.Add (ScreenNames.Home, new AndroidHomeScreen ());
        FeatureContext.Current.Add (ScreenNames.AddTask, new AndroidAddTaskScreen ());
    }
}

In the FeatureBase class, which is the base class for each Feature test in the project, we then call the InitializeScreens method before each NUnit test executes.

[SetUp]
public void BeforeEachTest ()  
{
  app = AppInitializer.StartApp (platform, iOSSimulator);
  FeatureContext.Current.Add ("App", app);
  AppInitializer.InitializeScreens (platform);
}

The class which defines our steps will then grab the implementations out of the FeatureContext. We now can rewrite our Step using strong typed abstractions which will use the correct query selector for the platform.

[Binding]
public class CommonSteps  
{
    readonly IHomeScreen homeScreen;
    readonly IAddTaskScreen addTaskScreen;
    readonly IApp app;

    public CommonSteps ()
    {
        app = FeatureContext.Current.Get<IApp>("App");
        homeScreen = FeatureContext.Current.Get<IHomeScreen> (ScreenNames.Home);
        addTaskScreen = FeatureContext.Current.Get<IAddTaskScreen> (ScreenNames.AddTask);
    }

    [When (@"I add a new task called ""(.*)""")]
    public void WhenIAddANewTaskCalled (string taskName)
    {
        app.WaitForElement (homeScreen.addButton);
        app.Tap (homeScreen.addButton);
        app.Screenshot ("When I add a new task called '" + taskName + "'");
        app.WaitForElement (addTaskScreen.nameEntry);
        app.EnterText (addTaskScreen.nameEntry, taskName);
        app.Screenshot ("When I add a new task called '" + taskName + "'");
    }
}

Multiple simulators/emulators

Lastly, when running the tests it is helpful to specify which simulators or emulators, including the operating system version, that you wish to execute on. Also, we generally want to reset the state of the simulator to clear any persistent state and run each test cleanly.

Note : resetting the iOS simulator currently only works on Mac, not through Visual Studio on Windows.

[TestFixture (Platform.Android, "")]

[TestFixture (Platform.iOS, iPhone5s.OS_8_1)]
[TestFixture (Platform.iOS, iPhone5s.OS_8_2)]
[TestFixture (Platform.iOS, iPhone5s.OS_8_3)]

[TestFixture (Platform.iOS, iPhone6.OS_8_1)]
[TestFixture (Platform.iOS, iPhone6.OS_8_2)]
[TestFixture (Platform.iOS, iPhone6.OS_8_3)]

[TestFixture (Platform.iOS, iPadAir.OS_8_1)]
[TestFixture (Platform.iOS, iPadAir.OS_8_2)]
[TestFixture (Platform.iOS, iPadAir.OS_8_3)]
public class FeatureBase  
{
    // ...
}

You can read the code for this in the source project.
Thanks to everyone on this forum post for the code

Running the tests locally

Xamarin Test Cloud

Even better than running these tests on local simulators and emulators would be to run them on hundreds or thousands of real devices. The great thing about using Xamarin.UITest is the ability to upload these tests to Xamarin Test Cloud. Xamarin Studio makes this as simple as right-clicking on the tests in the Unit Tests pad, and choosing Run in Test Cloud.

This will run all of the tests on either Android or iOS. You'll be able to see which tests pass or fail, the number of devices, OS versions, and a wealth of other information. We can even see the Gherkin steps in the Xamarin Test Cloud UI.

Sample code is available at my Github repo

May 04, 2015 2:08 GMT

Finding Nemo – Implementing Xamarin.Forms SearchBar

Xamarin.Forms gives you a component called the SearchBar, by default.

Like you would expect, this gives you a simple text edit box which is specifically designed to serve in search operations.

To show you how easy it is to implement, I will demonstrate how I built it into the sample app I have been using up till now, if you need to refresh your memory take a look at my previous post.
In this app there is an employee directory. Although this isn’t a endless list, it is desirable to quickly navigate to the right person. And how could we do it better than by searching?

First let’s take a look at how my ListView is before I make any changes.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FourDotNet.Pages.EmployeesPage"
             Title="Medewerkers">
  <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
    <ListView IsPullToRefreshEnabled="True" Refreshing="EmployeeListView_OnRefreshing" ItemTapped="EmployeeListView_OnItemTapped" x:Name="EmployeeListView">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ImageCell ImageSource="{Binding PhotoUrl}" Text="{Binding Name}" Detail="{Binding Function}">

            <ImageCell.ContextActions>
              <MenuItem Text="Stuur e-mail" Clicked="EmployeeContextEmail_OnClicked"></MenuItem>
            </ImageCell.ContextActions>
          </ImageCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </StackLayout>
</ContentPage>

As you can see I’ve made use of a simple StackLayout to put in a ListView which can be pulled to refresh, does something when an item is tapped and tells the list how to display a cell to the user.

In the running app this will be shown as underneath.

ListView without SearchBar

ListView without SearchBar

Adding a SearchBar is pretty easy, just go like this:

[...]
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
    <SearchBar Placeholder="Zoeken..." TextChanged="SearchBar_OnTextChanged"></SearchBar>
    <ListView IsPullToRefreshEnabled="True" Refreshing="EmployeeListView_OnRefreshing" ItemTapped="EmployeeListView_OnItemTapped" x:Name="EmployeeListView">
[...]

The Placeholder attribute sets the placeholder text when no search-term hasn’t been entered. The TextChanged is as advertised on the tin; the event that gets fired when the text is changed.

For the end-user the screen now looks like this;

ListView with SearchBar

ListView with SearchBar

Now lets have a look at the SearchBar_TextChanged event-handler.

private void SearchBar_OnTextChanged(object sender, TextChangedEventArgs e)
{
   EmployeeListView.BeginRefresh();

   if (string.IsNullOrWhiteSpace(e.NewTextValue))
      EmployeeListView.ItemsSource = _container.Employees;
   else
      EmployeeListView.ItemsSource = _container.Employees.Where(i => i.Name.Contains(e.NewTextValue));

   EmployeeListView.EndRefresh();
}

We are starting with telling the ListView that we are going to do some updates, so it will probably skip some redraw operations while we update the data inside it.

After that we check if the user has entered text, or cleared all text from the SearchBar and supply a corresponding ItemSource. Don’t forget to call the EndRefresh method, and that’s about it! Simple is it not?!

Now when you start entering text in the field it will start filtering in your ListView.

As a next step you would want to clean up your form code and not handle this there. So create a inheritance of a ListView which will handle filtering in its own, or create a composition of the SearchBar and the ListView to form a whole new component, a component which I like to call..

SearchableListView Dr. Evil meme

So far on the SearchBar for right now! Hope you’ll put it to good use.

May 04, 2015 12:40 GMT

Akavache is AKA Awesome!

In the last post we covered how to implement data caching in a cross platform application using Xamarin. And we also showed why providing a data cache to the users of our mobile applications is important.

Why caching is important
  • Network resiliency
  • Perceived app performance

However, the plumbing for the caching can be a bit of a pain to implement. The following diagram gives an example of the flow needed to implement caching. The order in which the tasks are implemented may vary based on the business requirements, some tasks may be omitted, but generally they are the same.

Ugh ... and this is just one of many different workflows!

Ugh … and this is just one of many different workflows!

Then we get to the characteristics of the data we want to cache. Obviously the data’s not volatile since we’re saving it for later use. Most likely we already know where and how we want to use the data within our app, so if we thought our design through, we’re saving the data in a way that it’s easy to get it and we’re not querying it in a relational manner. And the business requirements will dictate this, but the data already in the cache may not change where we have to update it.

So what if I told you there was a framework that provided everything above (and more), and made it super easy to implement the caching plumbing in a cross platform manner?

Enter Akavache

The official definition from Akavache’s GitHub site:

Akavache Logo

Akavache is an asynchronous, persistent (i.e. writes to disk) key-value store created for writing desktop and mobile applications in C#, based on SQLite3. Akavache is great for both storing important data (i.e. user settings) as well as cached local data that expires.

In other words, Akavache provides an awesome framework for caching data. It implements everything we mentioned above, and more (and in a way most likely better than we could have ourselves). Written by Paul Betts, it’s a library that I’m finding more and more useful every time I use it.

In the rest of this post we’ll take a look at the basic API that Akavache provides. Then in the next post we’ll refactor the code from the Cold Hard Data Cache Post on caching and see how much simpler and more elegant Akavache makes it.

Basic Installation and Usage

First things first – we’re going to need to install Akavache. It’s available via NuGet. Search “Akavache” and the top 3 results will look something like the following:

Akavache NuGet Options

Akavache NuGet Options


I found that trying to select “Akavache”, “Akavache.Core”, and “Akavache.SQLite3″ to install all at once makes Xamarin Studio unhappy. Select “Akavache.SQLite3″ first and install it. Then install “Akavache” and you’ll be off and running.

Akavache is asynchronous – which means it won’t block our UI. That’s not a bad thing and not even a difficult thing, just something to be aware of.

At its heart, Akavache is a key/value store with a SQLite backend. To simplify how it stores data, there’s a table which has a column for the key which is a VARCHAR and another for the value which is a BLOB. (There are also columns for the CLR type of data in the blob column, another column for the expiration date of the cached data, and another for the created date).

The cool thing about using the key/value model of persisting data is that we can put anything into the value portion. It can range from a simple object with nothing but properties, to a collection of objects, to a complex object hierarchy with nested objects within objects … etcetera and so forth.

As far as using the Akavache framework, the first thing to note is that everything in Akavache is accessed through an objected called

BlobCache
.

To define where the database will reside within the app’s sandbox, we set a property on the BlobCache object called ApplicationName. So we end up with something like the following:

Akavache.BlobCache.ApplicationName = "AkaAwesome";
There’s nothing fancy going on here, this is just basic setup stuff.

The BlobCache object exposes 4 different objects which can cache data for us. Each of these object implement the IBlobCache interface.

IBlobCache Description
BlobCache.LocalMachine Local machine cache (normal SQLite as described above).
BlobCache.InMemory Volatile cache (gone on restart).
BlobCache.Secure Encrypted cache within SQLite.
BlobCache.UserAccount User account cache. This acts the same as the LocalMachine above, except the SQLite database file will get backed up by Apple backups, while the LocalMachine database file does not.
Update (5/5/15): Paul Betts sent me a tweet to clarify the difference between the LocalMachine and UserAccount objects. Previously I had stated the UserAccount object was not of much use on a mobile device, turns out it is very useful.

When using the UserAccount cache in iOS, Akavache will ensure the SQLite database file is created in the proper location so the file is backed up (as in iCloud or iTunes backups). The database file used by the LocalMachine cache object is created in a location where it is not backed up.

The vast majority, if not all, of the time we’ll be using the LocalMachine or UserAccount object in our mobile apps. So let’s talk about getting data into, and out of the cache.

Inserting Objects

Method Description
InsertObject<T>(key, T, expiration) Insert single object of type T with key and optional DateTimeOffset expiration
InsertAllObjects<T>(dictionary, expiration) Insert all objects in IDictionary with optional expiration

The first function above will insert any object into the cache taking an optional parameter of when it should expire – or be deleted and not be returned from the cache any longer.

The second function does the same, but with multiple objects at a time.

A quick code example of adding a Question object that expires 2 hours from now:

var question = new QuestionInfo { QuestionID = 1, Title = "Hello?" };

await BlobCache.LocalMachine.InsertObject<QuestionInfo> (
    "first", 
    question, 
    DateTimeOffset.Now.AddHours (2));

Getting Objects

Method Description
GetObject<T>(key) Return single object via its key
GetAllObjects<T>() Return all objects of type T

These methods will return an object of type T if it exists in the cache. Pretty straight forward. One thing to watch out for is that if the key does not exist, an exception of the type
KeyNotFoundException
will be thrown.

In action it looks like the following:

try {
    var question = await BlobCache.LocalMachine.GetObject<QuestionInfo> ("first");
} catch (KeyNotFoundException) {
    // do something useful
}

Fetching Objects

Method Description
GetOrFetchObject<T>(key, Func<T>, expiration) Returns cached result – if none exists – execute the Func<T> parameter to load result, put it in the cache and expire it according to optional expiration parameter
GetAndFetchLatest<T>(key, Func<Task<T>>, Func<DateTimeOffset, bool>, DateTimeOffset?) Returns cached result. Also goes ahead and uses the function in the second parameter to load the latest value and put that into the cache. So this method will return twice – once with the value from the cache and again when it updates with the latest value. So as the official documentation says, awaiting this function is a "Bad Thing" and that we subscribe to it instead.

These two functions are where Akavache really starts to become awesome! In the first function we’re saying – give me what’s in the cache – can’t find it? No worries, just call the function I’m passing in, stick the result in the cache and give me the result. That’s awesome!

var question = await BlobCache.LocalMachine.GetOrFetchObject<QuestionInfo> (
    "first",
    async () => await StackAPI.GetQuestionFromWeb (123),
    DateTimeOffset.Now.AddHours (3)
);

The second is even better – it takes a bit to fully understand it though. We’re saying, give me what’s in the cache, but at the same time call the function I’m passing in and get the latest value. This way we can make our user interface super responsive and keep the UI and cache up to date with the latest data!

But because the function is returning twice we can’t await it – so we have to use Subscribe, so every time our value changes we’re alerted to it.

I told you – flipping awesome!

QuestionInfo augusteRodin;

BlobCache.LocalMachine.GetAndFetchLatest ("theThinker", 
    async () => await DownloadQuestion (), null, null).Subscribe (
    cachedThenUpdatedThought => {

        augusteRodin = cachedThenUpdatedThought;

        Device.BeginInvokeOnMainThread (() => theStatue.Text = augusteRodin.Title);


    });

Downloading

Method Description
DownloadUrl(url,IDictionary(string,string) headers, fetchAlways, expiration) Download the contents of the URL (using the URL as the key in the cache). By setting the fetchAlways boolean, can always hit the web to download.
LoadImageFromUrl(url, fetchAlways, desiredHeight, desiredWidth, expiration) Tries to load the image from the cache and if it does not exist, then download it from the internet. Of course, obeying the fetchAlways boolean.

These are pretty awesome functions too, and they’re straightforward.

We’re going to download either an array of bytes, as in the first function, or a cross platform IBitmap in the second function.

var talkingCats = await BlobCache.LocalMachine.LoadImageFromUrl ("http://catimages.com", false);

Deleting Objects

InvalidateObject<T>(key) Removes object corresponding to the key with type of T from the cache
InvalidateAllObjects<T>() Removes all objects of type T from the cache
Vacuum Removes all expired objects from the cache

Maintenance functions – not the most glamorous, but still necessary (and hopefully self-explanatory).

Conclusion

Akavache – our new most awesome friend in the world! Taking all of the tedious maintenance out of implementing caching plumbing so we can concentrate on creating great apps for our users.

Akavache employs a SQLite backend to store key/value pairs of objects. The value portion of those objects are stored in BLOB fields so they can hold anything from a plain POCO object to the most complex object hierarchy. Akavache gives us an easy to use API to store, delete and retrieve objects from the cache, including some sweet functions to automatically download info if it doesn’t exist and update the cache with the latest info.

So fire up Xamarin Studio or head on out to Github or NuGet and see for yourself why Akavache is Also Known As Awesome!

May 04, 2015 12:00 GMT

Xamarin.Forms in Anger – HeatMap

I am a Google Analytics junkie! There, I said it, I’m addicted to Page Views and Sessions statistics. My addiction is so bad that I installed the Google Analytics App on my iPhone and I check it often. Too often.

The Page Views heat map is the feature I like the most. The map shows me when people visit this site. My heat map shows a concentration of visitors whenever I release new blog posts, no surprise there. What is a surprise is how nice the heat map looks. Whenever I see a good looking UI, I think, can I build it in Xamarin.Forms? And the answer is, yes, yes we can.

The Blueprint

I think this might be the easiest blueprint of all the “In Anger” posts. Only 6 types and most of them are just supporting actors. The Grid and BoxView are the heroes of this UI.

HeatMap

The Code

For this post I went all out and separated the data and styles into different classes. I want you to see how easy it was to build this UI without all the B list celebrities getting in the way. If you want to see all the gory details, check out the GitHub repository.

public class HeatMapApp 
{
	Grid heatMap;

	public Page GetMainPage ()
	{
		SetupHeatMap ();

		AddHoursColumn ();
		AddWeekDayRow ();

		AddHeatSquares ();

		var stack = new StackLayout () {
			Padding = new Thickness (5, 0, 10, 0),
			Spacing = 0,
			Children = {
				new Label () {
					Text = "Page Views",
					Style = AppStyles.PageViewLabelStyle
				},
				new Label () {
					Text = "24,098",
					Style = AppStyles.PageViewCountLabelStyle
				},
				heatMap
			}
		};

		return new NavigationPage (new ContentPage () {
			Title = "Behavior",
			Padding = new Thickness (0, 5, 0, 0),
			Content = new ScrollView () { 
				Content = stack
			}
		});
	}

	public void SetupHeatMap()
	{
		heatMap = new Grid () {
			ColumnSpacing = 2,
			RowSpacing = 2,
			VerticalOptions = LayoutOptions.FillAndExpand
		};

		Enumerable.Range (1, 25).ToList ().ForEach (x =>
			heatMap.RowDefinitions.Add (
				new RowDefinition { Height = GridLength.Auto }
			));

		Enumerable.Range (1, 8).ToList ().ForEach (x =>
			heatMap.ColumnDefinitions.Add (new ColumnDefinition { 
				Width = new GridLength (1, GridUnitType.Star) 
			}));
	}

	private void AddHoursColumn()
	{
		var hours = AppData.Hours;

		for (int i = 0; i < 24; i++) {
			heatMap.Children.Add (new Label () { 
				Text = hours [i],
				Style = AppStyles.HoursLabelStyle
			}, 0, i + 1);
		}
	}

	private void AddWeekDayRow()
	{
		var days = AppData.Days;

		for (int i = 0; i < 7; i++) {
			heatMap.Children.Add (new Label () { 
				Text = days [i],
				Style = AppStyles.DaysLabelStyle,
			}, i + 1, 0);
		}
	}

	private void AddHeatSquares()
	{
		var values = AppData.Values;
		var colors = AppStyles.Colors;

		for (int i = 0; i < 7; i++) {
			for (int j = 0; j < 24; j++) {
				heatMap.Children.Add (new BoxView () { 
					Color = colors [values [i, j]],
					HeightRequest = 15
				}, i + 1, j + 1);
			}
		}
	}
}

The majority of the sample code deals with the setup and labeling of the Xamarin.Forms Grid. The only tricky bit was using the Enumerable.Range to loop through the days and hours for the labels. You can replace these with ForEach blocks if you like.

I’ve never needed a heat map for my applications but when I do, I’ll be ready. How about you? Have you ever used a heat map?

PS. I just want to say thank you for visiting my blog. I hope you find it helpful. If you have a question, please ask.

Xamarin.Forms in Anger Series

Can Xamarin.Forms produce good looking cross-platform UI from a single codebase? Each “In Anger” blog post will tackle a single page of a beautifully designed iOS or Android application. My job will be to reproduce the design in Xamarin.Forms as faithfully as possible. InAnger-Strip-6

The post Xamarin.Forms in Anger – HeatMap appeared first on Syntax is my UI.

May 03, 2015 1:00 GMT

NuGet Support in Xamarin Studio 5.9

Changes

  • NuGet 2.8.3 support
  • Always show Packages folder in Solution window
  • Target framework change detected on project reload

More information on all the new features and changes in Xamarin Studio 5.9 can be found in the release notes.

NuGet 2.8.3 support

Xamarin Studio now supports NuGet 2.8.3. This allows a NuGet package to target NuGet 2.8.3 explicitly. For example the PCLStorage 1.0.1 NuGet package will not install into Xamarin Studio 5.8, since it requires NuGet 2.8.3, but will install into Xamarin Studio 5.9.

NuGet packages, such as xunit, that target the new ASP.NET target frameworks, ASP.NetCore 5.0 and ASP.Net 5.0, can now be installed into Xamarin Studio now that it supports NuGet 2.8.3. Previously you would see an error message in the Package Console window:

'xunit.core' already has a dependency defined for 'xunit.extensibility.core'.

Support for NuGet 2.8.5 is planned for Xamarin Studio 5.9.1.

Always Show Packages Folder in Solution window

The Packages folder is now always shown in the Solution window even if the project has no NuGet packages. Previously the Packages folder would only be shown if one or more NuGet packages were installed in a project.

Packages folder in Solution window

Target Framework Change Detected on Project Reload

Xamarin Studio will detect a project file has been changed outside of Xamarin Studio and will reload the project. Now Xamarin Studio on reloading will detect the project’s target framework has been changed and will check the NuGet packages are compatible with the new target framework. Previously Xamarin Studio would only check the compatibility of NuGet packages if the target framework was changed from within Xamarin Studio via the project options.

This allows Xamarin Studio to check the NuGet packages are compatible when an iOS Classic project is converted to an iOS Unified project using Xamarin Studio’s migration tool. The NuGet packages, such as Xamarin.Forms, can then be retargeted by Xamarin Studio using the Retarget menu.

May 03, 2015 12:03 GMT

Introducing SVQXDG

Going back from past dotNet Conference Spain 2015, Javier Suárez and I shared our passion on Xamarin at the train’s cafeteria. We both liked the idea of having a local user group where talking about our projects made with Xamarin, which are the latest news, meet some other people doing the same things, etc.

Today I would like to introduce Sevilla Xamarin Developer Group, specially our first meetup, this following Wednesday 6th. We will have people who are landing from Build 2015, and it is thrilling for me to chat with those since the past days have been quite interesting for cross-platform mobile developers.

SVQXDG

If you are around Seville during this week (hey Andalusians we are looking at you!), and would like to attend, please visit our Meetup group and join us! Thank you!


May 02, 2015 6:40 GMT

Voice Dictation with WatchKit and Xamarin

Apple Watch has fantastic support for converting speech to text. However, there isn’t any direct API access to the text to speech engine in WatchKit. You can get access to it in your apps though via the Apple provided text input controller.

golf watch text input

You can open a text input controller via WKInterfaceController’s PresentTextInputController method. For example, here’s how I show a list of golf course names to start a new golf round in my app GolfWatch:


PresentTextInputController (courseNameList.ToArray (), WKTextInputMode.Plain,
delegate(NSArray results) {
// ...
}
});

In this case a list of course names is displayed along with a button, which when tapped opens a ui to receive speech input. The results are passed to the completion method specified in the third argument to PresentTextInputController. If you only want speech input, simply pass an empty suggestions array in the first argument and the user will be taken directly to the speech input screen on the device (speech input isn’t supported in the simulator).


May 02, 2015 4:16 GMT

Using compiled bindings in your Windows 10 universal app

One of the news in the Windows 10 SDK is that you can use compiled binding. In pre Windows 10 bindings was created in run time. When you’re building your windows universal app for windows 10 you can created bindings in compile time. This to boost the performance of the bindings, compiled bindings will make the page load much faster. This blog post will introduce you with the basics of compiled bindings.

To create a binding that will be created in compile time you will use x:Bind instead of Binding to create the binding.

      <TextBlock Text="{x:Bind Title}" />

One big difference against is that the binding will not be to DataContext, it will be to the page. If the code above should work you have to create a Title property in the code behind file. If you don’t do that you will get a error when you compiling your app. The reason to to bind to the actuall page instead of DataContext is that DataContext is of type object and the compiler will not know what you will assign to it during run time. Because you binding to the actual page it is also possible to bind directly to other controls on your page.

If you using a binding in a data template you have to specify data type for the data template with x:DataType as in the code below. Don’t forget to declare the namespace for your data type. In this example I have created a property in my code behind file called ViewModel that has a Items property that I binding to the ItemsSource of the ListView.

<ListView ItemsSource="{x:Bind ViewModel.Items}">  
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="model:ItemModel">
                        <TextBlock Text="{x:Bind Title}" />
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

The code behind can looks like the code below. In this example DataContext is set when the view is created and the ViewModel will have a method for loading data.

public sealed partial class ItemsView
{
        protected ItemsViewModel ViewModel { get { return DataContext as ItemsViewModel; } }
 
        public ItemsView()
        {
            this.InitializeComponent();
            DataContextChanged += ItemsView_DataContextChanged;
        }
 
        private async void ItemsView_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
        {
            if(ViewModel != null)
            {
                await ViewModel.LoadData();
            }
        }
}
May 02, 2015 11:35 GMT

Supercharging Xamarin Forms with Custom Renderers, Part 5

Making Xamarin Forms Richer with Custom Visual Elements

The BoxView class is handy for drawing rectangles in a Xamarin Forms UI. On Windows Phone, a BoxView renders a Rectangle element. On iOS and Android, it paints a rectangle onto a graphics context and a canvas, respectively. But what about other graphics primitives such as ellipses and paths? Windows Phone, Android, and iOS all support them, but Xamarin Forms doesn’t surface any of them as visual elements.

Good news: You can implement new visual elements in Xamarin Forms with custom renderers. Most renderers in Xamarin Forms wrap controls such as TextBlocks and UILabels. But renderers aren’t required to emit controls; some, such as the BoxRenderer classes found in iOS and Android, don’t output controls at all. Instead, they paint pixels depicting BoxViews onto a drawing surface. You can do the same to extend Xamarin Forms with custom visual elements.

The custom element presented in this article is EllipseView. You can declare instances of EllipseView in a Xamarin Forms UI the same way you declare BoxViews. EllipseView exposes the exact same properties as BoxView, including the Color property that controls the color of the element’s interior. Here’s a bubbly UI built with an AbsoluteLayout and a few EllipseViews:

Ellipses

And here’s the XAML that produced that UI:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:EllipseViewDemo;assembly=EllipseViewDemo"
             x:Class="EllipseViewDemo.MainPage"
             BackgroundColor="#FFBCA9F5">
             
    <AbsoluteLayout>
        <local:EllipseView Color="White" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="-60, -60, 400, 400" />
        <local:EllipseView Color="#FFF5A9F2" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="-40, -40, 360, 360" />

        <local:EllipseView Color="White" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="60, 380, 200, 200" />
        <local:EllipseView Color="#FFF2F5A9" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="80, 400, 160, 160" />

        <local:EllipseView Color="White" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="200, 220, 300, 300" />
        <local:EllipseView Color="#FFBCA9F5" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="220, 240, 260, 260" />

        <local:EllipseView Color="White" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="200, 360, 400, 400" />
        <local:EllipseView Color="#FFF781F3" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="220, 380, 360, 360" />

        <local:EllipseView Color="White" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="-100, 600, 600, 600" />
        <local:EllipseView Color="#FF81F79F" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="-80, 620, 560, 560" />

        <local:EllipseView Color="White" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="360, -40, 200, 200" />
        <local:EllipseView Color="#FFF2F5A9" Opacity="0.4"
            AbsoluteLayout.LayoutBounds="380, -20, 160, 160" />
    </AbsoluteLayout>

</ContentPage>

You could use the same techniques I used to build EllipseView to extend Xamarin Forms to support PolygonView, PathView, and other visual elements.… Read more

May 01, 2015 2:56 GMT

Damn it! Can’t you make your code less complex?

<Rant>

I am so tired of complex code that can’t be read without having to trace definitions within definitions withshutterstock_132360455in references, within Interface definitions within indirection….  until I have no flippin’ idea what is going on.

This is even worse when perpetrated in sample code.  Can someone please tell sample code writers that the rule is “make it as simple as possible and demonstrate only one thing; and that one thing is not how clever you are.”

Continued

 

 

May 01, 2015 1:27 GMT

Weekly Xamarin Newsletter Issue #38

Objective-C Categories in Xamarin.iOS
Adam Kemp shows you how to do the difficult and impossible with C#.

Xamarin.Forms TableView Recipe – with Bacon
I (Adam) save my bacon and my pride with Xamarin.Forms TableView.

Xamarin Passes 1 Million Developer Milestone
Nat Friedman, from Xamarin Inc., announced that Xamarin passed 1 million developers.

Creating a Xamarin Forms Accordion Control, without custom renders
Jonathan Yates gets creative without using custom renderers in Xamarin.Forms.

Sara Silva Xamarin Workshop Guide

7. Add support for WinRT Apps
8. Change the App.cs to App.xaml
9. Use MVVM pattern

Xamarin.Forms RelativeLayout Recipe
I (Adam) put my dog Alabama in the spotlight for Xamarin.Forms.

Delivering High Quality Apps with Every Submission
Michael James gets serious about testing with Xamarin Test Cloud.

Taming The Android Activity, Part 1
Adam Kemp gets back to basics with Android’s core building block, the Activity.

CocosSharp Beginner Series : Setup your Machine
XHackers Team shows you how to get up and running with CocosSharp.

Setting up a VPN server on a Mac and using it for #Xamarin.iOS development
Laurent Bugnion, from GalaSoft, gives Windows uses more options when developing for iOS.

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

May 01, 2015 1:41 GMT

Combining Xamarin Forms with Windows Universal Apps

One of the most exciting news at this years //Build/ conference was Microsofts commitment to Universal Apps. One binary and one store for all Windows 10 devices available, ranging from a Rasberry Pi to Xbox.

This did however raise a concert from my part. What will the integration with Xamarin and specifically Xamarin Forms look like?

The way I would most probably suggest, knowing what I know today, is to create a Xamarin Forms project but drop the Windows Phone project and create a universal project to represent the windows platform. You might want to keep the WP project if you want to support WP 8.0 (silverlight) though.

I would also use a Mvvm-framework, like MvvmCross or MvvmLight to share ViewModels between all projects. I still think MVVM is the way to go to achive the most code share possible.

It's also going to be interesting to see what Xamarin Forms for Windows is going to target in the end.

Bottom line, it looks like you are going to have build two sets of UIs from now on...
April 30, 2015 3:37 GMT

Objective-C Categories in Xamarin.iOS

One of the cool things about Objective-C is how dynamic it is. This includes the ability to add methods to classes that already exist even at runtime. Categories are a feature of Objective-C that can be used to do all kinds of things that might otherwise be difficult or impossible, but until very recently this feature has been inaccessible from C#. This post will explain what categories are, what they're used for, how to use them in C# using Xamarin.iOS 8.10, and a useful example.

What are Categories?

A category in Objective-C allows you to add a method to a class that already exists. This method can then be called from other code as if that method were a normal method on the original class. For example, you could add a ROT13 method to NSString. In Objective-C that would look like this:

@interface NSString (ROT13)

-(NSString*)rot13;

@end

@implementation NSString (ROT13)

-(NSString*)rot13
{
// ...
}

@end

Once you've written that code anyone who knows that this method exists (by #importing the right header) can call this method on any NSString:

self.textField.text = [self.textField.text rot13];

Categories vs. Extension Methods

Objective-C categories are similar to C# extension methods. An extension method is also a way of adding a new method to an existing class in C#. For instance, you could add the same kind of ROT13 method to the C# string class like this:

public static class MyStringExtensions
{
public static string Rot13(this string input)
{
// ...
}
}

And then any code that has access to MyStringExtensions can call that method on any string:

textField.Text = textField.Text.Rot13();

Obviously these two features are very similar, but there are a few key differences. One of the biggest differences is that an Objective-C category is treated just like any other method, and every method in Objective-C is virtual. Therefore category methods are also virtual, which means you can define one for a class and then a subclass can override it like any other method. Likewise, you can use a category to override a method from a parent class from outside that class.

For example, consider these classes:

@interface Parent : NSObject

-(void)doSomething;

@end

@interface Child : Parent

@end

@implementation Parent

-(void)doSomething
{
NSLog(@"Parent");
}

@end

@implementation Child

@end

With this code it is obvious that calling doSomething on an instance of Child will print "Parent" because the child class doesn't have its own implementation. Using a category, however, you could add an implementation from some other file (even if you don't have the source code to either class) like this:

@interface Child (MyCategory)

-(void)doSomething;

@end

@implementation Child (MyCategory)

-(void)doSomething
{
NSLog(@"Child");
}

@end

Now if you call doSomething on an instance of Child you will see "Child" printed.

Another difference between extension methods and categories is that extension methods are just syntactic sugar for calling a normal static method. That is, these two lines compile to the exact same code:

textField.Text = textField.Text.Rot13();
textField.Text = MyStringExtensions.Rot13(textField.Text);

The method isn't really added to string, and if you use reflection you won't see it listed. On the other hand, Objective-C categories are just like any other method in Objective-C, which means if you use the runtime to list the available methods for NSString you would find your rot13 method listed.

Categories in Xamarin.iOS

Starting in Xamarin.iOS 8.10 you can now create your own categories from C#. This allows you to do some things in C# that you previously might have to resort to writing some Objective-C code to do (see below for a useful example).

The syntax for writing categories in Xamarin.iOS is actually the same as writing an extension method but with a few added attributes. Here is our ROT13 category again in C# this time:

[Category(typeof(NSString))]
public static class MyStringExtensions
{
[Export("rot13")]
public static NSString Rot13(this NSString input)
{
// ...
}
}

The cool thing is that this method is now both an extension method and a category. That means that you can call if from C# code:

textField.Text = textField.Text.Rot13();

and from Objective-C:

self.textField.text = [self.textField.text rot13];

Example: Find The First Responder

Like most UI platforms, iOS has the concept of a focused element. There is a class called UIResponder that has methods for things like touch events and deciding what kind of keyboard to show and so on. At any given moment in time there is exactly one of these responder objects that is the "first responder"1. For example, when a UITextField gains focus it becomes the first responder (by calling BecomeFirstResponder()), which ultimately triggers the keyboard to appear. The keyboard can then ask the first responder which type of keyboard should appear.

However, there is an annoying gap in the iOS API for responders: there is no public API for getting the first responder. That is, while the iOS keyboard can ask the first responder which type of keyboard should appear there is no way for your code to even know what the first responder is so that you can ask the question.

However, there is a way to work around this by using categories along with the UIApplication SendEvent method. SendEvent lets you send a message up the responder chain starting from the first responder. "Sending a message" in Objective-C means "calling a method" so this lets you call a method on the first responder. The trick then is to call your method on the first responder, and you can do that if you create a method just for that purpose. Once your method is called you have access to the first responder in the this variable, and you can send that back to the sender.

Here is what it looks like:

/// <summary>
/// Utilities for UIResponder.
/// </summary>
public static class ResponderUtils
{
internal const string GetResponderSelectorName = "AK_findFirstResponder:";
private static readonly Selector GetResponderSelector = new Selector(GetResponderSelectorName);

/// <summary>
/// Gets the current first responder if there is one.
/// </summary>
/// <returns>The first responder if one was found or null otherwise..</returns>
public static UIResponder GetFirstResponder()
{
using (var result = new GetResponderResult())
{
UIApplication.SharedApplication.SendAction(GetResponderSelector, target: null, sender: result, forEvent: null);
return result.FirstResponder;
}
}

internal class GetResponderResult : NSObject
{
public UIResponder FirstResponder { get; set; }
}
}

[Category(typeof(UIResponder))]
internal static class FindFirstResponderCategory
{
[Export(ResponderUtils.GetResponderSelectorName)]
public static void GetResponder(this UIResponder responder, ResponderUtils.GetResponderResult result)
{
result.FirstResponder = responder;
}
}

What I'm doing here is adding a method (using a category) to UIResponder, and then I'm calling that method by using SendEvent. Since the call is going to ultimately come from Objective-C I'm using the Selector (the name of the method in Objective-C2) to tell it which method to call, and that Selector matches the string I used in the Export attribute.

When my category method is called the first responder is the this argument of the extension method. Once I have that I just need to somehow send it back to the code that called SendEvent. For that I use a temporary container class allocated in the caller and sent as an argument. The category method just pokes the this argument into the container, and then the caller will have access to it.

There is a complete example of this on GitHub. In the full example application I use GetFirstResponder to find which text field got focus when the keyboard is shown, and I use that to change a property of the text field. This is easier than handling an event on each text field separately. You could also use this to find the view that has focus in order to scroll so that the focused view remains visible.

Summary

Categories are a powerful feature in Objective-C, and now that they are available to C# developers there are all kinds of possibilities for what you can do that was just not possible before (without writing Objective-C).


  1. The word "first" is used because the responders actually form a linked list called the "responder chain", and events can propagate up the responder chain. The responder chain usually mirrors the view hierarchy, but other objects like view controllers, the application delegate, and the application itself also participate in the responder chain. 

  2. For more information about Objective-C selectors, how the runtime works, and how Xamarin.iOS is implemented see this video

April 29, 2015 10:36 GMT

1 Million Developers, Xamarin.Forms UAP, & I’m Speaking at Build!

Whoa! What an amazing day! Today Xamarin reached 1 Million Developer downloads, released awesome new Xamarin.Forms goodness, and tons of other updates to kick off Build. If you didn’t see the full announcement be sure to check it out on the Xamarin Blog.

If you are here at Build I hope that you are sporting that awesome Xamarin shirt from the Xamarin Build party. 

I am honored to be giving two presentations at this years Build, including a sessions with one of my favorite people in the entire world, Miguel de Icaza.

Be sure to stop by the Xamarin booth and say hi and come to one of my presentations on Friday!

Building Multi-Device Apps with Xamarin and Office 365 APIs

  • Date: May 1, 2015 from 9:00AM to 10:00AM
  • Day 3
  • Room 2014
  • 3-661

Go Mobile with C#, Visual Studio, and Xamarin

  • Date: May 1, 2015 from 2:00PM to 3:00PM
  • Day 3
  • Hall1 B
  • 3-770
April 29, 2015 7:06 GMT

Consistent Mobile UI Theming

Xamarin Forms allows us to write code once that targets all three major platforms – iOS, Android, and Windows Phone. But the default color palette for the platforms differ – iOS prefers a light background with dark text, while the default themes for Android and Windows Phone are the opposite of that. And unfortunately for us, that’s usually not good news. From a branding perspective, it is advantageous to have a consistent color palette between our application properties – no matter which mobile platform our application is running on. Furthermore, if we need to produce artwork (icons, glyphs, background images, etc.) for our app, then we would prefer to only need to do that work once.

The simplest and easiest way to provide that consistency among the three platforms is through themes. While Apple prefers that applications on their platform adhere to the visual theme of the operating system, both Android and Windows Phone offer ways to customize the theme elements. In my previous post, you saw how I used a custom Android theme to hide the Main Activity Icon while also switching the UI over to a light-background theme. In this post, we will do the same for Windows Phone.… Read more

April 29, 2015 5:46 GMT

Visual Studio Code with Xamarin on a Mac

Microsoft just announced a new cross-platform editor that has many of the features of Visual Studio called Visual Studio Code. I downloaded it on my Mac to try out with a Xamarin.iOS project and see if it works. I was pleased discover it works out of the box (as far as I can tell on a first look).

Visual Studio Code works against files and folders. When you open a folder where a Xamarin.iOS project lives, all the files load fine and features such as links to references and even intellisense on iOS classes work great.

Here’s a class that implements a UIView subclass for example showing intellisense on CALayer:

vscode

You can download Visual Studio Code at: https://code.visualstudio.com/Download


April 27, 2015 8:44 GMT

The best design is no design at all: AppleWatch Edition

No, not THAT AppleWatch Edition. From Supertop, makers of Unread

One Less Thing… We spent a lot of time not making a Watch app. We love our new wrist computers but they are not the place for reading articles.

This. 100 times this. So many of the watch apps I've seen - and Today Extensions - should never have been written. Just because you CAN write a Watch extension, doesn't mean you should, especially if all it does is launch your phone app (ahem Evernote).

Out of my three remaining apps:

  • Nearest Bus is a prime candidate for a watch app. That's next on my list.
  • Trip Wallet should never have one. Ever. No reason at all.
  • MobileAgent could - starting a timer or mileage maybe, but otherwise, no. If there was a way to get realtime, pushed bank account info that might be somewhat useful, but really, it's just a notification.

And of the ones I work in at the day job (not that I have much say in which ones would get it):

  • goMoney - balances and transfers maybe, but as there is no push of information to the phone (and hence watch), it's not overly useful (IMO - the company might think otherwise). It's just a notification in the end (and how often do you do a transfer?)

So think carefullly about if a Watch app - or a Today Extension for that matter - even makes sense1 before you commit to making one.


  1. It might be that it doesn't make UX/technical sense, but it has marketing value. Thats fine, I guess.... ¯\_(ツ)_/¯

April 27, 2015 4:00 GMT

Hiding the Android Activity icon in Xamarin Forms

In my previous post, I introduced a simple demo app that used the Stack Navigation Pattern. This is a standard pattern frequently used on all phone platforms to present hierarchically organized pages of information. In my demo app, it was used to navigate to each of the three detail pages from a main starting page. It is referred to as “stack navigation” because you can always return to the previous page.

On Windows Phone, this is done using the hardware “Back” button that resides below the touchscreen interface. On iOS devices, this is done using a UI button that is placed into the top navigation bar (on the left end of the bar). And on Android, both mechanisms are supported. There is a hardware button below the touchscreen as well as a UI button in the top navigation bar.

However, on Android the default behavior of a Xamarin Forms application is to display the application’s icon (the Main Activity’s icon) into this same area of the top navigation bar – and this behavior is fine for apps that don’t use stack navigation. But for apps that use stack navigation, this leads to a cluttered navigation bar which simply doesn’t look all that great (IMO).… Read more

April 27, 2015 2:59 GMT

Monday morning i San Francisco

Today it’s the second day in San Francisco. The day started early with running, the second run with my new Microsoft Band (I bought it the first I did when we arrived). I really enjoy it. I have a lots of ideas how to use Microsoft Band in my apps.

Right now we’re sitting in the hotel lobby (me, Karl-Henrik, Johan and Anders) and writing code, Johan is working on new cool Xamarin.Forms control for iOS and I will start to write the Windows Phone implementation for it.

On Wednesday the Build conference will start, the reason for our trip to San Francisco. Really looking forward to it. The key note was amazing last year and I think it will be at least so amazing this year.

April 27, 2015 2:32 GMT

Xamarin.Forms and iOS segemented control

A common control in many iOS apps is the segmented control. Xamarin.Forms has no support for the segemented control out of the box. This blog post will show you how to create a control in Xamarin.Forms that is mapped to UISegmentedControl in iOS.

In my sample I have named the control, FilterControl because is often used as a filter control and if you write a implementation of the control on the other platforms it will maybe not look lite the segmented control.

To make the control usefull I need to be able to bind items to it, bind to selected index, have an event that is thrown when selected index is changed and be able to change the color.

The first I will do is to create a class in the shared project that inherits from View.

If the properties will be bindable you have to create a BindableProperty as shown in the code below.

To set the choises (items) of the control we’re creating a List of strings.

public static readonly BindableProperty ItemsProperty =
			BindableProperty.Create<FilterControl, List<string>>
		(p => p.Items, new List<string>());
 
public List<string> Items 
{
	get 
        {
		return GetValue (ItemsProperty) as List<string>;
	}
	set 
        { 
		SetValue (ItemsProperty, value);
	}
}

When the control is defined next step is to create a renderer for iOS. The renderer will inherit from ViewRenderer.

public class FilterControlRenderer : ViewRenderer<FilterControl, UISegmentedControl>

In the override of the OnElementChanged we will create the native control, UISegmentedControl. I will put the code to map the list of choises to the segment control in a separate private method so I also can use it if the list of choices is changed. Then I will call it from the override of the OnElementPropertyChanged method.

You need to listen to ValueChanged of the UISegmentedControl so you can write the value back to the Xamarin.Forms control. In the event for selection changed I want both the old and new value, there for will I dont set selected index from the renderer. Instead I call a method in the control that is setting SelectedIndex and throwing the selection changed event.

protected override void OnElementChanged (ElementChangedEventArgs<FilterControl> e)
{
	base.OnElementChanged (e);
 
	var segmentControl = new UISegmentedControl ();
        SetNativeControl (segmentControl);
 
	UpdateSegments ();
 
	segmentControl.SelectedSegment = Element.SelectedIndex;
	segmentControl.SizeToFit ();
 
	segmentControl.ValueChanged += (object sender, EventArgs args) => 
	{
		if(segmentControl.SelectedSegment != Element.SelectedIndex)
		{
		     Element.OnSelectedIndexChanged((int)segmentControl.SelectedSegment);
		}
	};
}
 
private void UpdateSegments()
{
	Control.RemoveAllSegments ();
 
	for (int i = 0; i < Element.Items.Count; i++) 
	{
		Control.InsertSegment (Element.Items [i],i,true);
	}
}
public void OnSelectedIndexChanged(int newValue)
{
        var args = new IndexChangedEventArgs () {
		NewValue = newValue,
		OldValue = SelectedIndex
	};
 
	SelectedIndex = newValue;
 
	if (SelectedIndexChanged != null) 
	{				
		SelectedIndexChanged (this, args);
	}
}

Of course we also need to update the native control if the value for selected index is changed. That code will be placed in the OnElementPropertyChanged method.

protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
        base.OnElementPropertyChanged (sender, e);
 
	if (e.PropertyName == FilterControl.SelectedIndexProperty.PropertyName) 
	{
		if (Control.SelectedSegment != Element.SelectedIndex) 
		{
		         Control.SelectedSegment = Element.SelectedIndex;
		}
	}

The complete code can be found on GitHub, https://github.com/dhindrik/XamarinFormsSamples/tree/master/SegmentedControl

If you want the control to be in the NavigationBar on iOS read this blog post.

April 27, 2015 2:29 GMT

San Francisco

It's a beautiful Monday morning in San Francisco today! Started the day with a morning run along the piers and ended up in the hotel lobby drinking cheap coffee while working on my new cool Xamarin Forms control.

The control is a simple to use, no hassle carousel view for images that works out of the box by simply setting a list. It also comes with a framework to lazy load images on demand while keeping the memory at a minimal.

Is it done, nope not yet! But it will be available at github real soon. And perhaps I'll add it to Xamarin Forms Labs though I'm not to fund of their choice of OS license.
April 27, 2015 7:48 GMT

Say Hello To Xamarin.Forms – APAC Webinar Recording

Thanks to everyone who attended my Webinar on Say Hello To Xamarin.Forms. This is the second webinar from us which is timed to fit the APAC region. As promised, find the recording and the presentation files below.

Slides

Code Samples

WeatherCheck

In this webinar, we looked at a simple WeatherCheck sample that uses the Yahoo Weather APIs to query the weather forecast of a specified city.

Download the samples from my GitHub repository.

Have a feedback? Find me on twitter.


April 27, 2015 7:12 GMT

WWDC 2015 for a Xamarin Developer n+1 Series

WWDC-2015-invitation

How much can happen in a week? … well a lot, last week I was honoured to be announced as a Xamarin MVP, I purchased my first Apple Watch and… I’ve been lucky enough to win a golden ticket for the Apple World Wide Developers conference (WWDC). When I say win I mean pay apple $1999 AUD for the privilege to attend the conference. The ‘winning’ part is that there’s 9 million apple developers and many thousands apply to attend, so apple have a lottery in which attendee’s are selected at random.

WWDC is on June 8th – June 12th 2015, in San Francisco and will take place at Moscone West. There’s likely to be some new software announcements for iOS and OSX, possibly some more watch features and maybe even a 4K Apple TV. There’s over 100 technical sessions, 1000′s of apple engineers, hands-on labs and the apple design awards.

As an engineer I’m really keen to attend the technical sessions and get my hands dirty with some hands-on labs, maybe a little swift to c# conversion will be in order.

Given that I’ve been lucky enough to win a ticket to WWDC this year I thought it would only be fair if I shared the journey with other Xamarin developers. I’ll be giving daily overviews of different announcements and if possible providing technical detail from the conference, converting the swift applications into C# and F#.

This series of posts will be named ‘WWDC for a Xamarin Developer n+1′… Stay tuned… I think we’ll have some fun!

Michael

The post WWDC 2015 for a Xamarin Developer n+1 Series appeared first on Michael Ridland.

April 27, 2015 3:05 GMT

CocosSharp Beginner Series : Setup your Machine

CocosSharp, as explained in my earlier post is a cross-platform library for building 2D games. CocosSharp is an open source library and is built on top of the MonoGame engine and the fine work from the Cocos2D, Cocos2D-x and Cocos2D-XNA communities.

Today, we will start our CocosSharp beginner series with an introduction on How to set up your machine for getting started with CocosSharp.

First of all, you can either use Xamarin studio or Visual studio as an IDE for your game development. The only difference is Xamarin studio can be installed on Windows and Mac. But visual studio can't be directly installed on a Mac, you need virtualization tools like parallels or VMWare etc. on top of which you should run windows OS.

So, zero on your IDE and install the same.

Using Xamarin Studio

Xamarin Studio

Once you have xamarin studio installed, navigate to Add-in Manager
CS-2

As it's already installed on my machine, you see a blue check mark on the top with Disable and Uninstall buttons on the right. If you have picked a fresh machine, with Xamarin Studio just installed, Click and install "CocosSharp Project Templates". Once installed successfully, click on the first tab (Installed) and you should see CocosSharp there.
Android CocosSharp Project on Windows

On a machine running windows with Xamarin Studio installed, You will see only Android CocosSharp project types.

  • CocosSharp showcase has boilerplate code with all required packages pre-installed to get started.
  • CocosSharp empty game is a template to start your game from scratch.

On a Mac

For installing CocosSharp project templates, follow the steps mentioned above. Once installed successfully, specifically within the list of C# solutions you should now have CocosSharp projects for

  • Android
  • iOS/Classic API/iPad or iPhone or Universal
  • Mac/Classic API
  • Mobile Apps

provided you have all the necessary dependencies.

Xamarin Studio on a Mac Xamarin Studio on a Mac

Using Visual Studio

The templates are being held in a custom Visual Studio Gallery held at Mobile Essentials.

In order to get the custom gallery into your Visual Studio, open Tools | Options and configure the page Environment > Extension Manager as follows, using the gallery url http://gallery.mobileessentials.org/feed.atom:

image

Once the Mobile Essential gallery is set up, you can go to Visual Studio’s Tools | Extensions and Updates... menu and a new Mobile Essentials node will appear under the Online category, where you can explore and install the tools:

CS-05This image has been resized to fit in the page. Click to enlarge.

Click the Download button to install the highlighted extension. Once the download is complete you will get a verification screen prompting you to install the template package. Click the Install button:

image

Once installation is complete you will then see the CocosSharp Templates package marked with a little green arrow showing that it is installed.

image
This image has been resized to fit in the page. Click to enlarge.

Creating a new project

Now when creating a new project you will see a new section called CocosSharp with subcategories for:
  • Android
  • iOS
  • Windows
image

If you have created an empty CocosSharp project, right-click on From Packages | Add packages and then select platform specific CocosSharp Nuget package to get started. After successful installation, your project hierarchy should look like the one showed below. Showcase project template will look like this by default as packages will be pre-installed.

Project hierarchy with packages

Note : Check for updates before installing/updating latest packages.


Huff!!! hope everything went well with the machine setup for you. If you can't wait for the next chapter in our beginner series, Start exploring and share your experience via twitter @IAmVMac
Game ON !!!!
April 26, 2015 4:15 GMT

Taming The Android Activity, Part 1

The Activity is a core building block in an Android application, but in some cases it can be a pain to work with. This article is part one of a series showing how to deal with some of the complexities of the Activity in a clean way using some of the capabilities of C# available to Xamarin.Android developers.

Typically each screen in an Android application is represented by an Activity, and moving from one screen to another is done by starting a new Activity. In fact, the Activity and its related class Intent are the keys to Android's ability to let applications reuse pieces of other applications. That cross-application use case was the motivation behind the design of the Activity, but that design has the unfortunate side effect of making some common in-process use cases surprisingly difficult to deal with.

This series will cover three common scenarios that Android developers face in which the design of the Activity class causes problems:

  1. Dealing with device rotation (and other configuration changes)
  2. Launching and waiting for the results of another Activity
  3. Communicating between (in-process) Activitys

Each of these is very common and yet is surprisingly difficult to do on Android, especially compared to the way that view controllers work in iOS.

Configuration Changes

The Android documentation has this to say about configuration changes (emphasis added):

If the configuration of the device (as defined by the Resources.Configuration class) changes, then anything displaying a user interface will need to update to match that configuration. Because Activity is the primary mechanism for interacting with the user, it includes special support for handling configuration changes.

Unless you specify otherwise, a configuration change (such as a change in screen orientation, language, input devices, etc) will cause your current activity to be destroyed, going through the normal activity lifecycle process of onPause(), onStop(), and onDestroy() as appropriate.

What this means is that any "configuration change" will cause your Activity object to be destroyed and then recreated. What's a "configuration change"? There are actually a lot of things that count (see the complete list), but one of the most common is an orientation change. As a result, if a user rotates his device from portrait to landscape (or vice versa) then your Activity will be destroyed and recreated.

The most obvious consequence of having your Activity get destroyed is that all of the views also have to be recreated, but the most serious consequence is that all state stored in the Activity (meaning your fields and properties) will be lost, and a brand new instance of your Activity class will be created from scratch instead.

Handling Configuration Changes

There are a few approaches to dealing with this problem:

  1. Disable the behavior
  2. Serialize and deserialize your state
  3. Use a retained Fragment

The first option is to disable this behavior, which can be done by setting the configChanges property of the Activity to the configuration changes that you don't want to cause the Activity to be destroyed. This seems like a great option, and you will find many people recommending it. However, Google discourages this approach:

This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.

The second option was the best approach for a while, and many apps no doubt still use this approach. When an Activity is being destroyed for a configuration change it will receive a call to OnSaveInstanceState. This method has Bundle argument that can be used to stash data using a key/value system. Basic types are supported by default, but more complex data types are difficult to deal with. Once the new Activity is created it will receive a call to OnRestoreInstanceState, which is handed the same Bundle object in order to fetch the stashed data.

The downside of this approach is that it is tedious and error prone. If you forget any fields then your application will have subtle bugs any time a user rotates his device. Ideally we could just throw a whole object from the old Activity to the new one. In fact, there is a deprecated API for doing just this (see OnRetainNonConfigurationInstance and GetLastNonConfigurationInstance), but that mechanism has been replaced by a better one.

Since Android 3.0 the current recommended solution to dealing with configuration changes is with a retained Fragment.

Fragments

A Fragment is kind of like a miniature Activity. It has a lifecycle, state, and optionally a view hierarchy. A Fragment is attached to an Activity via the Activity's FragmentManager.

By default whenever an Activity is destroyed for a configuration change its associated Fragments are also destroyed. However, you can request that a Fragment be retained by setting the RetainInstance property to true, which allows the entire object and all of its fields (but not its views) to be reused.

Therefore, the best technique for dealing with configuration changes is to actually move most of your Activity's code into a Fragment instead. The Activity is then merely a dumb shell used to create the Fragment and deal with Activity-specific issues like Intents. Here is an overview of how this technique works:

  1. When the Activity is created it uses its FragmentManager to search for an existing instance of its Fragment (identified by a tag string).
  2. If an existing Fragment was not found then a new one is created and added to the Activity.

Other than dealing with things like Intents and results from other Activitys (both to be covered in future segments of this series) the Activity class doesn't have much else to do. As you can imagine, the code to perform these steps will end up looking fairly boilerplate. In fact, this is a great opportunity for some code reuse.

Example

As an example of how to deal with this problem in a generic way let's start with the Xamarin.Android stock template that you get when you create a new application. If you run this template without any modifications then you get a simple application with a button on it. When you click the button it shows you how many times it has been clicked. In order to demonstrate the problem click the button a few times and then rotate the device. The first thing you'll notice is that the button text reverts to the original "Hello World" text. If you click the button again you'll also notice that the count starts over. This is the bug we will be fixing.

In order to fix this we will introduce two new base classes: FragmentActivity and FragmentBase. These classes can be dropped in to any application, and we will build on them further throughout this series to add other useful capabilities. For this problem, though, the classes are pretty simple. Here is the code:

/// <summary>
/// An Activity that uses a retained Fragment for its implementation.
/// </summary>
public abstract class FragmentActivity<TFragment> : Activity where TFragment : FragmentBase, new()
{
/// <summary>
/// The top-level fragment which manages the view and state for this activity.
/// </summary>
public FragmentBase Fragment { get; protected set; }

/// <summary>
/// The tag string to use when finding or creating this activity's fragment. This will be contructed using the type of this generic instance.
/// </summary>
protected string FragmentTag
{
get
{
return GetType().Name;
}
}

/// <inheritdoc />
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);

LoadFragment();
}

/// <inheritdoc />
public override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
Fragment.OnAttachedToWindow();
}

/// <inheritdoc />
protected override void OnNewIntent(Intent intent)
{
Fragment.OnNewIntent(intent);
}

/// <summary>
/// Loads the fragment for this activity and stores it in the Fragment property.
/// </summary>
protected virtual void LoadFragment()
{
Fragment = FragmentBase.FindOrCreateFragment<TFragment>(this, FragmentTag, global::Android.Resource.Id.Content);
}

/// <inheritdoc />
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
Fragment.OnActivityResult(requestCode, resultCode, data);
}
}

/// <summary>
/// The base class for top-level fragments in Android. These are the fragments which maintain the view hierarchy and state for each top-level
/// Activity. These fragments all use RetainInstance = true to allow them to maintain state across configuration changes (i.e.,
/// when the device rotates we reuse the fragments). Activity classes are basically just dumb containers for these fragments.
/// </summary>
public abstract class FragmentBase : Fragment
{
/// <summary>
/// Tries to locate an already created fragment with the given tag. If the fragment is not found then a new one will be created and inserted into
/// the given activity using the given containerId as the parent view.
/// </summary>
/// <typeparam name="TFragment">The type of fragment to create.</typeparam>
/// <param name="activity">The activity to search for or create the view in.</param>
/// <param name="fragmentTag">The tag which uniquely identifies the fragment.</param>
/// <param name="containerId">The resource ID of the parent view to use for a newly created fragment.</param>
/// <returns></returns>
public static TFragment FindOrCreateFragment<TFragment>(Activity activity, string fragmentTag, int containerId) where TFragment : FragmentBase, new()
{
var fragment = activity.FragmentManager.FindFragmentByTag(fragmentTag) as TFragment;
if (fragment == null)
{
fragment = new TFragment();
activity.FragmentManager.BeginTransaction().Add(containerId, fragment, fragmentTag).Commit();
}

return fragment;
}

/// <inheritdoc />
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);

RetainInstance = true;
}

/// <summary>
/// Called when this fragment's activity is given a new Intent.
/// </summary>
/// <remarks>The default implementation does nothing</remarks>
public virtual void OnNewIntent(Intent intent)
{
}

/// <summary>
/// Called when this fragment's activity is attached to a window.
/// </summary>
/// <remarks>The default implementation does nothing</remarks>
public virtual void OnAttachedToWindow()
{
}
}

As you can see, FragmentActivity is a generic abstract class with a type parameter to specify the type of the Fragment that it should use. This class creates and holds on to the Fragment and forwards a few useful messages to the Fragment that otherwise would be handled by the Activity. The FragmentBase class is an abstract class that is used as the base class for any Fragments used by a FragmentActivity. Its static FindOrCreateFragment method, as its name implies, is used to find an existing instance of a Fragment or create a new one if one is not found. Also note that RetainInstance is set to true when this Fragment is created, which is the key to allowing the instance to be reused. The other methods are just there to receive notifications from the Activity.

The way you use these classes is simple. For each Activity you will create a pair of classes: a Fragment that inherits from FragmentBase and an Activity that inherits from FragmentActivity. The generic type argument links them together. In many cases the Activity doesn't need any additional code (it will just be an empty class), and all of the important code goes in the Fragment. To see this in action this is how I adapted the Xamarin.Android template to use these new classes (complete code):

[Activity(Label = "FragmentActivityTest", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : FragmentActivity<MainActivityFragment>
{
}

public class MainActivityFragment : FragmentBase
{
private int _count = 0;
private Button _button;

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.Main, container, attachToRoot: false);

_button = view.FindViewById<Button>(Resource.Id.myButton);

if (_count != 0)
{
UpdateButtonText();
}

_button.Click += delegate
{
_count++;
UpdateButtonText();
};

return view;
}

private void UpdateButtonText()
{
_button.Text = string.Format("{0} clicks!", _count);
}
}

The first thing you'll notice is that, as I mentioned before, the Activity has no code in it. Looking at the Fragment you'll notice that it looks very similar to the original code, but with a few key tweaks. Let's look at what I had to change.

The first change was the loading of the layout file. The original code looked like this:

SetContentView(Resource.Layout.Main);

SetContentView is a method of Activity, but we're not in an Activity anymore. Instead, we just have to load the layout and return it. For this purpose we are given a LayoutInflater, and we use it like this:

var view = inflater.Inflate(Resource.Layout.Main, container, attachToRoot: false);

There are two additional arguments being used here, and both are important. The first is the container ViewGroup that is passed to us as an argument to OnCreateView. This is the container in which the view we return will be inserted. The second is a boolean that tells the LayoutInflater that we don't want it to insert the inflated view into that container.1

Moving on, we have an extra bit of initialization code:

if (_count != 0)
{
UpdateButtonText();
}

This code is necessary because while the Fragment is reused across configuration changes the view is not. That means this method will be called multiple times on the same Fragment instance2, and it is up to us to initialize the view with the current state3. In order to handle this I created a field for the button and refactored the code for updating the text into a method that I can call in multiple places. Since the initial text comes from the layout file and doesn't match the format used after clicking the button I check first to see if the button has ever been pressed.

Lastly, I return the view that was created since that is needed by the Activity in order to insert it into the view hierarchy.

Summary

As you can see, this approach makes it very easy to handle configuration changes by mostly just ignoring them. The only remaining wrinkle is that the views are still destroyed and recreated, which requires a bit of extra initialization. This is necessary because the views may actually adapt to the configuration change. The good news is that we no longer have to tediously save and restore every state field.

I use this technique in every Android application I write, and it works very well. I hope that this post and the example code will help you save time dealing with the same issue.

In the next part of this series I will explain how to deal with the problem of starting a new Activity and waiting for its results.


  1. This may seem strange. Why are we passing in the container if we aren't inserting the view into it? It turns out that there is a good reason for this, which is explained in detail by this article. If you leave off the last argument the default is true, and you will get an exception because the view is inserted twice. If you pass null as the second argument then you won't crash, but your top-level LayoutParams in your layout file will be ignored. Thus we pass in the container and we tell it not to attach. 

  2. There is a corresponding method OnDestroyView, which can be used to do any necessary cleanup when the old view is destroyed during a configuration change (or when the Fragment itself is going to be destroyed). 

  3. Some views do their own saving and restoring of temporary state during configuration changes. For instance, an EditText will save the text that has been entered, the cursor location, and the current selection. This is handled by OnSaveInstanceState and OnRestoreInstanceState in the View class

April 25, 2015 3:25 GMT

Song of the Day: Press the Buzzer

DarWilliamsPress the Buzzer is based on the infamous Milgram Experiment.  This brilliant song captures the entire essence of the experiment and the fall out from it, without ever losing its compelling folk rock rhythm.

Like nearly all her music, this one is highly recommended.

I’m feeling sorry for this guy that I press to shock
He gets the answers wrong, I have to up the watts

And he begged me to stop, but they told me to go
I press the buzzer, I press the buzzer…

 

April 25, 2015 3:12 GMT

Xamarin.Forms: Incremental Search

I recently posted about obtaining data for purposes of creating demonstration programs.  IncrementalSearchFinal

That actually was written in service to today’s post, which will use that data to create a list of “people” and then allow you to search incrementally, as shown in the illustration; I typed “Jaco” and any name that contained Jaco was brought up.

This post shows two meaningful techniques: it reviews grouping and it demonstrates incremental searches.

Continued here