📜 ⬆️ ⬇️

Network non-cross-platform



Hello! In this article, I would like to share my experience with novice developers who are learning to write mobile applications, but have not advanced very far in this field. To be precise, I would like to tell you how to write portable code and design applications that will work both on native .NET platforms (Windows Phone 7 and Windows desktop applications) and on portable .NET versions for mobile platforms, such as Monotouch and Monodroid.

A bit about Mono and Portable Class Library


In order to understand in detail how to write portable code, you first need to understand how .NET works on iOS and Android. This topic is very large, therefore, as Vladimir Vladimirovich says, I will be brief.
')
Monotouch

Mono on iOS works like this: no JIT compiler and no .NET on iOS itself. All code, absolutely all, including the entire implementation of .NET, is compiled into the native bytecode and “stretches” with the distribution package of the application.

From here follow the following "pluses, minuses and an underwater rake". Plus - speed (native code, by definition, faster). Minus number 1: the volume of the distribution package of the application - at least 6 MB. Minus number 2: unfortunately, only the Silverlight 4 profile is ported, and not completely.

The main surprise: no generics and no reflection. And therefore - no games with collections, custom proxy classes for WCF, data binding a la WPF.

Monodroid

On .NET on Android, you need to say the following: at first glance, not everything is so sad: there is a JIT, and generics. However ... Generics are inferior (parameter classes must inherit from Java.Lang.Object), and JIT is not exactly JIT. Here, too, it is possible to single out the topic for a separate article, if this topic is interesting to the Habras community.

Portable Class Library and Windows Phone 7

The most extensive use of C # has, of course, the mobile platform from Microsoft. Especially for it was developed version of Silverlight. However, the builds that were compiled for Windows Phone will not work on the desktop application. This is understandable, although very inconvenient: the target platforms are still different.

To adequately support code portability between Windows Phone and a fully-fledged .NET, the Portable Class Library (PCL) profile was implemented - a set of base classes that are present on all platforms that support the official version of .NET - Windows, Metro, Windows Phone, Silverlight and Xbox.

Nuance

When developing for Mono *, you can directly refer to assemblies that have been compiled for full-fledged versions of .NET to 3.5. And if your build uses only classes from supported namespaces, everything will work fine. If you try to access an unimplemented class, you just get a NotImplementedException exception; such is the white magic of the Monotouch compiler.

However, the project for Windows Phone 7 will simply not allow adding a link to such a collection (which is quite logical). "But what about the Portable Class Library? .." - you ask. This is where black magic begins: when you try to use assemblies compiled for PCL or WP7 in Mono * projects, you will receive an error message: it is impossible to load an assembly that references WP7 or PCL libraries.

It is still not clear to me why it is implemented this way; All questions about this technical support answers: "Coming soon." I am glad only that the new version of MonoDevelop (the development environment for Monotouch on Mac) was released not so long ago, in the description of which it was explicitly stated that partial support for PCL is being implemented, but I could not understand where exactly.

Implementation


So, having the implementation of the libraries we need on all the platforms we are interested in, we cannot create one assembly for all platforms that would use the necessary classes. We will have to compile two assemblies - for Windows platforms and for Mono platforms.

But here we again face a small problem. The most convenient class when implementing a client for a web service is WebClient. But for some mysterious reasons, it was removed from the second edition of PCL, although it is implemented on Windows Phone 7 and in desktop applications. The developers argue that WebClient is not supported in Metro applications. Therefore, if you want to develop an application, including for Metro, you will have to use the lower-level classes WebHttpRequest and WebHttpResponse. For simplicity, I will show an example of the implementation of a proxy class for working with WebClient.

What we need:


Getting Started.

1. Install Windows Phone SDK and Monodroid. We create two projects: the first project is the Windows Phone Library, the second is the Android Class Library. If you want to develop a universal Windows library, create a Portable Class Library instead of the Windows Phone Class Library. But in this case, you will have to use the same less convenient HttpWebRequest and HttpWebResponse to work with the web service.

2. Further, we will conduct the main work with the Android Class Library. To ensure compatibility of this assembly with the Monotouch project, it is necessary to ensure that there are no unnecessary references specific to Monodroid in this assembly. In the project, leave the following links:


3. Suppose that we have a spherical REST service in vacuum, which is located at http: // webservice: 47154 / rest / vendor and returns us a list of software manufacturers.



To use this service, just write the following code (create a class into which our web service response will be deserialized, and the proxy class itself, which will request the service).

//   public class Vendor { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } } // -    - public class VendorsProxy { private string _host; public VendorsProxy(string host) { _host = host; } public event VendorsEventHandler GetVendorsCompleted; public void GetVendors() { var client = new WebClient(); client.DownloadStringCompleted += (s, e) => { var vendors = JsonConvert.DeserializeObject<IEnumerable<Vendor>>(e.Result); if (GetVendorsCompleted != null) GetVendorsCompleted(new VendorsEventArgs(vendors)); }; client.DownloadStringAsync(new Uri(_host + @"rest/vendor")); } } public delegate void VendorsEventHandler(VendorsEventArgs vendors); public class VendorsEventArgs : EventArgs { public IEnumerable<Vendor> Vendors { get; private set; } public VendorsEventArgs(IEnumerable<Vendor> vendors) { Vendors = vendors; } } 

4. Now in the WP Library project it’s enough to add not the files themselves, but the links to the files from the Android Class Library project.


That's all. Now, if you build a complete solution, the output will be two assemblies that work equally well on both Windows Phone and iOS and Android devices. You can use your web service on any platform as follows.

 var proxy = new VendorsProxy("http://mywebservice:8080/"); proxy.GetVendorsCompleted += (vendors) => { BindVedorsToVoewModel(vendors.Vendors); }; proxy.GetVendors(); 

Doubts


Of course, one can argue about the need for such “dances with a tambourine” to achieve such universality: for sure, each platform will have its own specifics and its own best practices. However, if you are a confident .NET programmer and you need to quickly create a simple mobile application that works with a web service, this solution may be useful.

If the Habrasoobshchestvo shows interest in this topic, then in the next article I will talk about how to protect connections in cross-platform applications.

Author: Sergey Shulik, senior programmer at Positive Technologies.

Source: https://habr.com/ru/post/146342/


All Articles