App icons missing after upgrading to iOS 11/Xamarin

I have an Xamarin iOS project and developing in Visual Studio 2017 and have app icons in an asset. Since I've upgraded to XCode 9/iOS11 the app icons aren't included anymore and Application Uploader would throw a ton of errors at me about the missing icons. Before XCode 9 it worked though.

Xamarin describes upgrading issues to iOS 11 here and there but nothing much for Visual Studio 2017 - a key is missing in Info.plist they say. But what key?

It turns out the solution is a really simple one. Open iOS project in Visual Studio 2017, open Info.plist in editor, go to Visual Assets and make sure that App Icons source is pointing towards correct asset (with app icons).

It will generate this Info.plist key and value (value might differ, based on where your app icons are):

<key>XSAppIconAssets</key>
<string>Resources/Default.xcassets/AppIcons.appiconset</string>

This value can be added manually, as well, if you know what to add.

Good bye Visual Studio Emulator for Android and hello problems

I recently tested a prototype of a Xamarin Android app that should run on Android 4.1+. So I fired up Visual Studio Emulator for Android and saw that API level 16 (4.1) is missing from the list. The oldest is level 17/4.2.

Since they have a nice smiley icon for feedback I wrote a quick request to include level 16 as well since a lot of apps are targeting 4.1+, not just me.

The shocker came few seconds later in a form of an automated e-mail response (emphasis mine):

Hello,

This is an automated message. Unfortunately, we have no plans to publish Android images past 4.4. We recommend that you try Google or GenyMotion’s emulator for future images of the Android operating system.
 
When we first released the Visual Studio Android emulator, the Google emulator was slow, out-of-date, and a significant source of pain for mobile developers. In addition to the great work performed by GenyMotion, the Visual Studio Android Emulator proved that emulators can be fast, productive tools for mobile development.
 
Since then, Google has responded to developer feedback by increasing their investment in their tools. The next generation Google Android Emulator has closed the feature gap that previously differentiated Visual Studio’s emulator. Google’s emulator has become much faster and more feature rich.
 
We also know that, for mobile developers, authenticity is key. We believe that Google, as the platform owner, is best positioned to provide ongoing support for new versions of the platform in a way that accurately and authentically reflects the real-world behavior on devices.
 
For developers like you who’ve come to love and depend on the VS Android Emulator, thank you! We will continue to support in-market platform images according to Visual Studio’s generous support policy. However, Microsoft will no longer produce new Android images for the VS Android Emulator. We consider this a successful project that has come to a natural conclusion.
 
Happy coding!

Wait, what? First time I heard that VSE4A is no more. Which wouldn't be that tragic if Hyper-V wasn't involved. See, VSE4A is the only Android emulator based on Hyper-V. Why do I even care? Oh, I do and you should do as well. When Hyper-V is enabled it doesn't allow any other virtualization host to run. Sure, you can disable Hyper-V (reboot required) and go with Google's Emulator or a better one from Genymotion. But then you can't run Docker, Windows Emulator and  your other Hyper-V guests at the same time. More here.

Happy coding, indeed.

There is light of hope though. Miguel tweeted that there might be a solution in the future



Hopefully that's the case. In the meantime VSE4A still works and is available for download, it is just missing images, specially newer ones (latest is API level 23 aka 6.0).

But at the end I'd really like Microsoft to address the cause of this blunder: the monopolistic Hyper-V behavior on desktop. If Windows virtualization worked like others do ("live and let live") there won't be a problem whatsoever. The way it works now it makes sense on servers, not on desktops.

But instead of fixing that, Microsoft choose to create all imaginable emulators on top of Hyper-V. What could go wrong?

Webpack’s cheap-module-eval-source-map requires a plugin

I’ve started experimenting with React and consequently Webpack. As a base I picked Cory House’s excellent "Building Applications with React and Redux in ES6" course on Pluralsight (disclaimer: as a MS MVP I get free subscription). BTW Pluralsight is a really good learning content delivery - so much good stuff there.

Anyway, I was building upon Cory's project and at some time I decided to update packages to their latest version (by updating versions in package.json, deleting node_modules and running npm update). Everything went smooth except that I noticed that debugging in browsers stopped for some reason. Breakpoints weren't observed, sources weren't shown. The later proved as hint what to look for - devtool settings in webpack.config.js that is.

It turns out that Cory was using cheap-module-eval-source-map which was working with the original version of webpack. However after updating it didn't work anymore.

The solution is rather simple: add a new plugin to webpack.config.js:

new webpack.EvalSourceMapDevToolPlugin()

Looks like that folks at webpack decided to put this functionality into a separate plugin at a certain point in time (I didn't follow its progress). And no, the solution isn't mine. Instead I found it at this stackoverflow thread.

LINQPad, LLBLGENPro and Npgsql

If you want to test LLBLGenPro/Npgsql queries with LINQPad, and you really should, you have to follow these steps.

  1. Install the official LLBLGenPro driver for LINQPad (Add connection, View more drivers..., ...)
  2. Reference LLBLGenPro generated assemblies (connection configuration), enter proper connection strings and, albeit optional, provide a .config file that contains DBProviderFactiories entry for Npgsql (watch out for version number)
  3. Once connection is created, add Npgsql NuGet package to query. The version should match the one configured in step #2.

And voila, beautiful interactive queries at your disposal. You can even use ORM Profiler.

Sample Npgsql factory entry:

....
<system.data>
    <DbProviderFactories>
      <!-- PostgreSql -->
      <add name="PostgreSql Client Data Provider" invariant="Npgsql" description=".Net Framework Data Provider for PostgreSql" type="Npgsql.NpgsqlFactory, Npgsql, Version=3.1.6.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7" />
    </DbProviderFactories>
  </system.data>

A solution to Visual Studio Tools for Docker debugging problem

I you have problems with debugging your .net core application using Visual Studio Tools for Docker - the app simply stops at start and you see a lot of Trying to connect to http://localhost (N/120) messages (where N = [1,120]) - then you might be interested in the workaround.
Which, as it turns out, is quite simple.
Open docker-compose.debug.yml file and simply remove the volumes section:
    volumes:
      - .:/app

Then you can debug it normally.

See the original solution post named Trying to connect to http://localhost/ (1/XXX) in Q and A section.

Mono, Docker, 3.14, WebAPI on NTK 2016

This year I’ll be presenting at Microsoft’s NT Konferenca as I do every year.

As the topic I’ve picked my experience of using Docker I gathered from a real world example. I’ve been building an application that is a combination of PostgreSQL database, Mono/NGINX/WebAPI on server and UWP/Windows10 on client. Server side supports various OS. Target is Linux but it should run on Windows without issues. The combination of server OS and server tools choice drives costs down significantly on one hand and makes it versatile on the other.

Docker helps a lot through the development and final deployment in production. And that’s what talk is all about. 3.14 will play a role as well – showing that there is almost no HW restriction for such a combination on server side. We’ll build and deploy the application through rich demos.

See you there, Monday at 9:00.

Strong typing DisplayAttribute reference to Resources

Let’s say there is a decorated member with DisplayAttribute in code, i.e.:

public enum SomeEnum
{
	[Display(Name = "ResourceKey", ResourceType=typeof(Resource)]
	SomeValue
}

That’s all right except for one problem. If Name is mistyped or given resource key is latter changed then DisplayAttribute will point to an incorrect value and compiler won’t help. Resources designer doesn’t help as well, at least indirectly, because it doesn’t generate externally usable key names. It generates strong typed getters though, like:

internal static string ResourceKey {
        get {
             return ResourceManager.GetString("ResourceKey", resourceCulture);
        }
}

So, these getters are the only strong typed artifact that can be used to achieve strong typed reference. Luckily there is one C# (also VB) feature that was introduced in 6.0 and it is very useful in improving strong typed aspect of code. it is nameof keyword. it is evaluated at compile time and replaces the given expression with a string representation.

In other words, the sample above can be rewritten in strong typed manner:

public enum SomeEnum
{
	[Display(Name = nameof(Resources.ResourceKey), ResourceType=typeof(Resource)]
	SomeValue
}

This way the name is guaranteed to match since it is checked at compile time. So, no more mismatch between the key name and reference to it.

Of course, nameof can be used in many other places. Most notably in INotifyPropertyChanged/MVVM scenario.

Fixing connection problems between Visual Studio and Mac when building iOS applications

I’ve been digging a bit into problems of connection between Visual Studio (Xamarin.iOS) and a Mac and wanted to share a few tips here.

It all started with my Visual Studio being unable to build an iOS application due to the connection issues. Basically I could connect through Xamarin Mac Agent (XMA) through Visual Studio but then the build would fail saying that it couldn’t log to target Mac given my username.

For starters one might read Connecting to the Mac and Connection Troubleshooting topics. But my problem wasn’t listed there or anywhere else. So I had to figure it out on my own.

First hint was that XMA required me to type in the username/password for connecting to the Mac. It connected and I could show the iOS simulator but I couldn’t build. When configured properly it shouldn’t ask for credentials, perhaps only for the first time. For me it was asking for credentials each time I started Visual Studio.

After reading, digging and googling I understood that XMA is using SSH tunnel to connect to the Mac. First thing was inspecting the log files (VS Help/Xamarin/Open Logs…). I didn’t find much there (other than failed connection to the host lines), or so I thought. Next thing was – checking the SSH connectivity (command prompt, ssh username@host). Using my default private key I had no problems connecting to the Mac but Visual Studio kept failing the build process. Next thing to try was Xamarin’s own SSH diagnostics app (provided as C# sources – kudos) which would throw Permission Denied (publickey) upon Connecting to host. Since the public key is on host, the problem obviously has to do with the host – but why since it was working from command prompt. Using this app I also found out what private key is XMA using. And it isn’t my default one, which I tested the connection with.

The thing is that XMA is using its own private key which you can find it at %LocalAppData%Xamarin/MonoTouch/id_rsa. So next thing I tried was connecting through command prompt/ssh using –i PATH argument (forces what key is used), i.e. (replace %LocalAppData% with value) ssh –i %LocalAppData%Xamarin/MonoTouch/id_rsa user@host. And yes, it didn’t work. So definitely a key issue.

The solution

Time for looking at Mac, specially in file /Users/username/.ssh/authorized_keys  where public keys for my profile are stored. And as anybody would guess, it was missing Xamarin’s public key. To get one from the private key I used Puttygen (a part of PuTTY): imported XMA’s private key and copy & pasted the public key portion right into the new line of authorized_keys file on Mac (I had my default public key already in there). This time the ssh command line tool connected without problems. And so did XMA from Visual Studio. Happy me.

The cause

This let me thinking, why does it usually works without intervention. After further examination of log files, it was clear. XMA first tries using its private key, if it doesn’t succeed it tries to cat the public key portion to authorized_keys file on Mac (probably using the credentials you have to enter ). But what happens if the authorized_keys file is read-only? Ha, nothing, a log entry and that’s it. This was my case, I had authorized_keys file as read only. I wouldn’t mind a clear warning: “hey dude, XMA was unable to modify your authorized_keys file, please enter this public_key manually”. It’d certainly spared me some time.

The security considerations

Let me repeat what happens when first time connecting to Mac. XMA would create a private key and put its public part into authorized_keys on Mac. Were you aware of that? No? Neither was I. To make things complicated, the private key in question isn’t password protected. Theoretically an app that user runs (no admin privileges required) could use the key (or worse, copy it through the Internet) to connect to your Mac and gain your credentials on the Mac, which are most probably administration ones. It still would have to type in password for su access, but nevertheless, this isn’t something that should be taken easily IMO.

I certainly wish that the connection mechanism was better documented and people were aware what’s going on. If nothing else, we could pinpoint the problems more easily. Also, an option to use password protected private key would be much more secure.