Monthly Archives: April 2016

Releasing MVVM Light V5.3 to Nuget

.NET, MVVM, Work, Xamarin, XAML
9 Comments

With Xamarin Evolve coming up (I am currently on the way to Orlando!), it was time to release a new version and take care of a few bugs, improvements and new features.

Update: To be clear I didn’t remove the Windows 8.1 version, it is still available! Only the Windows 8 version is removed.

In version 5.3, the majority of the activity was on the data binding system for Xamarin.iOS and Xamarin.Android, with many improvements in stability and performance, as well as a few new features. Existing code will continue to work as is, and at most you might have a few “deprecated” warnings, which will give you time to update your code. I also added 3 classes and a few helpers around them, which should help you greatly when you work with lists: ObservableRecyclerAdapter (for Android RecyclerView), ObservableTableViewSource (for iOS TableView) and ObservableCollectionViewSource (for iOS CollectionView). These objects will be detailed in separate blog posts.

In other areas not directly Xamarin-related, you will also find quite a few bug fixes. Here is list of changes. You will also find a few explanations below. I will publish additional blog posts with more details about the Observable list components mentioned above.

Removed old frameworks

In a desire of simplification, I removed the Silverlight 4, Windows Phone 7.1 and Windows 8 versions of MVVM Light from the repo. This does NOT affect the Silverlight 5, Windows Phone 8.0 and 8.1, Windows 8.1 as well as Windows 10 of course which are still very well supported. The main reason for not supporting these older versions is that they require Visual Studio 2012 and cannot be maintained or tested in VS2015. I hope that this doesn’t affect your projects too much. Should that be the case, please send me a note. We can always find a solution!

Fixing Nuget install.ps1 and documentation

There was a silly bug in the install.ps1 script that is run after the Nuget installation is performed, it is fixed now. Also, I added a more explicit description of the packages mvvmlight and mvvmlightlibs, in order to underline the differences between both.

Documentation: Closures not supported

In the same vein, I added explicit documentation warning that closures are not supported in the Messenger Register method, as well as in the RelayCommand Execute and CanExecute delegates. This is sometimes an issue. The reason is that these components are using WeakReference to avoid tight coupling with the objects using them. When we store the delegate that will be executed by the Messenger or respectively the RelayCommand, we store them as WeakAction instances. This causes the delegate to be “dehydrated” and stored as a MethodInfo. When we “rehydrate” the delegate, we notice that the closure has been lost, and the call fails. I am experimenting with ways to work around that limitation (i.e storing the delegates are actual Action or Func and not dehydrating them, which will of course cause a strong coupling to occur… but would be acceptable in some cases if the developer explicitly opts into this). For the moment, closures are not supported and the developer needs to find another way, for example storing the parameter in an attribute or a list of some kind.

ViewModelBase

I optimized the code a bit there and made it less redundant. I also made the RaisePropertyChanged methods public (was: protected) following a user’s request. This can make sense in certain scenarios when an external object wants to call this method on another VM.

NavigationService

Here too I fixed some bugs. I also added new features for iOS:

  • Navigating with an unconfigured key in iOS: In iOS, the key passed to the NavigateTo method is often the same value as the corresponding Storyboard ID set in the Storyboard designer for a given controller. Until V5.3, you had to configure the key for the NavigationService, which was often leading to code such as
    Nav.Configure(“SecondPage”, “SecondPage”);
    this didn’t quite make sense. As of V5.3, if you call NavigateTo with a key that is not configured, we will attempt to find a corresponding controller with this same Storyboard ID. Of course if you want to use a different ID, you can still configure the navigation service like before.
  • Retrieving parameter without deriving from ControllerBase: Until now, the implementation used to retrieve a navigation parameter from the NavigationService forced you to derive your controller from ControllerBase. That was annoying, especially in cases where you had to derive from another base class anyway. I removed this restriction. Instead, you can now retrieve the NavigationService from the ServiceLocator in the ViewDidLoad method, and then call the GetAndRemoveParameter method to get the navigation parameter (if there is one). This is the same method than in the Android NavigationService.

Binding system

I fixed a few bugs here which were causing the data binding to fail in certain scenarios. I also added a lot of unit tests to test current and new features (currently about 300 unit tests which run in both iOS and Android), as well as a few features. Expect samples very soon!

  • FallbackValue: This value can be set in the SetBinding method (or in the Binding constructor) and will be used in case an error occurs when the Binding is being resolved. This can happen, for example, if you have a complex path expression and one of the elements is null, which would cause a NullReferenceException to happen inside the Binding. This exception is caught and nothing happens in the application, but the FallbackValue will be used as the Binding value if the user has set it. This can be used for information purposes. For example, if your source property is MyViewModel.SelectedItem.Name, and nothing is selected, the SelectedItem is null and the FallbackValue (for instance “Nothing selected yet”) is used.
  • TargetNullValue: This value can also be set in the SetBinding method (or in the Binding constructor) and will be used in case the Binding value is null. This can also be used for information purposes.
  • SetCommand with static parameter: I added an overload to the SetCommand extension method which can be used to pass a static parameter to the ICommand’s Execute and CanExecute methods. Prior to V5.3, you had to define a binding for this (and use the SetCommand(…, Binding) method) which was very cumbersome in case the binding value never changed. Now you can use the SetCommand method with a simple value (or if you want to observe the value you can still use the SetCommand method with a binding).
  • SetCommand for ICommand: In previous versions, you could only use SetCommand with a RelayCommand (or RelayCommand<T>), which was an oversight. Now I modified this method to work with any ICommand.
  • New name for UpdateSourceTrigger: This method is now named ObserveSourceEvent. The old method is still available but marked as deprecated. The old name was confusing for users.
  • New name for UpdateTargetTrigger: Similarly, this method is now named ObserveTargetEvent. The old method is still available but marked as deprecated.
  • Binding with implicit event names: When you set a binding on a UI element in Android and iOS, you must also specify which event should be observed for changes. This is necessary because properties in these elements, unlike in Windows, aren’t depedency properties. For instance, you can choose between FocusChange or TextChanged for an EditText, etc. In the huge majority of cases however, the same event is used over and over for a given element.
    On Android, the TextChanged event is used for an EditText and the CheckedChange event for CheckBox; on iOS, the ValueChanged event is used for UISwitch, the Changed event for UITextView, and the EditingChanged for UITextField. Note that existing code does not need to be changed unless of course you want to simplify it. And like before, you can continue to use ObserveSourceEvent and ObserveTargetEvent (formerly UpdateSourceTrigger and UpdateTargetTrigger) to specify a different event if needed.
  • SetCommand with implicit event names: Like with the Binding class, when we set a Command on a control, we specify which event must be observed to trigger the command. For commonly used controls, this is mostly the same event. To simplify the code, you don’t have to explicitly specify these events anymore. The events that are observed implicitly are: On Android the Click event for Button, and the CheckedChange event for CheckBox. On iOS, the TouchUpInside event for UIButton, the Clicked event for UIBarButtonItem and the ValueChanged event for UISwitch. Of course you can also continue to specify these events explicitly, or any other event you wish to observe instead.
  • Binding to private fields and local variables: In previous versions, you could only set a binding on public properties (for example public MainViewModel Vm, or public CheckBox MyCheck; in V5.3, you can also set bindings on objects which are saved as private attributes. You can even create a new Binding (using the Binding constructor instead of the SetBinding method) on elements which are defined as local variables.
  • Binding on RecyclerView, TableViewSource and CollectionViewSource cells: The feature above (binding on local variables) can be useful, for example to create a new binding between a data item and the cell that represents it in a list control. I’ll have blog posts for RecyclerView, TableViewSource and CollectionViewSource.

As you can see, this is a massive change set and I am really happy that your excellent feedback has led to these improvements. Of course the task is not over and there is more coming. V5.3 should greatly improve working with data binding in MVVM Light, in Xamarin.iOS and Xamarin.Android. As always, keep your feedback coming!

For more information about data binding in Xamarin.iOS and Xamarin.Android, you can watch my Xamarin Evolve 2016 session (slides, sample code and video recording will be posted ASAP).

Happy coding!
Laurent

GalaSoft Laurent Bugnion
Laurent Bugnion (GalaSoft)
Share on Facebook
 

Why you shouldn’t buy the Earin True Wireless Earbuds

Technical stuff
4 Comments

I don’t usually write product reviews but here I will make an exception because my disappointment in both the product and the customer service are as high as the expectations I had.

The firm Earin went through Kickstarter and created a product that, on paper, is pretty amazing. A pair of super small earbuds that connect via bluetooth, and don’t have any wire between them. Basically you plug one earbud in one ear, the other in the other ear and you’re good to go. No cables, nothing.

I had this product delivered to my hotel in the US (in San Francisco for Build), so I could have it faster and try it during my trip. I ordered on March 16, it was delivered to me on March 28. The packaging is pretty amazing, a mix of very noble looking cardboard and magnets holding it together. Great first impression. Also, the idea of providing a charging case is really nice. You can see details and pictures here.

Now, my Jabra bluetooth headset is starting to get a bit old and the battery is not holding charges as well as it used to. So I was in the market for something else. The price for the Earin gave me pause (249 Euros!) but I thought that it looked like a really great product. Boy was I wrong.

Update: The last email from their customer service representative:

“Alright. You are very welcome to write back to the customer support once you feel cooperative and want to get the issue solved.
I wish you a very pleasant day.”

Passive aggressive much? Please tell me this person is going to get fired over this…

The issues

First, I paired the Earin L (left earbud) with my phone as instructed. Note that I have used a lot of Bluetooth devices with this phone, such as the Jabra I mentioned, the JBL speaker in my office, my car’s stereo device and more. Never had a single issue.

Unfortunately, the Earin kept dropping the connection. But even worse, the connection between the left and right earbud is extremely weak. In retrospect I should have expected it because there is a big bag of bones and fluids between them: My head. This is a basic flaw of the product and I cannot believe that they think it will work right. So not only the connection between the phone and the left earbud was bad, but the connection between the left and the right earbud was even worse. And there is nothing you can do about that one, because you cannot change the configuration of your ears.

Contacting customer service

I tried to talk to customer service but I had a bad experience there too. First they told me that they cannot refund me because I bought through Amazon. Ok fair enough, I contacted the Amazon reseller and am waiting for an answer.

More annoyingly, the tone of the representative is borderline insulting. Maybe it’s a language thing, not sure (Earin is located in Sweden) but you would expect them to be more respectful with customers who pay a lot of money for a defective product.

Then we tried some technical resolutions. In the end it boiled down to “you’re holding it wrong”. If I was holding the phone closer to my head, it would magically work better. Note that this doesn’t solve the bad connection between the two earbuds, so I wonder how holding the phone closer to my face would make things better. Also, I don’t wear shirts so I don’t have a pocket for that, and I use my phone in other occasions than jogging, so I cannot always use an armband.

The customer service representative reply:

“Thank you for the answers. So you are listening with a Windows phone as sending device, outdoors, with your sending device in the back pocket of your trousers. Okay. In this situation you write that you experience audio drop outs very frequently. Well, you are using the EARIN in far from optimal conditions, so I can understand that you get drop outs then.
As I wrote previously, it usually comes down to one thing: the distance between the phone and the master earbud. I cannot emphasize this enough. 
If that distance is not good enough to keep a drop out free connection, you can place the sending device closer: in the shirt pocket, or attached to an arm band on your over arm (usually used by joggers), of course on the same side as the master earbud.”

In other words, fuck you very much.

Lack of features

In addition to the inherent defectiveness of the product, there are also missing features that most other bluetooth headsets have.

  • No volume control on the earbuds. You need to take your phone out to control the volume.
  • No skip / forward / backward control on the earbuds. You need to take your phone out to skip a song.
  • No Cortana trigger on the earbuds. On my (old) Jabra, I can do a long press to start Cortana, which is super useful for example when skiing. Nothing like that on the Earin.

In short, the earbuds are just dumb earbuds. And they don’t even function as such.

Conclusion

I guess I was carried away by my enthusiasm and like Fox Mulder, I wanted to believe. But in the end there are basic physics at play here. The head is going to cause interferences. And the lack of features is just the last drop which makes me return the item.

I cannot stress that enough: Stay clear of this company. They don’t know what they built, and they don’t accept that it doesn’t work.

Laurent

GalaSoft Laurent Bugnion
Laurent Bugnion (GalaSoft)
Share on Facebook