Mobiele apps programmeren met Xamarin – Tekstbestanden integreren

print

Inhoud


Wat vooraf ging

  • U hebt kennis gemaakt met klassen.

De bestanden toevoegen

We bespreken de integratie van volgende bestandstypen:

  • Tekstbestanden
  • XML
  • JSON

We gaan deze bestanden rechtstreeks toevoegen aan het project als een Embedded Resource maar eerst maken we onze pagina aan.

  • Start een nieuw Xamarin-project en geef het een passende naam (bv. TekstIntegreren).
  • Voeg de onderstaande XAML toe aan MainPage.xaml.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:TekstIntegreren" x:Class="TekstIntegreren.MainPage">
    <StackLayout>
        <Button Text="Laden" Clicked="Button_Clicked"></Button>
        <Label Text="Tekst" VerticalOptions="Center" HorizontalOptions="Center" FontSize="Large"/>
        <Label x:Name="LblLaadTekst"></Label>
        <Label Text="XML" VerticalOptions="Center" HorizontalOptions="Center" FontSize="Large"/>
        <ListView x:Name="ListXML"></ListView>
        <Label Text="JSON" VerticalOptions="Center" HorizontalOptions="Center" FontSize="Large"/>
        <ListView x:Name="ListJson"></ListView>
    </StackLayout>

</ContentPage>


Tekstbestanden

  • Klik rechts op het project en klik op AddNew Item…..
  • In General selecteert u Text File en u geeft het een passende naam (bv. LaadTekst.txt).

  • Zet de eigenschap Build Action op Embedded Resource.

  • Typ een stukje tekst in het tekstbestand LaadTekst.txt.
Deze tekst is geladen vanuit een tekstbestand!

Geert Linthoudt

Het inlezen van de Embedded Resource gebeurt met behulp van assembly.GetManifestResourceStream() onderdeel van de bibliotheek System.Reflection die moet aangeroepen worden using System.Reflection;. Er wordt een Stream teruggegeven.

A stream is an abstraction of a sequence of bytes, such as a file, an input/output device, an inter-process communication pipe, or a TCP/IP socket.

De assembly, een gecompileerde uitvoer van code (zoals een .exe of .dll), is hier een verwijzing naar de huidige klasse (het huidige formulier, hier MainPage).

var assembly = typeof(MainPage).GetTypeInfo().Assembly;

De Embedded Resource zelf wordt aangeduid door de naam van het project (de namespace), gevolgd door de volledige naam, inclusief extensie, van het bestand.

Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadTekst.txt");

Deze Stream moet dan worden gelezen via een StreamReader.

var assembly = typeof(MainPage).GetTypeInfo().Assembly;

Deze Stream wordt tenslotte tot het einde gelezen en aan een tekst toegekend.

string tekst = reader.ReadToEnd();
LblLaadTekst.Text = tekst;

De volledige code wordt dus:

var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadTekst.txt");
var reader = new StreamReader(stream);
string tekst = reader.ReadToEnd();
LblLaadTekst.Text = tekst;

Omdat het bestand gebruik maakt van Resources die na gebruik moeten worden vrijgegeven kunnen we de code het best aanpassen en gebruik maken van using. Hiermee wordt er voor gezorgd dat alle gebruikte Resources correct worden vrijgegeven.

string tekst = "";

var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadTekst.txt");

using (var reader = new StreamReader(stream))
{
    tekst = reader.ReadToEnd();
}

LblLaadTekst.Text = tekst;

Of de volledige Code-behind:

using System;
using Xamarin.Forms;
using System.IO;
using System.Reflection;


namespace TekstIntegreren
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            string tekst = "";

            //Tekstbestand laden
            var assembly = typeof(MainPage).GetTypeInfo().Assembly;
            Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadTekst.txt");

            using (var reader = new StreamReader(stream))
            {
                tekst = reader.ReadToEnd();
            }

            LblLaadTekst.Text = tekst;

        }
    }
}

XML-bestanden

  • Klik rechts op het project en klik op AddNew Item…..
  • In Data selecteert u XML File en u geeft het een passende naam (bv. LaadXML.xml).

  • Zet de eigenschap Build Action op Embedded Resource.

  • Kopieer onderstaande xml-code (allemaal aapjes) in het bestand LaadXML.xml.
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfMonkey xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Monkey>
    <Name>Baboon</Name>
    <Location>Africa &amp; Asia</Location>
    <Details>Baboons are African and Arabian Old World monkeys belonging to the genus Papio, part of the subfamily Cercopithecinae.</Details>
  </Monkey>
  <Monkey>
    <Name>Capuchin Monkey</Name>
    <Location>Central &amp; South America</Location>   
    <Details>The capuchin monkeys are New World monkeys of the subfamily Cebinae. Prior to 2011, the subfamily contained only a single genus, Cebus.</Details>
  </Monkey>
  <Monkey>
    <Name>Blue Monkey</Name>
    <Location>Central &amp; East Africa</Location>
    <Details>The blue monkey or diademed monkey is a species of Old World monkey native to Central and East Africa, ranging from the upper Congo River basin east to the East African Rift and south to northern Angola and Zambia.</Details>
  </Monkey>
  <Monkey>
    <Name>Squirrel Monkey</Name>
    <Location>Central &amp; South America</Location>
    <Details>The squirrel monkeys are the New World monkeys of the genus Saimiri. They are the only genus in the subfamily Saimirinae. The name of the genus Saimiri is of Tupi origin, and was also used as an English name by early researchers.</Details>
  </Monkey>
  <Monkey>
    <Name>Golden Lion Tamarin</Name>
    <Location>Brazil</Location>
    <Details>The golden lion tamarin also known as the golden marmoset, is a small New World monkey of the family Callitrichidae.</Details>
  </Monkey>
  <Monkey>
    <Name>Howler Monkey</Name>
    <Location>South America</Location>
    <Details>Howler monkeys are among the largest of the New World monkeys. Fifteen species are currently recognised. Previously classified in the family Cebidae, they are now placed in the family Atelidae.</Details>
  </Monkey>
  <Monkey>
    <Name>Japanese Macaque</Name>
    <Location>Japan</Location>
    <Details>The Japanese macaque, is a terrestrial Old World monkey species native to Japan. They are also sometimes known as the snow monkey because they live in areas where snow covers the ground for months each</Details>
  </Monkey>
  <Monkey>
    <Name>Mandrill</Name>
    <Location>Southern Cameroon, Gabon, Equatorial Guinea, and Congo</Location> 
    <Details>The mandrill is a primate of the Old World monkey family, closely related to the baboons and even more closely to the drill. It is found in southern Cameroon, Gabon, Equatorial Guinea, and Congo.</Details>
  </Monkey>
  <Monkey>
    <Name>Proboscis Monkey</Name>
    <Location>Borneo</Location>
    <Details>The proboscis monkey or long-nosed monkey, known as the bekantan in Malay, is a reddish-brown arboreal Old World monkey that is endemic to the south-east Asian island of Borneo.</Details>
  </Monkey>
</ArrayOfMonkey>

Dit bestand bevat een lijst met “aapjes”. De Name, location en Details worden bijgehouden. Om deze informatie te kunnen opvangen dienen we een klasse aan te maken die dezelfde eigenschappen bevat.

  • Klik rechts op het project en klik op AddNew Item…..
  • In Code selecteert u Class en u geeft het de naam monkey.cs.

Maak onderstaande klasse aan.

namespace TekstIntegreren
{
    public class Monkey
    {
        public string Name { get; set; }
        public string Location { get; set; }
        public string Details { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}

De nodige eigenschappen Name, location en Details worden aangemaakt, allen van het type string.

De ToString()-methode wordt overschreven zodat de Name standaard getoond wordt in de lijst.

Het inladen van de Embedded Resource gebeurt op dezelfde manier als hierboven, bij het tekstbestand, beschreven.

var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadXML.xml");

Het eigenlijke omzetten van de XML naar de klasse gebeurt op basis van Serialization. Ik ga me hier beperken tot de finale werkende code, wie alles wilt weten over Serialization klikt de link maar aan.

List<Monkey> monkeys;
using (var reader = new StreamReader(stream))
{
    var serializer = new XmlSerializer(typeof(List<Monkey>));
    monkeys = (List<Monkey>)serializer.Deserialize(reader);
}

Er wordt eerst een lijst aangemaakt van het type Monkey.

List<Monkey> monkeys;

Gebruikmakend van een using, die zorgt voor een correct vrijgeven van gebruikte resources, wordt de Stream tot het einde gelezen.

List<Monkey> monkeys;
using (var reader = new StreamReader(stream))
{
}

Er wordt een XMLSerializer gedefinieerd die de ingelezen stroom, de lijst met aapjes, moet deserializeren.

using System;
using Xamarin.Forms;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using System.Collections.Generic;

namespace TekstIntegreren
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            string tekst = "";

            //Tekstbestand laden
            var assembly = typeof(MainPage).GetTypeInfo().Assembly;
            Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadTekst.txt");

            using (var reader = new StreamReader(stream))
            {
                tekst = reader.ReadToEnd();
            }

            LblLaadTekst.Text = tekst;


            //xml laden
            stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadXML.xml");

            List<Monkey> monkeys;
            using (var reader = new StreamReader(stream))
            {
                var serializer = new XmlSerializer(typeof(List<Monkey>));
                monkeys = (List<Monkey>)serializer.Deserialize(reader);
            }

            ListXML.ItemsSource = monkeys;

        }
    }
}

Vergeet niet de gebruikte bibliotheken toe te voegen.

using System.Xml.Serialization;
using System.Collections.Generic;

JSON

Net zoals bij tekstbestanden en Xml-bestanden.

  • Klik rechts op het project en klik op AddNew Item…..
  • In General selecteert u Text File en u geeft het een passende naam (bv. LaadJSON.json).
  • Zet de eigenschap Build Action op Embedded Resource.
  • Kopieer onderstaande JSON-code naar LaadJSON.json.
{"earthquakes": [
    {
      "datetime": "2011-03-11 04:46:23",
      "depth": 24.4,
      "lng": 142.369,
      "src": "us",
      "eqid": "c0001xgp",
      "magnitude": 8.8,
      "lat": 38.322
    },
    {
      "datetime": "2012-04-11 06:38:37",
      "depth": 22.9,
      "lng": 93.0632,
      "src": "us",
      "eqid": "c000905e",
      "magnitude": 8.6,
      "lat": 2.311
    },
    {
      "datetime": "2007-09-12 09:10:26",
      "depth": 30,
      "lng": 101.3815,
      "src": "us",
      "eqid": "2007hear",
      "magnitude": 8.4,
      "lat": -4.5172
    },
    {
      "datetime": "2012-04-11 08:43:09",
      "depth": 16.4,
      "lng": 92.4522,
      "src": "us",
      "eqid": "c00090da",
      "magnitude": 8.2,
      "lat": 0.7731
    },
    {
      "datetime": "2007-04-01 18:39:56",
      "depth": 10,
      "lng": 156.9567,
      "src": "us",
      "eqid": "2007aqbk",
      "magnitude": 8,
      "lat": -8.4528
    },
    {
      "datetime": "2015-04-25 06:13:40",
      "depth": 15,
      "lng": 84.6493,
      "src": "us",
      "eqid": "us20002926",
      "magnitude": 7.9,
      "lat": 28.1306
    },
    {
      "datetime": "2007-09-12 21:49:01",
      "depth": 10,
      "lng": 100.9638,
      "src": "us",
      "eqid": "2007hec6",
      "magnitude": 7.8,
      "lat": -2.5265
    },
    {
      "datetime": "2016-03-02 12:55:00",
      "depth": 24,
      "lng": 94.275,
      "src": "us",
      "eqid": "us10004u1y",
      "magnitude": 7.8,
      "lat": -4.9082
    },
    {
      "datetime": "2015-05-30 11:36:00",
      "depth": 677.56,
      "lng": 140.4932,
      "src": "us",
      "eqid": "us20002ki3",
      "magnitude": 7.8,
      "lat": 27.8312
    },
    {
      "datetime": "2013-04-16 08:44:20",
      "depth": 82,
      "lng": 62.0532,
      "src": "us",
      "eqid": "b000g7x7",
      "magnitude": 7.8,
      "lat": 28.1069
    }
  ]
}

Wie meer wilt weten over JSON kan hier en hier terecht.

Om JSON te kunnen gebruiken dienen we het eerst te integreren via een NuGet package.

  • Klik rechts op de Solution en klik op Manage NuGet Packages for solution.
  • Klik op Browse en u vindt Newtonsoft.JSON helemaal bovenaan (indien niet, zoekt u er achter).
  • Selecteer het volledige project en klik op Install.

Onderstaande video toont een volledige installatie (zij het in Visual Studio 2015 en voor een ASP.NET project maar in weze verschilt dit niet).

Dit bestand bevat een aantal aardbevingen met bijhorende informatie. Om deze informatie op te vangen maken we eerst weer een klasse die dezelfde eigenschappen bevat.

  • Klik rechts op het project en klik op AddNew Item…..
  • In Code selecteert u Class en u geeft het de naam Earthquake.cs.

Maak onderstaande klasse aan.

using System;

namespace TekstIntegreren
{
    public class Earthquake
    {
        public string eqid { get; set; }
        public float magnitude { get; set; }
        public float lng { get; set; }
        public string src { get; set; }
        public string datetime { get; set; }
        public float depth { get; set; }
        public float lat { get; set; }

        public override string ToString()
        {
            return String.Format("{0}, {1}, {2}, {3}", lat, lng, magnitude, depth);
        }

    }
}

De ToString()-methode wordt overschreven zodat een gewenste uitvoer getoond wordt in de lijst.
Omdat JSON de gegevens inleest als een array voegen we nog een klasse toe die een array van Earthquakes aanmaakt.

using System;

namespace TekstIntegreren
{
    public class Earthquake
    {
        public string eqid { get; set; }
        public float magnitude { get; set; }
        public float lng { get; set; }
        public string src { get; set; }
        public string datetime { get; set; }
        public float depth { get; set; }
        public float lat { get; set; }

        public override string ToString()
        {
            return String.Format("{0}, {1}, {2}, {3}", lat, lng, magnitude, depth);
        }

    public class EarthquakeList
    {
        public Earthquake[] earthquakes { get; set; }
    }
    }
}

De code voor het inladen is analoog met de bovenstaande code voor het inladen van tekstbestanden en Xml-bestanden.

Het inladen van de Embedded Resource gebeurt op dezelfde manier.

var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadJSON.json");

Het eigenlijke inlezen gebeurt nu niet in een lijst maar in een array (omdat JSON een array teruggeeft). Het eigenlijke deserialiseren gebeurt met de code JsonConvert.DeserializeObject(json) waarin EarthquakeList verwijst naar de net aangemaakte klasse die een array bevat.

Earthquake[] earthquakes;

using (var reader = new StreamReader(stream))
{
    var json = reader.ReadToEnd();
    var earthquakeList = JsonConvert.DeserializeObject<EarthquakeList>(json);

    earthquakes = earthquakeList.earthquakes;
}

ListJson.ItemsSource = earthquakes;

Vergeet niet de nodige bibliotheek op te nemen using Newtonsoft.Json;.

De volledige code is nu:

using System;
using Xamarin.Forms;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace TekstIntegreren
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            string tekst = "";

            //Tekstbestand laden
            var assembly = typeof(MainPage).GetTypeInfo().Assembly;
            Stream stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadTekst.txt");

            using (var reader = new StreamReader(stream))
            {
                tekst = reader.ReadToEnd();
            }

            LblLaadTekst.Text = tekst;


            //xml laden
            stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadXML.xml");

            List<Monkey> monkeys;
            using (var reader = new StreamReader(stream))
            {
                var serializer = new XmlSerializer(typeof(List<Monkey>));
                monkeys = (List<Monkey>)serializer.Deserialize(reader);
            }

            ListXML.ItemsSource = monkeys;

            //JSON laden

            stream = assembly.GetManifestResourceStream("TekstIntegreren.LaadJSON.json");

            Earthquake[] earthquakes;

            using (var reader = new StreamReader(stream))
            {
                var json = reader.ReadToEnd();
                var earthquakeList = JsonConvert.DeserializeObject<EarthquakeList>(json);

                earthquakes = earthquakeList.earthquakes;
            }

            ListJson.ItemsSource = earthquakes;

        }
    }
}


Behandelde Basiscompetenties uit de module ICT Programmeren – Integratie externe functionaliteiten

  • IC BC254 – kan externe content integreren en structureren
  • IC BC255 – kan de geïntegreerde content in functie van het beoogde eindresultaat aanpassen
  • IC BC256 – kan diverse elementen tot een nieuw betekenisvol geheel samenstellen
  • IC BC258 – houdt rekening met regelgeving m.b.t. licenties voor het gebruik en de publicatie van broncode
  • IC BC288 – kan ICT-problemen oplossen

Geef een reactie

  • Abonneer je op deze website d.m.v. e-mail

    Voer je e-mailadres in om je in te schrijven op deze website en e-mailmeldingen te ontvangen van nieuwe berichten.