<?xml version="1.0" encoding="utf-8"?>
<!-- generator="Kirby" -->
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">

  <channel>
    <title>Mot-cl&#233;: xamarin &#183; Blog &#183; Liip</title>
    <link>https://www.liip.ch/fr/blog/tags/xamarin</link>
    <generator>Kirby</generator>
    <lastBuildDate>Fri, 01 Jun 2018 00:00:00 +0200</lastBuildDate>
    <atom:link href="https://www.liip.ch" rel="self" type="application/rss+xml" />

        <description>Articles du blog Liip avec le mot-cl&#233; &#8220;xamarin&#8221;</description>
    
        <language>fr</language>
    
        <item>
      <title>Why and how we use Xamarin</title>
      <link>https://www.liip.ch/fr/blog/why-how-xamarin</link>
      <guid>https://www.liip.ch/fr/blog/why-how-xamarin</guid>
      <pubDate>Fri, 01 Jun 2018 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>When we start a new project, we always ask ourselves if we should choose Xamarin over a full native solution. I wanted to reflect on past projects and see if it was really worth using Xamarin. </p>
<p>But how do you compare projects? I decided to use line counting. It can seem obvious or simplistic, but the number of shared lines of code will easily show how much work has been done once instead of twice. I took the two most recent Xamarin projects that we worked on <a href="https://ski.ticketcorner.ch/campaign/ski-app">Ticketcorner Ski</a> and <a href="https://www.together-in-switzerland.ch">together</a>.</p>
<p>I used the following method:</p>
<ul>
<li>Use the well-known <a href="https://github.com/AlDanial/cloc/">cloc</a> tool to count the number of lines in a project.</li>
<li>Count only C# files.
<ul>
<li>Other types such as json configuration files or API response mocks in unit tests do not matter.</li>
</ul></li>
<li>Make an exception with Android layout files.
<ul>
<li>Our iOS layout is all done in Auto Layout code and we don't use Xcode Interface Builder.</li>
<li>To have a fair comparison, I included the Android XML files in the line count.</li>
</ul></li>
<li>Do not count auto-generated files.</li>
<li>Do not count blank lines and comments.</li>
<li>Other tools like <a href="https://fastlane.tools/">Fastlane</a> are also shared, but are not taken into account here.</li>
</ul>
<p>If you want to try with one of your one project, here are the commands I used for the C# files:</p>
<pre><code class="language-bash">cloc --include-lang="C#" --not-match-f="(([Dd]esigner)|(AssemblyInfo))\.cs" .</code></pre>
<p>For the Android XML layouts, I used:</p>
<pre><code class="language-bash">cloc  --include-lang="xml" --force-lang="xml",axml Together.Android/Resources/layout</code></pre>
<h2>Here is what I found:</h2>
<table>
<thead>
<tr>
<th style="text-align: left;">Project</th>
<th style="text-align: center;">Android</th>
<th style="text-align: center;">iOS</th>
<th style="text-align: center;">Shared</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">Ticketcorner Ski</td>
<td style="text-align: center;">31%</td>
<td style="text-align: center;">31%</td>
<td style="text-align: center;"><strong>38%</strong></td>
</tr>
<tr>
<td style="text-align: left;">together</td>
<td style="text-align: center;">42%</td>
<td style="text-align: center;">30%</td>
<td style="text-align: center;"><strong>28%</strong></td>
</tr>
</tbody>
</table>
<p>We can see that on those projects, an average of one third of code can be shared. I was pretty impressed to see that for Ticketcorner Ski we have the same number of lines on the two platforms. I was also pleasantly surprised to see that the project almost <strong>shares 40% of its code</strong>.</p>
<p>In a mobile app, most of the unit tests target the business logic, which is exactly what is shared with Xamarin: business logic and their unit tests are only written once. Most libraries not directly related to business logic are also shared: REST client, Database client, etc...</p>
<p>The code that is not shared is mostly UI code, interaction, etc... But it is also platform specific code: how to access the camera, how to handle push notifications, how to securely store user credentials according to each platform's guidelines.</p>
<p>It would not be fair to conclude that doing those projects in native would have been 30% more expensive. The shared code has sometimes to take into account that it will be used on two different platforms, and it gets more generic than it would be if written twice.</p>
<h2>So... how do you choose one or the other ?</h2>
<p>My goal with this blogpost is not to start a flame war on whether Xamarin is good or bad. I have shown here that for those projects, it was the right choice to use Xamarin. I want to share a few things we think about when we have to make a decision. Note that we use Xamarin.iOS and Xamarin.Android, but don't use Xamarin.Forms.</p>
<ul>
<li>Does the application contain a lot of business logic, or is it more UI-based?
<ul>
<li>With one Xamarin project we worked on in the past year, a specific (and complex) use-case was overlooked by the client and it resulted in paying users being pretty unhappy. We were very pleased to be able to fix the problem once, and write the related unit tests once too.</li>
<li>As a counterexample, for the <a href="https://www.zoo.ch/de/apps">Zürich Zoo app</a>, most of our job was writing UX/UI code. The business logic is solely doing GET requests to a backend.</li>
</ul></li>
<li>Do you plan to use external libraries/SDKs?
<ul>
<li>Xamarin is pretty good at <a href="https://docs.microsoft.com/en-us/xamarin/android/platform/binding-java-library/binding-a-jar">using .jar files on Android</a>.</li>
<li>Native libraries on iOS <a href="https://docs.microsoft.com/en-us/xamarin/cross-platform/macios/binding/objective-sharpie/">have to be processed manually</a> and it can be tedious to do. It is also hard to use a library packaged with CocoaPods that depends on many other pods.</li>
<li>For both platforms, We encountered closed-source tools that are not that easy to convert. As an example, we could use the <a href="https://www.datatrans.ch/en/technics/payment-apis/in-app-payment-libraries">Datatrans SDK</a>, but not without some <em>trial and error</em>.</li>
<li>There are however other Xamarin libraries that can replace what you are used to when developping on both platforms. We replace <a href="http://square.github.io/picasso/">Picasso</a> on Android and <a href="https://github.com/onevcat/Kingfisher">Kingfisher</a> on iOS by <a href="https://github.com/luberda-molinet/FFImageLoading">FFImageLoading</a> on Xamarin. This library has the same API methods on both platforms which makes it easy to use.</li>
</ul></li>
<li>Do you plan to use platform-specific features?
<ul>
<li>Xamarin is able to provide access to every platform feature, and it works well. It is also known that they update the Xamarin SDKs as soon as new iOS/Android versions are announced.</li>
<li>For <a href="https://www.liip.ch/x/cy7o8c">Urban Connect</a> however, the most important part of the app is using <em>Bluetooth Low Energy</em> to connect to bike locks. Even if Xamarin is able to do it too, it was the right decision to remove this extra layer and code everything natively.</li>
</ul></li>
<li>Tooling, state of the platform ecosystems:
<ul>
<li>In the mobile world, things move really fast:
<ul>
<li>Microsoft pushes really hard for developers to adopt Xamarin, for example with <a href="https://appcenter.ms/">App Center</a>, the new solution to build, test, release, and monitor apps. But Visual Studio for Mac is still really buggy and slow.</li>
<li>Google added first-class support for <a href="https://www.liip.ch/en/blog/kotlin-why-i-will-never-go-back-to-java">Kotlin</a>, has an awesome IDE and pushes mobile development with platforms like Firebase or Android Jetpack.</li>
<li>Apple follows along, but still somehow fails to improve Xcode and its tooling in a meaningful manner.</li>
</ul></li>
<li><strong>Choices made one day will certainly not be valid one year later.</strong></li>
</ul></li>
<li>Personal preferences:
<ul>
<li>Inside Liip there are very divergent opinions about Xamarin. We always choose the right tool for the job. Having someone efficient and motivated about a tool is important too.</li>
</ul></li>
</ul>
<p>I hope I was able to share my view on why and how we use Xamarin here at Liip. I personally enjoy working both on Xamarin or native projects. Have a look at <a href="https://www.together-in-switzerland.ch">together</a> and <a href="https://ski.ticketcorner.ch/campaign/ski-app">Ticketcorner Ski</a> and tell us what you think!</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/c03533/2000px-xamarin-logo-svg.jpg" length="48001" type="image/png" />
          </item>
        <item>
      <title>Hackday React Native for Android</title>
      <link>https://www.liip.ch/fr/blog/hackday-react-native-android</link>
      <guid>https://www.liip.ch/fr/blog/hackday-react-native-android</guid>
      <pubDate>Thu, 08 Oct 2015 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>When React Native for Android came out I was excited to investigate it more at one of Liips monthly innovation days. Liip already developed a React Native app for iOS and we wanted to know how it works for Android. We were: Andrey, Germain, Lukasz and me. Germain is currently working on a cross platform app written with Xamarin.</p>
<p>For this hackday we tried to port <a href="https://github.com/liip/guess-the-liiper-ios">an existing React Native iOS app</a> to Android.</p>
<p>TL;DR: We are waiting for WebViews to be supported. See the <a href="https://github.com/liip/guess-the-liiper-ios/pull/29/files">pull request</a> for changes. We didn't need to dive deep into Android APIs like XML Layouts for views.</p>
<h3>How code sharing works</h3>
<p>React Native has a “packer” which is responsible for collecting and loading all javascript files and resources. To avoid explicitly checking for the current platforms using  _if/else _blocks, the packer ignores all files which end in .android.js on iOS and all files ending in .ios.js  on Android. The way to develop platform specific components is: First divide the app into small components, each component in its own file. Then implement a platform specific version of a component that works differently.</p>
<figure><a href="https://www.liip.ch/content/4-blog/20151008-hackday-react-native-android/guess-android.gif"><img src="https://liip.rokka.io/www_inarticle/b3e35a72739b583231ed822accd71287f708c8f9/guess-android.jpg" alt="Guess the Liiper on Android – Progress circle animation"></a></figure>]]></description>
          </item>
        <item>
      <title>Writing iOS Layout Constraints The Easy Way</title>
      <link>https://www.liip.ch/fr/blog/writing-ios-layout-constraints-the-easy-way</link>
      <guid>https://www.liip.ch/fr/blog/writing-ios-layout-constraints-the-easy-way</guid>
      <pubDate>Thu, 27 Aug 2015 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Coming from a web-development background, native iOS development always feels a bit clunky to me when it comes to creating the layouts.</p>
<p>Yes, there is the Interface Builder and it is a great tool, but sometimes,</p>
<p>things get more generic and building the views and layouts can be more efficiently done by hand.</p>
<p>Except – layout constraints! Writing layout constraints can be tedious work.</p>
<p>Example, making an element the half of the width of its parent element in objective-c:</p>
<pre><code>[self.view addSubview:centerView];

// Width constraint, half of parent view width
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:centerView
                               attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual
                               toItem:self.view attribute:NSLayoutAttributeWidth
                               multiplier:0.5 constant:0]];</code></pre>
<p>It is not much better in C# with Xamarin either:</p>
<pre><code>View.AddSubview(centerView);

// Width constraint, half of parent view width
View.AddConstraint(
    NSLayoutConstraint.Create(centerView, 
        NSLayoutAttribute.Width, NSLayoutRelation.Equal, 
        View, NSLayoutAttribute.Width, 
        0.5f, 0f
   )
);</code></pre>
<p><strong>But behold! There is our ConstraintHelper!</strong> </p>
<pre><code>ConstraintHelper.Attach(centerView).WidthOfParent(0.5f).Top().Center();</code></pre>
<p>The ConstraintHelper is a small C# library to help with the layout constraints and it brings less common concepts like <a href="https://en.wikipedia.org/wiki/Method_chaining">Method Chaining</a> to the layout constraints.</p>
<p><a href="https://github.com/semiroot/ConstraintHelper">ConstraintHelper is Open Source and can be forked from GitHub</a>.</p>]]></description>
          </item>
        <item>
      <title>Using a powerful and full-featured search engine on mobile platforms</title>
      <link>https://www.liip.ch/fr/blog/using-a-powerful-and-full-featured-search-engine-on-mobile-platforms</link>
      <guid>https://www.liip.ch/fr/blog/using-a-powerful-and-full-featured-search-engine-on-mobile-platforms</guid>
      <pubDate>Mon, 15 Dec 2014 00:00:00 +0100</pubDate>
      <description><![CDATA[<h2>When Xamarin meets Lucene…</h2>
<h3>Introduction</h3>
<p>As soon as we are dealing with a bigger amount of data, it can be complicated to find what you are actually looking for. It is obvious that we can ease the task of finding information by structuring our data and by offering an intuitive user interface.</p>
<p>Nonetheless, there are several scenarios where a search engine can come in handy.</p>
<p>Probably the best example is our good old friend the Internet. Information is stored and obtained in various ways and it is an immense yet growing collection of information resources. If you do not exactly know what you are looking for, your search engine of choice is an essential helper to point you into the right direction.</p>
<p>Implementing search capabilities in your desktop application is no rocket science because you can rely on powerful search engines that do the difficult work for you. It is rather a matter of configuration than implementing complex algorithms yourself. Especially when software is growing up, handcrafted search functionality is simply not satisfying anymore.</p>
<p>What do I expect from a “good” search engine? At first the obvious: return me the most accurate data I am looking for. It should find my information even if I misspell it (we all make mistakes). It should suggest me similar results and it should do all that fast. Pretty basic needs but quite some work if you have to implement this from scratch.</p>
<h3>A search engine for mobile?</h3>
<p>Some months ago, we had the opportunity to work on a very interesting project. The goal was to build a rich product catalog with enhanced search features that runs on mobile devices. Back then, our data was stored in a closed SAP environment and the easiest would have been to create a web service that provides the data (and handles all the searching, filtering, etc.). Hovewer, one challenging requirement was the offline capability: once the data has been synchronized with the device it needs to be searchable without internet connection. This means that we need a client side search engine and so the journey began..</p>
<p>One problem in finding a search engine for mobile devices is the diversity of programming languages. Assuming that you have an application that runs on iOS and Android, you also need a search engine that is supported by both platforms. We did some research to find mobile optimized search engines without much success. In the meanwhile it became clear that we had to write our Application in C# using Xamarin. Our client wanted to maintain the codebase by themselves afterwards.</p>
<p>Note: The Xamarin platform enables developers to write iOS, Android, Mac and Windows apps with native user interfaces using C#. Xamarin utilizes Mono, a free and open source project to run Microsoft .NET applications on different platforms. You can re-use your existing C# code and share a significant amount across device platforms.</p>
<h2>How mobile is your .NET?</h2>
<p>Xamarin provides this convenient tool called the .Net Mobility Scanner. It shows you how much of your .NET code can run on other operating systems.</p>
<p>Suddenly we had this funny idea to scan an existing .Net search engine we usually use for desktop applications.</p>
<p>We've scanned  <strong>Lucene.Net</strong>  and the result was quite interesting: 95% of your code is ready for mobilization! For iOS and Android itself, it even reached <strong>99%</strong> compatibility. There was actually only one piece of code which was not supported using a System.Configuration dependency – nothing critical.</p>
<p>You can find the scan results here:</p>
<p><a href="http://scan.xamarin.com/Home/Report?scanId=021c2372-6760-4104-9a3c-07400d51c82e">scan.xamarin.com/Home/Report?scanId=021c2372-6760-4104-9a3c-07400d51c82e</a></p>
<p>Note: Apache Lucene is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform. It has been ported to other programming languages including C#, targeting .NET runtime users.</p>
<p>The scan results raised several questions. Could we adapt Lucene.Net to actually run on mobile devices? Would it perform well? Is it stable enough? Did others already try it out? One thing was clear, we all agreed on giving it a try.</p>
<p>I looked around but found only one guy on Twitter that used this library for iOS &amp; Android projects. He told me that it actually works fine but memory consumption was always a bit of a problem. Nonetheless, we wanted to try it out ourselves so we downloaded the Lucene.Net source code and quickly fixed the  <strong>1%</strong> issue with the System.Configuration dependency. Everything was ready to do an extensive testing.</p>
<h3>Make your data searchable</h3>
<p>In order to make your data searchable, the first thing you need to do is building an index. Lucene stores its data as documents containing fields of text. You can basically index everything that contains textual information. Take your data and create a document for each one with certain fields and save these documents to a physical directory on your filesystem.</p>
<p>Simplified example of how this could look like (using Lucene.Net v.3.0.3):</p>
<pre><code class="language-csharp">public void BuildIndex ()
{
  var indexPath = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
    "index"
  );
  var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
  var indexDirectory = FSDirectory.Open(indexPath);
  var writer = new IndexWriter(indexDirectory, analyzer, IndexWriter.MaxFieldLength.LIMITED);
  var data = new ListData&gt;()
  {
    new Data { Id = 0, Text = "Introducing the Technology" },
    new Data { Id = 1, Text = "Xamarin meets Lucene" },
    new Data { Id = 2, Text = "A full-featured search engine for mobile" },
    new Data { Id = 3, Text = "Make your data searchable" }
  };

  foreach (var row in data)
  {
    Document doc = new Document();
    doc.Add(new Field("Id", row.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    doc.Add(new Field("Text", row.Text, Field.Store.YES, Field.Index.ANALYZED));
    writer.AddDocument(doc);
  }

  writer.Optimize();
  writer.Commit ();
  writer.Dispose();
  indexDirectory.Dispose();
}</code></pre>
<p>This is our small <code>Data</code> class:</p>
<pre><code class="language-csharp">public class Data
{
    public int Id { get; set; }
    public string Text { get; set; }
}</code></pre>
<p>If you want to try it out yourself you'll need to download install Xamarin ( <a href="http://xamarin.com/download">xamarin.com/download</a>) and the slightly modified Lucene.Net library ( <a href="https://github.com/chrigu-ebert/Xamarin-Lucene.Net">github.com/chrigu-ebert/Xamarin-Lucene.Net</a>).</p>
<h3>Indexing in Lucene.Net</h3>
<p>You just indexed a couple of documents with Lucene.Net, yeah! Let's have a look at the code example above. There are a couple of important things you need to keep in mind.</p>
<p>We open an index directory using <code>FSDirectory.Open</code> in which Lucene will store its indexed data. If you open a directory or file you should always close it by calling the corresponding Dispose method: <code>indexDirectory.Dispose()</code>. If don't do this you might corrupt your index because of locked files. The same applies to the IndexWriter which actually writes data into the directory.</p>
<p>You might have noticed that the IndexWriter needs an analyzer instance, in our case the <code>StandardAnalyzer</code>. When you want to insert data into a Lucene index, or when you want to get the data back out of the index you will need to use an Analyzer to do this. Lucene provides many different analyzer classes such as:</p>
<ul>
<li>SimpleAnalyzer</li>
<li>StandardAnalyzer</li>
<li>StopAnalyzer</li>
<li>WhiteSpaceAnalyzer</li>
<li>…</li>
</ul>
<p>There are ones for working with different languages, ones which determine how words are treated (and which words to be ignored) or how whitespace is handled. Understanding analyzers is somehow tricky and as we do not want to loose time, we simply use the StandardAnalyzer. It works very well especially on english content.</p>
<p>Last but not least we loop over our data and create a <code>new Document</code> for each and pass it to the <code>IndexWriter</code>. Each Document contains a set of fields which contain the data that we want to make searchable. Normally we store <code>Field</code> content as string but there is also a <code>NumericField</code> type which is very powerful, if you search by numeric ranges.</p>
<p>It is important to understand the <code>Field</code> attributes especially the <em>store</em> and <em>index</em> values to avoid common mistakes:</p>
<table border="0" width="100%" cellspacing="0" cellpadding="2"><tbody><tr><th valign="top">name</th>
<td valign="top">The name of the field, used to build queries later</td>
</tr><tr><th valign="top">value</th>
<td valign="top">The string representation of your data</td>
</tr><tr><th valign="top">store</th>
<td valign="top">Specifies if you want to store the value of the field in the index or not. It does not affect the indexing or searching with Lucene. It just tells Lucene if you want it to act as a datastore for the values in the field.

If you use`Field.Store.YES`, then when you search, the value of that field will be included in your search result documents. If you are storing your data in a database and only using the Lucene index for searching, then you can get away with `Field.Store.NO` on all of your fields. However, if your are using the index as storage as well, then you will want`Field.Store.YES`.</td>
</tr><tr><th valign="top">index</th>
<td valign="top">`Field.Index.ANALYZED:`Index the tokens produced by running the fields value through an Analyzer. This makes a lot of sense on longer texts to improve performance significantly but you might run into problems if you try to sort analyzed fields or if you want to find exact matches on single terms (e.g. unique IDs).

`Field.Index.ANALYZED_NO_NORMS:`

Index the tokens produced by running the fields value through an Analyzer, and also separately disable the storing of norms. No norms means that a few bytes will be saved by not storing some normalization data. This data is what is used for boosting and field-length normalization. The benefit is less memory usage as norms take up one byte of RAM per indexed field for every document in the index, during searching. Only use this flag if you are sure that youre not using that normalization data.

`Field.Index.ANALYZED_NO:`

The field will not be indexed and therefore unsearchable. However, you can use Index.No along with Store.Yes to store a value that you dont want to be searchable.

`Field.Index.ANALYZED_NOT_ANALYZED:`

Index the fields value without using an Analyzer, so it can be searched. As no analyzer is used the value will be stored as a single term. This is useful for unique Ids like product numbers or if you want to sort the results using this field.

`Field.Index.ANALYZED_NOT_ANALYZED_NO_NORMS:`

Index the fields value without an Analyzer and also disable the storing of norms.</td>
</tr></tbody></table>
<p>Finally, you'll have to call <code>writer.Commit()</code> to persist the changes. It is always a good thing to use <code>writer.Optimize()</code> from time to time to re-structure your index and improve search-performance. If your index is getting bigger, the optimization can take some time (several seconds).</p>
<p>Are you still with me? At this point, you hopefully understand, how you can make your data searchable. Get yourself a cookie, congrats!</p>
<h3>Searching in Lucene.Net</h3>
<p>Searching data using Lucene is incredibly powerful. I could write books just about that but this is not the goal of this blog post. We will do some really simple searches to explain the basics. Based on this you can build your own, amazingly complex queries.</p>
<p>We will use the following helper method to execute basic queries:</p>
<pre><code class="language-csharp">public List&lt;Data&gt; GetDataForQuery(Query query, int limit = 50)
{
  var data = new List&lt;Data&gt;();
  var indexPath = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
    "index"
  );
  var indexDirectory = FSDirectory.Open(indexPath);
  using (var searcher = new IndexSearcher(indexDirectory))
  {
    var hits = searcher.Search(query, limit);
    Console.WriteLine(hits.TotalHits + " result(s) found for query: " + query.ToString());
    foreach (var scoreDoc in hits.ScoreDocs)
    {
      var document = searcher.Doc(scoreDoc.Doc);
      data.Add(new Data()
      {
        Id = int.Parse(document.Get("Id")),
        Text = document.Get("Text")
      });
    }
  }
  indexDirectory.Dispose();
  return data;
}</code></pre>
<p>We simply use <code>FSDirectory</code> and <code>IndexSearcher</code> to open our index and to perform Lucene queries. We loop over the results and return them as <code>Data</code> list. As you might have noticed, similar to the <code>IndexWriter</code>, we have to explicitly Dispose the <code>IndexSearcher</code> (automatically done due to the <code>using</code> statement) and the <code>indexDirectory</code>.</p>
<p>Since we stored both field values during the indexing (<code>Field.Store.YES</code>), we can retrieve them using <code>document.Get("FieldName"&gt;)</code>. Our helper method takes two arguments: a Lucene <code>Query</code> object which will be explained below and a limit parameter. The <code>hits</code> variable contains a property called <code>hits.TotalHits</code>. which gives you the total amount of documents that does match your given query. If you have thousands of documents stored in your index, it doesn't make sense to return them all. Usually it is enough to just return a certain subset (limit) where you know that there are probably more results.</p>
<p>Getting all documents becomes as simple as that:</p>
<pre><code class="language-csharp">var query = new MatchAllDocsQuery();
var data = GetDataForQuery(query);</code></pre>
<p>The following example shows how to find a document by id using a TermQuery:</p>
<pre><code class="language-csharp">var term = new Term("Id", 2);
var query = new TermQuery(term);
var data = GetDataForQuery(query);
if(data.Any())
{
  //writesAfull-featuredsearchengineformobile
  Console.WriteLine(data.FirstOrDefault().Text);
}</code></pre>
<p>The following example shows a common mistake. We're trying to use a PrefixQuery to find documents which have a Text-field that starts with “Intro”:</p>
<pre><code class="language-csharp">// this does not return any data!
var term = new Term("Text", "Intro");
var query = newPrefixQuery(term);
var data = GetDataForQuery(query);</code></pre>
<p>Actually, we do have a document that has the following Text “Introducing the Technology” and it should actually work. But since our Text field is analyzed using the <code>StandardAnalyzer</code>, the text is tokenized and in this case stored lowercase. If you would change your Term into <code>new Term("Text", "intro")</code> it would return the document.</p>
<p>An easier way is using the Lucene query syntax [x] and the <code>QueryParser</code>:</p>
<pre><code class="language-csharp">var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
var parser = newQueryParser(Lucene.Net.Util.Version.LUCENE_30, "Text", analyzer);
var query = parser.Parse("Xamarin");
var data = GetDataForQuery(query);</code></pre>
<p>Because we use the same analyzer (<code>StandardAnalyzer</code>) as we did while indexing the documents, the sample code above returns our document.</p>
<p>You can perform wildcard queries using an asterisk (*) at the end of a word:</p>
<pre><code class="language-csharp">// this will match the word Technology
var query = parser.Parse("Tec*gy");</code></pre>
<p>The query parser can do a lot more. Using a tilde character (~) at the end of a word, indicates a fuzzy query:</p>
<pre><code class="language-csharp">// this will matchXamarin assuming that were a little drunk
var query = parser.Parse("amixarin~");</code></pre>
<h3>Summary</h3>
<p>As you can see, indexing and searching data is actually pretty simple. The examples above are just scratching the surface. As soon as you start combining queries using <code>BooleanQuery</code> band giving weight to certain fields, it starts to get really serious. So far we didn't even talk about <strong>filtering</strong> and <strong>sorting</strong> .</p>
<p>I strongly suggest you to give it a try. We have worked months on a project using Lucene and Xamarin together and indexed thousands of documents. The performance and possibilities are simply amazing.</p>
<p>If you are curious and already tried it out, you could also have a look at the Linq to Lucene project. I didn't try it out on a mobile device so far but it helps a lot to get started.</p>
<p>The code examples are tested on Lucene.Net version 3.0.3. Things might have changed significantly on older/newer versions. The stable version on apache.org didn't change for quite a while. If you want to get the latest version which is under active development, you can clone the Github repository (links below).</p>
<h4>Links</h4>
<ul>
<li><a href="http://xamarin.com/">xamarin.com</a></li>
<li><a href="http://scan.xamarin.com/">scan.xamarin.com</a></li>
<li><a href="http://lucene.apache.org/core/">lucene.apache.org/core</a></li>
<li><a href="http://lucenenet.apache.org/">lucenenet.apache.org</a></li>
<li><a href="https://github.com/apache/lucene.net">github.com/apache/lucene.net</a></li>
<li><a href="https://linqtolucene.codeplex.com/">linqtolucene.codeplex.com</a></li>
</ul>]]></description>
          </item>
    
  </channel>
</rss>
