Matt Ward: 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.

Details

Xamarin: Developer Rig Giveaway Winners

After 913 submissions from 485 entrants, we’re happy to announce the randomly selected winners of our Build 2015 developer rig contest! The winning tweets were: Cameron Vetter from Wisconsin, USA: @xamarinhq I’m standing in line for the keynote at #bldwin thanks for the great year of mobile development             Thimo […]

The post Developer Rig Giveaway Winners appeared first on Xamarin Blog.

Details

Johan Karlsson: 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…

Details

Adam Kemp: 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

Details