SOFTWARE DEVELOPMENT NETWORK
MAGAZINE ISSN: 2211-6486
IN DIT NUMMER O.A.: Reflections On Mobile Development <
Seriële communicatie in .NET <
Visual Studio 2013: de vernieuwingen in vogelvlucht < Kinect for Windows: meer dan speelgoed! <
Nummer 120 februari 2014 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network
120
www.sdn.nl
Colofon Uitgave:
Software Development Network Tweeëntwintigste jaargang No. 120 • februari 2014
voorwoord
Bestuur van SDN:
Remi Caron, voorzitter Rob Suurland, penningmeester Marcel Meijer, secretaris
Redactie:
Beste SDN magazine lezer,
Marcel Meijer (
[email protected])
Bij de Olympische spelen in Rusland worden er knappe sportieve prestaties geleverd. Nederland zet zijn beste beentje voor en wij slepen een recordaantal medailles mee naar huis. Als SDN proberen we dat te evenaren met onze prestaties.
Aan dit magazine werd meegewerkt door:
Roel Hans Bethlehem, Bob Swart, Maarten van Stam, Arjen Bos, Alexander Meijers, Remi Caron, Marcel Meijer en natuurlijk alle auteurs!
Listings:
Zie de website www.sdn.nl voor eventuele source files uit deze uitgave.
Contact:
Software Development Network Postbus 506, 7100 AM Winterswijk Tel. (085) 21 01 310 Fax (085) 21 01 311 E-mail:
[email protected]
Vormgeving en opmaak:
Reclamebureau Bij Dageraad, Winterswijk www.bijdageraad.nl
©2014 Alle rechten voorbehouden. Niets uit deze uitgave mag worden overgenomen op welke wijze dan ook zonder voorafgaande schriftelijke toestemming van SDN. Tenzij anders vermeld zijn artikelen op persoonlijke titel geschreven en verwoorden zij dus niet noodzakelijkerwijs de mening van het bestuur en/of de redactie. Alle in dit magazine genoemde handelsmerken zijn het eigendom van hun respectievelijke eigenaren.
Adverteerders Microsoft Prodware
Op de evenementenagenda staan hele mooie events te wachten. Natuurlijk is er eerst ons SDN event op 28 maart en gevolgd door de Global Windows Azure Bootcamp op 5 verschillende locaties in Nederland (mede door ons georganiseerd). Daarna zal er tijdens het Build event in San Francisco meer duidelijk worden over de Windows 8.1 en de Windows Phone 8 update. Daar zullen vast ook weer meer mooie en nieuwe zaken rondom Windows Azure en Microsoft producten getoond gaan worden. Uiteraard staan de andere platforms ook niet stil. Apple zal binnenkort ook meer laten zien over hun iWatch en nieuwe producten. Op de CeBIT in Duitsland zullen producten voor de toekomst uitgelicht worden. Het worden spannende en mooie weken voor Gadgeteers zoals ik. In dit eerste SDN magazine van 2014 hebben we met de hulp van Sander, Dennis, Cary, Marcel, Marcel, Andre, Michiel, Hassan, Pietwillem, Sander, Bob en Alex weer een bonte verzameling van artikelen. Artikelen over tegels in Windows 8, REST in Delphi, Kinect for Windows, Xbox ONE review, CodeUI test, Cross device Testing, Reflections on Mobile development, Product ontwikkeling, Serial communicatie in .NET en een overzicht van de vele verbeteringen in Visual Studio 2013. Absoluut weer de moeite waard. Ik ben er erg trots op dat het ons ook deze keer weer gelukt is zo’n mooi en evenwichtig magazine te maken. Mocht je na het lezen van dit magazine denken, ik mis een artikel over een bepaald onderwerp. Laat het ons (de overige SDN medewerkers of mij) via de mail weten. Wij gaan dan ons uiterste best doen om een auteur te vinden over dat onderwerp. We helpen je ook om zelf een artikel te schrijven. Met raad en daad zullen we je dan ondersteunen. Veel leesplezier en mail ons jullie vragen cq. opmerkingen. Groeten, Marcel
[email protected] •
2 44
Adverteren? Informatie over adverteren en de advertentietarieven kunt u vinden op www.sdn.nl onder de rubriek Magazine.
magazine voor software development 3
Agenda 2014 • 28 maart 2014 SDN event 1 + ALV • 29 maart 2014 Global Windows Azure Bootcamp • 2-4 april 2014 Build event (San Francisco) • 16-17 april 2014 TechDays • 16 mei 2014 SDN magazine 121 • 23 mei 2014 SDN event 2 • 27-28 mei 2014 Techorama (België) • 22 augustus 2014 SDN magazine 122 • 19 september 2014 SDN event 3
Inhoud 03
Marcel Meijer
04 04 05
Voorwoord
Inhoudsopgave Agenda De weg naar continuous delivery: het maken van onderhoudbare UI-testen met Microsoft CodedUI
Marcel de Vries
09
Sander Hoogendoorn
11
Failing Fast
Reflections on Mobile Development
Cary Jensen
13
Product- en marktontwikkeling vanuit het perspectief van business development
Pietwillem Overvoorde
16
Alex Thissen
18
Seriële communicatie in .NET
Michiel van Otegem
19
Alles wordt anders
Visual Studio 2013 De vernieuwingen in vogelvlucht
Andre Obelink
23
Cross Device Test op basis van Visual Studio 2013/ Team Foundation Server /Service 2013 op basis van Perfecto Mobile Platform (Add-In)
Teched (Barcelona)
Hassan Fadili
• 14 november 2014
Marcel Meijer
• 27-31 oktober 2014
SDN magazine 123 • medio november/december 2014 SDC/SDE+
27 30
XBox One Review
Dennis Vroegop
36
Kinect for Windows: meer dan speelgoed!
Sander van de Velde
41
Betegel je startscherm met secondary tiles
Bob Swart
REST Debugging met Delphi XE5
TFS
Marcel de Vries
De weg naar continuous delivery: het maken van onderhoudbare UI-testen met Microsoft CodedUI Continuous delivery is momenteel een trends in de IT markt. Continuous delivery staat voor een aanpak waarbij we er niet alleen naar streven iedere sprint de software af te hebben, maar deze software ook daadwerkelijk in productie te hebben gebracht. Hierbij is het o.a. van groot belang dat we de tijd die nodig is voor het testen van onze applicaties, significant weten te reduceren. Hierbij wordt gebruik gemaakt van het geautomatiseerd testen van applicaties. Microsoft CodedUI is een technologie die dit mogelijk maakt. Met CodedUI kun je een eindgebruiker simuleren die gebruik maakt van de gebruikersinterface van een applicatie. Kenmerkend aan het testen van gebruikersinterfaces is dat ze in het algemeen een stuk langzamer zijn dan unit testen en dat ze veel gevoeliger zijn voor veranderingen in de applicatie. Toch is deze vorm van testen onontbeerlijk. Met de huidige trend richting web-applicaties ontkom je bijvoorbeeld niet aan de cross-browser-problematiek. Het valideren of je applicatie op verschillende browsers hetzelfde gedrag vertoont, is één van de mogelijkheden die CodedUI biedt. Omdat UI-testen extra gevoelig zijn voor veranderingen in de gebruikersinterface en omdat veranderingen regelmatig zullen plaatsvinden in de levenscyclus van een applicatie, is het extra belangrijk dat de testen die gemaakt worden, goed onderhoudbaar zijn. In dit artikel zal ik ingaan op de vraag hoe je met Microsoft CodedUI goed onderhoudbare testen kunt maken met behulp van het Page Object pattern. Dit pattern heeft in de praktijk bewezen deze doelstelling relatief eenvoudig realiseerbaar te maken. Introductie CodedUI Microsoft Visual Studio CodedUI is een technologie gebaseerd op MSTest, die het mogelijk maakt UI-testen uit te voeren. Met CodedUI is het mogelijk zowel Windows-Forms-applicaties, WPF applicaties, Xaml-gebaseerde Store-applicaties als web-applicaties te testen op dezelfde manier waarop je normaal gesproken Unit testen schrijft. CodedUI ondersteunt het concept van Record & Playback, waarbij je tools krijgt die het mogelijk maken schermacties in de applicatie op te nemen en later weer af te spelen. In dit artikel ga ik er niet op in hoe Record & Playback werkt, maar zal ik alleen ingaan op de vraag hoe je zogenaamde CodeFirst-testen opzet. Hierbij schrijf je zelf de testen direct tegen het CodedUI object model. Om een eerste indruk te geven hoe dit werkt, beginnen we met een simpel voorbeeld waarbij we een zoekactie uitvoeren op de Bing website. Om te beginnen moeten we de applicatie die we willen testen opstarten. Hiervoor heeft Microsoft de ApplicationUnderTest class geïntroduceerd. Voor web-testen is er een gespecialiseerde versie van deze class namelijk de BrowserWindow class. Deze encapsuleert de browser op je testmachine en biedt ook de mogelijkheid verschillende browsers (Chrome en Firefox) te starten als je de cross browser extenties voor CodedUI hebt geïnstalleerd vanuit de Visual Studio Gallery.
Zodra de applicatie is gestart, kun je aan de slag gaan met het zoeken van scherm elementen. Dit doe je door afhankelijk van het type applicatie een CodedUI control class te instantiëren die het zoeken en besturen van een schermcontrol abstraheert. We noemen dit type control in de rest van het artikel een search-control om goed het onderscheid te kunnen maken tussen controls die elementen zijn van een gebruikersinterface en de controls die CodedUI gebruikt voor de besturing van de applicaties die worden onderworpen aan een test. Voor WindowsForms applicaties maak je gebruik van search-controls met de prefix: Win. Voor Wpf applicaties van search-controls met: Wpf, voor Xaml-gebaseerde Store-applicaties zijn search-controls met prefix Xaml beschikbaar en last but not least voor web-applicaties zijn er search controls beschikbaar met de prefix Htlm. Al deze searchcontrols erven van een gemeenschapplijke baseclass, UITestControl. In onderstaande figuur is deze hiërarchie weergegeven.
Fig. 1: CodedUI Object model Nadat je een instantie maakt van het type search-control dat je wilt vinden, moet je criteria aangeven waarop een control gezocht kan worden. Hiervoor gebruik je, afhankelijk van de applicatie-technologie, een specifiek identificatie-mechanisme. Voor Web controls is dit bij voorkeur het HTML Element Id, voor Wpf controls de Automation identifier (dat is de xaml:name attribuut) en voor Windows applicaties de “Accessible Name”- property van het control.
magazine voor software development 5
TFS
In codevoorbeeld 1 start ik een web browser en zoek op de Bing.com website naar de search edit box waar ik vervolgens een zoek query invul. Daarna zoek ik de knop op de pagina om de zoek actie in Bing te starten. Na het klikken kunnen we valideren of we naar de resultatenpagina zijn genavigeerd. [TestMethod] public void CodedUITestMethodFirstTest() { BrowserWindow _bw = BrowserWindow.Launch(new Uri("http://www.bing.com")); EnterSearchValue(_bw, "Pluralsight CodedUI training"); ClickSearch(_bw); // valideer of we op een result page zijn geland…. } private static void EnterSearchValue(BrowserWindow _bw, string value) { //create CodedUI Html Control we want to interact with HtmlEdit searchBox = new HtmlEdit(_bw); searchBox.SearchProperties.Add(HtmlEdit.PropertyNames.Id, "sb_form_q"); // interaction with the control, will trigger the search searchBox.Text = value; } private static void ClickSearch(BrowserWindow _bw) { HtmlInputButton searchButton = new HtmlInputButton(_bw); searchButton.SearchProperties.Add(HtmlInputButton.PropertyNames.Id, "sb_form_go"); //Use the Mouse static methods to click on controls we search for Mouse.Click(searchButton); } Listing 1 Basis concept van search properties en interactie met controls Als je kijkt naar hoe CodedUI naar controls zoekt dan gaat dat als volgt: Iedere search-control heeft een constructor. In de constructor kun je een ander search-control meegeven als de scope waarbinnen de engine moet zoeken naar een ander control. Dus als je wil zoeken in een browserwindow, dan geef je de instantie van de BrowserWindow-class mee als zoekscope. Door de scope te beperken zorg je ervoor dat er sneller wordt gezocht in het HTML-document. De engine gaat pas zoeken op het moment dat er interactie met het search-control is. Dit kan bijvoorbeeld een Mouse.Click() zijn, maar kan ook bijvoorbeeld het zetten van een property zijn op een searchcontrol. Denk hierbij bijvoorbeeld aan het zetten van de text-property op een HtmlEdit search-control. Bij het zoeken wordt er gezocht naar alle search-properties die in de SearchProperties collectie zijn gestopt van de search-control. Dus je kan meerdere zoekcriteria meegeven als een control bijvoorbeeld niet op ID kan worden gevonden. Alle zoekcriteria worden als een AND-search uitgevoerd. Als het zoeken resulteert in één control, wordt deze direct gebruikt. Indien er meer controls worden gevonden, worden FilterProperties gebruikt om ervoor te zorgen dat we maar één control overblijft. Filter properties zijn vergelijkbaar met search properties alleen worden deze alleen gebruikt indien filtering nodig is
6
MAGAZINE
voor het zoek proces. Blijven er nog steeds meerdere controls over na het toepassen van de filter-properties, dan wordt de eerste in de lijst die gevonden is, teruggegeven. Indien de control niet wordt gevonden, zal de engine het opnieuw proberen (Er kan immers iets zijn veranderd in de UI in de tussentijd) en dit blijven doen totdat de default time-out van 2 minuten is verstreken. Kenmerken van onderhoudbare testen Nu we weten hoe CodedUI in de basis werkt, kunnen we gaan kijken naar de onderhoudbaarheid van de testen. Hiervoor passen we standaard een aantal principes toe. Principe één is: SOLID. SOLID is een algemeen geaccepteerde manier om code te schrijven die beter onderhoudbaar is. Het gaat te ver om dat hier in detail uit te leggen. Daarom pak ik het meest gebruikte concept hieruit, namelijk: het Single Responsibility principe. Dit betekent dat een class maar één verantwoordelijkheid heeft. Dit probeer je niet alleen voor classes te doen, maar ook voor methodes van die class. Verder gebruik je het DRY principe, dat staat voor Dont Repeat Yourself. Dit is om “Copy & Paste”-coding te voorkomen, hetgeen helaas opvallend veel vaker wordt toegepast voor het schrijven van testen. Het laatste Principe dat we toepassen is DAMP hetgeen staat voor Descriptive And Meaningful Phrases. Dit laatste passen we met name toe voor het schrijven van het uiteindelijke testscenario. Hierbij is het doel dat je de test scenario’s goed leesbaar opschrijft zodat ze min of meer leesbaar zijn als een zin. Dit is mogelijk door met behulp van het page object pattern een abstractie te schrijven voor je applicatie-onder-test die resulteert in een fluent API. Het Page object pattern Het page object pattern betreft een abstractie waarbij je de keuzes maakt om schermonderdelen, of in het geval van webapplicaties, webpagina’s laat aansturen door een specifieke class. Deze class is dan het zogenaamde page object. Vanuit het SOLID principe maken we dus één class verantwoordelijk voor één pagina en deze zal alle interactie met die achterliggende web pagina abstraheren. Voor alle acties die je op een pagina of schermonderdeel kunt uitvoeren, maken we publieke methodes die deze acties dan beschikbaar stellen. Verder zorg je ervoor dat ieder pageobject methodes heeft die condities evalueren die je wilt controleren in je testen. Deze methodes retourneren dus altijd een boolean-waarde. Door deze methodes op het page-object te plaatsen, zorg je ervoor dat het page-object alle kennis heeft van de pagina die hij abstraheert en zorg je ervoor dat de scenario’s die je maakt als test, geen kennis hebben van de pagina’s. Om een goed beeld te geven hoe dit werkt in code, heb ik een voorbeeld uitgewerkt dat toepasbaar is op de “TailSpin Toys”-website. Deze website is veel gebruikt in demonstraties van Microsoft en onderdeel van te downloaden test-virtual-machines. Als voorbeeld heb ik de Home Page, de Category Page, de Details Page en de Shopping Cart Page uitgewerkt. De flow van de pagina’s is in onderstaande figuur weergegeven.
Fig. 2: Home page
TFS
public partial class HomePage { private BrowserWindow _browserWindow; public HomePage(BrowserWindow browserWindow) { _browserWindow = browserWindow; }
Fig. 3: Category page
public static HomePage StartApplication() { var bw = BrowserWindow.Launch("http://www.tailspintoys.com/"); // zorg er voor dat de browser altijd maximized is bw.Maximized = true; return new HomePage(bw); } public CategoryPage SelectCategory(string categoryName) { HtmlControl link = new HtmlControl(_browserWindow); link.SearchProperties.Add(HtmlControl.PropertyNames.InnerText, categoryName); HtmlHyperlink innerLink = new HtmlHyperlink(link); Mouse.Click(innerLink); return new CategoryPage(_browserWindow); } }
Fig. 4: Details page
Fig. 5: Shopping Cart page Het Home Page object kent een aantal acties, namelijk: het terug gaan naar de home page, het kiezen van een categorie en het navigeren naar de shopping cart page. Dit wordt vertaald in methodes als NavigateToShoppingCart(), NavigateToHome(), SelectCategory(string category). Om met behulp van de page-objects een fluent API te maken, zorg je ervoor dat iedere methode die je maakt, altijd een nieuw page-object terug geeft. Dus in dit geval zou de Select Category een nieuw CategoryPage object moeten retourneren. In Code Voorbeeld 2 is te zien hoe je de HomePage class kunt uitwerken. Zoals je kunt zien heeft het HomePage object nog een extra methode om de testen te starten: hiervoor is de static methode StartApplication() gemaakt, die dan zelf het HomePage Object teruggeeft. Verder zie je dat het WebBrowser window wordt vastgehouden en wordt gebruikt bij het zoeken naar controls. Dit doen we om de scope van het zoeken te beperken tot de web pagina in de browser.
Listing 2 Indien we dat niet doen, zal het zoeken altijd starten op de desktop van windows en moet je een combinatie van CodedUI WindowsSearch-controls en Html-search-controls gebruiken om bij een element op een webpagina te komen. Zodra we de SelectCategory Methode aanroepen krijgen we een CategoryPage-object terug. Op de CategoryPage kan je een vliegtuig selecteren. Hiervoor maken we een methode SelectAirplane(string planeName) die een AirplaneDetail page object terug geeft. AirplaneDetail heeft op zijn beurt de optie om het geselecteerde vliegtuig aan de cart toe te voegen, dus daar maken we dan een methode AddToCart() voor die een ShoppingCartPageobject teruggeeft. De ShoppingCartPage biedt de mogelijkheden items uit de cart te verwijderen en naar het afrekenen te gaan. Hiervoor maken we dan methodes als RemoveitemFromShoppingBasket(string nameItem) en Checkout(). De Remove() methode laten we opnieuw een ShoppingCart page object retourneren, aangezien er niet van de pagina wordt weggenavigeerd. In codevoorbeeld 3 zijn de resterende page objects uitgewerkt. public class CategoryPage { private BrowserWindow _browserWindow; public CategoryPage(BrowserWindow browserWindow) { _browserWindow = browserWindow; } public AirplaneDetailPage SelectAirplane(string airplaneName) { var hyperlink = new HtmlHyperlink(_browserWindow); hyperlink.SearchProperties[HtmlHyperlink.PropertyNames.InnerText] = airplaneName; Mouse.Click(hyperlink);
magazine voor software development 7
TFS return new AirplaneDetailPage(_browserWindow); } } public class AirplaneDetailPage { private BrowserWindow _browserWindow; public AirplaneDetailPage(BrowserWindow browserWindow) { _browserWindow = browserWindow; } public ShoppingCartPage AddItemToShoppingCart() { var link = new HtmlInputButton(_browserWindow); link.SearchProperties.Add(HtmlButton.PropertyNames.Type, "submit"); Mouse.Click(link); return new ShoppingCartPage(_browserWindow); } } public partial class ShoppingCartPage { private BrowserWindow _browserWindow; public ShoppingCartPage(BrowserWindow browserWindow) { _browserWindow = browserWindow; } public CheckOutPage CheckOut() { var link = new HtmlInputButton(_browserWindow); link.SearchProperties.Add(HtmlButton.PropertyNames.DisplayText,"Checkout"); link.SearchProperties.Add(HtmlButton.PropertyNames.Type,"button"); Mouse.Click(link); return new CheckOutPage(_browserWindow); } } public partial class CheckOutPage { private BrowserWindow _browserWindow; public CheckOutPage(BrowserWindow broserWindow) { _browserWindow = broserWindow; } public bool IsPageValid() { return FindStreet1Edit().TryFind(); } private HtmlEdit FindStreet1Edit() { HtmlEdit edit = new HtmlEdit(_browserWindow); edit.SearchProperties.Add(HtmlEdit.PropertyNames.Id, "Street1"); return edit; } } Listing 3 Voor het laatste page-object heb ik alleen de query methode geïmplementeerd die we vanuit onze test methode gebruiken om de controle uit te voeren of de pagina correct is. Door een methode te maken IsPageValid() en aan de implementatie van het page object over te laten wat een geldige pagina is, wordt geen kennis “gelekt” naar de testmethode en hebben aanpassingen in een pagina alleen gevolgen voor de page-objecten. Dus door page-objecten te gebruiken hebben we een zeer eenvoudige onderhoudsrelatie. Voor iedere pagina die is aangepast, moet je het bijbehorende page object controleren of dit nog steeds werkt.
8
MAGAZINE
Doordat we page-objecten hebben voorzien van methoden die zelf weer page-objecten teruggeven, hebben we de mogelijkheid gecreëerd de test scenario’s beschrijvend op te stellen. Stel je wil het volgende scenario testen: We browsen eerst naar een categorie, dan selecteren we een vliegtuig om een vliegtuigdetail te bekijken waarna we ervoor kiezen het vliegtuig aan te schaffen. Als laatste gaan we naar de kassa om af te rekenen. Dit scenario kunnen we nu volledig uitschrijven met behulp van een fluent API. In codevoorbeeld 4 is het beschreven test scenario uitgewerkt op basis van het gemaakte object model en de daaruit volgende fluent API. Dit is dus een test scenario wat we hebben geschreven conform het DAMP principe. [TestMethod] public void BuyModelAirplaneAndCheckOut() { Assert.IsTrue( HomePage.StartApplication() .SelectCategory("Model Airplanes") .SelectAirplane("Fourth Coffee Flyer") .AddItemToShoppingCart() .CheckOut() .IsPageValid(),"Expected to be on page for checkout"); } Listing 4 Conclusie Met CodedUI is het mogelijk om testautomatisering door te voeren op eindgebruikerstesten via de gebruikersinterface van applicaties. Deze testen zijn in het algemeen lastig te onderhouden, maar als we een aantal principes toepassen in combinatie met het Page Object Pattern, is het mogelijk geworden onze testen dusdanig te bouwen dat ze goed te onderhouden zijn. We maken onze page-objecten op basis van de principes SOLID en DRY en door gebruik te maken van de techniek waarbij iedere methode een nieuw page-object teruggeeft, is het ook mogelijk geworden zogenaamde DAMP testscenario’s te schrijven. Door je testen te automatiseren en dit op een goed onderhoudbare wijze te doen, is het doel continuous delivery weer een stapje dichterbij gekomen. •
Marcel de Vries Marcel spends most of his time helping customers build enterprise systems based on Microsoft Technology. He has been working with Microsoft technology since he graduated in Computer Science in 1996. He started mainly with C/C++ and MFC.When Microsoft launched its new .NET platform in he immediately used it to write the first commercial application to go life in the Netherlands based on ASP.NET. Marcel writes articles and whitepapers on .NET, Application Lifecycle Management and Mobile solutions for MSDN, The Architecture journal and local magazines like Microsoft .NET magazine. Marcel is a frequent speaker at conferences like Microsoft TechDays, Visual Studio Live!, Microsoft Tech Ed and local user group events. Marcel is Technology Manager at Info Support and in his role he works as consultant in the Architect role for a variety of Financial and Insurance companies. He also teaches courses on topics like Visual Studio ALM, .NET , Mobile and Web development at the Info Support Knowledge Center. Marcel is awarded the Microsoft ALM MVP award and is a Microsoft Regional Director.
GENERAL
Sander Hoogendoorn
Failing fast There is an intriguing question that pops up frequently in organizations developing software in projects: when is a project successful? For sure, one of the most (mis)used resources on the subject is the Standish Group. In their frequently renewed CHAOS Report they define a project successful if it delivers on time, on budget, and with all planned features. For a number of reasons this is, in my opinion, a rather vague definition. First of all, how do you measure if a project has finished on budget? You would need to compare the actual budget to an originally planned budget. This originally planned budget is of course based on some estimate. At project start. An estimate at project start isn’t called an estimate for nothing. It’s not a calculation. At best, it’s an educated guess of the size of the project and of the speed at which the project travels. Estimation bias As we know from experience, estimates at project start are often incorrect, or at least highly biased. For instance, what if the people who create the estimate will not do the actual work in the project? Is that fair? Also, we often think we know the technical complexity of the technology and application landscape. In reality these appear to be much more complex during execution of the project than we originally thought. Second, when is a project on time? Again this part of the definition depends on a correct estimate of how long it will take to realize the software. At project start. Even when a project has a fixed deadline, you could well debate the value of such an on-time delivery comparison. How do we know that the time available to the project presents us with a realistic schedule? Once again, it boils down to how much software do we need to produce, and how fast can we do this. All planned features But the biggest issue I have with the Standish Group definition is the all planned features part of it. The big assumption here is that we know
all the planned features up-front. Otherwise, there is nothing to compare the actual delivered features to. Much research has been done on changes to requirements during projects. Most research shows that, on average, requirements change between twenty and twenty-five percent during a project. Independent of whether a project is traditional or agile. Left aside the accuracy of this research, these are percentages to take into account. And we do. In agile projects we allow for requirements to change, basically because changes in requirements are based on new and improved insights and will contribute to enhance the usefulness of the software. In short, we consider changes to requirements to increase the value of the delivered software. So much for software development projects success rates. Back to reality. In 2003 the company I worked for engaged in an interesting project with our client. The project set out to unify a large number of small systems, written in now exotic environments such as Microsoft Access, traditional ASP, Microsoft Excel, SQL Windows and PowerBuilder, into one stable back-end system. This new back-end system was then going to support the front-end software that was used in each of their five-thousand shops. Preparation sprints As usual, we started our agile project with a preliminary preparation sprint, during which we worked on backlog items such investigating the goals of the project, and the business processes to support. Using these business processes, we modeled the requirements for the project in (smart) use cases. We outlined a baseline software
magazine voor software development 9
GENERAL
architecture and came up with a plan for the project. The scope and estimates for the project were based on the modeled smart use cases. Due to the high relevance of this project for the organization, all twentytwo departments had high expectations of the project and were considered to be stakeholders on the project. Due to the very mixed interests of the different departments, we decided to talk to the stakeholders directly, instead of appointing a single product owner. We figured that the organization would never be able to appoint a single representative anyway. During the preparation sprint, we modeled eighty-five smart use cases during a short series of workshops with all stakeholders present. The outcome of the workshops looked very promising and, adhering to the customer collaboration statement in the Agile Manifesto, the client’s project manager, their software architect and I jointly wrote the plan for the project. We included the smart use case model, created an estimate based on the model, listed the team and planned a series of sixteen two-week sprints to implement the smart use cases on the backlog. Of course we did not fix the scope, as we welcomed changes to the requirements and even the addition of new smart use cases to the backlog by the stakeholders. No tilt However, we did add an unusual clause to the project plan. We included a go/no-go decision for further continuation of the project, to be made at the end of each sprint, during the retrospective. We allowed the project sponsor to stop the project for two reasons: • When the backlog items for the next sprint no longer add enough value compared to the costs of developing them. • In the rare case the requirements would grow exceptional in size between sprints – we set this to twenty percent of the total scope. Not that we expected the latter to happen, but given the diversity of interest of the stakeholders, we just wanted to make sure that the project wouldn’t tilt over to a totally new direction or was abundantly more expensive than originally expected. And, as you might expect, it did tilt over. After having successfully implemented a dozen or so smart use cases during the first two sprints, somewhere during the third sprint the software architect and I sat together with the representative of the accounting department. Much to our surprise, our accountant came up with as so far unforeseen functionality. He required an extensive set of printable reports from the application. Based on this single one-hour conversation, we had to add fortysomething new smart use cases for this new functionality to the model and the backlog. A scope change of almost fifty percent.
says: “We already invested so much money in this project, we can’t stop now!” And actually, in that sense, looking at the long history the client had with failing software development projects, the project sponsor, after the project had stopped, considered it to be successful. What is there to learn from this story? I would say it’s always a good thing to have one or two preliminary preparation sprints, that allow you to reason about the project at hand. I also consider it a good thing to develop an overall model of the requirements of your project at this stage - knowing that the model is neither fixed nor complete, and without going into a big-upfront design. And last but not least, that if you fail, fail fast. •
Sander Hoogendoorn Sander Hoogendoorn houdt zich in zijn rol als Principal Technology Officer bij Capgemini zich vooral bezig met de innovatie van software development. Sander is erkend global thought leader op het vlak van agile development bij Capgemini. Daarbij is hij onder meer verantwoordelijk voor Capgemini’s agile ontwikkelplatform, dat het Accelerated Delivery Platform (ADP) wordt genoemd.
TIP:
Global Windows Azure Bootcamp In navolging van vorig jaar organiseren SDN en WAZUG NL dit jaar wederom de Nederlandse deelname aan Global Windows Azure Bootcamp. Deze keer pakken we het echter nog groter aan. Op zaterdag 29 maart a.s. kun je namelijk op maar liefst 5 locaties in Nederland een hele dag gratis Windows Azure training krijgen!
There we were at the next retrospective. I can tell you it sure was quiet. All eyes were on the project sponsor. She there and then weighed all the pros and cons of continuing or stopping the project and the necessity of the newly discovered functionality. In the end, after about thirty minutes of intense discussion, she made a brave decision. She cancelled the project and said: it’s better to fail early with low costs than spend a lot of money and fail later. “We can’t stop now!” The question you could try to answer here is this: was this project successful or was it a total failure? For sure it didn’t implement all planned features. So, to the Standish Group, this is a failed project. But, on the other hand, at least it failed really early. This to me is one of the big advantages of being in agile projects: it’s not that you will avoid all problems, they just reveal themselves much earlier. Just think of all the painful projects that should have been euthanized a long time ago, but continue to struggle onwards, just because management
10
MAGAZINE
Locaties: Rotterdam, Eindhoven, Amsterdam, Veenendaal, Groningen http://bit.ly/1nDNejR
DELPHI
Cary Jensen
Reflections on Mobile Development In recent years there has been a steady increase in mobile development. Some might even call it an explosion. Indeed, the meteoric increase in sales of mobile devices such as smartphones and tablets compared to the flat sales of personal computers (PCs) and laptops have captured headlines both inside and outside the software industry. This had lead to the speculation that desktop applications are heading for extinction. This point was driven home to me recently. I was giving an interview and I was asked the following question: "Now that you can do everything you need to do with a tablet, what do you think about the future of desktop applications?". I found the question shocking and responded that the I felt strongly that the underlying assumption was wrong. Specifically, you cannot do everything you need to do with a tablet. For that same matter, you cannot do everything you need to do with a smartphone, or a browser-based application, or a PC, for that matter. Each platform/technology has its strengths and its weakness and these must be taken into account when evaluating for which platform you should target your software. In this article I want to reflect on the rapidly evolving landscape of software deployment, with particular emphasis on the role of mobile computer in the years to come. Here I will share my opinions and observations, and I am sure that these will not be shared by everyone. And, given that I have been developing software professionally for almost 30 years, my personal biases will no doubt come to the surface. Nonetheless, I feel motivated to express these opinions, as I find some of the statements being made in the press and in conversation incorrect and short-sighted. The Limitations of Mobile Computing To put it simply, mobile computing has its limits. From all the talk about smartphone and tablet apps these days, this fact might not be immediately apparent. But it is true. Specifically, I would identify three areas where mobile computing is limited. These are connectivity, display, and input. Mobile Network Connectivity Compared to the typical desktop workstation, where the computer is often connected to the network using a hard wired connection, network connectivity from mobile clients is less reliable. Even those workstations that are connected using a wireless access point have much more reliable network connections, largely due to the fact that the workstation often stays in one place. Mobile devices, by definition, are on the move. A given tablet might initially have a high-quality wireless connection, but as you travel with the device you may exit the range of the wireless connection. Even those devices that can rely on a mobile phone connection experience intermittent loss of connectivity. For the developer of data collection systems, this means that the application must accommodate the occasional loss of its network connection. Either it frequently sends updates back to a remote service, or it must provide for local, persistent storage on the client.
Mobile Display Limitations The display limitations on a phone are obvious, but even a tablet imposes significant restrictions on how data is displayed. One of the common mistakes that developers new to mobile development make is trying to duplicate the data display capabilities of a workstation client on the mobile platform and it almost never works. There are two aspects to the display limitations. One of these involves how the user navigates a mobile display. Specifically, users typically use their finger to select and change controls. This means that the actual size of the finger tip introduces a lower limit on the visual size of the individual controls that make up the interface. The second limitation is associated with the physical dimensions of mobile displays. There is just only so much data that you can fit, even on a larger tablet such as an iPad. Yes, it is true that many tablet models support high-resolution screens and nearly all support zooming. Additional issues, such as the physical environment (outdoors in the sun) dictate some of the options for how large and how close interface elements can be. In other words, how much data can be displayed at a time. Desktop applications have far more options when it comes to displaying data. In applications designed to manage shop floor production, it is not uncommon to find large monitors, or even two or more monitors. This capability permits exceptionally large amounts of data to be presented simultaneously, which in some cases is essential. Mobile Input Limitations Input on a workstation client is performed primarily from a keyboard and a pointing device (mouse or touchpad) and both of these give a fine degree of control over cursor position, text selection, and intercomponent navigation. While some tablets sport physical keyboards, and some support a stylus for pointing, they are the exception rather than the rule. For most mobile applications, the one and only input device is the finger. Gestures involving one or more fingers permit the user to navigate, resize, and select, but as mentioned in the preceding section, the size of the finger means that these operations are relatively course in nature. Even text input is often performed by the finger, typically through a virtual keyboard. Virtual keyboards do permit text input, but that input tends to be tedious. Specifically, most tablet users type on the virtual keyboard with one or two fingers. In addition, most virtual keyboards require sequential key presses for upper-case characters (first press the shift key followed by the upper-case character). Numeric input,
magazine voor software development 11
DELPHI
and that which requires special symbols, is often found on yet another version of the keyboard, also often requiring at least two, but sometimes more, sequential key presses.
expectations, and an excitement for the new opportunities it affords, while avoiding the easy but probably doomed attempt to create a straight desktop to mobile port.
Virtual keyboard input is slow and error prone. As a result, mobile applications are generally poor platforms for extensive manual input of text from the user. By comparison, workstations excel at those tasks where manual input of large amounts of textual or numeric data is necessary.
What do slumping PC sales mean for the future? Well, just because PC sales have been poor compared to tablet and smartphone sales doesn't mean we've come to the end of the PC era. There are several reasons for this shift. One is that Microsoft stumbled badly (again) with its short-sighted and cynical attempt to create an operating system that serves both a desktop as well as a mobile display. I am pretty sure that there are a lot of people who are holding off on upgrading their PC as a direct result of Windows 8. But the second reason is even more compelling. There are a lot of people out there who simply don't need a PC, but use one because, at the time of purchase, there was not a suitable alternative.
The Advantages of the Mobile Platform Although the mobile platform implies some significant limitations, there are some major benefits as well. This is clearly obvious, given the popularity of properly designed mobile applications at home and in the workplace. Like the limitations of the mobile platform, these can also be classified as being related to connectivity (mobility), display, and input. The Mobility Advantages Obviously, the mobility part of the equation is a really big deal. The user can be working with or collect data away from a traditional workstation. The ability to include both a wireless (WiFi) option as well as use cell phone technology means that this mobility aspect can reach very far indeed, even to remote locations. For applications that need this flexibility, there are few alternative options. Sure, you may have to implement a more complex mechanism to handle the occasional loss of connection, but those are details. Mobile Display Advantages There is a similar contrast related to the display and input issues. While there are limits to the way you can display on the mobile platform, there are some extremely useful options that are particularly well suited for the interactive nature of mobile devices. For example, while it is really not practical to display the values of hundreds of text fields on a tablet screen (and even fewer on a phone), mobile devices tend to be graphical in nature, and it is possible to convey complex concepts through more graphically oriented displays. For example, through graphs, images, topologies, or whatever visual interface makes sense with the type of data. Yes, these things can also be done on a workstation. However, when highly visual displays are paired with touch-based input (as I will discuss in the next section), mobile devices can provide a highly effective platform for communicating information. Mobile Input Advantages As for input, you don't ever want to ask a user to enter 500 integers into a mobile device. On the other hand, mobile devices have services that can collect data for and by the user. For example, you can use the GPS (global positioning system) features of a phone to collect the location where the data was observed. Likewise, you can use the device's camera to capture an image or a video stream, a barcode reader on the device to scan an object, or an accelerometer to record movement and orientation. This kind of data is real and has value, but it is not something that a user would be able to easily input manually. Similarly, mobile devices universally support expressive, interactive input by way of gestures. As mentioned in the preceding section, interactive, gesture-based input, combined with sophisticated graphical displays, can produce outstanding results. Final Reflections What does this all mean? In short, each platform has capabilities that make it appropriate for some solutions and not others. With respect to mobile development, the trick is to see the devices for what they are, leverage their capabilities, and build your applications accordingly. If you are a desktop developer, this takes some discipline. You need to approach the mobile platform with realistic
12
MAGAZINE
To put it simply, for some, a tablet is enough. If all you really need to do is send and receive email, browse the World Wide Web, use social media such as Facebook and Twitter, a tablet can satisfy all your needs. In the past these users bought PCs, and then used only a fraction of the capabilities of those systems. Tablets have the additional attraction that they support focused applications that leverage the benefits of the mobile platform, such as eReader apps, which make these devices invaluable in ways that PCs cannot match. (Honestly, I am sure that there are very few people who would even consider reading the latest best-selling novel on their PC or laptop.) By the same argument, PCs are not going away. There are too many applications that require the power and capabilities of a dedicated workstation. For most of these applications, a tablet just cannot provide the support that users of these systems need. What I do believe, however, is that in business we will see both PCs and mobile devices combining forces to provide superior solutions. Workstations will continue to be used to control processes, analyze data and write reports and documentation. Mobile devices will supplement these systems by providing remote data collection, mobile data access and limited but focused system control. Again, going back to a statement I made at the beginning of this section, the trick is to leverage yours platform's strengths. I've been thinking about this a lot lately. I have been fortunate enough to work with Google Glass and it's very interesting. Google Glass has limits. However, it's strength make is a terrific platform for specific types of applications where even a tablet or smartphone would fall short. We will continue to see specialized platforms emerge (like Glass and the Samsung watch) that will test our creativity. Our task will be to recognize the opportunities that these technologies represent and to use these to provide enhanced solutions to the problems at hand. •
Cary Jensen Cary Jensen is the bestselling author of more than 20 books on software development, including Delphi in Depth: ClientDataSets, and winner of the 2002 and 2003 Delphi Informant Reader's Choice Award for Best Training. A frequent speaker at conferences, workshops, and seminars throughout much of the world, he is widely regarded for his self-effacing humor and practical approaches to complex issues. Cary's company Web site is at: http://www. JensenData Systems.com. Cary has a Ph.D. from Rice University in Human Factors Psychology, specializing in human-computer interaction.
GENERAL
Pietwillem Overvoorde
Product- en marktontwikkeling vanuit het perspectief van business development De techniek achter de software is continu in ontwikkeling. En nodigt uit om steeds weer met nieuwe updates te komen. Dat is logisch en heel begrijpelijk. Tevens zijn er altijd weer allerlei functionele wensen, eisen en mogelijkheden die de uitdaging oproepen om opgenomen te willen worden in de standaard oplossing. In dit artikel worden diverse aspecten (maar zeker niet bedoeld als een uitputtende opsomming) besproken die bij de ontwikkeling en het onderhoud van een standaard oplossing aan de orde zijn. De basis voor markt- en product development Voordat aan het ontwikkelen van een product kan worden gedacht moet worden vastgesteld of er in een bepaalde markt inderdaad een behoefte is aan een oplossing. Alle relevante aspecten worden vastgelegd in een business plan. Dat weer de basis vormt voor een sales/marketingplan. De vaststelling om een oplossing wel of niet te gaan ontwikkelen is op zich heel eenvoudig te maken mits alle bepalende factoren aanwezig zijn. Enkele van de factoren die hierbij een rol spelen zijn: • Marktomvang en competitie; • Verwachte haalbare prijsstelling, verwachte haalbare omzet en verwachte haalbare marge over een periode van tenminste 5 jaar; • Verwachte hoogte van de investeringen; • Bekende en verwachte algemene en markt specifieke zaken die invloed (kunnen) hebben op de opzet en inhoud van de oplossing.
De verwachtingen worden vanaf het begin gemanaged. Tenslotte is het essentieel dat het business plan en het sales-/marketing plan onvoorwaardelijk worden gesteund door het management van de organisatie. Ook een goede budgettaire borging is belangrijk zodat inkomsten en uitgaven binnen hetzelfde kader blijven voor de volledige termijn waarop de plannen betrekking hebben. De klant bepaalt(?)(!) Potentiële gebruikers zullen (terecht) steeds meer gaan vragen om een concrete onderbouwing van het commitment van een organisatie naar een markt. Hierbij zal er ook meer aandacht komen voor de financiële positie van de aanbiedende partij. Omdat er onvoldoende aandacht was voor de nodige reserveringen voor investeringen zijn helaas diverse heel goede oplossingen ter ziele gegaan omdat de zich snel ontwikkelende techniek niet kon worden gevolgd, dat geldt onder andere voor diverse sub-segmenten binnen de sierteelt branche. Een manier om dit te managen is het beperken van de kosten door in basis alleen de echt relevante ontwikkelingen te ondersteunen. Klanten die meer willen kan de betreffende functionaliteit op basis van maatwerk worden aangeboden. Gelijktijdig is het belangrijk de (potentiële) klant uit te leggen dat tenminste de initiële en continue investeringen terugverdiend moeten kunnen worden en dat de prijsstelling hierop is gebaseerd. Anders komen de continuïteit van de oplossing en de organisatie in gevaar. Hier is niemand bij gebaat. Als er geen sprake is van een lange termijn planning inclusief budgettaire onderbouwing ligt het risico op de loer dat de prijsstelling gebaseerd wordt op een te korte terugverdientijd. Het prijsniveau zou als gevolg hiervan volkomen buiten de scope en het budget van de doelgroep kunnen komen te liggen. Dit is bijvoorbeeld voorgekomen bij oplossingen die ten behoeve van de gezondheidszorg zijn ontwikkeld. Door op basis van een verkeerd prijsniveau een markt te willen betreden gaat veel tijd en vooral vertrouwen verloren.
Het is van belang om zo veel als mogelijk relevante marktpartijen te informeren over en mee te nemen in de ontwikkeling van de plannen en concrete ontwikkelingen. De feedback die hiermee wordt verkregen kan onder andere onverstandige beslissingen voorkomen. Zo wordt vanaf het eerste moment de nodige duidelijkheid gecreëerd.
Als de werkelijke behoefte binnen een branche groter is dan wat binnen het budget kan worden gefinancierd zijn er op hoofdlijnen twee keuzes: • Of het business plan is niet goed onderbouwd en terugtrekken blijkt de enige juiste optie; • Of de oplossing wordt onder een ander licentie model aangeboden. Bijvoorbeeld op basis van een meer jaren contract waarbij de
magazine voor software development 13
GENERAL
kosten periodiek worden afgerekend en dus verdeeld in de tijd. De uiteindelijke omzet en marge zullen in dit model hoger zijn. Maar er zijn ook bepaalde, o.a. financiële, risico’s aan deze contractvorm verbonden. Vooral de lange termijn binding met de gebruikers is een positief aspect aan deze keuze. Alles bij elkaar moet de bestaande en potentiële klanten het gevoel en de overtuiging geven dat er geen sprake is van een eendagsvlieg maar van een duidelijk motivatie om een oplossing voor en met een markt te ontwikkelen en blijven onderhouden. Dat dit gevoel terecht is moet keer op keer bevestigd worden door alle betrokken medewerkers. Factoren die de wens of noodzaak voor de ontwikkeling van updates bepalen Naast de continue drive om een oplossing te perfectioneren vormen technische en functionele argumenten de basis voor nieuwe ontwikkelingen. Technische ontwikkelingen kunnen o.a. worden ingegeven door: • Nieuwe versies van ondersteunende software, bijvoorbeeld databases; • Nieuwe versie van basis software, bijvoorbeeld een ERP oplossing; • Aanvullende technische wensen en eisen vanuit de markt. Functionele ontwikkelingen kunnen o.a. worden ingegeven door: • Algemene ontwikkelingen in de markt; • Door derden opgelegde aanpassingen; • Aanvullende functionele wensen en eisen vanuit de markt. Binnen de standaard oplossing wordt de grootste gemene deler ontwikkeld. Dat is geen punt van aandacht: • Mits binnen projecten zoveel als mogelijk de standaard wordt geïmplementeerd; • Naarmate een oplossing meer algemeen bruikbaar is, bijvoorbeeld BI oplossingen; • Een oplossing zich richt op de ondersteuning van een beperkt deel van de markt, een niche.
Naar mate in projecten in het algemeen meer sprake is van aanpassingen en/of maatwerk zal de standaard geleverde functionaliteit substantieel afwijken van hetgeen bij een klant in gebruik is. In de praktijk is gebleken dat het implementeren van een bedoelde standaard oplossing erg veel discipline vraagt van alle betrokken partijen. Als met de discipline de hand wordt gelicht dan zal de Total Cost of Ownership uit de hand lopen. Bijvoorbeeld een reguliere migratie naar de actuele versie is dan vaak niet meer mogelijk. En dan is ook de vraag relevant of de beoogde Return on Investment criteria van de klant blijvend zal kunnen worden gerealiseerd.
14
MAGAZINE
Ontwikkelingen en trends Inmiddels ontwikkelt zich de trend dat processen bij voorkeur worden aangepast aan de standaard beschikbare functionaliteiten, in plaats van het realiseren van allerhande maatwerk. Er blijft natuurlijk de mogelijkheid om functionaliteiten in de vorm van blokken/modules aan te bieden. Op basis hiervan kan een organisatie de voor haar meest relevante oplossing samenstellen. Dat tegen redelijke kosten. Een keerzijde van deze manier van aanbieden is dat de kosten voor onderhoud en ontwikkeling naar verwachting zullen toenemen. Dit onder andere omdat er sprake kan/zal zijn van allerlei kruisverbanden tussen modules. Maar op dit punt geldt dat er zeker meerdere wegen naar Rome leiden die dit ‘risico’ kunnen beperken. Juist nu beginnen we, na al die jaren dat automatisering vooral en terecht als kostenpost is gezien, de echte voordelen van een professionele ICT omgeving te ervaren. Ook wat betreft reductie van kosten en de verhoging van de efficiency en de effectiviteit van processen en medewerkers. Daarmee zal de behoefte aan complete en betrouwbare oplossingen nog meer toe gaan nemen. Met deze verandering in het denken door klanten wijzigen ook de eisen die zij stellen aan hun leveranciers. Partnership en professionaliteit van de hele organisatie zijn onder andere criteria waarvoor bij de selectie van een leverancier en een oplossing nadrukkelijker aandacht zal zijn. De vraag is gerechtvaardigd, in het geval er veel maatwerk wordt ontwikkeld binnen een project of er echt nog sprake is van een standaard oplossing. Sluit de oplossing überhaupt nog wel voldoende aan bij de markt waarvoor ze oorspronkelijk bedoeld was. Is er nog echt een toekomst voor de oplossing? Het antwoord op deze laatste vraag is ook steeds meer relevant vanwege het meer en meer aanbieden en afnemen van oplossingen vanuit de zogenaamde cloud. Aanpassingen, optimalisaties en maatwerk, behoudens parameter instellingen, zijn hierbij in principe uitgesloten. Moet voor iedere vorm van installatie (on-premise, cloud of hybride) een separate architectuur en oplossing worden ontwikkeld? In deze afweging komen naast de architectuur en de technische aspecten ook het marktpotentieel en de gerelateerde kosten aan de orde. De kans is groot dat keuzes uit het verleden moeten worden heroverwogen. Een onderwerp dat hierbij ook zeker aandacht behoeft is de (potentiële) verandering in het verdienmodel. Vanzelfsprekend moet worden voldaan aan de licentievoorwaarden die voor een oplossing van toepassing zijn. Bij het opstellen van het business plan is ook dit een onderwerp dat voldoende aandacht moet krijgen. Er moet een verstandig evenwicht zijn tussen wat in redelijkheid kan worden gevraagd en wat in redelijkheid kan worden geleverd. De redelijkheid betreft onder andere de tijdschema’s die betrekking hebben op de beschikbaarheid van updates van de betreffende software. Factoren die de wens of noodzaak voor de implementatie van updates bepalen Iedere markt kent verschillende soorten klanten, op hoofdlijnen entrepreneurs, volgers en alles daar tussenin. De aard van de klant bepaalt mede wanneer er sprake zal zijn van het in gebruik nemen van nieuwe versies van de software. Maar er zijn meer factoren dan de aard van de ondernemer die bij deze keuze aan de orde zijn. De afwegingen/vragen bij de keuze voor het wel of niet in gebruik nemen van een nieuwe versie zijn onder andere: • Is er een technische en/of functionele noodzaak voor een overgang; • Wat is de planning voor volgende versies, inhoudelijk en in tijd; • Wat zijn de kosten voor de (her)implementatie; • Is er voldoende budget voorzien; • Is er voldoende menscapaciteit beschikbaar; • Wat zijn de voordelen en nadelen van de nieuwe versie ten opzichte van de nu gebruikte; • Wat zijn de risico’s en aandachtspunten wanneer er niet wordt
GENERAL
overgegaan naar een nieuwe versie; • Is een algehele heroverweging van de gebruikte oplossing(en) aan de orde. De vanzelfsprekendheid dat er periodiek wordt overgegaan naar een nieuwe versie lijkt af te nemen. Zeker wanneer er niet voldoende kwalitatieve aandacht is geweest voor de klant in de achterliggende periode, is de kans groot dat ook alternatieve oplossingen serieus worden overwogen. Afhankelijk van de antwoorden op onder andere de voorgaande vragen, maar bijvoorbeeld ook de stand van zaken bij de betreffende onderneming, zullen er conclusies worden getrokken. Die kunnen divers zijn, maar mogen nooit helemaal verrassen. Om dat laatste te bewerkstelligen zijn een goede business planning en het op een juiste wijze informeren van alle relaties hierover van groot belang is. Het is van essentieel belang dat accountmanagement en partnermanagement goed geregeld zijn. Alleen op deze manier blijven alle relevante partijen goed op elkaar aangesloten, blijft de oplossing marktconform en is de kans op de continuering van een succesvolle en een rendabele samenwerking gemaximaliseerd. Conclusie Om succesvol te worden en blijven met een oplossing is commitment in woord en daad essentieel. Dat commitment wordt vooral ervaren op basis van de kwaliteit van het product en de diensten. Zoals hiervoor is beschreven kent kwaliteit veel facetten, samengevat: functionele, technische, communicatieve en financiële. Al deze elementen op een goede manier beheersen vraagt een plan en constante afstemming en sturing. Zowel intern als extern gericht, met alle betrokken partijen, nieuwe en bekende. Wanneer dat allemaal goed is geregeld dan komt, blijft en groeit het succes (bijna) vanzelf, voor alle betrokken partijen.•
Pietwillem Overvoorde Pietwillem Overvoorde (1964) is na zijn studie Bedrijfseconomie en Commerciële Economie aan de HES Rotterdam in eerste instantie aan de slag gegaan in het financiële en logistieke werkveld. De kennis en ervaring die hierbij is opgedaan is keer op keer belangrijke bagage gebleken om zaken vanuit het perspectief van de klant en de gebruiker te kunnen beoordelen. In de afgelopen ruim 20 jaar is Pietwillem betrokken geweest bij talloze ERP, CRM, BI en SharePoint projecten in Nederland, Europa en Azië. In de rol van consultant, ontwikkelaar, sales-/accountmanager en projectleider. In de rol van business developer is Pietwillem de afgelopen 15 jaar (mede-) verantwoordelijk geweest voor de ontwikkeling en de (in)directe verkoop van branche specifieke oplossingen voor de service industrie, het vastgoedbeheer, de houthandel/verwerking en de sierteeltsector. Vanzelfsprekend kent iedere sector zijn eigen wensen en eisen waaraan een branche oplossing technisch en functioneel moet voldoen. Dat geldt ook voor de meest effectieve communicatie en marketing. De wijze waarop deze met de meeste kans op succes worden voorbereid en gerealiseerd is echter nagenoeg identiek. In dit artikel komen de meest belangrijke zaken aan de orde.
SDN > Update Windows Azure Costs Als je een Windows Azure subscription afsluit, dan zat daar standaard een Spending limiet op. Als je deze dan uitzet, dan had je geen mogelijkheid om hem later weer aan te zetten. Dat was heel vervelend, aangezien beginnende Windows Azure gebruikers graag de kosten in de hand willen houden. Zoals bekend is denk ik, als je je Windows Azure subscription koppelt aan je MSDN account, dan krijg je daardoor credits die je kunt opmaken aan alle soorten van services op het Windows Azure platform. Als je dat wel of niet gedaan hebt, dan wil je graag een limiet op de overige kosten zetten. Nu kun je wel de limiet weer aanzetten, maar het is alles of niets.
Liever zou je een alert willen hebben als je te betalen bedrag een bepaalde grens dreigt te overschrijden. Je wilt dan een mailtje, zodat je naar de portal kunt gaan en kunt controleren of je alles wel uitgezet hebt en kun dan opruimen. Deze optie is inmiddels ook in preview aanwezig. Je kunt nu alert instellen op totaal bedragen of beschikbare credits!
Dit maakt het toch weer een stuk relaxer om Windows Azure te koppelen aan je MSDN account. Op deze manier kun je de kosten nog beter in de hand houden. Happy Cloud developing!
magazine voor software development 15
.NET
Alex Thissen
Seriële communicatie in .NET De meeste PCs en laptops en zeker alle tablets hebben al lange tijd geen seriële COM en parallele LPT poorten meer. Wie weet ken je ze niet eens, aangezien standaard USB connectors deze vrijwel overal vervangen hebben. Toch komen de seriële en parallele poorten nog wel degelijk voor in huidige hardware of heb je ze nodig om oude hardware te kunnen koppelen aan moderne computers. De nieuwe hardware die seriële communicatie gebruiken vind je bijvoorbeeld in Arduino en .NET Gadgeteer electronica. Deze uit koppelbare componenten opgebouwde electronica is populair bij menigeen hobbyist die op eenvoudige manier zonder (al te veel) solderen leuke electronica prototypen wil bouwen.
UART en seriële communicatie Voor je aan de slag gaat is het goed om in ieder geval de beginselen van seriële communicatie te begrijpen. De basis hiervan ligt bij UART, kort voor Universal Asynchronous Receiver/Transmitter, wat de hardware aangeeft die in seriële poorten het werk doet. Minimaal komt daarin een drietal electronische signalen voor: Ground (GND), Receive (RX) en Transmit (TX) voor respektievelijk aarde, zenden en ontvangen. Je ziet deze bijvoorbeeld bij pin 5, 2 en 3 in de afbeelding boven. Via RX en TX kunnen twee apparaten aan weerszijden van de kabel met elkaar communiceren. Dat doen ze door pulsen over de RX lijn te sturen. De RX van de ene kant is verbonden met de TX van de andere kant en omgekeerd. Door af te spreken hoe lang een puls duurt (de baudrate) kunnen de data in individuele bits uitgewisseld worden. Het is daarbij van belang dat er een protocol gehanteerd wordt, want het is een relatief foutgevoelige manier van data-transfer.
Ook tref je regelmatig een USB connector aan met één van de seriële chipsets, zoals bijvoorbeeld de FTDI FT232 chipset en de CP2302. Deze chips leveren via een standaard USB stekker alsnog een gevirtualiseerde seriële poort op je computer. Je kunt deze zien in je Device Manager als een USB seriële poort.
Oud als de seriële communicatie mag zijn hebben de moderne varianten nog dezelfde kenmerken als de allereerste RS232 COM poorten met 9 of 25 pinnen.
De meest gebruikte standaard is het versturen van karakters in een data-frame, dat begint met een start bit en eindigt met een (of meerdere) stop bits. Dat markeert het begin en einde van de data. Daarbinnen komt de data voor die meestal uit 8 bits voor een karakter bestaat. Een pariteitsbit is een controle bit dat aan kan geven of de data correct is. Het gaat niet zover als een checksum, maar in 50% van de foute gevallen helpt het wel om transmissiefouten te detecteren. In het tempo van de baudrate worden de bits op de RX lijn gezet door het ene apparaat (bijvoorbeeld de computer) en gelezen aan de TX kant van het andere apparaat (zoals een Arduino electronica component). Door dezelfde baudrate te kiezen weten de apparaten van elkaar hoeveel bits er in een aanhoudende hoge of lage lijn (overeenkomend met een 1 of 0 voor de bits). Overigens worden een hoge lijn ook wel Mark genoemd en een lage lijn Space).
16
MAGAZINE
.NET
Programmeren met seriële poorten Er kan een moment komen dat je met Arduino of .NET Gadgeteer aan de gang gaat, of ergens een speciale interface naar oude hardware vindt waarbij je seriële communicatie nodig hebt. Als .NET programmeur is het niet onwaarschijnlijk dat je de seriële poort wilt aansturen vanuit je C# of VB.NET programma. Het .NET Framework biedt sinds versie 2.0 ondersteuning voor seriële poorten in de System.IO.Ports namespace van de System.dll assembly. Je kunt daarmee in managed code op een hoog abstractie-niveau communiceren via je poorten, zowel voor ouderwetse COM poorten of moderne USB virtuele seriële poorten. De abstractie van je seriële poort in het .NET Framework heet SerialPort. Om deze te gebruiken moet je weten op welke poortnummer je UART/COM device aanwezig is. In de afbeelding eerder is te zien dat het voor dat device nummer 6 is. Verder moet je de baudrate en de vorm van het karakter frame kiezen of kennen. De constructor heeft achtereenvolgens de argumenten voor poortnaam, baudrate, soort parity bit, het aantal bits in de data en het aantal stopbits: SerialPort port = new SerialPort("COM6", 62500, Parity.Mark, 8, StopBits.One);
Daarna is het relatief eenvoudig om data te versturen en/of te ontvangen. De SerialPort heeft een onderliggende Stream waarmee je kunt werken. Als je al eens met een MemoryStream of NetworkStream hebt geprogrammeerd, dan zal het je bekend voorkomen. De SerialPort heeft verder nog een tweetal buffers voor lezen en schrijven om meerdere bytes data vast te houden en efficienter te kunnen versturen en ontvangen. Een typisch stuk code om data te ontvangen ziet er als volgt uit: port.ReceivedBytesThreshold = 256; port.ReadBufferSize = 256;
Net als bij normale Stream objecten is het belangrijk om de daadwerkelijk gelezen hoeveelheid data uit te lezen bij een aanroep van de Read methode. In de event argumenten (van het type SerialData ReceivedEventArgs) van de handler kun je nog lezen of je karakters of de EndOfFile (EOF) hebt ontvangen. Verder kun je nog van een keur aan andere Read methoden aanroepen, bijvoorbeeld om per byte of karakter te lezen, de hele stream inclusief buffer in een keer of zelfs String objecten uit de data als je weet dat er tekstuele data binnen komt. Omgekeerd kun je met een aanroep van de Write methode data wegschrijven als String of byte array. Deze slaan de data eerst op in de Write buffer en serialiseren dat vervolgens byte voor byte over de lijn. Voorbij aan de basis Behalve de RX en TX lijn zijn er nog een aantal andere pinnen of lijnen in de seriële poort die het mogelijk maken om complexere communicatie protocollen te hanteren. Het is bijvoorbeeld mogelijk om eerst af te stemmen dat de ene kant van de kabel op het punt staat om data te verzenden en dat de andere kant van de kabel klaar moet zijn om data te ontvangen. Dat kan met de lijnen Clear To Send (CTS) en Request To Send (RTS). Er zijn er nog meer zoals Data Terminal Ready (DTR), Data Set Ready (DSR) en Carrier Detect en Ring Indicator, waarbij de laatste twee hinten naar modem-achtige scenarios. De SerialPort heeft hiervoor een event handler genaamd PinChanged die afgaat wanneer dergelijke lijnen veranderen. Het is daarna aan jezelf om deze signalen te gebruiken in een eigen protocol om tot juiste communicatie te komen. De software die je tegenwoordig veelal langs ziet komen is meestal bedoeld voor websites, Windows 8 en Windows Phone 8 applicaties. Het programmeren van code die directer interacteert met electronica, zoals de seriële poorten kom je daarin niet zoveel tegen. Het .NET Framework heeft hiervoor ondersteuning en maakt het makkelijk om programma’s voor UART devices te schrijven. Dat is eens wat anders dan de ASP.NET code en HTML of XAML markup die je wellicht dagelijks maakt. Een aanrader voor je volgende hobby project.
port.DataReceived += OnDataReceived; port.Open();
Je geeft aan hoe groot de buffer is en na hoeveel bytes je wilt dat de ontvangen data aan jouw code wordt aangeboden. Op dat moment wordt het DataReceived event getriggerd en je gekoppelde delegate aangeroepen. In het bovenstaande fragment is OnDataReceived de event handler die afgaat als er 256 bytes aan data ontvangen zijn. Je leest die data dan vervolgens in een grotere buffer om de totale dataset te verzamelen. Het DataReceived event gaat namelijk meerdere malen af voor hoeveelheden data die groter zijn dan je buffer. int totalBytes = 0; int bytesRead = 0;
Voor meer informatie, zie ook: http://msdn.microsoft.com/en-us/library/ System.IO.Ports (v=vs.110) .aspx http://www.codeproject.com/Articles/678025/Serial-Comms-inCsharp-for-Beginners http://www.netmf.com/gadgeteer/ http://arduino.cc/ •
Alex Thissen
byte[] file = new byte[0x10000]; void OnDataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort port = (SerialPort)sender; byte[] buffer = new byte[256]; bytesRead = port.Read(buffer, 0, 256); Array.Copy(buffer, 0, file, totalBytes, bytesRead); totalBytes += bytesRead; Console.Clear(); Console.WriteLine("Read bytes: {0}", bytesRead); Console.WriteLine("Total bytes: {0}", totalBytes); }
Alex Thissen is werkzaam als principal architect bij Achmea/Interpolis en concentreert zich op integratiearchitectuur en security. Je zult hem regelmatig tegenkomen op conferenties en seminars waar hij vertelt over de ervaringen die hij opdeed tijdens zijn werkzaamheden. Hij vindt alles wat met .NET te maken heeft interessant, maar probeert zich te concentreren op web-applicaties in gedistribueerde omgevingen. Alex is een fanatiek gamer en vindt de combinatie van gaming en .NET daarom ook heel interessant.
magazine voor software development 17
GENERAL
Michiel van Otegem
Alles wordt anders Ik luister vaak radio 1 in de auto en af en toe komt er een reclame langs waarin een of andere guru voorspelt dat alles anders wordt en dat bedrijven mee moeten veranderen. De reclame is grappig bedoeld maar er zit wel een kern van waarheid in, althans voor ontwikkelaars. Software ontwikkeling vereist al jaren veel aanpassingsvermogen. De ontwikkeling van de technologie gaat ontzettend snel en het framework dat gisteren hip was is vandaag alweer verouderd. Je kunt je natuurlijk afvragen in hoeverre dat echte verandering is. Nieuwe talen en frameworks maken het (hopelijk) mogelijk om sneller te ontwikkelen, beter onderhoudbare software te maken, enzovoorts. Maar in de meeste gevallen blijft het paradigma waaronder ontwikkeld wordt hetzelfde.
Nieuwe talen en frameworks maken het (hopelijk) mogelijk om sneller te ontwikkelen Ook cloud computing heeft tot nog toe niet heel erg veel veranderd aan de manier waarop we ontwikkelen. Cloud heeft alleen de plek veranderd waar onze applicaties en services gehost worden. Hoewel… veel applicaties werden al gehost in een data center op een andere plek, dus hoeveel is er werkelijk veranderd? Is Platform-as-a-Service echt anders? Er zullen vast mensen zijn die vinden dat er weldegelijk veel veranderd is. Kijk bijvoorbeeld maar naar Platform-as-a-Service diensten zoals Cloud Services in Windows Azure en de AppEngine van Google. In een notendop zorgen deze PaaS diensten ervoor dat we applicaties en services kunnen bouwen die robuust en schaalbaar zijn, en die in sommige gevallen automatisch schalen. Er wordt ons als ontwikkelaars dus werk uit handen genomen, zolang we ons maar aan bepaalde voorwaarden houden. Is dat significant anders dan wat we deden? Niet echt, want eigenlijk ontwikkelen we (weer) op basis van een framework dat bepaalde zaken voor ons verzorgt. Het verandert weinig aan de manier waarop we applicaties inrichten op architectuurniveau. Framework blijven groeien De frameworks waar me mee werken worden steeds groter en bieden steeds meer functionaliteit. .NET 4.5 lijkt alleen in de kern nog op .NET 1.0, maar de class library is zo ontzettend veel groter geworden dat het bijna niet leuk meer is. In dat proces hebben we bij ASP.NET onder andere Web Pages en MVC erbij gekregen, is Remoting vergeten en samen met de ASMX webservices vervangen door WCF, heeft WCF extensies gekregen voor REST, die vervolgens eigenlijk weer zijn vervangen door de Web API en zo kan ik nog wel even door gaan. Wat deze dingen gemeen hebben is dat het allemaal basis bouwblokken zijn die we nodig hebben, waarbij het ene bouwblok wat handiger is in een bepaalde situatie dan in een andere. Helaas moet ik ook vaststellen dat er nog wel eens wat overlap is, of dat een library voor web niet te gebruiken is in client applicaties.
18
MAGAZINE
Meer platform… Wie de ontwikkeling van Windows Azure een beetje volgt heeft gezien dat er ondertussen al aardig wat diensten zijn waar je gebruik van kunt maken. Storage Queues, Service Bus, Mobile Services, Windows Azure Active Directory (WAAD) en zeer recent de Scheduler bieden functionaliteit die verder gaat dan wat een framework biedt. Deze diensten zijn allemaal te benaderen via een REST API en daardoor op een min-of-meer universele manier te gebruiken. Dat was vroeger wel anders. MSMQ, Active Directory en de Windows Task Scheduler bieden in feite dezelfde functionaliteit als Storage Queues, WAAD en Scheduler, maar hebben allemaal hun eigen manier om ermee te communiceren. MSMQ is daarnaast een notoir voorbeeld van een functionaliteit die ingewikkeld te configureren en gebruiken is. Omdat de infrastructurele configuratie al gedaan is voor de Windows Azure diensten hoef je alleen nog maar functioneel te configureren en dat scheelt gigantisch. De diensten zijn daardoor een stuk makkelijker te gebruiken dan de vergelijkbare onderdelen in Windows. …minder framework? Met al die diensten die toegevoegd worden aan Windows Azure, maar ook steeds meer diensten in andere cloud platformen, kun je je afvragen of een steeds groter framework nog wel nodig is. In plaats van dat een applicatie met code van alles moet verzorgen, al dan niet steunend op componenten uit het onderliggende operating system, kun je een applicatie ook opzetten als regisseur van diensten die door cloud platformen geleverd worden. Alleen de applicatie specifieke functionaliteit programmeer je expliciet. Dat is wél significant anders.
Ontwikkelaars die bekend zijn met Enterprise Application Integration zijn in de cloud in het voordeel Het geeft een nieuwe dimensie aan het concept van een Service Oriented Architecture. Of misschien wel anders gezegd: het laat Service Oriented Architecture tot volle wasdom komen. Daarin is het vooral van belang dat je weet hoe je diensten gebruikt, of dat synchroon of asynchroon is, en hoe je om moet gaan met foutsituaties. In editie 108 heb ik al eens geschreven over transacties en webservices, en toen geconcludeerd dat die slechts zelden een goed idee zijn. Je moet dus op een andere manier omgaan met fouten en dat verschilt per situatie. Ontwikkelaars die bekend zijn met Enterprise Application Integration zijn daarom in de cloud in het voordeel, omdat ze al jaren met dat soort vraagstukken te maken hebben. Mijn advies voor nu: zorg dat je goed weet wat je met alle diensten kan en hoe je deze in je applicatie kunt verwerken. Met name als gaat om hoe je communiceert, bijvoorbeeld direct of via een Storage Queue. •
.NET
Andre Obelink
Visual Studio 2013 De vernieuwingen in vogelvlucht Half november 2013 heeft Microsoft, relatief kort na de vorige release, Visual Studio 2013 uitgebracht. Een versie boordevol met verbeteringen en uitbreidingen. In dit artikel wil ik kort een aantal van deze vernieuwingen aan bod laten komen. Zo langzamerhand is het pakket zo uitgebreid geworden dat veel uitbreidingen de gemiddelde ontwikkelaar niet eens meer raken. Wanneer je bijvoorbeeld in het dagelijks leven met name Windows Desktop applicaties bouwt, zal je niet snel in aanraking komen met de vernieuwingen met betrekking tot Windows Azure Mobile Services, ASP.NET of SharePoint.
Talen Uitgaande van het feit dat velen onder ons C# en VB.NET zullen gebruiken, is er wat de programmeertalen betreft niet veel veranderd. Onze C++ vrienden kunnen wel een groot aantal uitbreidingen aantreffen. Dit geldt ook, hoewel in mindere mate, voor JavaScript gebruikers. Als F# ontwikkelaar mag je je echter wel weer verheugen op een aantal uitbreidingen in de taal en compiler. De ondersteuning van onder meer generics is sterk verbeterd. Ook zijn er verbeteringen te vinden die betrekking hebben op de algehele performance en uitvoeringssnelheid. .NET Framework 4.5.1 Met Visual Studio 2012, die uitkwam in augustus 2012, is ook het .NET Framework 4.5 gereleased. Zoals het huidige versienummer dus al doet vermoeden zijn er in het .NET Framework zelf ook geen heel grotere veranderingen te verwachten. Toch kan het nieuwe .NET Framework er voor zorgen dat je applicaties sneller starten, doordat het beter gebruik maakt van de hardware waarop het draait. Een erg belangrijke, en ook veel gevraagde uitbreiding, is de ondersteuning van ‘Edit-and-continue’ voor 64-bits software. Met de term ‘asyncaware debugging’ is het debuggen van asynchrone processen ook sterk verbeterd.
Dit laatste lag natuurlijk ook wel voor de hand nadat Microsoft de laatste jaren zoveel verbeteringen ten behoeve van het asynchroon programmeren zelf heeft geïmplementeerd. Bij deze verbeteringen moet je denken aan bijvoorbeeld beter inzicht in de (asynchrone) programmaflow. Waar komt de huidige code vandaan? Wat is de volgende code die uitgevoerd zal worden? Of inzicht in de echte return-waarde van functies zonder het gebruik van een (lokale) variabele, maar direct zichtbaar in bijvoorbeeld het Watch Window. In de code in afbeelding 1 is het normaal gesproken immers lastig te zien wat het resultaat is van de functie VermenigVuldigMetDrie() omdat deze genest is in de aanroep van VermenigVuldigMetTwee(). Als je geen fan bent van de diverse Watch windows, maar liever de waarde van variabelen uitvraagt in het Immediate Window, kun je deze functionaliteit ook gebruiken. Gebruik hiervoor, direct nadat je uit de functie bent gesprongen, de opdracht $ReturnValue. Het print de waarde van de zojuist aangeroepen functie in het Immediate Window. Erg handig tijdens het debuggen! Net als enkele andere uitbreidingen voor het debuggen die in de komende alinea’s worden besproken. Debugging Een aantal vernieuwingen ten behoeve van het debuggen zijn reeds de revue gepasseerd. Edit-and-continue voor X64, extra support voor het debuggen van asynchrone operaties of het zojuist besproken inspectie van returnwaarden van .NET Framework methodes. Een andere uitbreiding, waarvan ik overigens hoop dat je het nooit hoeft toe te passen, is de mogelijkheid om memory analyses te doen op Dump files. Hiermee kan men bijvoorbeeld data analyseren die in een productieomgeving tot een crash heeft geleid. Je kunt hiermee bijvoorbeeld lastig te detecteren geheugenlekken opsporen. Naast ‘IntelliTrace debugging’ is ‘Code Map Debugging’ waarschijnlijk wel het meest in het oog springend. Deze functionaliteit, die echter alleen beschikbaar is binnen Visual Studio Ultimate, helpt u om beter inzicht te krijgen in het codeverloop. Het geeft de opeenvolgende functie-aanroepen grafisch weer.
Fig. 1: Toepassing van ‘Function return values’
magazine voor software development 19
.NET
Fig. 2: Code map in praktijk Het beperkt zich echter niet tot een weergave alleen, maar men kan ook vanuit dit venster weer naar procedures navigeren. Je kunt bijvoorbeeld ook aantekeningen toevoegen. Om de huidige callstack te visualiseren kies je, wanneer je in breakmodus bent, voor Debug > Show Call Stack on Code Map of middels de toetscombinatie Ctrl+Shift+`. Tijdens het debuggen wordt de Code map dynamisch bijgewerkt. Unit Testing Ik ben een fervent gebruiker van ReSharper, een productiviteitstool van JetBrains. Een van mijn favoriete features van deze niet-Microsoft tool, is de support om eenvoudig een of meerdere Unit Test te starten of debuggen. Doordat ik gewend ben om standaard ReSharper voor dit soort acties te gebruiken, was mij de uitbreidingen hiervoor binnen Visual Studio 2013 geheel ontgaan. Het venster Test Explorer biedt nu een bijna soortgelijke functionaliteit. Blijkbaar ook al in een voorgaande versie, maar men heeft nu de mogelijkheden om Unit Test te categoriseren en te filteren uitgebreid. De support voor Unit Tests beperkt zich echter niet alleen tot bovenstaande, maar men kan ook inzicht krijgen in de zogenaamde code coverage: Welke code wordt allemaal geraakt, of beter gezegd afgedekt, door Unit Tests? En, wellicht minstens zo belangrijk, welke code nog helemaal niet! Visual Studio IDE Het eerste wat opvalt als men Visual Studio 2013 opstart, is dat er de mogelijkheid wordt geboden om in te loggen met je Microsoft account. Op basis van dit account vindt Visual Studio eventuele licenties en zal deze ook toepassen. Daarnaast helpt het inloggen je om Visual Studio 2013 beter en over meerdere werkplekken te personaliseren. Het synchroniseert namelijk instellingen zoals het gebruikte lettertype, het gekozen thema, taal- en eventueel aangepaste toetsenbordinstellingen. Als gebruiker van Visual Studio Online, voorheen ook wel TFS Service genoemd, merk je ook zeker het verschil van wel of niet inloggen. Er zal namelijk standaard worden verbonden met Visual Studio Online en deze omgeving heeft ook weet van Visual Studio Online omgevingen van eventuele andere klanten. Ik werk inmiddels al met een handvol klanten op deze manier samen. Requirements, bugs, maar ook bijvoorbeeld de broncode op één plek. Het werkt super!
20
MAGAZINE
Hoewel ik inmiddels wel aan het veel bekritiseerde lichtgrijze thema van Visual Studio 2012 gewend ben geraakt, is het nieuwe blauwe thema wel weer een verademing. Er is sowieso weer wat meer kleur in de IDE te ontdekken. Met name het kleurgebruik van de icoontjes in de Solution Explorer helpt om beter en sneller te kunnen navigeren binnen de bestanden. Een andere kleine subtiele uitbreiding is het zogenaamde Notification Center. Dit panel, dat eenvoudig bereikbaar is middels het vlaggetje rechts in de titelbalk van Visual Studio 2013, geeft toegang tot verschillende notificaties. Denk hierbij aan updates van gekoppelde NuGet packages, maar ook aan eventueel bijna verlopen van licenties. Het meest opvallende in de code-editor zelf is waarschijnlijk wel, zoals Microsoft het noemt, CodeLens. Samen met ook de nieuwe functionaliteit Peek Definition kunt u nu sneller tussen aan elkaar gerelateerde code navigeren. CodeLens nestelt zich als een regeltje boven de declaratie van de procedure. Het helpt je om sneller gerelateerde code te vinden, zonder de context van de huidige weergave in de editor te verlaten. Men kan bijvoorbeeld snel zien hoe vaak, en uit welke procedures de desbetreffende methode wordt aangeroepen. Dat is echter niet het enige wat weergeven kan worden. Als men de code heeft draaien onder een on-premise installatie van Team Foundation Server 2013 kan men ook zie wie en wanneer de code eerder is aangepast en welke workitems eraan gekoppeld zijn. Mocht de bewuste collega via Microsoft Lync online zijn, kan men direct vanuit de code editor een chat-sessie of videogesprek starten. Ook kan men zien of de code geraakt wordt door één of meerdere Unit Tests en of deze wel of niet succesvol uitgevoerd zijn. In afbeelding 3 kan men zien dat de functie DecryptText() vanuit twee plekken wordt aangeroepen.
Fig. 3: Het gebruik van CodeLens
.NET
Wanneer men op het woord ‘2 references’ klikt klapt een popupvenster open met daarin de twee bewuste aanroepen. Klikt men vervolgens op zo’n aanroep dan krijgt men een preview te zien met wat meer context rondom de feitelijk aanroep. Dubbelklikken leidt je tot het echte codevenster. In dezelfde afbeelding ziet men ook de tekst ‘1/1 passing’ staan. Dit verwijst naar de ene Unit Test die deze methode raakt en inmiddels succesvol uitgevoerd is.
Andere kleine uitbreidingen binnen het codevenster is een verbeterde Navigate To (Ctrl+,) en de zogenaamde Enhanced Scroll Bar. Je kunt aangeven dat je in de scrollbar eventuele fouten, waarschuwingen, wijzigingen en breakpoints wilt zien. Met gekleurde blokjes in de scrollbar krijg je snel inzicht in waar zich de error of bijvoorbeeld warnings zich bevinden.
Fig. 4: Peek Definition Met Peek Definition kan men code inzien én bewerken, zonder je huidige code te verlaten. Feitelijk is Peek Definition gelijk aan het reeds bestaande commando Go To Definition, maar nu wordt de code getoond in een popup-venster. Je kunt het gebruiken in combinatie met Visual Basic, C# en C++. Binnen Visual Basic toont het een link naar de Object Browser voor symbols die geen metadata van de definitie bevatten, bijvoorbeeld de standaard .NET Framework types die beschikbaar zijn. Gebruik is simpel: kies Peek Definition uit het contextmenu wanneer men er met de rechtermuisknop op klikt, of kies voor de toets combinatie: Alt+F12. Wanneer het popup-venster opent, schuift de code onder de regel die getoond wordt naar beneden, zodat de gehele context bewaard blijft. Indien je behoefte hebt om het popup-venster groter te zien, kun je het venster promoveren tot een document, waardoor het een normaal codevenster wordt. Je kunt eventueel de code aanpassen in het popup-venster. Het venster sluiten gaat het snelst door op Esc te toetsen. Het is verstandig om bij nieuwe features binnen Visual Studio, maar met name in het codevenster, de shortcuts te leren. Hierdoor kunnen je handen op het toetsenbord blijven, zonder dat telkens de muis gezocht en gebruikt moet worden. Ik heb ze voor Peek Definition alvast voor je op een rij gezet.
Standaard zie je ze allemaal, maar je kunt het aanpassen door met je rechtermuisknop op de scrollbar te klikken en te kiezen voor Scroll Bar Options. Een andere optie in dit instellingenscherm is de keuze voor ‘Map mode’ in plaats van ‘Bar mode’. In Map Mode zie je een sterk verkleind overzicht van het gehele codebestand, waardoor je sneller naar bepaalde delen van je code kunt springen. Ik moet eerlijk zeggen dat ik mijn classes altijd zo klein mogelijk probeer te houden, waardoor ik van deze laatste optie de meerwaarde niet zozeer zie. Mocht je af en toe tijd doorbrengen in de XAML-editor van Visual Studio, dan zal je merken dat vanaf deze laatste versie IntelliSense wordt ondersteunt voor databinding en resources. Ook smart commenting en Go To Definition is nu beschikbaar. ASP.NET, Windows Azure Mobile Services, SharePoint en Office In het dagelijks leven bouw ik voornamelijk Windows Desktop applicaties, waardoor ik in het algemeen weinig bezig ben met bijvoorbeeld ASP.NET of Windows Azure Mobile Services. Ik kan hierdoor moeilijker inschatten wat echt belangrijke vernieuwingen zijn voor deze twee grote onderdelen. Een belangrijke wijziging is echter wel wat Microsoft noemt: One ASP.NET.
In Visual Studio 2013 hebben ze stap gemaakt om op een universelere manier de verschillende ASP.NET technologieën door elkaar te gebruiken. Indien je initieel hebt gekozen voor bijvoorbeeld een MVC project, kan je achteraf ook nog gewoon Web Forms aan je project toevoegen. ASP .NET Scaffolding (codegeneratie) werkt nu overigens niet alleen voor MVC projecten, maar voor alle ASP.NET projecten, waaronder Web Forms. Een uitbreiding die waarschijnlijk wel het meest gedemonstreerd is, is Browser Link. Hiermee kun je meerdere browser aan Visual Studio koppelen en met één knop in de toolbar allemaal bijwerken. Het is niet alleen eenrichtingsverkeer, je kunt ook kleine aanpassingen doen in een van de
magazine voor software development 21
.NET
gekoppelde browsers. De onderliggende code in Visual Studio, alsmede de andere gekoppelde browsers, zullen ook bijgewerkt worden. Een heel coole toepassing van SignalR! Binnen alle onderdelen van ASP.NET zijn wel vernieuwingen te vinden. ASP.NET Identity, MVC- en Web Forms project templates die gebruik maken van Bootstrap, Web API, OData, OAuth 2.0 en SignalR 2.0. Hetzelfde geldt natuurlijk ook voor Windows Azure Mobile Services. Dit artikel doet absoluut geen recht aan alle vernieuwingen dit binnen dit platform hebben plaatsgevonden. Ik heb echter te weinig ervaring met deze nieuwe tak van sport, om hier echt iets zinnigs over te zeggen. Feit is dat de teams van Microsoft hard werken om het Windows Azure platform razendsnel vorm te geven. Visual Studio 2013 sluit hierop aan door bijvoorbeeld nu ook het debuggen van remote applicaties te ondersteunen of snel remote desktops sessies te kunnen opzetten naar virtuele machines in de Windows Azure cloud. Je kunt overigens vanaf heden ook MVC gebruiken om nieuwe Office en SharePoint 2013 apps te bouwen. Niet alleen het bouwen van apps is aangepakt, maar zeker ook de deployment. Met App Packaging and Publishing is het uitrollen van apps voor SharePoint en Office sterk verbeterd. Verbeteringen kan men vinden in de deployment richting de hostomgeving, maar ook richting de Office Store. Daarnaast is er nu ook het nieuwe Cloud Business App project template. Hiermee kun je snel line of business (LOB) applicaties bouwen, gehost in SharePoint of Office 365, die gebruik maken van Visual Studio LightSwitch. Windows Store apps Vanzelfsprekend zijn er ook vernieuwingen te vinden voor het ontwikkelen van Windows Store apps. De rij van Visual Studio templates is ook uitgebreid met de nieuwe Hub App project template. Hiermee word je snel op weg geholpen om apps te maken die de data in zogenaamde horizontal panning view toont. Ook voor Windows Store apps is de deployment beter geworden. Allereerst kun je je app valideren tegen verschillende remote devices, alvorens je het aanbiedt voor certificering en om opgenomen te worden in de Windows Store. Blend kent ook een groot aantal uitbreidingen: ondersteuning van CSS animaties, zoeken en instellen van CSS eigenschappen en -elementen, eenvoudiger toepassen van JavaScript Behaviors en embed afwijkende lettertypes. Bind nu tijdens het ontwikkelen met designtime data om het scherm op te maken met echte data. Application Lifecycle Management Niet alle vernieuwingen binnen de ALM mogelijkheden zijn direct te linken aan Visual Studio 2013 zelf. Een groot aantal uitbreidingen zijn namelijk te vinden in Visual Studio Team Foundation Server 2013 en de online variant. Wat betreft versiecontrole is er nu ook support voor Git (team projects). Er is veel aandacht besteedt aan het eenvoudiger beschikbaar maken van versiecontrole in de webbrowser; denk hierbij aan navigatie, code bekijken, change- en shelvesets, aantekeningen en historie. Binnen Visual Studio 2013 zelf valt op te merken dat de vensters Pending Changes en bijvoorbeeld Changeset Details nu te ‘unocken’ zijn en als losse vensters te openen zijn. Het schakelen tussen verschillende teamprojecten, maar ook het schakelen tussen verschillende TFS omgevingen is sterk vereenvoudigd. Een uitbreiding met betrekking tot het samenwerken van meerdere teams omvat nu ook de mogelijkheid om backlogitems over verschillende teams te delen. Teams kunnen nog beter samenwerken door gebruik te maken van de zogenaamde Team Rooms. In dit veredelde chatvenster kun je ook informatie zichtbaar maken over checkins, builds en afgesloten workitems. In een soort Facebook time line wordt alle informatie over het project per dag gevisualiseerd.
22
MAGAZINE
Conclusie Ook al heeft Microsoft de release cylce van Visual Studio verhoogd, de uitbreidingen en vernieuwingen lijken steeds talrijker te worden. Met elke nieuwe release word je je echter ook steeds meer bewust van de omvang van Visual Studio. En je eigen beperkingen om alle nieuwe .NET technologieën in de vingers te krijgen. Ik wil je zeker aanmoedigen om deze nieuwe versie te adopteren. Het is wederom een stap voorwaarts voor elk type softwareontwikkelaar. Met de beschikbaarheid van Visual Studio 2013 Update Release Candidate zijn de eerste issues, die een nieuwe versie doorgaans met zich meebrengt, inmiddels ook al geadresseerd. •
André Obelink André Obelink (www.obelink.com) heeft al ruim 10 jaar ervaring in het programmeren met Microsoft .NET. Hij heeft een voorliefde voor Visual Basic.NET. André heeft inmiddels ruim vijf boeken geschreven over VB.NET en C#. Daarnaast is hij ook een graag gezien spreker op conferenties. Voor zijn werkzaamheden in de Nederlandse- en internationale .NET community is hij al acht jaar op rij onderscheiden met een Microsoft MVP award. In het dagelijks leven werkt hij als freelance senior software engineer, trainer en consultant voor verschillende bedrijven.
TIP: Als je naar de Global Windows Azure Bootcamp komt, dan is het handig om een Windows Azure subscription te hebben. Op deze site kun je lezen hoe je dit doet. http://bit.ly/1dzwjhj
TIP: Als je een MSDN account hebt, dan kun je daar ook een Windows Azure subscription aan koppelen. http://bit.ly/1gOWKhC
MOBILE
Hassan Fadili
Cross Device Test op basis van Visual Studio 2013/Team Foundation Server /Service 2013 op basis van Perfecto Mobile Platform (Add-In) Testen van software applicaties zowel voor desktop-, web- als voor mobile platformen kan op verschillende manieren plaats vinden. In dit artikel zal de developer- (test) oftewel unit-test mogelijkheid besproken worden, gebuik makend van Visual Studio 2013, Team Foundation Server / Service 2013 en Perfecto Mobile Platform Add-in. Dit initiatief is gebaseerd op de inspanning die ik geleverd heb aan de hand van een uitgewerkte klant case voor Microsoft in het kader van Visual Studio ALM Rangers. Binnen dit initiatief, is een poster opgesteld waarin alle benodigde componenten in kaart zijn gebracht en gepositioneerd om deze case tot succes te maken en in te passen binnen de Visual Studio ALM Agile Workflow. Deze poster ziet er als volgt uit:
Voordat men aan de slag gaat met het gebruik van de Perfecto Mobile Add-in, dient eerst een account aangemaakt te worden op de website van Perfecto Mobile (https://demo.perfectomobile.com/) om vervolgens daarvan gebruik te maken tijdens het testen van Mobile applicaties op verschillende devices. Wanneer men zich heeft geregistreerd op deze website via de bovenstaande link, zal de toegang verleend worden met de juiste gegevens
Fig. 1: Testing Mobile Applicaties met Mobile Cloud for TFS en Visual Studio
magazine voor software development 23
MOBILE
(gebruikersnaam en wachtwoord) en kan vanaf dat moment inloggen als hieronder is geschetst.
Fig. 4: Device Selectie op Perfecto Mobile Platform Vanuit de aanwezige devices, kan men een keuze maken om tegenaan te testen. In dit geval is de keuze gemaakt voor iPhone-4S . Met de Open kip zal de gebruiker doorverwezen worden naar de detail specificaties van de gekozen device zoals hieronder is weergegeven:
Fig. 1: Perfecto Mobile Platform Login Wanneer men geautoriseerd is op deze omgeving, wordt het volgende scherm getoond:
Fig. 5: iPhone-4S selectie voor test doeleinden
Fig. 2: Perfecto Mobile Overzicht Door op Automation knop te klikken, wordt het Automation gedeelte geladen. Daarin kunnen test scripts opgesteld en/of gewijzigd worden. Om de desbetreffende device te kunnen kiezen, dient de gebruiker op Devices knop te klikken om vervolgens de selectie te mogen maken. Dit onderdeel ziet er als volgt uit:
Fig. 3: Perfecto Mobile Platform – Automation Deel
24
MAGAZINE
Nu we hebben gezien hoe de Perfecto Mobile omgeving eruit ziet, is het zaak om een test project te genereren op basis van de Perfecto Mobile Add-in voor Visual Studio (Mobile Cloud Project). Deze Add-in dient eerst gedownload en geïnstalleerd te worden op de machine waarop Visual Studio (2012 en/of 2013) is geïnstalleerd. Deze Add-In kan gedownload worden vanuit: https://www.perfectomobile.com/support/tfs . Eenmaal gedownload en geïnstalleerd, deze Add-In bevindt zich onder de Visual Studio Templates onder: File\New\Projects\Installed\Templates\Visual C#\Test\Mobile Cloud Project zoals hieronder is weergegeven:
Fig. 6: Mobile Cloud Project template locatie in Visual Studio (2012/2013)
MOBILE
Wanneer de gebruiker de benodigde informatie voor het genereren van een test project op basis van deze template heeft ingevuld en op Ok heeft geklikt, zal het test project gecreëerd worden met daarin een test file waar alle testgegevens ingevuld kunnen worden. Deze ziet er als volgt uit:
Afhankelijk van de voortgang en de uiteindelijk resultaat van deze test, zal de status (Failed of Passed) en een link (Output) naar gedetailleerd informatie van deze test getoond worden in de Test Explorer zoals hieronder is weergegeven.
Fig. 7: Mobile Cloud Project-Test Generatie in Visual Studio
Fig. 10: Test Resultaten in Test Explorer en Link naar testdetails vanuit Perfecto Mobile Platform De resultaten van deze test link zien er als volgt uit.
Fig. 8: Mobile Cloud Project (DUT) Informatie voor iPhone & Samsung devices Wanneer aan alle voorwaarden is voldaan met het invullen van de test gegevens, kan deze Solution/Project gebuild worden in Visual Studio (F5). Deze build actie levert een TestScript op o.b.v. de Test method in de test file in dit geval is de test script (ExecuteScript1).
Fig. 11: Test Resultaten - Deel1
In Test Explorer, wordt deze testscript zichtbaar en kan worden gerund zoals hier onder is weergegeven:
Fig. 12: Test Resultaten - Deel2
Fig. 9: Runnen van TestScript in Test Explorer binnen Visual Studio
magazine voor software development 25
MOBILE
Fig. 13: Test Resultaten - Deel 3
Fig.14: Test Resultaten - Deel 4 PS: In deel 2 van dit artikel, zal de integratie met Team Foundation Server / Service en het gebruik van Automated Build voor deze test platform besproken worden. Conclusie: Microsoft streeft er altijd naar om samen te werken met partners die een toegevoegd waarde kunnen leveren aan het Windows/Microsoft Platform. Zo is dit traject een prima voorbeeld van een goede en geslaagde samenwerking tussen Microsoft en Perfect Mobile om de ondersteuning van Cross-Mobile platform te waarborgen gebruik makend van tools van beide kampen. Zo zijn o.a. alle Microsoft Visual Studio Application Life Cycle Management faciliteiten hier ingezet te weten: - Visual Studio IDE (C# , Test Project faciliteiten, Test Explorer) - Team Foundation Server (Version Control, Build Management, InRelease voor Deployment later) Zo hebben we gezien in eerst instantie hoe Microsoft Visual Studio IDE en Perfecto Mobile Cloud Test Project Add-In samen gebruikt kunnen worden om tot geslaagde test scenario’s te komen, die vervolgens gebruikt kunnen worden om op verschillende devices (iPhone, Samsung, ...etc) op verschillende platformen (iOS, Android, ...etc) met dezelfde scripts te kunnen testen.
26
MAGAZINE
Links • Perfecto Mobile knowledge base http://help.perfectomobile.com • Mobile Cloud for TFS http://www.perfectomobile.com/Solutions/MobileCloud_TFS • The Mobile Cloud Company https://demo.perfectomobile.com • Visual Studio and Cloud Based Mobile Device Testing http://vsardevicetest.codeplex.com/ • Testing Mobile Apps using Perfecto Mobile v2 http://vsardevicetest.codeplex.com/releases/view/116043 •
Hassan Fadili Hassan Fadili is werkzaam als Freelance Lead Architect / Consultant en VS ALM Consultant (MVP) voor zijn eigen bedrijf FadiliCT Consultancy (http://www.fadilict-consultancy.nl). Hassan is zeer actief in de Community en mede bestuurslid van DotNed (.NET & VS ALM UG NL) en VS ALM Track Owner. Hassan houdt zijn blog op: http://hassanfad001.blogspot.com en te bereiken via:
[email protected],
[email protected], hassanfad11 @hotmail.com en/of via Twitter op: @HassanFad
GADGET
Marcel Meijer
Xbox One Review Wat was ik teleurgesteld met de aankondiging, dat de launch van de XBox One in Nederland werd uitgesteld. Behalve in België en Luxemburg werd hij ook in Duitsland en Engeland uitgebracht. Even leek het erop dat de XBox pas eind 2014 uitgeleverd ging worden in de overige landen. Zolang wilde ik toch niet wachten, ik was gewoon te nieuwsgierig naar het apparaat. Wat kon het allemaal, hoe werkte de nieuwe Kinect, verschillen ten opzichte van de XBox 360 en wat is de kwaliteit van de spellen. Ik ben niet eens zo hele grote gamer, maar ik mag toch graag wat uurtjes verbranden achter de XBox.
In Nederland had ik de XBox One in pre-order staan. Maar ik wilde eigenlijk niet langer wachten. In Duitsland worden ze wel gewoon via de Microsoft Store of Amazon verzonden naar Nederland. Engeland had in principe ook gekunt, maar dan zit je met een stekker die niet past. Via Amazon heb ik een XBox One bundel besteld met Call of Duty. Gelukkig hoefde ik niet lang te wachten voordat hij bezorgd werd, allemaal net voor de kerstdagen.
zodat je kunt inloggen met je gezicht. Dan valt gelijk op dat de kwaliteit van de Kinect camera’s vergroot is.
Dan is je nieuwe XBox One ingesteld. Maar dan kun je eigenlijk nog niet veel. Eigenlijk is het dan gelijk aan een PC, het Operating Systeem is geladen en actief. Nu moet je de apps installeren.
Na het aansluiten van de XBox op je TV en het doorlopen van een wizard stel je XBox in. Standaard zaken zoals locatie, taal, Internet, XBox account etc moeten worden ingevoerd. Taal en locatie lijken aan elkaar gekoppeld, in locatie Duitsland kan een engelse taal kiezen. Tijdens de wizard krijg je ook de mogelijkheid om Kinect in te stellen
magazine voor software development 27
GADGET
Voor elke toepassing moet je een app installeren. Een app voor de audio CD’s, app voor de DVD’s of Blu Ray’s, Skype, Netflix, SkyDrive. Alles wat je niet gaat gebruiken wordt dus ook niet geinstalleerd, het is aan jou.
doorzetten. En eigenlijk zit het dus gewrapt in je XBox OS. Je hebt dan wel drie apparaten aan staan: XBox, Decoder en Televisie. Voordeel is dat je dan ook kunt Skypen tijdens het TV kijken. Wij hebben Interactieve Televisie van KPN en dat werkte gewoon. Je kunt overigens de XBox zo instellen dat hij ook de TV uitschakelt als je de XBox uitschakelt.
Mijn bundle bevat een game. Deze game wordt niet op Blu Ray meegeleverd. Maar er zit een kaartje in de doos met een QRCode. Om de game te installeren ga je naar de Store app, geeft aan dat je een QRCode hebt (de 26 tekens codes kunnen ook nog steeds voorkomen hoor) en je houdt de QRCode voor de Kinect terwijl je op de bank zit. De XBox scant hem, snapt hem en geeft de mogelijkheid om de game te downloaden en te installeren. Zo simpel. Oke, de games zijn wel iets groter, dus het duurt ook iets langer. Maar je hoeft niet te wachten tot de download en installatie volledig is afgerond, maar een bepaald aantal procenten kun je de game al spelen. Handig!
Skype is te installeren op de XBox en is erg compleet. Natuurlijk moest ik dat even uitproberen. De camera van de Kinect is waanzinnig, hij volgt degene die spreekt en zoomt ook nog eens in. Als microfoon wordt de Kinect gebruikt.
Andere nifty feature van de XBox One is snappen. Je kunt ongeveer gelijk aan Windows 8, twee apps naast elkaar zetten. In onderstaand geval Skype en TV, dat is er leuk. Hier mis ik wel de mogelijkheid om zelf te bepalen hoeveel ruimte de ‘snap’ inneemt, nu is dat een standaard waarde.
Als je de games geïnstalleerd hebt, dan kun je ook pinnen op je Home menu. Dit lijkt erg op Windows 8.1. Na het installeren staan de programma’s allemaal in de Apps en Games sectie, door ze te selecteren kun je ze pinnen. Hier mis ik wel de mogelijkheid om (net als Windows 8.1) secties te maken en pinned apps te groeperen. Ik zit niet de gehele dag te XBoxen en er wordt in de woonkamer ook gewoon televisie gekeken. Op de One kun je de digitale decoder van je provider aansluiten, de XBox zal het signaal dan naar de televisie
28
MAGAZINE
GADGET
Zoals gezegd, XBox One is ook geweldig met Voice te besturen. Je roept: “XBOX” en hij zal reageren met in de rechterbovenhoek “Listening”. Daarna geef je een ander commando, bijvoorbeeld “WATCH TV” of “GOTO SKYPE” of “SNAP TV”. En je commando wordt uitgevoerd. Super handig. Ondanks dat de XBox in Duitsland gekocht is, is alles functioneel. Ik heb spellen gekocht in Duitsland en in Engeland. Deze kunnen zonder problemen gespeeld worden. Het enige dat niet werkt zijn Xbox Music en XBox Video, deze twee apps zijn regio gebonden en sluiten niet aan op de regio van mijn Live account. En support is ook gewoon geregeld, dat heb ik moeten uitproberen. Mijn XBox One had een defecte Blu Ray drive, wat betekende dat ik geen CD/DVD/Games kon afspelen. Maar via Support site (in het Nederlands) opgestuurd naar Tsjechië, gerepareerd en per kerende post terug gestuurd gekregen. Dus mocht je ook niet kunnen wachten… •
Marcel Meijer Al meer dan 20 jaar begeeft deze 44-jarige zich in de wereld van de ICT. Op dit moment houdt hij zich voornamelijk bezig met Azure, Cloud, C#, Software Ontwikkeling, Architectuur in het algemeen en Windows Phone 7. Ook is hij bezig met Biztalk en Sharepoint. Hij werkt als Senior Solution Architect bij Prodware. In zijn vrije tijd is hij .NET track owner, eindredacteur en bestuurslid van de SDN. Binnen de SDN is hij verantwoordelijk voor het regelen van sprekers voor de SDN Events (SDE), het regelen/redigeren van artikelen voor het SDN Magazine, mede verantwoordelijk voor de eindredactie van de hardcopy en digitale magazines en de inhoud van de SDN Conferences. Op 1 oktober 2010 werd hij MVP.
Als je voorop wilt lopen in je vakgebied, sluit je je aan bij de SDN community! Als lid van het Software Development Network, kortweg het SDN, ben je op de hoogte van de nieuwste ontwikkelingen. Je maakt deel uit van een netwerk van professionele architecten, designers en ontwikkelaars die elkaar met raad en daad terzijde staan. Je kunt lid worden van het SDN op basis van een bedrijfs- of een persoonlijk lidmaatschap. Het belangrijkste verschil is dat bij een bedrijfslidmaatschap twee of meer personen recht hebben op gratis toegang tot bijeenkomsten en de SDN website, bij een persoonlijk lidmaatschap is dat één persoon.
De kosten voor een bedrijfslidmaatschap voor twee personen bedragen € 299,- per jaar. Uitbreiding kost € 99,- per persoon per jaar. Een persoonlijk lidmaatschap kost € 199,- per jaar. Bedragen zijn exclusief 21% BTW. (Bedrijfs)naam
:
T.a.v. Adres PC/Woonplaats Email adres Telefoonnr. Personen
(indien bedrijfsabonnement minimaal 2)
Een lidmaatschap wordt aangegaan voor tenminste één jaar en wordt zonder schriftelijke annulering automatisch met een jaar verlengd op 31 december. Facturering vindt plaats per kalenderjaar of een deel hiervan. Opzeggingen uitsluitend schriftelijk en tenminste zes weken voor het einde van het jaar. Datum
Handtekening
Verzend dit formulier naar het secretariaat van SDN: Postbus 506 7100 AM Winterswijk of mail naar
[email protected]
magazine voor software development 29
KINECT
Dennis Vroegop
Kinect for Windows: meer dan speelgoed! Kinect for Windows, door velen K4W genoemd, is de nieuwste versie van een stukje hardware van Microsoft. Deze controller komt van oorsprong uit de Xbox wereld, maar er is al een aantal jaar een versie speciaal voor de desktop beschikbaar. Met de nieuwe versie is er een hoop verbeterd ten opzichte van V1, maar de grote vraag blijft: wat moet je er nu mee?
In mijn carrière van meer dan 20 jaar heb ik een hele hoop verschillende projecten gedaan. En laten we eerlijk zijn: niet alle klussen zijn even leuk. Sommige teams lopen lekkerder, sommige kantoorgebouwen zijn fijner dan andere en bij weer andere is de koffie overheerlijk. Allemaal factoren die er voor zorgen dat je met plezier naar het werk gaat. Toch is dat niet het belangrijkste: het werk zelf en het soort project bepalen voor mij meestal hoeveel lol ik in het werk heb. En het meeste plezier heb ik altijd in projecten die iets met fysieke apparaten doen. Er is iets magisch aan het zien bewegen van apparaten, die bijna puur door mijn wilskracht dingen doen. Lichtjes, bliepjes, motoren: alles wat ik tot leven kan brengen door mijn software heeft een enorme aantrekkingskracht op me. In het verleden heb ik veel gewerkt met dit soort ‘speeltjes’; Lego Mindstorms, Microsoft Surface (de tafel, niet de tablet), PixelSense, Leap Controller en veel meer gadgets hebben tot verdriet van mijn vrouw ons huis bevolkt. De volgende in deze serie apparaten is de Kinect For Windows 2. Maar K4W is meer dan speelgoed. Het is een stuk technologie die niet al te lang geleden ondenkbaar was. Zelfs science fiction films van tien jaar geleden hebben dit niet kunnen voorspellen, tenminste: niet dat deze technologie voor een hele redelijke prijs beschikbaar zou zijn in de huiskamer. Maar het is er. Je kunt het gewoon in de winkel kopen. En dan heb je thuis een nieuw apparaat. En nu? Lees vooral door! Een stukje geschiedenis In 2010 kondigde Microsoft een nieuwe controller voor de Xbox 360
30
MAGAZINE
aan. Toen nog bekend onder de naam “Project Natal” zou de nieuwe controller ongekende mogelijkheden bieden aan game ontwikkelaars. Met dit apparaat konden spelers puur door middel van hun bewegingen en hun stem communiceren met de Xbox game console. Dit nieuws sloeg in als een bom bij de gaming wereld. Er waren uiteraard andere technieken beschikbaar die in de buurt kwamen, maar die hadden altijd nog een extra stukje hardware nodig. Denk bijvoorbeeld aan de Wii controller: draadloos en gestuurd door je bewegingen, maar nog altijd iets in je handen. Ook voor de PlayStation was een dergelijke controller beschikbaar. Project Natal beloofde meer: door hun technologie zou het systeem met camera’s de gebruiker in drie dimensies kunnen zien en die informatie doorgeven aan de spellen. Het hart van het systeem werd gevormd door chips van de Israëlische chipbouwer PrimeSense, die een exclusieve licentie aan Microsoft verkocht had. Het systeem, dat later Kinect genoemd werd, had al snel een grote groep fans. Een aantal van deze fans, vooral de hardcore ontwikkelaars, hadden al snel door dat het systeem communiceerde met de Xbox door middel van een USB poort. Een aangezien de systemen waar ze dagelijks mee werkten ook USB poorten hadden was het een kwestie van tijd voor ze hun Kinect aan de PC probeerden te koppelen. Wat ze dan ook deden. In feite deden ze dat zo goed dat er al snel een aantal Open Source drivers en frameworks beschikbaar kwamen voor de Kinect op de desktop. Microsoft zag dit allemaal gebeuren en was bang dat door inferieure drivers de Kinect een slechte naam zou
KINECT
krijgen. Er zat niets anders op dan zelf met een SDK te komen, welke dan ook gelanceerd werd op 16 juni 2011. Deze SDK bevatte drivers en samples waarmee ontwikkelaars de standaard Kinect op hun PC konden aansluiten en daar iets mee konden doen. Hoewel het bouwen van commerciële applicaties net deze SDK nog niet toegestaan was waren er al snel meer dan 350 bedrijven die zeiden dat ze hier iets mee gingen doen. In mei 2012 werd versie 1.5 van de SDK gelanceerd, tegelijk met een andere versie van de controller. De officiële Kinect For Windows controller was een stuk duurder dan de Xbox versie, maar leverde meer een meer accurate data. Een van de verschillen was bijvoorbeeld de implementatie van de ‘near-mode’: een instelling waarmee gebruikers op een afstand van 40 centimeter gedetecteerd werden in plaats van de minimale afstand van 1 meter bij de Xbox. De reden hiervoor ligt voor de hand: PC gebruikers zitten meestal dichter bij hun scherm en de controller dan spelers op de Xbox. Eind 2013 lanceerde Microsoft in een aantal landen de Xbox One: de langverwachte opvolger van de Xbox 360 console. Deze console heeft een totaal nieuw ontwikkelde Kinect controller. Deze controller, niet meer gebaseerd op de PrimeSense technologie (dat daarna overigens overgenomen is door Apple), biedt veel meer mogelijkheden dan de voorgaande versies. De Windows versie van deze nieuwe controller wordt in de zomer van 2014 verwacht, samen met een gloednieuwe SDK. De hardware Even een kleine disclaimer vooraf: dit artikel is geschreven op basis van een pre-productie model van de K4W controller en de informatie daarover die ik van het K4W team heb gekregen voor het product gelanceerd is. Met andere woorden: er kunnen verschillen zijn met het apparaat dat jij van de zomer koopt. De verschillen zullen echter klein en niet-significant zijn, op een punt na: de audio mogelijkheden. De licentievoorwaarden voor de SDK vereisen dat ik de volgende regel toevoeg aan dit artikel: “This is based on preliminary software and/or hardware, subject to change.” Dus dan weet je het maar… Er is geen verschil in de interne werking tussen de Xbox en de Windows variant van de controller. De verschillen die er wel zijn vind je bij de connectoren: de Xbox heeft een eigen plug voor de USB data en de voeding van de controller, de K4W versie heeft uiteraard een normale USB3 poort en een losse kabel voor de voeding. De controller zelf is gelijk in beide varianten. Wat je krijgt is een kastje met daarin een aantal camera’s en een aantal microfoons. En inderdaad: USB3. Een standaard USB poort kan de enorme hoeveelheden data die de camera’s en microfoons genereren niet aan dus een highspeed poort is nodig om die data te verwerken. In de behuizing vind je een standaard webcam (RGB) en een depth sensor. Deze depth sensor op zijn beurt bestaat uit een infrarood camera en een infrarood laser: de laser bundel wordt weerkaatst door objecten voor de controller en die weerkaatsing geeft informatie over waar ieder punt zich in de 3D ruimte bevindt. Het mooie van dit systeem is dat onafhankelijk is van de hoeveelheid omgevingslicht: ook in helder daglicht zou het systeem werken (de realiteit is dat het toch wel iets uitmaakt: buiten in de volle zomerzon wordt het allemaal wat minder nauwkeurig). Zoals al eerder gezegd zitten er ook microfoons in de behuizing. Deze microphone array zorgt ervoor dat de controller geluiden op kan vangen maar ook kan bepalen waar de geluiden vandaan komen. Zo gauw bekend is waar de geluiden vandaan komen kunnen de omgevingsgeluiden er uit gefilterd worden waardoor je dus ook in een rumoerige omgeving commando’s kan sturen of een Skype gesprek kan houden. In de vorige versie van K4W zat ook een motor waardoor je de controller enigszins omhoog of omlaag kon bewegen. In de nieuwe
versie is deze niet meer aanwezig: de controller heeft een veel grotere zichthoek gekregen waardoor het richten van de camera’s niet meer nodig is. De nieuwe K4W controller heeft ook een standaard bevestigingspunt voor statieven: je kunt hem nu dus ook op een statief plaatsen. Ideaal voor mobiel gebruik dus. De software De meeste magie komt uit de software. Hoewel er een aantal dedicated chips in de controller zitten die de data een beetje voorbewerken, komt de meeste functionaliteit uit de SDK. De controller levert een enorme hoeveelheid ruwe data aan en de ontwikkelaar is verantwoordelijk voor het afhandelen ervan. In de Xbox variant kost het verwerken van deze data ongeveer 5-8% procent van de capaciteit van een van de cores van de processor. Er is wel een architectuur wijziging doorgevoerd: in de oude versie kon maar één applicatie tegelijkertijd de Kinect uitluisteren en aansturen. In de nieuwe versie draait er een service op de PC die de ruwe data binnenkrijgt waarna verschillende applicaties tegelijk de stream kunnen uitlezen. Je kunt nu dus meerdere applicaties tegelijk laten aansturen door de controller. Het is ook mogelijk om meerdere controllers tegelijk te gebruiken, hoewel dat in de pre-release versie nog niet beschikbaar is. Voor de rest krijg je, naast de drivers en de Kinect Service, een SDK met daarin libraries en samples waarmee je in verschillende ontwikkelomgevingen je kunt bouwen. Grofweg zijn er twee varianten van alle code: een COM variant en een managed variant. Als C++ je taal is, zul je de COM versie gebruiken. Een .net ontwikkelaar zal eerder met de managed libraries aan de gang gaan. Hello World Laten we eens beginnen met een heel simpel voorbeeld. We initialiseren de sensor en vertellen de gebruiker dat we hem of haar zien. In de TechPreview versie moet ik, voor ik iets kan doen met K4W, eerst een service handmatig starten. Deze onderschept alle data en geeft deze als streams door aan alle geïnteresseerde applicaties. In de uiteindelijke versie zal dat waarschijnlijk niet meer nodig zijn. Ik maak een Console Project aan (in de TechPreview moet ik hem aanmerken als 64 bit), voeg de referentie naar de Microsoft.Kinect assembly en maak een aantal members beschikbaar: private static KinectSensor _sensor; private static Body[] _bodies; private static BodyFrameReader _bodyFrameReader;
De _sensor is een referentie naar de Kinect sensor, de _bodies is een verzameling van alle personen die de sensor ziet en de _bodyFrameReader is een reader voor de stream aan data. In de Main van onze applicatie schrijven we de volgende code static void Main(string[] args) { // In de tech-preview versie wordt er // maar 1 sensor ondersteund. Anders hadden // we door de collectie KinectSensors moeten // lopen. _sensor = KinectSensor.Default; _sensor.Open(); // Haal het aantal personen op die de sensor ziet. _bodies = new Body[_sensor.BodyFrameSource.BodyCount]; // Haal de datareader op
magazine voor software development 31
KINECT
_bodyFrameReader = _sensor.BodyFrameSource.OpenReader(); // Stel de frame event op _bodyFrameReader.FrameArrived += OnFrameArrived; Console.WriteLine("Alles is geinitialiseerd."); Console.ReadLine(); // Opruimen _sensor.Close(); } De commentaar regels geven aan wat er allemaal gebeurt, dus daar ga ik verder niet op in. Wat interessanter is, is de code in de event handler OnFrameArrived: private static void OnFrameArrived(object sender, BodyFrameArrivedEventArgs eventArgs) { // Haal info over de frame op var frameReference = eventArgs.FrameReference; var frame = frameReference.AcquireFrame(); if (frame == null) return; using (frame) { frame.GetAndRefreshBodyData(_bodies); foreach (var body in _bodies) { // Volgen we deze? if (body.IsTracked) { Console.WriteLine("We zien: {0} op {1}", body.TrackingId, DateTime.Now.TimeOfDay); } } } }
Hierin wordt al het werk gedaan. We halen een FrameReference op uit de eventArgs, welke ons vervolgens een frame levert. Deze frame kan null zijn: als er meerder applicaties gebruik maken van de sensor kunnen zij de frame al bewerkt hebben voor wij iets kunnen doen en zal deze null zijn. Dit moet je dus altijd controleren. De volgende stap is het ophalen van de body data. In voorgaande versies werd gesproken over Skeletons maar dat is blijkbaar niet zo goed bevallen. Nu hebben we het over bodies en over de BodyCount. Blijkbaar is de gaming-achtergrond van de controller ook in de SDK zichtbaar… Het systeem kan zes verschillende personen onderscheiden. Echter: er worden er maar twee tegelijk gevolgd: van deze twee personen wordt gekeken naar de houding van alle delen van het lichaam. Vandaar dat we in de code door alle bodies heen lopen en per stuk kijken of deze IsTracked met true teruggeeft. Als dat zo is, is het een persoon waar we in geïnteresseerd zijn. Dan geven we deze weer op het scherm. Aangezien iedere body een unieke Id heeft kunnen we onderscheid maken tussen de verschillende personen. Streams Alles wat de controller teruggeeft is gebaseerd op streams. Zoals je voorgaand voorbeeld zag, krijg je een event als er data op de stream binnenkomt. Deze data kun je dan verwerken in je applicatie.
32
MAGAZINE
Maar over wat voor soort data praten we nu eigenlijk? Zoals al eerder gezegd heb je de beschikking over een aantal databronnen: 1. RGB Data, dit is een gewone webcam 2. Depth Data, een monochrome camera die je de afstand tot iedere pixel die hij ziet teruggeeft 3. Audio Data: geluid. Aangezien het audio deel in de techpreview nog niet helemaal beschikbaar is, zal ik daar niet verder op gaan. RGB Laten we eens een plaatje op het scherm zetten. Dit doe ik niet in de Console Applicatie, die is niet zo goed in het tonen van plaatjes, maar in een WPF applicatie. Voor deze applicatie gelden dezelfde voorwaarden als voor de Console: 64 bit, referentie naar de Kinect SDK (Copy Local moet False zijn…)en de Service moet draaien. Ook het initialiseren is vrijwel hetzelfde: private KinectSensor _sensor; private ColorFrameReader _colorFrameReader; // Deze hebben we nodig voor het converteren // van de stream data naar een image private readonly int _bytesPerPixel = (PixelFormats.Bgr32.BitsPerPixel + 7) / 8; // Dit is wat we zullen laten zien private WriteableBitmap _bitmap; // Tijdelijke opslag van de data uit de sensor private byte[] _pixels = null; Dit is de data die we nodig hebben. Het grote verschil met het vorige voorbeeld is dat we nu gebruik maken van een ColorFrameReader: deze leest de colorFrame uit (dus de normale camera beelden). Vervolgens: public MainWindow() { // Same old... _sensor = KinectSensor.Default; if (_sensor == null) return; _sensor.Open(); // Haal info over de stream op FrameDescription frameDescription = _sensor.ColorFrameSource.FrameDescription; // Haal de reader op _colorFrameReader = _sensor.ColorFrameSource.OpenReader(); // Alloceer de buffer _pixels = new byte[frameDescription.Width * frameDescription.Height * _bytesPerPixel]; // Maak de bitmap gereed _bitmap = new WriteableBitmap( frameDescription.Width, // Width frameDescription.Height, // Height 96.0, // dots per inch X 96.0, // dots per inch Y PixelFormats.Bgr32, // Kleurformaat (blauw, groen, rood, 32 bits) null);// Pallette, niet gebruiken hier InitializeComponent(); this.Loaded += MainWindow_Loaded; this.Closing += MainWindow_Closing; DataContext = this; }
KINECT
We hebben wat informatie nodig over het formaat waarin we de video terug krijgen. We slaan het aantal bytes per pixel op, en we gebruiken de resolutie die de controller teruggeeft om onze data structuren te initialiseren. Voor de rest is het weer meer van hetzelfde. Voor de volledigheid: de Loaded event handler ziet er als volgt uit: void MainWindow_Loaded(object sender, RoutedEventArgs e) { _colorFrameReader.FrameArrived += ColorFrameArrived; } En in de closing event handler ruimen we de boel op: void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (_colorFrameReader != null) { _colorFrameReader.Dispose(); _colorFrameReader = null; } if (_sensor != null) { _sensor.Close(); _sensor.Dispose(); _sensor = null; } } Dit is belangrijk: we moeten dit allemaal netjes opruimen. Als je dat niet doet blijven er misschien handles naar de sensor openstaan en dat kan de werking van andere applicaties in de weg zitten. En dan nu: het verwerken van de data. Ik heb in de XAML een Image gezet met daarin als Source een verwijzing naar een property die wijst naar de _bitmap member die we eerder aangemaakt hebben. In de eventhandler FrameArrived moeten we die _bitmap vullen met de data uit de sensor: void ColorFrameArrived(object sender, ColorFrameArrivedEventArgs eventArgs) { // Weer hetzelfde: reference ophalen en frame uitlezen ColorFrameReference colorFrameReference = eventArgs.FrameReference; ColorFrame frame = colorFrameReference.AcquireFrame(); if (frame == null) return; // Frame is IDisposable... using (frame) { // Sla de description op FrameDescription frameDescription = frame.FrameDescription; // Controle op image type die we krijgen if (frame.RawColorImageFormat == ColorImageFormat.Bgra) { // Kopieer de data frame.CopyRawFrameDataToArray(_pixels); }
else { // Converteer, dan pas kopieren frame.CopyConvertedFrameDataToArray(_pixels, ColorImageFormat.Bgra); } _bitmap.WritePixels( new Int32Rect(0,0,frameDescription.Width,frameDescription.Height), _pixels, frameDescription.Width * _bytesPerPixel, 0 ); } }
Het begin is vrijwel hetzelfde als weer eerst zagen. FrameReference en Frame ophalen, controleren of hij niet null is en dan verwerken. We kunnen de color data in verschillende formaten terugkrijgen: afhankelijk van het format moeten we deze converteren of we kunnen hem direct kopieren naar onze _pixel buffer. Als we de data binnen hebben kopiëren we deze naar de WriteableBitmap en die komt op het scherm te staan. Depth Data Tot nu toe hebben we nou nog niet echt iets leuks gedaan. Wat we gezien hebben konden we altijd al, ook met gewone webcams. Sterker nog: die code is meestal simpeler dan wat we tot nu toe gedaan hebben. Het wordt pas interessant als we dit gaan uitbreiden met diepte informatie. Voor het uitrekenen van de diepte heeft de controller de Depth Sensor. Zoals al eerder gezegd bestaat dat uit twee onderdelen. Als eerste hebben we een laser die infrarood licht uitstraalt. De objecten voor de sensor weerkaatsen die en die weerkaatsing wordt opgevangen door een speciale camera. Door wat slimme rekentrucjes uit te halen kan de sensor vervolgens van alle opgevangen pixels uitrekenen hoever deze in de 3D ruimte van de sensor zijn. Er is in versie 2 geen Near Mode meer: alles tussen de 40 centimeter en ruwweg 10 meter afstand wordt waargenomen en terug gegeven. De code is vrijwel hetzelfde als voorgaand voorbeeld. Alleen gebruiken we dit keer geen ColorFrameReader maar een DepthFrameReader (en dus een DepthFrameSource en geen ColorFrameSource). Daarnaast is de tijdelijke buffer een ushort[] met de naam _frameData (private member). Deze initialiseren we met: _frameData = new ushort[frameDescription.Width * frameDescription.Height]; Het grote verschil zit in de afhandeling van de FrameReceived: void DepthFrameArrived(object sender, DepthFrameArrivedEventArgs eventArgs) { // En Weer hetzelfde DepthFrameReference depthFrameReference = eventArgs.FrameReference; DepthFrame frame = depthFrameReference.AcquireFrame(); if (frame == null) return; // Frame is IDisposable... using (frame) {
magazine voor software development 33
KINECT
// Sla de description op FrameDescription frameDescription = frame.FrameDescription; // Extra controle op out-of-range data if (((frameDescription.Width * frameDescription.Height) != _frameData.Length) || (frameDescription.Width != _bitmap.PixelWidth) || (frameDescription.Height != _bitmap.PixelHeight)) return; // Maak een kopie van de data frame.CopyFrameDataToArray(_frameData); // Welke afstanden kunnen we aan? ushort minDepth = frame.DepthMinReliableDistance; ushort maxDepth = frame.DepthMaxReliableDistance; // _frameData bevat nu waardes voor iedere pixel // met daarin de afstand. Dit gaan we omzetten naar // grijstinten: hoe donkerder, hoe verder.... int colorPixelIndex = 0; for (int i = 0; i < _frameData.Length; ++i) { ushort depth = _frameData[i]; // alles wat te ver weg of te dichtbij is, wordt zwart byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0); // Blauw... _pixels[colorPixelIndex++] = intensity; // Groen _pixels[colorPixelIndex++] = intensity; // Rood _pixels[colorPixelIndex++] = intensity; // Aangezien onze data in Bgr32 is, moeten we de laatste byte overslaan... ++colorPixelIndex; } _bitmap.WritePixels( new Int32Rect(0, 0, frameDescription.Width, frameDescription.Height), _pixels, frameDescription.Width * _bytesPerPixel, 0 ); } }
We moeten wat trucjes uithalen: we krijgen een buffer binnen met daarin per pixel de diepte informatie in millimeters. Om dit zichtbaar te maken moeten we deze data converteren naar grijstinten. We controleren of de data wel binnen de toegestane grenzen is en zo ja: dan maken we de punten grijs. Het leuke is dat dit dus werkt met infrarood licht dat weerkaatst wordt en dus zou dit vrijwel altijd en overal moeten werken… De volgende afbeelding is in het volledige donker gemaakt met alleen het licht van mijn Surface tablet. Gewoon, omdat het kan.
34
MAGAZINE
Bodies Nu komen we bij het meest interessante deel van de Kinect for Windows controller. De SDK is dusdanig intelligent dat hij in staat is om mensen te herkennen. De controller kan twee mensen tegelijk in de gaten houden maar ziet er maximaal 6. Van de mensen die getrackt worden (zoals dat in mooi Nederlands heet) “ziet” de controller 25 verschillende gewrichten. Zo kan de controller je de positie vertellen van je linkerhand, je rechterduim, je linkerheup, je rechterschouder, enzovoorts. En de positie die teruggeven wordt is dus een coördinaat in de 3D ruimte voor de sensor: het systeem weet precies waar welk lichaamsdeel is en geeft dat ergens tussen de 15 en 60 keer per seconde terug. En dat voor twee personen. De code is vrijwel gelijk als wat we in het eerste voorbeeld gezien hebben: we krijgen een body object terug en die kunnen we verder uitvragen. Waar we in het eerste voorbeeld alleen de TrackingId weergaven, kunnen we ook de Z-positie van het hoofd weergeven: body.Joints[JointType.Head].Position.Z Een kind kan de was doen… Maar wacht, er is meer! Naast de positie van de joints is de software slim genoeg om een aantal dingen te combineren en daar conclusies uit te trekken. Wil je weten of een hand open is? if(body.HandRightState == HandState.Open)... Of wil je weten of de gebruiker een bril draagt (body.Appearance == Appearance. WearingGlasses), of misschien wil je weten of de gebruiker blij is? (body.Expression == Expression.Happy). Het systeem moet soms gokken wat de waarde is en om dat aan te geven krijg je een DetectionResult terug met de zekerheid (No, Yes, Maybe). Of wat dacht je van de hoek waaronder een persoon naar links of naar rechts leunt? Op die manier kun je je hele lichaam als joystick gebruiken! (Body.Lean met waardes tussen -1 en 1). Je ziet: Kinect kan heel veel aflezen uit de omgeving. En de code die je nu gekregen hebt is alles wat je nodig hebt als basis: meer rocket science is er niet. Het enige wat je nu nog moet doen is uit je normale denkpatroon stappen en een geweldige applicatie bedenken! En nu? Je hebt de code gezien. Je hebt de samples gezien. Je hebt gezien wat er allemaal mogelijk is. Spellen bouwen voor de PC is veel leuker geworden door dit soort technieken. Maar ik wil je vragen om verder te gaan dan spelletjes. Denk eens aan mensen die niet met computers om kunnen gaan. Denk aan minder valide mensen die niet met een toetsenbord, muis of touchschreen kunnen werken. Denk aan kinderen die niets begrijpen van “voorzichtig omgaan met apparatuur”. Denk aan ouderen van dagen die bij data moeten komen maar niet durven.
KINECT
Het systeem kan zo ontzettend veel betekenen voor deze groepen mensen. Het zou zonde zijn om ze niet te betrekken in onze moderne wereld: door dit soort technologie kun je je software veel beter bereikbaar maken voor een veel grotere doelgroep. Mensen die voorheen verstoken waren van informatie kunnen door slim toepassen van deze technieken opeens meedoen in de race naar informatie. En je weet: kennis is macht. Waarom zouden we die macht niet binnen handbereik van een veel grotere groep brengen? Dat lijkt me geen slecht resultaat voor wat men in eerste instantie zag als een ietwat geavanceerdere spelletjes controller. •
Dennis Vroegop Dennis Vroegop (1970) heeft zo’n 20 jaar ervaring als professioneel ontwikkelaar, afgezien van de 10 jaar daar voorafgaand als hobbyist. Het meest van die tijd heeft hij besteed aan het maken van applicaties op het Microsoft platform. Naast het pure programmeren heeft hij een passie voor het uitdenken van goed bruikbare systemen. Die liefde is het meest duidelijk terug te zien in zijn werk op diverse Multi-touch platformen en dan met name de toepassingen voor mensen die een beperking hebben zoals kinderen met autisme. Naast zijn dagelijkse werk is Dennis voorzitter van dotNed en regelmatig spreker op diverse conferenties. Voor zijn inzet is Dennis regelmatig door Microsoft onderscheiden. Dennis mag zichzelf sinds kort de eerste Hardware Interaction Design and Development MVP noemen.
NAV 2013 R2 on Windows Azure Vorig jaar tijdens de Directions EMEA 2013 werd aangekondigd NAV 2013 R2 on Windows Azure in Office 365. Dat klonk toen nog vrij abstract aangezien er naast de aankondiging verder weinig was. Eigenlijk bestond de mededeling uit twee opmerkingen: • NAV 2013 R2 was gecertificeerd om geïnstalleerd te worden op een virtual machine in Windows Azure • Als gebruiker van Office 365, dan kun je dit user account ook gebruiken om in te loggen op NAV Windows Azure Active Directory, ookwel Active Directory van Office 365, had al een groot toepassingsgebied, maar nu ook voor standaard Business applicaties zoals NAV. Dat laat zien, dat de toepassingsgebieden wel erg groot worden van WAAD/Office 365. Handige links: http://msdn.microsoft.com/en-US/dynamics/nav/dn474204 en http://blogs.msdn.com/b/nav/archive/2013/12/19/validating-single-sign-onwith-office-365-and-nav-2013-r2.aspx Van oorsprong ben ik geen NAV Consultant of developer. Maar mijn werkgever Prodware zaken doet met Dynamics producten en ik wilde daar toch iets meer van weten. Om een eigen speelomgeving te hebben, heb ik een VM op Windows Azure opgezet. Handig die gratis Window Azure compute uren die bij je MSDN subscription horen. Vervolgens moet je in NAV een gebruiker aanmaken die een Office 365 account heeft. Daarna moet je de NAV services configuratie aanpassen. Standaard staat deze ingesteld op Windows en dat moet Access Control Service worden. Om dit goed te laten verlopen, moet je een aantal certificaten maken en installeren. Ook de web.config van de WebClient moet aangepast, inclusief CustomSettings.config en op de IIS moet de authenticatie ingesteld worden op Forms authentication.
Vergeet niet om de poorten (8080, 80, 443, 7048, 7047, 7046 etc) toe te voegen in de endpoints van je Virtual machine. Anders blijft NAV en de WebClient van buitenaf niet beschikbaar. In de Windows Azure Active directory configuratie voegen we een Application toe. Daarna zijn er verschillende EndPoints en die moet je overnemen in de NAV Configuratie. Als alles goed is ingericht, dan kun je naar de URL http://<server>.cloudapp.net: 8080/DynamicsNAV71/WebClient gaan. Mijn servernaam is MyNAVVM. Dit kun je natuurlijk ook met je Domein DNS netjes naar je Domein laten verwijzen.
Vervolgens zal het bekende Office 365 inlog scherm getoond worden.
Na het invullen van de credentials. Tada! Super handig!
magazine voor software development 35
WINDOWS
Sander van de Velde
Betegel je startscherm met secondary tiles In Windows 8.1 maken tegels op het startscherm hét verschil met andere moderne operating systems. Tegels kunnen verschillende groottes krijgen en wisselende inhoud tonen. Met deze ‘live tiles’ heeft Microsoft de standaard knop voor de app verheven tot handig doorkijkvenster. De maker van de app geeft een voorproefje van de informatie die de app biedt. De gebruiker hoeft alleen maar op de tegel te kijken om op de hoogte te blijven. Vaak is het starten van de app overbodig want de status is direct af te lezen. Iedere Windows Store app heeft standaard één vaste tegel (tile) om de app mee op te starten en die is geplaatst op het startscherm. Maar een app kan meerdere tiles op het startscherm plaatsen: secondary tiles. Het is namelijk mogelijk om extra tegels voor navigatie naar detailpagina’s aan het startscherm vast te maken. Hiermee is het mogelijk om direct bij het starten van de app naar een contactpersoon, een notitie of een agendapunt te navigeren. Microsoft stelt het niet op prijs als tiles tot commando’s vervallen om de werking van de app te beïnvloeden. Denk hierbij aan het springen naar een volgend of vorig muzieknummer in een muziekapp. Apps die dit toch doen worden niet tot de Windows App Store toegelaten. Tiles worden alleen aan het startscherm toegevoegd (pinnen) of verwijderd (unpinnen) door gebruikers zelf, zij zijn tenslotte de baas over het startscherm. Er moet dus eerst met een dialoog om toestemming gevraagd worden, voorafgaande aan het pinnen of unpinnen. In dit artikel laat ik zien hoe secondary tiles ondersteund worden en hoe de gebruiker naar de achterliggende detailpagina navigeert als deze op de tegel klikt. En de tegel wordt aangekleed met een notificatie voor nog meer informatie op de tile. Figuur 1 geeft een voorbeeld van het dialoog voor de gebruiker bij het pinnen van een knop. De gebruiker kan overigens de voorgestelde titel en het formaat van de tegel aanpassen.
Template voor Windows Store apps Om het aanmaken van secondary tiles te demonstreren heb ik besloten om gebruik te maken van de template voor Windows Store apps van Rajen Kishna, Technical Evangelist bij Microsoft Nederland. Deze template maakt het mogelijk om met één solution zowel een Windows Store app als een Windows Phone app te bouwen. Dit laatste laten we hier achterwege maar de template heeft al een hoofdscherm en een detail pagina voor venues. Dit zijn locaties verbonden aan het populaire Foursquare. Zijn template maakt ook gebruik van het Model View Viewmodel (MVVM) UI design pattern. Helaas is het erg lastig gebleken om dit patroon toe te passen bij secondary tiles.
Fig. 1: Voorbeeld van pin-dialoog
Listing 1: Voeg twee buttons toe onderaan de VenuePage.xaml
36
MAGAZINE
Buttons en viewmodel We beginnen met het plaatsen van twee knoppen op de Commandbar onderaan de detailpagina genaamd VenuePage.xaml. Deze knoppen zal de gebruiker gebruiken voor het pinnen en unpinnen van de venue op deze pagina (listing 1). <Page.BottomAppBar>
<AppBarButton Name="pinButton" Visibility="{Binding IsPinned, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=i}" Icon="Pin" Label="Pin to start" Click="pin_Click" /> <AppBarButton Name="unpinButton" Visibility="{Binding IsPinned, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=u}" Icon="UnPin" Label="Unpin from start" Click="unpin_Click" />
WINDOWS
De twee knoppen mogen nooit tegelijkertijd zichtbaar zijn. Dit wordt opgelost door op het viewmodel een boolean op te nemen die vertelt of de huidige pagina al vertegenwoordigd wordt door een secondary tile (listing 2). Deze boolean wordt door de BooleanTovisibilityConverter naar xaml vertaald. De ConverterParameter maakt het verschil in zichtbaarheid tussen de twee knoppen.
secondaryTile.VisualElements.ForegroundText = ForegroundText.Light; secondaryTile.VisualElements.BackgroundColor = Color.FromArgb(255, 21, 66, 115); secondaryTile.VisualElements.Square150x150Logo = new Uri("ms-appx:///Assets/Pin150-150.png"); secondaryTile.VisualElements. ShowNameOnSquare150x150Logo = true; secondaryTile.VisualElements.Wide310x150Logo = new Uri("ms-appx:///Assets/Pin310-150.png"); secondaryTile.VisualElements. ShowNameOnWide310x150Logo = true;
private bool _isPinned; public bool IsPinned { get { return _isPinned; } set { SetProperty(ref _isPinned, value); } }
// Now make the pin request. var isPinned = await secondaryTile. RequestCreateForSelectionAsync( GetElementRect((FrameworkElement)pinButton), Placement.Above);
Listing 2: Het viewmodel achter de VenuePage krijgt een extra boolean De boolean op het viewmodel wordt aangepast met de OnNavigatedTo() methode, dus als de gebruiker naar de detailpagina navigeert (listing 3). Iedere Secondary tile moet een unieke identificatie bezitten (van maximaal 64 karakters). Wij gebruiken straks als identificatie de id van de Venue, controleer dus of er al een tile bestaat met die identificatie. Als deze niet wordt aangetroffen dan mogen we pinnen. protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); ViewModelLocator.Venue.IsPinned = SecondaryTile.Exists(ViewModelLocator.Venue.Venue.id); } Listing 3: Forceer het tonen van de juiste button via het viewmodel Hiermee zijn we klaar met de zichtbaarheid van de knoppen op de Commandbar. Vastmaken aan het startscherm Als de gebruiker kiest voor het vastmaken van een tegel aan het startscherm dan moet een dialoog met een voorproefje aangeboden worden. De gebruiker moet actief toestemming geven. Microsoft biedt hiervoor een standaard formaat aan die beperkt aanpasbaar is. Instantieer dus een SecondaryTile en beschrijf daarmee hoe de tegel eruit zou kunnen zien (listing 4). private async void pin_Click(object sender, RoutedEventArgs e) { BottomAppBar.IsSticky = true; var tileId = ViewModelLocator.Venue.Venue.id; SecondaryTile secondaryTile = new SecondaryTile(tileId); secondaryTile.Arguments = string.Format("Lat={0}&Lon={1}", ViewModelLocator.Settings.Latitude, ViewModelLocator.Settings.Longitude); secondaryTile.DisplayName = ViewModelLocator.Venue.Venue.name;
ViewModelLocator.Venue.IsPinned = isPinned; //if (isPinned) //{ // await CreateTileUpdater(tileId); //} BottomAppBar.IsSticky = false; } Listing 4: Laten we eens vragen of we mogen pinnen De tile krijgt een unieke identificatie mee en er is ruimte voor extra argumenten (informatie die aan de detailpagina wordt doorgegeven zodra de gebruiker op de tegel drukt). De latitude en longitude van de meting wordt meegegeven. Naast een beschrijvende naam volgt ook de bestandsnaam en locatie van eventuele logo’s die als achtergrond van de tegel gaan dienen. Hier worden twee formaten opgegeven (de standaard 150 bij 150 en de dubbele breedte van 310 bij 150). De gebruiker wordt de keuze gelaten welk formaat daadwerkelijk op het startscherm gebruikt wordt. Maak dus even twee PNG plaatjes aan van het juiste formaat en plaats deze in de Assets map van het project. De opgegeven achtergrondkleur is nu nog overbodig maar die komt straks goed van pas bij het verfraaien van de tegel. Dialoog voor goedkeuring pinnen De gebruiker moet dus toestemming geven. Dit kan met de RequestCreateForSelectionAsync() methode. Zoals al in Figuur 1 te zien is, en zoals Microsoft het ook graag ziet, is deze dialoog net boven de pin-button geplaatst. De schermlocatie van de knop moet wel berekenen worden (listing 5). private static Rect GetElementRect(FrameworkElement element) { var pinTransform = element.TransformToVisual(null); var point = pinTransform.TransformPoint(new Point()); return new Rect(point, new Size(element.ActualWidth, element.ActualHeight)); } Listing 5: Bereken de locatie van de pin-button
magazine voor software development 37
WINDOWS
Dit stukje code maakt het ook lastig om alle logica rond Secondary Tiles in een helper te stoppen die naast het viewmodel zou leven. Er is eenvoudigweg kennis over het scherm nodig dus deze methode moet binnen de code behind van de view uitgevoerd worden. Uiteindelijk wordt na goedkeuring de tegel op het startscherm geplaatst (figuur 2).
if (venue != null) { ViewModelLocator.Venue.Venue = venue; //// The main form is already part of the navigation //// Now jump to the specific venue page rootFrame.Navigate(typeof(VenuePage), e.Arguments); } } } //// Update exisiting tiles //var tilelist = await SecondaryTile.FindAllAsync();
Fig. 2: De secondary tile op het startscherm Deze tegel opent wel de applicatie maar er wordt nog niet naar het detailscherm doorverwezen. Daarvoor is nog een extra handeling nodig. Navigatie naar het juiste detailscherm Ons uiteindelijke doel is om de gewenste venue te tonen. Reageer op het starten via de secondary tile via de bestaande OnLaunched() eventhandler in app.xaml.cs. Deze methode wordt alleen uitgevoerd als de app gestart wordt. Normaal wordt de hoofdpagina gekozen. Maar wij voegen dus een extra controle aan het einde van de methode toe (listing 6) om te kijken of de identificatie van een secondary tile ontvangen is. De tile identificatie wordt namelijk als event argument meegegeven. Het is opvallend dat als de app via de standaard tegel wordt opgestart, de waarde “App” wordt doorgegeven. Dit is dus niet zo’n ideale unieke identificatie voor een secundary tile.
//foreach (var tile in tilelist) //{ // await VenuePage.CreateTileUpdater(tile.TileId); //} } Listing 6: Navigeer naar de juiste venue via de tile Controleer de aan de app gerelateerde storage op opgeslagen venues. Als de venue behorende bij de unieke identificatie nog beschikbaar is dan start de navigatie daar naar toe. En zie, ook de extra argumenten worden doorgeven. Om de venues op te kunnen halen was wel een minimale aanpassing in de LoadData() methode in MainViewModel.cs nodig (listing 7). Ik heb ervoor gekozen om venues op te slaan na het uitlezen van de Foursquare-service. Hiervoor gebruik ik de in de template aanwezige Storage helper class. public async Task LoadData() { IsDataLoaded = false; LoadStaticData();
protected override async void OnLaunched( LaunchActivatedEventArgs e) { …
var venues = await FoursquareService.GetVenues(24); if (venues != null) { var venueList = new List
(venues);
//// Check for pin navigation from secondary tile var tileId = e.TileId; if (!string.IsNullOrEmpty(tileId)) && (tileId != "App")) { // Started by secondary tile var venues = await Storage.LoadAsync>( ApplicationData.Current.LocalFolder, "Venues"); if (venues != null) { var venue = venues.FirstOrDefault(x => x.id == tileId);
var saved = venueList.Count > 0 ? await Storage.SaveAsync( ApplicationData.Current.LocalFolder, "Venues", venueList) : false; if (saved) { Venues = new ObservableCollection(venues); } } IsDataLoaded = true; } Listing 7: Sla de laatste versie van ontvangen data op
38
MAGAZINE
WINDOWS
Venues zijn namelijk van een locatie afhankelijk die bij het ophalen via de service doorgegeven is. Als de gebruiker na het aanmaken van de tegel zich verplaatst, dan kan de tegel valse hoop wekken. De Foursquare service zal namelijk een nieuwe lijst van venues genereren waar onze gevraagde venue vrijwel zeker niet meer bij zit. Nu is door de opslag de kans groter dat de venue nog beschikbaar is. Ik laat het aan de lezer over om met de locatie in de argumenten te spelen.
Ook ditmaal wordt de identificatie van de venue vastgesteld en moeten de schermlocatie bepaald worden. De gebruiker mag uiteindelijk bevestigen dat de tile ontkoppeld wordt (figuur 4).
Debuggen Het debuggen van een secondary tile is lastig. Sluit eerst de app af en probeer deze daarna via de tegel te starten. Helaas is debugger niet actief is want Visual Studio heeft de app niet opgestart. Hoe koppelen we dan op tijd de debugger aan onze app in Visual Studio? Gelukkig heeft Microsoft hierin voorzien. Bij de project-opties op het Debug-tabblad, is speciaal voor deze situatie een optie in te stellen (figuur 3).
Fig. 4: Het Unpin-dialoog In principe hebben we nu een volledig werkende secondary tile voor de venue-detailpagina. Maar persoonlijk vind ik de opmaak wel wat magertjes. Een plaatje en een titeltje steekt schraal af tegen de mooie tegels van andere apps. Een kleine uitbreiding doet wonderen.
Fig. 3: Uitgesteld starten van de app maakt debuggen mogelijk Met deze optie aangevinkt, zal Visual Studio niet de app maar alleen de debugger starten. Het starten van de app wordt aan de gebruiker overgelaten. De debugger zal daarna direct beschikbaar komen voor een complete debugsessie. Losmaken van het startscherm Naast het pinnen moet ook het unpinnen ondersteund worden (listing 8). Ook deze code voorziet in een dialoog met de gebruiker die nu geforceerd wordt met de RequestDeleteForSelectionAsync() methode. private async void unpin_Click(object s, RoutedEventArgs e) { var tileId = ViewModelLocator.Venue.Venue.id;
Doe meer met notificaties Ik heb in bovenstaande codeblokken al verwijzingen opgenomen naar de CreateTileUpdater() methode (in listing 4 en listing 6). Deze methode voegt aan de bestaande tile een lokale updater toe (listing 9). Het is een eenmalige verfraaiing en wordt niet automatisch bijgewerkt. Deze is dus niet aan een feed of iets dergelijks gekoppeld maar we vullen deze gewoon met tekst. public async static Task CreateTileUpdater(string tileId) { var venues = await Storage.LoadAsync>( ApplicationData.Current.LocalFolder, "Venues"); if (venues != null) { var venue = venues.FirstOrDefault(x => x.id == tileId);
BottomAppBar.IsSticky = true; // Now make the unpin request. var isUnpinned = await new SecondaryTile(tileId). RequestDeleteForSelectionAsync( GetElementRect((FrameworkElement)unpinButton), Placement.Above); ViewModelLocator.Venue.IsPinned = !isUnpinned;
if (venue != null) { var loc = venue.location; var tileXml = TileUpdateManager. GetTemplateContent( TileTemplateType.TileWide310x150Text01); var tileTextAttributes = tileXml.GetElementsByTagName("text");
BottomAppBar.IsSticky = false; }
Listing 8: Ook unpinnen moet bevestigd worden
tileTextAttributes[0].AppendChild( tileXml.CreateTextNode(venue.name)); tileTextAttributes[1].AppendChild( tileXml.CreateTextNode("" + loc.address)); tileTextAttributes[2].AppendChild( tileXml.CreateTextNode("" + loc.city));
magazine voor software development 39
WINDOWS
tileTextAttributes[3].AppendChild( tileXml.CreateTextNode(loc.distance + "m")); var squareTileXml = TileUpdateManager. GetTemplateContent( TileTemplateType.TileSquare150x150Text01); var squareTileTextAttributes = squareTileXml.GetElementsByTagName("text"); squareTileTextAttributes[0].AppendChild( squareTileXml.CreateTextNode(venue.name)); squareTileTextAttributes[1].AppendChild( squareTileXml.CreateTextNode("" + loc.address)); squareTileTextAttributes[2].AppendChild( squareTileXml.CreateTextNode("" + loc.city)); squareTileTextAttributes[3].AppendChild( squareTileXml.CreateTextNode(loc.distance + "m")); var node = tileXml.ImportNode(squareTileXml. GetElementsByTagName("binding").Item(0), true); tileXml.GetElementsByTagName("visual"). Item(0). AppendChild(node); var tileNotification = new TileNotification(tileXml); var secondaryTileUpdater = TileUpdateManager. CreateTileUpdaterForSecondaryTile(tileId); secondaryTileUpdater.Update(tileNotification); } }
We maken dankbaar gebruik van de extra regels om naast de naam van de venue ook het adres en de afstand te tonen. De gebruiker kan achteraf zelf het formaat aanpassen en de live tile uitzetten (figuur 6).
Fig. 6: De gebruiker heeft controle over de tiles Deze TileUpdater maakt het ook mogelijk om bij het starten van de app de teksten op de beschikbare tiles bij te werken. Dit voorkomt dat de tegeltjes verouderde informatie gaan tonen. En dit draagt bij aan het vertrouwen van de gebruiker dat onze app altijd de juiste informatie toont. Het moet duidelijk zijn dat dit slechts een eenvoudige vorm van een live tile is. Secondary tiles kunnen ook steeds wijzigende notificaties en badges (de teller op een tegel) tonen. Conclusie Met het toepassen van secondary tiles krijgt de ontwikkelaar opeens een krachtige optie in handen om apps op een andere manier te laten ervaren. De gebruiker is nu nog maar één klik van een detailpagina verwijderd. En als tegels steeds met nieuwe informatie bijgewerkt worden dan maakt het startscherm onderdeel uit van onze app.
} Windows store app template http://blog.rajenki.com/ Listing 9: Maak van de tile een live tile met meer mogelijkheden Wat is dan het nut? Met deze methode kunnen beide formaten tegeltjes (de brede en de smalle) een alternatieve opmaak krijgen. Microsoft heeft een bonte verzameling van templates voor tegels van diverse formaten en opmaak. Ik heb gekozen voor een tegel waarin het logo van de app in het klein wordt weergegeven, net onder vier volle regels aan tekst (figuur 5). En de eerste regel is met grotere letters afgebeeld. Dit is formaat TileTemplateType.TileWide310x150Text01. Hierbij gebruik ik ook eindelijk de opgegeven achtergrondkleur.
Secondary tiles guide lines http://msdn.microsoft.com/en-us/library/windows/apps/ hh465398.aspx Tile formaat catalogus http://msdn.microsoft.com/en-us/library/windows/apps/ hh761491.aspx •
Sander van de Velde Sander van de Velde is sinds 1993 actief in de IT sector. Sander is werkzaam bij Atos TS als .Net Consultant. Sander is graag bezig met software innovaties zoals Windows Azure en Windows Phone en probeert die een plaats te geven in zijn dagelijkse werkzaamheden. Sander vindt het belangrijk om kennis te delen en dat doet hij door het schrijven van blogs en artikelen en het geven van presentaties. Kennis maakt kennis! Als er nog tijd overblijft, dan gaat hij graag zeilen of motorrijden met zijn vrouw of hij loopt een geocache met zijn drie zonen.
Fig. 5: Secondary live tiles krijgen een andere opmaak
40
MAGAZINE
DELPHI
Bob Swart
REST Debugging met Delphi XE5 Delphi XE5 kent enkele leuke toevoegingen op het gebied van REST en JSON. Zo zijn er speciale REST client componenten (hierover een andere keer meer), en is er nu ook een echte REST Debugger. Deze laatste kan een belangrijke rol spelen bij het testen en debuggen van DataSnap REST Servers, maar kan ook gebruikt worden voor het testen van "normale" REST servers en services. In dit artikel zal ik laten zien hoe we de Delphi XE5 REST Debugger kunnen installeren en gebruiken om enkele REST Servers aan te roepen. REST Debugger Allereerst moeten we de REST Debugger beschikbaar maken in het Delphi menu, bij voorkeur onder het Tools menu natuurlijk. Start hiervoor Delphi XE5, en doe dan Tools | Configure Tools.... In de dialog die volgt, kunnen we dan de Add knop gebruiken om een nieuwe "Tool" aan het Tools menu toe te voegen. In de nieuwe Tool Properties dialoog, kunnen we de Titel, locatie van de REST Debugger, en de working directory opgeven. De REST Debugger kan gevonden worden als RESTDebugger.exe in Delphi's eigen bin directory. Deze bin directory moet ook meteen de working directory worden:
Google Geocoding Het formaat van een Google Geocodign request is een URL van de volgende vorm: https://maps.googleapis.com/maps/api/geocode/formaat? parameters Waarbij formaat ofwel "json" ofwel "xml" kan zijn. En de parameters ofwel "address" gevolgd door een adres, ofwel "latlng" gevolgd door twee getallen lattitude en longitude), ofwel "components" kan zijn. De laatste optie kan gebruikt worden als filter, maar valt buiten de scope van dit artikel. Tot slot moet er ook altijd een sensor parameter volgen, die de waarde "true" of "false" moet hebben. Dit gebruiken we om aan te geven of het request van een device komt dat zelf een sensor heeft ("true" voor mijn smart phones, "false" voor mijn desktop computer). Als voorbeeld om de GPS coordinaten van mijn huis annex kantoor terug te laten rekenen, kan ik de volgende URL gebruiken: http://maps.googleapis.com/maps/api/geocode/json?latlng=51.461 6395,5.6113771&sensor=true De weg terug is ook mogelijk natuurlijk, van adres naar GPS waarden, maar dat laat ik over aan de lezer.
Na het bevestigen en afsluiten van deze dialoog, is de REST Debugger te vinden in het Tools menu. REST Debugging Als de REST Debugger gestart is, dan kunnen we deze gebruiken om REST Servers en services aan te roepen. Niet alleen de DataSnap REST Servers die we met Delphi zelf kunnen maken, maar ook andere REST Servers zijn om deze manier aan te roepen. Als voorbeeld - zodat iedereen kan meespelen - zal ik de Google Maps Geocoding API gebruiken nu, om de functionaliteit van de REST Debugger te demonstreren. Achtergrond informatie over de Google Geocoding API is te vinden op https://developers.google.com/maps/documentation/geocoding/. Op dit moment is versie 3 in gebruik, en wie nog versie 2 gebruikt krijgt een nette foutmelding te zien. De Google Geocoding APi kan gebruikt worden om een Geo locatie (in lattitude en longitude) om te zetten in een adres, of andersom. Het gebruik is gratis tot 2500 requests per 24 uur. Zakelijke gebruikers kunnen tot 100.000 gaan voordat de service stopt met antwoorden.
Geocoding in de REST Debugger Teneinde de Geocoding in de REST Debugger te kunnen gebruiken, starten we de REST Debugger van het Tools menu, en vullen dan http://maps.googleapis.com/maps/api/geocode/json in op de plek van de URL
magazine voor software development 41
DELPHI
In de Parameters tab voegen we met de "Add" knop een tweetal parameters toe: latlng=51.4616395,5.6113771 en sensor=false
We moeten ook even een parameter "type" toevoegen, met als waarde "master" (voor een CD of LP). Alternatieve waarde is "artist", als we naar een artiest zoeken met de opgegeven naam.
Hierna kunnen we op de Send Request knop klikken, en krijgen we het resultaat onderaan te zien. Zowel de Headers als de Body en (indien we bijvoorbeeld een array of dataset terugsturen), Tabular Data. Delphi REST Servers Ook al is het leuk om de REST Debugger te gebruiken om externe REST Servers aan te roepen, het zal duidelijk zijn dat de grootste meerwaarde zit in het aanroepen van lokale REST services, terwijl deze vanuit de Delphi IDE gestart zijn en ge-debugged worden. Op deze manier is de REST Debugger meer een soort van "Web App Debugger", maar dan specifiek voor REST servers. Er zijn nog twee tabs die ik niet heb laten zien, dat zijn de Authentication (niet zo interessant als je de werking en output van de REST service wilt zien), en de Connection tab waar je het gebruik van een Proxy server kunt aangeven indien nodig. Het feit dat je bij een request ook een custom body kan opgeven, en het request ook kan opslaan (en later weer kan laden om opnieuw te gebruiken), maakt de REST Debugger efficiënt in gebruik voor als je je REST services moet testen voor of na deployment. •
Op dezelfde manier kunnen we een Delphi DataSnap REST server testen, zoals https://www.bobswart.nl/Inessensa/ InessensaServer.dll met als Parameters dan de waarde DataSnap/rest/TServerMethods1/Behandeling zonder argumenten. Dit levert een DataSet op, met daarin de namen, duur (in minuten) en omschrijvingen van behandelingen van een keten schoonheidssalons in de BeNeLux. Vreemd genoeg wordt hiet dan wel het resultaat als "table" vertoond, maar zien we niet echt "Tabular Data". Om dat te zien, moeten we een array van values terugkrijgen. Voor Tabular Data kunnen we bijvoorbeeld gebruik maken van de discogs REST service te http://api.discogs.com. Voor dit artikel heb ik de Discogs API versie 2.0 gebruikt. Vul in de REST Debugger als Request de http://api.discogs.com in, bij parameters de waarde database/search, en tot slot een parameter (met de "Add" button), namelijk "title" met als waarde "dark side of the moon"
42
MAGAZINE
Bob Swart Bob Swart is werkzaam in de IT sinds 1983 en heeft daarbij een voorliefde voor (Turbo) Pascal en Delphi. Bob spreekt regelmatig op (internationale) conferenties over Delphi en heeft honderden artikelen geschreven, alsmede zijn eigen Delphi cursusmateriaal voor Delphi trainingen en workshops. Behalve voor het geven van trainingen, is Bob ook beschikbaar voor consultancy, coaching, ontwerp- en bouwwerkzaamheden, of andere ondersteuning op het gebied van software ontwikkeling met Delphi – voor zowel Win32 als .NET. Sinds de zomer van 2007 is Bob ook reseller van CodeGear producten zoals Delphi en RAD Studio. Bob Swart Training & Consultancy is gevestigd in Helmond Brandevoort, en beschikt over een eigen trainingsruimte van ruim 42 vierkante meter, inclusief een testlab voor alle mogelijke toepassingen. De voorliefde van Bob voor Pascal en Delphi heeft hij ook tot uiting laten komen in de namen van zijn kinderen Erik Mark Pascal en Natasha Louise Delphine.
SDN > Update
Delphi Nieuws Delphi XE5 Update #2 Op 10 december vorig jaar is Update #2 voor Delphi en C++Builder XE5 uitgekomen. Deze is te downloaden van de bekende pagina voor geregistreerde gebruikers te http://cc.embarcadero.com/myreg. Helaas ontbraken er enkele bestanden, dus moet je na het uitvoeren van deze update ook meteen de Hotfix #1, #2 en #3 draaien. Deze hotfixes zijn ook te downloaden van dezelfde locatie.
Korting van 5% voor SDN Leden Voor SDN leden geldt nog steeds de aanbieding van 5% korting op een Delphi of RAD Studio licentie als er tegelijkertijd een subscription wordt afgesloten. Zie http://www.eBob42.com/SDN voor meer details.
RAD in Action Embarcadero heeft op https://www.embarcadero.com/rad-in-action een hoeveelheid white papers, webinars, videos en links naar extra demos neergezet, waar vooral Delphi XE5 ontwikkelaars profijt van kunnen hebben.
Een verzameling online videos en tutorials voor mobile development is te zien op http://docwiki.embarcadero.com/RADStudio/XE5/ en/Mobile_Tutorials:_Mobile_Application_Development_(iOS_and_Android)
Coding in Delphi eBook Nick Hodges, voormalig Delphi Product Manager, heeft een eBook geschreven dat beschikbaar is voor alle geregistreerde gebruikers van Delphi XE5. Het boek is te downloaden van http://cc.embarcadero.com/ item/29670
Delphi in 2014 David I van Embarcadero heeft in zijn blog geschreven over de ontwikkelingen van Delphi in 2013, maar ook over een aantal zaken die we in 2014 kunnen verwachten. Zie http://blogs.embarcadero.com/davidi/ 2014/01/01/43162/ voor meer details en zijn nieuwjaarswensen.
Delphi XE5 Cursusboeken Naast Delphi trainingen en workshops van Bob Swart, zijn de cursusboeken die bij deze trainingen gebruikt worden nu ook beschikbaar voor mensen die geen tijd of gelegenheid hebben om deze trainingen bij te wonen. De Delphi XE5 cursusboeken bevatten specifieke informatie over onderwerpen als DataSnap, XML en SOAP, of Mobile Development (over zowel Android als iOS). De cursusboeken zijn beschikbaar in PDF formaat, en te vinden op http://www.eBob42.com/courseware
magazine voor software development 43