mastering xamarin ui developmentsd.blackball.lv/library/mastering_xamarin_ui_development... ·...

445

Upload: others

Post on 20-May-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools
Page 2: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

MasteringXamarinUIDevelopment

Page 3: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TableofContents

MasteringXamarinUIDevelopmentCreditsAbouttheAuthorAcknowledgmentsAbouttheReviewerswww.PacktPub.com

Whysubscribe?CustomerFeedbackDedicationPreface

WhatthisbookcoversWhatyouneedforthisbookWhothisbookisforConventionsReaderfeedbackCustomersupport

DownloadingtheexamplecodeErrataPiracyQuestions

1.CreatingtheTrackMyWalksNativeAppCreatingtheTrackMyWalkssolution

UpdatingtheTrackMyWalkssolutionpackagesCreatingtheTrackMyWalksmodelCreatingthewalksmainpageCreatingthenewwalkentrycontentpageCreatingthewalktrailcontentpage

AddingtheXamarin.Forms.MapsNuGetpackageCreatingtheDistanceTravelledPagecontentpageCreatingtheSplashscreencontentpage

UpdatingtheXamarin.FormsAppclassDifferencesbetweenXamarinStudioandVisualStudioRunningtheTrackMyWalksappusingthesimulatorSummary

2.MVVMandDataBindingUnderstandingtheMVVMpatternarchitectureImplementingtheMVVMViewModelswithinyourappCreatingtheWalkBaseViewModelfortheTrackMyWalksappImplementingtheWalksPageViewModel

UpdatingthewalksmainpagetousetheMVVMmodelImplementingthewalksentrypageViewModel

Page 4: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksEntryPagetousetheMVVMmodelImplementingthewalktrailpageViewModel

UpdatingtheWalksTrailPagetousetheMVVMmodelImplementingtheDistanceTravelledViewModel

UpdatingtheDistanceTravelledPagetousetheMVVMmodelSummary

3.NavigatingwithintheMVVMModel-TheXamarin.FormsWayUnderstandingtheXamarin.FormsNavigationAPIDifferencesbetweenthenavigationandViewModelapproachesImplementingthenavigationservicewithinyourapp

CreatingthenavigationserviceinterfacefortheTrackMyWalksappCreatinganavigationservicetonavigatewithinourViewModelsUpdatingtheWalkBaseViewModeltouseournavigationserviceUpdatingthewalksmainpageViewModelandnavigationserviceUpdatingthewalksmainpagetousetheupdatedViewModelUpdatingthewalksentrypageViewModelandnavigationserviceUpdatingtheWalksEntryPagetousetheupdatedViewModelUpdatingthewalkstrailpageViewModelandnavigationserviceUpdatingtheWalksTrailPagetousetheupdatedViewModelUpdatingthedistancetravelledViewModelandnavigationserviceUpdatingtheDistanceTravelledPagetousetheupdatedViewModelUpdatingtheXamarin.Forms.Appclasstousethenavigationservice

Summary4.AddingLocation-BasedFeatureswithinYourApp

Creatingandusingplatform-specificservicesCreatingtheLocationServiceInterfacefortheTrackMyWalksappCreatingtheLocationServiceclassfortheAndroidplatformCreatingtheLocationServiceclassfortheiOSplatformEnablingbackgroundupdatesandgettingtheuser'scurrentlocationUpdatingtheWalkEntryViewModeltousethelocationserviceUpdatingtheDistanceTravelledViewModeltousethelocationserviceUpdatingtheSplashPagetoregisterourViewModelsUpdatingtheMainActivityclasstouseXamarin.Forms.MapsUpdatingtheXamarin.FormsAppclasstouseplatformspecifics

Summary5.CustomizingtheUserInterface

CreatingtheDataTemplateclassfortheTrackMyWalksappUpdatingthewalksmainpagetousethedatatemplate

CreatingaTableViewEntryCellcustompickerfortheiOSplatformCreatingthecustompickerrendererclassfortheiOSplatform

UpdatingtheWalksEntryPagetousethecustompickerrendererCreatingPlatformEffectsusingtheEffectsAPIfortheiOSplatformCreatingPlatformEffectsusingtheEffectsAPIfortheAndroidplatformImplementingvalueconverterswithintheTrackMyWalksapp

Page 5: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkBaseViewModeltouseourBooleanconverterUpdatingtheWalksPageViewModeltouseourBooleanconverterUpdatingthewalksmainpagetousetheupdatedViewModelUpdatingtheWalksTrailPagetousetheupdatedViewModelUpdatingtheDistanceTravelledPagetousetheupdatedViewModelUpdatingtheWalkCellDataTemplateclasstousePlatformEffects

Summary6.WorkingwithRazorTemplates

UnderstandingtheRazortemplateengineCreatingandimplementingRazortemplateswithinXamarinStudio

AddingtheSQLite.NetpackagetotheBookLibrarysolutionCreatingandimplementingthebooklibrarydatabasemodelCreatingandimplementingthebookdatabasewrapperCreatingandimplementingtheBookLibrarydatabasewrapperCreatingandimplementingthebooklistingmainpageCreatingandimplementingtheBookLibraryAddRazortemplateCreatingandimplementingtheBookLibraryEditRazortemplateCreatingandimplementingtheWebViewControllerclass

UpdatingthebooklibraryCascadingStyleSheet(CSS)Summary

7.IncorporatingAPIDataAccessUsingMicrosoftAzureAppServicesSettingupourTrackMyWalksappusingMicrosoftAzure

AddingtheJson.NetNuGetpackagetotheTrackMyWalksappAddingtheHttpClientNuGetpackagetotheTrackMyWalksappUpdatingtheWalkEntriesmodeltousetheJson.Netframework

CreatingtheHTTPwebserviceclassfortheTrackMyWalksappCreatingtheDataServiceAPIfortheTrackMyWalksappCreatingtheDataServiceAPIclassfortheTrackMyWalksapp

UpdatingtheWalkBaseViewModeltouseourDataServiceAPIUpdatingtheWalkEntryViewModeltouseourDataServiceAPIUpdatingtheWalksPageViewModeltouseourDataServiceAPIUpdatingtheWalksPagetousetheupdatedViewModelUpdatingthecustompickerrendererclassfortheiOSplatformUpdatingtheWalksEntryPagetousetheupdatedcustompicker

Summary8.MakingOurAppSocial-UsingtheFacebookAPI

SettingupandregisteringtheTrackMyWalksappwithFacebookAddingtheXamarin.AuthNuGetpackagetotheTrackMyWalksappAddingtheFaceBookSDKlibrarytotheTrackMyWalksapp

CreatingaFacebookusermodelfortheTrackMyWalksappCreatingaFacebookCredentialsclassfortheTrackMyWalksappCreatingtheFacebookSignIntousewithinourTrackMyWalksappCreatingtheFacebookSignInClassforTrackMyWalks(iOS)app

UpdatingtheNavigationServiceInterfacefortheTrackMyWalksapp

Page 6: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheNavigationServiceclassfortheTrackMyWalksappUpdatingtheWalksPagetoproperlyhandleFacebookSignIn

UpdatingtheWalksPageViewModeltouseourFaceBookApiUserUpdatingtheDistanceTravelledPagefortheTrackMyWalksappUpdatingtheXamarin.FormsAppclasstohandleFacebookSignInEnablingFacebookfunctionalitywithintheTrackMyWalksapp

Summary9.UnitTestingYourXamarin.FormsAppsUsingtheNUnitandUITestFrameworks

CreatingaunittestsolutionfolderusingXamarinStudioCreatingaunittestprojectusingXamarinStudio

AddingtheMoqNuGetpackagetotheunittestprojectAddingtheTrackMyWalksprojecttoTrackMyWalks.UnitTestsCreatingandimplementingtheWalksTrailViewModelNUnittestclassCreatingandimplementingtheWalkEntryViewModelNUnittestclassRunningtheTrackMyWalks.UnitTestsusingXamarinStudio

CreatingaUItestprojectusingXamarinStudioUnderstandingthecommonlyusedUITestmethods

SettingupandinitializingourTrackMyWalksappforUITestImplementingtheCreateNewWalkEntryusingtheUITest.Framework

AddingtheXamarinTestCloudAgenttotheiOSprojectUpdatingtheTrackMyWalksAppDelegateclasstohandleXamarinTestCloudAgent

RunningtheTrackMyWalksUITestsusingXamarinStudioSummary

10.PackagingandDeployingYourXamarin.FormsApplicationsCreatingandsettingupyouriOSdevelopmentteamCreatingtheTrackMyWalksiOSdevelopmentcertificate

ObtainingtheiOSdevelopmentcertificatefromAppleCreatingtheAppIDfortheTrackMyWalks(iOS)application

CreatingtheTrackMyWalksdevelopmentprovisioningprofilePreparingtheTrackMyWalks(iOS)appforsubmission

SubmittingtheTrackMyWalks(iOS)apptoiTunesConnectusingXamarinStudioSummary

Page 7: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

MasteringXamarinUIDevelopment

Page 8: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

MasteringXamarinUIDevelopmentCopyright©2017PacktPublishing

Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.

Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.

PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.

Firstpublished:January2017

Productionreference:1130117

PublishedbyPacktPublishingLtd.

LiveryPlace

35LiveryStreet

Birmingham

B32PB,UK.

ISBN978-1-78646-200-8

www.packtpub.com

Page 9: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Credits

Author

StevenF.Daniel

CopyEditor

SafisEditing

Reviewers

LanceMcCarthy

EnginPolat

ProjectCoordinator

IzzatContractor

CommissioningEditor

AmarabhaBanerjee

Proofreader

SafisEditing

AcquisitionEditor

ShwetaPant

Indexer

TejalDaruwaleSoni

ContentDevelopmentEditor

PriyankaMehta

Graphics

AbhinashSahu

TechnicalEditor

AbhishekSharma

ProductionCoordinator

DeepikaNaik

Page 10: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AbouttheAuthorStevenF.DanielistheCEOandfounderofGENIESOFTSTUDIOS,asoftwaredevelopmentcompanybasedinMelbourne,Victoria,thatfocusesprimarilyondevelopinggamesandbusinessapplicationsfortheiOS,Android,andMacOSXplatforms.Heisanexperiencedsoftwaredeveloperwithmorethan17yearsofexperienceindevelopingdesktopandweb-basedapplicationsforseveralcompaniesandstartups.

StevenisextremelypassionateaboutmakingpeopleemployablebyhelpingthembridgethegapbetweenusingtheirexistingskillsiniOS,Android,andXamarintogetthejobdone.Toachievethis,hewritesbookstohelpnoviceandadvancedprogrammerssucceedwithintheindustry.Stevenisextremelypassionateabout,andlovesbeingattheforefrontof,technology.HeisamemberoftheSQLServerSpecialInterestGroup(SQLSIG),MelbourneCocoaHeads,andtheJavaCommunity.HewasthecofounderandChiefTechnologyOfficer(CTO)atSoftMpirePtyLtd.,acompanythatisfocusedprimarilyondevelopingbusinessapplicationsfortheiOSandAndroidplatforms.

Stevenistheauthorofvariousbooktitles,someofwhichareasfollows:

AppleWatchAppDevelopmentAndroidWearableProgrammingXcode4CookbookiPadEnterpriseApplicationDevelopmentBlueprintsiOS5EssentialsXcode4iOSDevelopmentBeginner’sGuide

Checkouthisblogathttp://www.geniesoftstudios.com/blog/,orfollowhimontwitterathttp://twitter.com/GenieSoftStudio.

Page 11: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AcknowledgmentsNobookistheproductofjusttheauthor;hejusthappenstobetheonewithhisnameonthecover.Severalpeoplecontributedtothesuccessofthisbook,anditwouldtakemorespacethanthankingeachoneindividually.

Iwouldpersonallyliketothankthreespecialpeoplewhohavebeenaninspirationandwhohaveprovidedmewithsomuchsupportduringthewritingofthisbook,ReshmaRaman,mySeniorAcquisitionEditor,whoisthereasonthatthisbookexists;ShwetaPant,myAcquisitionEditor;andPriyankaMehtaforherunderstandingandsupport,aswellasherbrilliantsuggestiveapproachesduringthechapterrewrites.Iwouldliketothankeachofyouforeverything,andmakingthewritingprocessenjoyable.

Lastly,tomyreviewers,thankyousomuchforyourvaluedsuggestionsandimprovementstomakethisbookwhatitis;Iamtrulygratefultoeachoneofyou.

ThankyoualsototheentirePACKTPublishingteamforworkingsodiligentlytohelpbringoutahigh-qualityproduct.Finally,abigshoutouttotheengineersatXamarin,Inc.forcreatingXamarinStudioandtheMonoPlatformtoprovidedeveloperswiththetoolstocreatefunandsophisticatedapplicationswiththepowerofXamarin.Forms.

Finally,Iwouldliketothankallmyfriendsfortheirsupport,understanding,andencouragementduringthebookwritingprocess.Iamextremelygratefultohaveyouasmyfriends,anditisaprivilegetoknoweachoneofyou.

Page 12: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AbouttheReviewersLanceMcCarthyisanexceptionalcommunityleaderwithanacuteexpertiseforallthings.NETandC#,especiallyontheXAMLstack,includingWPF,Silverlight,WindowsPhone,andWindowsstoreapps.Heisveryhelpfulonline,guidingandansweringquestionsfromMicrosoftdevelopersonTwitteras@lancewmccarthy;heblogsonhisowntimeaswell,withastrongfocusonWindowsUniversalapps,atWinPlatform.wordpress.com.HeorganizesandhostseventsintheBostonarea,suchasusergroupnights,mini-codecamps,andfullhackathons.

Duringtheday,LanceisaseniortechnicalsupportengineeratTelerik,wherehesupportsdeveloperswiththeirClassicWindows,UniversalWindows,webandmobile(Xamarin,AndroidandiOSnative)applicationdevelopment.

Ontheside,Lancewritesblogpostsforblogs.windows.com/buildingapps/,createsresourcesfordevelopers(tutorials,samplesourcecode,tipsoftheweek,andsoon),andhelpsthedevelopercommunityinanywaypossible.

Previously,LanceworkedforNokiaandMicrosoftasaDeveloperAmbassador,wherehesoughtoutandengageddevelopersthroughoutreachprogramsandprovidesthemwithtechnicalsupportandresourcestomakethemsuccessfulontheWindowsplatforms.

LancewasalsoanassistantprofessoratHarvardUniversity,helpingstudentsbuild,market,andpublishsuccessfulWindowsPhoneapps.Hehasalsoappearedonpodcasts,suchastheWindowsDeveloperShow,hasbeenatechnicaleditorforpublicationsandbooks,haswonseveralappbuildingcontestsandhackathons(includingfirstplaceintheMicrosoftBuild2013hackathon),andisapublisheddeveloperwithoveramilliondownloadsintheWindowsStore.

Someofthebooksthathehasreviewedareasfollows:

NetdunioHomeAutomationProjectsbyMattCavanaughMasteringCross-PlatformDevelopmentwithXamarinbyCanBilginBegintoCodewithC#byRobMiles

EnginPolathasbeeninvolvedinmanylargeandmedium-scaleprojectson.NETtechnologiesasadeveloper,architect,andconsulting,andhehaswonmanyawardssince1999.Since2008,hehasbeentrainingmanylargeenterprisesinTurkeyonWindowsdevelopment,webdevelopment,distributedapplicationdevelopment,softwarearchitecture,mobiledevelopment,clouddevelopment,andsoon.Apartfromthis,heorganizesseminarsandeventsinmanyuniversitiesinTurkeyabout.NETtechnologies,Windowsplatformdevelopment,clouddevelopment,webdevelopment,gamedevelopment,andsoon.Heshareshisexperiencesonhispersonalblog(http://www.enginpolat.com).HehasMCP,MCAD,MCSD,MCDBA,andMCTcertifications.Since2012,heisrecognizedasaWindowsDevelopmentMVPbyMicrosoft;since2017,heisrecognizedasaVisualStudioandDevelopmentTechnologiesMVPtoo.Between2013and2015,

Page 13: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

hewasrecognizedasaNokiaDeveloperChampion-veryfewpeopleintheworldaregiventhisaward.Since2015,hehasbeenrecognizedasaRegionalDirectorbyMicrosoft.

HehasreviewedafewbooksforPackt,someofwhichareasfollows:

MasteringCross-PlatformDevelopmentwithXamarinXamarinBlueprintsXamarin4byExample

I'dliketothankmydearwife,Yeliz,andmybeautifuldaughter,MelisAda,forallthesupporttheygavemewhileIwasworkingonthisbookproject.

Ialsowanttoextendawarmwelcometothenewestmemberofmyfamily,mydearson,UtkuEge.

Page 14: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

www.PacktPub.comForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.

DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusatservice@packtpub.comformoredetails.

Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.

https://www.packtpub.com/mapt

Getthemostin-demandsoftwareskillswithMapt.MaptgivesyoufullaccesstoallPacktbooksandvideocourses,aswellasindustry-leadingtoolstohelpyouplanyourpersonaldevelopmentandadvanceyourcareer.

Page 15: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser

Page 16: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CustomerFeedbackThankyouforpurchasingthisPacktbook.Wetakeourcommitmenttoimprovingourcontentandproductstomeetyourneedsseriously-that'swhyyourfeedbackissovaluable.Whateveryourfeelingsaboutyourpurchase,pleaseconsiderleavingareviewonthisbook'sAmazonpage.Notonlywillthishelpus,moreimportantlyitwillalsohelpothersinthecommunitytomakeaninformeddecisionabouttheresourcesthattheyinvestintolearn.Youcanalsoreviewforusonaregularbasisbyjoiningourreviewers'club.Ifyou'reinterestedinjoining,orwouldliketolearnmoreaboutthebenefitsweoffer,pleasecontactus:[email protected].

Page 17: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

DedicationTomyfavoriteuncle,BenjaminJacobDaniel,thankyouforalwaysmakingmesmileandforinspiringmetoworkhardandachievemydreams;youareatrueinspirationandIcouldn’thavedonethiswithoutyourlove,support,andguidance.Thankyou.

Asalways,toChanBanGuan,forthecontinuedpatience,encouragement,andsupport,andmostofallforbelievinginmeduringthewritingofthisbook.Iwouldliketothankmyfamilyfortheircontinuedloveandsupport,andforalwaysbelievinginmethroughoutthewritingofthisbook.

ThisbookwouldnothavebeenpossiblewithoutyourloveandunderstandingandIwouldliketothankyoufromthebottomofmyheart.

Page 18: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

PrefaceXamarinisthemostpowerfulcross-platformmobiledevelopmentframework.IfyouareinterestedincreatingstunninguserinterfacesfortheiOSandAndroidmobileplatformsusingthepowerofXamarinandXamarin.Forms,thenthisisyourticket.

Thisbookwillprovideyouwiththepracticalskillsrequiredtodevelopreal-worldXamarinapplications.Youwilllearnhowtoimplementuserinterfacestructuresandlayouts,createcustomizedelements,andwriteC#scriptstocustomizelayouts.You’lllearnhowtocreateUserInterfacelayoutsfromscratchandcustomizetheselayoutstosuityourneedsbyusingDataTemplatesandCustomRenderers.

You’llbeintroducedtothearchitecturebehindtheModel-View-ViewModel(MVVM)pattern,andhowtoimplementthiswithinyourapplicationsothatyoucannavigatebetweeneachofyourViewModelsandContentPages.

Wewillthenmoveontodiscussmoreadvancedtopics,suchashowtoincorporateplatform-specificfeatureswithinyourappsthataredependentonthemobileplatformbeingrun,andyouwilllearnhowtoproperlyperformlocationupdates,whethertheapplication'sstateisintheforegroundorbackground,byregisteringtheappasabackground-necessaryapplication.

Wediscussmoreadvancedtopics,suchasworkingwithMicrosoftAzureAppservicestocreateyourveryfirstcloud-basedbackendHTTPwebservicetohandlecommunicationbetweenthecloudandtheapp,bycreatingaDataServiceAPIthatwillallowourapptoconsumetheAPIsothatitcanretrieve,store,anddeletewalktrailinformationfromthecloud.

WewillalsocoverhowyoucanworkwiththeFacebookSDKtoincorporatesocialnetworkingfeaturestoobtaininformationaboutaFacebookuser,aswellaspostinformationtotheirFacebookwallandusetheOpenGraphAPItoretrievecertaininformationabouttheuser.

Movingon,youwilllearnhowtousethird-partylibraries,suchastheRazortemplateengine,whichallowsyoutocreateyourownHTML5templates,withintheXamarinStudioenvironmenttobuildabooklibraryHybridsolutionthatusestheSQLite.Netlibrarytostore,update,retrieve,anddeleteinformationwithinaSQLitelocaldatabase.You’llalsoimplementkeydatabindingtechniquesthatwillmakeyouruserinterfacesdynamicandcreatepersonalizedanimationsandvisualeffectswithinyouruserinterfacesusingcustomrenderersandthePlatformEffectsAPItocustomizeandchangetheappearanceofcontrolelements.

Attheendofthisbook,youwilllearnhowtocreateandrununittestsusingtheNUnitandUITesttestingframeworksrightwithintheXamarinStudioIDE.You'lllearnhowtowriteunittestsforyourViewModelsthatwillessentiallytestthebusinesslogictovalidatethateverythingisworkingcorrectly,beforemovingontotesttheuserinterfaceportionusingautomatedUItesting.

Inthisbook,Ihavetriedmybesttokeepthecodesimpleandeasytounderstandbyprovidinga

Page 19: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

step-by-stepapproach,withlotsofscreenshotsateachsteptomakeiteasiertofollow.YouwillsoonmasterthedifferentaspectsofXamarin.Forms,andthetechnologyandskillsneededtocreateyourownapplicationsfortheXamarin.Formsplatform.

[email protected],orjustdropmeane-mailtosayafriendly"Hello".

Page 20: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

WhatthisbookcoversChapter1,CreatingtheTrackMyWalksNativeApp,focusesonhowtosetupabasiccross-platformnativeappstructureusingXamarin.Formsbeforeproceedingwithaddingnew,andupdatingexisting,packageswithinyoursolution.

You’lllearnhowtocreateC#classesthatwillactasthemodelforourapp,andwillcreatecontentpagesthatwillformtheuserinterface.WewillalsocoverthedifferencesbetweendevelopingappsusingXamarinStudioandMicrosoftVisualStudio.

Chapter2,MVVMandDataBinding,introducesyoutothearchitecturebehindtheMVVMpattern,andhowyoucanimplementthiswithinyourapplicationbyaddingnewViewsandtheassociatedModels.

You’lllearnhowtocreatetheunderlyingC#classfilesthatwillactastheViewModelsforyourapp,andupdateexistingcontentpagestodata-bindwiththeViewModelstorepresenttheinformationthatwillbedisplayedwithintheuserinterfaceforourapplication.

Chapter3,NavigatingwithintheMVVMModel-TheXamarin.FormsWay,buildsuponyourworkingknowledgeoftheMVVMdesignpatternarchitecturetoshowyouhowyoucannavigatethroughtheViewModelsbycreatingaC#classthatactsasthenavigationserviceforourapp,andupdatesourexistingWalkBaseViewModelclasstoincludeadditionalabstractclassmethodseachofourViewModelswillinherit;inturn,you'llupdatecontentpagestobindwiththeViewModelstoallownavigationbetweentheseViewstohappen.

Chapter4,AddingLocation-BasedFeatureswithinYourApp,focusesonhowyoucanincorporateplatform-specificfeatureswithintheTrackMyWalksapp,whichisdependentonthemobileplatform,bycreatingalocationserviceC#classthatwillincludeseveralclassmethodsforboththeiOSandAndroidplatforms.

You’lllearnhowtoproperlyperformlocationupdateswhethertheapplication'sstateisintheforegroundorbackgroundbyregisteringtheappasabackground-necessaryapplication.

Chapter5,CustomizingtheUserInterface,showsyouhowyoucanworkwithDataTemplatestolayoutyourviewsneatlywithinyourapplicationsuserinterfacebycreatingaC#class.You’llgetaccustomedtoworkingwithplatform-specificAPIstoextendthedefaultbehaviorofXamarin.Formscontrolsusingcustomrendererstocreateacustompicker,beforemovingontolearnhowtousetheXamarin.FormsEffectsAPItocustomizetheappearanceandstylingofnativecontrolelementsforeachplatformbyimplementingaCustomRendererclass.

Finally,youwilllearnhowtomanipulatethevisualappearanceofdataboundusingvalueandimageconverters.

Chapter6,WorkingwithRazorTemplates,introducesyoutotheRazorHTMLtemplatingengine,

Page 21: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

andhowyoucanuseittocreateahybridmobilesolution.You'lllearnhowtobuildabooklibrarymobilesolutionusingthepowerofRazortemplates,howtocreateandusemodelswithinyourapplication,andhowtoconnectthisuptoaSQLitedatabasetostore,retrieve,update,anddeletebookdetails.

Chapter7,IncorporatingAPIDataAccessusingMicrosoftAzureAppServices,showsyouhowyoucanuseMicrosoftAzureAppservicestocreateyourveryfirstlive,cloud-basedbackendHTTPwebservicetohandleallthecommunicationbetweenthecloudandtheapp.You’lllearnhowtocreateaDataServiceAPIthatwillallowtheapptoconsumetheAPIsothatitcanretrieve,store,anddeletewalktrailinformationfromthecloud,allfromwithintheTrackMyWalksapp.

Chapter8,MakingourAppSocial–UsingtheFacebookAPI,showsyouhowyoucanusebothXamarin.AuthandtheFacebookSDKtoincorporatesocialnetworkingfeatureswithintheTrackMyWalksapptoobtaininformationaboutaFacebookuser,aswellaspostinformationtotheirFacebookwall.

You’lllearnhowtocreateasign-inpagethatallowsuserstologintoyourappusingtheirFacebookcredentials,andhowtocreateaFacebookApiUserclassthatwillbeusedtostoreinformationaboutthelogged-inuser,andusetheOpenGraphAPItoretrievecertaininformationabouttheuser.

Finally,youwillseehowyoucanleveragetheFacebooklibrarytopostwalkdatatoyourFacebookprofilepage,soyoucanshowoffyourWalkTrailprogresstoyourfriendsand/orworkcolleagues.

Chapter9,UnitTestingyourXamarin.FormsAppusingtheNUnitandUITestFrameworks,focusesonshowingyouhowtocreateandrununittestsusingtheNUnitandUITesttestingframeworksrightwithintheXamarinStudioIDE.You'lllearnhowtowriteunittestsforourViewModelsthatwillessentiallytestthebusinesslogictovalidatethateverythingisworkingcorrectlybeforetestingtheuserinterface'sportionusingautomatedUItesting.

Chapter10,PackagingandDeployingyourXamarin.FormsApplications,focusesonhowtosubmityourTrackMyWalksiOSapptotheAppleAppStore,andshareyourcreationswiththerestofthecommunity.You'lllearnthestepsrequiredtosetupyouriOSdevelopmentteam,aswellascertificatesforbothdevelopmentanddistribution,andyouwilllearnhowtocreatethenecessaryprovisioningprofilesforbothyourdevelopmentanddistributionbuildsandcreatethenecessaryappIDsforyourapplication.

Finally,youwilllearnhowtoregisteryouriOSdevicessothatyouruserscandownloadandtestyourappsontheiriOSdevicesandlearnhowtoprepareyourTrackMyWalksiOSappforsubmissiontoiTunesConnectusingtheXamarinStudioIDE.

Page 22: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

WhatyouneedforthisbookTheminimumrequirementforthisbookisanIntel-basedMacintoshcomputerrunningOSXElCapitan10.11.WewillbeusingXamarinStudio6.1.2,whichistheIntegratedDevelopmentEnvironment(IDE)usedforcreatingXamarin.FormsapplicationsusingC#,aswellasXcode8.2.1tocompileouriOSappandrunthiswithinthesimulator.

AlmostalltheprojectsthatyoucreatewiththehelpofthisbookwillworkandrunontheiOSsimulator.However,someprojectswillrequireaniOSorAndroiddevicetoworkcorrectly.YoucandownloadthelatestversionsofXamarinStudioandXcodeat:

XamarinStudio:http://xamarin.com/download

Xcode:https://itunes.apple.com/au/app/xcode/id497799835?mt=12

Page 23: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

WhothisbookisforThisbookisintendedfordeveloperswhohaveaworkingexperienceofapplicationdevelopmentprinciples,aswellasabasicknowledgeofXamarinandC#codingandwishtoexpandtheirknowledgeanddevelopapplicationsusingXamarin.Forms.ItisassumedthatyouarefamiliarwithObject-OrientedProgramming(OOP),andhavesomeexperiencedevelopingC#applicationsusingXamarinStudio.

Page 24: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ConventionsInthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestylesandanexplanationoftheirmeaning.

Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:"OnethingyouwillnoticeisthatoursolutioncontainsafilecalledTrackMyWalks.cswhichispartoftheTrackMyWalksPortableClassLibrary."

Ablockofcodeissetasfollows:

//

//WalkEntryViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassWalkEntryViewModel:WalkBaseViewModel

{

Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Collections.Generic;

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage

{

publicWalksPage()

{

Anycommand-lineinputoroutputiswrittenasfollows:

Lastlogin:SunNov610:48:41onconsole

GENIESOFT-MAC-Mini:~stevendaniel$curl

https://trackmywalks.azurewebsites.net/tables/walkentries

Page 25: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

--header"ZUMO-API-VERSION:2.0.0"

Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,forexample,inmenusordialogboxes,appearinthetextlikethis:"ifyouclickontheProceedWith...button,itwillnavigatetothewalksTrailDetailspagewhereyoucanbeginyourtrail,byclickingontheBeginthisTrailbutton."

Note

Warningsorimportantnotesappearinaboxlikethis.

Tip

Tipsandtricksappearlikethis.

Page 26: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook-whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.Tosendusgeneralfeedback,[email protected],andmentionthebook'stitleinthesubjectofyourmessage.Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.

Page 27: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.

Page 28: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesforthisbookfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

Youcandownloadthecodefilesbyfollowingthesesteps:

1. Loginorregistertoourwebsiteusingyoure-mailaddressandpassword.2. HoverthemousepointerontheSUPPORTtabatthetop.3. ClickonCodeDownloads&Errata.4. EnterthenameofthebookintheSearchbox.5. Selectthebookforwhichyou'relookingtodownloadthecodefiles.6. Choosefromthedrop-downmenuwhereyoupurchasedthisbookfrom.7. ClickonCodeDownload.

Oncethefileisdownloaded,pleasemakesurethatyouunziporextractthefolderusingthelatestversionof:

WinRAR/7-ZipforWindowsZipeg/iZip/UnRarXforMac7-Zip/PeaZipforLinux

ThecodebundleforthebookisalsohostedonGitHubathttps://github.com/PacktPublishing/Mastering-Xamarin-UI-Development.Wealsohaveothercodebundlesfromourrichcatalogofbooksandvideosavailableathttps://github.com/PacktPublishing/.Checkthemout!

Page 29: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks-maybeamistakeinthetextorthecode-wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.

Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.

Page 30: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.

Pleasecontactusatcopyright@packtpub.comwithalinktothesuspectedpiratedmaterial.

Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.

Page 31: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

QuestionsIfyouhaveaproblemwithanyaspectofthisbook,[email protected],andwewilldoourbesttoaddresstheproblem.

Page 32: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter1.CreatingtheTrackMyWalksNativeAppSinceXamarinmadeitsappearanceseveralyearsago,developershavebeendelightedwithbeingabletocreatenativemobileapplicationsthattargetnon-Microsoftplatforms,andwithhavingtheoptionofdevelopingappsusingeitherC#orF#programminglanguages,whichenablesdeveloperstodistributetheirappideasoniOSandAndroidplatforms.

Asyouprogressthroughthisbook,youwilllearnhowtoapplybestpracticeprincipleswhendevelopingcross-platformmobileapplicationsanddesignpatternsusingtheXamarin.Formsplatform,whichallowsdeveloperstobuildcross-platformuserinterfacelayoutsthatcanbesharedacrossAndroid,iOS,andWindowsPhonemobileplatforms.

Sinceeachoftheseappscanbewrittenusingasingleprogramminglanguage,itmakessensetowriteasinglecodebasethatwouldcompileandbuildseparateappsforeachofthesedifferentplatforms.

ThischapterwillbeginbysettingupabasicstructureofanappbuiltusingXamarin.Forms,whichwillbethefoundationforthesubsequentchapters,wherewewillcontinuallybuilduponthis,applyingnewconcepts.Inthischapter,youwillseehowtocreateaninitialcross-platformnativeappusingXamarin.Formsandhowtogoaboutaddingnew,andupdatingexisting,packageswithinyoursolution.

You'lllearnhowtocreateC#classesthatwillactasthemodelforourapp,aswellascreatingcontentpagesthatwillformtheuserinterface.Toendthechapter,youwilllearnaboutthedifferencesbetweendevelopingappsusingXamarinStudioand/orMicrosoftVisualStudio.

Thischapterwillcoverthefollowingpoints:

CreatingtheXamarin.FormsTrackMyWalksmobileappsolutionUpdatingtheTrackMyWalkssolutionpackagesusingtheNuGetpackagemanagerCreatingtheTrackMyWalksdatamodelCreatingtheContentPagesfortheTrackMyWalkssolutionUnderstandingthedifferencesbetweenXamarinStudioandVisualStudio

Page 33: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheTrackMyWalkssolutionInthissection,wewilltakealookathowwecangoaboutcreatinganewXamarin.Formssolutionforthefirsttime.Wewillbeginbydevelopingthebasicstructureforourapplication,aswellasbyaddingthenecessaryentitymodelsanddesigningtheuserinterfacefiles.

Beforewecanproceed,weneedtocreateourTrackMyWalksproject.ItisverysimpletocreatethisusingXamarinStudio.Simplyfollowthestepslistedbelow:

1. LaunchtheXamarinStudioapplication.Youwillbepresentedwiththefollowingscreen:

2. Next,clickontheNewSolution...button,oralternativelychoosetheFile|New|Solution...orsimplypressShift+Command+N.

3. Next,choosetheFormsAppoptionwhichislocatedundertheMultiplatform|Appsection.EnsureyouhaveselectedC#astheprogramminglanguagetouse:

Page 34: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

4. Next,enterTrackMyWalkstouseasthenameforyourappintheAppNamefield.5. Then,specifyanamefortheOrganizationIdentifierfield.6. Next,ensurethatboththeAndroidandiOScheckboxeshavebeenselectedintheTarget

Platformsfields.7. Then,ensurethattheUsePortableClassLibraryoptionhasbeenselectedintheShared

Codesection,asshowninthefollowingscreenshot.

Tip

ThedifferencebetweenusingaPortableClassLibraryversusaSharedLibraryisessentiallythataPortableClassLibraryenablesdeveloperstowritecodeonce,sothatitcanbeusedwithindifferentplatformprojectssuchasWebsites,Android,andiOS.ASharedLibraryenablesdeveloperstocopyallthefileswithinthelibraryprojecttoalltheprojectsthatarecontainedwithinthesolutionduringcompilationforthevariousplatformsthatwilluseit.

Page 35: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Note

TheOrganizationIdentifieroptionforyourappneedstobeunique.XamarinStudiorecommendsthatyouusethereversedomainstyle(forexample,com.domainName.appName).

8. Next,ensurethattheUseXAMLforuserinterfacefilesoptionhasnotbeenselected.9. Then,clickontheNextbuttontoproceedtothenextstepinthewizard.

Page 36: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

10. Next,ensurethattheCreateaprojectdirectorywithinthesolutiondirectory.checkboxhasbeenselected.

11. Then,clickontheCreatebuttontosaveyourprojecttothespecifiedlocation.

Onceyourprojecthasbeencreated,youwillbepresentedwiththeXamarindevelopmentenvironmentalongwithseveralprojectfilesthatthetemplatehascreatedforyou,asshowninthefollowingscreenshot:

Page 37: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,theTrackMyWalkssolutionhasbeendividedintothreemainareas.Thefollowingtableprovidesabriefdescriptionofwhateachareaisusedfor:

Platformspecificproject Description

TrackMyWalks

ThisisthePortableClassLibrary(PCL)projectthatwillberesponsibleforactingasthemainarchitecturallayerfortheTrackMyWalkssolution.

Thisprojectcontainsallofthebusinesslogic,dataobjects,Xamarin.FormsPages,views,andothernon-platformspecificcode.

Anycodethatyoucreatewithinthisprojectcanbesharedacrossmultipleplatform-specificprojects.

TrackMyWalks.Droid

ThisprojectisanAndroidspecificprojectthatcontainsallofthecodeandassetsrequiredtobuildanddeploytheAndroidappcontainedwithinthesolution.

Bydefault,thisprojectcontainsareferencetotheTrackMyWalksPortableClassLibrary.

ThisprojectisaniOSspecificprojectthatcontainsallofthecodeandassetsrequiredtobuildanddeploytheiOSappcontainedwithinthesolution.

Page 38: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TrackMyWalks.iOS Bydefault,thisprojectcontainsareferencetotheTrackMyWalksPortableClassLibrary.

OnethingyouwillnoticeisthatoursolutioncontainsafilecalledTrackMyWalks.cswhichispartoftheTrackMyWalksPortableClassLibrary.TheTrackMyWalks.csfilecontainsaclassnamedAppthatinheritsfromtheXamarin.Forms.Applicationclasshierarchy,ascanbeseeninthefollowingcodesnippet:

//

//TrackMyWalks.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassApp:Application

{

publicApp()

{

//Therootpageofyourapplication

varcontent=newContentPage

{

Title="TrackMyWalks",

Content=newStackLayout{

VerticalOptions=LayoutOptions.Center,

Children={newLabel{

HorizontalTextAlignment=

TextAlignment.Center,

Text="WelcometoXamarinForms!"

}

}

}

};

MainPage=newNavigationPage(content);

}

protectedoverridevoidOnStart()

{

//Handlewhenyourappstarts

}

protectedoverridevoidOnSleep()

{

//Handlewhenyourappsleeps

}

protectedoverridevoidOnResume()

{

//Handlewhenyourappresumes

Page 39: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

}

}

TheAppconstructormethodsetsuptheMainPagepropertytoanewinstanceoftheContentPagethatwillsimplydisplaysomedefaulttextascreatedbytheprojectwizard.Throughoutthischapter,wewillbebuildingtheinitialuserinterfacepageviewsandthenmodifyingtheMainPagepropertyforourAppclass,containedwithintheTrackMyWalks.csfile.

Page 40: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheTrackMyWalkssolutionpackagesInthissection,wewilltakealookathowtoupdatetheXamarin.FormspackagescontainedwithinourTrackMyWalkssolution.Basically,youwillnoticethateachprojectcontainedwithinoursolutioncontainsaPackagesfolder.

TheXamarin.FormspackageisessentiallyaNuGetpackagethatgetsautomaticallyincludedinoursolutionwheneverwespecifythatwewanttocreateaXamarin.FormsAppprojecttemplate.

Fromtimetotime,youwillnoticethatXamarinwillnotifyyouwheneverapackageisoutofdateandneedstobeupdatedtoensurethatyouarerunningthelatestversion.

Note

ANuGetpackage,isessentiallythepackagemanagerfortheMicrosoftDevelopmentPlatformthatcontainstheclienttoolsthatprovidethecapabilityforproducingandconsuming.NETpackages.

Let'stakealookathowtogoaboutupdatingtheNuGetpackageswithinourTrackMyWalkssolutiontoensurethatwearerunningthelatestXamarin.Formspackages.Performthefollowingsteps:

1. Right-clickontheTrackMyWalkssolutionandchoosetheUpdateNuGetPackagesmenuoption,asshowninthefollowingscreenshot:

Page 41: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Onceyouhaveselectedthisoption,XamarinStudiowillproceedtoupdateeachpackagethatiscontainedwithintheTrackMyWalkssolutionforeachoftheplatform-specificprojects,andwilldisplayaprogressindicatorsimilartotheoneshowninthefollowingscreenshot:

Duringthepackageupdateprocess,somepackagesthatarecontainedaspartofeachplatform-specificprojectrequireyoutoaccepttheirlicensetermspriortoinstalling,whichisshowninthefollowingscreenshot:

2. ClickontheAcceptbuttontoacceptthelicensetermsandconditionsforthepackagesdisplayedwithinthedialogboxandtoinstallthepackages,asshownintheprecedingscreenshot.

NowthatyouhavesuccessfullyupdatedtheXamarin.Formspackageswithinyoursolution,wecannowproceedwithbuildingtheuserinterfacefilesfortheTrackMyWalkssolution.

Page 42: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheTrackMyWalksmodelInthissection,wewillproceedtocreateourTrackMyWalksmodelthatwillrepresentourwalkentries.Asweprogressthroughoutthischapter,wewillseehowwecanusethismodeltosetupandinitializesomewalkentriesforourmainWalksPageusingaListViewcontrolsothatwecandisplaywalkentryforeachrowwithintheListView.

Let'stakealookathowwecanachievethis,byfollowingthestepsbelow:

1. CreateanewfolderwithintheTrackMyWalksPortableClassLibraryprojectsolution,calledModelsasshowninthefollowingscreenshot:

2. Next,createanewclassfilewithintheModelsfolder,asshowninthefollowingscreenshot:

Page 43: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Then,choosetheEmptyClassoptionundertheGeneralsectionandenterinWalkEntriesforthenameofthenewclassfiletobecreatedasshowninthefollowingscreenshot:

Page 44: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

4. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewfile,asshownintheprecedingscreenshot.

Congratulations,youhavecreatedyourfirstfolderandC#classfileforoursolution.Wecannowproceedwithaddingthepropertydescriptorsthatwillbeusedtodefineourmodel.

5. EnsurethattheWalkEntries.csfileisdisplayed,thenlocatetheWalkEntriesclassconstructorandenterthefollowinghighlightedcodesections:

//

//WalkEntries.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

namespaceTrackMyWalks.Models

{

publicclassWalkEntries

{

publicstringTitle{get;set;}

publicstringNotes{get;set;}

publicdoubleLongitude{get;set;}

publicdoubleLatitude{get;set;}

publicdoubleKilometers{get;set;}

publicstringDifficulty{get;set;}

publicdoubleDistance{get;set;}

publicstringImageUrl{get;set;}

}

}

Intheprecedingcodesnippet,wehavesuccessfullydefinedthemodelthatwillbeusedtorepresentourwalkentries.Inthenextsection,wewillusethismodeltosetupandinitializesomewalkentriesforourmainWalksPageusingaListViewcontrol,thenuseaDataTemplatetodescribehowthemodeldatashouldbedisplayedforeachrowwithintheListView.

Page 45: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingthewalksmainpageAsmentionedintheprevioussection,theWalksPagewillessentiallyserveasthemainentrypointforourapplication.WewilluseourWalkEntriesmodeltopopulatesomestaticwalksinformationdata,thendisplaythisinformationwithinaListViewcontrolusingaDataTemplate.Solet'sgetstartedbyfollowingthesesteps:

1. Firstly,createanewfolderwithintheTrackMyWalksPortableClassLibraryprojectsolutioncalledPages,asyoudidintheprevioussection.

2. Next,fromtheNewFilescreen,selecttheFormssectionwithintheleftsectionpane.3. Then,selecttheFormsContentPageoptionintherightpane.4. Next,enterWalksPageforthenameofthenewclasstobecreated.5. Finally,clickontheNewbutton,asshowninthefollowingscreenshot:

6. Next,ensurethattheWalksPage.csfileisdisplayedwithinthecodeeditorandenterinthefollowinghighlightedcodesections.

Page 46: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Collections.Generic;

usingXamarin.Forms;

usingTrackMyWalks.Models;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage

{

publicWalksPage()

{

varnewWalkItem=newToolbarItem

{

Text="AddWalk"

};

newWalkItem.Clicked+=(sender,e)=>

{

Navigation.PushAsync(newWalkEntryPage());

};

ToolbarItems.Add(newWalkItem);

varwalkItems=newList<WalkEntries>

{

newWalkEntries{

Title="10MileBrookTrail,MargaretRiver",

Notes="The10MileBrookTrailstartsintheRotaryPark

nearOldKate,apreservedsteam"+

"engineatthenorthernedgeofMargaretRiver.",

Latitude=-33.9727604,

Longitude=115.0861599,

Kilometers=7.5,

Distance=0,

Difficulty="Medium",

ImageUrl="http://trailswa.com.au/media/cache/media/

images/trails/_mid/FullSizeRender1_600_480_c1.jpg"

},

newWalkEntries{

Title="AncientEmpireWalk,ValleyoftheGiants",

Notes="TheAncientEmpireisa450metrewalktrail

thattakesyouaroundandthroughsomeof"+

"thegianttingletreesincludingthemostpopular

ofthegnarledveterans,knownasGrandmaTingle.",

Latitude=-34.9749188,

Longitude=117.3560796,

Kilometers=450,

Distance=0,

Difficulty="Hard",

ImageUrl="http://trailswa.com.au/media/cache/media/

images/trails/_mid/Ancient_Empire_534_480_c1.jpg"

Page 47: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

},

};

varitemTemplate=newDataTemplate(typeof(ImageCell));

itemTemplate.SetBinding(TextCell.TextProperty,"Title");

itemTemplate.SetBinding(TextCell.DetailProperty,"Notes");

itemTemplate.SetBinding(ImageCell.ImageSourceProperty,

"ImageUrl");

varwalksList=newListView{

HasUnevenRows=true,

ItemTemplate=itemTemplate,

ItemsSource=walkItems,

SeparatorColor=Color.FromHex("#ddd"),

};

//Setupoureventhandler

walksList.ItemTapped+=(objectsender,

ItemTappedEventArgse)=>

{

varitem=(WalkEntries)e.Item;

if(item==null)return;

Navigation.PushAsync(newWalkTrailPage(item));

item=null;

};

Content=walksList;

}

}

}

Intheprecedingcodesnippet,webeganbydeclaringournewWalkItemvariablethatinstantiatesfromtheToolbarItemclasswhichwillbeusedtoattachanewAddWalkbuttontothemaintoolbarofthebaseContentPage.ToolbarItemscollectiontoprovideawayforuserstoaddnewwalktrailinformationwithintheapp.

Next,wecreateaneventforournewWalkItemusingtheClickedeventoftheToolbarItemclass,whichwillbeusedtonavigatetothenewWalksEntryPage.

Inournextstep,wedeclareanewvariablewalkItemsthatisacollectionoflistitemstostoreeachofourwalkentrieswithinourmodelandthenusetheDataTemplateclasstodescribehowwewantourmodeldatatobedisplayedwithineachoftherowsdeclaredwithintheListView.

Finally,wesetupaneventhandlerforourListViewthatwillbeusedtomovetotheWalksTrailPagetodisplayinformationabouttheitemselected.

Page 48: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingthenewwalkentrycontentpageInthissection,wewillbeginbuildingtheuserinterfaceforournewWalkEntryPage.ThispageiscalledwhentheuserclicksontheAddWalkbuttonfromthemainpageandwillbeusedtoallowtheuserameansofaddingnewwalkinformationtobeusedwithintheapplication.

Thereareanumberofwaysyoucangoaboutpresentingthisinformationtocollectdata.Forthepurposeofthisapp,wewillbeusingaTableView,butyoucouldquiteeasilyuseaStackLayoutandpresentthisinformationasaseriesofLabelsandEntryCells.

Let'sbeginbycreatingthenewWalkEntryPagebyperformingthefollowingsteps:

1. CreateanewContentPagecalledWalkEntryPage,asyoudidinthesectionentitledCreatingthewalksmainpage,locatedwithinthischapter.

2. Next,ensurethattheWalkEntryPage.csfileisdisplayedwithinthecodeeditorandenterinthefollowinghighlightedcodesections:

//

//WalkEntryPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingSystem.Collections.Generic;

namespaceTrackMyWalks

{

publicclassWalkEntryPage:ContentPage

{

publicWalkEntryPage()

{

//SettheContentPageTitle

Title="NewWalkEntry";

//DefineourNewWalkEntryfields

varwalkTitle=newEntryCell

{

Label="Title:",

Placeholder="TrailTitle"

};

varwalkNotes=newEntryCell

{

Label="Notes:",

Placeholder="Description"

};

varwalkLatitude=newEntryCell

{

Label="Latitude:",

Page 49: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Placeholder="Latitude",

Keyboard=Keyboard.Numeric

};

varwalkLongitude=newEntryCell

{

Label="Longitude:",

Placeholder="Longitude",

Keyboard=Keyboard.Numeric

};

varwalkKilometers=newEntryCell

{

Label="Kilometers:",

Placeholder="Kilometers",

Keyboard=Keyboard.Numeric

};

varwalkDifficulty=newEntryCell

{

Label="DifficultyLevel:",

Placeholder="WalkDifficulty"

};

varwalkImageUrl=newEntryCell

{

Label="ImageUrl:",

Placeholder="ImageURL"

};

//DefineourTableView

Content=newTableView

{

Intent=TableIntent.Form,

Root=newTableRoot

{

newTableSection()

{

walkTitle,

walkNotes,

walkLatitude,

walkLongitude,

walkKilometers,

walkDifficulty,

walkImageUrl

}

}

};

varsaveWalkItem=newToolbarItem{

Text="Save"

};

saveWalkItem.Clicked+=(sender,e)=>{

Navigation.PopToRootAsync(true);

};

ToolbarItems.Add(saveWalkItem);

}

}

}

Page 50: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Intheprecedingcodesnippet,webeganbydeclaringanumberofEntryCelllabelsforouruserinterfacetocaptureinformationenteredbytheuserfor-Title,Notes,Latitude,Longitude,Kilometers,DifficultyandImageURL.Asyouprogressthroughthisbook,youwilllearnhowtocustomizethelookandfeeloftheEntryCellsbycreatingacustomizedplatform-specificpickerfortheWalkDifficultyandKilometers.

Next,wedefineourTableViewandaddeachofourEntryCellfieldstotheTableSectionpropertyoftheTableViewcontrol.EachTableSectionthatisdefinedwithinaTableViewconsistsofaheadingandoneormoreViewCells,which,inourcase,aretheEntryCellfields.

Finally,wedeclareandaddaToolbarItemcalledsaveWalkItemtoourContentPageToolbarItemscollection,thencreateaneventthat,whenclicked,willsavethewalkinformationenteredtothemainwalkspage.Obviously,wewillberefactoringthenewWalkEntryPagethroughoutthisbook,which,whentheSavebuttonispressed,willactuallysendthisinformationtotheserverusingaRESTfulAPIandrefreshthemainTrackMyWalkspage.

Page 51: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingthewalktrailcontentpageInthissection,wewillbeginbuildingtheuserinterfaceforourWalksTrailPage.ThispageiscalledwhentheuserclicksonanentrywithintheListViewonourTrackMyWalksmaincontentpageandwillbeusedtodisplayinformationassociatedwiththechosentrail:

1. CreateanewContentPagecalledWalkTrailPageasyoudidinthesectionentitledCreatingthewalksmainpage,locatedwithinthischapter.

2. Next,ensurethattheWalkTrailPage.csfileisdisplayedwithinthecodeeditorandenterthefollowinghighlightedcodesections:

//

//WalkTrailPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

namespaceTrackMyWalks

{

publicclassWalkTrailPage:ContentPage

{

publicWalkTrailPage(WalkEntrieswalkItem)

{

Title="WalksTrail";

varbeginTrailWalk=newButton

{

BackgroundColor=Color.FromHex("#008080"),

TextColor=Color.White,

Text="BeginthisTrail"

};

//Setupoureventhandler

beginTrailWalk.Clicked+=(sender,e)=>

{

if(walkItem==null)return;

Navigation.PushAsync(newDistanceTravelledPage(walkItem));

Navigation.RemovePage(this);

walkItem=null;

};

varwalkTrailImage=newImage()

{

Aspect=Aspect.AspectFill,

Source=walkItem.ImageUrl

};

vartrailNameLabel=newLabel()

{

Page 52: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

FontSize=28,

FontAttributes=FontAttributes.Bold,

TextColor=Color.Black,

Text=walkItem.Title

};

vartrailKilometersLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.Black,

Text=$"Length:{walkItem.Kilometers}km"

};

vartrailDifficultyLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.Black,

Text=$"Difficulty:{walkItem.Difficulty}"

};

vartrailFullDescription=newLabel()

{

FontSize=11,

TextColor=Color.Black,

Text=$"{walkItem.Notes}",

HorizontalOptions=LayoutOptions.FillAndExpand

};

this.Content=newScrollView

{

Padding=10,

Content=newStackLayout

{

Orientation=StackOrientation.Vertical,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children=

{

walkTrailImage,

trailNameLabel,

trailKilometersLabel,

trailDifficultyLabel,

trailFullDescription,

beginTrailWalk

}

}

};

}

}

}

Intheprecedingcodesnippet,webeganbyimportingourTrackMyWalks.ModelsclassaswewillbeusingthistoextracttheinformationpassedinfromourWalksPage.

Page 53: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Next,wedeclareourbeginTrailWalkvariablethatinheritsfromtheButtonclass;thenwesetuptheClickedeventoftheButtonclass,whichwillbeusedtonavigatetotheDistanceTravelledPagecontentpagewhenclickedtodisplayinformationaboutourtrailafterremovingourwalkstrailcontentpagefromtheNavigationPagehierarchy.

Inthenextstep,wedeclareanimagevariablewalkTrailImageandsettheSourcepropertyoftheimagetobetheimageoftheselectedwalkItemfromtheListView.WethendeclareandinitializeanumberoflabelobjectsthatwillcontainthewalkIteminformationthathasbeenpassedfromtheWalksPagecontentpageListViewcontrolanddisplayed.

Next,wedefineaScrollViewcontrolthatispartoftheXamarin.Forms.Corebaseclass,thenaddeachofourformImageandLabelfieldstotheStackLayoutcontrol.TheScrollViewcontrolisafantasticcontrolthatallowsourContentPagetoscrollitscontentsshouldtheinformationbetoobigtofitwithintheactualdevice'sscreenrealestate.

Page 54: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheXamarin.Forms.MapsNuGetpackageInthissection,wewillneedtoaddtheXamarin.Forms.MapsNuGetpackagetoourcoreproject,aswellasforeachoftheplatform-specificprojectsforbothiOSandAndroidplatforms.ThispackageisrequiredinordertousetheXamarin.FormsMapcontrolintheDistanceTravelledcontentpagethatwewillbebuildinginthenextsection.

1. Right-clickontheTrackMyWalkssolutionandchoosetheAddPackages...menuoption,asshowninthefollowingscreenshot:

2. ThiswilldisplaytheAddPackagesdialog.EnterinmapswithintheSearchdialogandthenselectandclicktheXamarin.Forms.Mapsoptionwithinthelist,asshowninthefollowingscreenshot:

Page 55: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Finally,clickontheAddPackagebuttontoaddtheXamarin.Forms.MapsNuGetpackagetotheTrackMyWalkscoresolution.

4. RepeatthesameprocesstoaddtheXamarin.Forms.MapsNuGetpackageforboththeiOSandAndroidprojectsthatarecontainedwithintheTrackMyWalkssolution.

NowthatyouhaveaddedtheNuGetPackagefortheXamarin.FormsMap,wecanbegintoutilizethiscontrolwithintheDistanceTravelledcontentpagethatwewillbecoveringinthenextsection.

Page 56: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheDistanceTravelledPagecontentpageInthissection,wewillbeginbuildingtheuserinterfaceforourDistanceTravelledPagecontentpage.ThispageiscalledwhentheuserclicksontheBeginthisTrailbuttonfromtheWalksTrailPagecontentpage,whichwillbeusedtodisplayinformationaboutthechosentrail,aswellasplacingapinplaceholderwithintheXamarin.Forms.Mapscontrolandcalculatingthedistancetravelled,andtimetaken:

1. CreateanewContentPagecalledDistanceTravelledPageasyoudidintheprevioussection.

2. Next,ensurethattheDistanceTravelledPage.csfileisdisplayedwithinthecodeeditorandenterthefollowinghighlightedcodesections:

//

//DistanceTravelledPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingXamarin.Forms.Maps;

usingTrackMyWalks.Models;

namespaceTrackMyWalks

{

publicclassDistanceTravelledPage:ContentPage

{

3. Then,updatetheDistanceTravelledPagemethodconstructortoincludethewalkItemparameterforthechosenwalk,asshownbythefollowinghighlightedcodesections:

publicDistanceTravelledPage(WalkEntrieswalkItem)

{

Title="DistanceTravelled";

4. Next,wedeclareatrailMapvariablethatwillpointtoaninstanceoftheXamarin.Forms.Mapscontroltocreateaplaceholderpinmarkerwithinthemapcontrol.Usingthelatitudeandlongitudecoordinates,enterthefollowinghighlightedcodesections:

//Instantiateourmapobject

vartrailMap=newMap();

//Placeapinonthemapforthechosenwalktype

trailMap.Pins.Add(newPin

{

Type=PinType.Place,

Label=walkItem.Title,

Position=newPosition(walkItem.Latitude,walkItem.Longitude)

});

Page 57: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//Centerthemaparoundthelistofwalksentry'slocation

trailMap.MoveToRegion(MapSpan.FromCenterAndRadius(new

Position(walkItem.Latitude,walkItem.Longitude),

Distance.FromKilometers(1.0)));

5. Then,wedeclareanumberofLabelobjectsthatcontainourwalkIteminformation,whichhasbeenpassedfromtheWalkTrailPagecontentpagesothatwecantrailrelatedinformation.Enterinthefollowinghighlightedcodesections:

vartrailNameLabel=newLabel()

{

FontSize=18,

FontAttributes=FontAttributes.Bold,

TextColor=Color.Black,

Text=walkItem.Title

};

vartrailDistanceTravelledLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=20,

TextColor=Color.Black,

Text="DistanceTravelled",

HorizontalTextAlignment=TextAlignment.Center

};

vartotalDistanceTaken=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=20,

TextColor=Color.Black,

Text=$"{walkItem.Distance}km",

HorizontalTextAlignment=TextAlignment.Center

};

vartotalTimeTakenLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=20,

TextColor=Color.Black,

Text="TimeTaken:",

HorizontalTextAlignment=TextAlignment.Center

};

vartotalTimeTaken=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=20,

TextColor=Color.Black,

Text="0h0m0s",

HorizontalTextAlignment=TextAlignment.Center

};

6. Next,wedeclareourwalksHomeButtonvariablethatinheritsfromtheButtonclassandproceedtosetupourclickhandler,whichwillbeusedtonavigateourapptothemainWalksPagecontentpagewhenclicked.Enterthefollowinghighlightedcodesections:

Page 58: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

varwalksHomeButton=newButton

{

BackgroundColor=Color.FromHex("#008080"),

TextColor=Color.White,

Text="EndthisTrail"

};

//Setupoureventhandler

walksHomeButton.Clicked+=(sender,e)=>

{

if(walkItem==null)return;

Navigation.PopToRootAsync(true);

walkItem=null;

};

7. Then,wedefineaScrollViewcontrolthatispartoftheXamarin.Forms.CorebaseclassandproceedtoaddeachofourformButtonandLabelfieldstotheStackLayoutcontrol.Enterthefollowinghighlightedcodesections:

this.Content=newScrollView

{

Padding=10,

Content=newStackLayout

{

Orientation=StackOrientation.Vertical,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children={

trailMap,

trailNameLabel,

trailDistanceTravelledLabel,

totalDistanceTaken,

totalTimeTakenLabel,

totalTimeTaken,

walksHomeButton

}

}

};

}

}

}

Intheprecedingcodesnippet,webeganbyimportingourTrackMyWalks.ModelsclassaswewillbeusingthistoextracttheinformationpassedinfromourWalksPage.TheXamarin.Forms.MapsNuGetpackageisacross-platformlibrarythatallowsdeveloperstodisplayandannotateinformationwithinthemap.Wewillbeusingthiscontroltocreateapinplaceholderwithinthemapcontrol,alongwithadditionaldetailsassociatedwiththetrail.

Next,wedeclareourtrailMapvariablethatpointstoaninstanceoftheXamarin.Forms.Mapscontrolandcreateaplaceholderpinmarkerwithinthemapcontainingthedetailsforthechosentrail,thencenterinonthemaptoshowtheareaforourwalkslocation,derivedbythelatitudeandlongitudecoordinates.WethendeclareandinitializeanumberofLabelobjectsthatcontainthewalkIteminformationthathasbeenpassedfromtheWalkTrailPagecontentpageand

Page 59: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

declareourwalksHomeButtonvariablethatinheritsfromtheButtonclass,thensetuptheClickedeventfortheButtonclass,whichwillbeusedtonavigatebacktotheTrackMyWalkswhenclicked.

Finally,wedefineaScrollViewcontrolthatispartoftheXamarin.Forms.Corebaseclass,thenaddeachofourformButtonandLabelfieldstotheStackLayoutcontrol.

Inournextsection,wewillneedtoinitializetheXamarin.Forms.MapsNuGetpackagelibrarywithineachofourplatform-specificstartupclasses(forexample,AppDelegate.csforiOSandMainActivity.csforAndroid).Let'stakealookathowwecanachievethisbyfollowingthestepsbelow.

1. EnsurethattheAppDelegate.csfileisdisplayedwithinthecodeeditorandenterthefollowinghighlightedcodesections:

//

//AppDelegate.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingFoundation;

usingUIKit;

namespaceTrackMyWalks.iOS

{

[Register("AppDelegate")]

publicpartialclassAppDelegate:

global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate

{

publicoverrideboolFinishedLaunching(UIApplicationapp,

NSDictionaryoptions)

{

global::Xamarin.Forms.Forms.Init();

Xamarin.FormsMaps.Init();

LoadApplication(newApp());

returnbase.FinishedLaunching(app,options);

}

}

}

Intheprecedingcodesnippet,webeganbyinitializingourAppDelegateclasstousetheXamarin.Forms.Mapslibrary,byaddingtheXamarin.FormsMaps.InitwhichinitializestheXamarin.Formsplatform,sothatourTrackMyWalkssolutioncanusethemaps.Ifthisisomittedfromthisclass,theDistanceTravelledPagecontentpagewillnotdisplaythemapandwillnotworkasexpected.

Note

FormoreinformationonXamarin.Forms.Mapslibrary,aswellasthevarioustypesofdifferent

Page 60: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

classesavailable,pleaserefertotheXamarindeveloperdocumentationathttps://developer.xamarin.com/api/namespace/Xamarin.Forms.Maps/.

Page 61: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheSplashscreencontentpageInthissection,wewillbeginbuildingtheuserinterfaceforourSplashpagewhichwillonlybeusedfortheAndroidplatform,sinceiOSalreadycontainsamethodofachievingthis.ThesplashpagewillsimplydisplaythedefaultXamarinicon,butasweprogressthroughoutthisbook,wewillberefactoringthispagetoincludeamoresuitableimageforourapp:

1. CreateanewContentPagecalledSplashPageasyoudidintheprevioussection.2. Next,ensurethattheSplashPage.csfileisdisplayedwithinthecodeeditorandenterthe

followinghighlightedcodesections:

//

//SplashPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Threading.Tasks;

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassSplashPage:ContentPage

{

3. Then,locatetheSplashPageconstructormethodandenterthefollowinghighlightedcodesections:

publicSplashPage()

{

AbsoluteLayoutsplashLayout=newAbsoluteLayout

{

HeightRequest=600

};

varimage=newImage()

{

Source=ImageSource.FromFile("icon.png"),

Aspect=Aspect.AspectFill,

};

AbsoluteLayout.SetLayoutFlags(image,AbsoluteLayoutFlags.All);

AbsoluteLayout.SetLayoutBounds(image,newRectangle(0f,0f,

1f,1f));

splashLayout.Children.Add(image);

Content=newStackLayout()

{

Children={splashLayout}

};

Page 62: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

4. Next,locatetheOnAppearingmethodandenterthefollowinghighlightedcodesections:

protectedoverrideasyncvoidOnAppearing()

{

base.OnAppearing();

//Delayforafewsecondsonthesplashscreen

awaitTask.Delay(3000);

//InstantiateaNavigationPagewiththeMainPage

varnavPage=newNavigationPage(newWalksPage()

{

Title="TrackMyWalks"

});

Application.Current.MainPage=navPage;

}

}

}

Intheprecedingcodesnippet,webeganbyimportingourSystem.Threading.Tasksclass.Thisclasswillbeusedtoperformaslightdelaytoallowourusertoseethesplashscreen,asdefinedwithintheOnAppearingclassmethod.

WethencreateasplashLayoutvariableoftypeAbsoluteLayoutthatwillbeusedtopositionandsizeeachofthechildelementsproportionallywithinourview,andthensettheHeightRequestproperty.

Next,wedeclareanimagevariablethatinheritsfromtheImageclass;thenassigntheSourcepropertytotheimagethatwewouldliketouseandsettheimagesAspectpropertysothattheimagefillstheview.

Inourfinalsteps,wedefinevaluesforbothoftheLayoutFlagsandLayoutBoundspropertiesontheAbsoluteLayoutclasssothattheimageresizeswithintheview.ThenweaddoursplashLayouttothecontentpageusingtheStackLayoutcontrol.Finally,weoverridetheOnAppearingclassmethodoftheXamarin.Forms.Pagepagelifecycle,whichgetscalledimmediatelypriortothepagebecomingvisibleonthescreen,andthenspecifyadelayofthreesecondspriortoinstantiatinganewinstanceoftheNavigationPage,whichwillcallourWalksPagetobethemaincontentrootpage.

Page 63: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheXamarin.FormsAppclassInthissection,weneedtoinitializetheAppclassofXamarin.FormslibrarytocallourSplashPageandsettherootpageforourapplicationifthedetectedOSdeviceisAndroid.Let'stakealookathowwecanachievethis:

1. OpentheTrackMyWalks.cslocatedwithintheTrackMyWalksgroupandensurethatitisdisplayedwithinthecodeeditor.

2. Next,locatetheAppmethodandenterthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

//

//TrackMyWalks.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassApp:Application

{

publicApp()

{

//ChecktheTargetOSPlatform

if(Device.OS==TargetPlatform.Android)

{

MainPage=newSplashPage();

}

else

{

//Therootpageofyourapplication

varnavPage=newNavigationPage(newTrackMyWalks.

WalksPage()

{

Title="TrackMyWalks"

});

MainPage=navPage;

}

}

}

}

Intheprecedingcodesnippet,webegancheckingtheDevice.OSclasstodeterminewhatOSXamarin.Formsisrunningon,thenusedtheTargetPlatformclasstodeterminewhetherourappisbeingrunonGoogle'sAndroidOSplatform.IfourappisrunningonAndroid,wesettheAppconstructormethodsMainPagetoanewinstanceoftheContentPagethatwillsimplyusetheSplashPageastherootpage.Alternatively,wecreateanewinstanceoftheNavigationPageclassandsetthistoourWalksPagetobethemaincontentrootpageforourContentPage.

Page 64: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

DifferencesbetweenXamarinStudioandVisualStudioWhendevelopingcross-platformmobileapps,youcurrentlyhaveachoiceofusingeitherXamarinStudioorMicrosoft'sVisualStudiodevelopmentenvironments.Itisworthnotingthat,althoughthescreenshotsandexamplecodeusedthroughoutthisbookhavebeendevelopedusingXamarinStudiorunningonanAppleMacintoshcomputer,thecodeshouldcompilefineonaWindowsmachinerunningMicrosoftVisualStudio2015.

However,therearesomedifferencesthatyouneedtobeawareofbeforeembarkingonthejourneyofbuildingyourmobiledevelopmentsolutions.IfyouarerunningXamarinStudioonaWindowsmachine,youwillgetanAndroidprojectsolutionwheneveryoucreateanewXamarin.Formssolution.

IfyouwanttointegrateanddevelopappsforWindowsPhone,youwillneedtoensurethatyouarerunningMicrosoftVisualStudioonaWindowsmachine.WhendevelopingappsforiOSapplications,youwillneedtoprepareyourMactobetheXamarinbuildhostbyfirstlyenablingRemoteLoginonyourMacwithintheSystemPreferencessection,andthenselectingtheMactobethebuildhostfromwithintheMicrosoftVisualStudioenvironmentonyourWindowsmachine.

Note

FormoreinformationonhowtoprepareyourMactobetheXamarinbuildhost,refertotheXamarindeveloperdocumentationathttps://developer.xamarin.com/guides/ios/getting_started/installation/windows/connecting-to-mac/.

NowthatyouhaveanunderstandingofthedifferencesbetweenXamarinStudioandMicrosoftVisualStudio,ournextstepistocompile,buildandruntheTrackMyWalksapplicationwithintheiOSsimulator.

Page 65: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

RunningtheTrackMyWalksappusingthesimulatorInthissection,wewilltakealookathowtocompileandruntheTrackMyWalksapplication.Youhavetheoptionofchoosingtorunyourapplicationusinganactualdevice,orchoosingfromalistofsimulatorsavailableforaniOSdevice.

TheversionnumberofthesimulatorisdependentontheversionoftheiOSSDKthatisinstalledonyourcomputer.Performthefollowingsteps:

1. Toruntheapp,chooseyourpreferreddevicefromthelistofavailableiOSsimulatorsandselecttheRunmenuoption,asshowninthefollowingscreenshot:

2. Next,choosetheRunWithsub-menuitem,andthenchoosetheCustomConfiguration...thenclickontheRunbuttonfromtheCustomParametersdialog,asshowninthefollowingscreenshot:

Page 66: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Alternatively,youcanalsobuildandruntheTrackMyWalksapplicationbypressingCommand+Returnkeycombinations.

Whenthecompilationiscomplete,theiOSsimulatorwillappearautomaticallyandtheTrackMyWalksapplicationwillbedisplayed,asshowninthefollowingscreenshot:

Page 67: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,thiscurrentlydisplaysalistofstaticwalktrailentries,thataredisplayedwithinourListView.WhentheuserclicksontheAddWalkbuttonlink,thiswilldisplaythenewWalkEntrycontentpage,sotheycanbeginenteringnewWalktrailinformation.

Currently,thispagedoesn'tsaveenteredinformation,butasweprogressthroughoutthisbook,wewillberefactoringthesepagestoallowforthistohappen.UponclickingtheSavebutton,theuserwillberedirectedbacktothemainTrackMyWalkspage.

Page 68: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Theprecedingscreenshotshowsyouthenavigationflowbetweeneachofthepageswhenatrailhasbeenselectedfromthelist,withthefinalscreenshowingthedistancetravelledpagealongwiththeplaceholderpinmarkershowingthetraillocationwithinthemapview.

Congratulations,youhavesuccessfullybuiltthefoundationfortheTrackMyWalksapplication,aswellastheuserinterfaceforeachofthecontentpagesthatwillbeusedbyourapp.Asweprogressthroughthisbook,wewillbeenhancingourapptoincludebetterarchitecturaldesignpatterns,nicerlookinguserinterfaceelements,aswellasreal-timedatabeingsynchronizedthroughtheuseofRESTfulwebserviceAPIs.

Page 69: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapterweexploredhowtogoaboutcreatingaXamarin.Formscross-platformapplicationforbothiOSandAndroidplatforms.Wethenmovedontobuildingaseriesofcontentpageswithstaticdata.

Next,welookedathowtousethedefaultXamarin.FormsnavigationAPIstohelpmovebetweeneachofthecontentpages,whichwewillrefactorquiteabitwhenwecoverthisinChapter3,NavigatingwithintheMVVMModel-TheXamarin.FormsWaytouseamoreflexible,customizednavigationservice.Finally,wetalkedaboutsomeofthedifferencesbetweenusingXamarinStudioandMicrosoftVisualStudiofordevelopment,beforerunningourTrackMyWalksappwithinthesimulator.

Inthenextchapter,youwilllearnabouttheconceptsbehindtheModel-View-View-Model(MVVM)patternarchitecture,howtoimplementtheMVVMmodelwithinyourapplication,andtheprocessofhowtoaddnewViewModelstoyourXamarinsolution.

Page 70: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter2.MVVMandDataBindingInthepreviouschapter,weexploredhowtogoaboutcreatinganativeXamarin.Formscross-platformapplicationforboththeiOSandAndroidplatforms,andlearnedhowtoaddnewpackagestoyoursolutionusingtheNuGetpackagemanager.WealsolookedathowtogoaboutaddingandcreatingseveralContentPagestoyoursolution,aswellashowtorunandtestyourappwithinthesimulator.

TheModel-View-ViewModel(MVVM)architecturalpatternwasinventedwiththeExtensibleApplicationMarkupLanguage(XAML)inmindthatwascreatedbyMicrosoftbackin2008andisparticularlywellsuitedforusewiththeMVVMapplicationarchitecturalpattern,becauseitenforcesaseparationoftheXAMLuserinterfacefromtheunderlyingdatamodelthroughaclassthatwillactasaconnectionbetweenboththeViewandtheModel.TheViewandtheViewModelcanthenbeconnectedthroughdatabindingsthathavebeendefinedwithintheXAMLfile.

XAMLhasalsobeenintegratedintotheXamarin.Formsplatformthatallowsforthecreationofcross-platform,natively-basedprogramminginterfacesforiOS,Android,andWindowsPhonemobiledevices.ThisallowsdeveloperstodefineuserinterfacesusingalltheXamarin.Formsviews,layouts,andpages,aswellascustomclasses.

XAMLenforcestheseparationbetweentheapplication'suserinterfacefromtheunderlyingdata,throughaclassthatwillactasthecommunicationlayerbetweentheViewandtheViewModel,whichareconnectedthroughdata-bindingsthataredefinedineithertheXAMLorunderlyingcodefile,alongwiththebindingcontextfortheView,thatpointstoaninstanceoftheViewModel.

ThischapterwillbeginbyintroducingyoutothearchitecturebehindtheMVVMpatternarchitecture,andhowyoucanimplementthesewithinyourapplication,byaddingnewViewsandtheassociatedModels.

You'lllearnhowtocreatetheunderlyingC#classfilesthatwillactastheViewModelsforourapp,aswellasupdatingtheexistingcontentpagestodata-bindwiththeViewModelstorepresenttheinformationthatwillbedisplayedwithintheuser-interfaceforourapplication.

Thischapterwillcoverthefollowingpoints:

UnderstandingtheMVVMpatternarchitectureanddata-bindingImplementingtheMVVMbasemodelwithintheTrackMyWalkssolutionImplementingtheMVVMViewModelswithintheappImplementingtheMVVMdata-bindingstoouruserinterfacepages

Page 71: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UnderstandingtheMVVMpatternarchitectureInthissectionwewillbetakingalookattheMVVMpatternarchitectureandthecommunicationbetweenthecomponentsthatmakeupthearchitecture.

TheMVVMdesignpatternisdesignedtocontroltheseparationbetweentheuserinterfaces(views),theViewModelsthatcontaintheactualbindingtotheModel,andthemodelsthatcontaintheactualstructureoftheentitiesrepresentinginformationstoredonadatabaseorfromawebservice.

ThefollowingscreenshotshowsthecommunicationbetweeneachofthecomponentscontainedwithintheMVVMdesignpatternarchitecture:

TheMVVMdesignpatternisdividedintothreemainareas,asyoucanseefromtheprecedingscreenshot,andtheseareexplainedinthefollowingtable:

MVVMtype Description

ModelTheModelisbasicallyarepresentationofbusinessrelatedentitiesusedbyanapplication,andisresponsibleforfetchingdatafromeitheradatabase,orwebservice,andthende-serializedtotheentitiescontainedwithintheModel.

View

TheViewcomponentoftheMVVMmodelbasicallyrepresentstheactualscreensthatmakeuptheapplication,alongwithanycustomcontrolcomponents,andcontrolelements,suchasbuttons,labels,andtextfields.

TheviewscontainedwithintheMVVMpatternareplatform-specificandaredependentontheplatformAPIsthatareusedtorendertheinformationthatis

Page 72: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

containedwithintheapplication'suserinterface.

ViewModel

TheViewModelessentiallycontrols,andmanipulatestheviewsbyactingastheirmaindatacontext.TheViewModelcontainsaseriesofpropertiesthatareboundtotheinformationcontainedwithineachModel.Thosepropertiesarethenboundtoeachoftheviewstorepresentthisinformationwithintheuserinterface.

ViewModelscanalsocontaincommandobjectsthatprovideaction-basedeventsthatcantriggertheexecutionofeventmethodsthatoccurwithintheView.Forexample,whentheusertapsonatoolbaritem,orabutton.

ViewModelsgenerallyimplementtheINotifyPropertyChangedandINotifyCollectionChangedinterfaces.SuchaclassfiresaPropertyChangedandINotifyCollectionChangedeventwheneveracollectionhaschanged(suchas,addinganitem,removinganitem,orwhenachangeoccurstooneoftheitems,properties)changes.ThedatabindingmechanisminXamarin.FormsattachesahandlertothisPropertyChangedandCollectionChangedeventssoitcanbenotifiedwhenapropertychangesandkeepthetargetupdatedwiththenewvalue.

NowthatyouhaveagoodunderstandingofthecomponentsthatarecontainedwithinMVVMdesignpatternarchitecture,wecanbegintocreateourentitymodelsandupdateouruserinterfacefiles.

Note

InXamarin.Forms,thetermViewisusedtodescribeformcontrols,suchasbuttonsandlabels,andusesthetermPagetodescribetheuserinterfaceorscreen.Whereas,inMVVM,Viewsareusedtodescribetheuserinterface,orscreen.

Page 73: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingtheMVVMViewModelswithinyourappInthissection,wewillbeginbysettingupthebasicstructureforourTrackMyWalkssolutiontoincludethefolderthatwillbeusedtorepresentourViewModels.Let'stakealookatthefollowingstepstoachievethis:

1. LaunchtheXamarinStudioapplicationandensurethattheTrackMyWalkssolutionisloadedwithintheXamarinStudioIDE.

2. Next,createanewfolderwithintheTrackMyWalksPCLproject,calledViewModelsasshowninthefollowingscreenshot:

Page 74: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheWalkBaseViewModelfortheTrackMyWalksappInthissection,wewillbeginbycreatingabaseMVVMViewModelthatwillbeusedbyeachofourViewModelswhenwecreatethese,theViews(pages)willthenimplementthoseViewModelsandusethemastheirBindingContext.

Tip

WewillstartbycreatingabaseViewModelclassthatwillessentiallybeanabstractclass,containingbasicfunctionalitythateachofourViewModelswillinheritfrom,andwillimplementtheINotifyPropertyChangedInterface.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. CreateanemptyclasswithintheViewModelsfolder,showninthefollowingscreenshot:

2. Next,choosetheEmptyClassoptionlocatedwithintheGeneralsection,andenterinWalkBaseViewModelforthenameofthenewclassfiletobecreated,asshowninthefollowingscreenshot:

Page 75: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyclassfile,asshownintheprecedingscreenshot.

Upuntilthispoint,allwehavedoneiscreateourWalkBaseViewModelclassfile.ThisabstractclasswillactasthebaseViewModelclassthatwillcontainthebasicfunctionalitythateachofourViewModelswillinheritfrom.

Aswestarttobuildthebaseclass,youwillseethatitcontainsacoupleofmembersanditwillimplementtheINotifyPropertyChangedInterface.Asweprogressthroughthisbook,wewillbuildtothisclass,whichwillbeusedbytheTrackMyWalksapplication.ToproceedwithcreatingthebaseViewModelclass.

EnsurethattheWalkBaseViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//WalkBaseViewModel.cs

//TrackMyWalksBaseViewModel

Page 76: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.ComponentModel;

usingSystem.Runtime.CompilerServices;

namespaceTrackMyWalks.ViewModels

{

publicabstractclassWalkBaseViewModel:

INotifyPropertyChanged

{

protectedWalkBaseViewModel()

{

}

publiceventPropertyChangedEventHandlerPropertyChanged;

protectedvirtualvoidOnPropertyChanged

([CallerMemberName]stringpropertyName=null)

{

varhandler=PropertyChanged;

if(handler!=null)

{

handler(this,newPropertyChangedEventArgs(propertyName));

}

}

}

}

Intheprecedingcodesnippet,webeginbycreatinganewabstractclassforourWalkBaseViewModelthatimplementsfromtheINotifyPropertyChangedinterfaceclass,whichallowstheVieworpagetobenotifiedwheneverpropertiescontainedwithintheViewModelhavechanged.Next,wedeclareavariablePropertyChangedthatinheritsfromthePropertyChangedEventHandlerthatwillbeusedtoindicatewheneverpropertiesontheobjecthavechanged.Finally,withintheOnPropertyChangedmethod,thiswillbecalledwhenithasdeterminedthatachangehasoccurredonapropertywithintheViewModelfromachildclass.

Note

TheINotifyPropertyChangedinterfaceisusedtonotifyclients,typicallybindingclients,whenthevalueofapropertyhaschanged.

Page 77: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingtheWalksPageViewModelIntheprevioussection,webuiltourbaseclassViewModelforourTrackMyWalksapplication.ThiswillactasthemainclassthatwillallowourVieworpagestobenotifiedwheneverchangestopropertieswithintheViewModelhavebeenmade.

Inthissection,wewillneedtobeginbuildingtheViewModelforourWalksPage.ThismodelwillbeusedtostoretheWalkEntries,whichwilllaterbeusedanddisplayedwithintheListViewontheWalksPagecontentpage.

Let'stakealookathowwecanachievethisbyfollowingthesesteps:

1. First,createanewclassfilewithintheViewModelsfoldercalledWalksPageViewModel,asyoudidintheprevioussection,entitledCreatingtheWalkBaseViewModellocatedwithinthischapter.

2. Next,ensurethattheWalksPageViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//WalksPageViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Collections.ObjectModel;

usingTrackMyWalks.Models;

namespaceTrackMyWalks.ViewModels

{

publicclassWalksPageViewModel:WalkBaseViewModel

{

ObservableCollection<WalkEntries>_walkEntries;

publicObservableCollection<WalkEntries>walkEntries

{

get{return_walkEntries;}

set{_walkEntries=value;

OnPropertyChanged();

}

}

Intheprecedingcodesnippet,webeginbyensuringthatourViewModelinheritsfromtheWalkBaseViewModelclass.Next,wecreateanObservableCollectionvariable_walkEntrieswhichisveryusefulwhenyouwanttoknowwhenthecollectionhaschanged,andaneventistriggeredthatwilltelltheuserwhatentrieshavebeenaddedorremovedfromtheWalkEntriesmodel.

Inournextstep,wecreatetheObservableCollectionconstructorWalkEntries,thatisdefinedwithintheSystem.Collections.ObjectModelclass,andacceptsaList

Page 78: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

parametercontainingourWalkEntriesmodel.TheWalkEntriespropertywillbeusedtobindtotheItemSourcepropertyoftheListViewwithintheWalksMainPage.Finally,wedefinethegetter(get)andsetter(set)methodsthatwillreturnandsetthecontentofour_walkEntrieswhenithasbeendeterminedwhetherapropertyhasbeenmodifiedornot.

3. Next,locatetheWalksPageViewModelclassconstructor,andenterthefollowinghighlightedcodesections:

publicWalksPageViewModel()

{

walkEntries=newObservableCollection<WalkEntries>(){

newWalkEntries{

Title="10MileBrookTrail,MargaretRiver",

Notes="The10MileBrookTrailstartsinthe

RotaryParknearOldKate,apreservedsteam"+

"engineatthenorthernedgeofMargaretRiver.",

Latitude=-33.9727604,

Longitude=115.0861599,

Kilometers=7.5,

Distance=0,

Difficulty="Medium",

ImageUrl="http://trailswa.com.au/media/

cache/media/images/trails/_mid/"+

"FullSizeRender1_600_480_c1.jpg"

},

newWalkEntries{

Title="AncientEmpireWalk,ValleyoftheGiants",

Notes="TheAncientEmpireisa450metrewalktrail

thattakesyouaroundandthroughsomeof"+

"thegianttingletreesincludingthemostpopularof

thegnarledveterans,knownas"+"GrandmaTingle.",

Latitude=-34.9749188,

Longitude=117.3560796,

Kilometers=450,

Distance=0,

Difficulty="Hard",

ImageUrl="http://trailswa.com.au/media/cache/media/

images/trails/_mid/"+"Ancient_Empire_534_480_c1.jpg"

},

};

}

}

}

Intheprecedingcodesnippet,webeganbycreatinganewObservableCollectionforourwalkEntriesmethodandthenaddedeachofthewalklistitemsthatwewouldliketostorewithinourModel.Aseachitemisadded,theObservableCollection,constructoriscalled,andthesetter(set)methodisinvokedtoaddtheitem,thentheINotifyPropertyChangedeventwillbetriggeredtonotifythatachangehasoccurred.

Page 79: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthewalksmainpagetousetheMVVMmodelNowthatwehavecreatedtheMVVMViewModelthatwillbeusedforourmainWalksPage,weneedtomodifytheWalksmainpage.Inthissection,wewillbetakingalookathowtobindtheWalksPageBindingContexttotheWalksPageViewModelsothatthewalkentrydetailscanbedisplayed.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. EnsurethattheWalksPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Collections.Generic;

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage

{

publicWalksPage()

{

varnewWalkItem=newToolbarItem

{

Text="AddWalk"

};

//Setupourclickeventhandler

newWalkItem.Clicked+=(sender,e)=>

{

Navigation.PushAsync(newWalkEntryPage());

};

//AddtheToolBaritemtoourToolBar

ToolbarItems.Add(newWalkItem);

2. Next,weneedtodeclareandcreateanewBindingContextinstancefortheWalksPage,andsetthistoanewinstanceoftheWalksPageViewModelsothatitknowswheretogettheWalkEntriessothatwecanpopulatethesewithintheListView.Proceedandenterinthefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

BindingContext=newWalksPageViewModel();

Page 80: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//DefineourItemTemplate

varitemTemplate=newDataTemplate(typeof(ImageCell));

itemTemplate.SetBinding(TextCell.TextProperty,"Title");

itemTemplate.SetBinding(TextCell.DetailProperty,"Notes");

itemTemplate.SetBinding(ImageCell.ImageSourceProperty,

"ImageUrl");

3. Then,changethewayinwhichourListViewgetstheWalkEntriesvariableitems,byupdatingtheListViewclassandsettingthebindingpropertyforthewalkentries,byinitializingtheItemsView<Cell>.ItemsSourcePropertypropertyandusingtheSetBindingmethodtobindthecontents.Proceedandenterinthefollowinghighlightedcodesections:

varwalksList=newListView

{

HasUnevenRows=true,

ItemTemplate=itemTemplate,

SeparatorColor=Color.FromHex("#ddd"),

};

//SettheBindingpropertyforourwalksEntries

walksList.SetBinding(ItemsView<Cell>.ItemsSourceProperty,

"walkEntries");

//InitializeoureventHandlertousewhentheitemistapped

walksList.ItemTapped+=(objectsender,ItemTappedEventArgse)=>

{

varitem=(WalkEntries)e.Item;

if(item==null)return;

Navigation.PushAsync(newWalkTrailPage(item));

item=null;

};

Content=walksList;

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingourWalksPagesothatitcantakeadvantageofourWalksPageViewModel.WelookedathowtosetourcontentpagetoaninstanceofourWalksPageViewModelsothatitknowswheretogetthelistofwalkentriestobeusedanddisplayedwithintheListViewcontrol.TheSetBindingpropertycreatesandappliesabindingtoaspecificproperty.Asyoucansee,byusingViewModelswithinyourapplication,youcanseethattheresultisbothcleanandelegant,andmakesyourcodealotmorereadablewhensupportingcodemodifications.

Page 81: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingthewalksentrypageViewModelWehavecreatedtheViewModelthatwillbeusedbyourWalksPagesothatthewalkentriescanbedisplayedwithintheListViewcontrol.ThenextstepistobuildtheViewModelthatwillbeusedtocreatenewwalkentriesandhavethisinformationsavedbacktoourWalkBaseViewModel,whichwewillbecoveringinalaterchapterasweprogressthroughthisbook.

Inthissection,wewillbetakingalookatthestepsrequiredtocreatetheViewModelforourWalksEntryViewModelsothatwecaninitialize,andcaptureinformationenteredwithinthisscreen.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. CreateanewclassfilewithintheViewModelsfoldercalledWalksEntryViewModel,asyoudidintheprevioussection,entitledCreatingtheWalkBaseViewModellocatedwithinthischapter.

2. Next,ensurethattheWalksEntryViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet.

//

//WalkEntryViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassWalkEntryViewModel:WalkBaseViewModel

{

3. Then,createthefollowingTitlepropertyanditsassociatedgettersandsetterqualifiers.TheOnPropertyChangedmethod,aswementionedpreviously,willbecalledwhenourpropertydeterminesthatthecontentshavebeenchanged.AcallismadetotheSaveCommand.ChangeCanExecutemethodthatwillvalidatetheformfields,andthendeterminewhethertheSaveToolBarItemshouldbeenabledornottoallowtheusertosavethewalkentrydetails.Proceedandenterinthefollowingcodesnippet:

string_title;

publicstringTitle

{

get{return_title;}

set

{

_title=value;

OnPropertyChanged();

Page 82: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SaveCommand.ChangeCanExecute();

}

}

4. Next,createtheremainingViewModelpropertiesandtheassociatedgettersandsetterqualifiersthatwillbeusedtobindthevaluesenteredontheWalkEntryPage,asshowninthefollowingcodesnippets:

string_notes;

publicstringNotes

{

get{return_notes;}

set

{

_notes=value;

OnPropertyChanged();

}

}

double_latitude;

publicdoubleLatitude

{

get{return_latitude;}

set

{

_latitude=value;

OnPropertyChanged();

}

}

double_longitude;

publicdoubleLongitude

{

get{return_longitude;}

set

{

_longitude=value;

OnPropertyChanged();

}

}

double_kilometers;

publicdoubleKilometers

{

get{return_kilometers;}

set

{

_kilometers=value;

OnPropertyChanged();

}

}

string_difficulty;

publicstringDifficulty

{

get{return_difficulty;}

Page 83: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

set

{

_difficulty=value;

OnPropertyChanged();

}

}

double_distance;

publicdoubleDistance

{

get{return_distance;}

set

{

_distance=value;

OnPropertyChanged();

}

}

string_imageUrl;

publicstringImageUrl

{

get{return_imageUrl;}

set

{

_imageUrl=value;

OnPropertyChanged();

}

}

5. Next,weneedtoinitializeourViewModelclassconstructorwithdefaultvaluesforourTitle,DifficultyandDistanceproperties.LocatetheWalkEntryViewModelclassconstructor,andenterthefollowinghighlightedcodesections:

publicWalkEntryViewModel()

{

Title="NewWalk";

Difficulty="Easy";

Distance=1.0;

}

6. Then,weneedtocreateaCommandpropertyforourclass.ThiswillbeusedwithinourWalkEntryPageandwillbeusedtobindtotheSaveToolBarItem.TheCommandpropertywillrunanactionuponbeingpressed,thenexecuteaclassinstancemethodtodeterminewhetherthecommandcanbeexecuted.Proceedandenterthefollowinghighlightedcodesections:

Command_saveCommand;

publicCommandSaveCommand

{

get

{

return_saveCommand??(_saveCommand=new

Command(ExecuteSaveCommand,ValidateFormDetails));

}

Page 84: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

7. Next,weneedtocreatetheExecuteSaveCommandinstancemethod.Thiswillbeusedtostorethewalkinformationthatweenter,whichwillbewrittentoeachofthepropertiesasdefinedwithintheWalkEntriesmodel.Thesavingportionwillnotbecoveredinthischapter,asthiswillbecoveredinalaterchapter.Fornow,proceedandenterinthefollowinghighlightedcodesections:

voidExecuteSaveCommand()

{

varnewWalkItem=newWalkEntries

{

Title=this.Title,

Notes=this.Notes,

Latitude=this.Latitude,

Longitude=this.Longitude,

Kilometers=this.Kilometers,

Difficulty=this.Difficulty,

Distance=this.Distance,

ImageUrl=this.ImageUrl

};

//Here,wewillsavethedetailsenteredinalaterchapter.

}

8. Finally,createtheValidateFormDetailsinstancemethod.Thiswillbeusedtodeterminewhetherornotwecansaveournewwalkinformation.Thismethodisprettybasic,butyoucouldaddadditionalchecksdependingonyourneeds.Forthisexample,we'llusetheIsNullOrWhiteSpacemethodonthestringclass,andpassintheTitleproperty,whichcheckstoseeiftheTitlepropertycontainsanyblankspaces,orisanemptyfield.Toproceed,enterinthefollowinghighlightedcodesection:

//methodtocheckforanyformerrors

boolValidateFormDetails()

{

return!string.IsNullOrWhiteSpace(Title);

}

}

}

Inthissection,webeganbyensuringthatourViewModelinheritsfromtheWalkBaseViewModelclassandthenmovedontocreateaTitlepropertyanditsassociatedgettersandsetterqualifiers.WealsocreatedtheOnPropertyChangedmethod,aswedefinedpreviouslysothatitwillbecalledwhenthepropertydeterminesthatthecontentshavebeenchanged.

Next,weaddedareferencetothemethodSaveCommand.ChangeCanExecutethatwillvalidatetheformfieldstodetermineiftheSaveToolBarItemshouldbeenabledtoallowtheusertosavethewalkentrydetails.WethencreatedtheremainingpropertiesforourViewModelwiththeirassociatedgettersandsetters,whichwillbeusedtobindthevaluesenteredontheWalkEntryPage.

Page 85: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Inthenextsteps,weinitializedtheclassconstructorwithdefaultvaluesfortheTitle,DifficultyandDistancepropertiesandthencreatedaCommandpropertytoourclasssothatitcanbeusedwithintheWalkEntryPageandwillbeusedtobindtotheSaveToolBarItem.

Finally,weneededtocreatetheExecuteSaveCommandinstancemethodsothatitcanstoreourwalkinformationtoeachofthepropertiesasdefinedwithintheWalkEntriesmodel.

Page 86: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksEntryPagetousetheMVVMmodelInthissection,weneedtobindourmodelbindingcontextBindingContexttotheWalkEntryViewModelsothatthenewwalkinformationthatwillbeenteredwithinthispagecanbestoredwithintheWalkEntriesmodel.Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. EnsurethattheWalkEntryPage.csfileisdisplayedwithinthecodeeditor.

//

//WalkEntryPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingSystem.Collections.Generic;

namespaceTrackMyWalks

{

publicclassWalkEntryPage:ContentPage

{

publicWalkEntryPage()

{

//SettheContentPageTitle

Title="NewWalkEntry";

2. Next,weneedtodeclareandcreateanewBindingContextinstancefortheWalksEntryPage,andsetthistoanewinstanceoftheWalkEntryViewModelsothatitknowswheretogettheWalkEntriessothatwecanbindittotheassociatedpropertiescontainedwithinourmodel.Proceedandenterinthefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

BindingContext=newWalkEntryViewModel();

3. Next,createtheremainingEntryCellobjects,aswellastheSetBindingpropertiestotheirmatchedpropertynameascontainedwithintheViewModel,asshowninthefollowingcodesnippets:

//DefineourNewWalkEntryfields

varwalkTitle=newEntryCell

{

Label="Title:",

Placeholder="TrailTitle"

};

walkTitle.SetBinding(EntryCell.TextProperty,"Title",

BindingMode.TwoWay);

varwalkNotes=newEntryCell

{

Label="Notes:",

Placeholder="Description"

Page 87: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

};

walkNotes.SetBinding(EntryCell.TextProperty,"Notes",

BindingMode.TwoWay);

varwalkLatitude=newEntryCell

{

Label="Latitude:",

Placeholder="Latitude",

Keyboard=Keyboard.Numeric

};

walkLatitude.SetBinding(EntryCell.TextProperty,

"Latitude",BindingMode.TwoWay);

varwalkLongitude=newEntryCell

{

Label="Longitude:",

Placeholder="Longitude",

Keyboard=Keyboard.Numeric

};

walkLongitude.SetBinding(EntryCell.TextProperty,

"Longitude",BindingMode.TwoWay);

varwalkKilometers=newEntryCell

{

Label="Kilometers:",

Placeholder="Kilometers",

Keyboard=Keyboard.Numeric

};

walkKilometers.SetBinding(EntryCell.TextProperty,

"Kilometers",BindingMode.TwoWay);

varwalkDifficulty=newEntryCell

{

Label="DifficultyLevel:",

Placeholder="WalkDifficulty"

};

walkDifficulty.SetBinding(EntryCell.TextProperty,

"Difficulty",BindingMode.TwoWay);

varwalkImageUrl=newEntryCell

Label="ImageUrl:",

Placeholder="ImageURL"

};

walkImageUrl.SetBinding(EntryCell.TextProperty,

"ImageUrl",BindingMode.TwoWay);

//DefineourTableView

Content=newTableView

{

Intent=TableIntent.Form,

Root=newTableRoot

{

newTableSection()

{

walkTitle,

Page 88: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

walkNotes,

walkLatitude,

walkLongitude,

walkKilometers,

walkDifficulty,

walkImageUrl

}

}

};

varsaveWalkItem=newToolbarItem

{

Text="Save"

};

saveWalkItem.SetBinding(MenuItem.CommandProperty,

"SaveCommand");

ToolbarItems.Add(saveWalkItem);

saveWalkItem.Clicked+=(sender,e)=>

{

Navigation.PopToRootAsync(true);

};

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingourWalksEntryPagesothatitcantakeadvantageofourWalksEntryViewModel.WelookedathowtosetthecontentpagetoaninstanceoftheWalksEntryViewModelsothatitpointstotheWalkEntriesmodel.WethenusedtheSetBindingmethodoneachofourEntryCellssothatitcanbindtotheappropriateViewModelproperty.Finally,weupdatedtheSaveToolbarItemontheWalkEntryPagetobindtotheWalksEntryViewModelSaveCommandproperty.

Thefollowingtableprovidesabriefdescriptionofthedifferentbindingtypes,andwhentheseshouldbeusedwithinyourapplications:

Bindingmode Description

OneWayThistypeofbindingindicatesthatthebindingshouldonlypropagatechangesfromsource(usuallytheViewModel)totarget(theBindableObject).ThisisthedefaultmodeformostBindablePropertyvalues.

OneWayToSourceThistypeofbindingindicatesthatthebindingonlypropagateschangesfromthetargetBindableObjecttotheViewModelandismainlyusedforread-onlyBindablePropertyvalues.

Page 89: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TwoWayThistypeofbindingindicatesthatthebindingshouldpropagatethechangesfromtheViewModeltothetargetBindableObjectinbothdirections.

Onethingtonoticeisthat,ifyoudon'tspecifyavaluefortheBindingModeproperty,itwillusethedefaultBindingMode.OneWaywhichisdefinedintheBindableProperty.DefaultBindingModeproperty.

Page 90: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingthewalktrailpageViewModelInthissection,wewillbetakingalookatthestepsrequiredtocreatetheViewModelforourWalksTrailViewModelsothatwecanobtainthewalkentryinformationassociatedwiththechosenwalkthathasbeenselectedfromthemainWalksPage.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. CreateanewclassfilewithintheViewModelsfoldercalledWalksTrailViewModel,asyoudidintheprevioussectionentitledCreatingtheWalkBaseViewModel,locatedwithinthischapter.

2. Next,ensurethattheWalksTrailViewModel.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//WalksTrailViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.Models;

namespaceTrackMyWalks.ViewModels

{

publicclassWalksTrailViewModel:WalkBaseViewModel

{

WalkEntries_walkEntry;

publicWalkEntriesWalkEntry

{

get{return_walkEntry;}

set

{

_walkEntry=value;

OnPropertyChanged();

}

}

publicWalksTrailViewModel(WalkEntrieswalkEntry)

{

WalkEntry=walkEntry;

}

}

}

Inthissection,webeganbyensuringthatourViewModelinheritsfromtheWalkBaseViewModelclassandthenwecreatedanWalkEntriesvariable_walkEntriesthatwillbeusedtostoreourWalkEntries.Next,wecreatedaWalkEntrypropertyanditsassociatedgettersandsetter

Page 91: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

qualifiersandtheOnPropertyChangedmethod,sothatitwillbecalledwhenourpropertydeterminesthatthecontentshavebeenchanged.Inthefinalstep,wecreatedtheWalksTrailViewModelconstructor,thatacceptsaListparametercontainingourWalkEntriesmodel.

Page 92: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksTrailPagetousetheMVVMmodelInthissectionweneedtobindourmodelbindingcontextBindingContexttotheWalksTrailViewModelsothatthewalkinformationdetailswillbedisplayedfromtheWalkEntriesmodelwhenawalkhasbeenclickedonwithinthemainWalksPage.Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. EnsurethattheWalkTrailPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalkTrailPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

namespaceTrackMyWalks

{

publicclassWalkTrailPage:ContentPage

{

publicWalkTrailPage(WalkEntrieswalkItem)

{

Title="WalksTrail";

2. Next,weneedtodeclareandcreateanewBindingContextinstancefortheWalksTrailPage,andsetthistoanewinstanceoftheWalksTrailViewModelsothatitknowswheretogettheWalkEntriessothatwecanbindittotheassociatedpropertiescontainedwithinourModelanddisplaythiswithintheView.Proceedandenterthefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

BindingContext=newWalksTrailViewModel(walkItem);

varbeginTrailWalk=newButton

{

BackgroundColor=Color.FromHex("#008080"),

TextColor=Color.White,

Text="BeginthisTrail"

};

//DeclareandinitializeourEventHandler

beginTrailWalk.Clicked+=(sender,e)=>

{

if(walkItem==null)return;

Navigation.PushAsync(newDistanceTravelled(walkItem));

Navigation.RemovePage(this);

walkItem=null;

};

Page 93: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Next,createtheremainingImageandLabelcontrolobjects,aswellastheSetBindingpropertiestotheirmatchedpropertynameascontainedwithintheViewModel,asshowninthefollowingcodesnippets:

varwalkTrailImage=newImage()

{

Aspect=Aspect.AspectFill

};

walkTrailImage.SetBinding(Image.SourceProperty,

"WalkEntry.ImageUrl");

vartrailNameLabel=newLabel()

{

FontSize=28,

FontAttributes=FontAttributes.Bold,

TextColor=Color.Black

};

trailNameLabel.SetBinding(Label.TextProperty,

"WalkEntry.Title");

vartrailKilometersLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.Black,

};

trailKilometersLabel.SetBinding(Label.TextProperty,

"WalkEntry.Kilometers",stringFormat:"Length:{0}km");

vartrailDifficultyLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.Black

};

trailDifficultyLabel.SetBinding(Label.TextProperty,

"WalkEntry.Difficulty",stringFormat:"Difficulty:{0}");

vartrailFullDescription=newLabel()

{

FontSize=11,

TextColor=Color.Black,

HorizontalOptions=LayoutOptions.FillAndExpand

};

trailFullDescription.SetBinding(Label.TextProperty,

"WalkEntry.Notes");

this.Content=newScrollView

{

Padding=10,

Content=newStackLayout

{

Orientation=StackOrientation.Vertical,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children=

Page 94: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

walkTrailImage,

trailNameLabel,

trailKilometersLabel,

trailDifficultyLabel,

trailFullDescription,

beginTrailWalk

}

}

};

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingourWalksTrailPagesothatitcantakeadvantageoftheWalksTrailViewModel.WelookedathowtosetthecontentpagetoaninstanceofourWalksTrailViewModelsothatitknowswheretogetthelistofwalkentriestobeusedanddisplayedwithinourStackLayoutcontrol.WeusedtheSetBindingpropertytocreateandbindeachofourmodelvaluestoaspecificproperty.

Finally,wedefinedaScrollViewcontrol,thenaddedeachofourformImageandLabelfieldstotheStackLayoutcontrol.

Page 95: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingtheDistanceTravelledViewModelInthissection,wewillbetakingalookatthestepsrequiredtocreatetheViewModelforourDistTravelledViewModelsothatwecancalculatehowlongthechosenwalkfromthemainWalksPagetooktocomplete.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. CreateanewclassfilewithintheViewModelsfoldercalledDistTravelledViewModel,asyoudidintheprevioussectionentitledCreatingtheWalkBaseViewModel,locatedwithinthischapter.

2. Next,ensurethattheDistTravelledViewModel.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//DistTravelledViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

namespaceTrackMyWalks.ViewModels

{

publicclassDistTravelledViewModel:WalkBaseViewModel

{

WalkEntries_walkEntry;

3. Then,createthefollowingWalkEntrypropertyanditsassociatedgettersandsetterqualifiers.TheOnPropertyChangedmethod,aswementionedpreviously,willbecalledwhenourpropertydeterminesthatthecontentshavebeenchanged.Proceedandenterinthefollowingcodesnippet:

publicWalkEntriesWalkEntry

{

get{return_walkEntry;}

set

{

_walkEntry=value;

OnPropertyChanged();

}

}

4. Next,createtheremainingViewModelpropertiesandtheassociatedgettersandsetterqualifiersthatwillbeusedtobindthevaluesenteredontheDistanceTravelledPage,asshowninthefollowingcodesnippets:

double_travelled;

publicdoubleTravelled

{

Page 96: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

get{return_travelled;}

set

{

_travelled=value;

OnPropertyChanged();

}

}

double_hours;

publicdoubleHours

{

get{return_hours;}

set

{

_hours=value;

OnPropertyChanged();

}

}

double_minutes;

publicdoubleMinutes

{

get{return_minutes;}

set

{

_minutes=value;

OnPropertyChanged();

}

}

double_seconds;

publicdoubleSeconds

{

get{return_seconds;}

set

{

_seconds=value;

OnPropertyChanged();

}

}

publicstringTimeTaken

{

get

{

returnstring.Format("{0:00}:{1:00}:{2:00}",this.Hours,

this.Minutes,this.Seconds);

}

}

publicDistTravelledViewModel(WalkEntrieswalkEntry)

{

this.Hours=0;

this.Minutes=0;

this.Seconds=0;

this.Travelled=100;

Page 97: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

WalkEntry=walkEntry;

}

}

}

Inthissection,webeganbyensuringthatourViewModelinheritsfromtheWalkBaseViewModelclassandthenwecreatedanWalkEntriesvariable_walkEntriesthatwillbeusedtostoreourWalkEntries.

Next,wecreatedaWalkEntrypropertyanditsassociatedgettersandsetterqualifiersandtheOnPropertyChangedmethod,sothatitwillbecalledwhenourpropertydeterminesthatthecontentshavebeenchanged.

Inourfinalstep,wecreatedtheDistTravelledViewModelconstructor,thatacceptsaListparametercontainingourWalkEntriesmodel,priortoinitializingourclassconstructorwithdefaultvaluesfortheHours,Minutes,Seconds,andTravelledproperties.

Page 98: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheDistanceTravelledPagetousetheMVVMmodelInthissectionweneedtobindourmodelbindingcontextBindingContexttotheDistTravelledViewModelsothatthewalkinformationdetailsandthecalculationsofdistancetravelledwillbedisplayedfromtheWalkEntriesmodel.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. EnsurethattheDistanceTravelledPage.csfileisdisplayedwithinthecodeeditor.

//

//DistanceTravelledPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingXamarin.Forms.Maps;

usingTrackMyWalks.Models;

namespaceTrackMyWalks

{

publicclassDistanceTravelledPage:ContentPage

{

2. Next,weneedtoupdatethemaptogetitsvaluesfromtheDistTravelledViewModelsothatitcorrectlyplotsthesewithinthemapview.WeneedtodothisbecausetheXamarin.Forms.Mapcontroldoesn'tprovidesupportforbindingdirectlytothemap,sowehavetosetthesedirectlywithinourViewModelinstead.Therefore,weneedtocreateaprivate_viewModelvariablewithinthecontentpagetoreturnthevaluefromthepage'sBindingContext.

3. Proceedandenterthefollowinghighlightedcodesections:

DistTravelledViewModel_viewModel

{

get{returnBindingContextasDistTravelledViewModel;}

}

publicDistanceTravelledPage(WalkEntrieswalkItem)

{

Title="DistanceTravelled";

4. Next,createanewBindingContextinstancefortheDistanceTravelledPage,andsetthistoanewinstanceoftheDistTravelledViewModelsothatitknowswheretogettheWalkEntriestobindittotheassociatedpropertiescontainedwithinourmodelanddisplaythiswithintheView.Proceedandenterinthefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

BindingContext=newDistTravelledViewModel(walkItem);

Page 99: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//Instantiateourmapobject

vartrailMap=newMap();

5. Next,updatethemaptograbthenameofthechosenwalkandtheLatitudeandLongitudevaluesfromtheDistTravelledViewModel.Proceedandenterthefollowinghighlightedcodesections:

//Placeapinonthemapforthechosenwalktype

trailMap.Pins.Add(newPin

{

Type=PinType.Place,

Label=_viewModel.WalkEntry.Title,

Position=newPosition(_viewModel.WalkEntry.Latitude,

_viewModel.WalkEntry.Longitude)

});

//Centerthemaparoundthelistofwalksentry'slocation

trailMap.MoveToRegion(MapSpan.FromCenterAndRadius(new

Position(_viewModel.WalkEntry.Latitude,

_viewModel.WalkEntry.Longitude),

Distance.FromKilometers(1.0)));

6. Next,createtheremainingLabelcontrolobjects,aswellastheSetBindingpropertiestotheirmatchedpropertynameascontainedwithintheViewModel,asshowninthefollowingcodesnippets:

vartrailNameLabel=newLabel()

{

FontSize=18,

FontAttributes=FontAttributes.Bold,

TextColor=Color.Black,

HorizontalTextAlignment=TextAlignment.Center

};

trailNameLabel.SetBinding(Label.TextProperty,

"WalkEntry.Title");

vartrailDistanceTravelledLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=20,

TextColor=Color.Black,

HorizontalTextAlignment=TextAlignment.Center

};

trailDistanceTravelledLabel.SetBinding(Label.TextProperty,

"Travelled",stringFormat:"DistanceTravelled:{0}km");

vartotalTimeTakenLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=20,

TextColor=Color.Black,

HorizontalTextAlignment=TextAlignment.Center

};

totalTimeTakenLabel.SetBinding(Label.TextProperty,"TimeTaken",

Page 100: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

stringFormat:"TimeTaken:{0}");

varwalksHomeButton=newButton

{

BackgroundColor=Color.FromHex("#008080"),

TextColor=Color.White,

Text="EndthisTrail"

};

//Setupoureventhandler

walksHomeButton.Clicked+=(sender,e)=>

{

if(walkItem==null)return;

Navigation.PopToRootAsync(true);

walkItem=null;

};

this.Content=newScrollView

{

Padding=10,

Content=newStackLayout

{

Orientation=StackOrientation.Vertical,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children={

trailMap,

trailNameLabel,

trailDistanceTravelledLabel,

totalTimeTakenLabel,

walksHomeButton

}

}

};

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingtheDistanceTraveledPagesothatitcantakeadvantageoftheDistTravelledViewModel.WelookedathowtosetthecontentpagetoaninstanceofourDistTravelledViewModel.WeusedtheSetBindingpropertytocreateandbindeachofourmodelvaluestoaspecificproperty.Finally,wedefinedaScrollViewcontrol,thenaddedeachoftheformImageandLabelfieldstotheStackLayoutcontrol.

NowthatyouhavecreatedalloftheMVVMViewModelsandhaveupdatedtheassociatedcontentpages,ournextstepistofinallybuildandruntheTrackMyWalksapplicationwithintheiOSsimulator.

Whencompilationcompletes,theiOSSimulatorwillappearautomaticallyandtheTrackMyWalksapplicationwillbedisplayed,asshowninthefollowingscreenshot:

Page 101: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,thiscurrentlydisplaysalistofstatictrailentries,thataredisplayedwithintheListView.WhentheuserclicksontheAddWalkbuttonlink,thiswilldisplaytheNewWalkEntrycontentpage.

AsyoucanseefromtheNewWalkEntryscreen,wehavesuccessfullybindedeachoftheEntryCellpropertiestoourWalkEntryViewModelandhavedisplayedthisinformationbesideeachofthecontentpageproperties.IfyouclearouttheinformationassociatedwiththeTitleproperty,youwillnoticethattheSavebuttonwilldim.ThisisbecausetheValidateFormDetailsinstancemethodperformsacheck,thentheSaveCommandcommandeventistriggered,andhandlesitaccordingly.

Page 102: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Theprecedingscreenshotshowsyouthenavigationflowbetweeneachofthepageswhenatrailhasbeenselectedfromthelist,withthefinalscreenshowingtheDistanceTravelledpagealongwiththeplaceholderpinmarkershowingthetraillocationwithinthemapview.

Page 103: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,weupdatedourTrackMyWalksapplicationandcreatedanumberofViewModels.Wethenremovedandmigratedourdataandlogicfromeachofourpages,thenaddedbindingtothosepagessothattheypointdirectlytotheViewModelsassociatedwiththepage.

Inthenextchapter,youwilllearnaboutthedifferentnavigationtechniquesthatcanbeusedwithintheMVVMmodelarchitecture,tonavigatebetweenViewModelsbycreatingandimplementinganavigationservicebetweeneachoftheViews,sothatyoucaneasilynavigatebetweenthem.

Page 104: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter3.NavigatingwithintheMVVMModel-TheXamarin.FormsWayUptothispoint,youhaveseenhowtoincorporatetheMVVMarchitecturalpatternintoyourapplications,sothatitenforcestheseparationbetweentheapplication'suserinterface,orpresentationlayer,fromtheunderlyingdata.ThisisdonebyusingaclassthatactsasthecommunicationlayerbetweenboththeViewandtheViewModel,andisconnectedthroughdatabindingsalongwiththebindingcontextfortheView,pointingtoaninstanceoftheViewModel.

Inthischapter,youwillseehowyoucanleveragewhatyoualreadyknowabouttheMVVMdesignpattern,andwewilllearnhowtomovenavigationintotheViewModels.You'lllearnhowtocreateaC#classthatwillactasthenavigationserviceforourapp,aswellashowtoupdateourexistingWalkBaseViewModelclassfile.ThiswillincludeanumberofabstractclassmethodsthateachofourViewModelswillinherit,andinturnupdatethecontentpagestobindwiththeViewModelstoallownavigationbetweentheseViewstohappen.

Thischapterwillcoverthefollowingtopics:

UnderstandingtheXamarin.FormsNavigationAPIpatternarchitectureCreatinganavigationserviceusingtheXamarin.Forms.NavigationclassUpdatingtheTrackMyWalksapplicationtousethenavigationserviceUpdatingtheMVVMViewModelstousethenavigationserviceinterfaceUpdatingtheuserinterfacecontentpagestousetheupdatedMVVMViewModels

Page 105: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UnderstandingtheXamarin.FormsNavigationAPIInthissection,wewilltakealookattheXamarin.FormsNavigationAPIpatternarchitectureandgainanunderstandingintothedifferenttypesofnavigationpatternsthatareavailable.

TheXamarin.FormsNavigationAPIisexposedthroughtheXamarin.Forms.INavigationinterface,andisimplementedviatheNavigationproperty.TheNavigationpropertycanbecalledfromanyXamarin.Formsobject,typicallytheXamarin.Forms.PagethatinheritsfromtheContentPageclassthatispartoftheXamarin.Forms.Coreassembly.

TheXamarin.FormsNavigationAPIsupportstwodifferenttypesofnavigation-hierarchicalandmodal,andtheseareexplainedinthefollowingtable:

Navigationpage Description

Hierarchical

Thehierarchicalnavigationtypeisessentiallyastack-basednavigationpatternthatenablesuserstomoveiterativelythrougheachofthescreenswithinthehierarchy,andthennavigatebackoutagain,onescreenatatime,removingthemfromthenavigationstack.

ModalThemodalnavigationtypeisasinglepop-uporscreenthatinterruptsthehierarchicalnavigationbyrequiringtheusertorespondtoanaction,priortothescreenorpopupfrombeingdismissed.

Thehierarchicalnavigationpatternprovidesameansofnavigatingthroughthenavigationalstructureandistypicallythemostused.Thisinvolvestheusertappingtheirwayforwardthroughaseriesofpages,andthennavigatingbackwardsthroughthestackusingthenavigationmethodsonAndroidoriOSdevices.

Thefollowingscreenshotshowstheprocesswhenmovingfromonepagetoanotherwithinthehierarchicalnavigationmodel,andpoppingpagesfromtheNavigationStack.Wheneveranewpageispushedontothenavigationstack,thiswillbecometheactivepage.

Page 106: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Alternatively,whenyouwanttoreturnbacktothepreviouspage,theapplicationwillstartbypoppingthecurrentpagefromthenavigationstack,andthenewtopmostpagewillthenbecometheactivepage.Themodalnavigationpatterndisplaysapageontopofthecurrentpagethatpreventstheuserfromanyinteractionfromthepageunderneathit,andprovidestheuserwithchoicesforwhattheywanttodobeforethemodalpagecanbeclosed.

TheINavigationinterface,whichispartoftheXamarin.Forms.NavigationPage,implementsandexposestwoseparateread-onlyproperties-NavigationStackandModalStack.Thiswillallowyoutoviewboththehierarchicalandmodalnavigationstacks.

TheXamarin.FormsINavigationinterfaceprovidesyouwithseveralmethodsthatwillallowyoutoasynchronouslypush(add)andpop(remove)pagesontothenavigationandmodalstacks,andtheseareexplainedinthetablebelow:

Navigationmethods Description

PushAsync(Page

page)

ThismethodaddsanewpageatthetopoftheNavigationStackthatenablesuserstomovedeeperwithinthescreenhierarchy.

PopAsync()

ThismethodallowsyoutonavigatebackthroughtheNavigationStacktothepreviouspage,ifonehasbeenpreviouslyaddedtotheNavigationStack.

Thismethodallowsyoutodisplayapagemodallywhenyouneedtoeitherdisplaysomeinformationalinformationorrequestinformation

Page 107: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

PushModalAsync(Page

page)fromtheuser.Agoodexampleofamodalpagewouldbeasign-onpage,whereyouneedtogetusercredentials.

PopModalAsync()Thismethodwilldismissthecurrentlydisplayedmodalpageandreturnyoutothepagedisplayedunderneath.

Aswellastheabovementionednavigationmethods,theXamarin.Forms.INavigationinterfaceprovidesyouwithanumberofadditionalmethodsthatwillhelpyoumanipulatetheNavigationStack,andtheseareexplainedinthefollowingtable:

Navigationmethods Description

InsertPageBefore(Page

page,Pagebefore)

ThismethodallowsyoutoinsertapagebeforeaspecificpagethathasalreadybeenaddedtotheNavigationStack.

RemovePage(Pagepage)ThismethodallowsyoutoremoveaspecificpagewithintheNavigationStack.

PopToRootAsync()

ThismethodnavigatesyoubacktothefirstpagethatiscontainedwithintheNavigationStackwhilstremovingalloftheotherpagesthatarecontainedwithintheNavigationStack.

NowthatyouhaveagoodunderstandingofthecomponentsthatarecontainedwithintheNavigationAPIpatternarchitecture,wecanbegintotakealookatsomeofthedifferentapproachestonavigatingbetweenpagesandViewModels.

Page 108: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

DifferencesbetweenthenavigationandViewModelapproachesInthissection,wewilltakealookattheapproacheswhenperformingnavigationwithinViewModelscontainedwithinanXamarin.Formssolution.WhenperformingnavigationwithinyourViewModels,thereareacoupleofapproachesthatyoushouldconsiderbeforegoingdownthispath.Anapproachwouldbetousethepagenavigationapproach,whichinvolvesnavigatingtoanotherpageusingadirectreferencetothatpage.

ThepagenavigationapproachcanbeaccomplishedinXamarin.FormsbyessentiallypassingthecurrentINavigationinstanceintoaViewModel'sobjectconstructor,whichwillforcetheViewModeltousetheXamarin.Formsdefaultnavigationmechanismtonavigatetootherpages.

IfyouwantedtousetheViewModelapproachtonavigatetoapageusingtheassociatedpagesViewModel,youwouldneedtoformsomesortofmappingbetweeneachofthepages,aswellastheirassociatedViewModels.Thiswouldbedonebycreatingadictionaryorkey-valuetypepropertyinthenavigationservicethatwillmaintainaone-to-onemappingforeachofthepagesandtheirtype.

InMVVM,actionstakenbytheuseronaparticularpageareboundtocommandsthatarepartofthepages,ViewModel,andsothisprocessneedstobethoughtthroughdifferentlywhennavigatingtoanotherpage,oreventhepreviouspage,whenperformingtaskssuchassavingdataorupdatingamapslocation.Assuch,weneedtorethinkhowtoachievenavigationthatleveragestheMVVMdesignpatternwithinourapp,sothatitcanbecontrolledbytheViewModelsandnotbytheunderlyingpages.

WhenusingtheViewModelstohandlethenavigation,thisalleviatestheneedforaViewModeltohaveanydependenciesonthespecificimplementationofapage,andbecausetheViewModeldoesn'tnavigatedirectlytoapageviatheContentPage'sViewModel,thismeansthatwhenyouimplementthisapproach,thereisaneedforarelationshipormappingtobedonebetweeneachofthepagesandtheirassociatedViewModels.

Inthenextsection,wewillbetakingalookathowtonavigatethroughourTrackMyWalksappbycreatinganavigationservicethatwillincludeViewModelandpagetypemappings.

Page 109: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingthenavigationservicewithinyourappInthissection,wewillbeginbysettingupthebasicstructureforourTrackMyWalkssolutiontoincludethefolderthatwillbeusedtorepresentourServices.Let'stakealookathowwecanachievethis,byperformingfollowingthesteps:

1. LaunchtheXamarinStudioapplicationandensurethattheTrackMyWalkssolutionisloadedwithintheXamarinStudioIDE.

2. Next,createanewfolderwithintheTrackMyWalksPortableClassLibraryproject,calledServices,asshowninthefollowingscreenshot:

Nowthatwehavecreatedthefolderstructurethatwillbeusedtostoreournavigationservices,wecanbegintostartbuildingtheNavigationServiceInterfaceclassthatwillbeusedbyourNavigationServiceclassandinturnusedbyourViewModels.

Page 110: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingthenavigationserviceinterfacefortheTrackMyWalksappInthissection,wewillbeginbycreatinganavigationserviceinterfaceclassthatwillextendfromtheXamarin.Formsnavigationabstractionlayer.ThisissothatwecanperformViewModeltoViewModelnavigationwithinourMVVMdesignpattern,andinturnbindwithourcontentpagestoallownavigationbetweentheseViewstohappen.

Wewillfirstneedtodefinetheinterfaceforournavigationservice,asthiswillcontainanddefineitsmethods,andwillmakeitaloteasierifweeverwantedtoaddnewmethodimplementationsforourservice,withouttheneedtochangeeachofourViewModels.

Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. CreateanemptyclasswithintheServicesfolder,asshowninthefollowingscreenshot:

2. Next,choosetheEmptyInterfaceoptionlocatedwithintheGeneralsection,andenterinIWalkNavServiceforthenameofthenewinterfacefiletocreate,asshowninthefollowingscreenshot:

Page 111: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyclassfile,asshownintheprecedingscreenshot.

Upuntilthispoint,allwehavedoneiscreateourIWalkNavServiceclassfile.ThisInterfaceclasswillbeusedandwillactasthebaseNavigationServiceclassthateachofourViewModelswillinheritfrom.AswestarttobuildtheNavigationServiceInterfaceclass,youwillseethatitcontainsacoupleofclassmembersthatwillbeusedbyourcontentpagesandViewModels,aswewillbeusingthisasourbaseclasswithinourViewModelsusedbytheTrackMyWalksapplication.

ToproceedwithcreatingthebaseIWalkNavServiceinterface,ensurethattheIWalkNavService.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//IWalkNavService.cs

//TrackMyWalksNavigationServiceInterface

//

Page 112: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//CreatedbyStevenF.Danielon03/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Threading.Tasks;

usingTrackMyWalks.ViewModels;

namespaceTrackMyWalks.Services

{

publicinterfaceIWalkNavService

{

//NavigatebacktothePreviouspagein

theNavigationStack

TaskPreviousPage();

//Navigatetothefirstpagewithin

theNavigationStack

TaskBackToMainPage();

//NavigatetoaparticularViewModelwithin

ourMVVMModel,

//andpassaparameter

TaskNavigateToViewModel<ViewModel,

TParameter>(TParameterparameter)

whereViewModel:WalkBaseViewModel;

}

}

Intheprecedingcodesnippet,westartedbycreatinganewInterfaceclassforourIWalkNavServicethatallowstheabilitytonavigatetoeachofourViewModels,aswellasnavigatingbacktothePreviousPagemethod,andbacktothefirstpagewithinourhierarchicalmodel,asdeterminedbytheBackToMainPagemethod.

Note

Aninterfacecontainsonlythemethods,properties,andeventsignaturedefinitions.Anyclassthatimplementstheinterfacemustimplementallmembersoftheinterfacethatarespecifiedintheinterfacedefinition.

TheNavigateToViewModelmethoddeclaresagenerictypewhichisusedtorestricttheViewModeltoitsusetoobjectsoftheWalkBaseViewModelbaseclass,andastrongly-typedTParameterparametertobepassedalongwiththenavigation.

Note

Thetermstrongly-typedmeansthat,ifavariablehasbeendeclaredofaspecifictype(string,integer,ordefinedasauser-definedtype),itcannotbeassignedavalueofadifferenttypelateron,asthiswillresultinthecompilernotifyingyouofanerror.Anexamplewouldbe:inti=10;i="Ten"

TheTaskclassisessentiallyusedtohandleasynchronousoperations.Thisisdonebyensuringthattheasynchronousmethodyouinitiatedwilleventuallyfinish,thuscompletingthetask.The

Page 113: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TaskobjectisusedtoreturnbackinformationonceithasfinishedbyreturningbackaTaskobjectalmostinstantaneously,althoughtheunderlyingworkwithinthemethodwouldlikelyfinishlater.

Tohandlethis,youcanusetheawaitkeywordtowaitforthetasktocompletewhichwillblockthecurrentthreadandwaituntiltheasynchronousmethodhascompleted.

Page 114: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatinganavigationservicetonavigatewithinourViewModelsIntheprevioussection,wecreatedourbaseinterfaceclassforournavigationserviceanddefinedanumberofdifferentmethods,whichwillbeusedtonavigatewithinourMVVMViewModel.

ThesewillbeusedbyeachofourViewModels,andtheViews(pages)willimplementtheseViewModelsandusethemastheirBindingContext.

Let'stakealookathowwecanachievethis,byperformingthefollowingthesteps:

1. CreateanemptyclasswithintheServicesfolder,asshowninthenextscreenshot.2. Next,choosetheEmptyClassoptionlocatedwithintheGeneralsection,andenterin

WalkNavServiceforthenameofthenewclassfiletocreate,asshowninthefollowingscreenshot:

3. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyclassfile,asshownintheprecedingscreenshot.

Page 115: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

4. Upuntilthispoint,allwehavedoneiscreateourWalkNavServiceclassfile.ThisclasswillbeusedandwillactasthebaseNavigationServiceclassthatwillcontainthefunctionalityrequiredthateachofourViewModelswillinheritfrom,inordertonavigatebetweeneachoftheViewModelswithinourMVVMmodel.

5. AswestarttobuildourNavigationclass,youwillseethatitcontainsanumberofmethodmembersthatwillbeusedtoenablenavigationbetweeneachofourViewModelsanditwillimplementtheIWalkNavServiceInterface.ToproceedwithcreatingthebaseWalkNavServiceclass,performthefollowingsteps:

6. EnsurethattheWalkNavService.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//WalkNavService.cs

//TrackMyWalksNavigationServiceClass

//

//CreatedbyStevenF.Danielon03/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingXamarin.Forms;

usingSystem.Collections.Generic;

usingSystem.Threading.Tasks;

usingSystem.Reflection;

usingSystem.Linq;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

First,weneedtoinitializeournavigationclasstobemarkedasadependency,byaddingtheDependencymetadataattributesothatitcanberesolvedbytheXamarin.FormsDependencyServiceclass.Thiswillenablesothatittofindanduseourmethodimplementationasdefinedbyourinterface.

7. Next,wealsoneedtoneedtoensurethatourWalkNavServiceclassinheritsfromtheIWalkNavServicenavigationinterfaceclass,sothatitcanaccessthemethodgettersandsetters.Proceedandenterinthefollowingcodesnippetasshownhere:

[assembly:Dependency(typeof(WalkNavService))]

namespaceTrackMyWalks.Services

{

publicclassWalkNavService:IWalkNavService

{

8. Next,weneedtocreateapublicINavigationpropertynamednavigation.ThenavigationpropertywillprovideourclasswithareferencetothecurrentXamarin.Forms.INavigationinstance,andthiswillneedtobesetwhenthenavigationserviceisfirstinitialized.WewillseehowthisisdoneasweprogressthroughupdatingourTrackMyWalksapp.Proceedandenterinthefollowingcodesnippet:

publicINavigationnavigation{get;set;}

9. ThenweneedtoregisterthenavigationservicetohandleContentPagetoViewModelmappingsbydeclaringadictionary_viewMappingpropertyvariablethatinheritsfromthe

Page 116: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

IDictionaryinterface.Proceedandenterinthefollowingcodesnippet:

readonlyIDictionary<Type,Type>_viewMapping=

newDictionary<Type,Type>();

10. Next,weneedtodeclareanewmethodcalledRegisterViewMappingwhichwillbeusedtopopulateourViewModelandContentPage(View)withinthe_viewMappingdictionarypropertyobject.Proceedandenterinthefollowingcodesections:

//RegisterourViewModelandViewwithinourDictionary

publicvoidRegisterViewMapping(TypeviewModel,Typeview)

{

_viewMapping.Add(viewModel,view);

}

11. Then,weneedtocreatethePreviousPageinstancemethodforourWalkNavServiceclass.ThiswillbeusedtonavigatebacktothepreviouspagecontainedwithinourNavigationStack,byfirstcheckingtheNavigationStackpropertyofthenavigationpropertyINavigationinterfacetoensurethatitisnotnullandthatwehavemorethanoneViewModelcontainedwithinourNavigationStacktonavigatebackto.Ifwedon'tperformthischeck,itcouldresultinourapplicationcrashing.Finally,weusethePopAsyncmethodtoremovethelastviewaddedtoourNavigationStack,thusreturningbacktothepreviousViewModel.Proceedandenterinthefollowingcodesections:

//Instancemethodthatallowsustomovebacktothe

//previouspage.

publicasyncTaskPreviousPage()

{

//Checktoseeifwecanmovebacktothepreviouspage

if(navigation.NavigationStack!=null&&

navigation.NavigationStack.Count>0)

{

awaitnavigation.PopAsync(true);

}

}

12. Next,weneedtocreatetheBackToMainPageinstancemethodforourWalkNavServiceclass.ThiswillbeusedtotakeusbacktothefirstContentPagecontainedwithinourNavigationStack.WeusethePopToRootAsyncmethodofournavigationpropertyandusetheawaitoperatortowaituntilthetaskcompletes,beforeremovingallViewModelscontainedwithinourNavigationStackandreturningbackaTaskobject.Proceedandenterthefollowingcode:

//Instancemethodthattakesusbacktothemain

//RootWalksPage

publicasyncTaskBackToMainPage()

{

awaitnavigation.PopToRootAsync(true);

}

13. Then,weneedtocreatetheNavigateToViewModelinstancemethodforourWalkNavServiceclass.ThiswillbeusedtonavigatetoaspecificViewModelthatiscontainedwithinour_viewMappingdictionaryobject.Next,weusetheTryGetValue

Page 117: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

methodofthe_viewMappingdictionaryobjecttochecktoseeifourViewModeldoesindeedexistwithinourdictionary,andreturnthenameoftheViewModel.

14. ThenameofthereturnedviewwillbestoredwithintheviewTypeobject,andwethenusethePushAsyncmethodtonavigatetothatview.Finally,wesettheBindingContextforthelastpushedviewthatiscontainedwithinourNavigationStack,andthennavigatetotheview,passinginanyparametersrequired.Proceedandenterinthefollowingcodesections:

//InstancemethodthatnavigatestoaspecificViewModel

//withinourdictionaryviewMapping

publicasyncTaskNavigateToViewModel<ViewModel,

WalkParam>(WalkParamparameter)

whereViewModel:WalkBaseViewModel

{

TypeviewType;

if(_viewMapping.TryGetValue(typeof(ViewModel),out

viewType))

{

varconstructor=viewType.GetTypeInfo()

.DeclaredConstructors

.FirstOrDefault(dc=>dc.GetParameters()

.Count()<=0);

varview=constructor.Invoke(null)asPage;

awaitnavigation.PushAsync(view,true);

}

if(navigation.NavigationStack.Last().BindingContextis

WalkBaseViewModel<WalkParam>)

await((WalkBaseViewModel<WalkParam>)(

navigation.NavigationStack.Last().BindingContext)).

Init(parameter);

}

}

}

Intheprecedingcodesnippet,webeganbyensuringthatourWalkNavServiceclassinheritsfromourIWalkNavServiceclass,andthenmovedontocreateanavigationpropertythatinheritsfromourINavigationclass.Wethencreateditsassociatedgetterandsetterqualifiers.

Finally,wecreatedtheinstancemethodsrequiredforourWalkNavServiceclass.

Page 118: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkBaseViewModeltouseournavigationserviceInthissectionwewillproceedtoupdateourWalkBaseViewModelclasstoincludereferencestoourIWalkNavService.SinceourWalkBaseViewModelinheritsandisusedbyeachofourViewModels,itmakessensetoplaceitwithinthisclass.Thatway,ifweneedtoaddadditionalmethods,wecanjustaddthemwithinthisclass.Toproceed,performthefollowingsteps:

1. EnsurethattheWalkBaseViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//WalkBaseViewModel.cs

//TrackMyWalksBaseViewModel

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.ComponentModel;

usingSystem.Runtime.CompilerServices;

usingSystem.Threading.Tasks;usingTrackMyWalks.Services;

namespaceTrackMyWalks.ViewModels

{

publicabstractclassWalkBaseViewModel:

INotifyPropertyChanged

{

2. Next,weneedtocreateaprotectedIWalkNavServicepropertynamedNavService.TheNavServicepropertywillprovideourclasswithareferencetothecurrentnavigationinstancethatiscontainedwithinourIWalkNavServiceinterfaceclass.Proceedandenterinthefollowingcodesection:

protectedIWalkNavServiceNavService{get;privateset;}

3. Then,weneedtomodifytheclassconstructoranddeclareanavServiceparameterthatinheritsfromourIWalkNavServiceinterfaceclass.Next,wesettheNavServicepropertyforourWalkBaseViewModelbaseclass,toaninstanceofthenavServiceparameter.Proceedandenterinthefollowinghighlightedcodesections:

protectedWalkBaseViewModel(IWalkNavServicenavService)

{

NavService=navService;

}

4. Next,weneedtocreatetheInitabstractmethodforourWalkBaseViewModelclassthatreturnsbackanasynchronousTaskobject.ThiswillbeusedtoinitializeourWalkBaseViewModel.Proceedandenterinthefollowinghighlightedcodesections:

publicabstractTaskInit();

publiceventPropertyChangedEventHandlerPropertyChanged;

protectedvirtualvoidOnPropertyChanged(

Page 119: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

[CallerMemberName]stringpropertyName=null)

{

varhandler=PropertyChanged;

if(handler!=null)

{

handler(this,newPropertyChangedEventArgs(propertyName));

}

}

}

5. Then,weneedtocreateasecondaryabstractclassforourWalkBaseViewModelthatinheritsfromtheWalkBaseViewModelanddefinesageneric-typedTParameterobject.WethenproceedtooverloadtheWalkBaseViewModelclassconstructor,andsetthisclasstoinheritfromournavServicebaseclass.Proceedandenterinthefollowinghighlightedcodesections:

publicabstractclassWalkBaseViewModel<WalkParam>:

WalkBaseViewModel

{

protectedWalkBaseViewModel(IWalkNavServicenavService):

base(navService)

{

}

6. Next,weneedtooverridetheInitmethodforourWalkBaseViewModel<WalkParam>thatacceptsadefaultWalkParamvalueforourwalkDetailsmodel.Proceedandenterinthefollowinghighlightedcodesections:

publicoverrideasyncTaskInit()

{

awaitInit(default(WalkParam));

}

publicabstractTaskInit(WalkParamwalkDetails);

}

}

Intheprecedingcodesnippet,webeganbycreatingaNavServicepropertythatinheritsfromourIWalkNavServiceclass,andthencreateditsassociatedgetterandsetterqualifiers.

Next,weupdatetheWalkBaseViewModelclassconstructortosettheNavServicepropertytoaninstanceofournavService,beforecreatingourInitabstractionmethodthatwillbeusedtoinitializeourclass.

Inthenextstep,wecreateanewabstractclassforourWalkBaseViewModelthatimplementsfromtheWalkBaseViewModelclass,andthenoverloadsourclassconstructorsothatitinheritsfromournavServiceclass.

Next,we'lloverridetheInitmethodforourWalkBaseViewModel<WalkParam>thatacceptsadefaultWalkParamvalueforourwalkDetailsmodel.

Page 120: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthewalksmainpageViewModelandnavigationserviceWehavecreatedourIWalkNavServiceInterfaceclassandupdatedtheNavServiceclasstoincludeallofthenecessaryclassinstancemethods.WealsomadesomechangestoourWalkBaseViewModelclasstoinheritfromourIWalkNavServicenavigationservice.WehavealsoincludedanadditionalabstractionclassthatwillbeusedtoinitializeourWalkBaseViewModelwhennavigatingbetweenViewModelswithinourMVVMmodel.

Ournextstepistomodifythewalksmainpage.Inthissection,wewillbetakingalookathowtoupdateourWalksPageViewModelsothatitcantakeadvantageofournavigationservice.

Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. EnsurethattheWalksPageViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalksPageViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Collections.ObjectModel;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassWalksPageViewModel:WalkBaseViewModel

{

ObservableCollection<WalkEntries>_walkEntries;

publicObservableCollection<WalkEntries>walkEntries

{

get{return_walkEntries;}

set

{

_walkEntries=value;

OnPropertyChanged();

}

}

2. NowweneedtomodifytheWalksPageViewModelclassconstructor,whichwillneedtoincludeaparameternavServicethatisincludedwithinourIWalkNavServiceinterfaceclass.ThenweneedtosettheViewModel'sclassconstructortoaccessallinstanceclassmemberscontainedwithinthenavServicewithintheWalksPageViewModelbyusingthe

Page 121: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

basekeyword.WethensetupanObservableCollectioncalledwalkEntries.ThisacceptsalistparametercontainingourWalkEntriesmodel,whichwillbeusedtodeterminewheneverthecollectionhaschangedwithintheWalkEntriesmodel.

3. Next,wecreatetheInitmethodwithinourWalksPageViewmodel,andamethodcalledLoadWalkDetailstopopulatetheWalkDetails.Proceedandenterinthefollowinghighlightedcodesections:

publicWalksPageViewModel(IWalkNavServicenavService):

base(navService)

{

walkEntries=newObservableCollection<WalkEntries>();

}

publicoverrideasyncTaskInit()

{

awaitLoadWalkDetails();

}

4. Next,weneedtocreateanewasyncmethodcalledLoadWalkDetailsthatwillbeusedtoaddeachofthewalkentrieswithinourmodel.WeusetheTask.Factory.StartNewtostartandexecuteourtask,andthenproceedtopopulateeachofourlistsofWalkEntriesasynchronously.WethenuseandspecifytheawaitkeywordtowaituntilourTaskcompletes.Proceedandenterinthefollowinghighlightedcodesections:

publicasyncTaskLoadWalkDetails()

{

awaitTask.Factory.StartNew(()=>

{

walkEntries=newObservableCollection<WalkEntries>(){

newWalkEntries{

Title="10MileBrookTrail,MargaretRiver",

Notes="The10MileBrookTrailstartsinthe

RotaryParknearOldKate,apreservedsteam"+

"engineatthenorthernedgeofMargaretRiver.",

Latitude=-33.9727604,

Longitude=115.0861599,

Kilometers=7.5,

Distance=0,

Difficulty="Medium",

ImageUrl=

"http://trailswa.com.au/media/cache/media/images/

trails/_mid/"+

"FullSizeRender1_600_480_c1.jpg"

},

newWalkEntries

{

Title="AncientEmpireWalk,ValleyoftheGiants",

Notes="TheAncientEmpireisa450metrewalktrail

thattakesyouaroundandthroughsomeof"+

"thegianttingletreesincludingthemostpopular

ofthegnarledveterans,knownas"+

Page 122: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

"GrandmaTingle.",

Latitude=-34.9749188,

Longitude=117.3560796,

Kilometers=450,

Distance=0,

Difficulty="Hard",

ImageUrl="http://trailswa.com.au/media/cache

/media/images/trails/_mid/"+

"Ancient_Empire_534_480_c1.jpg"

},

};

});

}

5. Next,weneedtocreateaCommandpropertyforourclass.ThiswillbeusedwithinourWalksPageandwillbeusedtobindtotheAddWalkToolBarItem.TheCommandpropertywillrunanactionuponbeingpressed,andthenexecuteaclassinstancemethod,todeterminewhetherthecommandcanbeexecuted.Proceedandenterinthefollowinghighlightedcodesections:

Command_createNewWalk;

publicCommandCreateNewWalk

{

get

{

return_createNewWalk

??(_createNewWalk=

newCommand(async()=>

awaitNavService.NavigateToViewModel<WalkEntryViewMod

el,WalkEntries>(null)));

}

}

6. Then,createaCommandpropertytoourclass.ThiswillbeusedwithintheWalksPageandwillbeusedtohandleclicksonawalkitemwithintheListView.TheCommandpropertywillrunanactionuponbeingpressed,andthenexecuteaclassinstancemethodtodeterminewhetherthecommandcanbeexecutedornot,priortonavigatingtotheWalksTrailViewModelandpassinginthetrailDetailsforthechosenwalkwithintheListView.Proceedandenterinthefollowinghighlightedcodesections:

Command<WalkEntries>_trailDetails;

publicCommand<WalkEntries>WalkTrailDetails

{

get

{

return_trailDetails

??(_trailDetails=

newCommand<WalkEntries>(async(trailDetails)=>

awaitNavService.NavigateToViewModel

<WalksTrailVi

ewModel,WalkEntries>(trailDetails)));

Page 123: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

}

}

}

NowthatwehavemodifiedourWalksPageViewModeltoincludethenavigationserviceclass,whichwillbeusedbyourmainWalksPage,ournextstepistomodifyourwalksmainpagesothatitpointstoareferenceofourWalksPageViewModel,andensuresthatallofthenecessaryCommandbindingsandBindingContextshavebeensetupcorrectly.

Page 124: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthewalksmainpagetousetheupdatedViewModelNowthatwehavemodifiedourMVVMViewModeltotakeadvantageofthenavigationservice,weneedtomodifyourwalksmainpagetobindtheWalksPageBindingContexttotheWalksPageViewModelsothatthewalkentrydetailscanbedisplayedandallofthenavigationalaspectsareworkingasexpected.

Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. EnsurethattheWalksPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Collections.Generic;

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage

{

2. Next,weneedtocreateanewprivatepropertynamed_viewModelwithinourWalksPageclass.ThisisoftheWalksPageViewModeltype,andwillessentiallyprovideuswithaccesstotheContentPage'sBindingContextobject.Proceedandenterinthefollowinghighlightedcodesections:

WalksPageViewModel_viewModel

{

get{returnBindingContextasWalksPageViewModel;

}

}

publicWalksPage()

{

varnewWalkItem=newToolbarItem

{

Text="AddWalk"

};

3. Then,weneedtosetupaBindingtotheCommandpropertythatwedefinedwithinourWalksPageViewModelclass.ThiswillbecalledwhentheuserchoosestheAddWalk

Page 125: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

button.Proceedandenterinthefollowinghighlightedcodesections:

//SetupourBindingclickeventhandler

newWalkItem.SetBinding(ToolbarItem.CommandProperty,

"CreateNewWalk");

//AddtheToolBaritemtoourToolBar

ToolbarItems.Add(newWalkItem);

4. Next,weneedtodeclareandinitializeourWalksPageViewModelBindingContexttoincludeourIWalkNavServiceconstructor,whichisusedbytheWalkBaseViewModelclass,andisretrievedfromtheXamarin.FormsDependencyServiceclass.Proceedandenterinthefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

BindingContext=newWalksPageViewModel(DependencyService.Get

<IWalkNavS

ervice>());

//DefineourItemTemplate

varitemTemplate=newDataTemplate(typeof(ImageCell));

itemTemplate.SetBinding(TextCell.TextProperty,"Title");

itemTemplate.SetBinding(TextCell.DetailProperty,"Notes");

itemTemplate.SetBinding(ImageCell.ImageSourceProperty,

"ImageUrl");

varwalksList=newListView

{

HasUnevenRows=true,

ItemTemplate=itemTemplate,

SeparatorColor=Color.FromHex("#ddd"),

};

//SettheBindingpropertyforourwalksEntries

walksList.SetBinding(ItemsView<Cell>.ItemsSourceProperty,

"walkEntries");

5. Then,weneedtochangethewayinwhichanitemgetsselectedfromtheListView.WeneedtomakeacalltotheWalksTrailDetailscommandthatisincludedwithinourWalksPageViewModelclass,sothatitcannavigatetotheWalksTrailViewModel,whilstpassinginthechosenitemfromwithintheListView.Proceedandenterthefollowinghighlightedcodesections:

//InitializeoureventHandlertousewhen

theitemistapped

walksList.ItemTapped+=(objectsender,

ItemTappedEventArgse)=>

{

varitem=(WalkEntries)e.Item;

if(item==null)return;

_viewModel.WalkTrailDetails.Execute(item);

item=null;

};

Page 126: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Content=walksList;

}

6. Finally,weneedtocreateanOnAppearinginstancemethodofthenavigationhierarchythatwillbeusedtodisplayourWalksEntriespriortotheViewModelappearingonscreen.

7. WeneedtoensurethatourViewModelhasbeenproperlyinitializedbycheckingtoseethatitisn'tnull,priortocallingtheInitmethodofourWalksPageViewModel.Proceedandenterthefollowinghighlightedcodesections:

protectedoverrideasyncvoidOnAppearing()

{

base.OnAppearing();

//InitializeourWalksPageViewModel

if(_viewModel!=null)

await_viewModel.Init();

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingtheWalksPagesothatitcantakeadvantageofourupdatedWalksPageViewModel.WelookedathowtosetthecontentpagetoaninstanceoftheWalksPageViewModelsothatitknowswheretogetthelistofwalkentries.ThelistwillbeusedanddisplayedwithintheListViewcontrol,andwillthenupdatetheBindingContextpropertyfortheWalksPagetopointtoaninstanceoftheIWalkNavServiceinterface.Asyoucansee,byusinganavigationservicewithinyourViewModels,itmakesnavigatingbetweeneachoftheViewModelsquiteeasy.

Page 127: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthewalksentrypageViewModelandnavigationserviceNowthatwehavemodifiedtheMVVMViewModelthatwillbeusedforthemainWalksPage,ournextstepistobeginmodifyingtheWalkEntryViewModeltotakeadvantageofthenavigationservice,whichwillbeusedtocreatenewwalkentries,andsavethisinformationbacktotheWalkBaseViewModel.Thiswillbecoveredinalaterchapterasweprogressthroughoutthisbook.

Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. EnsurethattheWalkEntryViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalkEntryViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Diagnostics.Contracts;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassWalkEntryViewModel:WalkBaseViewModel

{

string_title;

publicstringTitle

{

get{return_title;}

set

{

_title=value;

OnPropertyChanged();

SaveCommand.ChangeCanExecute();

}

}

string_notes;

publicstringNotes

{

get{return_notes;}

set

{

_notes=value;

Page 128: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

OnPropertyChanged();

}

}

double_latitude;

publicdoubleLatitude

{

get{return_latitude;}

set

{

_latitude=value;

OnPropertyChanged();

}

}

double_longitude;

publicdoubleLongitude

{

get{return_longitude;}

set

{

_longitude=value;

OnPropertyChanged();

}

}

double_kilometers;

publicdoubleKilometers

{

get{return_kilometers;}

set

{

_kilometers=value;

OnPropertyChanged();

}

}

string_difficulty;

publicstringDifficulty

{

get{return_difficulty;}

set

{

_difficulty=value;

OnPropertyChanged();

}

}

double_distance;

publicdoubleDistance

{

get{return_distance;}

set

{

_distance=value;

OnPropertyChanged();

Page 129: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

}

string_imageUrl;

publicstringImageUrl

{

get{return_imageUrl;}

set

{

_imageUrl=value;

OnPropertyChanged();

}

}

2. Inthenextstep,weneedtomodifytheWalksEntryViewModelclassconstructorwhichwillnowneedtoincludeaparameternavServicethatisincludedwithintheIWalkNavServiceinterfaceclass.Thenwe'llsettheViewModel'sclassconstructortoaccessallinstanceclassmemberscontainedwithinthenavServicewithintheWalksEntryViewModel,byusingthebasekeyword.Next,we'llinitializetheconstructorwithdefaultvaluesforourTitle,DifficultyandDistanceproperties.

3. LocatetheWalkEntryViewModelclassconstructor,andenterthefollowinghighlightedcodesections:

publicWalkEntryViewModel(IWalkNavServicenavService):

base(navService)

{

Title="NewWalk";

Difficulty="Easy";

Distance=1.0;

}

4. Next,weneedtomodifytheSaveCommandcommandpropertytoincludetheasyncandawaitkeywords.ThiscommandpropertywillbeusedtobindtotheSaveToolBarItemandwillrunanactionuponbeingpressed.Itwillthenexecuteaclassinstancemethodtodeterminewhetherthecommandcanbeexecuted.Proceedandenterinthefollowinghighlightedcodesections:

Command_saveCommand;

publicCommandSaveCommand

{

get

{

return_saveCommand??(_saveCommand=

newCommand(async()=>awaitExecuteSaveCommand(),

ValidateFormDetails));

}

}

5. Next,welocateandmodifytheExecuteSaveCommandinstancemethodtoincludetheasyncTaskkeywordstothemethoddefinition,andthenincludeareferencetoourPreviousPagemethodthatisdefinedwithinourIWalkNavServiceinterfacetoallowourWalkEntryPage

Page 130: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

tobedismissedupontheuserclickingontheSavebutton.Proceedandenterinthefollowinghighlightedcodesections:

asyncTaskExecuteSaveCommand()

{

varnewWalkItem=newWalkEntries

{

Title=this.Title,

Notes=this.Notes,

Latitude=this.Latitude,

Longitude=this.Longitude,

Kilometers=this.Kilometers,

Difficulty=this.Difficulty,

Distance=this.Distance,

ImageUrl=this.ImageUrl

};

//Here,wewillsavethedetailsenteredinalaterchapter.

awaitNavService.PreviousPage();

}

//methodtocheckforanyformerrors

boolValidateFormDetails()

{

return!string.IsNullOrWhiteSpace(Title);

}

6. Finally,createtheInitmethodwithintheWalkEntryViewModel.ThiswillbeusedtoinitializetheWalkEntryPagewhenitiscalled.WeusetheTask.Factory.StartNewmethodtogivetheViewModelenoughtimetodisplaythepageonscreen,priortoinitializingtheContentPagecontents.Proceedandenterinthefollowinghighlightedcodesections:

publicoverrideasyncTaskInit()

{

awaitTask.Factory.StartNew(()=>

{

Title="NewWalk";

Difficulty="Easy";

Distance=1.0;

});

}

}

}

Inthissection,webeganbyensuringthatourViewModelinheritsfromtheWalkBaseViewModelclassandthenmodifiestheWalksEntryViewModelclassconstructortoincludetheparameternavServicewhichisincludedwithintheIWalkNavServiceinterfaceclass.Inournextstep,we'llinitializetheclassconstructorwithdefaultvaluesfortheTitle,Difficulty,andDistancepropertiesandthenmodifytheSaveCommandcommandmethodtoincludeareference

Page 131: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

totheNavService.PreviousPagemethod.ThisisdeclaredwithintheIWalkNavServiceinterfaceclasstoallowourWalkEntryPagetonavigatebacktothepreviouscallingpagewhentheSavebuttonisclicked.

Page 132: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksEntryPagetousetheupdatedViewModelInthissection,weneedtobindourmodelbindingcontext,BindingContext,totheWalkEntryViewModelsothatthenewwalkinformation,whichwillbeenteredwithinthispage,canbestoredwithintheWalkEntriesmodel.Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. EnsurethattheWalkEntryPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalkEntryPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingSystem.Collections.Generic;

namespaceTrackMyWalks

{

publicclassWalkEntryPage:ContentPage

{

2. Next,weneedtocreateanewprivatepropertynamed_viewModelwithintheWalkEntryPageclassthatisoftheWalksEntryViewModeltype,andwhichwillessentiallyprovideuswithaccesstotheContentPage'sBindingContextobject.Proceedandenterinthefollowinghighlightedcodesections:

WalkEntryViewModel_viewModel

{

get

{returnBindingContextasWalkEntryViewModel;

}

}

publicWalkEntryPage()

{

//SettheContentPageTitle

Title="NewWalkEntry";

3. Next,weneedtodeclareandinitializeourWalkEntryViewModelBindingContexttoincludetheIWalkNavServiceconstructor,whichisusedbytheWalkBaseViewModelclass,andisretrievedfromtheXamarin.FormsDependencyServiceclass.Proceedandenterinthefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

Page 133: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

BindingContext=newWalkEntryViewModel(

DependencyService.

Get<IWalkNavService>());

//DefineourNewWalkEntryfields

varwalkTitle=newEntryCell

{

Label="Title:",

Placeholder="TrailTitle"

};

walkTitle.SetBinding(EntryCell.TextProperty,

"Title",BindingMode.TwoWay);

varwalkNotes=newEntryCell

{

Label="Notes:",

Placeholder="Description"

};

walkNotes.SetBinding(EntryCell.TextProperty,

"Notes",BindingMode.TwoWay);

varwalkLatitude=newEntryCell

{

Label="Latitude:",

Placeholder="Latitude",

Keyboard=Keyboard.Numeric

};

walkLatitude.SetBinding(EntryCell.TextProperty,

"Latitude",BindingMode.TwoWay);

varwalkLongitude=newEntryCell

{

Label="Longitude:",

Placeholder="Longitude",

Keyboard=Keyboard.Numeric

};

walkLongitude.SetBinding(EntryCell.TextProperty,

"Longitude",BindingMode.TwoWay);

varwalkKilometers=newEntryCell

{

Label="Kilometers:",

Placeholder="Kilometers",

Keyboard=Keyboard.Numeric

};

walkKilometers.SetBinding(EntryCell.TextProperty,

"Kilometers",BindingMode.TwoWay);

varwalkDifficulty=newEntryCell

{

Label="DifficultyLevel:",

Placeholder="WalkDifficulty"

};

walkDifficulty.SetBinding(EntryCell.TextProperty,

"Difficulty",BindingMode.TwoWay);

Page 134: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

varwalkImageUrl=newEntryCell

{

Label="ImageUrl:",

Placeholder="ImageURL"

};

walkImageUrl.SetBinding(EntryCell.TextProperty,

"ImageUrl",BindingMode.TwoWay);

//DefineourTableView

Content=newTableView

{

Intent=TableIntent.Form,

Root=newTableRoot

{

newTableSection()

{

walkTitle,

walkNotes,

walkLatitude,

walkLongitude,

walkKilometers,

walkDifficulty,

walkImageUrl

}

}

};

varsaveWalkItem=newToolbarItem

{

Text="Save"

};

saveWalkItem.SetBinding(MenuItem.CommandProperty,

"SaveCommand");

ToolbarItems.Add(saveWalkItem);}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingtheWalkEntryPagesothatitcantakeadvantageofourupdatedWalkEntryViewModel.WelookedathowtosetthecontentpagetoaninstanceoftheWalkEntryViewModelsothattheBindingContextpropertyfortheWalkEntryPagewillnowpointtoaninstanceoftheIWalkNavServiceinterface.

Page 135: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthewalkstrailpageViewModelandnavigationserviceNowthatwehavemodifiedtheMVVMViewModelthatwillbeusedforourWalkEntrypage,ournextstepistobeginmodifyingtheWalksTrailViewModeltotakeadvantageofthenavigationservice,sothatitwillbeusedtodisplaythewalkentryinformationthathasbeenassociatedwiththechosenwalk.

Let'stakealookathowwecanachievethis,byperformingthefollowingthesteps:

1. EnsurethattheWalksTrailViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalksTrailViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassWalksTrailViewModel:

WalkBaseViewModel<WalkEntries>

{

WalkEntries_walkEntry;

publicWalkEntriesWalkEntry

{

get{return_walkEntry;}

set

{

_walkEntry=value;

OnPropertyChanged();

}

}

2. Next,weneedtocreateaCommandpropertyforourclass.ThiswillbeusedwithinourWalkTrailPageandwillbeusedtohandlewhentheuserclicksontheBeginThisTrialbutton.TheCommandpropertywillrunanactionuponbeingpressed,andthenexecuteaclassinstancemethodtodeterminewhetherthecommandcanbeexecutedornot,priortonavigatingtotheDistTravelledViewModel,andpassinginthetrailDetailsforthechosenwalkfromtheWalksPage.Proceedandenterinthefollowinghighlightedcodesections:

Command<WalkEntries>_command;

publicCommand<WalkEntries>DistanceTravelled

{

get

Page 136: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

return_command

??(_command=

newCommand<WalkEntries>(async(trailDetails)=>

awaitNavService.NavigateToViewModel

<DistTravelledViewModel,WalkEntries>(trailDetails)));

}

}

3. Next,weneedtodeclareandinitializeourWalksTrailViewModelBindingContexttoincludetheIWalkNavServiceconstructor,whichisusedbytheWalkBaseViewModelclass,andisretrievedfromtheXamarin.FormsDependencyServiceclass.Proceedandenterinthefollowinghighlightedcodesections:

publicWalksTrailViewModel(IWalkNavServicenavService):

base(navService)

{

}

4. Finally,createtheInitmethodwithintheWalksTrailViewModel.ThiswillbeusedtoinitializetheWalkTrailPagewhenitiscalled.WeusetheTask.Factory.StartNewmethodtogivetheViewModelenoughtimetodisplaythepageonscreen,priortoinitializingtheContentPagecontents,usingthepassedinwalkDetailsforourmodel.Proceedandenterinthefollowinghighlightedcodesections:

publicoverrideasyncTaskInit(WalkEntrieswalkDetails)

{

awaitTask.Factory.StartNew(()=>

{

WalkEntry=walkDetails;

});

}

}

}

Inthissection,webeginbyensuringthatourViewModelinheritsfromtheWalkBaseViewModelclass,andthatitacceptstheWalkEntriesdictionaryasitsparameter.Inournextstep,we'llcreateaDistanceTravelledCommandmethodthatwillnavigatetotheDistanceTravelledPagecontentpagewithinourNavigationStackthatpassestheWalkEntrydictionarytotheDistTravelledViewModelViewModelandpassaparametercontainingthetrailDetailsofthechosenwalk.

Page 137: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksTrailPagetousetheupdatedViewModelInthissection,weneedtobindourmodelbindingcontext,BindingContext,totheWalksTrailViewModelsothatthewalkinformationdetailswillbedisplayedfromtheWalkEntriesmodelwhenawalkhasbeenclickedonwithinthemainWalksPage.Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. EnsurethattheWalkTrailPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalkTrailPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

namespaceTrackMyWalks

{

publicclassWalkTrailPage:ContentPage

{

publicWalkTrailPage(WalkEntrieswalkItem)

{

Title="WalksTrail";

2. Next,weneedtodeclareandinitializeourWalkEntryViewModelBindingContexttoincludetheIWalkNavServiceconstructor,whichisusedbytheWalkBaseViewModelclass,andisretrievedfromtheXamarin.FormsDependencyServiceclass.Proceedandenterinthefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

BindingContext=newWalksTrailViewModel(DependencyService.

Get<IWalkNavService>());

varbeginTrailWalk=newButton

{

BackgroundColor=Color.FromHex("#008080"),

TextColor=Color.White,

Text="BeginthisTrail"

};

3. Next,weneedtomodifythebeginTrailWalk.Clickedhandlerforourbutton,sothatuponbeingclicked,itwillnavigatetotheDistTravelledViewModelandpassintheWalkEntrydictionaryforthechosenwalkfromtheWalksPage.Proceedandenterinthefollowinghighlightedcodesections:

Page 138: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//DeclareandinitializeourEventHandler

beginTrailWalk.Clicked+=(sender,e)=>

{

if(_viewModel.WalkEntry==null)return;

_viewModel.DistanceTravelled.Execute(_viewModel.WalkEntry);

};

varwalkTrailImage=newImage()

{

Aspect=Aspect.AspectFill

};

walkTrailImage.SetBinding(Image.SourceProperty,

"WalkEntry.ImageUrl");

vartrailNameLabel=newLabel()

{

FontSize=28,

FontAttributes=FontAttributes.Bold,

TextColor=Color.Black

};

trailNameLabel.SetBinding(Label.TextProperty,

"WalkEntry.Title");

vartrailKilometersLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.Black,

};

trailKilometersLabel.SetBinding(Label.TextProperty,

"WalkEntry.Kilometers",

stringFormat:"Length:{0}km");

vartrailDifficultyLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.Black

};

trailDifficultyLabel.SetBinding(Label.TextProperty,

"WalkEntry.Difficulty",stringFormat:"Difficulty:{0}");

vartrailFullDescription=newLabel()

{

FontSize=11,

TextColor=Color.Black,

HorizontalOptions=LayoutOptions.FillAndExpand

};

trailFullDescription.SetBinding(Label.TextProperty,

"WalkEntry.Notes");

this.Content=newScrollView

{

Page 139: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Padding=10,

Content=newStackLayout

{

Orientation=StackOrientation.Vertical,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children=

{

walkTrailImage,

trailNameLabel,

trailKilometersLabel,

trailDifficultyLabel,

trailFullDescription,

beginTrailWalk

}

}

};

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingtheWalksTrailPagesothatitcantakeadvantageoftheWalksTrailViewModel.WelookedathowtosetthecontentpagetoaninstanceoftheWalksTrailViewModelsothattheBindingContextpropertyfortheWalkTrailPagewillnowpointtoaninstanceoftheIWalkNavServiceinterface.

WealsoslightlymodifiedourClickedhandlerforthebeginTrailWalkbuttonsothatitwillnownavigatetotheDistanceTravelledPagecontentpagewithintheNavigationStack,andpassintheWalkEntrydictionaryobjecttotheDistTravelledViewModelViewModel.

Page 140: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthedistancetravelledViewModelandnavigationserviceNowthatwehavemodifiedtheMVVMViewModelthatwillbeusedforourWalkTrailPage,ournextstepistoupdatetheDistTravelledViewModeltotakeadvantageofthenavigationservice,sothatitcandisplaythewalkentryinformationthathasbeenassociatedwiththechosenwalk.

Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. EnsurethattheDistTravelledViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//DistTravelledViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassDistTravelledViewModel:

WalkBaseViewModel<WalkEntries>

{

WalkEntries_walkEntry;

publicWalkEntriesWalkEntry

{

get{return_walkEntry;}

set

{

_walkEntry=value;

OnPropertyChanged();

}

}

double_travelled;

publicdoubleTravelled

{

get{return_travelled;}

set

{

_travelled=value;

OnPropertyChanged();

Page 141: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

}

double_hours;

publicdoubleHours

{

get{return_hours;}

set

{

_hours=value;

OnPropertyChanged();

}

}

double_minutes;

publicdoubleMinutes

{

get{return_minutes;}

set

{

_minutes=value;

OnPropertyChanged();

}

}

double_seconds;

publicdoubleSeconds

{

get{return_seconds;}

set

{

_seconds=value;

OnPropertyChanged();

}

}

publicstringTimeTaken

{

get

{

returnstring.Format("{0:00}:{1:00}:{2:00}",

this.Hours,this.Minutes,this.Seconds);

}

}

2. Next,weneedtomodifytheDistTravelledViewModelclassconstructor,whichwillnowneedtoincludeanavServiceparameterthatisincludedwithintheIWalkNavServiceinterfaceclass.WethensettheViewModel'sclassconstructortoaccessallinstanceclassmemberscontainedwithinthenavServicebyusingthebasekeywordandinitializetheconstructorwithdefaultvaluesfortheHours,Minutes,Seconds,andTravelledproperties.

3. LocatetheDistTravelledViewModelclassconstructor,andenterthefollowinghighlightedcode:

publicDistTravelledViewModel(IWalkNavServicenavService):

Page 142: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

base(navService)

{

this.Hours=0;

this.Minutes=0;

this.Seconds=0;

this.Travelled=100;

}

4. Then,createtheInitmethodwithintheDistTravelledViewModel,whichwillbeusedtoinitializetheDistanceTravelledPagecontentpagewhenitiscalled.WeneedtospecifyandusetheTask.Factory.StartNewmethodtogivetheViewModelenoughtimetodisplaythepageonscreen,priortoinitializingtheContentPagecontents,usingthepassedinwalkDetailsforourmodel.Proceedandenterinthefollowinghighlightedcodesections:

publicoverrideasyncTaskInit(WalkEntrieswalkDetails)

{

awaitTask.Factory.StartNew(()=>

{

WalkEntry=walkDetails;

});

}

5. Next,weneedtocreatetheBackToMainPagecommandpropertythatwillbeusedtobindtotheEndThisTrailbuttonthatwillrunanactionuponbeingpressed.Thisactionwillexecuteaclassinstancemethod,todeterminewhethertheCommandcanbeexecuted.

6. IftheCommandcanbeexecuted,acallwillbemadetotheBackToMainPagemethodontheNavServicenavigationserviceclasstotaketheuserbacktotheTrackMyWalksmainpage,byremovingallexistingViewModelswithintheNavigationStack,exceptthefirstpage.Proceedandenterinthefollowinghighlightedcodesections:

Command_mainPage;

publicCommandBackToMainPage

{

get

{

return_mainPage

??(_mainPage=new

Command(async()=>await

NavService.BackToMainPage()));

}

}

}

}

Inthissection,weupdatedtheDistanceTravelledViewModeltoinheritfromour

Page 143: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

WalkBaseViewModelInterfaceclassandthenmodifytheDistTravelledViewModelclassconstructortopointtoaninstanceoftheIWalkNavServiceinterfaceclass.

WethencreatedtheInitmethodthatwillinitializetheDistanceTravelledViewModelwhenitiscalledandusetheTask.Factory.StartNewmethodtogivetheViewModelenoughtimetodisplaytheDistanceTravelledPagecontentpageonscreen,priortoinitializingtheContentPagecontents,usingthepassedinwalkDetailsforourmodel.

WealsocreatedtheBackToMainPagecommandpropertythatwillbeusedtobindtotheEndThisTrailbuttonthatwillrunanactiontoexecuteaclassinstancemethod,todeterminewhethertheCommandcanbeexecuted,andthenacallwillbemadetoBackToMainPagemethodontheNavServicenavigationserviceclasstotaketheuserbacktothefirstpagewithintheNavigationStack.

Page 144: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheDistanceTravelledPagetousetheupdatedViewModelNowthatwehavemodifiedtheMVVMViewModelthatwillbeusedbyourDistanceTravelledPagecontentpage,ournextstepistobeginmodifyingtheDistanceTravelledPagepagetotakeadvantageofournavigationservice,anddisplaywalkinformationdetails.ThecalculationsanddistancetravelledwillbedisplayedfromtheWalkEntriesmodel.

Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. EnsurethattheDistanceTravelledPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//DistanceTravelledPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingXamarin.Forms.Maps;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

namespaceTrackMyWalks

{

publicclassDistanceTravelledPage:ContentPage

{

2. Next,weneedtocreateanewprivatepropertynamed_viewModelwithintheDistanceTravelledPageclass,whichisofourDistTravelledViewModeltype,andwillessentiallyprovideuswithaccesstotheContentPage'sBindingContextobject.Proceedandenterinthefollowinghighlightedcodesections:

DistTravelledViewModel_viewModel

{

get{returnBindingContextasDistTravelledViewModel;}

}

publicDistanceTravelledPage()

{

Title="DistanceTravelled";

3. Next,weneedtodeclareandinitializetheDistTravelledViewModelBindingContexttoincludeourIWalkNavServiceconstructor,whichisusedbytheWalkBaseViewModelclass,andisretrievedfromtheXamarin.FormsDependencyServiceclass.Proceedandenterin

Page 145: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

thefollowinghighlightedcodesections:

//DeclareandinitializeourModelBindingContext

BindingContext=newDistTravelledViewModel

(DependencyService.

Get<IWalkNavService>());

4. Then,weneedtocreateanewmethodcalledLoadDetailswhichwillbeusedtograbthenameofthechosenwalkandtheLatitudeandLongitudevaluesfromtheDistTravelledViewModelaswellaszoomintotheuserentrylocation,usingtheMoveToRegionmethod.Proceedandenterinthefollowinghighlightedcodesections:

publicvoidLoadDetails()

{

//Instantiateourmapobject

vartrailMap=newMap();

//Placeapinonthemapforthechosen

//walktype

trailMap.Pins.Add(newPin

{

Type=PinType.Place,

Label=_viewModel.WalkEntry.Title,

Position=newPosition(_viewModel.WalkEntry.Latitude,

_viewModel.WalkEntry.Longitude)

});

//Centerthemaparoundthelistof

//walksentry'slocation

trailMap.MoveToRegion(MapSpan.FromCenterAndRadius(

newPosition(_viewModel.WalkEntry.Latitude,

_viewModel.WalkEntry.Longitude),

Distance.FromKilometers(1.0)));

vartrailNameLabel=newLabel()

{

FontSize=18,

FontAttributes=FontAttributes.Bold,

TextColor=Color.Black,

HorizontalTextAlignment=TextAlignment.Center

};

trailNameLabel.SetBinding(Label.TextProperty,

"WalkEntry.Title");

vartrailDistanceTravelledLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

Page 146: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

FontSize=20,

TextColor=Color.Black,

HorizontalTextAlignment=TextAlignment.Center

};

trailDistanceTravelledLabel.SetBinding(Label.TextProperty,

"Travelled",stringFormat:"DistanceTravelled:{0}km");

vartotalTimeTakenLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=20,

TextColor=Color.Black,

HorizontalTextAlignment=TextAlignment.Center

};

totalTimeTakenLabel.SetBinding(Label.TextProperty,

"TimeTaken",stringFormat:"TimeTaken:{0}");

varwalksHomeButton=newButton

{

BackgroundColor=Color.FromHex("#008080"),

TextColor=Color.White,

Text="EndthisTrail"

};

5. Next,weneedtomodifythewalksHomeButton.Clickedhandlerforourbuttonsothat,uponbeingclicked,itwillallowtheDistanceTravelledPagetonavigatebacktothefirstpagewithintheNavigationStack.Proceedandenterinthefollowinghighlightedcodesections:

//Setupoureventhandler

walksHomeButton.Clicked+=(sender,e)=>

{

if(_viewModel.WalkEntry==null)return;

_viewModel.BackToMainPage.Execute(0);

};

this.Content=newScrollView

{

Padding=10,

Content=newStackLayout

{

Orientation=StackOrientation.Vertical,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children={

trailMap,

trailNameLabel,

trailDistanceTravelledLabel,

totalTimeTakenLabel,

walksHomeButton

}

}

};

}

Page 147: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Finally,weneedtocreateanOnAppearinginstancemethodofthenavigationhierarchythatwillbeusedtocorrectlyplotthewalk'sLongitudeandLatitudecoordinateswithinthemap,alongwiththewalkinformation,priortotheViewModelappearingonscreen.WeneedtoensurethattheViewModelhasproperlybeeninitializedbycheckingtoseethatitisn'tnull,priortocallingtheInitmethodoftheDistTravelledViewModel.Proceedandenterinthefollowinghighlightedcodesections:

protectedoverrideasyncvoidOnAppearing()

{

base.OnAppearing();

//InitializeourDistanceTravelledViewModel

if(_viewModel!=null)

{

await_viewModel.Init();

LoadDetails();

}

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingtheDistanceTraveledPagesothatitcantakeadvantageoftheDistTravelledViewModel.WelookedathowtosetthecontentpagetoaninstanceoftheDistTravelledViewModelsothattheBindingContextpropertyfortheDistanceTravelledPagewillnowpointtoaninstanceoftheIWalkNavServiceinterface.

WealsoslightlymodifiedourClickedhandlerfortheWalksHomeButtonbutton,sothatitwillnownavigatetotheNavService.BackToMainPagemethod,whichisdeclaredwithintheIWalkNavServiceinterfaceclasstoallowtheDistanceTravelledPagetonavigatebacktothefirstpagewithintheNavigationStack.

Page 148: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheXamarin.Forms.AppclasstousethenavigationserviceInthissection,weneedtoupdateourXamarin.Forms.Appclass,bymodifyingtheconstructorinthemainAppclasstocreateanewinstanceofthenavigationserviceandregistertheapplication'sContentPagetoViewModelmappings.

Let'stakealookathowwecanachievethis,byperformingthefollowingsteps:

1. OpentheTrackMyWalks.csfileandensurethatitisdisplayedwithinthecodeeditor.2. Next,locatetheAppmethodandenterinthefollowinghighlightedcodesections:

//

//TrackMyWalks.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassApp:Application

{

publicApp()

{

//ChecktheTargetOSPlatform

if(Device.OS==TargetPlatform.Android)

{

MainPage=newSplashPage();

}

else

{

//Therootpageofyourapplication

varwalksPage=newNavigationPage(new

WalksPage()

{

Title="TrackMyWalks"

});

varnavService=DependencyService.

Get<IWalkNavService>()asWalkNavService;

navService.navigation=walksPage.Navigation;

Page 149: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

navService.RegisterViewMapping(typeof

(WalksPageViewModel

),typeof(WalksPage));

navService.RegisterViewMapping(

typeof(WalkEntryViewModel

),

typeof(WalkEntryPage));

navService.RegisterViewMapping(

typeof(WalksTrailViewModel

),

typeof(WalkTrailPage));

navService.RegisterViewMapping(

typeof(DistTravelledViewMo

del),

typeof(DistanceTravelledPage));

MainPage=walksPage;

}

}

protectedoverridevoidOnStart()

{

//Handlewhenyourappstarts

}

protectedoverridevoidOnSleep()

{

//Handlewhenyourappsleeps

}

protectedoverridevoidOnResume()

{

//Handlewhenyourappresumes

}

}

}

Intheprecedingcodesnippet,webeginbydeclaringanavServicevariablethatpointstoaninstanceofthenavigationserviceasdefinedbyourassemblyattributefortheXamarin.FormsDependencyService,asdeclaredintheWalkNavServiceclass.

Inournextstep,wesetthenavService.navigationpropertytopointtoaninstanceoftheNavigationPageclassthatthewalksPage.navigationpropertycurrentlypointsto,andwillbeusedasthemainrootpage.

Finally,wecalltheRegisterViewMappinginstancemethodforeachoftheViewModelsandspecifytheassociatedContentPageforeach.

Page 150: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,weupdatedourTrackMyWalksapplicationandcreatedanavigationserviceclassthatextendsthedefaultXamarin.Forms.NavigationAPI,whichprovidesuswithabettermethodofperformingViewModelnavigation.ThisseparatesthepresentationaspectsandbusinesslogicthatarecontainedwithintheViewModels.

Inthenextchapter,you'lllearnhowtocreatealocationservicesclassthatwillallowourTrackMyWalksapptoretrievelocation-basedinformation,anddeterminetheuser'scurrentlocation.You'llalsolearnhowtosetupourapptohandlebackgroundlocationupdates.Youwillalsolearnhowtoincorporateplatform-specificfeatureswithinyourapp,dependingontheplatformthatisbeingrun.

Page 151: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter4.AddingLocation-BasedFeatureswithinYourAppInourpreviouschapter,welookedathowwecanapplywhatwealreadyknowabouttheMVVMdesignpattern,andhowwecannavigatebetweenourViewModels,bycreatinganavigationserviceC#classthatactsasthenavigationserviceforourapp,usingtheXamarin.FormsDependencyServiceclass.

Inthischapter,you'lllearnhowtogoaboutincorporatingplatform-specificfeatureswithintheTrackMyWalksapp,dependingonthemobileplatform.You'lllearnhowtocreateaC#class,whichwillactastheLocationServiceforourapp,aswellascreatingaIWalkLocationServiceinterfaceclassfile,whichwillincludeanumberofclassmethodsthatbothouriOSandAndroidplatformswillinherit,and,inturn,updatethecontentpagestobindwiththeViewModelstoallowlocation-basedinformationbetweentheseViewstohappen.

Wewillalsobecoveringhowtoproperlyperformlocationupdateswhiletheapplicationiseitherintheforegroundorbackground,andwewillalsobetouchingonsomekeybackgroundconcepts,whichincluderegisteringanappasabackground-necessaryapplication.

Thischapterwillcoverthefollowingtopics:

Creatingalocation-basedclassthatutilizesthenativeplatformcapabilitiesthatcomeaspartoftheiOSandAndroidplatformsEnablingbackgroundlocationupdatesaswellasgettingtheuser'scurrentlocationUpdatingtheTrackMyWalksapplicationtousetheLocationServiceUpdatingtheWalkEntryViewModeltousetheLocationServiceInterfaceUpdatingtheDistanceTravelledViewModeltousetheLocationServiceInterface

Page 152: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Creatingandusingplatform-specificservicesAsmentionedintheintroductiontothischapter,wecreatedacustomizednavigationservice,whichprovidedanIWalkNavServiceInterfaceclassforwhichourWalkBaseViewModelcontainedapropertyofthatinterfacetype,sothatanyimplementationsoftheIWalkNavServicecanbeprovidedtoeachoftheViewModels,asrequired.

ThebenefitofusinganInterfacetodefineplatform-specificservicesisthatitcanbeusedwithintheViewModelsandtheimplementationsoftheservicecanbeprovidedviadependencyinjection,usingtheDependencyService,withthoseimplementationsbeingactualservices,orevenmocked-upservicesforunittestingtheViewModels,whichwewillbecoveringinChapter9,UnitTestingYourXamarin.FormsAppsUsingtheNUnitandUITestFrameworks.

Inadditiontothenavigationservice,wecanuseacoupleofotherplatform-specificfeatureserviceswithinourTrackMyWalksapptoenrichitsdataanduserexperience.Inthissection,wewillbetakingalookathowtocreateaLocationServiceclassthatallowsustogetthespecificgeolocationcoordinatesfromtheactualdeviceforbothouriOSandAndroidplatforms.

Page 153: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheLocationServiceInterfacefortheTrackMyWalksappBeforewecanbeginallowingourTrackMyWalksapptotakeadvantageofthedevice'sgeolocationcapabilitiesforbothouriOSandAndroidplatforms,wewillneedtocreateanInterfacewithintheTrackMyWalksPortableClassLibrary,whichcanthenbeusedbytheViewModelsforeachplatform.

Wewillneedtodefinetheinterfaceforourlocationservice,asthiswillcontainmethodimplementations,aswellasadatastructurethatwillbeusedtorepresentourlatitudeandlongitudecoordinates.

Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. LaunchtheXamarinStudioapplication,andensurethattheTrackMyWalkssolutionisloadedwithintheXamarinStudioIDE.

2. Next,createanewemptyinterfacewithintheTrackMyWalksPCLprojectsolution,undertheServicesfolder.

3. Then,choosetheEmptyInterfaceoptionlocatedwithintheGeneralsectionandenterIWalkLocationServiceforthenameofthenewinterfacefiletobecreated,asshowninthefollowingscreenshot:

Page 154: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

4. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewEmptyInterfaceclassfile,asshownintheprecedingscreenshot.

5. OurwizardhascreatedourIWalkLocationServiceclassfile,whichwillbeusedbyourViewModelsandcontentpageViewstodisplaygeolocationcoordinates.AswestarttobuildtheLocationServiceInterfaceclass,youwillseethatitcontainsacoupleofclassmembersthatwillallowustogettheuser'slocationaswellasdeterminingthedistancethattheuserhastravelledfrompointAtopointB.

6. ItalsocontainsadatastructureIWalkLocationCoordsthatwillbeusedtoholdourlatitudeandlongitudegeolocationcoordinates.ToproceedwithcreatingthebaseIWalkLocationServiceInterface,performthefollowingsteps:

7. EnsurethattheIWalkLocationService.csfileisdisplayedwithinthecodeeditorandenterthefollowingcodesnippet:

//

//IWalkLocationService.cs

//TrackMyWalksLocationServiceInterface

//

//CreatedbyStevenF.Danielon16/09/2016.

Page 155: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

namespaceTrackMyWalks.Services

{

//DefineourWalkLocationServiceInterface

publicinterfaceIWalkLocationService

{

//DefineourLocationServiceInstanceMethods

voidGetMyLocation();

doubleGetDistanceTravelled(doublelat,doublelon);

eventEventHandler<IWalkLocationCoords>MyLocation;

}

//WalkLocationCoordinatesObtained

publicinterfaceIWalkLocationCoords

{

doublelatitude{get;set;}

doublelongitude{get;set;}

}

}

Intheprecedingcodesnippet,westartbydefiningtheimplementationforourIWalkLocationService,whichwillprovideourTrackMyWalksappwiththeabilitytogettheuser'scurrentlocation,calculatingthedistancetravelledfromtheuser'scurrentlocationtothetrailgoal.WealsodefineanEventHandlermyLocation,whichwillbecalledwhenevertheplatformobtainsanewlocation.

TheIWalkLocationCoordsinterfacedefinesaclassthatcontainstwopropertiesthatwillbeusedbyourEventHandlertoreturnthelatitudeandlongitudevalues.

Note

AnInterfacecontainsonlythemethods,properties,andeventssignaturedefinitions.Anyclassthatimplementstheinterfacemustimplementallmembersoftheinterfacethatarespecifiedintheinterfacedefinition.

NowthatwehavedefinedthepropertyandmethodimplementationsthatwillbeusedbyourIWalkLocationService,ournextstepwillbetocreatetherequiredLocationServiceclassimplementationsforeachofourplatforms,astheyaredefinedquitedifferently.

Page 156: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheLocationServiceclassfortheAndroidplatformInthissection,wewillbeginbysettingupthebasicstructureforourTrackMyWalks.DroidsolutiontoincludethefolderthatwillbeusedtorepresentourServices.Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. LaunchtheXamarinStudioapplication,andensurethattheTrackMyWalkssolutionisloadedwithintheXamarinStudioIDE.

2. Next,createanewfolderwithintheTrackMyWalks.Droidproject,calledServices,asshowninthefollowingscreenshot:

3. Next,createanemptyclasswithintheServicesfolder.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingtheNavigationServiceInterfacefortheTrackMyWalksapp,withinChapter3,NavigatingwithintheMVVMModel-TheXamarin.FormsWay.

4. Then,choosetheEmptyClassoptionlocatedwithintheGeneralsectionandenterWalkLocationServiceforthenameofthenewclassfiletobecreated,asshowninthefollowingscreenshot:

Page 157: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyclassfile,asshownintheprecedingscreenshot.

Upuntilthispoint,allwehavedoneiscreateourWalkLocationServiceclassfile.ThisclasswillbeusedandwillactasthebaseLocationServiceclassthatwillcontainthefunctionalityrequiredbyourViewModels.

AswestarttobuildourLocationClass,youwillseethatitcontainsanumberofmethodmembersthatwillbeusedtohelpusgettheuser'scurrentgeolocationcoordinatesfromtheirdevice,sothatwecandisplaythiswithineachofourViewModels,anditwillimplementtheIWalkLocationServiceInterface.

ToproceedwithcreatingandimplementingthebaseWalkLocationServiceclass,performthefollowingsteps:

1. EnsurethattheWalkLocationService.csfileisdisplayedwithinthecodeeditor,andenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

Page 158: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//

//WalkLocationService.cs

//TrackMyWalksLocationServiceClass(Android)

//

//CreatedbyStevenF.Danielon16/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingAndroid.Content;

usingAndroid.Locations;

usingTrackMyWalks.Droid;

usingTrackMyWalks.Services;

usingXamarin.Forms;

2. First,weinitializeourWalkLocationServiceclass,whichistobemarkedasadependency,byaddingtheDependencymetadataattributejustaswedidforournavigationservice.ThisissothatitcanberesolvedbytheXamarin.FormsDependencyServicetoallowittofindanduseourmethodimplementationsasdefinedwithinourInterface.WealsoneedtoimplementtheIWalkCoordinatesinterfaceusingtheLocationEventArgsclassthatcontainsourlatitudeandlongitudeproperties,whichwillbepopulatedwheneveranewlocationisobtained:

[assembly:Xamarin.Forms.Dependency(

typeof(WalkLocationService))]

namespaceTrackMyWalks.Droid

{

//Eventargumentscontaininglatitudeandlongitude

publicclassCoordinates:EventArgs,IWalkCoordinates

{

publicdoublelatitude{get;set;}

publicdoublelongitude{get;set;}

}

3. Next,weneedtomodifyourWalkLocationServiceclassconstructorsignature,sothatitinheritsfromtheIWalkLocationServiceInterfaceclass,aswellasimplementinganILocationListenerinterfaceclass,whichwillbeusedtoindicatewhenevertheuser'slocationchanges,byimplementingfourmethods-OnLocationChanged,OnProviderDisabled,OnProviderEnabled,andOnStatusChanged:

publicclassWalkLocationService:Java.Lang.Object,

IWalkLocationService,ILocationListener{

LocationManagerlocationManager;

LocationnewLocation;

//CreatethefourmethodsforourLocationListener

//interface.

publicvoidOnProviderDisabled(stringprovider){}

publicvoidOnProviderEnabled(stringprovider){}

publicvoidOnStatusChanged(stringprovider,

Availabilitystatus,Android.OS.Bundleextras){}

Page 159: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Note

WeneedtoensurethatourWalkLocationServiceclassinheritsfromtheAndroid-specificJava.Lang.Objectclass,sothatwecanprovideaccesstothesystemlocationservices,inordertoobtainperiodicupdatesonthedevice'sgeographicallocation.

WheneveryourclassesinheritfromtheILocationListenerAPI,theILocationListenerInterfacesupportsseveraldifferentmethodtypes,whichareexplainedinthefollowingtable:

Methodname Description

OnProviderDisabledThismethodisfiredupwheneverthelocationserviceproviderhasbeendisabledbytheuser.

OnProviderEnabledThismethodisfiredupwheneverthelocationserviceproviderhasbeenenabledbytheuser.

OnStatusChanged

Thismethodisfiredupwheneverthelocationserviceproviderstatushasbeenchanged,thatis,thelocationserviceshavebeendisabledbytheuser.

OnLocationChangedThismethodisfiredupwheneverachangeinlocationhasbeendetected.

4. Then,weneedtosetupanEventHandlerdelegateobjectthatwillbecalledwheneverthelocationhasbeenobtainedorchanged:

//SetupourEventHandlerdelegatethatiscalled

//wheneveralocationhasbeenobtained

publiceventEventHandler<IWalkCoordinates>MyLocation;

5. Next,wecreatetheOnLocationChangedmethodthatwillbefiredupwhenevertheuser'slocationhasbeenchangedsincethelasttime.Thismethodacceptstheuser'scurrentlocation,andweneedtoaddachecktoensurethatourlocationisnotemptypriortocreatinganinstanceofourCoordinatesclassdatastructure,andthenassigningthenewlocationdetailsforourlatitudeandlongitude,beforefinallypassingacopyoftheCoordinatestotheMyLocationEventHandler:

//Firedwheneverthereisachangeinlocation

publicvoidOnLocationChanged(Locationlocation)

{

if(location!=null)

Page 160: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

//CreateaninstanceofourCoordinates

varcoords=newCoordinates();

//Assignouruser'sLatitudeandLongitude

//values

coords.latitude=location.Latitude;

coords.longitude=location.Longitude;

//Updateournewlocationtostorethe

//newdetails.

newLocation=newLocation("PointA");

newLocation.Latitude=coords.latitude;

newLocation.Longitude=coords.longitude;

//Passthenewlocationdetailstoour

//LocationServiceEventHandler.

MyLocation(this,coords);

};

}

6. Then,wecreatetheGetMyLocationmethodthatwillbeusedtostartgettingtheuser'slocation.WethensetupourlocationManagertorequestlocationupdates.Thisisbecause,whendealingwithAndroid,theseservicesrequireaContextobjectinorderforthemtowork.Xamarin.FormscomeswiththeForms.Contextobject,andweusetheNetworkProvidermethodtoobtainthelocationusingthecellularnetworkandWi-Fi.Considerthefollowingcode:

//Methodtocalltostartgettinglocation

publicvoidGetMyLocation()

{

locationManager=(LocationManager)

longminTime=0;//Timeinmilliseconds

floatminDistance=0;//Distanceinmetres

Forms.Context.GetSystemService(Context.LocationService);

locationManager.RequestLocationUpdates(

LocationManager.NetworkProvider,

minTime,

minDistance,

this);

}

7. Next,createtheGetDistanceTravelledmethod,whichacceptstwoparameterscontainingourlatitudeandlongitudevalues.Wecreateanewlocation,andsettheLatitudeandLongitudevaluesthatcontaintheendingcoordinatesforourtrail.Wethendeclareavariabledistance,whichcallstheDistanceTomethodonournewLocationobject,todetermineourcurrentdistancefromtheendgoal.Wedividethedistanceby1000toconvertthedistancetravelledtometers:

//Calculatesthedistancebetweentwopoints

publicdoubleGetDistanceTravelled(doublelat,doublelon)

{

LocationlocationB=newLocation("TrailFinish");

Page 161: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

locationB.Latitude=lat;

locationB.Longitude=lon;

floatdistance=newLocation.DistanceTo(locationB)/1000;

returndistance;

}

8. Finally,createtheWalkLocationServiceclassfinalizer;thiswillbeusedtostopallupdatelistenereventswhenourclasshasbeensettonull.

//Stopthelocationupdatewhentheobjectissettonull

~WalkLocationService()

{

locationManager.RemoveUpdates(this);

}

}

}

NowthatwehavecreatedtheWalkLocationServiceclassfortheAndroidportionofourTrackMyWalksapp,ournextstepistocreatethesameclassfortheiOSportion,whichwillbecoveredinthenextsection.

Page 162: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheLocationServiceclassfortheiOSplatformIntheprevioussection,wecreatedtheclassforourWalkLocationService.Wealsodefinedanumberofdifferentmethodsthatwillbeusedtoprovidelocation-basedinformationwithinourMVVMViewModel.

Inthissection,wewillbuildtheiOSportionforourWalkLocationService,justlikewedidforourAndroidportion.Youwillnoticethattheimplementationsforbothoftheseclassesarequitesimilar;however,theseimplementdifferentmethods,asyouwillseeoncewestartimplementingthem.

Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. CreateanemptyclasswithintheServicesfolderforourTrackMyWalks.iOSproject,andenterWalkLocationServiceforthenameofthenewclassfiletocreate.

2. OnceyouhavecreatedtheWalkLocationServiceclassfile,ensurethattheWalkLocationService.csfileisdisplayedwithinthecodeeditorandenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

//

//WalkLocationService.cs

//TrackMyWalksLocationServiceClass(iOS)

//

//CreatedbyStevenF.Danielon16/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingCoreLocation;

usingTrackMyWalks.iOS;

usingTrackMyWalks.Services;

usingUIKit;

3. Next,weinitializeourWalkLocationServiceclass,whichistobemarkedasadependency,byaddingtheDependencymetadataattributejustaswedidforournavigationservice.ThisissothatitcanberesolvedbytheXamarin.FormsDependencyServicetoallowittofindanduseourmethodimplementationsasdefinedwithinourInterface.WealsoneedtoimplementtheIWalkCoordinatesinterfaceusingtheCoordinatesclass,whichcontainsthelatitudeandlongitudepropertiesthatwillbepopulatedwheneveranewlocationisobtained:

[assembly:Xamarin.Forms.Dependency(typeof(WalkLocationService))]

namespaceTrackMyWalks.iOS

{

//Eventargumentscontaininglatitudeandlongitude

publicclassCoordinates:EventArgs,IWalkCoordinates

{

publicdoublelatitude{get;set;}

publicdoublelongitude{get;set;}

Page 163: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

4. Then,weneedtomodifyourWalkLocationServiceclassconstructorsignature,sothatitinheritsfromtheIWalkLocationServiceInterfaceclass.WealsoneedtodeclareourlocationManagerobject,whichwillbeusedtoobtaintheuser'slocation.WealsocreateanewLocationobjectoftypeCLLocation,whichwillbeusedtoconvertthelatitudeandlongitudecoordinatesfromthelocationManagerobjectintoaCLLocationobject:

//WalkLocationServiceclassthatinheritsfromour

//IWalkLocationServiceinterface

publicclassWalkLocationService:IWalkLocationService

{

//DeclareourLocationManager

CLLocationManagerlocationManager;

CLLocationnewLocation;

5. Next,weneedtosetupanEventHandlerdelegateobjectthatwillbecalledwheneverthelocationhasbeenobtainedorchanged:

//SetupourEventHandlerdelegatethatiscalled

//wheneveralocationhasbeenobtained

publiceventEventHandler<IWalkCoordinates>MyLocation;

6. Then,wecreatetheGetMyLocationmethodthatwillbeusedtostartgettingtheuser'slocation.Next,wesetupourlocationManagerusingtheiOSCLLocationManagerclasstoallowourclasstorequestlocationupdates.Wethenperformacheck,usingtheLocationServicesEnabledpropertyoftheCLLocationManagerclass,toensurethatlocationserviceshavebeenenabledontheuser'sdevice.

7. Thisisagoodchecktoenforcepriortorequestingthegettingoftheuser'slocation,andifourCLLocationManagerclassdeterminesthatlocationserviceshavebeendisabled,wedisplayamessagetotheuser,usingtheUIAlertViewclass:

//Methodtocalltostartgettinglocation

publicvoidGetMyLocation()

{

locationManager=newCLLocationManager();

//Checktoseeifwehavelocationservices

//enabled

if(CLLocationManager.LocationServicesEnabled)

{

//Setthedesiredaccuracy,inmeters

locationManager.DesiredAccuracy=1;

//CLLocationManagerDelegateMethods

8. Next,wesetupaneventhandler,LocationsUpdated,thatwillstartfiringupwheneverthereisachangeintheuser'scurrentlocation,andwecallthelocationUpdatedinstancemethod,passinginthelocationgeo-coordinates:

//Firedwheneverthereisachangein

//location

locationManager.LocationsUpdated+=(objectsender,

CLLocationsUpdatedEventArgse)=>

Page 164: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

locationUpdated(e);

};

9. Then,wesetupaneventhandler,AuthorizationChanged,whichwillbecalledwheneveritdetectsachangemadetotheauthorizationoflocation-basedservices.Forexample,thiswillbecalledif,forsomereason,theuserdecidestoturnofflocation-basedservices:

//Thiseventgetsfiredwheneverit

//detectsachange,i.e.,iftheuser

//hasturnedoffordisabledlocation

//basedservices.

locationManager.AuthorizationChanged+=(object

sender,CLAuthorizationChangedEventArgse)=>

{

didAuthorizationChange(e);

//Performlocationchangeswithinthe

//foreground.

locationManager.RequestWhenInUseAuthorization();

};

}

}

10. Next,wecreatethelocationUpdatedmethodthatwillbefiredupwhenevertheuser'slocationhasbeenchangedsincethelasttime.Thismethodacceptstheuser'scurrentlocation,whichisdefinedbytheCLLocationsUpdatedEventArgsinavariablecallede.Next,wecreateaninstanceofourCoordinatesclassdatastructure,andthenassignthenewlocationdetailsforthelatitudeandlongitude,beforefinallypassingacopyoftheCoordinatestotheMyLocationEventHandler:

//Methodiscalledwheneverthereisachangein

//location

publicvoidlocationUpdated(CLLocationsUpdatedEventArgse)

{

//CreateourLocationCoordinates

varcoords=newCoordinates();

//Getalistofourlocationsfound

varlocations=e.Locations;

//ExtractourLatitudeandLongitudevalues

//fromourlocationsarray.

coords.latitude=locations[locations.Length-1].

Coordinate.Latitude;

coords.longitude=locations[locations.Length-1].

Coordinate.Longitude;

//Then,convertbothourLatitudeandLongitude

//valuestoaCLLocationobject.

newLocation=newCLLocation(coords.latitude,

coords.longitude);

MyLocation(this,coords);

}

Page 165: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

11. Then,wecreatethedidAuthorizationChangemethod,whichwillbecalledwhenevertheCLLocationManagerdelegatedetectsachangeintheauthorizationstatus;youwillbenotifiedaboutthosechanges.Tohandleanychangesintheauthorizationstatuswhileyourappisrunning,andtopreventyourapplicationfromcrashingunexpectedly,youwillneedtoensurethattheproperauthorizationishandledaccordingly.

12. Ifwedetectthattheuserhasrestrictedordeniedaccesstolocationservicesonthedevice,wewillneedtoalerttheusertothis,anddisplayanalertdialogpopup:

publicvoiddidAuthorizationChange(

CLAuthorizationChangedEventArgsauthStatus)

{

switch(authStatus.Status){

caseCLAuthorizationStatus.AuthorizedAlways:

locationManager.RequestAlwaysAuthorization();

break;

caseCLAuthorizationStatus.AuthorizedWhenInUse:

locationManager.StartUpdatingLocation();

break;

caseCLAuthorizationStatus.Denied:

UIAlertViewalert=newUIAlertView();

alert.Title="LocationServicesDisabled";

alert.AddButton("OK");

alert.AddButton("Cancel");

alert.Message="Enablelocationsforthisapp

via\ntheSettingsapponyouriPhone";

alert.AlertViewStyle=UIAlertViewStyle.Default;

alert.Show();

alert.Clicked+=(objects,

UIButtonEventArgsev)=>

{

varButton=ev.ButtonIndex;

};

break;

default:

break;

}

}

13. ThedidAuthorizationChangemethodcontainsanumberofauthorizationstatuscodes,andtheseareexplained,alongwiththeirdescriptions,inthefollowingtable:

Authorizationstatus Description

.AuthorizedAlwaysor

.AuthorizedWhenInUse

Eitherofthesecasescanoccurwhenevertheuserhasgrantedaccessforyourapptouselocationservices.Thesestatusesarebothmutuallyexclusive,asyoucanonlyreceiveonetypeofauthorizationatatime.

Page 166: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

.NotDetermined

Thisgenerallyhappenswhenevertheuserhasn'tmadeachoiceregardingwhetheryouriOSappcanbeginacceptinglocationupdates,andcanbecausediftheuserhasinstalledyourappforthefirsttimeandhasnotrunityet.

.Restrictedor

.Denied

Youwillgenerallyreceivethistypeofauthorizationstatusstatewhenevertheuserhasexplicitlydeniedaccesstoyourappfortheuseoflocationservices,orwhenlocationservicesarecurrentlyunavailable.

Note

IfyouareinterestedinfindingoutmoreinformationontheCLLocationManagerclass,pleaserefertotheXamarindeveloperdocumentationlocatedathttps://developer.xamarin.com/api/type/CoreLocation.CLLocationManager/.

14. Next,createtheGetDistanceTravelledmethod,whichacceptstwoparameterscontainingourlatandlonvalues,anddeclaresavariabledistance,whichcallstheDistanceFrommethodonournewLocationobject,todetermineourcurrentdistancefromtheendgoal.Wedividethedistanceby1000toconvertthedistancetravelledtometers:

//Calculatesthedistancebetweentwopoints

publicdoubleGetDistanceTravelled(doublelat,doublelon)

{

//Getthedistancetravelledfrom

//currentlocationtothepreviouslocation.

vardistance=newLocation.DistanceFrom(new

CLLocation(lat,lon))/1000;

returndistance;

}

15. Finally,createtheWalkLocationServiceclassfinalizer,whichwillbeusedtostopallupdatelistenereventsandfreethememoryusedwhenourclasshasbeensettonull:

//Stopsperforminglocationupdateswhenthe

//objecthasbeensettonull.

~WalkLocationService()

{

locationManager.StopUpdatingLocation();

}

}

}

NowthatwehavecreatedtheWalkLocationServiceclassfortheiOSportionofourTrackMyWalksapp,ournextstepistolearnhowtoprovideouriOSappwiththefunctionalitytoperformcontinuouslocationupdatesinthebackground.

Page 167: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Enablingbackgroundupdatesandgettingtheuser'scurrentlocationThisrelatestoworkingwithbackgroundlocationupdatestocontinuouslymonitorchangestotheuserlocationinthebackground.

Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. Double-clickontheInfo.plistfile,whichiscontainedwithintheTrackMyWalks.iOSproject,andensurethattheApplicationtabisshowing.

2. Next,scrolldowntothebottomofthepageandselectEnableBackgroundModesfromundertheBackgroundModessectiontoenablebackgroundupdates.

3. Then,ensurethattheLocationUpdatesoptionhasbeenselected,sothatXcodecanprovisionyourapptomonitorlocation-basedupdatesinthebackground:

4. NowthatwehavemodifiedourTrackMyWalks.iOSprojecttomonitorlocationupdatesinthebackground,weneedtodoonemorethingandtellXcodetohandleLocationupdates.Solet'sdothatnow.

5. EnsurethattheInfo.plistfileisdisplayedwithintheXamarinIDE,andthattheSourcetabisshowing.

6. Next,createthekeysNSLocationAlwaysUsageDescriptionandNSLocationWhenInUseUsageDescriptionbyclickingwithintheAddnewentrysection

Page 168: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

oftheInfo.plist.

7. Then,addTrackMyWalkswouldliketoobtainyourlocationasthestringdescriptionfortheValuefield,asshownintheprecedingscreenshot.

Next,weneedtoprovideourappwiththeabilitytomonitorlocationupdatesinthebackgroundforourTrackMyWalks.iOSproject.Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. EnsurethattheWalkLocationService.csfileisdisplayedwithinthecodeeditor.2. Next,locatetheGetMyLocationmethodandenterthefollowingcodesnippet:

//Methodtocalltostartgettinglocation

publicvoidGetMyLocation()

{

locationManager=newCLLocationManager();

//Checktoseeifwehavelocationservices

//enabled

if(CLLocationManager.LocationServicesEnabled)

{

//Setthedesiredaccuracy,inmeters

locationManager.DesiredAccuracy=1;

//iOS8hasadditionalpermission

Page 169: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//requirements

if(UIDevice.CurrentDevice.CheckSystemVersion(8,0))

{

//Performlocationchangeswithinthe

//background

locationManager.RequestAlwaysAuthorization();

}

//iOS9,comeswithanewmethodthat

//allowsustoreceivelocationupdates

//withintheback,whentheapphas

//suspended.

if(UIDevice.CurrentDevice.CheckSystemVersion(9,0))

{

locationManager.AllowsBackgroundLocationUpdates=

true;

}

//CLLocationManagerDelegateMethods

//Firedwheneverthereisachangein

//location

locationManager.LocationsUpdated+=(objectsender,

CLLocationsUpdatedEventArgse)=>

{

locationUpdated(e);

};

//Thiseventgetsfiredwheneverit

//detectsachange,i.e.,iftheuserhas

//turnedoffordisabledLocationBased

//Services.

locationManager.AuthorizationChanged+=(object

sender,CLAuthorizationChangedEventArgse)=>

{

didAuthorizationChange(e);

//Performlocationchangeswithin

//theforeground.

locationManager.RequestWhenInUseAuthorization();

};

}

}

Intheprecedingcodesnippet,wechecktheiOSversioncurrentlyrunningontheuser'sdevice,andusetheRequestAlwaysAuthorizationmethodcallonthelocationManagerclasstorequesttheuser'spermissiontoobtaintheircurrentlocation.IniOS9,AppledecidedtoaddanewmethodcalledAllowsBackgroundLocationUpdates,whichallowsthehandlingofbackgroundlocationupdates.Next,wealsoneedtoconfigureourAndroidportionofourTrackMyWalks.DroidprojectbymodifyingtheAndroidManifest.xmlfile.

Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. Double-clickontheAndroidManifest.xmlfile,whichiscontainedwithinthe

Page 170: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TrackMyWalks.Droidproject,andensurethattheSourcetabisselected,asshowninthefollowingscreenshot:

2. EnsurethattheAndroidManifest.xmlfileisdisplayedwithinthecodeeditor,andenterthefollowinghighlightedcodesections:

<?xmlversion="1.0"encoding="utf-8"?>

<manifestxmlns:android="http://schemas.

android.com/apk/res/android"

android:versionCode="1"android:versionName="1.0"

package="com.geniesoftstudios.trackmywalks">

<uses-sdkandroid:minSdkVersion="15"/>

<uses-permissionandroid:name="android.

permission.ACCESS_FINE_LOCATION"/>

<uses-permissionandroid:name="android.

permission.ACCESS_COARSE_LOCATION"/>

<uses-permissionandroid:name="android.

permission.INTERNET"/>

<applicationandroid:label="TrackMyWalks">

</application>

</manifest>

Intheprecedingcodesnippet,webeginbyaddingpermissionsthatwillallowour

Page 171: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TrackMyWalksAndroidapptoaccesslocationinformationforlocationupdates,aswellastheInternet.Googleisprettystrictaboutwhichpermissionsareallowed,andthesemustbeapprovedpriortoyourappbeingacceptedintotheGooglePlayStore.

Page 172: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkEntryViewModeltousethelocationserviceNowthatwehavecreatedourWalkLocationServiceforbothourAndroidandiOSimplementations,weneedtobeginmodifyingourViewModel,whichwillbeusedbyourWalkEntrypage,totakeadvantageofourLocationService.

Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. EnsurethattheWalkEntryViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalkEntryViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Diagnostics.Contracts;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassWalkEntryViewModel:WalkBaseViewModel

{

2. Next,wedeclarealocationServicevariablethatwillbeusedtoprovideareferencetoourIWalkLocationServiceandprovideourclasswithareferencetotheEventHandler,whichiscontainedwithinourIWalkLocationServiceinterfaceclass;thiswillcontainourlocationcoordinateinformationwheneverthelocationchanges.Toproceed,enterthefollowinghighlightedcodesections:

IWalkLocationServicelocationService;

string_title;

publicstringTitle

{

get{return_title;}

set

{

_title=value;

OnPropertyChanged();

SaveCommand.ChangeCanExecute();

}

}

string_notes;

publicstringNotes

Page 173: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

get{return_notes;}

set

{

_notes=value;

OnPropertyChanged();

}

}

double_latitude;

publicdoubleLatitude

{

get{return_latitude;}

set

{

_latitude=value;

OnPropertyChanged();

}

}

double_longitude;

publicdoubleLongitude

{

get{return_longitude;}

set

{

_longitude=value;

OnPropertyChanged();

}

}

double_kilometers;

publicdoubleKilometers

{

get{return_kilometers;}

set

{

_kilometers=value;

OnPropertyChanged();

}

}

string_difficulty;

publicstringDifficulty

{

get{return_difficulty;}

set

{

_difficulty=value;

OnPropertyChanged();

}

}

double_distance;

publicdoubleDistance

{

Page 174: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

get{return_distance;}

set

{

_distance=value;

OnPropertyChanged();

}

}

string_imageUrl;

publicstringImageUrl

{

get{return_imageUrl;}

set

{

_imageUrl=value;

OnPropertyChanged();

}

}

3. Inournextstep,wewillneedtomodifythecontentsofourWalksEntryViewModelclassconstructortodeclareandinitializeourlocationServicevariable,whichwillincludeourIWalkLocationServiceconstructorthatisretrievedfromtheXamarin.FormsDependencyServiceclass.WethenproceedtocalltheMyLocationmethodonourEventHandler,whichisdefinedwithintheIWalkLocationServiceinterface;thiswillreturnthegeographicallocationcoordinatesdefinedbytheirLatitudeandLongitudevalues.

4. LocatetheWalksEntryViewModelclassconstructorandenterthefollowinghighlightedcodesections:

publicWalkEntryViewModel(IWalkNavServicenavService):

base(navService)

{

Title="NewWalk";

Difficulty="Easy";

Distance=1.0;

//GetourLocationService

locationService

=DependencyService.Get<IWalkLocationService>();

//Checktoensurethatwehaveavalue

//forourobject

if(locationService!=null)

{

locationService.MyLocation+=(objectsender,

IWalkCoordinatese)=>

{

//ObtainourLatitudeandLongitude

//coordinates

Page 175: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Latitude=e.latitude;

Longitude=e.longitude;

};

}

//CallourServicetogetourGPSlocation

locationService.GetMyLocation();

}

Command_saveCommand;

publicCommandSaveCommand

{

get

{

return_saveCommand??(

_saveCommand=newCommand(async()=>

awaitExecuteSaveCommand(),ValidateFormDetails));

}

}

asyncTaskExecuteSaveCommand()

{

varnewWalkItem=newWalkEntries

{

Title=this.Title,

Notes=this.Notes,

Latitude=this.Latitude,

Longitude=this.Longitude,

Kilometers=this.Kilometers,

Difficulty=this.Difficulty,

Distance=this.Distance,

ImageUrl=this.ImageUrl

};

5. Then,welocateandmodifytheExecuteSaveCommandinstancemethodtofreethememoryusedbyourlocationServicevariablewhentheSavebuttonispressed.Thisisachievedbysettingthistonull,whichinturnwillcallthe~GetMyLocation()withintheiOSandAndroidclassde-constructor.Proceedtoenterthefollowinghighlightedcodesections:

//UponexitingourNewWalkEntryPage,

//weneedtostopcheckingforlocation

//updates

locationService=null;

//Here,wewillsavethedetailsentered

//inalaterchapter.

awaitNavService.PreviousPage();

}

//methodtocheckforanyformerrors

boolValidateFormDetails()

{

return!string.IsNullOrWhiteSpace(Title);

}

Page 176: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

publicoverrideasyncTaskInit()

{

awaitTask.Factory.StartNew(()=>

{

Title="NewWalk";

Difficulty="Easy";

Distance=1.0;

});

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingourWalkEntryViewModelsothatitcantakeadvantageofourWalkLocationService.

WethendeclaredalocationServicevariablethatwillbeusedtoprovideareferencetoourIWalkLocationServiceandprovideourclasswithareferencetotheEventHandler,whichiscontainedwithinourIWalkLocationServiceinterfaceclass;thiswillcontainourlocationcoordinateinformationwheneverthelocationchanges.

WealsomodifiedourWalkEntryViewModelclassconstructortoinitializeourlocationServicevariable,topointtotheIWalkLocationServiceconstructorthatisretrievedfromtheXamarin.FormsDependencyServiceclass,whichneedstobedonepriortocallingtheMyLocationmethodonourEventHandler,sothatitcanreturnthegeographicallocationcoordinates,definedbytheirLatitudeandLongitudevalues.

Finally,wesetourlocationServiceobjecttonulltostopcheckingforlocationupdates.

Page 177: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheDistanceTravelledViewModeltousethelocationserviceNowthatwehavemodifiedourMVVMViewModelforourWalkEntryViewModel,ournextstepistobeginmodifyingourDistTravelledViewModeltotakeadvantageofourWalkLocationServiceclass,thatwillbeusedtocalculatethedistancetravelled,andsavethisinformationbacktoourDistTravelledViewModel.

Let'stakealookathowwecanachievethisthroughthefollowingsteps:

1. EnsurethattheDistTravelledViewModel.csfileisdisplayedwithinthecodeeditor.

//

//DistTravelledViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassDistTravelledViewModel:

WalkBaseViewModel<WalkEntries>

{

WalkEntries_walkEntry;

2. Next,wedeclaredalocationServicevariablethatwillbeusedtoprovideareferencetoourIWalkLocationServiceandprovideourclasswithareferencetotheEventHandler,whichiscontainedwithinourIWalkLocationServiceinterfaceclass;thiswillcontainourlocationcoordinateinformationwheneverthelocationchanges.Toproceed,enterthefollowinghighlightedcodesections:

IWalkLocationServicelocationService;

publicWalkEntriesWalkEntry

{

get{return_walkEntry;}

set

{

_walkEntry=value;

OnPropertyChanged();

}

}

double_travelled;

publicdoubleTravelled

Page 178: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

get{return_travelled;}

set

{

_travelled=value;

OnPropertyChanged();

}

}

double_hours;

publicdoubleHours

{

get{return_hours;}

set

{

_hours=value;

OnPropertyChanged();

}

}

double_minutes;

publicdoubleMinutes

{

get{return_minutes;}

set

{

_minutes=value;

OnPropertyChanged();

}

}

double_seconds;

publicdoubleSeconds

{

get{return_seconds;}

set

{

_seconds=value;

OnPropertyChanged();

}

}

publicstringTimeTaken

{

get

{

returnstring.Format("{0:00}:{1:00}:{2:00}",

this.Hours,this.Minutes,this.Seconds);

}

}

3. Next,weneedtomodifytheDistTravelledViewModelclassconstructortodeclareandinitializeourlocationServicevariable;thiswillincludeourIWalkLocationServiceconstructor,whichisretrievedfromtheXamarin.FormsDependencyServiceclass.WethenproceedtocalltheMyLocationmethodonourEventHandler,whichisdefinedwithin

Page 179: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

theIWalkLocationServiceinterface;thiswillreturnthegeographicallocationcoordinates,definedbytheirLatitudeandLongitudevalues.

4. LocatetheDistTravelledViewModelclassconstructorandenterthefollowinghighlightedcode:

publicDistTravelledViewModel(IWalkNavServicenavService):

base(navService)

{

this.Hours=0;

this.Minutes=0;

this.Seconds=0;

this.Travelled=100;

locationService=DependencyService.Get

<IWalkLocationService>();

locationService.MyLocation+=(objectsender,

IWalkCoordinatese)=>

{

//DetermineDistanceTravelled

if(_walkEntry!=null)

{

vardistance=locationService.GetDistanceTravelled(

_walkEntry.Latitude,_walkEntry.Longitude);

this.Travelled=distance;

}

};

locationService.GetMyLocation();

}

5. Then,wecreatetheInitmethodwithinourDistTravelledViewModel,whichwillbeusedtoinitializetheDistanceTravelledwhenitiscalled.WeneedtospecifyandusetheTask.Factory.StartNewmethodtogivetheViewModelenoughtimetodisplaythepageonscreen,priortoinitializingtheContentPagecontentsandusingthepassed-inwalkDetailsforourmodel:

publicoverrideasyncTaskInit(WalkEntrieswalkDetails)

{

awaitTask.Factory.StartNew(()=>

{

WalkEntry=walkDetails;

});

}

Page 180: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Next,weneedtocreatetheBackToMainPagecommandpropertythatwillbeusedtobindtotheEndThisTrailbutton,whichwillrunanactionuponbeingpressed.Thisactionwillexecuteaclassinstancemethodtodeterminewhetherthecommandcanbeexecuted.

7. Ifthecommandcanbeexecuted,acallwillbemadetotheBackToMainPagemethodontheNavServicenavigationserviceclasstotaketheuserbacktotheTrackMyWalksmainpage;thisisdonebyremovingallexistingViewModelswithintheNavigationStack,exceptthefirstpage:

Command_mainPage;

publicCommandBackToMainPage

{

get

{

return_mainPage??(_mainPage=newCommand(

async()=>await

NavService.BackToMainPage()));

}

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingourDistanceTravelledViewModelsothatitcantakeadvantageofourWalkLocationService.WethendeclaredalocationServicevariablethatwillbeusedtoprovideareferencetoourIWalkLocationServiceandprovideourclasswithareferencetotheEventHandler,whichiscontainedwithinourIWalkLocationServiceinterfaceclass;thiswillcontainourlocationcoordinateinformationwheneverthelocationchanges.

WealsomodifiedourDistTravelledViewModelclassconstructortoinitializeourlocationServicevariabletopointtotheIWalkLocationServiceconstructorthatisretrievedfromtheXamarin.FormsDependencyServiceclass;thisneedstobedonepriortocallingtheMyLocationmethodonourEventHandler,sothatitcanreturnthegeographicallocationcoordinates,definedbytheirLatitudeandLongitudevalues.

Page 181: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheSplashPagetoregisterourViewModelsInthissection,weneedtoupdateourSplashPagetoregisterourViewModelsforourAndroidplatform;thiswillinvolvecreatinganewinstanceofthenavigationservice,andregisteringtheapplicationContentPageandViewModelmappings:

1. EnsurethattheSplashPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//SplashPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassSplashPage:ContentPage

{

publicSplashPage()

{

AbsoluteLayoutsplashLayout=newAbsoluteLayout

{

HeightRequest=600

};

varimage=newImage()

{

Source=ImageSource.FromFile("icon.png"),

Aspect=Aspect.AspectFill,

};

AbsoluteLayout.SetLayoutFlags(image,

AbsoluteLayoutFlags.All);

AbsoluteLayout.SetLayoutBounds(image,

newRectangle(0f,0f,1f,1f));

splashLayout.Children.Add(image);

Content=newStackLayout()

{

Children={splashLayout}

};

}

2. Next,locatetheOnAppearingmethodandenterthefollowinghighlightedcodesections:

protectedoverrideasyncvoidOnAppearing()

Page 182: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

base.OnAppearing();

//Delayforafewsecondsonthesplashscreen

awaitTask.Delay(3000);

//InstantiateaNavigationPagewiththe

//MainPage

varnavPage=newNavigationPage(newWalksPage()

{

Title="TrackMyWalks-Android"

});

navPage.BarBackgroundColor=Color.FromHex("#4C5678");

navPage.BarTextColor=Color.White;

//DeclareourDependencyServiceInterface

varnavService=DependencyService.Get<IWalkNavService>()

asWalkNavService;

navService.navigation=navPage.Navigation;

//RegisterourViewModelMappingsbetween

//ourViewModelsandViews(Pages).

navService.

RegisterViewMapping(typeof(WalksPageViewModel),

typeof(WalksPage));

navService.RegisterViewMapping(

typeof(WalkEntryViewModel),

typeof(WalkEntryPage));

navService.RegisterViewMapping(

typeof(WalksTrailViewModel),

typeof(WalkTrailPage));

navService.RegisterViewMapping(

typeof(DistTravelledViewModel)

,

typeof(DistanceTravelledPage));

//SettheMainPagetobeourWalksNavigationPage

Application.Current.MainPage=navPage;

}

}

}

Intheprecedingcodesnippet,webeginbycustomizingourNavigationBar,bysettingtheBackgroundandTextColorattributes,andthendeclaringavariablenavServicethatpointsto

Page 183: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

aninstanceofournavigationserviceasdefinedbyourassemblyattributeforourXamarin.FormsDependencyService,whichisdeclaredinourWalkNavServiceclass.

Inournextstep,wesetthenavService.navigationpropertytopointtoaninstanceoftheNavigationPageclassthatourwalksPage.navigationpropertycurrentlypointsto,andthiswillbeusedasthemainrootpage.

Finally,wecalltheRegisterViewMappinginstancemethodforeachofourViewModelsandspecifytheassociatedContentPageforeach.

Page 184: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheMainActivityclasstouseXamarin.Forms.MapsInthissection,weneedtoupdateourMainActivityClasstointegratewiththeXamarin.Forms.MapspackageforourAndroidplatform,sothatourViewModelscanusethistodisplaymappingcapabilities:

1. OpentheMainActivity.csfileandensurethatitisdisplayedwithinthecodeeditor.2. Next,locatetheOnCreatemethodandenterthefollowinghighlightedcodesections:

//

//MainActivity.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingAndroid.App;

usingAndroid.Content.PM;

usingAndroid.OS;

namespaceTrackMyWalks.Droid

{

[Activity(Label="TrackMyWalks.Droid",

Icon="@drawable/icon",Theme="@style/MyTheme",

MainLauncher=true,ConfigurationChanges=

ConfigChanges.ScreenSize|

ConfigChanges.Orientation)]

publicclassMainActivity:

global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity

{

protectedoverridevoidOnCreate(Bundle

savedInstanceState)

{

TabLayoutResource=Resource.Layout.Tabbar;

ToolbarResource=Resource.Layout.Toolbar;

base.OnCreate(savedInstanceState);

global::Xamarin.Forms.Forms.Init(this,

savedInstanceState);

//IntegrateXamarinFormsMaps

Xamarin.FormsMaps.Init(this,savedInstanceState);

LoadApplication(newApp());

}

}

}

Intheprecedingcodesnippet,webeginbyinitializingourMainActivityclasstousetheXamarin.Forms.Mapslibrary,sothatourTrackMyWalkssolutioncanusethemaps.Ifthisisomittedfromtheclass,theDistanceTravelledPagecontentpagewillnotdisplaythemap,and

Page 185: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

thereforewillnotworkasexpected.

Page 186: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheXamarin.FormsAppclasstouseplatformspecificsInthissection,weneedtoupdateourXamarin.Forms.AppclassbymodifyingtheconstructorinthemainAppclasstosettheMainPageinstance,dependingontheTargetPlatformthatourdeviceisrunning.ThisisextremelyeasywhenusingXamarin.Forms.

Let'stakealookathowwecanachievethisbyfollowingthesesteps:

1. OpentheTrackMyWalks.csfileandensurethatitisdisplayedwithinthecodeeditor.2. Next,locatetheAppmethodandenterthefollowinghighlightedcodesections:

//

//TrackMyWalks.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassApp:Application

{

publicApp()

{

//ChecktheDeviceTargetOSPlatform

if(Device.OS==TargetPlatform.Android)

{

//Therootpageofyourapplication

MainPage=newSplashPage();

}

elseif(Device.OS==TargetPlatform.iOS)

{

//Therootpageofyourapplication

varwalksPage=newNavigationPage(new

WalksPage()

{

Title="TrackMyWalks-iOS"

});

//SettheNavigationBarTextColorand

//BackgroundColor

walksPage.BarBackgroundColor=

Color.FromHex("#440099");

walksPage.BarTextColor=Color.White;

//DeclareourDependencyServiceInterface

varnavService=DependencyService.

Get<IWalkNavService>()asWalkNavService;

navService.navigation=walksPage.Navigation;

Page 187: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//RegisterourViewModelMappings

//betweenourViewModelsandViews(Pages)

navService.RegisterViewMapping(

typeof(WalksPageViewModel),typeof(WalksPage));

navService.RegisterViewMapping(

typeof(WalkEntryViewModel),

typeof(WalkEntryPage));

navService.RegisterViewMapping(

typeof(WalksTrailViewModel),

typeof(WalkTrailPage));

navService.RegisterViewMapping(typeof(

DistTravelledViewModel),

typeof(DistanceTravelledPage));

//SettheMainPagetobeour

//WalksNavigationPage

MainPage=walksPage;

}

}

protectedoverridevoidOnStart()

{

//Handlewhenyourappstarts

}

protectedoverridevoidOnSleep()

{

//Handlewhenyourappsleeps

}

protectedoverridevoidOnResume()

{

//Handlewhenyourappresumes

}

}

}

Intheprecedingcodesnippet,weusetheTargetPlatformclassthatcomesaspartoftheXamarin.Forms.Corelibrary,andwecheckthisagainsttheDevice.OSclassandhandleitaccordingly.

TheTargetPlatformmethodcontainsanumberplatformcodes,whichareexplainedalongwiththeirdescriptionsinthefollowingtable:

Platformname Description

Android ThisindicatesthattheXamarin.FormsplatformisrunningonadevicethatisrunningtheAndroidoperatingsystem.

Page 188: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

iOS ThisindicatesthattheXamarin.FormsplatformisrunningonadevicethatisrunningtheAppleiOSoperatingsystem.

Windows ThisindicatesthattheXamarin.FormsplatformisrunningonadevicethatisrunningtheWindowsplatform.

WinPhone ThisindicatesthattheXamarin.FormsplatformisrunningonadevicethatisrunningtheMicrosoftWinPhoneOS.

Note

FormoreinformationontheDeviceclass,refertotheXamarindocumentationathttps://developer.xamarin.com/guides/xamarin-forms/platform-features/device/.

NowthatwehaveupdatedthenecessaryMVVMViewModelstotakeadvantageofourWalkLocationService,ournextstepistofinallybuildandruntheTrackMyWalksapplicationwithintheiOSsimulator.Whencompilationcompletes,theiOSsimulatorwillappearautomaticallyandtheTrackMyWalksapplicationwillbedisplayed,asshowninthefollowingscreenshot:

Page 189: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,thisdisplaysourcurrentlistofwalktrailentries,whicharedisplayedwithinourListView.WhentheuserclicksontheAddWalkbuttonlink,thiswilldisplaytheNewWalkEntrycontentpage,andwilldisplaythecurrentuser'sgeolocationcoordinatesfortheLatitudeandLongitudeEntryCellpropertiescontainedwithinourWalkEntryViewModel.Theprecedingscreenshot,thisshowsthedistancetravelledpagealongwiththeplaceholderpinmarkershowingthetraillocationwithinthemapView.YouwillnoticethattheDistanceTravelledsectionhasbeenupdatedandshowsthedistancetravelledbytheuserthatiscalculatedbytheGetDistanceTravelledmethodcontainedwithinourIWalkLocationServiceinterface.

Page 190: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,weupdatedourTrackMyWalksapplication,andcreatedaLocationServiceclassthatextendedthedefaultnativecoreLocationServicesclassesforiOSandAndroid,whichprovidesuswithabettermethodofcapturinggeolocationcoordinateswithintheViewModel.

Inthenextchapter,you'lllearnaboutcustomrenderersandhowyoucanusethemtochangetheappearanceofthecontrolelementswithintheuserinterfacethattargetaspecificplatform.

YouwilllearnhowtoworkwithDataTemplatesbycreatingaC#classtolayoutyourviewsbeautifullythroughoutyourapplication,andworkwiththeplatform-specificAPIstoextendthedefaultbehaviorofXamarin.Formscontrolsthroughtheuseofcustomrenderers,bycreatingacustompickercontrolforiOS.

WewillalsobecoveringhowyoucanusetheXamarin.FormsEffectsAPItocustomizetheappearanceandstylingofnativecontrolelementsforeachplatform,byimplementingacustomrendererclass,andmanipulatethevisualappearanceofdatathatisbound,throughtheuseofValueandImageConverters.

Page 191: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter5.CustomizingtheUserInterfaceInourpreviouschapter,welookedathowwecanincorporateplatform-specificfeatureswithintheTrackMyWalksapp,whichisdependentonthemobileplatform.YoulearnedhowtocreateaC#class,whichactedasalocationservicethatincludedanumberofclassmethodsforbothiOSandAndroidplatforms.

Wealsocoveredhowtoproperlyperformlocationupdateswhethertheapplication'sstateisintheforegroundorbackgroundbyregisteringtheappasabackground-necessaryapplication.

Inthischapter,you'lllearnhowtoworkwiththeDataTemplateCustomRendererbycreatingaC#classtolayoutyourviewsbeautifullywithinyourapplications,andyouwillalsogetaccustomedtoworkingwithplatform-specificAPIstoextendthedefaultbehaviorofXamarin.Forms'controlsthroughtheuseofcustomrenderers,bycreatingacustompicker.

WewillalsobecoveringhowtousetheXamarin.FormsEffectsAPItocustomizetheappearanceandstylingofnativecontrolelementsforeachplatform,byimplementingaCustomRendererclass.We'lllookathowtomanipulatethevisualappearanceofdatathatisbound,throughtheuseofvalueandimageconverters.

Thischapterwillcoverthefollowingpoints:

CreatingacustomDataTemplateclasswhichutilizesnativeplatformcapabilities,thatcomeaspartoftheiOSandAndroidplatformsWorkingwithcustomrendererstochangetheappearanceofcontrolelementsUsingtheplatformEffectsAPItochangetheappearanceofcontrolelementsWorkingwithBooleanandstringtoimagevalueconvertersUpdatingthewalkscontentpageapplicationtousethedatatemplateUpdatingtheWalkEntrycontentpagetousetheCustomRendererUpdatingtheDistanceTravelledcontentpagetousetheEffectsAPI

Page 192: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheDataTemplateclassfortheTrackMyWalksappOneofthefeaturesoftheXamarin.Formstoolkitistheabilitytomanipulatetheuserinterfacebyleveragingthevariousplatform-specificAPIsthatareavailable,whetheritbemanipulatingtheappearanceofcontrolsandtheirelementsusingcustomrenderers,orchangingtheappearanceandstylingofnativecontrolelements.

Inthissection,wewillbeworkingwiththeXamarin.Formsdatatemplates,whichwillprovidetheabilitytodefinethepresentationofdata.Let'sbeginbycreatinganewfoldercalledDataTemplates,withinourTrackMyWalkssolution,whichwillbeusedtorepresentourDataTemplates,byfollowingthesesteps:

1. LaunchtheXamarinStudioapplication,andensurethattheTrackMyWalkssolutionisloadedwithintheXamarinStudioIDE.

2. Next,createanewfolder,withintheTrackMyWalksPortableClassLibraryproject,calledDataTemplatesasshowninthefollowingscreenshot:

3. Next,createanemptyclasswithintheDataTemplatesfolder.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingtheNavigationServiceInterface

Page 193: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

fortheTrackMyWalksapp,withinChapter3,NavigatingwithintheMVVMmodel-TheXamarin.FormsWay.

4. Then,choosetheEmptyClassoptionlocatedwithintheGeneralsection,andenterWalkCellDataTemplateasthenameofthenewclassfile,asshowninthefollowingscreenshot:

5. Next,clickontheNewbuttontoallowthewizardtocreatethenewemptyclassfile,asshownintheprecedingscreenshot.

6. OurnextstepistobegincreatingandimplementingthecodeforourWalkCellDataTemplateclass;performthefollowingsteps.

7. EnsurethattheWalkCellDataTemplate.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//WalkCellDataTemplate.cs

//TrackMyWalksDataTemplateforCells

//

//CreatedbyStevenF.Danielon01/10/2016.

Page 194: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.Converters;

usingXamarin.Forms;

namespaceTrackMyWalks.Controls

{

publicclassWalkCellDataTemplate:ViewCell

{

publicWalkCellDataTemplate()

{

varwalkTrailImage=newImage

{

WidthRequest=140,

HeightRequest=140,

HorizontalOptions=LayoutOptions.FillAndExpand,

VerticalOptions=LayoutOptions.FillAndExpand,

Aspect=Aspect.Fill

};

walkTrailImage.SetBinding(Image.SourceProperty,

"ImageUrl");

varTrailNameLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=16,

TextColor=Color.Black

};

TrailNameLabel.SetBinding(Label.TextProperty,

"Title");

vartotalKilometersLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.FromHex("#666")

};

totalKilometersLabel.SetBinding(Label.TextProperty,

"Kilometers",stringFormat:"Kilometers:{0}");

vartrailDifficultyLabel=newLabel()

{

FontAttributes=FontAttributes.Bold,

FontSize=12,

TextColor=Color.Black

};

trailDifficultyLabel.SetBinding(Label.TextProperty,

"Difficulty",stringFormat:"Difficulty:{0}");

vartrailDifficultyImage=newImage

{

HeightRequest=50,

WidthRequest=50,

Aspect=Aspect.AspectFill,

Page 195: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

HorizontalOptions=LayoutOptions.Start

};

trailDifficultyImage.SetBinding(Image.SourceProperty,

"Difficulty",converter:new

TrailImageConverter());

varnotesLabel=newLabel()

{

FontSize=12,

TextColor=Color.Black

};

notesLabel.SetBinding(Label.TextProperty,"Notes");

varnotesStack=newStackLayout()

{

Spacing=3,

Orientation=StackOrientation.Vertical,

VerticalOptions=LayoutOptions.FillAndExpand,

Children={notesLabel}

};

varstatusLayout=newStackLayout

{

Orientation=StackOrientation.Vertical,

Children={totalKilometersLabel,

trailDifficultyLabel,

trailDifficultyImage

}

};

varDetailsLayout=newStackLayout

{

Padding=newThickness(10,0,0,0),

Spacing=0,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children={TrailNameLabel,statusLayout,

notesStack

}

};

varcellLayout=newStackLayout

{

Spacing=0,

Padding=newThickness(10,5,10,5),

Orientation=StackOrientation.Horizontal,

HorizontalOptions=LayoutOptions.FillAndExpand,

Children={walkTrailImage,DetailsLayout}

};

this.View=cellLayout;

}

}

}

Page 196: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Intheprecedingcodesnippet,webeganbyensuringthatourclassinheritsfromtheXamarin.FormsViewCellclassrenderer,andisessentiallyacellthatcanbeaddedtoanyListVieworTableViewcontrolthatcontainsadefinedview.WhenworkingwithXamarin.Forms,andtheViewCellclass,everycellhasanaccompanyingrendererthatisassociatedwitheachplatformthatcreatesaninstanceofanativecontrol.WheneveraViewCellclassisrenderedundertheiOSplatform,theViewCellRendererclasswillinstantiatethenativeUITableViewCellcontrol.Alternatively,undertheAndroidplatform,theViewCellRendererclassinstantiatesanativeViewcontrol.

Finally,ontheWindowsPhoneplatform,theViewCellRendererclassinstantiatesanativeDataTemplatecontrol.Next,wecreatethecelllayoutinformationusingtheStackLayoutcontrol,andthenusetheSetBindingpropertytocreateandbindeachofourmodelvaluestoaspecificproperty.Finally,wedefineacellLayoutvariablethatusestheStackLayoutcontrol,toaddeachofourchildelementsandthenassigntheresultingcellLayouttotheclassView.

Note

IfyouareinterestedinfindingoutmoreinformationaboutDataTemplates,pleaserefertotheXamarindeveloperdocumentationlocatedathttps://developer.xamarin.com/guides/xamarin-forms/templates/data-templates/.

NowthatwehavecreatedourWalkCellDataTemplate,thenextstepistomodifythewalksmainpagesothatitcanmakeuseofthisclass.

Page 197: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthewalksmainpagetousethedatatemplateIntheprevioussection,wecreatedtheclassforourWalkCellDataTemplate,aswellasdefiningthelayoutinformationforeachofthecontrolelementsthatwewouldliketohavedisplayedwithinourView.

Inthissection,wewilltakealookathowtoimplementthenecessarycodechangessothattheWalksPageContentPagecantakeadvantageofourWalkCellDataTemplateclass.

Let'stakealookathowwecanachievethis,byfollowingthesteps:

1. EnsurethattheWalksPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesectionsasshowninthefollowingcodesnippet:

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

usingTrackMyWalks.DataTemplates;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage

{

WalksPageViewModel_viewModel

{

get{returnBindingContextasWalksPageViewModel;}

}

publicWalksPage()

{

varnewWalkItem=newToolbarItem

{

Text="AddWalk"

};

...

...

...

//DefineourDataTemplateClass

varwalksList=newListView

{

HasUnevenRows=true,

ItemTemplate=newDataTemplate(typeof(

WalkCellDataTemplate)),

Page 198: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SeparatorColor=(Device.OS

==TargetPlatform.iOS)?

Color.Default:Color.Black

};

...

...

...

}

}

Intheprecedingcodesnippet,webeganbyincludingareferencetoourDataTemplatesclass,viatheusingstatement.ThenwepassedintheWalkCellDataTemplatedatatemplatetotheDataTemplateclassobject,whichwillbeassignedtotheItemTemplatepropertyoftheListViewclass.Next,dependingontheoperatingsystemwearerunningon,we'llsettheseparatorcolorforourTableView.

Page 199: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,thiswillshowyoualistofourcurrentwalkstrailentries,whicharenicelyrenderedusingtheDataTemplate,anddisplayedwithintheListViewcontrol.

Inournextsection,youwillseehowwecangoaboutcreatingacustompickerforourWalkEntrycontentpage,sothatwecandisplayalistofdifficultychoicesfortheusertochoosefrom.

Page 200: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingaTableViewEntryCellcustompickerfortheiOSplatformOurTrackMyWalksappusesaTableViewwithEntryCellstopresentaformtotheusertoaddnewwalkentrieswithintheWalkEntryPage.Currently,thedifficultyfieldwithintheformisusingtheregularEntryCellcontrol,whichpresentstheuserwithaneditabletextfieldusingthedefaultkeyboard.

Asyoucanimagine,thisisnottheidealuserexperiencethatweareafter,asthiscancauseissueswhenitcomestovalidatingtheinformationentered.Ourgoalistopresenttheuserwithastandard,customplatform-specificpickerthatcontainsanumberofchoicestheusercanchoosefrom.

Inthissection,wewillbecreatingacustomrendererthatwillextendtheEntryCellRenderertodisplayanEntryCellthatwillbehavemuchlikethestandardpickercontrol.Sincewedon'twantourpickertorenderalloftheEntryCellswithintheWalkEntryPage,wewillneedtocreateacustomEntryCellcontrolthatthecustomrendererwillassociatedwith.

Let'stakealookathowwecanachievethis,byfollowingthesteps:

1. CreateanewfolderwithintheTrackMyWalksPortableClassLibraryproject,calledControlsandthencreateanemptyclasswithintheControlsfolder.

2. Next,choosetheEmptyClassoptionlocatedwithintheGeneralsection,andenterDifficultyPickerEntryCellasthenameofthenewclassfiletocreate.

3. Next,onceyouhavecreatedtheDifficultyPickerEntryCellclassfile,ensurethattheDifficultyPickerEntryCell.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//DifficultyPickerEntryCell.cs

//TrackMyWalksCustomRendererforDifficultyEntryCells

//

//CreatedbyStevenF.Danielon01/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingXamarin.Forms;

namespaceTrackMyWalks.Controls

{

4. Then,weneedtomodifytheDifficultyPickerEntryCellclassconstructorsignature,sothatitinheritsfromtheXamarin.Forms.EntryEntryCellclass,sincetheWalkEntryPagecontainsanumberofEntryCellcontrols:

publicclassDifficultyPickerEntryCell:EntryCell{

5. Next,weneedtocreateastringBindablePropertysothatthecustomcontrolcanbedata-

Page 201: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

boundjustlikeourothercontrols:

publicstaticreadonlyBindablePropertyDifficultyProperty=

BindableProperty.Create<DifficultyPickerEntryCell,

String>(p=>p.Difficulty,"Easy",propertyChanged:

newBindableProperty.BindingPropertyChangedDelegate<String>

(DifficultyPropertyChanged));

6. Then,wecreateaDifficultypropertysothat,whenthevalueschangeswithinthecustomcontrol,itcanreturnthevaluebacktoourEntryCell:

publicStringDifficulty

{

get{return(String)GetValue(DifficultyProperty);}

set{SetValue(DifficultyProperty,value);}

}

7. Next,wecreateaCompletedEventHandlerthatwillbeusedinrelationtotheDifficultyPropertyChangedevent,sowecanrespondtotheCompletedeventsonourDifficultyPickerEntryCell:

publicneweventEventHandlerCompleted;

staticvoidDifficultyPropertyChanged(BindableObjectbindable,

StringoldValue,StringnewValue)

{

var@this=(DifficultyPickerEntryCell)bindable;

if(@this.Completed!=null)

@this.Completed(bindable,newEventArgs());

}

}

}

NowthatwehavecreatedtheDifficultyPickerEntryCellclassfortheiOSportionofourTrackMyWalksapp,ournextstepistocreatethecustompickerrendererfortheiOSplatform,whichwewillbecoveringinthenextsection.

Page 202: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingthecustompickerrendererclassfortheiOSplatformIntheprevioussection,wecreatedaclassfortheDifficultyPickerEntryCell,aswellasdefininganumberofdifferentdata-bindablepropertymethodsthatwillbeusedtohandletheuserchoosinganitemwithinourcustompicker.

Inthissection,wewillbuildthecustompickerrenderermodelthatwillbeusedbytheiOSportionoftheDifficultyPickerEntryCell.Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. CreateanewfolderwithintheTrackMyWalks.iOSproject,calledRenderers.2. Next,createanemptyclasswithintheRenderersfolderforourTrackMyWalks.iOS

project,andenterDifficultyPickerModelasthenameofthenewclassfiletocreate.3. Then,ensurethattheDifficultyPickerModel.csfileisdisplayedwithinthecodeeditor,

andenterinthefollowingcodesnippet:

//

//DifficultyPickerModel.cs

//TrackMyWalksLevelModelforUIPickerViewModel(iOS)

//

//CreatedbyStevenF.Danielon01/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingUIKit;

namespaceTrackMyWalks.iOS.Renderers

{

4. Next,weneedtomodifytheDifficultyPickerModelclassconstructorsignature,sothatitinheritsfromtheUIPickerViewModelinterfaceclass,aswellasdeclaringourdifficultyStringobjectwhichcontainsavalidlistofchoicesfortheusertochoosefrom:

//DeclareourDifficultyPickerModelClass

publicclassDifficultyPickerModel:UIPickerViewModel

{

//Defineourlistofdifficultylevels

staticpublicstring[]difficulty=newstring[]

{

"Easy",

"Moderate",

"Challenging",

"Difficult",

"VeryDifficult",

"Extreme"

};

5. Then,weneedtocreatetheGetComponentCountmethod,whichacceptsapickerView

Page 203: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

objectthattellstheUIPickerViewhowmanycomponentsweareexpectingourcustompickertocontain:

publicoverridenintGetComponentCount(UIPickerViewpickerView)

{

return1;

}

6. Next,weneedtocreatetheGetRowsInComponentmethodthatacceptsapickerViewobjectandacomponentvalue.ThismethodworksouthowmanyrowstodisplaywithinourUIPickerViewcustomcontrol,whichisderivedfromthedifficultystringarray.Thecomponentparameterdetermineswhichsectiontodisplaythosevaluesin:

publicoverridenintGetRowsInComponent(UIPickerViewpickerView,

nintcomponent)

{

returndifficulty.Length;

}

7. Finally,weneedtocreatetheGetTitlemethod,whichacceptsapickerViewobject,arowparameter,andacomponentvalue.Thismethodisusedtodisplaythetitleinformationforeachrowcontainedwithinourdifficultyarray:

publicoverridestringGetTitle(UIPickerViewpickerView,

nintrow,nintcomponent)

{

returndifficulty[row];

}

}

}

Upuntilthispoint,allwehavedoneiscreateourmodelforourDifficultyPicker,whichactsasthebasemodelneededbyourDifficultyPickerCellRendererclass.OurnextstepistocreatetheDifficultyPickerCellRendererthatwillusethemodelfortheiOSplatformtodisplayacustomlistofentriesfortheusertochoosefrom.

1. CreateanemptyclasswithintheRenderersfolderfortheTrackMyWalks.iOSproject,andenterinDifficultyPickerCellRendererasthenameofthenewclassfiletocreate.

2. Next,ensurethattheDifficultyPickerCellRenderer.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//DifficultyPickerCellRenderer.cs

//TrackMyWalksCustomRendererforUIPickerViewEntryCells

(iOS)

//

//CreatedbyStevenF.Danielon01/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms.Platform.iOS;

usingUIKit;

usingTrackMyWalks.Controls;

Page 204: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

usingXamarin.Forms;

usingTrackMyWalks.iOS.Renderers;

3. Then,weneedtoinitializeourDifficultyCellRendererclasstobemarkedasanExportRendererbyincludingtheExportRendererassemblyattributeatthetopofourclassdefinition.ThisletsourclassknowthatitinheritsfromtheViewRendererclass:

[assembly:ExportRenderer(typeof(DifficultyPickerEntryCell),

typeof(DifficultyPickerCellRenderer))]

namespaceTrackMyWalks.iOS.Renderers

{

4. Next,weneedtomodifytheDifficultyCellRendererclassconstructorsignature,sothatitcaninheritfromtheEntryCellRendererclass:

publicclassDifficultyPickerCellRenderer:EntryCellRenderer

{

5. Then,weneedtooverridetheEntryCellRendererGetCellmethodsothatitcanoverridethedefaultbehavioroftheEntryCellforiOSbysettingtheInputViewoftheUITextFieldtoaUIPickerViewclassinstance:

publicoverrideUITableViewCellGetCell(Cellitem,

UITableViewCellreusableCell,UITableViewtv)

{

varcell=base.GetCell(item,reusableCell,tv);

varentryPickerCell=(EntryCell)item;

UITextFieldtextField=null;

if(cell!=null)

textField=(UITextField)cell.ContentView.Subviews[0];

6. Next,wecreateaninstancetoouriOSUIPickerViewnativecontrol,thatpointstotheDifficultyPickerModel;andthenwecreateatoolbarthatwillcontainaDonebuttonandwillprovideuswithamechanismtoupdatetheEntryCellUITextFieldwiththechosenvaluefromthedifficultyPickerobject.Thendismissthecustompickercontrol:

//CreateouriOSUIPickerViewNativeControl

vardifficultyPicker=newUIPickerView

{

AutoresizingMask=UIViewAutoresizing.FlexibleWidth,

ShowSelectionIndicator=true,

Model=newDifficultyPickerModel(),

BackgroundColor=UIColor.White,

};

//Createatoolbarwithadonebuttonthatwill

//settheselectedvaluewhenclosed.

vardone=newUIBarButtonItem("Done",

UIBarButtonItemStyle.Done,(s,e)=>

{

//UpdatethevalueoftheUITextFieldwithin

//theCell.

if(textField!=null)

Page 205: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

textField.Text=DifficultyPickerModel.difficulty

[difficultyPicker.SelectedRowInComponent(0)];

textField.ResignFirstResponder();

}

});

vartoolbar=newUIToolbar

{

BarStyle=UIBarStyle.BlackTranslucent,

Translucent=true

};

toolbar.SizeToFit();

toolbar.SetItems(new[]{done},true);

7. Then,wesettheinputviewandtoolbarandaninitialdefaultvaluefortheEntryCell'sTextFieldifnothinghasbeenchosen.ThisisdonebysettingtheInputViewoftheUITextFieldtoaUIPickerViewclassinstance:

//Settheinputview,toolbarandinitialvalue

//fortheCell'sUITextField.

if(textField!=null)

{

textField.InputView=difficultyPicker;

textField.InputAccessoryView=toolbar;

textField.Font=UIFont.FromName("Courier",16);

textField.BorderStyle=UITextBorderStyle.Bezel;

textField.TextColor=UIColor.Red;

8. Finally,ifwehaveselectedadifficultyvaluefromourUIPickerViewcontrol,wefirstneedtoensurethatwehavechosenavalue,andthenassignthisvaluetotheDifficultyEntryCellfieldwithintheentryform:

if(entryPickerCell!=null)

{

textField.Text=DifficultyPickerModel.difficulty

[difficultyPicker.SelectedRowInComponent(0)];

}

}

returncell;

}

}

}

Note

IfyouareinterestedinfindingoutmoreinformationabouttheUIPickerViewclass,pleaserefertotheXamarindeveloperdocumentationathttps://developer.xamarin.com/api/type/MonoTouch.UIKit.UIPickerView/.

NowthatwehavecreatedtheDifficultyPickerCellRendererclassfortheiOSportionofourTrackMyWalksapp,ournextstepistoimplementthiswithintheWalkEntrycontentpage.

Page 206: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksEntryPagetousethecustompickerrendererIntheprevioussection,wecreatedtheclassforourDifficultyPickerCellRenderer,aswellasdefiningthevariousmethodsthatwillhandlethedisplayoftheUIPickerViewcontrolwhenanEntryCellwithintheViewModelhasbeentapped.

Inthissection,wewilltakealookathowtoimplementthecodechangesrequiredsothattheWalkEntryPagecontentpagecantakeadvantageoftheDifficultyPickerCellRendererclass.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

EnsurethattheWalkEntryPage.csfileisdisplayedwithinthecodeeditor,andenterthefollowinghighlightedcodesectionsasshowninthefollowingcodesnippet:

//

//WalkEntryPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Services;

usingTrackMyWalks.Controls;

namespaceTrackMyWalks

{

publicclassWalkEntryPage:ContentPage

{

WalkEntryViewModel_viewModel

{

get{returnBindingContextasWalkEntryViewModel;}

}

publicWalkEntryPage()

{

//SettheContentPageTitle

Title="NewWalkEntry";

//DeclareandinitializeourModelBindingContext

BindingContext=newWalkEntryViewModel

(DependencyService

.Get<IWalkNavService>());

...

...

...

varwalkDifficulty=newDifficultyPickerEntryCell

{

Label="DifficultyLevel:",

Page 207: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Placeholder="WalkDifficulty"

};

walkDifficulty.SetBinding(

DifficultyPickerEntryCell.DifficultyProperty,

"Difficulty",BindingMode.TwoWay);

...

...

...

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingourWalkEntryPagetotakeadvantageoftheDifficultyPickerEntryCellclasscustomrenderer.WelookedatupdatingthewalkDifficultyobjectvariable,toreferencetheDifficultyPickerEntryCellclass,andupdatedthesetBindingtoreturnthevaluefromtheDifficultyPropertythatisimplementedwithintheDifficultyPickerEntryCellclass.

Page 208: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,thisshowsourcustomUIPickerViewcontrol,populatedwiththeentriesfromtheDifficultyPickerModel,aswellastheDonebuttondisplayedastheheader.ScrollingthroughthelistofchoicesoperatesinthesamewayasyouwouldexpectunderiOS;clickingontheDonebuttonwillpopulatetheDifficultyLevelUITextFieldwiththehighlightedchoicewithintheUIPickerViewcontrol.

Inournextsection,wewillfocusonhowwecanusetheXamarin.FormsEffectsAPItocustomizetheappearanceandstylingofnativecontrolelementsforboththeiOSandAndroidplatformsbyimplementingacustomrendererclass.Youwillnoticethattheimplementationsforbothoftheseclassesarequitesimilar.However,theseimplementdifferentmethods,asyouwillseeoncewestartimplementingthem.

Page 209: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingPlatformEffectsusingtheEffectsAPIfortheiOSplatformInthissection,wewillbuildtheiOSportionofourPlatformEffects,whichwillallowustocustomizetheappearanceoftheXamarin.Formscontrolelements.Wewillbecreatingtwocompletelydifferentplatformeffects-LabelShadowandButtonShadow,forboththeiOSandAndroidplatforms.

Let'stakealookathowwecanachievethis,byfollowingthesesteps:

1. CreateanewfolderwithintheTrackMyWalks.iOSproject,calledPlatformEffects.2. Next,createanemptyclasswithinthePlatformEffectsfolderforourTrackMyWalks.iOS

project.3. Then,enterButtonShadowEffectasthenameofthenewclassfiletocreate,ensurethatthe

ButtonShadowEffect.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//ButtonShadowEffect.cs

//TrackMyWalksButtonShadowEffect(iOS)

//

//CreatedbyStevenF.Danielon02/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.iOS.PlatformEffects;

usingUIKit;

usingXamarin.Forms;

usingXamarin.Forms.Platform.iOS;

4. Next,weinitializetheButtonShadowEffectclassassemblytobemarkedwithtwoimportantattributesforourclasssothatitcanbeusedasaneffectwithintheTrackMyWalksapplication:

[assembly:ResolutionGroupName("com.geniesoftstudios")]

[assembly:ExportEffect(typeof(ButtonShadowEffect),

"ButtonShadowEffect")]

namespaceTrackMyWalks.iOS.PlatformEffects

{

5. Then,weneedtomodifyourButtonShadowEffectclassconstructorsothatitcaninheritfromthePlatformEffectclassandaccesseachoftheplatform-specificimplementationsofthePlatformEffectclass:

publicclassButtonShadowEffect:PlatformEffect

{

6. Next,wecreatetheOnAttachedmethodthatwillbecalledwheneveranaffectisattachedtoaXamarin.FormscontrolandthenusetheContainerpropertytoreferencetheplatform-specificcontrolthatisusedtoimplementthelayout:

Page 210: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

protectedoverridevoidOnAttached()

{

Container.Layer.ShadowOpacity=0.5f;

Container.Layer.ShadowColor=UIColor.Black.CGColor;

Container.Layer.ShadowRadius=2;

}

7. Then,wecreatetheOnDetachedmethod,whichwillbecalledwheneveraneffectisdetachedfromaXamarin.Formscontroltoperformanyeffectclean-up.Here,inthismethod,wesettheShadowOpacityoftheContainerpropertytozero:

protectedoverridevoidOnDetached()

{

Container.Layer.ShadowOpacity=0;

}

}

}

Eachplatform-specificPlatformEffectclassexposesanumberofpropertiesandtheseareexplainedinthefollowingtable:

Platformeffect Description

ContainerThisparticulartypereferencestheplatform-specificcontrolthatisbeingusedtoimplementthelayout.

ControlThistypereferencestheplatform-specificcontrolthatisbeingusedtoimplementtheXamarin.Formscontrol.

Element ThistypereferencestheXamarin.Formscontrolthatiscurrentlybeingrendered.

WheneveryoucreateyourownPlatformEffects,theseinheritfromthePlatformEffectclass,whichisdependentontheplatformthatisbeingrun.However,theAPIforaneffectisprettymuchidenticalacrosseachoftheplatformsastheyderivefromthePlatformEffect<T,T>andcontaindifferentgenericparameters.TherearealsotwoveryimportantattributesthatyouneedtosetforeachclassthatsubclassesfromthePlatformEffectclass,andtheseareexplainedinthefollowingtable:

Attributetype Description

ResolutionGroupName

Thisattributesetsacompany-widenamespaceforeffects,preventingcollisionswithothereffectswiththesamename.Itisworthmentioning

Page 211: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

that,ifyoucreatemultiplePlatformEffects,youcanonlyapplythisattributeonceperproject.

ExportEffect

ThisattributeregisterstheeffectusingauniqueIDandisusedbytheXamarin.Formsplatformalongwiththegroupname.Theattributetakestwoparameters:thetypenameoftheeffect,andauniquestringthatwillbeusedtolocatetheeffectpriortoapplyingittoacontrol.

Note

IfyouareinterestedinfindingoutmoreinformationaboutthePlatFormEffectclass,pleaserefertotheXamarindeveloperdocumentationathttps://developer.xamarin.com/guides/xamarin-forms/effects/.

NowthatwehavecreatedtheButtonShadowEffectclass,ournextstepistocreatetheLabelShadowEffectfortheiOSportionofourTrackMyWalksapp:

1. Next,createanemptyclasswithinthePlatformEffectsfolderfortheTrackMyWalks.iOSprojectandenterLabelShadowEffectasthenameofthenewclassfiletocreate.

2. Then,ensurethattheLabelShadowEffect.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//LabelShadowEffect.cs

//TrackMyWalksLabelShadowEffect(iOS)

//

//CreatedbyStevenF.Danielon02/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingCoreGraphics;

usingTrackMyWalks.iOS.PlatformEffects;

usingXamarin.Forms;

usingXamarin.Forms.Platform.iOS;

3. Next,weinitializetheLabelShadowEffectclassassemblytobemarkedwiththeExportEffectattributesothatitcanbeusedasaneffectwithintheTrackMyWalksapplication:

[assembly:ExportEffect(typeof(LabelShadowEffect),

"LabelShadowEffect")]

namespaceTrackMyWalks.iOS.PlatformEffects

{

4. Then,weneedtomodifytheLabelShadowEffectclassconstructorsothatitcaninheritfromthePlatformEffectclass,andaccesseachoftheplatform-specificimplementationsofthePlatformEffectclass:

publicclassLabelShadowEffect:PlatformEffect{

Page 212: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Next,wecreatetheOnAttachedmethodthatwillbecalledwheneveranaffectisattachedtoaXamarin.FormscontrolandthenusetheControlpropertytoreferencetheplatform-specificcontrolthatwillbeusedtochangetheappearanceofthecontrol.

protectedoverridevoidOnAttached()

{

try

{

Control.Layer.CornerRadius=5;

Control.Layer.ShadowColor=Device.OnPlatform(

Color.Black,Color.White,Color.Black).ToCGColor();

Control.Layer.ShadowOffset=newCGSize(4,4);

Control.Layer.ShadowOpacity=0.5f;

}

catch(Exceptionex)

{

Console.WriteLine("Cannotsetpropertyonattached

control.Error:",ex.Message);

}

}

6. Then,wecreatetheOnDetachedmethod,whichwillbecalledwheneveraneffectisdetachedfromaXamarin.Formscontroltoperformanyeffectcleanup.Here,inthismethod,wedon'tneedtodoanything,butwestillneedtoimplementthistoconformwiththePlatformEffectclassprotocolimplementations:

protectedoverridevoidOnDetached()

{

}

}

}

NowthatwehavecreatedthePlatformEffectsfortheiOSplatform,weneedtoimplementthesamePlatformEffectsfortheAndroidplatform,whichwewillbecoveringinthenextsection.

Page 213: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingPlatformEffectsusingtheEffectsAPIfortheAndroidplatformInthissection,wewillbuildtheAndroidportionofourPlatformEffectsthatwillallowustocustomizetheappearanceofXamarin.FormscontrolelementsjustlikewedidfortheiOSportion,andwewillbeimplementingthesamePlatformEffects--LabelShadowandButtonShadowtoshowyouhowtheseimplementationsdifferoneachplatform,eventhoughtheresultingrenderingisthesame.

Let'stakealookathowwecanachievethis,byfollowingthesteps:

1. CreateanewfolderwithintheTrackMyWalks.Droidproject,calledPlatformEffects.2. Next,createanemptyclasswithinthePlatformEffectsfolderforour

TrackMyWalks.Droidproject.3. Then,enterButtonShadowEffectasthenameofthenewclassfiletocreate,ensurethatthe

ButtonShadowEffect.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//ButtonShadowEffect.cs

//TrackMyWalksButtonShadowEffect(Droid)

//

//CreatedbyStevenF.Danielon02/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.Droid.PlatformEffects;

usingXamarin.Forms;

usingXamarin.Forms.Platform.Android;

usingSystem;

4. Next,weinitializetheButtonShadowEffectclassassemblytobemarkedwiththesametwoattributesforourclass,justlikewedidfortheiOSportion,sothatitcanbeusedasaneffectwithintheTrackMyWalksapplication:

[assembly:ResolutionGroupName("com.geniesoftstudios")]

[assembly:ExportEffect(typeof(ButtonShadowEffect),

"ButtonShadowEffect")]

namespaceTrackMyWalks.Droid.PlatformEffects

{

5. Then,weneedtomodifytheButtonShadowEffectclassconstructorsothatitcaninheritfromthePlatformEffectclass,andaccesseachoftheplatform-specificimplementationsofthePlatformEffectclass:

publicclassButtonShadowEffect:PlatformEffect

{

6. Next,wecreatetheOnAttachedmethodthatwillbecalledwheneveranaffectisattachedtoaXamarin.FormscontrolandthenusetheControlpropertytoreferencetheplatform-specificcontrolthatwillbeusedtochangetheappearanceofthecontrol.UnderAndroidwe

Page 214: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

needtocreateacontrolobjectandconverttheButtonintoaControlobject,andthenapplythecustomizationstotheControl.Wewrapthiswithinatry...catch()block,tocatchanyerrorsthatmayoccurif,forsomereason,wecan'tapplythecolororshadowLayerforourcontrol:

protectedoverridevoidOnAttached()

{

try

{

varcontrol=ControlasAndroid.Widget.Button;

Android.Graphics.Colorcolor=

Android.Graphics.Color.Red;

control.SetShadowLayer(12,4,4,color);

}

catch(Exceptionex)

{

Console.WriteLine("Cannotsetpropertyonattached

control.Error:",ex.Message);

}

}

7. Then,wecreatetheOnDetachedmethod,whichwillbecalledwheneveraneffectisdetachedfromaXamarin.Formscontroltoperformanyeffectcleanup.Hereinthismethod,wedon'tneedtodoanything,butwestillneedtoimplementthistoconformwiththePlatformEffectclassprotocolimplementations:

protectedoverridevoidOnDetached()

{

thrownewNotImplementedException();

}

}

}

NowthatwehavecreatedtheButtonShadowEffectclass,ournextstepistocreatetheLabelShadowEffectfortheAndroidportionofourTrackMyWalksapp:

1. Next,createanemptyclasswithinthePlatformEffectsfolderfortheTrackMyWalks.DroidprojectandenterLabelShadowEffectasthenameofthenewclassfiletocreate.

2. Then,ensurethattheLabelShadowEffect.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//LabelShadowEffect.cs

//TrackMyWalksLabelShadowEffect(Droid)

//

//CreatedbyStevenF.Danielon02/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingTrackMyWalks.Droid.PlatformEffects;

usingXamarin.Forms;

Page 215: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

usingXamarin.Forms.Platform.Android;

3. Next,weinitializeourLabelShadowEffectclassassemblytobemarkedwiththeExportEffectattributesothatitcanbeusedasaneffectwithintheTrackMyWalksapplication:

[assembly:ExportEffect(typeof(LabelShadowEffect),

"LabelShadowEffect")]

namespaceTrackMyWalks.Droid.PlatformEffects

{

4. Then,weneedtomodifytheLabelShadowEffectclassconstructorsothatitcaninheritfromthePlatformEffectclass,andaccesseachoftheplatform-specificimplementationsofthePlatformEffectclass:

publicclassLabelShadowEffect:PlatformEffect

{

5. Next,wecreatetheOnAttachedmethodthatwillbecalledwheneveranaffectisattachedtoaXamarin.FormscontrolandthenusetheControlpropertytoreferencetheplatform-specificcontrolthatwillbeusedtochangetheappearanceofthecontrol.InAndroidweneedtocreateacontrolobject,converttheTextViewintoaControlobject,andthenapplythecustomizationstotheControl.Wewrapthiswithinatry...catch()block,tocatchanyerrorsthatmayoccurif,forsomereason,wecan'tapplythecolororshadowLayerforourcontrol:

protectedoverridevoidOnAttached()

{

try

{

varcontrol=ControlasAndroid.Widget.TextView;

floatradius=5;

floatdistanceX=4;

floatdistanceY=4;

Android.Graphics.Colorcolor=Device.OnPlatform(

Color.Black,Color.White,Color.Black).ToAndroid();

control.SetShadowLayer(

radius,distanceX,distanceY,color);

}

catch(Exceptionex)

{

Console.WriteLine("Cannotsetpropertyonattached

control.

Error:",ex.Message);

}

}

6. Then,wecreatetheOnDetachedmethodthatwillbecalledwheneveraneffectisdetachedfromaXamarin.Formscontroltoperformanyeffectcleanupinthismethod.AswhatwedidintheiOSimplementation,wedon'tneedtodoanything,butwestillneedtoimplementthistoconformwiththePlatformEffectclassprotocolimplementations:

protectedoverridevoidOnDetached()

{

Page 216: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

}

}

NowthatwehavecreatedPlatformEffectsforboththeiOSandAndroidimplementations,ournextstepistobegincreatingtwovalueconvertersthatwillbeusedbyourapplication,beforewecanstartmodifyingthecontentpages,andthiswillbecoveredinthenextsection.

Page 217: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingvalueconverterswithintheTrackMyWalksappAsmentionedintheprevioussection,valueconvertersformanimportantconceptindatabindingastheyallowyoutocustomizetheappearanceofadatapropertyatthetimeitisbound.ThisprocessisquitesimilartoWPF(WindowsPresentationFoundation)ontheWindowsapplicationdevelopmentplatform.Xamarin.FormsprovidesyouwithanumberofvalueconverterinterfacesaspartofitsAPI.

ValueconvertersareextremelyhelpfulwhenworkingwiththeXamarin.Formsplatform,astheyallowyoutotogglethevisibilityofelements,basedonaBooleanproperty.

Inthissection,wewillcreateaBooleanConverterthatwewillusetohidecontrolsuntiltheViewModelhascompletelyfinishedloading.WewillalsocreateaconverterthatconvertsastringvalueintoaURLpropertythatwillbeusedtodisplayanimageforourdifficultyrating.

Let'stakealookathowwecanachievethis,byfollowingthesteps:

1. Createanewfolder,withintheTrackMyWalksPortableClassLibraryproject,calledValueConvertersandthencreateanemptyclasswithintheValueConvertersfolder.

2. Next,choosetheEmptyClassoptionlocatedwithintheGeneralsection,andenterBooleanConverterasthenameofthenewclassfiletocreate.

3. Next,ensurethattheBooleanConverter.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//BooleanConverter.cs

//TrackMyWalksValueConverterforconvertingBooleanvalues

//

//CreatedbyStevenF.Danielon02/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingXamarin.Forms;

namespaceTrackMyWalks.ValueConverters

{

4. Then,weneedtomodifytheBooleanConverterclassconstructorsothatitcaninheritfromtheIValueConverterclass:

publicclassBooleanConverter:IValueConverter

{

5. Next,createtheConvertandConvertBackmethodsoftheIValueConverterclass,sothattheconverterwillreturntheoppositeofagivenBooleanvalue:

publicobjectConvert(objectvalue,TypetargetType,

objectparameter,System.Globalization.CultureInfoculture)

Page 218: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

if(!(valueisBoolean))

returnvalue;

return!((Boolean)value);

}

publicobjectConvertBack(objectvalue,TypetargetType,

objectparameter,System.Globalization.CultureInfoculture)

{

if(!(valueisBoolean))

returnvalue;

return!((Boolean)value);

}

}

}

Intheprecedingcodesnippet,webeganbymodifyingtheBooleanConverterclassconstructorsothatitcaninheritfromtheIValueConverterclass.ThenweproceededtocreatetheConvertandConvertBackmethodsoftheIValueConverterclass.ThisissothattheconverterwillreturntheoppositeofagivenBooleanvalue;forexample,ifthevalueisTrue,itwillreturnFalse,andconvertitfromFalsebacktoTrue.

NowthatwehavecreatedtheBooleanConverterclass,ournextstepistobegincreatingtheTrailImageConverterthatwillbeusedbytheTrackMyWalksapp.ThisclasswillbeusedtoconvertastringvalueintoaURLpropertythatwillbeusedtodisplayanimageforourdifficultyrating:

1. CreateanemptyclasswithintheValueConvertersfolder,whichislocatedwithintheTrackMyWalksPortableClassLibraryproject.

2. Next,choosetheEmptyClassoptionlocatedwithintheGeneralsection,andenterTrailImageConverterasthenameofthenewclassfiletocreate.

3. Next,ensurethattheTrailImageConverter.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//TrailImageConverter.cs

//TrackMyWalksValueConverterforconvertingdifficultyvalue

//toanimage.

//

//CreatedbyStevenF.Danielon02/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingXamarin.Forms;

namespaceTrackMyWalks.ValueConverters

{

4. Then,weneedtomodifyourTrailImageConverterclassconstructorsothatitcaninheritfromtheIValueConverterclass:

Page 219: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

publicclassTrailImageConverter:IValueConverter

{

5. Next,createtheConvertandConvertBackmethodsoftheIValueConverterclass,sothattheconverterwillreturnbackanimageURLbasedonthedifficultylevel:

publicobjectConvert(objectvalue,TypetargetType,

objectparameter,System.Globalization.CultureInfoculture)

{

//Returnbacktherelevantimagebasedonthe

//difficultylevel.

switch((string)value)

{

case"Easy":

return"http://www.yourdomain.com/g1.jpeg";

case"Moderate":

return"http://www.yourdomain.com/g2.jpeg";

case"Challenging":

case"Difficult":

return"http://www.yourdomain.com/g3.jpeg";

case"VeryDifficult":

case"Extreme":

return"http://www.yourdomain.com/g5.jpeg";

default:

return"http://www.yourdomain.com/g1.jpeg";

}

}

publicobjectConvertBack(objectvalue,TypetargetType,

objectparameter,System.Globalization.CultureInfoculture)

{

thrownewNotImplementedException();

}

}

}

Intheprecedingcodesnippet,webeganbymodifyingourTrailImageConverterclassconstructorsothatitcaninheritfromtheIValueConverterclass.Inournextstep,we'llproceedtocreatetheConvertandConvertBackprotocolmethodsoftheIValueConverterclass.ThisissothattheconverterwillreturnbackanimageURLbasedonthedifficultylevelandwillbedisplayedwithinourTrackMyWalksapp.

Page 220: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkBaseViewModeltouseourBooleanconverterInthissection,wewillproceedtoupdateourWalkBaseViewModelclasstoincludereferencestoourBooleanvalueconverter.SincetheWalkBaseViewModelalreadyinheritsandisusedbyeachoftheViewModels,itmakessensetoplaceitwithinthisclass.Thatway,ifweneedtoaddadditionalmethods,wecanjustaddthemwithinthisclass.Toproceed,performthefollowingsteps,asshownhere.

EnsurethattheWalkBaseViewModel.csfileisdisplayedwithinthecodeeditor,andenterthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

//

//WalkBaseViewModel.cs

//TrackMyWalksBaseViewModel

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.ComponentModel;

usingSystem.Runtime.CompilerServices;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Services;

namespaceTrackMyWalks.ViewModels

{

publicabstractclassWalkBaseViewModel:

INotifyPropertyChanged

{

protectedIWalkNavServiceNavService

{get;privateset;}

bool_isProcessBusy;

publicboolIsProcessBusy

{

get{return_isProcessBusy;}

set

{

_isProcessBusy=value;

OnPropertyChanged();

OnIsBusyChanged();

}

}

...

...

Page 221: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

...

protectedvirtualvoidOnIsBusyChanged()

{

//WeareprocessingourWalksTrailInformation

}

}

publicabstractclassWalkBaseViewModel<WalkParam>:

WalkBaseViewModel

{

protectedWalkBaseViewModel(

IWalkNavServicenavService):

base(navService)

{

}

publicoverrideasyncTaskInit()

{

awaitInit(default(WalkParam));

}

publicabstractTaskInit(WalkParamwalkDetails);

}

}

Intheprecedingcodesnippet,webeganbycreatingaBooleanproperty,calledisProcessBusy,whichwewillonlysettoTruewhileweareintheprocessofactuallyloadingdatawithinourListView,ordoingsomeotherprocessthattakesquitealongtime.TheIsProcessBusypropertycontainsboththegetter(get)andsetter(set)implementations.WhenwesettheIsProcessBusyproperty,weassignthisvaluetoour_isProcessBusyvariable,andthencalltheOnPropertyChangedandOnIsBusyChangedinstancemethodstotelltheViewModelsthatachangehasbeenmade.

Page 222: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksPageViewModeltouseourBooleanconverterInthissection,wewillproceedtoupdatetheWalksPageViewModelViewModeltoreferenceourBooleanvalueconverter.SincetheWalksPageViewModelisusedtodisplayinformationfromtheWalkEntriesmodel,wewillneedtoupdatetheLoadWalksinstancemethodtotogglebetweentheIsProcessBusyvaluewhileitisloadingdatawithintheListView.Toproceed,performthefollowingsteps,asshownhere:

EnsurethattheWalksPageViewModel.csfileisdisplayedwithinthecodeeditor,andenterthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

//

//WalksPageViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Collections.ObjectModel;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassWalksPageViewModel:WalkBaseViewModel

{

ObservableCollection<WalkEntries>_walkEntries;

publicObservableCollection<WalkEntries>walkEntries

{

get{return_walkEntries;}

set

{

_walkEntries=value;

OnPropertyChanged();

}

}

publicWalksPageViewModel(IWalkNavServicenavService):

base(navService)

{

walkEntries=newObservableCollection<WalkEntries>();

}

publicoverrideasyncTaskInit()

{

awaitLoadWalkDetails();

}

publicasyncTaskLoadWalkDetails()

Page 223: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

//Checktoseeifwearealreadyprocessingour

//WalkTrailItems

if(IsProcessBusy){

return;

}

//Ifwearen'tcurrentlyprocessing,weneedto

//initialiseourvariabletotrue.

IsProcessBusy=true;

//Addatemporarytimer,sothatwecansee

//ourprogressindicatorworking

awaitTask.Delay(1000);

...

...

...

//Re-initialiseourprocessbusyvaluebacktofalse

IsProcessBusy=false;

}

...

...

...

}

}

Intheprecedingcodesnippet,webeganbyupdatingtheLoadWalksmethodtotogglebetweentheBooleanpropertycalledIsProcessBusy.WesetthistoTruewhileweareintheprocessofactuallyloadingdatawithintheListView.Wethenaddedatemporarytimersowecanseethisprocessinaction,butwewillberemovingthisinChapter7,IncorporatingAPIDataAccess,whenweloadtheTrailinformationfromanAPI.Finally,were-initializedourIsProcessBusystatevaluebysettingthistoFalsetotelltheWalkBaseViewModelthatwehavecompletedprocessingofthewalktrailitems.

NowthattheViewModelisawareofwhenitisbusilyprocessingitemswithintheListView,ournextstepistomodifytheuserinterfaceforthewalkspagetoincludeanactivityindicatorthatinheritsfromtheXamarin.Forms.Coreplatform.WewillalsobemodifyingourDistanceTravelledandWalksTrailPagetoincludethePlatFormEffectsclasses.

Page 224: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthewalksmainpagetousetheupdatedViewModelInthissection,wewillproceedtoupdatetheWalksPagecontentpage,whichwillincludeanactivityprocessindicatorthatwilldisplayatextstringtotheuser,lettingthemknowthatthetrailwalksarebeingpopulatedwithintheListViewcontrol.WewillalsobemakinguseofourPlatformEffectsclassesfortheLabelShadow.Toproceed,performthefollowingsteps:

1. EnsurethattheWalksPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

usingTrackMyWalks.DataTemplates;

usingTrackMyWalks.ValueConverters;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage{

WalksPageViewModel_viewModel

{

get{

returnBindingContextasWalksPageViewModel;}

}

publicWalksPage()

{

varnewWalkItem=newToolbarItem

{

Text="AddWalk"

};

...

...

...

//DeclareandinitializeourModelBindingContext

BindingContext=newWalksPageViewModel(DependencyService

.Get<IWalkNavService>());

//DefineourItemTemplate

varwalksList=newListView

{

HasUnevenRows=true,

ItemTemplate=newDataTemplate(typeof(

WalkCellDataTemplate)),

Page 225: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SeparatorColor=(Device.OS==TargetPlatform.iOS)?

Color.Default:Color.Black

};

//SettheBindingpropertyforourwalksEntries

walksList.SetBinding(ItemsView<Cell>.ItemsSourceProperty,

"walkEntries");

2. Next,weneedtosetuptheBindingtotheIsVisiblePropertythatwedefinedwithintheWalkBaseViewModelclass.ThiswillbecalledwhenthispropertyhasbeensetTruetodisplayourWalkEntrieswithintheListViewandishandledbytheIsProcessBusyproperty.Proceedandenterthefollowinghighlightedcodesections,asshowninthecodesnippet:

walksList.SetBinding(ItemsView<Cell>.IsVisibleProperty,

"IsProcessBusy",converter:newBooleanConverter());

//InitializeoureventHandlertousewhentheitem

//istapped

walksList.ItemTapped+=(objectsender,

ItemTappedEventArgse)=>

{

varitem=(WalkEntries)e.Item;

if(item==null)return;

_viewModel.WalkTrailDetails.Execute(item);

item=null;

};

3. Then,wedeclareandinitializeanewprogressLabelcontrol,whichwillbeusedtodisplayinstructiveinformationtotheuserwhentheListViewisbeingpopulated.Proceedandenterinthefollowinghighlightedcodesections,asshowninthecodesnippet:

//DeclareourProgressLabel

varprogressLabel=newLabel()

{

FontSize=14,

FontAttributes=FontAttributes.Bold,

TextColor=Color.Black,

HorizontalTextAlignment=TextAlignment.Center,

Text="LoadingTrailWalks..."

};

4. Next,weapplythePlatformEffectLabelShadowEffectclasstoourprogressLabelcontrol,instantiateandinitializetheActivityIndicatorclass,andsettheIsRunningpropertytoTrue,beforecreatingaStackLayoutvariableprogressIndicatorandaddingboththeactivityIndicatorandprogressLabelitems.Finally,wesetuptheBindingforourProgressIndicatorusingtheisVisiblePropertyoftheStackLayoutcontrol.ThiswillusetheIsProcessBusypropertytodeterminewhetherornottoshowtheActivityIndicator.Proceedandenterinthefollowinghighlightedcodesections,asshowninthecodesnippet:

//ApplyPlatformEffectstoourProgressLabel

Page 226: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

progressLabel.Effects.Add(Effect.Resolve("com.geniesoftst

udios.LabelShadowEffect"));

//InstantiateandinitialiseourActivityIndicator.

varactivityIndicator=newActivityIndicator()

{

IsRunning=true

};

varprogressIndicator=newStackLayout

{

Orientation=StackOrientation.Vertical,

HorizontalOptions=LayoutOptions.CenterAndExpand,

VerticalOptions=LayoutOptions.CenterAndExpand,

Children={

activityIndicator,

progressLabel

}

};

progressIndicator.SetBinding(StackLayout.IsVisibleProperty,

"IsProcessBusy");

varmainLayout=newStackLayout

{

Children=

{

walksList,

progressIndicator

}

};

Content=mainLayout;

}

protectedoverrideasyncvoidOnAppearing()

{

base.OnAppearing();

//InitializeourWalksPageViewModel

Page 227: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

if(_viewModel!=null)

await_viewModel.Init();

}

}

}

Intheprecedingcodesnippet,webeganbysettinguptheBindingtoourIsVisibleProperty,whichwedefinedwithintheWalkBaseViewModelclass;thiswillbecalledwhenthepropertyhasbeensettoTruetodisplaytheWalkEntrieswithintheListView,andishandledbytheIsProcessBusyproperty.Inournextstep,wedeclaredandinitializedanewprogressLabelcontrol,whichwillbeusedtodisplayinstructiveinformationtotheuserwhentheListViewisbeingpopulated.

ThenweappliedtheLabelShadowEffectclasstotheprogressLabelcontrol,instantiatedandinitializedtheActivityIndicatorclass,andsettheIsRunningpropertytoTrue,beforecreatingaStackLayoutvariableprogressIndicatorandaddingboththeactivityIndicatorandprogressLabelitems.

Next,wesetuptheBindingfortheProgressIndicatorusingtheisVisiblePropertyofourStackLayoutcontrol,whichwillusetheIsProcessBusypropertytodeterminewhetherornottoshowtheActivityIndicator.Finally,weaddedtheProgressIndicatortoourmainLayoutaspartoftheChildrenproperty,sothatthiscanbedisplayedaspartofthemaincontentpage.

Tip

Ifyoudon'texportanEffectforaparticularplatform,theEffect.Resolvewillreturnanon-nullvaluethateffectivelydoesn'tdoanything,andyouwon'tseeanyrenderinghappenonyourcontrols.Youwillneedtoensurethat,withinyourPlatformEffectclasses,youincludetheExportEffectassemblyattributeatthetopofyourclassimplementations.

Page 228: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksTrailPagetousetheupdatedViewModelInthissection,wewillproceedtoupdateourWalksTrailPagecontentpagewillmakeuseofthePlatformEffectsclassesfortheButtonShadow.Toproceed,performthefollowingsteps:

EnsurethattheWalksTrailPage.csfileisdisplayedwithinthecodeeditor,andenterthefollowinghighlightedcodesections,asshowninthecodesnippet:

//

//WalkTrailPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

usingTrackMyWalks.ValueConverters;

namespaceTrackMyWalks

{

publicclassWalkTrailPage:ContentPage

{

WalksTrailViewModel_viewModel

{

get{returnBindingContext

asWalksTrailViewModel;}

}

publicWalkTrailPage()

{

Title="WalksTrail";

...

...

...

beginTrailWalk.Effects.Add(Effect.Resolve

("com.geniesofts

tudios.ButtonShadowEffect"));

...

...

...

trailDifficultyLabel.SetBinding(Label.TextProperty,

"WalkEntry.Difficulty",stringFormat:"Difficulty:{0}");

vartrailDifficultyImage=newImage

{

HeightRequest=50,

WidthRequest=50,

Aspect=Aspect.AspectFill,

Page 229: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

HorizontalOptions=LayoutOptions.Start

};

trailDifficultyImage.SetBinding(Image.SourceProperty,

"WalkEntry.Difficulty",

converter:newTrailImageConverter());

...

...

...

}

}

}

Intheprecedingcodesnippet,webeganbyapplyingtheButtonShadowEffectclasstoourbeginTrailWalkbutton,andthenupdatedthebindingofthetrailDifficultyImagetousetheTrailImageConvertervalueconverter.Thiswillconvertthestringrepresentationforthechosendifficulty,andreturnbackanimageURLthatwillbedisplayedwithinthecontentpage.

Page 230: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheDistanceTravelledPagetousetheupdatedViewModelInthissection,wewillproceedtoupdateanotherDistanceTravelledPagecontentpagethatwillmakeuseofthePlatformEffectsclassesforourButtonShadow.Toproceed,performthefollowingsteps:

EnsurethattheDistanceTravelledPage.csfileisdisplayedwithinthecodeeditor,andenterthefollowinghighlightedcodesections,asshowninthecodesnippet:

//

//DistanceTravelledPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingXamarin.Forms.Maps;

usingTrackMyWalks.Services;

namespaceTrackMyWalks

{

publicclassDistanceTravelledPage:ContentPage

{

DistTravelledViewModel_viewModel

{

get{returnBindingContextas

DistTravelledViewModel;}

}

publicDistanceTravelledPage()

{

Title="DistanceTravelled";

...

...

...

varwalksHomeButton=newButton

{

BackgroundColor=Color.FromHex("#008080"),

TextColor=Color.White,

Text="EndthisTrail"

};

walksHomeButton.Effects.Add(Effect.Resolve

("com.geniesoft

studios.ButtonShadowEffect"));

Page 231: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

...

...

...

}

}

Intheprecedingcodesnippet,webeginbyapplyingtheButtonShadowEffectclasstoourwalksHomeButtoncontrolsothatitcantakeadvantageoftheniceplatform-specificrenderingeffectstovisualcontrolelements.

Page 232: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkCellDataTemplateclasstousePlatformEffectsInthissection,wewillproceedtoupdatetheWalkCellDataTemplateclass,whichwillmakeuseofthePlatformEffectsclassesforourLabelShadow,sothattheDataTemplatewillinheritsomeofthenicevisualrepresentationsthatyouruserswilllove.Toproceed,performthefollowingsteps,asshownhere:

EnsurethattheWalkCellDataTemplate.csfileisdisplayedwithinthecodeeditor,andenterthefollowinghighlightedcodesections,asshowninthecodesnippet:

//

//WalkCellDataTemplate.cs

//TrackMyWalksDataTemplateforCells

//

//CreatedbyStevenF.Danielon01/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.ValueConverters;

usingXamarin.Forms;

namespaceTrackMyWalks.DataTemplates

{

publicclassWalkCellDataTemplate:ViewCell

{

publicWalkCellDataTemplate()

{

...

...

...

//ApplyPlatformEffectstoourTrailNameLabelControl

TrailNameLabel.Effects.Add(Effect.Resolve

("com.geniesofts

tudios.LabelShadowEffect"));

TrailNameLabel.SetBinding(Label.TextProperty,"Title");

...

...

...

trailDifficultyImage.SetBinding(Image.SourceProperty,

"Difficulty",converter:newTrailImageConverter());

...

...

...

this.View=cellLayout;

}

}

}

Intheprecedingcodesnippet,webeganbyapplyingtheLabelShadowEffectclasstoourTrailNameLabelcontrol,andthenupdatedthebindingofthetrailDifficultyImagetousethe

Page 233: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TrailImageConvertervalueconverter.Thiswillconvertthestringrepresentationforourchosendifficulty,andreturnbackanimageURLthatwillbedisplayedwithinthecontentpage.

NowthatyouhaveupdatedthenecessaryViewModelsandContentPagestotakeadvantageofourPlatFormEffectsandValueConverters,ournextstepistofinallybuildandruntheTrackMyWalksapplicationwithintheiOSsimulator.

Whenthecompilationiscomplete,theiOSsimulatorwillappearautomatically,andtheTrackMyWalksapplicationwillbedisplayed,asshowninthefollowingscreenshot:

Asyoucanseefromtheprecedingscreenshot,thiscurrentlydisplaysourActivityIndicatorspinnercontrol,withtheassociatedLoadingTrailWalks...text.AfterthistheListViewcontainingthelistoftrailwalksfromtheDataTemplatecontrolwilldisplay.Youwillnoticethatitdisplaysaniceimageassociatedwiththedifficultyforthetrailwalk,whichispulleddirectlyfromtheTrailImageValueConverterclass.

WhentheAddWalkbuttonispressedfromthemainTrackMyWalkscontentpage,thisdisplaystheNewWalkEntryscreen,withtheDifficultyLevelcustompickershowingthelistofchoicesasdefinedwithinourDifficultyPickerModel:

Page 234: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TheprecedingscreenshotshowstheupdatedViewModelandContentPagesthatmakeuseofthePlatformEffectsclassesfortheButtonShadoweffects,aswellastheValueConvertersfortheTrailImageValueConverter.Asyoucansee,byusingthepowerofXamarin.FormsPlatformEffectsandValueConverterswithinyourownapplications,youcanreallycreatesomestunninguserinterfacesthatwillshowoffyourappsandthatyouruserswilllove.

Page 235: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,weupdatedtheTrackMyWalksapplicationtouseCustomRendererstochangetheappearanceofcontrolelementsthataredisplayedwithintheuserinterfaceforeachspecificplatform.Next,youlearnedhowtoworkwithDataTemplates,bycreatingacustomclasstorepresenttheinformationthatispresentedwithintheListViewclass,aswellascreatingtwoValueConverterclassesBooleanValueConverterthatareusedtodeterminewheninformationiscurrentlybeingdisplayedwithintheuserinterface.YoualsocreatedaTrailImageValueConverterthatreturnsanimageURLbasedonthestringpassedintoit.Finally,youlearnedhowtoworkwiththePlatformEffectsclass,tocreateaLabelShadowandButtonShadow,andupdatedtheViewModelandContentPagestoapplythoseeffectstocontrolelements.

Inthenextchapter,you'lllearnabouttheRazorTemplatingEngineandhowyoucanuseittocreateahybridmobilesolution.You'lllearnhowtocreate,andusemodelswithinyourapplication,aswellascallingJavaScriptcodeusingC#toexecutemethodcalls.

Page 236: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter6.WorkingwithRazorTemplatesInourpreviouschapter,welookedathowtoworkwiththeDataTemplateCustomRendererbycreatingaC#classtolayoutyourviewsbeautifullywithinyourapplications,andhowyouwillalsogetaccustomedtoworkingwiththeplatform-specificAPIstoextendthedefaultbehaviorofXamarin.Formscontrolsusingcustomrenderers,bycreatingacustompicker.

YoualsolearnedhowtousetheXamarin.FormsEffectsAPItocustomizetheappearanceandstylingofnativecontrolelementsforeachplatform,byimplementingacustomrendererclass,andlookedathowtomanipulatethevisualappearanceofdatathatisbound,usingvalueandimageconverters.

Inthischapter,you'lllearnabouttheRazorHTMLtemplateengineandhowyoucanuseittocreateahybridmobilesolution.You'lllearnhowtobuildabooklibrarymobilesolutionusingthepowerofRazortemplates,andlearnhowtocreate,andusemodelswithinyourapplicationandconnectthisuptoanSQLitedatabasetostore,retrieve,update,anddeletebookdetails.

Thischapterwillcoverthefollowingtopics:

IntroductiontotheRazorHTMLtemplateengineHowtobuildahybridmobilesolutionusingXamarinStudioIncorporatingSQLite.NetandcreatingaSQLitedatabasewrapperCreatingthebookdatabasemodelCreatingthebooklistingmainpageCreatingthebooklistingaddpageCreatingthebooklistingeditpage

Page 237: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UnderstandingtheRazortemplateengineTheRazortemplatingenginewasfirstintroducedaspartoftheASP.NetMVCarchitecture,andwasoriginallydesignedtorunonawebservertogenerateHTMLfilestobeservedtowebbrowsers.

SinceRazormadeitsfirstappearanceonthedevelopmentscene,theRazortemplatingenginehascomealongwayandnowextendsthestandardHTMLsyntax,sothatyoucanuseC#toexpressthelayoutofyourHTMLfiles,andincorporateCSSstylesheetsandJavaScripteasily.

EachRazortemplatehastheabilitytoreferenceaModelclasswhichcanbeofanycustomtype,andpropertiescanbeaccesseddirectlyfromthetemplate,byhavingtheabilitytomixHTMLandC#syntaxeasily.

Asyouworkthroughthischapter,youwillseehow,byworkingwithXamarinStudio,youcanutilizetheRazorHTMLtemplatingengineandbeequippedwiththeflexibilityofbuildingcross-platformtemplatedHTMLviewsthatusebothJavaScriptandCSS,aswellashavingaccesstotheunderlyingplatformAPIsusingthepowerofC#.

Note

FormoreinformationonusingRazorsyntax(C#)withASP.NETwebprogrammingrefertothefollowingURL:https://www.asp.net/web-pages/overview/getting-started/introducing-razor-syntax-c.

Page 238: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingRazortemplateswithinXamarinStudioInthissection,wewilllookathowtogoaboutcreatinganewRazortemplatesolutionusingXamarinStudio.Wewillbeginbydevelopingthebasicstructureforourapplication,aswellasaddingallthenecessarydatabasemodelsanduserinterfacefiles.

Beforewecanproceed,weneedtocreatetheBookLibraryproject.ItisverysimpletocreatethisusingXamarinStudio.Simplyfollowthegivensteps:

1. LaunchtheXamarinStudioapplication,andchoosetheNewSolution...option,oralternativelychooseFile|New|Solution...orsimplypressShift+Command+N.

2. Next,choosetheWebViewAppoptionwhichislocatedundertheiOS|Appsection,ensurethatyouhaveselectedC#astheprogramminglanguagetouse,andclickNext:

3. Then,enterinBookLibraryasthenameforyourappintheAppNamefieldaswellasspecifyinganamefortheOrganizationIdentifierfield.

Page 239: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

4. Next,ensurethatboththeiPadandiPhonecheckboxeshavebeenselectedfortheDevicesfield,aswellasensuringthatyouhavechoseniOS10.0fortheTargetfieldtosupporttheminimumiOSversionthatwewantourapptosupport:

5. ClickontheNextbuttontoproceedtothenextstepinthewizard:

Page 240: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Next,ensurethattheCreateaprojectdirectorywithinthesolutiondirectory.checkboxhasbeenselectedandclickontheCreatebuttontosaveyourprojectatthespecifiedlocation.

Onceyourprojecthasbeencreated,youwillbepresentedwiththeXamarinStudiodevelopmentenvironment,alongwithseveralprojectfilesthatthetemplatecreatedforyourRazortemplateSolution,asshowninthefollowingscreenshot:

Page 241: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,theBookLibrarysolutionhasbeendividedintothreeseparatefolders.Thefollowingtableprovidesabriefdescriptionofwhateachareaisusedfor:

Foldertype Description

Models

Thissectionisresponsibleforrepresentingthemodelthatourviewswilluse,andcontainsastructureoffieldsthatwillbedisplayedand/orwrittentobyourRazortemplates.

ResourcesThissectioncontainsaplaceforyoutoaddtheimagesandCSS,orJavaScriptfilesthatyourapplicationwilluse.

Views

ThissectionisresponsibleforcontainingalloftheHTML5Razortemplatesthatyourapplicationwillbereferencing,andtheyneedtocontainandbeprefixedwiththe.cshtmlextension.

Onethingyouwillnoticeisthatoursolutioncontainsafilecalledstyle.css.Thisisbecauseourapplicationisessentiallyahybridmobilesolution,andcontainsthefilesyoumightexpectfromawebsolution,ascanbeseeninthefollowingcodesnippet:

Page 242: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

/*Thisisaminimalstylesheetintendedtodemonstrate

howtoincludestaticcontentinyourhybridapp.

Otherstaticcontent,suchasjavascriptfilesandimages,

canbeincludedinthissamefolder(ResourcesoniOSorAssets

onAndroid),withthesameBuildAction(BundleResourceoniOS

orAndroidAssetonAndroid),tobeaccessiblefromapathstarting

attherootofyourhybridapplication.*/

#page{

margin-top:10px;

}

Asyoucansee,thisfiledoesn'tcontainmuchinformation,butasweworkourwaythroughthischapter,wewillbeaddingtothisfile,andbuildingtheRazortemplateuser-interfacefiles.

Page 243: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheSQLite.NetpackagetotheBookLibrarysolutionNowthatwehavecreatedourBookLibrarysolution,thenextstepistoaddtheSQLite.NetNuGetpackagetooursolution,sincethisdoesn'tgetaddedautomaticallyforus.TheSQLite.NetpackagewillessentiallyprovideuswiththeabilitytohaveourapplicationwritetoanSQLitedatabase,tostoreourbookdetails.

Note

ANuGetpackageisessentiallythepackagemanagerfortheMicrosoftdevelopmentplatformthatcontainstheclienttoolsthatprovideoursolutionwiththeabilitytoproduceandconsume.NETpackages.

Let'slookathowtoaddtheSQLite.NETNuGetpackagewithinourBookLibrarysolution,byperformingthefollowingsteps:

1. Right-clickonthePackagesfolderthatiscontainedwithintheBookLibrarysolution,andchoosetheAddPackages...menuoption,asshowninthefollowingscreenshot.

2. ThiswilldisplaytheAddPackages...dialog.EnterinSQLite.Netwithinthesearchdialog,andthenclickonthesqlite-netoptionwithinthelist,asshowninthefollowingscreenshot:

Page 244: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Finally,clickontheAddPackagebuttontoaddthesqlite-netNuGetpackagetothePackagesfolder,containedwithintheBookLibrarysolution.

WhenyouclickontheAddPackagebutton,youwillnoticethatthepackagemanagerwillcreatetwonewfilesforuswithinoursolution.ThesearecalledSQLite.csandSQLiteAsync.cs,andarebasicallywrapperconvenienceclassesthatallow.NETandMonoapplicationstostoredatawithinaSQLite3database.

NowthatyouhaveaddedtheNuGetpackageforthesqlite-netlibrary,wecanbegintoutilizethislibrarywithintheBookLibrarysolutionthatwewillbecoveringinthenextsection.

Page 245: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingthebooklibrarydatabasemodelInthissection,wewillbeginbybuildingthedatabasemodelthatwillbeusedbyourBookLibraryprojectsolutionthatwillbeusedbyourRazortemplateswhenwecreatethese,andthentheWebViewController.csfilewillcommunicateandinteractwitheachoftheRazortemplateviewsandhandletheactionswithinthem.

Let'slookathowwecanachievethis,byperformingfollowingsteps:

1. CreateanemptyclasswithintheModelsfolder,bychoosingAdd|NewFile...,asshowninthefollowingscreenshot:

2. Next,choosetheEmptyClassoption,locatedwithintheGeneralsection,andenterinBookItem,asshowninthefollowingscreenshot:

Page 246: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyclassfile.

Upuntilnow,allwehavedoneiscreateourBookItemclassfile.ThisclasswillbeusedbyeachofourRazortemplateviews,aswellasourWebViewController.csfilethatwilleventuallyallowcommunicationtohappenbetweeneachoftheRazortemplateviews,aswellasbeingabletohandleactionswithinthem,whenevertheuserinteractswiththem.

Let'snowstarttoimplementthecoderequiredforourBookItemclassmodel,byperformingthefollowingsteps:

1. EnsurethattheBookItem.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//BookItem.cs

//BookLibraryDatabaseModel

//

//CreatedbyStevenF.Danielon20/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

Page 247: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//

usingSQLite;

namespaceBookLibrary{

publicclassBookItem

{

publicBookItem()

{

}

[PrimaryKey,AutoIncrement]

publicintId{get;set;}

publicstringTitle{get;set;}

publicstringAuthor{get;set;}

publicstringIsbn{get;set;}

publicstringSynopsis{get;set;}

}

}

Intheprecedingcodesnippet,wehavesuccessfullydefinedourdatabasemodelthatwillbeusedtorepresentourbookitems.YouwillnoticesomethingthatisdifferentwithinourmodeltowhatyouwouldhaveseenwithinourTrackMyWalksapp:herewehavedefineda[PrimaryKey,AutoIncrement]itemforouridfield,thiswilltellourBookLibrarydatabasetosettheidpropertytoautomaticallyincrementwheneverweaddanewitemtoourdatabase.

Ifyouhaveusedrelationaldatabasesinthepast,suchasMicrosoftSQLServer,Oracle,orMicrosoftAccess,thisshouldbequitefamiliartoyou.Inthenextsection,wewillusethismodeltosetupandinitializeourdatabase,bycreatingadatabaselibrarywrappertohandleconnectionstoourdatabase,aswellasCreation,Retrieval,Updating,andDeletion(CRUD),ofeachofourbookentries.

Note

TheAndroidversionoftheBookItemclassmodelisavailableinthecompanionsourcecodeforthisbook.

Page 248: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingthebookdatabasewrapperIntheprevioussection,wesuccessfullycreatedandimplementedourBookItemdatabasemodelthatwillbeusedbyourBookLibraryapplication.OurnextstepistobeginimplementingthecoderequiredforourBookItemDatabaseclassmodel,byperformingthefollowingsteps:

1. CreateanewfolderwithintheBookLibraryprojectsolution,calledDatabaseasshowninthefollowingscreenshot:

2. Next,createanemptyclasswithintheDatabasefolder,bychoosingAdd|NewFile...,asyoudidwhencreatingthemodelintheprevioussectionentitledCreatingandimplementing

Page 249: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

thebooklibrarydatabasemodel,locatedwithinthischapter.3. Then,enterinBookDatabaseforthenameofthenewclassthatyouwanttocreate,andclick

ontheNewbuttontoallowthewizardtoproceedandcreatethenewfile.4. Next,ensurethattheBookDatabase.csfileisdisplayedwithinthecodeeditorwindow,and

thenenterinthefollowingcodesnippet:

//

//BookDatabase.cs

//BookLibraryDatabasetohandleperformingdatabase

//Creation,Retrieval,UpdatingandDeletionofBookItems.

//

//CreatedbyStevenF.Danielon20/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSQLite;

namespaceBookLibrary

{

publicclassBookDatabase

{

5. Next,weneedtocreatealockervariablethatwillbeusedtocreateamutually-exclusivelockonthedatabasewhileweareeithercreating,updating,retrieving,ordeletingbookitems.Wedothissothatnootheroperationcaninterferewhileweareprocessing,andthiswillpreventissuesfromarising.Wealsoneedtodeclareadatabasevariable,thatpointstoaninstanceofourSQLiteConnectionlocatedwithinourSQLitelibrary,sothatwecanperformdatabaseoperations:

staticobjectlocker=newobject();

SQLiteConnectiondatabase;

6. Then,weneedtocreatetheBookDatabase(SQLiteConnectionconn)methodthatacceptsaconnobject,whichisaninstanceofourSQLiteConnectionclass,andthisinstancemethodwillbeusedtocreatethenecessarydatabasetablestructure,basedonourBookItemmodel:

///<summary>

///InitializesanewinstanceoftheBookLibrary

///Databaseclass.

///</summary>

///<paramname="conn">Conn.</param>

publicBookDatabase(SQLiteConnectionconn)

{

database=conn;

//CreatethetableswithinourBookLibraryDatabase

database.CreateTable<BookItem>();

}

7. Next,weneedtocreatetheGetItems()methodthatwillbeusedtoextractalloftheexistingbookentriesthathavebeensavedtothedatabase.WeusetheLINQlanguagesyntax

Page 250: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

toiterateandretrieveallitemsfromourBookItemtable,andconvertthiscollectiontoalistinstance,asdeterminedbythe.ToList()method:

///<summary>

///Getsallofthebooklibraryitemsfromourdatabase.

///</summary>

///<returns>Theitems.</returns>

publicIEnumerable<BookItem>GetItems()

{

//Setamutual-exclusivelockonourdatabase,while

//retrievingitems.

lock(locker)

{

return(fromiindatabase.Table<BookItem>()

selecti).ToList();

}

}

8. Then,weneedtocreatetheGetItem()methodthatwillextracttheselectedbookentryfromtheBookItemdatabasetable,usingtheiridasthekey.Again,weusetheLINQlanguagesyntaxtoretrievethefirstitemfromtheBookItemtablethatmatchestheidofthebookitem:

///<summary>

///Getsaspecificbookitemfromthedatabase.

///</summary>

///<returns>Theitem.</returns>

///<paramname="id">Identifier.</param>

publicBookItemGetItem(intid)

{

//Setamutual-exclusivelockonourdatabase,while

//retrievingthebookitem.

lock(locker)

{

returndatabase.Table<BookItem>().FirstOrDefault(x=>

x.Id==id);

}

}

9. Next,weneedtocreatetheSaveItem()methodthatwillsavethebookitemtotheBookItemdatabasetable.Inthisinstancemethod,wearehandlingtwocasescenarios:oneiftheitemwearesavingisanexistingitem,wechecktheidofthebookitem,andifitisanon-zerovalue,weproceedtoupdatethebookitemusingtheUpdatemethodonthedatabaseobject,andreturnthebookitemidback.

10. However,iftheitemisanewbookrecord,thatisallnewbooksthatgetcreatedwillhaveanidof0,thiswillbedirectlyinsertedintotheBookItemtable,usingtheInsertmethodonthedatabaseobject:

///<summary>

///Savesthebookitemcurrentlybeingedited.

///</summary>

///<returns>Theitem.</returns>

///<paramname="item">Item.</param>

publicintSaveItem(BookItemitem)

{

Page 251: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//Setamutual-exclusivelockonourdatabase,while

//saving/updatingourbookitem.

lock(locker)

{

if(item.Id!=0)

{

database.Update(item);

returnitem.Id;

}

else{

returndatabase.Insert(item);

}

}

}

11. Finally,wecreatetheDeleteItem()methodthatwill,asyoumighthaveguessed,deleteabookitemfromtheBookItemdatabasetableusingthebook'sitemidandthencallingtheDeletemethodonthedatabaseobject:

///<summary>

///Deletesaspecificbookitemfromthedatabase.

///</summary>

///<returns>Theitem.</returns>

///<paramname="id">Identifier.</param>

publicintDeleteItem(intid)

{

//Setamutual-exclusivelockonourdatabase,while

//deletingourbookitem.

lock(locker)

{

returndatabase.Delete<BookItem>(id);

}

}

}

}

NowthatwehavecreatedourBookDatabaseclass,wecanproceedandcreateourBookLibraryDBdatabasewrapperthatwilluseourBookDatabaseclasstohandlealltheoperationsforcreating,retrieving,updating,anddeletionofbookitemsfromourdatabase.ThatwillbeusedbyourWebViewController.csclasstointeractwithourRazortemplateViews.

Note

TheAndroidversionoftheBookDatabaseclassisavailableinthecompanionsourcecodeforthisbook.

Page 252: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingtheBookLibrarydatabasewrapperIntheprevioussection,wesuccessfullycreatedandimplementedourBookDatabasedatabaseclassthatwillbeusedbyourBookLibraryapplication.OurnextstepistobeginimplementingthecoderequiredforourBookLibraryDBclassthatwillactasawrapperforourBookDatabaseclass,toperformalldatabaseactionsforourBookLibraryapplication.

Let'sbeginbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheBookLibrarysolution,bychoosingAdd|NewFile...,asyoudidwhencreatingthemodelintheprevioussectionentitledCreatingandimplementingthebooklibrarydatabasemodel,locatedwithinthischapter.

2. Then,enterinBookLibraryDBforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethenewfile.

3. Next,ensurethattheBookLibraryDB.csfileisdisplayedwithinthecodeeditorwindow,andthenenterinthefollowingcodesnippet:

//

//BookLibraryDB.cs

//BookLibraryDatabaseLayer

//

//CreatedbyStevenF.Danielon20/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSQLite;

namespaceBookLibrary

{

publicclassBookLibraryDB

{

4. Next,weneedtocreateaconnvariablethatwillbeusedtosetaconnectiontoourBookLibrarydatabase,andwealsoneedtodeclareadatabasevariable,thatpointstoaninstanceofourBookDatabasethatcontainseachoftheoperationsforhandlingandperformingtheinsertion,updating,anddeletionofbookentries:

staticSQLiteConnectionconn;

staticBookDatabasedatabase;

5. Then,weneedtocreatetheSetDatabaseConnection()methodthatwillsetaconnectiontoourBookDatabasedatabaseclass,sothatitcanaccesseachofourinstancemethodsforhandlingthecreation,updating,retrieval,anddeletionofourbookentries,withinourBookItemdatabasetable.Withinthisinstancemethod,wesetupandinitializetheconnvariablethatcontainsthevalueofourconnectionparameter,andtheninstantiatesaconnectiontoourBookDatabaseclass,passingintheconnconnectionobjectsothattheclasscanreturnourdatabaseobject:

///<summary>

Page 253: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

///SetsaconnectiontoourBookDatabasedatabaseclass.

///</summary>

///<paramname="connection">Connection.</param>

publicstaticvoidSetDatabaseConnection(SQLiteConnection

connection)

{

conn=connection;

database=newBookDatabase(conn);

}

6. Finally,wecreatetheDatabasemethodthatgetsareferencetoourBookLibrarydatabasetouse:

///<summary>

///GetsareferencetoourBookLibrarydatabase.

///</summary>

///<value>Thedatabase.</value>

publicstaticBookDatabaseDatabase

{

get{returndatabase;}

}

}

}

NowthatwehavecreatedourBookLibraryDBclass,wecancreateourRazortemplateuserinterfacefilesthatwillconnecttoourBookLibrarydatabase,andallowtheusertointeractwiththedatabasemodeltocreate,retrieve,update,anddeletebookitemsfromthedatabase.

Note

TheAndroidversionoftheBookLibraryDBclassisavailableinthecompanionsourcecodeforthisbook.

Page 254: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingthebooklistingmainpageIntheprevioussection,wecreatedandimplementedourBookLibraryDBdatabasewrapperclassthatwillbeusedbyourBookLibraryapplication.ThenextstepistobegincreatingeachoftheRazortemplatesthatwillconnecttoourdatabasemodelallowingtheusertointeractwiththedatabasevisuallybyenteringinbookdetails,andhavingthisinformationpresentedbacktothem,sotheycanmakechanges,ordeletethebookitemaltogether.

Let'sbeginbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheViewsfolder,bychoosingAdd|NewFile...,asyoudidwhencreatingthemodelintheprevioussectionentitledCreatingandimplementingthebooklibrarydatabasemodel,locatedwithinthischapter.

2. Next,choosethePreprocessedRazorTemplateoption,locatedwithintheTextTemplatingsection,andenterinBookLibraryListing,asshowninthefollowingscreenshot:

Page 255: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyRazortemplatefile.

Congratulations,youhavecreatedyourfirstRazortemplate!ThisfilewillbeusedtolistallthebookentriesthatarestoredwithinourBookItemdatabasetable,containedwithinourBookLibrarydatabase.ThenextstepistostarttoimplementthecoderequiredforourBookLibraryListingRazortemplate,byperformingthefollowingstep:

1. EnsurethattheBookLibraryListing.cshtmlfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

@usingBookLibrary

@modelList<BookItem>

<html>

<head><linkrel="stylesheet"href="style.css"/></head>

<body>

<p></p>

<h1>BookLibraryDatabaseListing</h1>

<tableborder="1"cellpadding="8">

@foreach(varbookin@Model){

<tr>

<td>@book.Id</td>

<td>@book.Title</td>

<td>@book.Author</td>

<td>@book.Isbn</td>

<td>

<ahref="hybrid:[email protected]">

Edit</a>

</td>

</tr>

}

<tr>

<tdcolspan="8">

<ahref="hybrid:CreateNewBook?">

<inputtype="submit"name="Button"

value="AddNewBook"/></a>

</td>

</tr>

</table>

</body>

</html>

Intheprecedingcodesnippet,wedefinetheHTMLlayoutinformationthatwillbeusedbyourBookLibraryListingRazortemplate.WefirstlyspecifythatweareusingtheBookLibrary.iOSnamespace,sothatwecanhaveaccesstoourdatabasemodelasspecifiedbythe@modeldirective,andthismustbetheveryfirstlineprecedingthe<html>tagwithinaRazortemplatefile.Youwillnoticethatthe@modeldirectivehasthetypeofList.ThisisbecauseweareiteratingthrougheachofourbookitemswithinourModel,anddisplayingtheid,title,

Page 256: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

author,andisbndetailsforeachbook.

Next,wesetupa<ahreftag,thatpointstoourWebViewController.csclass,andin-turnwillcalltheBookLibraryEdit.cshtmlRazortemplatetoretrieveanddisplaythebookentrydetailsfortheassociatedidentifier.Thehybridtag,usedtoidentifyiftheURLisnotourowncustomscheme,andwilljustlettheWebViewloadtheURLasusual.Finally,wesetupanother<ahreftag,thatpointstoourWebViewController.csclass,andin-turnwillcalltheBookLibraryAdd.cshtmlRazortemplatetoallowtheusertocreateanotherbook.Youwillnoticethatwedon'tneedtopassinanidforthebook,asthiswillbeautomaticallyassignedoncethebookhassuccessfullybeenwrittentothedatabase.

Page 257: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingtheBookLibraryAddRazortemplateIntheprevioussection,wecreatedandimplementedtheBookLibraryListingRazortemplatethatwillbeusedtodisplayalistofallbooksthathavebeenpreviouslyaddedtotheBookLibraryapplication.OurnextstepistobegincreatingtheRazortemplatethatwillallowtheusertocreateanewbookandsavethistoourdatabasemodel.

Let'sbeginbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheViewsfolder,bychoosingAdd|NewFile...,asyoudidwhencreatingtheBookLibraryListingintheprevioussectionentitledCreatingandimplementingthebooklistingmainpage,locatedwithinthischapter.

2. Next,choosethePreprocessedRazorTemplateoption,locatedwithintheTextTemplatingsection,andenterinBookLibraryAdd.

3. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyRazortemplatefile.

OurnextstepistostarttoimplementthecoderequiredforourBookLibraryAddRazortemplate,byperformingthefollowingsteps:

EnsurethattheBookLibraryAdd.cshtmlfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

@usingBookLibrary

@modelBookItem

<html>

<head>

<linkrel="stylesheet"href="style.css"/>

</head>

<body>

<h1>AddNewBookDetails</h1>

<tableborder="1"cellpadding="8">

<formaction="hybrid:SaveBookDetails"method="GET">

<inputname="id"type="hidden"value="@Model.Id"/>

<tr>

<td>Title:

<inputname="Title"value="@Model.Title"/></td>

<tr>

<td>Author:

<inputname="Author"value="@Model.Author"/></td>

<tr>

<td>BookISBN:

<inputname="ISBN"value="@Model.Isbn"/></td>

<tr>

<td>Synopsis:

<textareaname="Synopsis"rows="5"cols="40">

Page 258: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

@Model.Synopsis

</textarea>

</td>

<tr>

<tdcolspan="8">

<inputtype="submit"name="Button"value="Save"/>

<inputtype="submit"name="Button"value="Cancel"/>

</td>

</tr>

</form>

</table>

</body>

</html>

Intheprecedingcodesnippet,wedefinedtheHTMLlayoutinformationthatwillbeusedbyourBookLibraryAddRazortemplate.WefirstlyspecifiedthatweareusingtheBookLibrary.iOSnamespace,sothatwecanhaveaccesstoourdatabasemodelasspecifiedbythe@modeldirective.We'vealreadyexplainedthatthismustbetheveryfirstlineprecedingthe<html>tagwithinaRazortemplatefile.

Next,wesetupa<formactiontagsothatwhentheformgetssubmitted,theSaveorCancelbuttonsarepressed,ourWebViewController.csclasswillbecalled,andtheappropriateactionwilltakeplace.WespecifythehybridtaghereagaintoidentifyiftheURLisnotourowncustomscheme,andwilljustlettheWebViewloadtheURLasusual.

Page 259: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingtheBookLibraryEditRazortemplateIntheprevioussection,wecreatedandimplementedtheBookLibraryAddRazortemplatethatwillbeusedtoallowtheusertoaddnewbookentriestotheBookLibraryapplication.OurnextstepistobegincreatingtheRazortemplatethatwillallowtheusertoeditanexistingbookandsavethisbacktoourdatabasemodel.

Let'sbeginbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheViewsfolder,bychoosingAdd|NewFile...,asyoudidwhencreatingtheBookLibraryListingintheprevioussectionentitledCreatingandimplementingthebooklistingmainpage,locatedwithinthischapter.

2. Next,choosethePreprocessedRazorTemplateoption,locatedwithintheTextTemplatingsection,andenterinBookLibraryEdit.

3. Next,clickontheNewbuttontoallowthewizardtoproceedandcreatethenewemptyRazortemplatefile.

OurnextstepistostarttoimplementthecoderequiredforourBookLibraryEditRazortemplate,byperformingthefollowingsteps:

EnsurethattheBookLibraryEdit.cshtmlfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

@usingBookLibrary

@modelBookItem

<html>

<head>

<linkrel="stylesheet"href="style.css"/>

</head>

<body>

<h1>EditBookDetails</h1>

<tableborder="1"cellpadding="8">

<formaction="hybrid:SaveBookDetails"method="GET">

<inputname="id"type="hidden"value="@Model.Id"/>

<tr>

<td>Title:

<inputname="Title"value="@Model.Title"/></td>

<tr>

<td>Author:

<inputname="Author"value="@Model.Author"/></td>

<tr>

<td>BookISBN:

<inputname="ISBN"value="@Model.Isbn"/></td>

<tr>

<td>Synopsis:

<textareaname="Synopsis"rows="5"cols="40">

@Model.Synopsis

Page 260: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

</textarea></td>

<tr>

<tdcolspan="8">

<inputtype="submit"name="Button"value="Save"/>

<inputtype="submit"name="Button"value="Cancel"/>

@if(Model.Id>0){

<inputtype="submit"name="Button"value="Delete"/>

}

</td>

</tr>

</form>

</table>

</body>

</html>

Intheprecedingcodesnippet,wedefinetheHTMLlayoutinformationthatwillbeusedbyourBookLibraryEditRazortemplate.WefirstlyspecifythatweareusingtheBookLibrary.iOSnamespace,sothatwecanhaveaccesstoourdatabasemodelasspecifiedbythe@modeldirective,whichandwehavesaidthatthismustbetheveryfirstlineprecedingthe<html>tagwithinaRazortemplatefile.

Next,wesetupa<formactiontag,sothatwhentheformgetssubmittedtheSaveorCancelbuttonsarepressed,ourWebViewController.csclasswillbecalled,andtheappropriateactionwilltakeplace.WespecifythehybridtaghereagaintoidentifyiftheURLisnotourowncustomscheme,andwilljustlettheWebViewloadtheURLasusual.YouwillnoticethatthisimplementationisquitesimilartothatofourBookLibraryAdd.TheonlythingthatthisRazortemplatedoesdifferently,isifwehaveavalueforourbookid,wedisplaytheDeletebuttonsothattheusercanchoosetodeletethebookentry.

Note

TheAndroidversionoftheRazortemplatesareavailableinthecompanionsourcecodeforthisbook.

Page 261: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingtheWebViewControllerclassIntheprevioussection,wesuccessfullycreatedandimplementedeachofourRazortemplatesthatwillbeusedbyourBookLibraryapplication.Ournextstepistobeginimplementingthecodeforourapplication,thatwillberesponsibleforinteractingwithourRazortemplates,andhandlingtheactionsassociatedwitheachmodel.ItwilluseourBookDatabaseclass,tohandletheperformanceofallthedatabaseactionsforourBookLibraryapplication.

Let'sbeginbyperformingthefollowingsteps:

1. EnsurethattheWebViewController.csfileisdisplayedwithinthecodeeditorwindow,andthenenterinthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

//

//WebViewController.cs

//WebContainerforrepresentingRazorTemplates

withinaWebView

//

//CreatedbyStevenF.Danielon20/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Linq;

usingFoundation;

usingUIKit;

usingSystem.Collections.Specialized;

namespaceBookLibrary

{

publicpartialclassWebViewController:

UIViewController

{

staticboolUserInterfaceIdiomIsPhone

{

get{return

UIDevice.CurrentDevice.UserInterfaceIdiom

==UIUserInterfaceIdiom.Phone;}

}

2. Next,wedeclareawebViewobjectthatwillpointtoourUIWebViewinstance,andthendeclareourWebViewController()classconstructormethodthatwillbeinstantiatedfromourAppDelegateclass,asyouwillseeoncewebeginimplementingthenecessarychanges.

3. Enterinthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

UIWebViewwebView;

publicWebViewController()

{

Page 262: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

protectedWebViewController(IntPtrhandle):base(handle)

{

//Note:thisconstructorshouldnotcontainany

//initializationlogic.

}

publicoverridevoidViewDidLoad()

{

base.ViewDidLoad();

4. Then,wedefineandspecifythescreendimensionsthatwewouldlikeourwebViewtocontain.Inthiscase,wesetthistotakeupthewholeregionofourscreenandthenaddthistoourexistingviewcontainer.Inthenextstep,wecalltheGetItemsinstancemethodonourBookLibraryDB.Databasetoreturnallexistingbookentrieswithinthedatabase,andassignthistoourmodel.

5. Inthenextstep,wespecifytheBookLibraryListingRazortemplate,andpassinthemodelthatwillbeusedtopopulatetheViewModel.Next,wecalltheGenerateString()methodonourtemplate,toexecutethetemplatewithinthemainapplicationbundleandreturntheoutputasastring,andthenloadthiswithinourwebView,usingtheLoadHtmlStringmethod:

webView=newUIWebView(UIScreen.MainScreen.Bounds);

View.Add(webView);

//InterceptURLloadingtohandlenativecallsfrom

//browser

webView.ShouldStartLoad+=HandleShouldStartLoad;

//RendertheviewtouseourBookList.cshtmlfile

varmodel=BookLibraryDB.Database.GetItems().ToList();

vartemplate=newBookLibraryListing()

{Model=model};

varpage=template.GenerateString();

//LoadtherenderedHTMLintotheviewwithabaseURL

//thatpointstotherootofthebundledResources

//folder

webView.LoadHtmlString(page,NSBundle.MainBundle.BundleUrl);

//Performanyadditionalsetupafterloadingtheview,

//typicallyfromanib.

}

publicoverridevoidDidReceiveMemoryWarning()

{

base.DidReceiveMemoryWarning();

//Releaseanycacheddata,images,etcthataren't

//inuse.

}

Page 263: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

boolHandleShouldStartLoad(UIWebViewwebView,NSUrlRequest

request,UIWebViewNavigationTypenavigationType)

{

//IftheURLisnotourowncustomscheme,just

//letthewebViewloadtheURLasusual

conststringscheme="hybrid:";

if(request.Url.Scheme!=scheme.Replace(":",""))

returntrue;

//Thishandlerwilltreateverythingbetweenthe

//protocoland"?"asthemethodname.Thequerystring

//hasalloftheparameters.

varresources=request.Url.ResourceSpecifier.Split('?');

varmethod=resources[0];

varparameters=System.Web.HttpUtility.ParseQueryString(

resources[1]);

6. Next,wecreateaswitchstatementtohandlethetypeofmethodoperationthatweobtainedfromtheRazortemplatedirectlyafterthehybrid:tag,andhandleaccordingly:

switch(method)

{

case"CreateNewBook":

CreateNewBook(webView);

break;

case"EditBookDetails":

EditBookDetails(webView,parameters);

break;

case"SaveBookDetails":

SaveBookDetails(webView,parameters);

break;

default:

//Casesnotcoveredarehandledhere.

break;

}

returnfalse;

}

7. Then,weneedtocreatetheCreateNewBook()instancemethodthatwillberesponsibleforhandlingthecreationofournewbookentry.ThismethodacceptsthenameofthewebViewto

Page 264: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

displayitscontentandwespecifytheBookLibraryAddRazortemplate,andpassinthemodelthatwillbeusedtopopulatetheViewModel.Next,wecalltheGenerateString()methodonourtemplate,toexecutethetemplatewithinthemainapplicationbundleandreturntheoutputasastring,andthenloadthiswithinourwebView,usingtheLoadHtmlStringmethod:

///<summary>

///Handlesthecreationofournewbookentry.

///</summary>

///<paramname="webView">Webview.</param>

voidCreateNewBook(UIWebViewwebView,

NameValueCollectionparameters)

{

vartemplate=newBookLibraryAdd()

{Model=newBookItem()};

varpage=template.GenerateString();

webView.LoadHtmlString(page,

NSBundle.MainBundle.BundleUrl);

}

8. Next,weneedtocreatetheEditBookDetails()instancemethodthatwillberesponsibleforhandlingtheeditingofourbookentry.ThismethodacceptsthenameofthewebViewtodisplayitscontentaswellasanyparameters.Next,wespecifytheBookLibraryEditRazortemplate,andpassinthemodelaswellastheidvaluefortheselectedbookentrytobeusedtopopulatetheViewModel.Next,wecalltheGenerateString()methodonourtemplate,toexecutethetemplatewithinthemainapplicationbundleandreturntheoutputasastring,andthenloadthiswithinourwebView,usingtheLoadHtmlStringmethod:

///<summary>

///Handlestheeditingofourbookdetails.

///</summary>

///<paramname="webView">Webview.</param>

///<paramname="parameters">Parameters.</param>

voidEditBookDetails(UIWebViewwebView,

System.Collections.Specialized.NameValueCollectionparameters)

{

varmodel=BookLibraryDB.Database.GetItem(

Convert.ToInt32(parameters["Id"]));

vartemplate=newBookLibraryEdit(){Model=model};

varpage=template.GenerateString();

webView.LoadHtmlString(page,

NSBundle.MainBundle.BundleUrl);

}

9. Then,weneedtocreatetheSaveBookDetails()instancemethodthatwillberesponsibleforhandlingthesavingofourbookentry.ThismethodacceptsthenameofthewebViewtodisplayitscontentaswellasanyparameters.Next,wegrabthenameofthebuttonthatwepressedfromtherelevantRazortemplateanduseaswitchstatementtohandlethetypeofbuttonoperationandhandleaccordingly.Oncetheoperationhascompletedsuccessfully,wereturn,andloadtheBookLibraryListingpagewithinthewebViewcontainer:

///<summary>

///SavesthebookdetailstotheSQLiteBookDetailsDatabase.

Page 265: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

///</summary>

///<paramname="webView">Webview.</param>

///<paramname="parameters">Parameters.</param>

voidSaveBookDetails(UIWebViewwebView,

System.Collections.Specialized.NameValueCollectionparameters)

{

//PointstoourEditBookDetailsHTMLpage.

varbutton=parameters["Button"];

switch(button)

{

case"Save":

SaveDetailsToDatabase(parameters);

break;

case"Delete":

DeleteBookDetails(parameters);

break;

case"Cancel":

break;

default:

//Casesnotcoveredarehandledhere.

break;

}

varmodel=BookLibraryDB.Database.GetItems().ToList();

vartemplate=newBookLibraryListing(){Model=model};

webView.LoadHtmlString(template.GenerateString(),

NSBundle.MainBundle.BundleUrl);

}

10. Next,weneedtocreatetheSaveDetailsToDatabase()instancemethodthatwillberesponsibleforhandlingthesavingofourbookentrytotheSQLitedatabase.ThismethodacceptsalistofparametersthathavebeenenteredwithintheBookLibraryAddorBookLibraryEditRazortemplatescreens,andcreatesaBookItemdatabasemodel.ThisthengetspassedtotheSaveItemmethodthatourBookLibraryDBwrapperclasscallstheBookDatabaseclass:

///<summary>

///SavesthebookdetailstoourSQLitedatabase.

///</summary>

///<returns>Thedetailstodatabase.</returns>

///<paramname="parameters">Parameters.</param>

voidSaveDetailsToDatabase(System.Collections.Specialized.NameV

alueCollectionparameters)

{

varbook=newBookItem

{

id=Convert.ToInt32(parameters["Id"]),

title=parameters["Title"],

author=parameters["Author"],

isbn=parameters["Isbn"],

synopsis=parameters["Synopsis"]

};

BookLibraryDB.Database.SaveItem(book);

}

11. Then,weneedtocreatetheDeleteBookDetails()instancemethodthatwillbe

Page 266: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

responsibleforhandlingthesavingofourbookentrytotheSQLitedatabase.ThismethodacceptsalistofparametersthathavebeenenteredwithintheBookLibraryEditRazortemplatescreen,andpassestheidofthebookentrytotheDeleteItemmethodthatourBookLibraryDBwrapperclasscallstheBookDatabase:

///<summary>

///HandlewhentheDeletebuttonhasbeenpressed

///</summary>

///<returns>Thebookdetails.</returns>

///<paramname="parameters">Parameters.</param>

voidDeleteBookDetails(System.Collections.Specialized.NameValue

Collectionparameters)

{

BookLibraryDB.Database.DeleteItem(Convert.ToInt32(

parameters["Id"]));

}

}

NowwehavesuccessfullyaddedthenecessarycodetoourWebViewController.csclasstoallowittocommunicatewithourRazortemplateswhenbookentrieshavebeencreated,updated,retrieved,deleted,andsaved.

Note

TheAndroidversionoftheWebViewController.csclassisavailableinthecompanionsourcecodeforthisbook.

12. Next,weneedtoinitializeourbookslibrarySQLitelibrarydatabasewithineachofourplatform-specificstart-upclasses(forexample,AppDelegate.csforiOSandMainActivity.csforAndroid).

13. EnsurethattheAppDelegate.csfileisdisplayedwithinthecodeeditorwindow,andthenenterinthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

usingSystem;

usingSystem.IO;

usingFoundation;

usingUIKit;

usingSQLite;

namespaceBookLibrary

{

//TheUIApplicationDelegatefortheapplication.

Thisclass

//isresponsibleforlaunchingtheUserInterfaceofthe

//application,aswellaslistening

(andoptionallyresponding)

//toapplicationeventsfromiOS.

[Register("AppDelegate")]

publicclassAppDelegate:UIApplicationDelegate

{

//class-leveldeclarations

publicoverrideUIWindowWindow

{

Page 267: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

get;

set;

}

publicoverrideboolFinishedLaunching(UIApplication

application,NSDictionarylaunchOptions)

{

//Overridepointforcustomizationafterapplication

//launch.Ifnotrequiredforyourapplicationyoucan

//safelydeletethismethod

//createanewwindowinstancebasedonthescreensize

Window=newUIWindow(UIScreen.MainScreen.Bounds);

//Declarethenametouseforourdatabasename

varsqliteFilename="BookLibrary.db";

stringdocumentsPath=Environment.GetFolderPath(

Environment.SpecialFolder.Personal);

stringlibraryPath=Path.Combine(documentsPath,"..",

"Library");

vardatabasePath=Path.Combine(libraryPath,sqliteFilename);

//Setaconnectiontoourdatabase

vardatabaseConn=newSQLiteConnection(databasePath);

BookLibraryDB.SetDatabaseConnection(databaseConn);

//SetourRootViewControllertobetheinstanceof

//ourBookViewControllerclassandmakeitvisible.

Window.RootViewController=newWebViewController();

Window.MakeKeyAndVisible();

returntrue;

}

...

...

...

}

Intheprecedingcodesnippet,webeganbyimportingboththeSQLiteandSystem.IOclasses,andthenmodifiedtheFinishedLaunchingmethodtocreateanewWindowinstance

Page 268: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

basedonthescreensizeofthedevice.SincewehavespecifiedthatwewantourprojecttoworkonbothiPadandiPhonedevices,thiswilltakeupthefullscreendimensions.

Next,wedeclaredthenametouseforourdatabasenameandspecifiedthelocationofwheretosavetheBookLibrary.dbdatabaseto,asdeterminedbythedatabasePathstring.Inournextstep,wesetupaconnectiontoourdatabase,andthensettheRootViewControllertobetheinstanceofourBookViewControllerclass,beforefinallymakingthisbecomevisibleonscreen.

Note

TheAndroidversionoftheMainActivity.csclassisavailableinthecompanionsourcecodeforthisbook.

Page 269: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthebooklibraryCascadingStyleSheet(CSS)Inthissection,weneedtomakesomefinalchangestothestyles.cssfile.ThisfileisessentiallyaCSS,andanyRazortemplatesthatutilizethisstylesheetwillinheriteverythingthatitcontains.WewillbasicallybemakingsomeminorchangestothebodyorourHTMLpages,applyingpaddingtomargins,settingfontsizes,andcolorsofweblinkswhentheyarepressed.

Let'sbeginbyperformingthefollowingstep:

1. EnsurethattheStyle.cssfileisdisplayedwithinthecodeeditorwindow,andthenenterinthefollowinghighlightedcodesections,asshowninthefollowingcodesnippet:

/*Thisisaminimalstylesheetintendedtodemonstrate

howtoincludestaticcontentinyourhybridapp.

Otherstaticcontent,suchasjavascriptfilesandimages,

canbeincludedinthissamefolder(ResourcesoniOS

orAssetsonAndroid),withthesameBuildAction

(BundleResourceoniOSorAndroidAssetonAndroid),

tobeaccessiblefromapathstartingattheroot

ofyourhybridapplication.*/

#page{

margin-top:10px;

}

html,

body{

margin:7px;

padding:0px;

border:0px;

color:#000;

background:#ffffe0;

}

html,body,p,th,td,li,dd,dt

{

font:1emArial,Helvetica,sans-serif;

}

h1{

font-family:Arial,Helvetica,sans-serif;

font-size:18;

}

a:link{

color:#00f;

}

Page 270: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

a:visited{

color:#009;

}

a:hover{

color:#06f;

}

a:active{

color:#0cf;

}

NowthatwehavefinishedbuildingallthenecessarycomponentsforourBookLibraryapplication,ournextstepistofinallybuildandruntheBookLibraryapplicationwithintheiOSsimulator.Whencompilationcompletes,theiOSSimulatorwillappearautomaticallyandtheBookLibraryapplicationwillbedisplayed,asshowninthefollowingscreenshot:

Asyoucanseefromtheprecedingscreenshot,thiscurrentlydisplaysourBookLibraryDatabaseListingpage.Sincewedon'thaveanydetailsaddedyet,thiswillshowupasblank,andyoumustpresstheAddNewBookbuttontodisplaytheAddNewBookDetailsscreen:

Page 271: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TheprecedingscreenshotshowstheupdatedBookLibraryDatabaseListingRazortemplatepageViewModelwiththeinformationsavedfromthepreviousscreen.ClickingontheEditlinkwilldisplaytheEditBookDetailsscreenwithallthepreviouslyenteredbookdetailspopulated.

Page 272: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,youlearnedabouttheRazortemplatingengineandhowyoucanuseittocreateahybridmobilesolution.Youalsolearnedhowtocreateandusemodelswithinyourapplication,andhavetheinformationsavedtoanSQLitedatabase,andretrievedlater.Finally,youlearnedhowyoucanuseJavaScriptcodeusingC#toexecutemethodcalls.

Inthenextchapter,you'lllearnhowtocreateandconsumeaRESTfulwebserviceAPI,sothatitcanbeusedwithintheTrackMyWalksapplicationtosaveandretrieveinformationenteredwithintheViewModels.

Page 273: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter7.IncorporatingAPIDataAccessUsingMicrosoftAzureAppServicesInthepreviouschapter,welearnedabouttheRazortemplatingengineandhowyoucanuseittocreateahybridmobilesolution.Youlearnedhowtocreateandusemodelswithinyourapplication,andhowtosavetheinformationtoaSQLitedatabaseandretrieveitlater.Towardstheendofthechapter,youlearnedhowyoucanuseJavaScriptcodeusingC#toexecutemethodcalls.

Upuntilthispoint,youhavebeenbuildingtheTrackMyWalksappwithstaticwalktrailinformationthathasbeenhard-codedwithintheTrackMyWalksapp.However,intherealworld,itisveryrarethatyourappwilldependpurelyonlocalstaticdata,andyouwillneedtosourceyourinformationfromaremotedatasource,typicallyusingaRESTfulAPI.Insomecases,yourappmayevencommunicatewithathird-partyAPI,forexampleFacebook.

Inthischapter,you'lllearnhowyoucanuseMicrosoftAzureAppservicestocreateyourveryfirstlive,cloud-basedbackendHTTPwebservicetohandleallthecommunicationbetweenthecloudandtheapp.YouwillalsolearnhowtocreateaDataServiceAPIthatwillallowtheapptoconsumetheAPIsothatwecanretrieve,store,anddeletewalktrailinformationfromthecloudallwithintheTrackMyWalksapp.

Thischapterwillcoverthefollowingpoints:

GainanunderstandingofwhatMicrosoftAzureAppservicesareSettinguptheTrackMyWalksappwithintheMicrosoftAzureportalAddingtheHttpClientandJSON.NetNuGetpackagestothesolutionCreatingtheTrackMyWalksbaseHTTPserviceCreatingtheTrackMyWalksAPIdataserviceUpdatingtheTrackMyWalksViewModelstousetheAPIdataserviceRunningtheTrackMyWalksappwithinthesimulator

Page 274: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SettingupourTrackMyWalksappusingMicrosoftAzureInthissection,wewilllookatthestepsrequiredtosetuptheTrackMyWalksapplicationwithinMicrosoftAzure.NearlyallmobileapplicationsthatyouwilldevelopwillrequiretheabilitytocommunicatewithanAPItostore,retrieve,update,anddeleteinformation.ThisAPIcanbeanexistingonethatsomeonewithinyourorganizationhasalreadycreated,butsometimesyouwillneedtocreateyourownAPIforyourapplication.

MicrosoftAzure,or("Azure"asit'sbestknownfor),isessentiallyacloud-basedplatformthatwascreatedbyMicrosoftbackinFebruary2010.Azurewasdesignedforbuilding,deploying,andmanagingseveralapplicationsandtheirassociatedservices,suchasSaaS,PaaS,andIaaS.

EachoftheMicrosoftAzurespecificassociatedservicesareexplainedinthefollowingtable:

Azureservice Description

SaaS SoftwareasaServiceprovidessoftwarelicensinganddeliverymodelswheresoftwareislicensedonasubscriptionbasisandiscentrallyhosted.

PaaSPlatformasaServiceprovidescustomerswithaplatformtodevelop,run,andmanageapplicationswithoutthecomplexitiesofmaintainingtheinfrastructurewhendevelopingandlaunchinganapp.

IaaS InfrastructureasaServiceprovidesvirtualizedcomputingresourcesovertheInternet.

OneofthemainbenefitsofusingMicrosoftAzureMobileAppsisthattheyprovideyouwithaveryquickandeasywaytogetafullyfunctionalbackendserviceupandrunningwithinamatterofminutes.BeforewecanproceedwithsettingupandcreatingourTrackMyWalksdatabasewithinthecloud,youwillneedtohaveaMicrosoftAzureaccount.Ifyoudon'talreadyhaveone,youcancreateoneforfreeathttps://azure.microsoft.com/en-us/pricing/free-trial/.

OnceyouhavecreatedyourMicrosoftAzureaccount,youwillneedtologintotheMicrosoftAzureportalusingyourwebbrowser.Let'slookathowtodothis,byperformingthefollowingsteps:

1. LaunchyourwebbrowserwiththefollowingURLhttps://portal.azure.com/andlogintotheMicrosoftAzureportalusingyourcredentials.

2. Next,fromthemainMicrosoftAzureportaldashboard,clickthe+buttoninthetop-lefthandcornerfromtheNewsection,andselecttheWeb+Mobileoption,andthenchoosethe

Page 275: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

MobileAppoptionasshowninthefollowingscreenshot:

3. Then,enterinTrackMyWalkstouseasthenameforourappfortheAppnamefield.4. Next,eitherchooseyourSubscriptiontype,orleavethedefaultofFreeTrial.5. Then,provideanameforyourResourceGroup,eitherbycreatinganewone,orchoosing

fromanexistingone.6. Next,ensurethatthePintodashboardoptionhasbeenselected,sothatyoucanhaveyour

MobileAppdisplayedontheMicrosoftAzureDashboard.Thisisparticularlyuseful,andprovideseasyaccess.

NowthatwehavesuccessfullycreatedourMobileAppwithinMicrosoftAzure,ournextstepistobeginsettingupthedatabasethatwillallowourapptostorewalkentryinformation.Let'slookathowwecanachievethiswiththefollowingsteps:

1. FromtheDashboard,clickontheTrackMyWalksservice,asshowninthefollowingscreenshot:

Page 276: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

2. Next,choosetheDataconnectionsoptionfromtheMOBILEsectionundertheTrackMyWalksAppServicesection,asshowninthefollowingscreenshot:

Page 277: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Then,withintheTrackMyWalks-Dataconnectionsscreen,clickonthe+Addbutton,todisplaytheAdddataconnectionscreen,asshowninthefollowingscreenshot:

Page 278: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

4. Next,ensurethatyouhaveselectedSQLDatabasefromtheTypedropdown,andproceedtoconfigureyourSQLDatabase.

5. Then,clickontheOKbuttontosaveyourchangesandcreatethenewdataconnectionforourTrackMyWalksSQLserverdatabase.

OnceyouhavecreatedyourTrackMyWalksmobileappandSQLdatabasewithinMicrosoftAzure,bydefault,yourdatabasewon'tcontainanydatabasetablesordata.BeforewecanstartcommunicatingwithandconsumingtheAPIwithinourTrackMyWalksapp,weneedtocreateanewtablethatwillstoreourwalktrailentries.

Let'slookatthefollowingstepstoachievethis:

1. FromtheDashboard,clickontheTrackMyWalksservice,thenchoosetheEasytablesoptionfromtheMOBILEsectionundertheTrackMyWalksAppServicesection.

2. Next,withintheTrackMyWalks-Easytablesscreen,clickonthe+Addbutton,todisplaytheAddatablescreen,asshowninthefollowingscreenshot:

Page 279: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Then,enterinWalkEntriestouseasthenameforourtablefortheNamefield.4. Next,leavethedefaultpermissionsthathavebeensetforourInsertpermission,Update

permission,Deletepermission,Readpermission,andUndeletepermissiondropdownentries:

Page 280: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Then,clickontheOKbuttontosaveyourchanges,andyournewWalkEntriestablewillbeaddedtothelistofEasyTablesentries.

Note

WheneveryouchoosetheAllowanonymousaccesspermissionduringthecreationofyourtable,youareessentiallymakingtheAPIavailablewithoutprovidinganyspecificauthenticationheadersaspartoftheHTTPrequest.

BeforewecanstartmakingcallstoourAPIandconsumingthiswithinourTrackMyWalksapp,we'llrunaquickchecktoseeifourAPIendpointisworkingcorrectly.ThisisachievedbyissuingaGETHTTPrequestusingthecommandline,orifyou'dprefer,youcanuseaRESTconsoleclient.

6. Openyourterminalwindow,andtypeinthefollowingstatementfromthecommandlineasfollows:

Lastlogin:SunNov610:48:41onconsole

GENIESOFT-MAC-Mini:~stevendaniel$curl

https://trackmywalks.azurewebsites.net/tables/

walkentries--header"ZUMO-API-VERSION:2.0.0"

Page 281: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

IfyouhaveseteverythingupcorrectlywithintheMicrosoftAzureportal,youshouldreceivebacka200(Success)statuscode,alongwithanemptycollectionintheresponsebodyasfollows:

Lastlogin:SunNov610:48:41onconsole

GENIESOFT-MAC-Mini:~stevendaniel$curl

https://trackmywalks.azurewebsites.net/tables/

walkentries--header"ZUMO-API-VERSION:2.0.0"

[]GENIESOFT-MAC-Mini:~stevendaniel$

Note

ThereareseveralRESTconsoleclientsthatexistforyoutochoosefrom,ifyoudon'talreadyhaveoneinstalled.ItendtousePostmanforhandlingRESTAPIs,whichyoucandownloadfromhttp://www.getpostman.com/.

NowthatwehavesuccessfullycreatedourTrackMyWalksAPIandWalkEntriesdatatablewithintheservice,wecanbeginmakingcallstoourAPIandreceivingthoseresponsemessagesdirectlybackfromtheAPI.Inthenextsection,wewillbegintoaddtheJson.NetandHttpClient.NETFrameworklibrariesthatwillberesponsibleforhandlingtheRESTAPIrequeststosaveandretrieveourwalkentrydetails.

Page 282: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheJson.NetNuGetpackagetotheTrackMyWalksappNowthatyouhavesetupandcreatedtheTrackMyWalksdatabasewithintheMicrosoftAzureplatform,ournextstepistoaddtheJson.NetNuGetpackagetoourTrackMyWalksPortableClassLibrarysolution.TheJson.Netpackageisahigh-performanceJSONframeworkforthe.NETplatformthatallowsyoutoserializeanddeserializeanytypeof.NETobjectwithhelpoftheJSONserializer.

WhenwestarttoincorporatethisframeworkwithinourTrackMyWalkssolution,wewillhavetheabilityofperformingLINQtoJSONcapabilitiesthatwillenableustocreate,parse,query,andmodifytheJSONstructurethatwereceivebackfromourMicrosoftAzureTrackMyWalksdatabasetable.

Let'slookathowtoaddtheJson.NetNuGetpackagetoourTrackMyWalksPortableClassLibrary,byperformingthefollowingsteps:

1. Right-clickonthePackagesfolderthatiscontainedwithintheTrackMyWalksPortableClassLibrarysolution,andchooseAddPackages...menuoption,asshowninthefollowingscreenshot:

2. ThiswilldisplaytheAddPackagesdialog,enterinJson.Netwithinthesearchdialog,andselecttheJson.Netoptionwithinthelist,asshowninthefollowingscreenshot:

Page 283: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Finally,clickontheAddPackagebuttontoaddtheNuGetpackagetothePackagesfolder,containedwithintheTrackMyWalksPortableClassLibrarysolution.

NowthatyouhaveaddedtheJson.NetNuGetpackage,ournextstepistoaddtheHttpClientframeworktoourTrackMyWalksPortableClassLibrary,whichwewillbecoveringinthenextsection.

Page 284: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheHttpClientNuGetpackagetotheTrackMyWalksappIntheprevioussection,weaddedtheJson.NetNuGetpackagetoourTrackMyWalkssolution.OurnextstepistoaddtheHTTPlibrarytoourTrackMyWalkssolutiontoenableittocommunicatewithanAPIoverHTTP.

Sinceweareusingboth.NETandC#tobuildourXamarin.Formsapplication,wecanleveragealibrarywithinthe.NETFrameworkcalledSystem.Net.Http.HttpClient.ThisHttpClientframeworkprovidesuswithamechanismofsendingandreceivingdatausingstandardHTTPmethods,suchasGETandPOST.

Let'slookathowtoaddtheHttpClientNuGetpackagetoourTrackMyWalksPortableClassLibrary,byperformingthefollowingsteps:

1. Right-clickonthePackagesfolderthatiscontainedwithintheTrackMyWalksPortableClassLibrarysolution,andchoosetheAddPackages...menuoption.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledAddingtheJson.NetNuGetpackagetotheTrackMyWalksapplocatedwithinthischapter.

2. ThiswilldisplaytheAddPackagesdialog.Here,enterinHttpwithinthesearchdialog,andselecttheSystem.Net.Httpoption,asshowninthefollowingscreenshot:

Page 285: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Finally,clickontheAddPackagebuttontoaddtheNuGetpackagetothePackagesfolder,containedwithintheTrackMyWalksPortableClassLibrarysolution.

NowthatyouhaveaddedboththeJson.NetandSystem.Net.HttpNuGetpackagestooursolution,wecanbeginutilizingtheseframeworklibrariesasweprogressthroughoutthischapter.

Page 286: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkEntriesmodeltousetheJson.NetframeworkInthissection,wewillbeginbyupdatingtheWalkEntriesdatamodeltotakeadvantageofourbackendservicecalls,whenwecreatethese,andthentheWalkDataService.csandWalkWebService.csfileswillcommunicateandinteractwithourMicrosoftAzureTrackMyWalksdatabasetostore,delete,andretrievewalkentryinformation.

Let'snowstarttomodifyandimplementthecoderequiredforourWalkEntriesclassmodel,byperformingthefollowingsteps:

EnsurethattheWalkEntries.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections:

//

//WalkEntries.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingNewtonsoft.Json;

namespaceTrackMyWalks.Models

{

publicclassWalkEntries

{

[JsonProperty("id")]

publicstringId{get;set;}

publicstringTitle{get;set;}

publicstringNotes{get;set;}

publicdoubleLatitude{get;set;}

publicdoubleLongitude{get;set;}

publicdoubleKilometers{get;set;}

publicstringDifficulty{get;set;}

publicdoubleDistance{get;set;}

publicUriImageUrl{get;set;}

}

}

Intheprecedingcodesnippet,wehavesuccessfullymodifiedthedatabasemodelthatwillbeusedtostorewalkentryinformationwithinourMicrosoftAzuredatabase.Youwillnoticethatwehavedefineda[JsonProperty("id")]item,aswellasastringpropertynamedIdthatwillserveasauniqueprimarykeyforeachrecordthatwestorewithinthedatabase.WehavealsoupdatedourImageUrlpropertytoincludetheUritypethatwillbeusedtoconverttheURLenteredwithinthewalkentrypage,sothatitisstoredcorrectlywithinthedatabase.

Note

IfyouareinterestedinfindingoutmoreinformationabouttheJsonPropertyandtheNewtonsoft.Jsonclasses,pleaserefertotheJson.NETdocumentationlocatedat

Page 287: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_JsonProperty.htm.

Page 288: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheHTTPwebserviceclassfortheTrackMyWalksappIntheprevioussection,wesuccessfullymodifiedtheWalkEntriesdatabasemodelthatwillbeusedbyourTrackMyWalksapplication.ThiswillallowustohavealivebackendservicethatwillenableourapplicationtocommunicateoverHTTPsothatitcansendrequeststotheAPItoretrieve,add,anddeletetrailwalkentries.Inthissection,wewillneedameansforourapptocommunicatewithourAPIoverHTTP,andthereforeitwillrequireanHTTPlibrary.

Sinceweareusing.NETandC#,wecanusealibrarywithinthe.NETFramework,calledSystem.Net.Http.HttpClient.ThisFrameworkprovidesamechanismforallowingourapptosendandreceivedatausingstandardHTTPmethodssuchasGETandPOST.WewillbeginbycreatingabaseserviceclasswithinourTrackMyWalksPortableClassLibrarythatwillberesponsibleforhandlingalltheHTTPcommunicationsforus.

Let'snowstarttoimplementthecoderequiredforourWalkWebServicebase-classmodel,byperformingthefollowingsteps:

1. CreateanemptyclasswithintheServicesfolder,bychoosingAdd|NewFile...,asyoudidinthesectionentitled,CreatingthenavigationserviceinterfacefortheTrackMyWalksappwithinChapter3,NavigatingwithintheMVVMModel-TheXamarin.FormsWay.

2. Then,enterinWalkWebServiceforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethenewfile.

3. Next,ensurethattheWalkWebService.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//WalkWebService.cs

//TrackMyWalksHttpWebServiceClass

//

//CreatedbyStevenF.Danielon30/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Net.Http;

usingSystem.Text;

usingSystem.Threading.Tasks;

usingNewtonsoft.Json;

namespaceTrackMyWalks.Services

{

publicabstractclassWalkWebService

{

4. Then,weneedtocreateaprotectedasyncmethodcalledSendRequestAsync<T>thatacceptsaUrinamedurlaswellaHttpMethodnamedhttpMethod,andfinallyaDictionary<string,string>objectnamedheaders,aswellasanobjectnamed

Page 289: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

requestData,thatwillbeusedtoconstructtheHTTPrequest.Proceedandenterinthefollowingcodesnippet:

protectedasyncTask<T>SendRequestAsync<T>(

Uriurl,HttpMethodhttpMethod=null,

IDictionary<string,string>headers=null,

objectrequestData=null)

{

5. Next,we'llsetuptheresulttothedefault(T)typethatwillreturnadefaultvaluetoaparameterizedtypesincewedon'tknowwhatourresultwillcontainatthispoint.We'llthendeclareourmethodvariabletocontaintheGETHttpMethod.ThiswillbeusedtoreturnthecontentandthencreatearequestvariablethatwillsetupaninstanceofourHttpRequestMessageclassandthenserializeourrequesteddatatoourrequestobjectandreturntheinformationbackinJsonformatasdefinedbytheapplication/jsontype.Proceedandenterinthefollowingcodesnippet:

varresult=default(T);

varmethod=httpMethod??HttpMethod.Get;

varrequest=newHttpRequestMessage(method,url);

//Serializeourrequestdata

vardata=requestData==null?null:

JsonConvert.SerializeObject(requestData);

if(data!=null)

{

//Addtheserializedrequestdatatoourrequest

//object.

request.Content=newStringContent(data,

Encoding.UTF8,"application/json");

}

6. Then,we'llbeginiteratingthroughourheaderscollectiontoaddeachofourspecificheaderstotherequestobjectthatwillbesentalongwiththeHttpRequestMessageclass.Proceedandenterinthefollowingcodesnippet:

//Addeachofthespecifiedheaderstoourrequest

if(headers!=null)

{

foreach(varhinheaders)

{

request.Headers.Add(h.Key,h.Value);

}

}

7. Next,we'llsetupanddeclareahandlervariablethatinstantiatesaninstanceoftheHttpClientHandlerclasswhichisessentiallyaHttpMessageHandlerthatcontainsacommonsetofpropertiesthatworkacrosstheHttpWebRequestAPI.Inthenextstep,we'lldeclareaclientvariablethatinstantiatesourHttpClientclassthatacceptsourhandlervariabletobeginsendingourrequestoverHTTP.

8. Next,we'lldeclareourresponseobjectthatperformsaSendAsyncandacceptsourrequestobject,alongwithourHttpCompletionOption.ResponseContentReadthat

Page 290: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

completesafterreadingtheentireresponsecontent.9. Finally,we'llperformacomparisonchecktoseeifwehavesuccessfullyreadourcontent

andhavearesponsecodeof200(Success)returned,beforedeserializingourcontentintoJsonformat,usingtheJsonConvertmethod.Proceedandenterinthefollowingcodesnippet:

//GetaresponsefromourWebService

varhandler=newHttpClientHandler();

varclient=newHttpClient(handler;

varresponse=awaitclient.SendAsync(request,

HttpCompletionOption.ResponseContentRead);

if(response.IsSuccessStatusCode&&

response.Content!=null)

{

varcontent=awaitresponse.Content.

ReadAsStringAsync();

result=JsonConvert.DeserializeObject<T>(content);

}

returnresult;

}

}

}

NowthatwehavesuccessfullycreatedourbaseHTTPserviceclass,wecanbegintousethiswithinourViewModelsaswellasourWalkEntriesdatabasemodel,bycreatingabasesub-classwithinourDataServiceAPIwhichwewillbecoveringinthenextsection.

Note

IfyouareinterestedinfindingoutmoreinformationabouttheHttpClientHandlerandHttpClientclasses,pleaserefertotheMicrosoftdeveloperdocumentationlocatedathttps://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.118).aspx.

Page 291: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheDataServiceAPIfortheTrackMyWalksappIntheprevioussection,wecreatedaWalkWebServiceclassthatprovidesuswithameansofsendingHTTPrequeststoourTrackMyWalksMicrosoftAzuredatabase.Inthissection,wewillbeginbycreatingadataserviceclassthatwillallowustosendandreceiveresponsesbackfromourAPI,inJsonformatwhichwillupdatetheWalkEntriesdatabasemodelsoourapplicationcanusethis.

WewillbeginbycreatingtheinterfaceforourdataservicethatcanbeusedtocommunicatewitheachoftheViewModelsthatourTrackMyWalksapplicationutilizes.Let'snowstarttoimplementthecoderequiredforourIWalkDataServicebase-classmodel,byperformingthefollowingsteps:

1. CreateanemptyinterfacewithintheServicesfolder.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingthenavigationserviceinterfacefortheTrackMyWalksappwithinChapter3,NavigatingwithintheMVVMModel-TheXamarin.FormsWay.

2. Next,enterinIWalkDataServiceforthenameofthenewinterfacethatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethefile.

3. Then,ensurethattheIWalkDataService.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//IWalkDataService.cs

//TrackMyWalksDataServiceInterface

//

//CreatedbyStevenF.Danielon30/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Threading.Tasks;

usingSystem.Collections.Generic;

usingTrackMyWalks.Models;

namespaceTrackMyWalks.Services

{

publicinterfaceIWalkDataService

{

Task<IList<WalkEntries>>GetWalkEntriesAsync();

TaskAddWalkEntryAsync(WalkEntriesentry);

TaskDeleteWalkEntryAsync(WalkEntriesentry);

}

}

Intheprecedingcodesnippet,webeginbyimplementingthemethodsthatwillberequiredtoretrieve,update,anddeleteourWalkEntriesinformation.TheGetWalkEntriesAsyncinstance

Page 292: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

methodusesagenerictypewhichisusedtorestricttheWalkEntriestouseobjectsoftheIListclass.

TheAddWalkEntryAsyncinstancemethodacceptsanentryparameterthatcontainsthewalkentrydetailstobeaddedoftypeWalkEntries,andourDeleteWalkEntryAsyncinstancemethodacceptsanentryparameterthatneedstobedeletedfromourdatabase.WeusetheTaskclasstoessentiallyhandleallasynchronousoperations,byensuringthattheasynchronousmethodsthatweinitiatewilleventuallyfinish,thuscompletingthetaskinhand.

Page 293: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheDataServiceAPIclassfortheTrackMyWalksappIntheprevioussection,wecreatedourdataservicebaseinterfaceclassforourdataservice,andwedefinedseveraldifferentinstancemethodsthatourclasswillbeutilizing.ThiswillessentiallybeusedbyeachofourViewModelsalongwiththeViews(pages).Let'snowstarttoimplementthecoderequiredforourWalkDataServiceclass,byperformingthefollowingsteps:

1. CreateanemptyclasswithintheServicesfolder,bychoosingAdd|NewFile...,asyoudidwhencreatingtheDataServiceinterfaceintheprevioussectionentitledCreatingtheDataServiceAPIfortheTrackMyWalksapplocatedwithinthischapter.

2. Then,enterinWalkDataServiceforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethenewfile.

3. Next,ensurethattheWalkDataService.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//WalkDataService.cs

//TrackMyWalksAPIDataServiceClass

//

//CreatedbyStevenF.Danielon30/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Threading.Tasks;

usingSystem.Net.Http;

usingTrackMyWalks.Models;

usingNewtonsoft.Json;

namespaceTrackMyWalks.Services

{

4. Next,weneedtomodifyourWalkDataServiceclassconstructor,sothatitcaninheritfrombothourWalkWebServicebase-classaswellastheIWalkDataServiceclass:

publicclassWalkDataService:WalkWebService,IWalkDataService

{

5. Next,we'lldeclaretwoprivateclassproperties,_baseUriand_headers.The_baseUripropertywillbeusedtostorethebaseURLandthe_headerspropertyoftheIDictionary<string,string>typethatwillbeusedtostoretheheaderinformationthatwewanttopasstoourWalkWebServiceclass.

6. Thezumo-api-versionisbasicallyaspecialheadervaluethatisusedbytheHTTPclientwhencommunicatingwithMicrosoftAzuredatabases.Proceedandenterinthefollowingcodesnippet.

readonlyUri_baseUri;

readonlyIDictionary<string,string>_headers;

Page 294: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//OurClassConstructorthatacceptstheAzureDatabase

//Uripath

publicWalkDataService(UribaseUri)

{

_baseUri=baseUri;

_headers=newDictionary<string,string>();

_headers.Add("zumo-api-version","2.0.0");

}

7. Next,we'llimplementtheGetWalkEntriesAsyncinstancemethodthatwillretrieveallWalkEntriesthatarecontainedwithinourdatabase.We'lldefineaurlvariablethatconstructsanewUriobjectusingour_baseUriURLandcombiningthiswithourwalkEntriesdatabasetablewithinthetablessectionofourTrackMyWalksAzuredatabaseandcalltheSendRequestAsyncWalkWebServicebase-classinstancemethod.

8. We'llpassintheHttpMethod.GetmethodtypetotellourbaseclassthatwearereadytoretrieveourWalkEntries.Proceedandenterinthefollowingcodesnippet:

//APItoretrieveourWalkEntriesfromourdatabase

publicasyncTask<IList<WalkEntries>>GetWalkEntriesAsync()

{

varurl=newUri(_baseUri,"/tables/walkentries");

returnawaitSendRequestAsync<WalkEntries[]>

(url,HttpMethod.Get,_headers);

}

9. Next,we'llimplementtheAddWalkEntryAsyncinstancemethodthatwilladdwalkentryinformationtothewalkEntriestablecontainedwithinourdatabase.WedefineaurlvariablethatconstructsanewUriobjectusingour_baseUriURLandcombiningthiswiththewalkEntriesdatabasetablewithinthetablessectionofourTrackMyWalksAzuredatabaseandcalltheSendRequestAsyncWalkWebServicebase-classinstancemethod.

10. We'llpassintheHttpMethod.PostmethodtypethatwilltellourbaseclassthatwearereadytosubmitinformationtoourwalkEntriesdatabasetable.Proceedandenterinthefollowingcodesnippet:

//APItoaddourWalkEntryinformationtothedatabase

publicasyncTask<WalkEntries>AddWalkEntryAsync(

WalkEntriesentry)

{

varurl=newUri(_baseUri,"/tables/walkentries");

awaitSendRequestAsync<WalkEntries>(url,HttpMethod.Post,

_headers,entry);

}

11. Next,we'llimplementtheDeleteWalkEntryAsyncinstancemethodthatwillpermanentlydeleteassociatedwalkentryinformationfromourwalkEntriestablecontainedwithinourdatabase.We'lldefineaurlvariablethatconstructsanewUriobjectusingour_baseUriURLandcombiningthiswithourwalkEntriesdatabasetable,andpassintheIdvalueofourselectedwalkentrywithintheWalksPageListView.

12. We'llthencalltheSendRequestAsyncWalkWebServicebaseclassinstancemethod.We'llpassintheHttpMethod.DeletemethodtypethatwilltellourbaseclassthatwearereadytopermanentlydeletethewalkentrywithinourwalkEntriesdatabasetable.Proceedand

Page 295: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

enterinthefollowingcodesnippet:

//APItodeleteourWalkEntryfromthedatabase

publicasyncTaskDeleteWalkEntryAsync(WalkEntriesentry)

{

varurl=newUri(_baseUri,string.Format("/tables/walken

tries/{0}",entry.Id));

awaitSendRequestAsync<WalkEntries>(url,HttpMethod.Delete

,_headers);

}

}

}

Intheprecedingcodesnippet,webeganbyimplementingeachoftheinstancemethodsthatwedefinedwithinourIWalkDataServiceinterfaceclass.WeusedtheSendRequestAsyncmethodonourbaseclass,andpassedintheAPIdetails,alongwiththeHttpMethodtype,andthezumo-api-versionheaderinformation.YouwillhavenoticedthatwepassedintheWalkEntriesdatamodelobject.ThisissothattheobjectcanbeserializedandaddedtotheHTTPrequestmessagecontent.

Note

IfyouareinterestedinlearningmoreHTTP,pleaserefertotheHypertextTransferProtocolguidelocatedathttps://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol.

TheHTTPclassexposesseveraldifferenttypesofHTTPmethodsthatareusedbytheHttpMethodclass,whichareexplainedinthefollowingtable.

HTTPmethods Description

GET

ThistypetellstheHttpMethodclassprotocolthatwearereadytorequestmessagecontentoverHTTPtoretrieveinformationfromourAPI,andreturnthisinformationback,basedontherepresentationformatspecifiedwithintheAPI.

POSTThistypetellstheHttpMethodclassprotocolthatwewanttocreateanewentrywithinourtable,asspecifiedwithinourAPI.

DELETEThistypetellstheHttpMethodclassprotocolthatwewanttodeleteanexistingentrywithinourtable,asspecifiedwithinourAPI.

Note

IfyouareinterestedinlearningmoreaboutclientandserverversioninginMobileAppsand

Page 296: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

MobileServices,pleaserefertotheMicrosoftAzuredocumentationlocatedathttps://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-client-and-server-versioning/.

Inthenextsection,wewillupdateourWalkBaseViewModelsothatitcanuseourDataServiceAPIclass,andinitializeourMicrosoftAzureTrackMyWalksdatabase.

Page 297: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkBaseViewModeltouseourDataServiceAPIIntheprevioussections,wecreatedtheinterfacesclassesthatwillbeusedbyourWalkWebServiceandWalkDataServiceclasstoenableourTrackMyWalksapplicationtocommunicatewiththedatabasethatisstoredwithintheMicrosoftAzureplatform.

OurnextstepistobeginimplementingthecodethatwillberequiredtomakeaconnectiontoourTrackMyWalksMicrosoftAzuredatabasesothatourappuseslivedatainsteadofthelocal,hard-codeddatathatwecurrentlyhaveinplace.

Let'slookathowwecanachievethis,byfollowingthesteps:

1. EnsurethattheWalkBaseViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesectionsasshowninthecodesnippet:

//

//WalkBaseViewModel.cs

//TrackMyWalksBaseViewModel

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.ComponentModel;

usingSystem.Runtime.CompilerServices;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Services;

namespaceTrackMyWalks.ViewModels

{

publicabstractclassWalkBaseViewModel:

INotifyPropertyChanged

{

protectedIWalkNavServiceNavService{

get;privateset;}

bool_isProcessBusy;

publicboolIsProcessBusy

{

get{return_isProcessBusy;}

set

{

_isProcessBusy=value;

OnPropertyChanged();

OnIsBusyChanged();

}

}

2. Next,we'llcreateaIWalkDataServiceinterfacepropertycalled_azureDatabaseService.TiswillstoreandretrievethevalueofourTrackMyWalksAzuredatabaseURL.TheAzureDatabaseServicepropertycontainsboththegetter(get)andsetter(set)implementationsthat.WhenwesettheAzureDatabaseServiceproperty,weassignthisvaluetoour_azureDatabaseServicevariable,andthencallthe

Page 298: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

OnPropertyChangedinstancemethodstotelltheViewModelsthatachangehasbeenmade:

IWalkDataService_azureDatabaseService;

publicIWalkDataServiceAzureDatabaseService

{

get{return_azureDatabaseService;}

set

{

_azureDatabaseService=value;

OnPropertyChanged();

}

}

3. Then,we'llneedtomodifytheWalkBaseViewModelclassconstructorandcreateaninstancetoourWalkDataServiceclass,thatinheritsfromtheIWalkDataServiceinterfaceclass,andthenassignthistoourAzureDatabaseServicepropertysothatitcanbeusedthroughouteachofourViewModels:

protectedWalkBaseViewModel(IWalkNavServicenavService)

{

//DeclareourNavigationServiceandAzureDatabaseURL

varWALKS_URL="https://trackmywalks.azurewebsites.net";

NavService=navService;

AzureDatabaseService=newWalkDataService(new

Uri(WALKS_URL,UriKind.RelativeOrAbsolute));

}

publicabstractTaskInit();

publiceventPropertyChangedEventHandlerPropertyChanged;

protectedvirtualvoidOnPropertyChanged([CallerMemberName]

stringpropertyName=null)

{

varhandler=PropertyChanged;

if(handler!=null)

{

handler(this,newPropertyChangedEventArgs(

propertyName));

}

}

protectedvirtualvoidOnIsBusyChanged()

{

//WeareprocessingourWalksTrailInformation

}

}

publicabstractclassWalkBaseViewModel<WalkParam>:

WalkBaseViewModel{

protectedWalkBaseViewModel(IWalkNavServicenavService):

base(navService)

Page 299: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

}

publicoverrideasyncTaskInit()

{

awaitInit(default(WalkParam));

}

publicabstractTaskInit(WalkParamwalkDetails);

}

}

Intheprecedingcodesnippet,webeginbycreatingaAzureDatabaseServicepropertythatinheritsfromourIWalkDataServiceclass,andthencreateditsassociatedgetterandsetterqualifiers.Next,weupdatedtheWalkBaseViewModelclassconstructortosettheAzureDatabaseServicepropertytoaninstanceofWalkDataServiceclasssothatitcanbeusedthroughouteachofourViewModels.

Page 300: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalkEntryViewModeltouseourDataServiceAPINowthatwehavemodifiedourWalkBaseViewModelclasssothatitwillbeusedbyanyViewModelthatinheritsfromthisbaseclass,ournextstepistobeginmodifyingtheWalkEntryViewModelthatwillutilizeourWalkDataServiceclass,sothatanynewwalkinformationthatisenteredwillbesavedbacktoourAzuredatabase.Oncethat'sdonewecanbeginstoringwalkentryinformationwhentheSavebuttonispressed.

Let'slookathowwecanachievethiswiththefollowingsteps:

1. EnsurethattheWalkEntryViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesectionsasshowninthecodesnippet:

//

//WalkEntryViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

usingSystem;

namespaceTrackMyWalks

{

publicclassWalkEntryViewModel:WalkBaseViewModel

{

IWalkLocationServicemyLocation;

string_title;

publicstringTitle

{

get{return_title;}

set

{

_title=value;

OnPropertyChanged();

SaveCommand.ChangeCanExecute();

}

}

...

...

2. Next,locateandmodifytheExecuteSaveCommandinstancemethodtoincludeachecktoseeifourImageUrlfieldcontainsavalue,otherwisestoreanemptyplaceholderimagefortheImageUrlpropertywhentheSaveToolBarItemhasbeenpressed.Proceedandenterinthefollowinghighlightedcodesections:

asyncTaskExecuteSaveCommand()

Page 301: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

//Checktoseeifweareinthemiddleofprocessing

//arequest.

if(IsProcessBusy)

return;

//InitialiseourWalkEntryModeltostatethatweare

//inthemiddleofupdatingdetailstothedatabase.

IsProcessBusy=true;

//SetupourNewWalkitemmodel

varnewWalkItem=newWalkEntries

{

Title=this.Title,

Notes=this.Notes,

Latitude=this.Latitude,

Longitude=this.Longitude,

Kilometers=this.Kilometers,

Difficulty=this.Difficulty,

Distance=this.Distance,

ImageUrl=(this.ImageUrl==null?

newUri("https://heuft.com/upload/image/4

00x267/no_image_placeholder.png"):

newUri(this.ImageUrl))

};

//UponexitingourNewWalkEntryPage,weneedto

//stopcheckingforlocationupdates

myLocation=null;

3. Then,we'llmakeacalltoourAddWalkEntryAsyncinstancemethod,containedwithintheAzureDatabaseServiceclasstostorethenewlyenteredinformation.We'llincludeareferencetoourNavService.PreviousPagemethod,whichisdeclaredwithintheIWalkNavServiceinterfaceclasstoallowourWalkEntryPagetonavigatebacktothepreviouscallingpage,beforefinallyinitializingourIsProcessBusyindicatortofalsetoinformourViewModelthatwearenolongerprocessing.Proceedandenterinthefollowinghighlightedcodesections:

try

{

//SavethedetailsenteredtoourAzureDatabase

awaitAzureDatabaseService.AddWalkEntryAsync(newWalkItem);

awaitNavService.PreviousPage();

}

finally

Page 302: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

//Re-InitialiseourProcessBusyIndicator

IsProcessBusy=false;

}

}

//methodtocheckforanyformerrors

boolValidateFormDetails()

{

return!string.IsNullOrWhiteSpace(Title);

}

publicoverrideasyncTaskInit()

{

awaitTask.Factory.StartNew(()=>

{

Title="NewWalk";

Difficulty="Easy";

Distance=1.0;

});

}

}

}

Intheprecedingcodesnippet,wemodifiedtheExecuteSaveCommandinstancemethodtoincludeachecktoseeifourImageUrlfieldcontainsavaluepriortostoringtheinformationwithintheImageUrlproperty.Ifwehavedeterminedthatthispropertyisempty,weproceedtoassignanemptyplaceholderimagefortheImageUrlpropertytoavoidourapplicationperformingunexpectedresults.

Inthenextstep,weattempttomakeacalltoourAddWalkEntryAsyncinstancemethod,containedwithinourAzureDatabaseServiceclasstostorethenewlyenteredinformation.

Next,we'llincludeareferencetoourNavService.PreviousPagemethod,whichisdeclaredwithintheIWalkNavServiceinterfaceclasstoallowourWalkEntryPagetonavigatebacktothepreviouscallingpagewhentheSavebuttonhasbeenpressed.Finally,we'llinitializeourIsProcessBusyindicatortofalsetoinformourViewModelthatwearenolongerprocessing.

Page 303: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksPageViewModeltouseourDataServiceAPIInthissection,wewillproceedtoupdateourWalksPageViewModelViewModeltoreferenceourWalkDataServiceclass.SinceourWalksPageViewModelisusedtodisplayinformationfromourWalkEntriesmodel,wewillneedtoupdatethissothatitretrievesthisinformationfromtheTrackMyWalksdatabase,locatedwithinourMicrosoftAzureplatform,anddisplaythiswithintheListViewcontrol.

Let'slookathowwecanachievethiswiththefollowingsteps:

1. EnsurethattheWalksPageViewModel.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesectionsasshowninthefollowingcodesnippet:

//

//WalksPageViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Collections.ObjectModel;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingXamarin.Forms;

namespaceTrackMyWalks.ViewModels

{

publicclassWalksPageViewModel:WalkBaseViewModel

{

ObservableCollection<WalkEntries>_walkEntries;

publicObservableCollection<WalkEntries>walkEntries

{

get{return_walkEntries;}

set

{

_walkEntries=value;

OnPropertyChanged();

}

}

...

...

2. Next,locateandmodifytheLoadWalkDetailsinstancemethodtochecktoseeifwearealreadyinthemiddleofprocessingwalktrailitemswithintheListView.Nextwe'llproceedtopopulateourWalkEntriesarraywithitemsretrievedfromourGetWalkEntriesAsyncAzurewebserviceinstancemethodcalltopopulateourWalkEntriesasynchronouslyandusetheawaitkeywordtowaituntiltheTaskcompleted.Finally,we'llinitializeourIsProcessBusyindicatortofalsetoinformourViewModelthatwearenolongerprocessing.Proceedandenterinthefollowinghighlightedcode

Page 304: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

sections:

publicasyncTaskLoadWalkDetails()

{

//Checktoseeifwearealreadyprocessingour

//WalkTrailItems

if(IsProcessBusy)

{return;}

//Ifwearen'tcurrentlyprocessing,weneedto

//initialiseourvariabletotrue

IsProcessBusy=true;

try

{

//PopulateourWalkEntriesarraywithitems

//fromourAzureWebService

walkEntries=newObservableCollection<WalkEntries>

(awaitAzureDatabaseService.GetWalkEntriesAsync());

}

finally

{

//Re-initialiseourprocessbusyvaluebacktofalse

IsProcessBusy=false;

}

}

...

...

3. Then,createtheDeleteWalkItemcommandpropertywithinourclass,thatwillbeusedwithinourWalksPagetohandlewheneverweclickonawalkitemwithinourListView.TheDeleteWalkItempropertywillthenrunanaction,whenevertheDeleteoptionhasbeenchosenfromtheActionSheet,todeletethechosenitemasdeterminedbyourtrailDetailstopermanentlyremovetherecordfromourTrackMyWalksdatabaselocatedwithinourMicrosoftAzureplatform.Proceedandenterinthefollowinghighlightedcodesections:

Command_deleteWalkItem;

Page 305: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

publicCommandDeleteWalkItem

{

get

{

return_deleteWalkItem

??(_deleteWalkItem=

newCommand(async

(trailDetails)=>

awaitAzureDatabaseService.

DeleteWalkEntryAsync((WalkEntries)trailDetails)));

}

}

}

}

Intheprecedingcodesnippet,wemodifiedourLoadWalkDetailsinstancemethodtochecktoseeifwearealreadyinthemiddleofprocessingwalktrailitemswithintheListView.Then,weproceededtopopulateourWalkEntriesarraywithitemsretrievedfromourGetWalkEntriesAsyncAzurewebserviceinstancemethodcalltopopulateourWalkEntriesasynchronouslyandusetheawaitkeywordtowaituntiltheTaskcompleted.

Inthenextstep,weinitializedtheIsProcessBusyindicatortofalse,toinformourViewModelthatwearenolongerprocessing.

Finally,wecreatedaCommandpropertywithinourclassthatwillbeusedtopermanentlyhandlethedeletionofthechosenwalkentrywithinourListViewandourTrackMyWalksMicrosoftAzuredatabase.

Page 306: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksPagetousetheupdatedViewModelInthissection,weneedtoupdateourWalksPageContentPagesothatitcanreferencetheupdatedchangeswithinourWalksPageViewModel.WewillneedtoapplyadditionallogictohandledeletionsofwalkentryinformationfromourWalkEntriesmodelsothatitcanretrievenewlyupdatedinformationfromourTrackMyWalksdatabaselocatedwithinourMicrosoftAzureplatform,anddisplaythiswithintheListViewcontrol.

Let'slookathowwecanachievethiswithfollowingsteps:

1. EnsurethattheWalksPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesectionsasshowninthecodesnippet:

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

usingTrackMyWalks.DataTemplates;

usingTrackMyWalks.ValueConverters;

usingSystem.Diagnostics;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage

{

WalksPageViewModel_viewModel

{

get{returnBindingContextas

WalksPageViewModel;}

}

2. Next,modifythenewWalkItemvariable,whichiswithintheWalksPageclassconstructorandupdatetheTextpropertyforourToolbarItem.Proceedandenterinthefollowinghighlightedcodesections:

publicWalksPage()

{

varnewWalkItem=newToolbarItem

{

Text="Add"

};

//SetupourBindingclickeventhandler

Page 307: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

newWalkItem.SetBinding(ToolbarItem.CommandProperty,

"CreateNewWalk");

//AddtheToolBaritemtoourToolBar

ToolbarItems.Add(newWalkItem);

//DeclareandinitialiseourModelBindingContext

BindingContext=newWalksPageViewModel(DependencyService

.Get<IWalkNavService>());

...

...

3. Then,weneedtomodifyourwalksList.ItemTappedmethodwheneveranitemwithintheListViewhasbeenselected.Here,weneedtodisplayaselectionofchoicesfortheusertochoosefrom,usingtheDisplayActionSheetmethod.WhentheuserchoosestheProceedWithoption,theuserwillbenavigatedtotheWalksTrailpagewithinourViewModel,andpassintheitemthathasbeenselected.Alternatively,iftheuserchoosestheDeletebutton,acallismadetoourDeleteWalkItemcommandthatisincludedwithinourWalksPageViewModelclass,sothatitcanthenpermanentlydeletetheWalkEntryfromourTrackMyWalksAzuredatabase.Oncethewalkentryhasbeendeletedfromthedatabase,theuserwillreceiveapop-upnotificationtellingthemthattheitemhasbeendeleted.Proceedandenterinthefollowinghighlightedcodesections:

//InitializeoureventHandlertousewhenthe

//itemistapped

walksList.ItemTapped+=async(objectsender,

ItemTappedEventArgse)=>

{

//Gettheselecteditembytheuser

varitem=(WalkEntries)e.Item;

//Checktoseeifwehaveavalueforouritem

if(item==null)return;

//Displayanactionsheetwithchoices

varaction=awaitDisplayActionSheet("TrackMyWalks

-TrailDetails","Cancel","Delete",

"ProceedWith"+item.Title+"Trail");

if(action.Contains("Proceed"))

{

_viewModel.WalkTrailDetails.Execute(item);

}

//IfwehavechosenDelete,deletetheitemfrom

//ourdatabaseandrefreshtheListView

Page 308: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

elseif(action.Contains("Delete"))

{

_viewModel.DeleteWalkItem.Execute(item);

awaitDisplayAlert("TrackMyWalks-TrailDetails",

item.Title+

"hasbeendeletedfromthedatabase.","OK");

await_viewModel.Init();

}

//Initialiseouritemvariabletonull

item=null;

};

...

...

}

}

Intheprecedingcodesnippet,wemodifiedournewWalkItemvariable,whichiswithintheWalksPageclassconstructorandupdatedtheTextpropertyforourToolbarItem.

Next,wemodifiedourwalksList.ItemTappedmethodtohandlesituationswhenanitemhasbeenselectedfromtheListView,whichwilldisplayaselectionofchoicesfortheusertochoosefrom.WeaccomplishedthisbyusingtheDisplayActionSheetmethod.WhentheuserchoosestheDeletebutton,acallismadetoourDeleteWalkItemcommandthatisincludedwithinourWalksPageViewModelclass,sothatitcanthenpermanentlydeletethewalkentryfromourTrackMyWalksAzuredatabase,andusetheawaitkeywordtowaituntiltheTaskhascompletedbeforedisplayingapop-upnotificationtellingthemthattheitemhasbeendeleted.

Page 309: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingthecustompickerrendererclassfortheiOSplatformNowthatwehavemodifiedourWalkEntriesdatabasemodel,wewillneedtoupdatetheDifficultyPickerCellRendererclasswhichwillbeusedbyouriOSportionoftheDifficultyPickerEntryCellclass.

ThiscustompickerwillbeusedtoobtaintheitemchosenfromthecustomlistofentriesdefinedwithintheDifficultyPickerclassandstorethiswithintheDifficultypropertythatwillthenbewrittentoourTrackMyWalksMicrosoftAzuredatabase.

Let'slookathowwecanachievethiswiththefollowingsteps:

1. OpentheTrackMyWalks.iOSprojectlocatedwithinourTrackMyWalkssolution,andexpandtheRenderersfolder.

2. Next,selecttheDifficultyPickerCellRenderer.csfileandensurethatitisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesectionsinthecodesnippet:

//

//DifficultyPickerCellRenderer.cs

//TrackMyWalksCustomRendererforUIPickerViewEntryCells

(iOS)

//

//CreatedbyStevenF.Danielon01/10/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms.Platform.iOS;

usingUIKit;

usingTrackMyWalks.Controls;

usingXamarin.Forms;

usingTrackMyWalks.iOS.Renderers;

[assembly:ExportRenderer(typeof(

DifficultyPickerEntryCell),

typeof(DifficultyPickerCellRenderer))]

namespaceTrackMyWalks.iOS.Renderers

{

publicclassDifficultyPickerCellRenderer:

EntryCellRenderer

{

publicoverrideUITableViewCellGetCell(

Cellitem,UITableViewCellreusableCell,

UITableViewtv)

{

varcell=base.GetCell(item,reusableCell,tv);

varentryPickerCell=(EntryCell)item;

UITextFieldtextField=null;

if(cell!=null)

textField=

(UITextField)cell.ContentView.Subviews[0];

Page 310: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//CreateouriOSUIPickerViewNativeControl

vardifficultyPicker=newUIPickerView

{

AutoresizingMask=

UIViewAutoresizing.FlexibleWidth,

ShowSelectionIndicator=true,

Model=newDifficultyPickerModel(),

BackgroundColor=UIColor.White,

};

3. Next,weneedtomodifytheEntryCellRendererGetCellmethodsothatitcanupdatetheDifficultypropertyfortheEntryCellwearecurrentlyonwhentheDonebuttonhasbeenpressed.ItwillupdateitwiththevaluefromthedifficultyPickerobjectandthendismissthecustompickercontrol.Proceedandenterinthefollowinghighlightedcodesections:

//Createatoolbarwithadonebuttonthatwill

//settheselectedvaluewhenclosed.

vardone=newUIBarButtonItem("Done",

UIBarButtonItemStyle.Done,(s,e)=>

{

//UpdatetheDifficultypropertyontheCell

if(entryPickerCell!=null)

entryPickerCell.Text=DifficultyPickerModel.

difficulty[difficultyPicker.

SelectedRowInComponent(0)];

//UpdatethevalueoftheUITextFieldwithinthe

//Cell

if(textField!=null)

{

textField.Text=DifficultyPickerModel.difficulty

[difficultyPicker.SelectedRowInComponent(0)];

textField.ResignFirstResponder();

}

});

...

...

}

}

}

NowthatwehaveappliedthecodechangesrequiredtotheDifficultyPickerCellRendererclassforouriOSportionofourTrackMyWalksapp,thenextstepistomakechangestoourWalkEntryContentPagesothatitwillretrievethecorrectdifficultyvaluethatisreturnedfromourcustompicker,andtheDifficultypropertyvalue.

Page 311: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksEntryPagetousetheupdatedcustompickerIntheprevioussection,wemodifiedourDifficultyPickerCellRendererclass,aswellasdefiningthevariousmethodsthatwillhandlethedisplayoftheUIPickerViewcontrolwhenanEntryCellwithintheViewModelhasbeentapped.

Inthissection,we'lllookatmakingthenecessarycodechangesrequiredsothatourWalkEntryPageContentPagecorrectlyretrievesthelevelofdifficultychosenfromourcustomUIPickerViewDifficultyPickerCellRendererclass.

Let'slookathowwecanachievethiswiththefollowingsteps:

1. EnsurethattheWalkEntryPage.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesectionsasshowninthecodesnippet:

//

//WalkEntryPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Services;

usingTrackMyWalks.Controls;

namespaceTrackMyWalks

{

publicclassWalkEntryPage:ContentPage

{

WalkEntryViewModel_viewModel

{

get{returnBindingContextasWalkEntryViewModel;}

}

publicWalkEntryPage()

{

//SettheContentPageTitle

Title="NewWalkEntry";

//DeclareandinitialiseourModelBindingContext

BindingContext=newWalkEntryViewModel(

DependencyService.Get<IWalkNavService>());

//DefineourNewWalkEntryfields

varwalkTitle=newEntryCell

{

Label="Title:",

Placeholder="TrailTitle"

};

walkTitle.SetBinding(EntryCell.TextProperty,"Title",

BindingMode.TwoWay);

...

Page 312: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

...

2. Next,locateandmodifythewalkDifficultyEntryCellpropertysothatitcancorrectlyreturnthevalueoftheDifficultypropertyfromourWalkEntriesViewModel,thatisupdatedbyourDifficultyPickerEntryCellclass.Proceedandenterinthefollowinghighlightedcodesections:

varwalkDifficulty=newDifficultyPickerEntryCell

{

Label="DifficultyLevel:",

Placeholder="WalkDifficulty"

};

walkDifficulty.SetBinding(EntryCell.TextProperty,

"Difficulty",BindingMode.TwoWay);

...

...

}

}

}

Inthissection,welookedatthestepsinvolvedinmodifyingourWalkEntryPagesothatitcorrectlyreturnsthelevelofdifficultythathasbeenchosenfromourDifficultyPickerEntryCellclasscustomrenderer.WelookedatupdatingourwalkDifficultyobjectvariabletoreferencetheDifficultyPickerEntryCellclass,andupdatedthesetBindingtoreturnthevalueoftheDifficultypropertythatisimplementedwithintheWalkEntriesViewModelclass.

NowthatwehavefinishedbuildingallthenecessarycomponentsforourTrackMyWalksapplication,thenextstepistofinallybuildandruntheTrackMyWalksapplicationwithintheiOSsimulator.Whencompilationcompletes,theiOSSimulatorwillappearautomaticallyandtheTrackMyWalksapplicationwillbedisplayed,asshowninthefollowingscreenshot:

Page 313: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingscreenshot,thiscurrentlydisplaysourActivityIndicatorspinnercontrol,withtheassociatedLoadingTrailWalks...text,afterwhichthiswilldisplaytheListViewthatwillcontainourlistoftrailwalksfromourDataTemplatecontrol.Sincewedon'thaveanywalkentriescontainedwithinourMicrosoftAzureTrackMyWalksdatabase,theNewWalkEntryscreendisplaysentriesbeingentered:

Page 314: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Theprecedingscreenshot,showstheupdatedListViewcontroldisplayinginformationfromourTrackMyWalksMicrosoftAzuredatabase.Youwillnotice,thatuponselectingaWalkentryitemfromtheListViewcontrol,itwillpopupwithseveralchoicesforyoutochoosefrom.IfyouclickontheDeletebutton,itwillcalltheDeleteWalkEntryAsyncAPIandpassintheIdentifierfortheselecteditemthatistobepermanentlydeletedfromthedatabase.

Uponsuccessfuldeletion,youwillbepresentedwithadialogboxtellingyouthatthewalkentryhasbeendeleted.WhenclickingontheOKbutton,theListViewcontrolwillberefreshedanddisplayallentries,exceptfortheonethatyouhadjustdeleted.Alternatively,ifyouclickontheProceedWith...button,itwillnavigatetothewalksTrailDetailspagewhereyoucanbeginyourtrail,byclickingontheBeginthisTrailbutton.

Page 315: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,youlearnedaboutMicrosoftAzureAppservicesandhowyoucanusethisplatformtogetinformationfromaremotedatasourcebycreatingyourveryfirstAPIwithinthecloudtoconnectto,andstoreandretrieveinformationfrom,allwithintheTrackMyWalksapp.Youlearnedhowtocreatealive,cloud-basedbackendserviceandAPIusingtheMicrosoft'sAzureAppservicesplatformtostoreandretrieveWalkEntryinformation,aswellascreatingaDataServiceclassthatwillbeusedtohandleallthecommunicationbetweenthecloudandtheTrackMyWalksapp.

Inthenextchapter,you'lllearnhowtocreateasign-inpagethatwillallowtheusertosignintotheTrackMyWalksappusingtheirFacebookcredentials.You'lllearnhowyoucantakeadvantageoftheFacebookSDKandessentiallypostwalkdatatoyourFacebookprofilepagesoyoucanshowoffyourprogresstoyourfriendsand/orworkcolleagues.

Page 316: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter8.MakingOurAppSocial-UsingtheFacebookAPIInthepreviouschapter,youlearnedhowyoucanuseMicrosoftAzureAppservicestocreateyourveryfirstlive,cloud-based,backendHTTPwebservicetohandleallthecommunicationbetweenthecloudandourapp.Now,youwillalsolearnhowtocreateaDataServiceAPIthatwillallowourapptoconsumetheAPI,sothatwecanhavetheabilitytoretrieve,store,anddeletewalktrailinformationfromthecloud,allwithintheTrackMyWalksapp.

OnMay24th,2007,MarkZuckerbergannouncedtheFacebookplatform,adevelopmentplatformforprogrammerstocreatesocialapplicationswithinFacebook.WhenFacebooklaunchedthedevelopmentplatform,numerousapplicationshadbeenbuiltandalreadyhadmillionsofusersplayingthem.ThesocialnetworkingapplicationutilizestheFacebookcollectionofAPIsthatenablesdeveloperstoconnecttotheFacebookplatformandsendapplicationrequests.

Inthischapter,you'lllearnhowyoucanusebothXamarin.AuthandFacebookSDK,whichwillallowyoutoincorporatesocialnetworkingfeatureswithintheTrackMyWalksapptoobtaininformationaboutaFacebookuser,aswellaspostinformationtotheirFacebookwall.

You'lllearnhowtocreateasign-inpagethatwillallowtheusertosignintotheTrackMyWalksappusingtheirFacebookcredentials.YouwillalsocreateaFacebookApiUserclassthatwillbeusedtostoreinformationaboutthelogged-inuser,aswellasusingtheOpenGraphAPItoretrievecertaininformationabouttheuseranddisplaythiswithintheTrackMyWalksapp.Toendthischapter,youwillseehowyoucanleveragetheFacebooklibrary,essentiallytopostwalkdatatoyourFacebookprofilepage,soyoucanshowoffyourprogresstoyourfriendsand/orworkcolleagues.

Thischapterwillcoverthefollowingpoints:

SettingupourTrackMyWalksappwithintheFacebookDeveloperportalAddingtheXamarin.AuthandFacebookSDKpackagestothesolutionCreatingtheFacebookApiUserandFacebookCredentialsclassCreatingtheFBSignInPageandFBSignInPageRendererclassesUpdatingtheTrackMyWalksViewModelstousetheFacebookAPIUsingtheOpenGraphAPItoreadJSONdataRuntheTrackMyWalksappwithinthesimulator

Page 317: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SettingupandregisteringtheTrackMyWalksappwithFacebookInthissection,wewillbeginbysettingupourTrackMyWalksappandregisteringitwiththeFacebookplatform,sothatwecanbegincommunicatingandinteractingwithFacebook,andhavetheabilitytoretrieveuserinformation,aswellasallowingtheusertopostwalkinformationtotheirFacebookwall.

Let'snowstarttoimplementthecoderequiredforourFacebookApiUserclassmodel,byperformingthefollowingsteps:

1. Launchyourwebbrowserandtypeinhttps://developers.facebook.com/apps.2. Next,eithersignupforFacebookifyouarenotaregistereduser,orenteryourFacebook

accountcredentials.3. Then,clickontheCreateaNewAppbutton,whichwilldisplaytheCreateaNewAppID

screen,asshowninthefollowingscreenshot:

4. Next,enterTrackMyWalksfortheDisplayNamefieldandprovideyourContactEmailaddresssothatFacebookcancontactyouiftheyneedto.

5. Then,withintheCategorysection,selectacategoryfromtheChooseaCategorydropdown,andclickontheCreateAppIDbuttontocreateourTrackMyWalksapp,asshownintheprecedingscreenshot.

6. Next,youwillbepromptedtoentertheSecurityCheckanswerbeforeyoucanproceedtothenextstep:

Page 318: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

7. Then,enterthetextdisplayedonyourscreenandclickontheSubmitbuttontocontinue.

Note

Ifyouenterthetextincorrectly,youmayendupwithyouraccountbeingblocked.Ifthisisthecase,youwillneedtocontactFacebookdirectlytohavethisunblocked.

NowthatwehavecreatedourTrackMyWalksFacebookAppID,ournextstepistobeginsettinguptheClientOAuthSettings,whichwillbeusedbyourOAuth2AuthenticatorclasswithinourTrackMyWalksapp:

Page 319: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

8. Next,fromtheValidOAuthredirectURIssectionlocatedwithintheClientOAuthSettingscreen,enterhttps://www.facebook.com/connect/login_success.htmlastheURLtousewheneverwedetectthatwehavesuccessfullysignedintoFacebookfromwithinourapp.

9. Then,clickontheSaveChangesbuttontosaveourchangeswithinthisscreen.10. Next,choosetheAppReviewmenuitemlocatedundertheDashboard,ascanbeseeninthe

followingscreenshot:

Page 320: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

11. Then,ensurethatyouhavechosenYesfortheMakeTrackMyWalkspublic?question.

Note

Essentially,theAPPIDisanimportantfieldthatwewillusewithinouriOSandAndroidapplicationtocommunicatewithFacebook.

WheneveryouenabletheMakeTrackMyWalkspublic?option,thiswillmakeyourapplivetothepubliconFacebook,sothatyourfriendsandfamilycanseeyourwalkinformationpostedonyourFacebookwall.Youwillnoticethat,whenyouenablethisoption,thelistofApprovedItemswillbeenabledbydefault,aswellastheirloginpermissions.

Note

Ifyouareinterestedinlearningmoreaboutthevarioustypesofloginpermissions,pleaserefertothePermissionsReference-FacebookLoginwhichcanbeaccessedathttps://developers.facebook.com/docs/facebook-login/permissions.

NowthatwehavesuccessfullysetupourTrackMyWalksappnamewithintheFacebookplatform,wecanbeginmakingourappcommunicatewiththeFacebookAPIstoobtainuserinformation,aswellaspostingmessagestothecurrentlylogged-inuser'sFacebookwall.Inournextsection,we

Page 321: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

willbegintoaddtheXamarin.Auth.NETFrameworklibrary,aswellastheFacebookSDK,toconnectourTrackMyWalksapptoFacebookandauthenticateuserswithFacebook,sothatwecanpoststatusmessagesdirectlyfromwithinourappandmore.

Page 322: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheXamarin.AuthNuGetpackagetotheTrackMyWalksappNowthatwehavesetupourFacebookAppID,ournextstepistoaddtheXamarin.AuthNuGetpackagetoourTrackMyWalksPortableClassLibraryproject.TheXamarin.AuthpackagewillallowourapptoauthenticateauserwhorequiresaccesstousetheFacebookplatformbyusingOAuth2.0authentication.

TheseAuthenticatorsareresponsibleformanagingtheuserinterfaceandcommunicatingwithauthenticationservices.Authenticatorstakeavarietyofparameters;inthiscase,theapplication'sID,itsauthorizationscope,aswellasFacebook'svariousservicelocationsarerequired.

Let'slookathowtoaddtheXamarin.AuthNuGetpackagetoourTrackMyWalksPortableClassLibrarybyperformingthefollowingsteps:

1. Right-clickonthePackagesfolder,whichiscontainedwithintheTrackMyWalksPortableClassLibraryproject,andchoosetheAddPackages...menuoption,asshowninthefollowingscreenshot:

2. ThiswilldisplaytheAddPackagesdialog.EnterXamarin.AuthwithinthesearchdialogandselecttheXamarin.Authoptionwithinthelist,asshowninthefollowingscreenshot:

Page 323: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Finally,clickontheAddPackagebuttontoaddtheNuGetpackagetothePackagesfolder,whichiscontainedwithintheTrackMyWalksPortableClassLibraryproject.

NowthatwehaveaddedtheXamarin.AuthNuGetPackage,ournextstepistoaddtheFacebookFrameworktoourTrackMyWalksPortableClassLibrary,whichwewillbecoveringinthenextsection.

Page 324: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheFaceBookSDKlibrarytotheTrackMyWalksappIntheprevioussection,weaddedourXamarin.AuthNuGetpackagetoourTrackMyWalkssolution;thismeansthatournextstepistoaddtheFacebooklibrarytoourTrackMyWalkssolution.

Sinceweareusingboth.NETandC#tobuildourXamarin.Formsapplication,wecanleveragealibrarydevelopedbyacompanycalledTheOutercurveFoundation.ThislibraryisessentiallyaFacebookSDKthathelps.NETdevelopersbuildapplicationsthatintegratewithFacebook.

TheFacebookSDKframeworkcontainsallthemethodobjectsandAPIsthatarerequiredtoenableyoutointeractwithFacebookandsendnotificationrequests,orsimplypostmessagestothecurrentuser'swallpageusingthesinglesign-onfeatureofFacebookSDK.ThissimplyletsyouruserssignintoyourappusingtheirFacebookidentity,andwilldisplayaninlinedialogboxcomprisingaWebViewcontainerinwhichtheauthorizationUIwillbeshowntotheuser,whichrequiresthemtoentertheircredentialstogainaccesstoyourapp.

Let'slookathowwecanaddtheFacebookSDKlibrarytoourTrackMyWalksPortableClassLibrarybyperformingthefollowingsteps:

1. Launchyourwebbrowser,andtypethefollowingURL,https://components.xamarin.com/view/facebook-sdk,andlogintotheXamarinportalusingyourXamarincredentials.

2. Next,fromtheFacebookSDKsection,ensurethatyouhaveselectedversion6.2.2asthelatestversiontodownloadfromundertheVersionssection.

3. Then,proceedtoclickontheDownloadbuttontodownloadtheFacebookSDKlibrary,asshowninthefollowingscreenshot:

Page 325: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Note

OnceyouhavedownloadedtheFacebookSDK,extracttheZiparchivepackagecontents.Thedefaultdownloadlocationis~/Downloads/facebook-sdk-6.2.2.zip.

4. Next,right-clickontheReferencesfolder,whichiscontainedwithintheTrackMyWalksPortableClassLibraryproject,andchoosetheEditReferences...menuoption,asshowninthefollowingscreenshot:

Page 326: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Then,ensurethatthe.NetAssemblytabhasbeenselected,andclickontheBrowsebuttontochoosetheFacebook.dllforeithertheAndroidoriOSplatform:

Page 327: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Finally,ensurethatyouhaveselectedtheFacebook.dllassemblywithinthe.NetAssemblytab,clickontheOKbuttonaddthenewassemblytothereferencessectionofyourTrackMyWalksPortableClassLibrary,andclosetheEditReferencesdialog.

IncorporatingandusingtheFacebookSDKwithinyourapplicationsallowsyoutodowhatisdescribedinthefollowingtable:

FACEBOOKSDKTypes Description

Authenticationandauthorization

ThispromptsyouruserstosignintoFacebookandgrantpermissionstoyourapplication.

MakeAPIcalls

Thisallowsyoutofetchuser-profiledata,aswellasanyinformationthatrelatestotheuser'sfriends,usingtheJSONAPIcalls.

Displaydialog

ThisallowsyoutointeractwiththeuserviaaWebViewcontainerobject,whichisextremelyusefulforenablinginteractionswithFacebook,withouttheneedforrequiringupfrontpermissions.

NowthatwehaveaddedboththeXamarin.AuthNuGetpackageandFacebookDynamic-LinkLibrary(DLL)packagestooursolution,wecannowbeginutilizingtheseframeworklibrariesasweprogressthroughoutthischapter.

Page 328: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingaFacebookusermodelfortheTrackMyWalksappIntheprevioussection,weaddedbothofourXamarin.AuthandFacebookSDK.NETAssemblypackagestoourTrackMyWalksPortableClassLibrary.ThiswillessentiallybeusedbyeachofourViewModelsalongwiththeViews(pages).

Inthissection,wewillbeginbycreatingourFacebookApiUserdatamodel,whichwillbeusedtostoreourFacebooklogininformationfromwhenwecreateourbackendservicecalls,andthentheFacebookCredentials.csandFBSignInRenderer.csfileswillcommunicateandinteractwithourFacebookTrackMyWalksAppIDtoretrieveFacebookrelatedinformation,aswellasallowingtheusertopostwalkinformationtotheirFacebookwall.

Let'snowstarttoimplementthecoderequiredforourFacebookApiUserclassmodelbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheModelsfolderbychoosingAdd|NewFile....Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingtheTrackMyWalksModelwithinChapter1,CreatingtheTrackMyWalksNativeApp.

2. Then,enterFacebookApiUserforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethenewfile.

3. Next,ensurethattheFacebookApiUser.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//FacebookApiUser.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon07/11/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingXamarin.Auth;

usingNewtonsoft.Json.Linq;

namespaceTrackMyWalks.Facebook

{

4. Next,weneedtoimplementtheFacebookApiUserclassthatwillcontainthevariouspropertymethodsusedtostorethecurrentlylogged-inuser,theirFacebookId,andthepropertiesthatwillbeusedtostoreandretrievetheuser'sFacebookdetails.Toproceed,enterthefollowingcodesnippet:

publicclassFacebookApiUser

{

//Storethecurrentlyloggedinuser

publicstaticboolIsLoggedIn

{

Page 329: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

get{return!string.IsNullOrWhiteSpace

(FaceBookApiAuthToken.GetAuthToken);

}

}

//DefineourFacebookIdproperty

publicstaticstringFacebookId

{

get{return"<YOUR_FACEBOOK_ID>";}

}

//Retrieveouruserdetails

staticJObject_userDetails;

publicstaticJObjectGetUserDetails

{

get{return_userDetails;}

}

//Storeouruserdetails

publicstaticvoidSaveUserDetails(JObjectuserDetails)

{

_userDetails=userDetails;

}

}

5. Next,weneedtoimplementtheFacebookApiAuthTokenclassthatwillcontainthevariouspropertymethodsthatwillbeusedtostoreandretrieveourFacebookauthenticationTokenonsuccessfullyloggingintoourTrackMyWalksapp.ThesepropertieswillbeusedthroughoutourapplicationtoretrieveourFacebookuserdetails,andwhenwepostwalkinformationtoourFacebookwall.Toproceed,enterthefollowingcodesnippet:

//FacebookAPIauthenticationToken

publicclassFacebookApiAuthToken

{

//PropertytopointtotheApiuser

publicFacebookApiUserUser{get;set;}

//GetourFacebookauthenticationToken

staticstring_authToken;

publicstaticstringGetAuthToken

{

get{return_authToken;}

}

//StoreourauthenticationToken

publicstaticvoidStoreAuthToken(stringauthToken)

{

_authToken=authToken;

}

//GetourFacebookauthenticationAccountDetails

staticAuthenticatorCompletedEventArgs_authAccount;

publicstaticEventArgsGetAuthAccount

{

get{return_authAccount;}

}

//StoreourFacebookauthenticationAccountDetails

publicstaticvoidStoreAuthAccount

(AuthenticatorCompletedEventArgsauthAccount)

{

Page 330: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

_authAccount=authAccount;

}

}

}

Intheprecedingcodesnippet,webeginbyimplementingthevariouspropertymethodsthatwillberequiredtohandlecommunicationbetweenourTrackMyWalksappandFacebook,toallowourapptosuccessfullylogin.TheFacebookApiUserclassmethodisresponsibleforhandlingtheinformationrelatingtotheFacebookuserwhowillbeloggingin.ItcontainsapropertycalledIsLoggedInthatwillbeusedthroughoutourapptodetermineiftheuserhasloggedin;thisisdeterminedbycheckingtoseeifwehavereceivedavalidauthenticationtokenbackfromFacebook.

TheFacebookIdpropertyisessentiallytheuser'sFacebookId.YouwillneedtoreplacethiswithyourownFacebookIDsothatyoucanpostwalktrailinformationtoyourFacebookwall.TheGetUserDetailsandSaveUserDetailspropertiesareusedtostoretheuserinformationthatwillbedisplayedwithintheDistanceTravelledpage.TheFaceBookApiAuthTokenmethodcontainsthevariouspropertiesthatwillbeusedtohandlethestoringoftheusertokendetails,whenourappdeterminesthatwehavesuccessfullybeenauthenticatedwithFacebook.

Page 331: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingaFacebookCredentialsclassfortheTrackMyWalksappInourprevioussection,wecreatedourFacebookApiUserclassmodel,whichwillprovideuswithamechanismforstoringourFacebookcredentials,thatwecanusethroughoutourTrackMyWalksapp.

Inthissection,wewillbeginbycreatingaFacebookCredentialsclassthatwillallowustomakeAPIcalls,sothatwecanretrieveuserprofileinformationbackfromourAPI,inJSONformat,andstorethisinformationtobeusedlater.OurFacebookCredentialsclasscontainsamethodthatallowsourapptopostwalktrailinformationtotheuser'sFacebookpagewall.

Let'snowstarttoimplementthecoderequiredforourFacebookCredentialsclassbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheServicesfolder.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingtheNavigationServiceInterfacefortheTrackMyWalksappwithinChapter3,NavigatingwithintheMVVMModel-TheXamarin.FormsWay.

2. Next,entertheFacebookCredentialsforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethefile.

3. Then,ensurethattheFacebookCredentials.csfileisdisplayedwithinthecodeeditor,andenterthefollowingcodesnippet:

//

//FacebookCredentials.cs

//StoresthecredentialstobeusedforFacebook

//

//CreatedbyStevenF.Danielon09/11/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingTrackMyWalks.Models;

usingFacebook;

usingXamarin.Auth;

usingSystem;

usingSystem.Threading.Tasks;

usingNewtonsoft.Json.Linq;

usingSystem.Collections.Generic;

usingTrackMyWalks.Facebook;

namespaceTrackMyWalks

{

publicclassFacebookCredentials

{

4. Next,implementthePostWalkInformationinstancemethodthatwillbeusedtopostinformationrelatingtothecurrentlyactivewalktrailtotheuser'sFacebookpagewall.WedefineanfbvariablethatinstantiatesanewFacebookClientobjectusingtheauthorizationtokenGetAuthTokenfromourFacebookAuthTokenclass,whichweobtainedupon

Page 332: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

achievingasuccessfulloginfromFacebook.5. WeusethePostTaskAsyncmethodandpassintheGraphAPIme/feedsyntaxvalueasthe

firstparameter,followedbyamessageparameter,alongwiththemessagedetailsthatwewanttoposttotheuser'sFacebookwall.Toproceed,enterthefollowingcodesnippet:

//Postinformationtotheuser'sFacebookWall

publicstaticvoidPostWalkInformation(stringTitle,

doubleKilometers,stringDifficulty,

stringNotes,stringtrailPictureUrl)

{

FacebookClientfb=newFacebookClient(FacebookApiAuthToken.

GetAuthToken);

//Themessagetopostasakey/valuepair

stringpostMessage="TrackMyWalksApp-TrailCompleted-

Results.";

postMessage+="\n\nTitle:"+Title;

postMessage+="\nKilometers:"+Kilometers;

postMessage+="\nDifficulty:"+Difficulty;

postMessage+="\nNotes:"+Notes;

postMessage+="\nTrailImage:"+trailPictureUrl;

fb.PostTaskAsync("me/feed",new{message=postMessage}).

ContinueWith(t=>

{

if(t.IsFaulted)

{

//Catchanyerrorsthatoccurhere.

}

});

}

Note

TheGraphAPIistheprimarywayinwhichwecangetdatainandoutofFacebook'ssocialgraph,andisessentiallyalow-levelHTTP-basedAPIthatisusedtoquerydata,postnewstories,anduploadphotos.IfyouareinterestedinfindingourmoreinformationabouttheFacebookGraphAPIframeworkclasses,pleaserefertotheFacebookDeveloperdocumentationlocatedathttps://developers.facebook.com/docs/graph-api/using-graph-api/.

6. Then,implementtheGetProfileInformationinstancemethodthatwillbeusedtoretrieveinformationrelatingtothecurrentlyactiveFacebookuser.WedefinearequestobjectthatinitializesanewinstanceoftheOAuth2Requestclass,andacceptstheHTTPmethodtype,alongwiththeURL,andalistofparameters.ThefinalparameterisourobtainedFacebookaccountdetailsthatwillbeusedtoauthenticateourrequest.

7. WethenusetheGetResponseAsyncmethodtomakeanasynchronouswebrequestcalltoretrievetheinformation,asspecifiedbyourrequestobject,andthenusetheGetReponseTextmethodtoreturnaJSONobject,containingtheFacebookuserdetailsasspecifiedinourURLstring,andthenparsethisusingtheJObject.ParsemethodtoconvertthedetailstoaJSONobjectandassignthistoourobjvariable.

8. Next,wechecktoensurethatwehavetheinformationreturnedbyourwebrequest,andthen

Page 333: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

passtheJSONobjectdetails,asdefinedbyourobjvariable,toourSaveUserDetailsproperty,whichiscontainedwithinourFacebookApiUserclass.Toproceed,enterthefollowingcodesnippet:

//RetrieveFacebookinformationpertainingtotheuser.

publicstaticasyncTaskGetProfileInformation(AuthenticatorCompl

etedEventArgseventArgs)

{

//Makearequesttoretrieveouritemsbasedonthelistof

//parametersbelow.

varrequest=newOAuth2Request("GET",

newUri("https://graph.facebook.com/me?fields=id,name,

first_name,last_name,gender,picture,email,devices,education"),

null,eventArgs.Account);

varresponse=awaitrequest.GetResponseAsync();

varobj=JObject.Parse(response.GetResponseText());

//Checktoseeifwehavereturnedanyinformation

if(obj!=null)

{

try

{

//Storeouruserprofileinformationintoour

property.

FacebookApiUser.SaveUserDetails(obj);

}

catch(Exceptione)

{

//Handleanyerrorsthatfallinhere.

}

}

}

}

}

Intheprecedingcodesnippet,webeginbyimplementingthemethodsthatarerequiredtopostandretrieveourFacebookinformationusingtheFacebookClientclassthatisusedtomakesynchronousrequeststotheFacebookserver.ThePostWalkInformationinstancemethodisusedtopostinformationrelatingtothecurrentlyactiveusertotheuser'sFacebookpagewall.

TheGetProfileInformationinstancemethodisusedtoretrieveinformationassociatedwiththecurrentlylogged-inFacebookuser,usingtheOAuth2RequestclassandtheFacebookGraphAPI,whichacceptsaURL,containingalistofparametersthatwewouldlikeourmethodtoreturnandthatwillbestoredwithinourSaveUserDetailsproperty,whichisdefinedwithinourFacebookApiUserclass.

Note

IfyouareinterestedinfindingoutmoreinformationabouttheOAuth2RequestandtheXamarin.Authclasses,pleaserefertotheXamarindeveloperdocumentationlocatedat

Page 334: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

https://components.xamarin.com/gettingstarted/xamarin.auth.

Page 335: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheFacebookSignIntousewithinourTrackMyWalksappInourprevioussection,wecreatedandimplementedourFacebookCredentialswrapperclassthatwillbeusedbyourTrackMyWalksapplicationtohandletheretrievingofourFacebookuserdetails,aswellasprovidingtheabilitytopostwalktrailinformationdirectlytoourFacebookwallsothatourfriendsandfamilycantrackourprogress.

OurnextstepistobegincreatingaFacebookSignInpagethatwillbehookeduptoacustomrendererpagethatwillbeusedtodisplaytheFacebookloginpagewithinawebcontainer.

Let'snowstarttoimplementthecoderequiredforourFBSignInPageContentPagebyperformingthefollowingsteps:

1. CreateanemptyFormsContentPagewithinthePagesfolder.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingthewalksmainpagewithinChapter1,CreatingtheTrackMyWalksNativeApp.

2. Next,enterFBSignInPageforthenameofthenewContentPagethatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethefile.

3. Then,ensurethattheFBSignInPage.csfileisdisplayedwithinthecodeeditorandenterthefollowingcodesnippet:

//

//FBSignInPage.cs

//TrackMyWalksFacebookSignInPage

//

//CreatedbyStevenF.Danielon09/11/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassFBSignInPage:ContentPage

{

}

}

Intheprecedingcodesnippet,ourContentPagecontainsthebare-bonesimplementation.Thisisintentional,as,inournextsection,wewillbecreatingacustomclassrendererthatwilluseourFBSignInPageContentPagetoinstantiateaninstanceoftheFacebookloginwebpage.

Page 336: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheFacebookSignInClassforTrackMyWalks(iOS)appInourprevioussection,wecreatedourFBSignInPagecontentpagethatwillbeusedasaplaceholderforourFacebookSignInclasscustomrenderer.Inthissection,wewillbuildthecustomFacebooksign-inpagerenderer,whichwillbeusedbytheiOSandAndroidportionsofourapptohandlethesigningintoFacebookviatheFacebookApiAuthTokenmodel,tostorethereceivedFacebooktokenthatwillbeusedthroughouttheTrackMyWalksapplication.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheRenderersfolderforourTrackMyWalks.iOSproject.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingthecustompickerrendererclassfortheiOSplatformwithinChapter5,CustomizingtheUserInterface.

2. Next,enterFBSignInPageRendererforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethefile.

3. Then,ensurethattheFBSignInPageRenderer.csfileisdisplayedwithinthecodeeditorandenterthefollowingcodesnippet:

//

//FBSignInPageRenderer.cs

//TrackMyWalksFacebookSignInPage(iOS)

//

//CreatedbyStevenF.Danielon09/11/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingXamarin.Forms;

usingTrackMyWalks;

usingXamarin.Forms.Platform.iOS;

usingXamarin.Auth;

usingTrackMyWalks.Facebook;

4. Next,weneedtoinitializeourFBSignInPageRendererclassbeingmarkedasanExportRendererbyincludingtheExportRendererassemblyattributetothetopofourclassdefinition.ThisletsourclassknowthatitinheritsfromtheViewRendererclass.

[assembly:ExportRenderer(typeof(FBSignInPage),

typeof(TrackMyWalks.iOS.FBSignInPageRenderer))]

namespaceTrackMyWalks.iOS

{

publicclassFBSignInPageRenderer:PageRenderer

{

Then,wedeclareanIsVerifiedBooleanvariablethatwillbeusedtodetermineifasuccessfultoFacebookhashappened.Next,weimplementtheViewDidAppearmethodthatwillbelaunchedupontheContentPagebecomingvisible,andthencalltheFacebookSignIninstancemethod:

Page 337: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

boolIsVerified=false;

publicoverridevoidViewDidAppear(boolanimated)

{

base.ViewDidAppear(animated);

if(!IsVerified)

{

FacebookSignIn();

}

}

5. Next,weneedtocreatetheFacebookSignIninstancemethodthatwillbecalledwhenevertheuserhasn'tsignedintoFacebook.WeusetheOAuth2Authenticatormethod,whichwillberesponsibleformanagingtheuserinterfaceandhandlingthecommunicationwiththeFacebookauthenticationservices.

6. TheOAuth2Authenticatorclassacceptstheuser'sFacebookID,whichisstoredwithintheFacebookIdpropertythatisdeclaredwithintheFacebookApiUserclass.TheOAuth2AuthenticatorclassalsoacceptstheauthorizationscopeandtheFacebookservicelocationstoauthenticateanddeterminewhattodowhenasuccessfulloginhappens:

voidFacebookSignIn()

{

stringAccessToken=String.Empty;

varauth=new

OAuth2Authenticator(FaceBookApiUser.FacebookId,

"publish_actions",

newUri("https://m.facebook.com/dialog/oauth/"),

new

Uri("https://www.facebook.com/connect/login_success.html")

);

//Preventourformfrombeingdismissedbytheuser.

auth.AllowCancel=false;

7. Then,beforewepresenttheFacebookUItotheuser,weneedtostartlisteningtotheCompletedeventoftheOAuth2Authenticatorinstance,whichfiresupwhenevertheusersuccessfullyauthenticatesorcancels,andthenchecktheIsAuthenticatedpropertyoftheeventArgspropertytoproperlydetermineiftheauthenticationhassucceeded.

8. Ifwehavedeterminedthatasuccessfulloginhashappened,wemakeacalltotheDismissViewControllermethodtodismissthecurrentlypresentedFacebookUIandthencalltheRemoveFBSignInPageinstancemethodfromourTrackMyWalksappclass,withinPortableClassLibrary,toremoveourFBSignInPagefrommemory:

auth.Completed+=async(sender,eventArgs)=>

{

if(eventArgs.IsAuthenticated)

{

//DismissourFacebookAuthenticationUIDialog

DismissViewController(true,null);

//RemoveourFacebookSignInPageViewfrommemory.

Page 338: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

App.RemoveFBSignInPage();

9. Next,weproceedtoretrievetheaccesstokenfromtheFacebooksessionofthesuccessfullylogged-inuser,andproceedtostorethevalueswithintheStoreAuthTokenandStoreAuthAccountdetailswithinourFacebookApiAuthTokenclass.Finally,wecallourNavigateToWalksPageActionwithinourTrackMyWalksAppclass:

//RetrieveouraccesstokenforourFacebooksession.

eventArgs.Account.Properties.TryGetValue("access_token",

outAccessToken);

FacebookApiAuthToken.StoreAuthToken(AccessToken);

FacebookApiAuthToken.StoreAuthAccount(eventArgs);

//NavigateToWalksListmethodfromourmainclass.

awaitApp.NavigateToWalksPage();

}

else

{

//TheusercancelledtheFacebookLoginUI

Console.WriteLine("Youarenotauthorisedtouse

theTrackMyWalksapp");

IsVerified=false;

return;

}

};

10. Then,wepresenttheFacebookloginUIbyusingthePresentViewControllermethod,andcalltheGetUImethodreturnsUINavigationControllersoniOSandintentsonAndroid.OnAndroid,wewouldwritethefollowingcodetopresenttheUIfromtheOnCreatemethod:

IsVerified=true;

PresentViewController(auth.GetUI(),true,null);

}

}

}

Intheprecedingcodesnippet,webeginbyinitializingourFBSignInPageRendererclass,beingmarkedasanExportRenderer,toletourclassknowthatitinheritsfromtheViewRendererclass,andthendeclareanIsVerifiedBooleanvariablethatwillbeusedtodetermineifasuccessfullogintoFacebookhashappened.WethenproceedandimplementtheViewDidAppearmethod,whichwillbelaunchedwhentheContentPagebecomesvisible,andthencalltheFacebookSignIninstancemethod,whichwillbecalledwhenevertheuserhasn'tsignedintoFacebook,andusetheOAuth2Authenticatormethod,whichwillberesponsibleformanagingtheuserinterfaceandhandlingthecommunicationwiththeFacebookauthenticationservices.

Finally,wepresenttheFacebookloginUI,retrievetheaccesstokenfromtheFacebooksessionofthesuccessfullylogged-inuser,andproceedtostorethevalueswithintheStoreAuthTokenandStoreAuthAccountdetailswithinourFacebookApiAuthTokenclass:

Note

Page 339: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TheAndroidversionoftheFBSignInPageRendererclassisavailableinthecompanionsourcecodeforthisbook,whichcanbelocatedwithintheTrackMyWalks.Droidproject.

Page 340: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheNavigationServiceInterfacefortheTrackMyWalksappInthissection,wewillproceedtoupdateourIWalkNavServiceInterfacetocontainanewmethodofimplementationthatwillallowourapptoclearallpreviouslycreatedviewsfromtheNavigationStack.SincethisabstractInterfaceclasswillactasthebaseNavigationServiceclassthateachofourViewModelswillinheritfrom,theywillbeabletoaccesseachoftheclassmemberscontainedwithinthisInterface.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

EnsurethattheIWalkNavService.csfileisdisplayedwithinthecodeeditorandenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

//

//IWalkNavService.cs

//TrackMyWalksNavigationServiceInterface

//

//CreatedbyStevenF.Danielon03/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem.Threading.Tasks;

usingTrackMyWalks.ViewModels;

namespaceTrackMyWalks.Services

{

publicinterfaceIWalkNavService

{

//NavigatebacktothePreviouspage

intheNavigationStack

TaskPreviousPage();

//Navigatetothefirstpagewithin

theNavigationStack

TaskBackToMainPage();

//NavigatetoaparticularViewModel

withinourMVVMModel,

//andpassaparameter

TaskNavigateToViewModel<ViewModel,

WalkParam>(WalkParamparameter)

whereViewModel:WalkBaseViewModel;

//Clearallpreviouslycreatedviews

fromtheNavigationStack

voidClearAllViewsFromStack();

}

}

Intheprecedingcodesnippet,weimplementanewclassmemberClearAllViewsFromStack

Page 341: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

methodthatwillbeusedtoclearallpreviouslycreatedviewsfromtheNavigationStack.Thisisbecause,uponsuccessfullyloggingintoourTrackMyWalksappaftertheFacebookUIloginhasbeendismissed,weneedtohavetheabilitytoremovetheFBSignInPagefromtheNavigationStack.

Page 342: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheNavigationServiceclassfortheTrackMyWalksappIntheprevioussection,weupdatedthebaseInterfaceclassforourNavigationService,aswellasdefininganewclassmemberthatwillbeusedtohandletheremovingofallpreviouslycreatedviewsfromourNavigationStackwithinourMVVMViewModel.

ThesewillbeusedbyeachofourViewModels,andtheViews(pages)willimplementthoseViewModelsandusethemastheirBindingContext.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

1. EnsurethattheWalkNavService.csfileisdisplayedwithinthecodeeditor,andenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

//

//WalkNavService.cs

//TrackMyWalksNavigationServiceClass

//

//CreatedbyStevenF.Danielon03/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingXamarin.Forms;

usingSystem.Collections.Generic;

usingSystem.Threading.Tasks;

usingSystem.Reflection;

usingSystem.Linq;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

[assembly:Dependency(typeof(WalkNavService))]

namespaceTrackMyWalks.Services

{

publicclassWalkNavService:IWalkNavService

{

publicINavigationnavigation{get;set;}

readonlyIDictionary<Type,Type>

_viewMapping=new

Dictionary<Type,Type>();

//RegisterourViewModelandViewwithinourDictionary

publicvoidRegisterViewMapping(

TypeviewModel,Typeview)

{

_viewMapping.Add(viewModel,view);

}

//Instancemethodthatallowsustomovebackto

thepreviouspage

publicasyncTaskPreviousPage()

{

//Checktoseeifwecanmovebacktothepreviouspage

Page 343: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

if(navigation.NavigationStack!=null&&

navigation.NavigationStack.Count>0)

{

awaitnavigation.PopAsync(true);

}

}

//Instancemethodthattakesusbacktothe

mainRootWalksPage

publicasyncTaskBackToMainPage()

{

awaitnavigation.PopToRootAsync(true);

}

//InstancemethodthatnavigatestoaspecificViewModel

//withinourdictionaryviewMapping.

publicasyncTaskNavigateToViewModel

<ViewModel,WalkParam>(WalkParamparameter)

whereViewModel:WalkBaseViewModel

{

TypeviewType;

if(_viewMapping.TryGetValue(typeof(ViewModel),

outviewType))

{

varconstructor=viewType.GetTypeInfo()

.DeclaredConstructors

.FirstOrDefault(dc=>dc.GetParameters()

.Count()<=0);

varview=constructor.Invoke(null)asPage;

awaitnavigation.PushAsync(view,true);

}

if(navigation.NavigationStack.Last().BindingContextis

WalkBaseViewModel<WalkParam>)

await((WalkBaseViewModel<WalkParam>)

(navigation.Navigation

Stack.Last().BindingContext)).Init(parameter);

}

2. Next,weneedtocreatetheClearAllViewsFromStackinstancemethodforourWalkNavServiceclass,whichwillbeusedtoremoveallpreviouslycreatedviewsfromtheNavigationStackbyfirstcheckingtheNavigationStackpropertyforthenavigationpropertyINavigationinterfacetoseeifanyitemsalreadyhavebeenpushedontotheNavigationStack.Thisistoensurethatacrashdoesn'thappenwithinourapp.

3. Inournextstep,weproceedtoiteratethrougheachitemthatiscontainedinourNavigationStackandcalltheRemovePage,methodtoremoveeachpage:

//Instancemethodtoremoveallpreviouslycreatedviewsfrom

//theNavigationStack.

publicvoidClearAllViewsFromStack()

Page 344: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

//Checktoseeifanyitemshavealreadybeenpushed

//ontotheNavigationStack.

if(navigation.NavigationStack.Count<=1)

return;

for(vari=0;i<navigation.NavigationStack.Count-1;

i++)

navigation.RemovePage(navigation.NavigationStack[i]);

}

}

}

Intheprecedingcodesnippet,weimplementanewclassmemberClearAllViewsFromStackinstancemethodwithinourWalkNavServiceclass,tohandletheclearingofallpreviouslycreatedViews(pages)fromtheNavigationStack.

Page 345: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksPagetoproperlyhandleFacebookSignInInthissection,weneedtoupdateourWalksPageContentPagesothatitcanreferencetheupdateswithinourWalksPageViewModel.WewillneedtoapplyadditionallogictoupdatetheNavigationBarTitleoncewehavedismissedourFacebookSignIndialog.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

EnsurethattheWalksPage.csfileisdisplayedwithinthecodeeditor,andenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

//

//WalksPage.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingXamarin.Forms;

usingTrackMyWalks.Models;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

usingTrackMyWalks.DataTemplates;

usingTrackMyWalks.ValueConverters;

namespaceTrackMyWalks

{

publicclassWalksPage:ContentPage

{

WalksPageViewModel_viewModel

{

get{returnBindingContext

asWalksPageViewModel;}

}

publicWalksPage()

{

varnewWalkItem=newToolbarItem

{

Text="Add"

};

if(Device.OS==TargetPlatform.iOS)

{

Title="TrackMyWalks-iOS";

}

elseif(Device.OS==TargetPlatform.Android)

Page 346: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

{

Title="TrackMyWalks-Android";

}

...

...

...

...

Intheprecedingcodesnippet,webeginbycheckingtheDevice.OSclass,todeterminewhatOSXamarin.Formsisrunningon,andthenusetheTargetPlatformclasstodetermineifourappisrunningontheAndroidoriOSplatform.IfwehavedeterminedthatourappisrunningonAndroid,wesettheTitlepropertyforourContentPage;alternatively,ifwearerunningoniOS,wesettheTitlepropertyaswell.

Page 347: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheWalksPageViewModeltouseourFaceBookApiUserInthissection,wewillproceedtoupdateourWalksPageViewModelViewModel,sothatithastheabilitytodisplayourFacebookSignInpageifitdeterminesthatwehaven'talreadyloggedin.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

EnsurethattheWalksPageViewModel.csfileisdisplayedwithinthecodeeditor,andenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

//

//WalksPageViewModel.cs

//TrackMyWalksViewModels

//

//CreatedbyStevenF.Danielon22/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Collections.ObjectModel;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Models;

usingTrackMyWalks.Services;

usingXamarin.Forms;

usingTrackMyWalks.Facebook;

namespaceTrackMyWalks.ViewModels

{

publicclassWalksPageViewModel:

WalkBaseViewModel

{

ObservableCollection<WalkEntries>

_walkEntries;

publicObservableCollection<WalkEntries>

walkEntries

{

get{return_walkEntries;}

set

{

_walkEntries=value;

OnPropertyChanged();

}

}

publicWalksPageViewModel

(IWalkNavServicenavService):

base(navService)

{

walkEntries=newObservableCollection

<WalkEntries>();

}

Page 348: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

publicoverrideasyncTaskInit()

{

//Checkifwehaveloggedinandthatwearerunningour

//deviceoniOS

if(!FacebookApiUser.IsLoggedIn&&

Device.OS==TargetPlatform.iOS)

{

awaitApp.Current.MainPage.Navigation

.PushModalAsync(new

FBSignInPage());

}

else{

awaitLoadWalkDetails();

awaitNavService.ClearAllViewsFromStack();

}

}

...

...

...

...

Intheprecedingcodesnippet,webeginbymodifyingtheInitmethodtoincludeachecktoseeifwehavealreadyloggedintoFacebook,bycheckingtheIsLoggedInpropertyoftheFacebookApiUserclass,andwhetherwearerunningonadevicerunningiOS.IfwedeterminethattheIsLoggedInpropertydoesn'tcontainavalue,wecallthePushModalAsyncmethodontheNavigationpropertyfromtheMainPagetodisplayourFBSignInPageContentPage.Alternatively,iftheuserhasloggedin,weproceedtoloadourwalkentrydetailsusingtheLoadWalkDetailsinstancemethod,andcalltheClearAllViewsFromStackinstancemethodthatislocatedwithinourWalkNavServiceclass.

Page 349: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheDistanceTravelledPagefortheTrackMyWalksappInthissection,weneedtoupdateourDistanceTravelledPageContentPage,sothatitcanmakeuseofourFacebookAPIandretrievethecurrentlylogged-inFacebookuser,aswellasprovidingtheabilitytopostWalkTrailinformationtotheuser'sFacebookwall.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

1. EnsurethattheDistanceTravelledPage.csfileisdisplayedwithinthecodeeditor,andenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

varpostToFacebook=newButton

{

BackgroundColor=Color.FromHex("#455c9f"),

TextColor=Color.White,

Text="PosttoFacebook"

};

postToFacebook.Effects.Add(Effect.Resolve(

"com.geniesoftstudi

os.ButtonShadowEffect"));

2. Next,wecreateaClickedhandlermethodforourpostToFacebookbutton,sothatwheneverthePosttoFacebookispressedwedisplayaselectionofchoicesfortheusertochoosefrom,usingtheDisplayActionSheetmethod:

//Setupoureventhandler

postToFacebook.Clicked+=async(sender,e)=>

{

if(_viewModel.WalkEntry==null)return;

//Displayourlistofchoicestochoosefrom

varaction=awaitDisplayActionSheet(

"TrackMyWalks-TrailDetails",

"Cancel",

"DisplayUserDetails",

"PosttoFacebookWall");

3. Then,weusetheContainspropertyoftheactionvariabletodetermineifthePostoptionhasbeenselected,and,ifso,wecallthePostWalkInformationinstancemethodofourFacebookCredentialsclass;passintheTitle,Kilometers,Difficulty,Notes,andImageUrlasparameterstotheclass;andthendisplayanalertdialogboxtellingtheuserthattheirwalkinformationhasbeenpostedtotheirFacebookwall:

if(action.Contains("Post"))

{

//DeclareaninstancetoourFacebookCredentialsClass

FacebookCredentials.PostWalkInformation(

_viewModel.WalkEntry.Title,

_viewModel.WalkEntry.Kilometers,

_viewModel.WalkEntry.Difficulty,

_viewModel.WalkEntry.Notes,

_viewModel.WalkEntry.ImageUrl.AbsoluteUri);

//Displayanalertdialoglettingtheuserknowthat

//theirinformationhasbeenpostedtotheirFacebook

Page 350: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//Wall.

awaitDisplayAlert("PosttoFacebook","Trail

informationhasbeenpostedtoyourwall!","OK");

}

4. Next,weusetheContainspropertyoftheactionvariabletodetermineiftheUserDetailsoptionhasbeenselected,and,ifso,wecalltheGetProfileInformationinstancemethodofourFacebookCredentialsclass,andpassintheGetAuthAccountpropertyfromourFacebookApiAuthTokenclasstoretrieveourcurrentlylogged-inFacebookuser'sdetailsandassignthevaluetoourobjUserDetailsvariable.WethenproceedtoconstructouruserDetailsstringwiththeinformationextractedfromtheobjUserDetailsdictionary,anddisplaytheinformationwithinanalertdialogbox:

elseif(action.Contains("UserDetails"))

{

//DeclareaninstancetoourFacebookCredentialsClass

awaitFacebookCredentials.GetProfileInformation((Xamarin

.Auth.AuthenticatorCompletedEventArgs)

FacebookApiAuthToken.GetAuthAccount);

//ConstructourFacebookUserdetailsbasedon

//informationstoredwithineachoftheproperties

varobjUserDetails=FacebookApiUser.GetUserDetails;

varuserDetails=objUserDetails.GetValue("id").ToString();

userDetails

+="\n"+objUserDetails.GetValue("name").ToString();

userDetails+="\n"+objUserDetails.GetValue("first_name")

.

ToString();

userDetails+="\n"+objUserDetails.GetValue("last_name")

.ToString();

userDetails+="\n"+objUserDetails.GetValue("gender")

.ToString();

userDetails+="\n"+objUserDetails.GetValue("devices")

.ToString();

//DisplayanAlertDialogthatwilldisplay

//informationfromouruserproperties

Page 351: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

awaitDisplayAlert("FacebookUserDetails",

userDetails,"OK");

}

};

Intheprecedingcodesnippet,wecreateourpostToFacebookbuttonandbeginapplyingtheButtonShadowEffectclasstoourcontrol,sothatitcantakeadvantageoftheniceplatform-specificrenderingeffectsforvisualcontrolelements.

Next,wemodifytheClickedmethodtohandleeachpressofthebutton,sothatwecandisplayaselectionofoptionsfortheusertochoosefrom.WeaccomplishthisbyusingtheDisplayActionSheetmethod.WhentheuserchoosesthePostbutton,acallismadetoourFacebookCredentialsclassandthePostWalkInformationmethodtosubmitthecurrentwalkinformationtotheuser'sFacebookpage.Alternatively,iftheuserchoosestheUserDetailsoption,wemakeacalltoourFacebookCredentialsclass,butthistimewecalltheGetProfileInformationmethodtoreturnaJSONdictionarythatcontainsthecurrentlylogged-inFacebookuser'sdetails,whichweassigntoanobjectvariablecalledobjUserDetails.

Finally,wecreateauserDetailsvariablethatweconstructbyextractingeachofthevaluesforname,last_name,first_name,etc.anddisplaythisinformationwithinanalertdialogboxusingtheDisplayAlertmethod.

Page 352: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheXamarin.FormsAppclasstohandleFacebookSignInInthissection,weneedtoupdateourXamarin.Forms.AppclassbymodifyingtheconstructorinthemainAppclasstoincludeadditionalpropertyandactionmethodsthatwillhelpwithnavigatingtoourWalksPageContentPageafterourTrackMyWalksapphassuccessfullysignedintoFacebook.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

1. OpentheTrackMyWalks.csfile,locatedwithintheTrackMyWalksPortableClassLibraryprojectsolution.

2. Next,ensurethattheTrackMyWalks.csfileisdisplayedwithinthecodeeditor,locatetheAppmethod,andenterthehighlightedcodesectionsshowninthefollowingcodesnippet:

//

//TrackMyWalks.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingSystem;

usingSystem.Threading.Tasks;

usingTrackMyWalks.Services;

usingTrackMyWalks.ViewModels;

usingXamarin.Forms;

namespaceTrackMyWalks

{

publicclassApp:Application

{

publicApp()

{

//ChecktheDeviceTargetOSPlatform

if(Device.OS==TargetPlatform.Android)

{

//Settherootpageofyourapplication

MainPage=newSplashPage();

}

elseif(Device.OS==TargetPlatform.iOS)

{

//SetourWalksPagetobetherootpageofour

//application.

varmainPage=newNavigationPage(newWalksPage()

{

Title="TrackMyWalks-iOS",

});

...

...

...

...

}

Page 353: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

3. Next,createtheRemoveFBSignInPageactionpropertymethod,whichwillbeusedtohandletheremovaloftheFBSignInPageoncewehavesuccessfullysignedintoFacebook,asdeterminedbytheFBSignInPageRendererclass.WethencallthePopModalAsyncpropertyoftheNavigationpropertyontheMainPagetopopthelastpageofftheNavigationStack:

//PropertymethodinstancetoremoveourFBSignInPage

publicstaticActionRemoveFBSignInPage

{

get

{

returnnewAction(()=>App.Current.

MainPage.Navigation.

PopModalAsync());

}

}

4. Then,createtheNavigateToWalksPageinstancemethod;thiswillbeusedtohandlenavigatingtotheWalksPageViewModelwithintheNavigationStackbycallingthePushAsyncpropertyontheNavigationpropertyontheMainPage:

//HandlenavigatingtoourWalksPagewhen

wehavesuccessfully

//signedintoFacebook.

publicasyncstaticTaskNavigateToWalksPage()

{

awaitApp.Current.MainPage.Navigation.PushAsync

(newWalksPage());

}

}

Intheprecedingcodesnippet,webeginbyimplementingthemethodsthatwillberequiredtoremoveaninstanceofFBSignInPage,asdeterminedbytheRemoveFBSignInPagepropertyActionmethodthatwillbeusedtohandleremovaloftheFBSignInPageoncewehavesuccessfullysignedintoFacebook,asdeterminedbytheFBSignInPageRendererclass.WethencallthePopModalAsyncpropertyoftheNavigationpropertyontheMainPagetopopthelastpageofftheNavigationStack.

TheNavigateToWalksPageinstancemethodwillbeusedtohandlethenavigationtoourWalksPageViewModeluponsuccessfullybeingloggedintoFacebookviatheTrackMyWalksapp;thisisdonebyusingthePushAsyncpropertyontheNavigationproperty.

Page 354: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

EnablingFacebookfunctionalitywithintheTrackMyWalksappWhenworkingwiththeFacebookSDKandtheXamarin.Authframework,weneedtomakesomeadditionalchangestoouriOSprojectsolutionpropertylisttoenableSSO(SingleSign-On)supportwhentheapplicationruns.

Let'slookathowwecanachievethisbyperformingthefollowingsteps:

1. Double-clickontheInfo.plistfilethatiscontainedwithintheTrackMyWalks.iOSproject,andensurethattheAdvancedtabisshowing.

2. Next,scrolldowntothebottomofthepage,andexpandtheURLTypessection.3. Then,withintheIdentifierfield,provideyourFacebookIdwhilstprefixingitwithfbasthe

firsttwocharactersthatisfb1234567890:

Note

TheURLtypessectionisasinglearraysub-itemthatneedsyourFacebookAppIDtobeprefixedwithfb.Thisisusedtoensuretheapplicationwillreceivethecall-backmethodsoftheURLandtheweb-basedOAuthflow.

NowthatwehavemodifiedourTrackMyWalks.iOSprojecttoallowourapptoreceivethecall-backmethodsoftheURLandtheweb-basedOAuthflow,weneedtodoonemorething,andset

Page 355: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

upourFacebookAppIDandapplicationnamethatweconfiguredwithintheappdashboard:

1. EnsurethattheInfo.plistfileisdisplayedwithintheXamarinIDE,andthattheSourcetabisshowing.

2. Next,createtheFacebookAppIDandFacebookDisplayNamekeysbyclickingwithintheAddnewentrysectionoftheInfo.plist.

3. Then,enteryourFacebookAppIDasthestringdescriptionfortheValuefield,asshowninthefollowingscreenshot.Youwillnoticeherethatwedon'tneedtoprovidethefbprefixaswedidforourURLtypessection.

4. Next,enterTrackMyWalksasthestringdescriptionfortheValuefield,asshowninthefollowingscreenshot:

5. Then,createtheLSApplicationQueriesScenesarraykeys,andaddthestringdescriptionfieldsandtheirvalues,usingfbapi,fbauth2,andfbshareextensionastheValuefields,asshownintheprecedingscreenshot.

AppleintroducedtheAppTransportSecurityprotocolwithiOS9toenforcesecureconnectionsbetweenInternetconnections,aswellaswithanyappthatcommunicatesusingtheHTTPSprotocol.ItrequiresthatinformationisencryptedusingtheTLSversion1.2.WeneedtodisableandoptoutofATSentirelybyconfiguringourlocalInfo.plistfilewithintheTrackMyWalks.iOSprojectsolution,sothatitcancommunicateoverHTTPSwithoutanyissues.

Page 356: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Next,withtheInfo.plistfilestillopenwithintheXamarinIDEenvironment,createtheNSAppTransportSecuritydictionaryarray.

7. Next,addtheNSAllowArbitraryLoadsBooleanvalue,settingittoYes,asshownintheprecedingscreenshot.

Note

IfyouareinterestedinfindingoutmoreinformationontheAppTransportSecurityandNSAppTransportSecurityclass,refertotheXamarindeveloperdocumentationlocatedathttps://developer.xamarin.com/guides/ios/platform_features/introduction_to_ios9/ats/.

NowthatwehavefinishedbuildingallthecomponentsforourTrackMyWalksapplicationnecessarytoenableintegrationwithFacebook,wecanbuildandruntheTrackMyWalksapplicationwithintheiOSsimulator.Whencompilationcompletes,theiOSSimulatorwillappearautomaticallyandtheTrackMyWalksapplicationwillbedisplayed,asshowninthefollowingscreenshot:

Asyoucanseefromtheprecedingscreenshot,thiscurrentlydisplaysourFacebookSignInpage,whichtellstheusertoLogintoyourFacebookaccounttoconnecttoTrackMyWalksapplication.Toproceed,provideyourEmailaddressorphonenumberandyourFacebookpassword,andclickontheLogInbutton.

Page 357: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UponsuccessfullydeterminingthatyourdetailshavebeenvalidatedbyFacebook,youwillbepresentedwithaPosttoFacebookauthenticationscreen,askingyouwhoyouwouldliketoshareyourpostswith;youhavetheoptiontochooseeitherFriends,Public,orOnlyMe.Onceyouhavemadeyourchoice,clickontheOKbuttontodismissthePosttoFacebookdialoganddisplaytheListViewthatwillcontainourlistofwalktrailsfromourDataTemplatecontrol:

TheprecedingscreenshotshowstheDistanceTravelledpagethatincludesourPosttoFacebookbutton,andyouwillnoticethat,uponclickingonthisbutton,severalchoiceswillpopupforyoutochoosefrom.IfyouproceedandclickontheDisplayUserDetailsbutton,thiswillmakeacalltotheGetProfileInformationmethodthatislocatedwithinourFacebookCredentialsclass,andwillpasstheGetAuthAccountaccountinformationtoobtaintheuserdetails,whicharelocatedwithinourFacebookApiAuthToken,usingtheOpenGraphAPIplatform.Uponsuccessfullyobtainingtheuser'sFacebookdetails,youwillbepresentedwithadialogboxcontainingeachofouruser'sfielddetails:

Page 358: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TheprecedingscreenshotshowstheDistanceTravelledpagethatincludesourPosttoFacebookbutton,andyouwillnoticethat,uponclickingonthisbutton,severalchoiceswillpopupforyoutochoosefrom.IfyouclickonthePosttoFacebookWallbutton,thiswillmakeacalltothePostWalkInformationmethodthatislocatedwithinourFacebookCredentialsclass,andwillpassthecurrentlychosenwalktrailinformation,asdeterminedbyourViewModel.Uponsuccessfullypostingtotheuser'sFacebookwall,youwillbepresentedwithadialogboxtellingyouthatthewalkentryhasbeenpostedtotheuser'sFacebookwall.

Page 359: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,weupdatedourTrackMyWalksapplicationtoallowustouseFacebooktosignintoourapp.YoulearnedhowyoucanuseboththeXamarin.AuthandtheFacebookSDKtoauthenticatewhethertheuserisavalidFacebookuser.Next,youlearnedhowtocreateacustomFacebookApiUsermodelandaFacebookCredentialsclassthatareusedtostoretheuser'scredentials,sothatthesecanbeusedthroughoutourapptoobtaininformationabouttheuser.

Asweprogressedthroughoutthechapter,youcreatedaFacebookSignIncontentpageandacustompagerendererclassthatwillallowtheusertosignintotheTrackMyWalksappusingtheirFacebookcredentials,andupdatedtheViewModelandcontentpagessothattheycanutilizetheFacebookfunctionalityappropriately.YoulearnedhowtotakeadvantageoftheFacebookSDKandpostwalkdatatoyourFacebookprofilepage,soyoucanshowoffyourprogresstoyourfriendsand/orworkcolleagues.

Inthenextchapter,you'lllearnhowtocreateandrununittestswithintheXamarinStudioIDE,usingtheUITestframework,beforemovingontolearnhowtoprofileourapplicationusingtheXamarinProfiler,andhowtousetheXamarinInspectortoinspectanddebugouruserinterfacesvisually,andfixUI-relatedproblems.

Page 360: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter9.UnitTestingYourXamarin.FormsAppsUsingtheNUnitandUITestFrameworksInourpreviouschapter,weupdatedourTrackMyWalksapplicationtoallowustouseFacebooktosignintoourapp.YoulearnedhowyoucanuseboththeXamarin.AuthandFacebookSDKtoauthenticateiftheuserisavalidFacebookuser.Next,youlearnedhowtocreateacustomFacebookApiUsermodelandFacebookCredentialsclassthatwillbeusedtostoretheuser'scredentials,sothatthesecanbeusedthroughoutourapptoobtaininformationabouttheuser,aswellaspostinformationtotheirFacebookwall.

DuringthedevelopmentofourTrackMyWalksapp,wehavedesignedandimplementedvariousdesignpatternsandbestpractices,withtheintentionofmakingiteasiertomaintainandtestourappbyseparatingtheuserinterfaceandbusinesslogic.

Inthischapter,you'lllearnhowtocreateandrununittestsusingtheNUnitandUITesttestingframeworksrightwithintheXamarinStudioIDE.You'lllearnhowtowriteunittestsforourViewModelsthatwillessentiallytestthebusinesslogictovalidatethateverythingisworkingcorrectly,beforemovingontotestingtheuserinterfacesportionusingautomatedUItesting.

Thischapterwillcoverthefollowingtopics:

CreatingaunittestingsolutionusingthepopularNUnittestingframeworkAddingtheMoqNuGetpackagetotheunittestingsolutionAddingtheXamarinTestCloudAgentNuGetpackagetotheUITestsolutionSuccessfullylearninghowtotestyourViewModelsRunningunittestsandUITestsusingtheXamarinStudioIDEUnderstandingthecommontypesofUITesttestingmethodsCreatingaunittestingsolutionusingtheUITestframeworkSuccessfullylearninghowtotestyourContentPages(Views)

Page 361: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingaunittestsolutionfolderusingXamarinStudioDuringthedevelopmentofourTrackMyWalksapplication,wehavedesignedtheuserinterfaces,ViewModels,andContentPages.Asdevelopers,theremaybetimeswhenwewouldliketoobtainfeedbacktoletusknowwhenourapplicationlogicisworkingasexpected.WecanusetheNUnittestingframeworktoprovideuswiththatconfirmation.

Inthissection,you'llbeginbyaddinganewsolutionfoldertoourexistingTrackMyWalksPortableClassLibrarysolution.ThisnewsolutionfolderwillbeusedtoseparateeachofourNUnitandUITestsfromourmainsolution.

ThegoodnewsisthatXamarinStudiohasbuiltinsupportfortheNUnitframeworkthatwecanrunourunittestsfrom,andthenhaveourresultsdisplayed,rightwithintheXamarinStudioIDE.

Let'slookathowtoaddanewSolutionfoldertoourTrackMyWalksPortableClassLibrary,byperformingthefollowingsteps:

1. Right-clickontheTrackMyWalkssolutionprojectandchoosetheAdd|AddSolutionFoldermenuoption,asshowninthefollowingscreenshot:

Page 362: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

2. Next,enterinTrackMyWalks.Testsforthenameofthesolutionfolder.

NowthatyouhavecreatedtheTrackMyWalks.TestssolutionwithinthemainTrackMyWalkssolutionproject,ournextstepistocreateanewunittestprojectsolution,thatwillberesponsiblefortestingthebusinesslogicwithinourTrackMyWalksViewModels.

Page 363: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingaunittestprojectusingXamarinStudioIntheprevioussection,wecreatedtheunittestingSolutionfolderwithinourTrackMyWalksmainprojectsolutionthatwillbeusedtoseparatetheunittestsfromourmainiOSandAndroidprojectsolutions.Thisissothatwecanruntheseindependentlyfromthemainsolution.

OneofthegreatbenefitsofusingXamarinStudiotohandleyourtestsisthatitleveragesthepopularNUnittestingframeworkforperformingunittests.WewillbeginbycreatingtheNUnittestprojectwithintheTrackMyWalks.Testssolutionthatwe'vepreviouslycreated.

Let'sstartbycreatinganewNUnitprojectwithinourTrackMyWalks.Testsprojectsolution,byperformingthefollowingsteps:

1. Right-clickontheTrackMyWalks.TestssolutionprojectandchoosetheAdd|AddNewProject...menuoption,asshowninthefollowingscreenshot:

2. Next,choosetheNUnitLibraryProjectoptionlocatedwithintheGeneralsectionundertheOther|.NETsection;ensureyouhaveselectedC#astheprogramminglanguagetouse,asshowninthefollowingscreenshot:

Page 364: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Then,clickontheNextbuttontoproceedtothenextstepinthewizard.4. Next,enterTrackMyWalks.UnitTeststouseasthenameforyournewprojectinthe

ProjectNamefield.5. Then,ensurethattheCreateaprojectdirectorywithinthesolutiondirectory.hasbeen

selected,asshowninthefollowingscreenshot:

Page 365: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Finally,clickontheCreatebuttontosaveyourprojectatthespecifiedlocation.

Onceyourprojecthasbeencreated,youwillbepresentedwiththeXamarinStudiodevelopmentenvironment,withyournewprojectedcreatedwithintheTrackMyWalks.Testssolutionfolder.

Inthenextsection,wewillbegintoaddtheMoq(pronouncedasmock)frameworklibrarythatwillberesponsibleforallowingustotestourViewModelswithintheTrackMyWalkssolution.

Page 366: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheMoqNuGetpackagetotheunittestprojectNowthatyouhavesetupandcreatedanewunittestproject,ournextstepistoaddtheMoq(pronouncedasMock)NuGetpackagetotheTrackMyWalks.UnitTestssolution.Thislibraryisessentiallyoneofthemostpopularandfriendlymockingframeworklibrariesforthe.NETplatform,andwewillusethistotestsomeofourViewModelswithinourTrackMyWalksapp.

Let'slookathowtoaddtheMoqNuGetpackagetoourTrackMyWalks.UnitTestsprojectsolution,byperformingthefollowingsteps:

1. Right-clickonthePackagesfolderthatiscontainedwithintheTrackMyWalks.UnitTestssolution,andchoosetheAddPackages...menuoption,asshowninthefollowingscreenshot:

2. ThiswilldisplaytheAddPackagesdialog,enterinmoqwithinthesearchdialog,andselecttheMoq:anenjoyablemockinglibraryoptionwithinthelist,asshowninthefollowingscreenshot:

Page 367: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Finally,clickontheAddPackagebuttontoaddtheNuGetpackagetothePackagesfoldercontainedwithintheTrackMyWalks.UnitTestssolution.

NowthatyouhaveaddedtheMoqNuGetpackage,ournextstepistobeginwritingthetestcasescenariosforourViewModels,whichwewillbecoveringinthenextsection.

Page 368: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheTrackMyWalksprojecttoTrackMyWalks.UnitTestsIntheprevioussection,weaddedtheMoqNuGetpackagetoourTrackMyWalkssolution.ThenextstepistoaddareferencetotheTrackMyWalkscorelibrarytoourTrackMyWalks.UnitTestssolution.

SincewewillbetestingourViewModels,youwillneedtoensurethatyouhaveappliedallofthecumulativecodechangestotheTrackMyWalkssolutionprojectthroughoutthisbooktoavoidanyissues,aswewillessentiallyneedtobreakeachofthetestsintoindividualclassesrepresentingeachViewModelandtheaccompanyingunittestclassthatwewanttotestthebusinesslogicon.TosuccessfullytestourViewModels,wewillfirstneedtoincludeareferencetotheTrackMyWalksprojectwithinourTrackMyWalks.UnitTestssolutionproject.

Let'slookathowwecanachievethis,byperformingthefollowingsteps:

1. Right-clickontheReferencesfolderthatiscontainedwithintheTrackMyWalks.UnitTestsprojectsolution,andchoosetheEditReferences...menuoption,asshowninthefollowingscreenshot:

2. Then,ensurethattheProjectstabhasbeenselectedandchoosetheTrackMyWalksprojecttoincludeourAndroidandiOSplatformsolutionprojectswithinourTrackMyWalks.UnitTestsprojectsolution:

Page 369: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Next,ensurethatyouhaveselectedtheTrackMyWalksprojectwithintheProjectstab,clickonOKtoaddtheprojectreferencetoyourReferencessectionofyourTrackMyWalks.UnitTestsprojectsolution,andclosetheEditReferencesdialog.

Inthenextsection,wewillbeginbycreatingourfirstunittestwhichwillberesponsibleforvalidatingtheWalkEntrymodeltoensurethataftertheViewModelhasbeeninitialized,itwillcontainwalkinformation.

Page 370: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingtheWalksTrailViewModelNUnittestclassNowthatyouhaveincorporatedtheTrackMyWalksprojectintotheTrackMyWalks.UnitTestssolution,ournextstepistocreatetheunittestforourWalksTrailViewModel.ThesetestswillbeusedtohelpuschecktoseewhenourViewModelpassesorfailsunderthesetestconditions.

Let'snowstarttoimplementthecoderequiredforourWalksTrailViewModelTestclass,byperformingthefollowingsteps:

1. CreateanemptyclasswithintheTrackMyWalks.UnitTestsprojectsolutionfolder,bychoosingAdd|NewFile....Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingtheTrackMyWalksmodel,withinChapter1,CreatingtheTrackMyWalksNativeApp.

2. Then,enterWalksTrailViewModelTestforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethenewfile.

3. Next,ensurethattheWalksTrailViewModelTest.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//WalksTrailViewModelTest.cs

//WalksTrailViewModelTestingFramework

//

//CreatedbyStevenF.Danielon23/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingNUnit.Framework;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

usingMoq;

usingSystem.Threading.Tasks;

namespaceTrackMyWalks.Tests

{

4. Next,weneedtomodifytheWalksTrailViewModelTestclassconstructorbyaddingthe[TestFixture]attributewhichsetsupourclasstobeaninstanceoftheTestFixturetestingclass.Proceedandenterinthefollowingcodesnippet:

[TestFixture]

publicclassWalksTrailViewModelTest

{

WalksTrailViewModel_vm;

5. Then,createtheSetupinstancemethodthatwillberesponsibleforcreatinganewinstanceofourViewModelforeachoftheteststhataredeclaredwithintheclass.ThisistoensurethateachtestisrunusingacleaninstanceoftheViewModel.WethenproceedtodeclareanavMockvariableinstanceoftheMockclassfromourMoqlibrarytocreateanewinstanceoftheIWalkNavServiceandinstantiatetheWalksTrailViewModel,usingthenavMockinstance.Proceedandenterinthefollowingcodesnippet:

Page 371: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

[SetUp]

publicvoidSetup()

{

varnavMock=newMock<IWalkNavService>().Object;

_vm=newWalksTrailViewModel(navMock);

}

6. Next,weneedtoimplementtheCheckIfWalkEntryIsNotNullinstancemethodthatwillchecktoseeifourWalksTrailViewModelhasbeenproperlyinitializedwhentheInitmethodiscalled.Wedeclarethe[Test]attributewhichisessentiallyanabstractclassthatrepresentsatestwithintheNUnit.Testframework.WeproceedtoinitializeourWalkEntrymodeltonull,andthencalltheInitmethodtochecktoseeiftheWalkEntrymodelhasbeenproperlysettothevalueprovidedintheInitmethod'sparameterandthenusetheIsNotNullmethodontheAssertclasstodisplayamessageshouldthetestfail.Thisissothatyoucantroubleshootthecodeatalaterpoint.Proceedandenterinthefollowingcodesnippet:

[Test]

publicasyncTaskCheckIfWalkEntryIsNotNull()

{

//Arrange

_vm.WalkEntry=null;

//Act

await_vm.Init();

//Assert

Assert.IsNotNull(_vm.WalkEntry,"WalkEntryisnull

afterbeinginitializedwithavalidWalkEntriesobject.");

}

}

}

Intheprecedingcodesnippet,webeganbyimplementingthevariousinstancemethodsthatwillberequiredtoperformeachtestforourWalksTrailViewModel.Weaddedthe[TestFixture]attributeatthebeginningofourclassconstructorsothatitwillbeaninstanceoftheTestFixturetestingclass.WethenproceededtocreatetheSetupinstancemethodsothatitwillberesponsibleforcreatinganewinstanceofourViewModelforeachoftheteststhataredeclaredwithintheclass,usingthe[Test]attribute.ThisisessentiallyanabstractclassthatrepresentsatestwithintheNUnit.Testframework,andensuresthateachtestisrunusingacleaninstanceoftheViewModel.

Next,weusedtheMockclassfromourMoqlibrarytocreateanewinstanceoftheIWalkNavServicewheninstantiatingtheWalksTrailViewModel.

Inthenextstep,weimplementedtheCheckIfWalkEntryIsNotNullinstancemethodthatwillperformachecktoseeifourWalksTrailViewModelhasbeenproperlyinitializedwhenevertheInitmethodhasbeencalled.Again,wedeclaredthe[Test]attributepriortoinitializingourWalkEntrymodeltonull,andpriortocallingtheInitmethodtochecktoseeiftheWalkEntry

Page 372: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

modelhasbeenproperlysettothevalueprovidedintheInitmethod'sparameter.Afterthat,weusedtheIsNotNullmethodontheAssertclasstodisplayamessageshouldthetestfail.Thisissothatyoucantroubleshootthecodeatalaterpoint.

Inthenextsection,wewillbeginbycreatingthesecondunittestwhichwillberesponsibleforvalidatinginformationcontainedwithinourWalkEntryViewModeltoensurethatafterourViewModelhasbeeninitialized,wereceivetheexpectedresultsreturned.

Page 373: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandimplementingtheWalkEntryViewModelNUnittestclassIntheprevioussection,wecreatedtheNUnittestforourWalksTrailViewModelwhichcheckedtoensurethattheWalksEntrymodelwasproperlyinitializedaftertheInitmethodwascalled.Inthissection,wewillcreateanotherNUnittestthatwillchecktoseeifcertainpropertieswithinourWalksEntryViewModelhavebeensetupandinitialized.

Let'snowstarttoimplementthecoderequiredforourWalkEntryViewModelTestclassbyperformingthefollowingsteps:

1. CreateanemptyclasswithintheTrackMyWalks.UnitTestsprojectsolutionfolder,bychoosingAdd|NewFile....Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingandimplementingtheWalksTrailViewModelNUnittestclass,withinthischapter.

2. Then,enterinWalkEntryViewModelTestforthenameofthenewclassthatyouwanttocreate,andclickontheNewbuttontoallowthewizardtoproceedandcreatethenewfile.

3. Next,ensurethattheWalkEntryViewModelTest.csfileisdisplayedwithinthecodeeditor,andenterinthefollowingcodesnippet:

//

//WalkEntryViewModelTest.cs

//WalkEntryViewModelTestingFramework

//

//CreatedbyStevenF.Danielon23/09/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingNUnit.Framework;

usingTrackMyWalks.ViewModels;

usingTrackMyWalks.Services;

usingMoq;

usingSystem.Threading.Tasks;

namespaceTrackMyWalks.UnitTests

{

4. Next,weneedtomodifytheWalkEntryViewModelTestclassconstructorbyaddingthe[TestFixture]attributejustaswedidintheprevioussection.ThissetsupourclasstobeaninstanceoftheTestFixturetestingclass.Proceedandenterinthefollowingcodesnippet:

[TestFixture]

publicclassWalkEntryViewModelTest

{

WalkEntryViewModel_vm;

5. Then,createtheSetupinstancemethodthatwillberesponsibleforcreatinganewinstanceofourViewModelforeachoftheteststhataredeclaredwithintheclass.ThisistoensurethateachtestisrunusingacleaninstanceoftheViewModel.WethenusetheMockclassfromourMoqlibrarytocreateanewinstanceoftheIWalkNavServicewheninstantiating

Page 374: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

theWalkEntryViewModel.Proceedandenterinthefollowingcodesnippet:

[SetUp]

publicvoidSetup()

{

varnavMock=newMock<IWalkNavService>().Object;

_vm=newWalkEntryViewModel(navMock);

}

6. Next,weneedtoimplementtheCheckIfEntryTitleIsEqualinstancemethodthatwillchecktoseeifourTitlepropertyhasbeenproperlyinitializedwhentheInitmethodhasbeencalled.We'lldeclarethe[Test]attributejustaswedidintheprevioustest,andthenwe'llproceedtoinitializetheTitlepropertyandcalltheInitmethodtocheckwhethertheTitlepropertyhasbeeninitializedcorrectlytothevalueprovidedintheInitmethod'sparameter.

7. Next,weusetheAreEqualmethodontheAssertclasstochecktoseeiftheTitlepropertyhasbeeninitializedcorrectly,andthendisplayamessagecontainingthevalueoftheTitlepropertyfromtheViewModel,shouldthetestfail.Proceedandenterinthefollowingcodesnippet:

[Test]

publicasyncTaskCheckIfEntryTitleIsEqual()

{

//Arrange

_vm.Title="NewWalk";

//Act

await_vm.Init();

//Assert

Assert.AreEqual("NewWalk",_vm.Title);

}

8. Then,weneedtoimplementtheCheckIfDifficultyIsEqualinstancemethodanddeclarethe[Test]attribute,priortoinitializingourDifficultypropertytoastringvalue,andthencallingtheInitmethod.Inthenextstep,weusetheAreEqualmethodontheAssertclasstocheckwhethertheDifficultypropertyhasbeeninitializedcorrectly,anddisplayamessagecontainingthevalueoftheDifficultypropertyfromtheViewModel,shouldthetestfail.Proceedandenterinthefollowingcodesnippet:

[Test]

publicasyncTaskCheckIfDifficultyIsEqual()

{

//Arrange

_vm.Difficulty="Easy";

//Act

await_vm.Init();

//Assert

Assert.AreEqual("Easy",_vm.Difficulty);

}

Page 375: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

9. Next,weneedtoimplementtheCheckIfKilometersIsNotEqualinstancemethodthatdeclaresthe[Test]attributejustaswedidintheprevioustest.WetheninitializeourKilometerspropertytoaDoublevalue,andcalltheInitmethod.Inthenextstep,weusetheAreEqualmethodontheAssertclasstochecktoseeiftheKilometerspropertyhasbeeninitializedcorrectly,anddisplayamessagecontainingthevalueoftheKilometerspropertyfromtheViewModel,shouldthetestfail.Proceedandenterinthefollowingcodesnippet:

[Test]

publicasyncTaskCheckIfKilometersIsNotEqual()

{

//Arrange

_vm.Kilometers=40.0;

//Act

await_vm.Init();

//Assert

Assert.AreNotEqual(40.0,_vm.Kilometers);

}

}

}

Intheprecedingcodesnippet,webeganbyimplementingthevariousinstancemethodsthatwillberequiredtoperformeachtestforourWalkEntryViewModel.Weaddedthe[TestFixture]attributeatthebeginningoftheclassconstructorsothatitwillbeaninstanceoftheTestFixturetestingclass;andthenproceededtocreatetheSetupinstancemethodsothatitwillberesponsibleforcreatinganewinstanceofourViewModelforeachoftheteststhatisdeclaredwithintheclass,usingthe[Test]attributewhichisessentiallyanabstractclassthatrepresentsatestwithintheNUnit.Testframework,andensuresthateachtestisrunusingacleaninstanceoftheViewModel.

Next,weusedtheMockclassfromourMoqlibrarytocreateanewinstanceoftheIWalkNavServicewheninstantiatingtheWalkEntryViewModel.Inthenextstep,weimplementedtheCheckIfEntryTitleIsEqualinstancemethodthatwillperformachecktoseeiftheTitlepropertyhasbeenproperlyinitializedwhenevertheInitmethodhasbeencalled.Again,wedeclarethe[Test]attributepriortoinitializingtheTitlepropertyoftheWalksEntrymodel,andpriortocallingtheAreEqualmethodontheAssertclasstochecktoseeiftheTitlepropertyhasbeeninitializedcorrectly.WethendisplayedamessagecontainingthevalueoftheTitlepropertyfromtheViewModel,shouldthetestfail.

Next,weimplementedtheCheckIfDifficultyIsEqualinstancemethodthatwillinitializetheDifficultypropertytoastringvalue,andthencalltheInitmethodoftheWalkEntryViewModel.WecalledtheAreEqualmethodontheAssertclasstoconfirmthat,afterwecalltheInitmethod,thevalueoftheDifficultypropertyfromtheViewModelisthevaluethatweexpecttocomebackfromtheprovidedMockinstance.Ifthevalueisnotwhatweexpect,

Page 376: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

thetestwillfailandwilldisplayamessagecontainingthevalueoftheDifficultypropertyfromtheViewModel.

Inourfinalstep,weimplementedtheCheckIfKilometersIsNotEqualinstancemethodthatinitializesourKilometerspropertytoaDoublevalue,andthencallstheInitmethod.JustaswedidinourCheckIfDifficultyIsEqualinstancemethod,weusedtheAreNotEqualmethodontheAssertclasstoconfirmthat,afterwecalltheInitmethod,thevalueoftheKilometerspropertyfromtheViewModelisthevaluethatweexpecttocomebackfromtheprovidedmockinstance.Ifthevalueisnotwhatweexpect,thetestwillfailandwilldisplayamessagecontainingthevalueoftheKilometerspropertyfromtheViewModel.

ForeachtestmethodthatyoucreatethatwillberepresentedbytheNUnit[Test]attribute,theArrange-Act-Assertpatternwillfollow.Thisisdescribedinthefollowingtable:

Testpattern Description

Arrange Thiswillessentiallyperformallthesettingupandinitializationconditionsforyourtest.

Act Thisensuresthatyourtestwillsuccessfullyinteractwiththeapplication.

Assert ThiswillexaminetheresultsoftheactionsthatwereinitiallyperformedwithintheActsteptoverifytheresults.

Youcannowsee,thatbyincorporatingtheNUnit.Frameworkwithinyourapplications,aswellasadoptingtheArrange-Act-Assertpattern,youcanessentiallyperformtestsonyourViewModelstoensurethattheresultsyouareexpectingarereturned.

Note

IfyouareinterestedinlearningmoreabouttheNUnit.Framework.Testclass,anditsassociatedmethods,pleaserefertotheinformationcontainedathttps://developer.xamarin.com/api/type/NUnit.Framework.Internal.Test/.

TolearnmoreabouttheNUnit.Framework.Assertclassandothermethodsthatyoucanusetohandlethedifferenttypesofassertions,pleaserefertotheinformationlocatedathttps://developer.xamarin.com/api/type/NUnit.Framework.Assert/.

Nowthatyouhavecreatedyourunittests,ournextstepistobeginrunningourtestsrightwithintheXamarinStudioIDE,whichwewillbecoveringinthenextsection.

Page 377: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

RunningtheTrackMyWalks.UnitTestsusingXamarinStudioInourprevioussection,wecreatedandimplementedunittestsforboththeWalksTrailViewModelandtheWalkEntryViewModel.Thesecontainedsetsofvarioustestconditionsthatwecheckedagainst.

OurnextstepistobeginrunningtheseunittestsdirectlyfromwithintheXamarinStudiodevelopmentenvironment.

Let'slookathowwecanachievethiswiththefollowingsteps:

1. Torunaunittest,right-clickontheTrackMyWalks.UnitTestsprojectwithintheSolutionpane,andchoosetheRunItemoption,asshowninthefollowingscreenshot:

2. Alternatively,youcanalsoruntheunittestbyselectingtheTrackMyWalks.UnitTestssolutionprojectandthennavigatingtotheRunmenuoptionandchoosingtheRunUnitTestssub-menuitem.

Whenthecompilationoftheunittestshascompleted,youwillbepresentedwithalistshowingeachofyourtestresultsthathavepassed,failed,orwereignored.ThesearedisplayedwithintheTestResultspane,asshowninthefollowingscreenshot:

Page 378: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Shouldanyofyourtestsfail,thesewillbedisplayedwithintheTestResultspane,alongwiththeirassociatedStackTrace.YouwillalsonoticethatthemessagethatweprovidedwithintheAssert.AreEqualmethodwillalsobedisplayedaspartofthefailureresult:

Fromthisscreen,youhavetheoptionoffilteringyourtestresultsorre-runningyourunittestconditionsagain.Theseareexplainedinmoredetailinthefollowingtable:

Testresultoption Description

SuccessfulTests

Thiswilldisplayallthesuccessfullyexecutedtestswhichpassedtheconditionsasspecifiedwithinthetestcase.

Page 379: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

InconclusiveTests

Thiswilldisplayanytestresultsthatwerefoundtobeinconclusive,meaningthatafirmresultcouldnotbedetermined.

FailedTests Thisoptiondisplaysalistofanyteststhatdidnotmeettheconditionsasspecifiedwithinthetestcasescenario.

IgnoredTests

Thisoptiondisplaysalistofanyteststhatwereignoredasspecifiedbythe[Ignore]attribute.

OutputThisoptiondisplaysaconsoleoutputforeachoftheteststhatareexecutedandwillcontainanyteststhathavesuccessfullypassed,failed,beenignored,orwerefoundtobeinconclusive.

RerunTests Thisoptionenablesyoutore-runyourtestsagain,withouttheneedforrecompilingyourtestcases.

NowthatyouhaveagoodunderstandingofhowtocreateyourownunittestsusingtheNUnittestingframework,wecannowlookathowtocreateanotherformofunittesting,whichiscalledautomatedUItesting.ThistimewewillbeleveragingtheUITestframeworkwhichwillenableustoperformtestsontheuserinterfaceportionofourTrackMyWalksappwhichwewillbecoveringoverthenextsections.

Page 380: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingaUItestprojectusingXamarinStudioIntheprevioussection,wesawhoweasyitistocreateasetofunitteststhatenableustotestourViewModelswithintheTrackMyWalksproject.Whilstunittestingensuresthatasignificantamountofcodeistested,itisprimarilyfocusedontestingtheactualbusinesslogicwithintheapp.Thisleavestheuserinterfaceportionsoftheappstilluntested,butthebeautyofusingUItestingallowsustoautomatespecificactionswithinourapp'suserinterfacetoensurethatitisworkingasexpected.

Fortunately,XamarinStudioprovidesyouwitharichsetoftoolsforperformingautomatedUItests,andthesecanbebothwritteninC#andmakeuseoftheUITestframework.Let'sstartbycreatinganewUITestprojectwithinourTrackMyWalks.Testsprojectsolution,byperformingthefollowingsteps:

1. Right-clickontheTrackMyWalks.TestssolutionprojectandchoosetheAdd|AddNewProject...menuoption.Ifyoucan'trememberhowtodothis,youcanrefertothesectionentitledCreatingaunittestprojectusingXamarinStudio,locatedwithinthischapter.

2. Next,choosetheUITestAppoptionlocatedwithintheXamarinTestCloudsection,undertheMultiplatform|Testssection.EnsurethatyouhaveselectedC#astheprogramminglanguagetouse,asshowninthefollowingscreenshot:

Page 381: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Then,clickontheNextbuttontoproceedtothenextstepinthewizard.4. Next,enterTrackMyWalks.UITeststouseasthenameforyournewprojectastheProject

Namefield.5. Then,ensurethattheCreateaprojectdirectorywithinthesolutiondirectory.hasbeen

selected,asshowninthefollowingscreenshot:

Page 382: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Finally,clickontheCreatebuttontosaveyourprojectatthespecifiedlocation.

Onceyourprojecthasbeencreated,youwillbepresentedwiththeXamarinStudiodevelopmentenvironment,withyournewprojectcreatedwithintheTrackMyWalks.Testssolutionfolder.

YouwillnoticethatbydefaultourprojecthascreatedafilenamedTest.csthatwecanusetowriteourUITests,aswellasaclassnamedAppInitializer.csthatisessentiallyusedbytheTest.csclasstocreateanIAppinstanceandstarttheappforeachtestcondition.SincewewillonlybecreatingoneUITestforthischapter,wecanessentiallyjustusetheTest.csfilefornow.

Inanidealworld,youwouldbecreatingvarioustests,oneforeachtestcondition,soitwouldmakesensetobreakeachofyourUITestsintoindividualfiles.Inthenextsection,wewilllearnaboutsomeofthecommonlyusedUITestmethodsthatwecanusewhileperformingUITestsforourapplication'suserinterface.

Page 383: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UnderstandingthecommonlyusedUITestmethodsAsmentionedpreviously,inthissection,wewilllearnaboutsomeofthecommonlyusedmethodsthatwecanusewiththeUITestframework.TheUITestframeworkprovidesyouwithawayofautomatingtheinteractionsbetweenyouriOS,orAndroidappsusingC#andtheNUnittestingplatform.

WewillbeusinganinstanceoftheIAppandConfigureAppclassesthatwillbeusedtocreateouriOSandAndroidIAppinstancestohandlealltheinteractionswithintheUI.

Asweprogressthroughoutthenextcoupleofsections,wewillbetakingacloserlookathowtocreateIAppinstancesusingtheConfigureAppclass.TheUITestframeworkprovidesyouwithseveralAPIsthatyoucanusetointeractwithanapp'suserinterface.

ThefollowingtabledescribessomeofthemorecommonlyusedmethodsandtheonesthatwewillbeusingtotesttheTrackMyWalksapp:

UITestmethods Description

Screenshot() Thiswillessentiallytakeascreenshotofthecurrentstateoftheapp.

Tap()Thisisusedtosendatapinteractiontoaspecificelementontheapp'scurrentscreen.

EnterText()andClearText()

ThesemethodsareusedtoaddandremovetextfrominputelementssuchastheentryviewsusedwithinXamarin.Forms.

Query()Thismethodisessentiallyusedtolocateorfindelementsthatarecurrentlydisplayedwithintheapp'sscreen.

Repl()Thiscommandiscommonlyusedtointeractinreal-timewiththeappthroughtheterminalusingtheUITestAPI.

WaitForElement()Thismethodisusedtopausethetestuntilaspecificelementappearsontheapp'scurrentscreenwithinaspecifictimeoutperiod.

MethodssuchastheQueryandWaitForElementreturnanAppResult[]objectthatyoucan

Page 384: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

essentiallyusetodeterminetheresultsofthecall.AnexamplewouldbethatifyouusedtheQuerymethodcallthatreturnsanemptyresultset,wecanbesurethattheelementdoesnotexistwithintheapp'scurrentscreen.

Note

ItisworthmentioningthatcurrentlytheUITestframeworkonlyprovidessupportforboththeiOSandAndroidplatformsanddoesn'tyetprovidesupportfortheWindowsPhoneplatform.

Asyouwillseefromthemethodsdisplayedinthefollowingtable,theseareessentiallyallthememberspertainingtotheAppQueryclassthatareusedbytheQueryandWaitForElementmethodmembersoftheIAppmethods:

AppQueryclassmethods Description

Class() Findselementsontheapp'scurrentscreen,basedontheirclasstype.

Marked()Findselementswithintheapp'scurrentscreen,basedontheirtextoridentifier.

Css()PerformsCSSselectoroperationsonthecontentsofaWebViewontheapp'scurrentscreen.

Note

IfyouareinterestedinlearningmoreaboutthevarioustypesofUITestmethods,pleaserefertotheIntroductiontoXamarin.UITestathttps://developer.xamarin.com/guides/testcloud/uitest/intro-to-uitest/.

NowthatyouunderstandsomeofthemostcommonlyusedUITestmethods,wecanstarttoimplementsometestswhichwewillbecoveringoverthenextcoupleofsectionswithinthischapter.

Page 385: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SettingupandinitializingourTrackMyWalksappforUITestPriortostartinganappandinteractingwithitusingtheUITestframework,weneedtodosomepreliminaryinitializationstepsforwhichwe'llmakesomemodificationswithintheAppInitializerclass.TheAppInitializerclasscontainsastaticmethodcalledStartApp.

Thisstaticmethodiscalledeachtimethetest'sSetupmethodiscalledtogetanIAppinstance.ItcurrentlysupportsboththeiOSAppandAndroidAppasdefinedbytheConfigureAppclass.

OnethingthatyouwillnoticewithintheAppInitializerclassisthattheApkFileandtheAppBundlehavebothbeencommentedout.YouwillneedtouncommenttheseifyouwouldliketorunthetestslocallywithintheunittestpaneusingXamarinStudio.

usingSystem;

usingSystem.IO;

usingSystem.Linq;

usingXamarin.UITest;

usingXamarin.UITest.Queries;

namespaceTrackMyWalks.UITests

{

publicclassAppInitializer

{

publicstaticIAppStartApp(Platformplatform)

{

...

...

...

if(platform==Platform.Android)

{

returnConfigureApp.Android

//TODO:Updatethispathtopoint

toyourAndroid

//appanduncommentthecodeifthe

appisnot

//includedinthesolution.

//.ApkFile("../../../Droid/bin/Debug

/TrackMyWalks.apk").StartApp();

}

returnConfigureApp.iOS

//TODO:Updatethispathtopointto

youriOSappand

//uncommentthecodeiftheappis

notincludedinthe

//solution.

//.AppBundle("../../../iOS/bin/

iPhoneSimulator/Debug/TrackM

//yWalks.iOS.app").StartApp();

}

}

}

Page 386: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Asyoucanseefromtheprecedingcodesnippet,theAppInitializerclasscontainsseveraldifferentmethodsthatarepartoftheConfigureAppmethod.Thefollowingtableprovidesabriefdescriptionofwhateachoneisusedfor:

ConfigureAppmethods Description

AppBundle()Thismethodisusedforspecifyingthepathtotheappbundletouseduringtesting.

StartApp() Thismethodessentiallylaunchestheappwithinthesimulator.

Debug()

Thismethodisessentiallyusedtoenabledebuggingandloggingofmessagesandisparticularlyusefulifyouneedtotroubleshootproblemswhenrunningtheapplicationusingthesimulator.

DeviceIdentifier()

Thismethodconfiguresthedevicetousewiththedeviceidentifier.ThiscanbeusedtodetectiOSsimulatorsusingthefollowingcommandlinestatement:

xcruninstruments-sdevices

EnableLocalScreenshots

Thismethodisusedtoenablescreenshotswhenyou'rerunningtestslocally.Bydefault,screenshotsarealwaysenabledwhenevertestsarebeingrunusingXamarinTestCloud.

Repl()ThismethodwillessentiallypausethetestexecutionandinvoketheREPLinaterminalprompt.

Asyoucansee,theAppInitializerfiledoesn'tcontainmuchinformation,butasweworkourwaythroughthischapter,wewillbeaddingtheXamarin.TestCloud.AgenttotheiOSportionoftheTrackMyWalksappsothatwewillbeabletorunourUITests.

Page 387: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ImplementingtheCreateNewWalkEntryusingtheUITest.FrameworkIntheprevioussection,welookedatsomeofthedifferenttypesofmethodsthatwecanusetocustomizetheAppInitializerclasssothatwecanspecifydifferentappbundlestouseduringtesting,aswellastoenablescreenshots,andprovidetheabilitytodebugourunittestswithintheXamarinStudioenvironment.

Inthissection,wewillbeginbyimplementingaUITestthatwecanusetohandlesigningintoFacebookandcreatinganewwalkentryusingtheUITestframework.

Let'snowstarttoimplementthecoderequiredforourclassbyperformingthefollowingsteps:

1. OpentheTest.csfilewhichcanbelocatedwithintheTrackMyWalks.UITestsprojectaspartoftheTrackMyWalks.Testssolutionfolder.

2. Next,ensurethattheTest.csfileisdisplayedwithinthecodeeditor,andenterinthefollowinghighlightedcodesections,asshowninthecodesnippet:

usingSystem;

usingSystem.IO;

usingSystem.Linq;

usingNUnit.Framework;

usingXamarin.UITest;

usingXamarin.UITest.Queries;

namespaceTrackMyWalks.UITests

{

[TestFixture(Platform.Android)]

[TestFixture(Platform.iOS)]

publicclassTests

{

IAppapp;

Platformplatform;

3. Then,modifytheTestsinstancemethodthatwillberesponsibleforcreatinganewinstanceofourIAppinstance.WeupdateourentryCellPlatformClassNamestringvariabletoreturnthetypeofTextField,dependentontheplatformthatwearetestingon.UnderiOS,weusetheUITextField,whereasunderAndroiditwillusethedefaultEntryCellEditTextclass.Proceedandenterinthehighlightedcodesectionswithinthefollowingcodesnippet:

stringentryCellPlatformClassName;

publicTests(Platformplatform)

{

this.platform=platform;

entryCellPlatformClassName=platform

==Platform.iOS

Page 388: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

?"UITextField"

:"EntryCellEditText";

}

[SetUp]

publicvoidBeforeEachTest()

{

app=AppInitializer.StartApp(platform);

}

[Test]

publicvoidAppLaunches()

{

app.Screenshot("Firstscreen.");

}

4. Next,createtheSignInToFacebookinstancemethodthatwillberesponsibleforhandlingthetest'sstepsspecificallytotheFacebooksign-inprocess.Thisusestheuser'slogincredentialstoautomatetheloginprocesspriortocarryingoutotherstepswithintheUI.Proceedandenterinthehighlightedcodesectionswithinthefollowingcodesnippet:

//PerformsigningintoFacebook

publicvoidSignInToFacebook()

{

//SetupourFacebookcredentials

varFaceBookEmail="<Your-Facebook-Email-Address>";

varFaceBookPassword="<Your-Facebook-Password>";

//WaitforLoginbuttonwithinFacebookoAuthwebview

//toappear.

app.WaitForElement(x=>x.WebView().Css("[name=login]"));

//Entertextwithinthewebviewwithname="email"

app.EnterText(x=>x.WebView().Css("[name=email]"),

FaceBookEmail);

//Entertextwithinthewebviewwithname="email"

app.EnterText(x=>x.WebView().Css("[name=pass]"),

FaceBookPassword);

app.ScrollDownTo(x=>x.WebView().Css("[name=login]"));

//Tapthebuttoninthewebviewwithname="login"

app.Tap(x=>x.WebView().Css("[name=login]"));

}

5. Then,createthePopulateEntryCellFieldsinstancemethodthatwillberesponsibleforhandlingtheteststepsspecificallyforthecreationofanewwalkentry.Inthismethod,wemakeuseofboththeClearTextandEnterTextmethodsoftheUITestframeworkthatwilllocateeachentryfieldwithintheNewWalkEntryformandpopulateitwiththenecessaryinformation.TheDismissKeyboardmethodwill,asthenamesuggests,dismissthekeyboardfromtheviewandcontinuetothenextstep.Proceedandenterinthehighlightedcodesectionswithinthefollowingcodesnippet:

//PopulateourEntryCellFields

voidPopulateEntryCellFields()

{

//ClearthedefaulttextentryforourTitleEntryCell

app.ClearText(x=>x.Class

(entryCellPlatformClassName).Index(0));

app.DismissKeyboard();

Page 389: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//EnterinsomedefaulttextforourTitleEntryCell

app.EnterText(x=>x.Class

(entryCellPlatformClassName).Index(0),

"ThisisanewwalkEntry");

app.DismissKeyboard();

//EnterinsomedefaulttextforourNotesEntryCell

app.EnterText(x=>x.Class(entryCellPlatformClassName).Index(1),

"NewNoteEntryForWalkEntry");

app.DismissKeyboard();

//ClearthedefaulttextforourImageUrlEntryCell

app.ClearText(x=>x.Class(entryCellPlatformClassName).Index(6));

app.DismissKeyboard();

//EnterinsomedefaulttextImageUrlEntryCell

app.EnterText(x=>x.Class(entryCellPlatformClassName).Index(6),"

https://heuft.com/upload/image/

400x267/no_image_placeholder.png");

app.DismissKeyboard();

}

6. Next,createtheChooseDifficultyPickerinstancemethodthatwillberesponsiblefordisplayingthedifficultypickerthatcontainsvariouschoicesofdifficultyfortheusertochoosefrom.Allwearedoinghereisdisplayingthepickerwhentheusertapsintothecellentry,anddismissingthepickerfromtheviewwhenthenusertapstheDoneorOKbuttons.Proceedandenterthehighlightedcodesections,asshownwithinthefollowingcodesnippet:

//AutomaticallytapintotheDifficultyCelltodisplaythe

//DifficultyPicker,anddismissitbypressingtheDoneor

//OKbutton.

publicvoidChooseDifficultyPicker()

{

//TapintoDifficultyEntryCell

app.Tap(x=>x.Class(entryCellPlatformClassName).Index(5));

//TapDonelocatedwithintheDifficultyPickerCell

if(platform==Platform.iOS)

app.Tap(x=>x.Marked("Done"));

else

app.Tap(x=>x.Marked("OK"));

}

}

7. Then,createtheCreateNewWalkEntryUITestmethodthatincludesthe[Test]attribute.ThisisanabstractclassthatrepresentsatestwithintheUITestandNUnit.Testframework.Thismethodwillessentiallybethemaintestdriverandwillcalleachoftheotherinstancemethodsthatwe'vepreviouslydeclared.Withinthismethod,wecallourSignInToFacebookmethodtoperformthesign-intoFacebook,usingtheuser'sFacebookcredentials.

8. Uponsuccessfullogin,weusetheWaitForElementmethodtowaituntilthemainTrackMyWalksscreenhasbeendisplayed,priortousingtheAssert.IsTruemethodtochecktoseeiftheTrackMyWalksscreenisdisplayed.Ifit'snotdisplayed,ourtestwillfailanddisplaytheassignederrormessagewithintheTestResultsscreen.Proceedandenterthefollowingcodesectionsshownwithinthefollowingcodesnippet:

Page 390: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

[Test]

publicvoidCreateNewWalkEntry()

{

//SignintoFacebook

SignInToFacebook();

//Waitformainscreentoappearandcheckforour

//navigationtitle.

varnavigationBarTitle=(platform==Platform.iOS?

"TrackMyWalks-iOS":

"TrackMyWalks-Android");

varmainScreen=app.WaitForElement(x=>x.Marked

(navigationBarTitle).Class("UINavigationBar"));

//ChecktoseeiftheTrackMyWalks-iOSmainscreenis

//displayed.

Assert.IsTrue(mainScreen.Any(),navigationBarTitle+"screen

wasn'tshownaftersigningin.");

9. Next,weusetheTapmethodoftheappclassinstanceandtheMarkedmethodtofindtheAddelementwithintheapp'scurrentscreen,andwaituntiltheNewWalkEntrypageisdisplayedwithinthescreen.WethenproceedtousetheAssert.IsTruemethodtochecktoseeiftheNewWalkEntryscreenhasbeensuccessfullydisplayed.Alternatively,ourtestwillfailanddisplaytheassignederrormessagewithintheTestResultsscreen.Proceedandenterinthehighlightedcodesectionsshownwithinthefollowingcodesnippet:

//ClickontheAddbuttonfromourmainscreenandwaitfor

//theNewWalkEntryscreentoappear.

app.Tap(x=>x.Marked("Add"));

varnewWalkEntryBarTitle="NewWalkEntry";

varnewWalkEntryScreen=app.WaitForElement(x=>x.Marked(newWalk

EntryBarTitle));

//ChecktoensurethatourNewWalkEntryscreenwasdisplayed.

Assert.IsTrue(newWalkEntryScreen.Any(),newWalkEntryBarTitle+"

screenwasnotshownaftertappingtheAddbutton.");

10. Then,wecallthePopulateEntryCellFieldsandChooseDifficultyPickerinstancemethodstopopulateourentrycellfieldsandhandlethedisplayofthedifficultypickerselector.Inourfinalsteps,weusetheTapmethodoftheappclassinstance,andweusetheMarkedmethodtofindtheSaveelementwithintheapp'scurrentscreen.We'llwaituntiltheTrackMyWalkspageisdisplayed,beforeusingtheAssert.IsTruemethodtochecktoseeiftheTrackMyWalksscreenhasbeensuccessfullydisplayed.Alternatively,ourtestwillfailanddisplaytheassignederrormessagewithintheTestResultsscreen.Proceedandenterthefollowinghighlightedcodesections,asshownwithinthefollowingcodesnippet:

//PopulateourEntryCellFields

PopulateEntryCellFields();

//DisplayourDifficultyPickerselector.

ChooseDifficultyPicker();

//ThentapontheSavebuttontosavethedetailsandexit

Page 391: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

//thescreen.

app.Tap(x=>x.Marked("Save"));

//Next,waitformainscreentoappear

mainScreen=app.WaitForElement(x=>x.Marked

(navigationBarTitle).

Class("UINavigationBar"));

//ChecktoseeiftheTrackMyWalks-iOSmainscreenis

//displayed.

Assert.IsTrue(mainScreen.Any(),navigationBarTitle

+"screenwasn'tshownaftersigningin.");

}

}

}

Intheprecedingcodesnippet,webeganbyimplementingthevariousinstancemethodsthatwillberequiredtoperformeachtestforourCreateNewWalkEntry.Weaddedthe[Test]attributetoourCreateNewWalkEntryinstancemethod.Thismethodwillessentiallybethemaintestdriverandcalleachoftheotherinstancemethodsthatwe'vepreviouslydeclared.Withinthismethod,wecallourSignInToFacebookmethodtoperformthesign-intoFacebook,usingtheuser'sFacebookcredentials.Uponsuccessfullogin,weusetheWaitForElementmethodtowaituntilthemainTrackMyWalksscreenhasbeendisplayed.

Inthenextstep,weusedtheTapmethodoftheAppclassinstance,andusetheMarkedmethodtofindtheAddelementwithintheApp'scurrentscreen,andwaituntiltheNewWalkEntrypageisdisplayedwithinthescreen.WethenproceedtousetheAssert.IsTruemethodtochecktoseeiftheNewWalkEntryscreenwassuccessfullydisplayed.Alternatively,ourtestwillfailanddisplaytheassignederrormessagewithintheTestResultsscreen.

Page 392: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

AddingtheXamarinTestCloudAgenttotheiOSprojectNowthatyouhavecreatedyourUITest,thenextstepistoaddtheXamarinTestCloudAgentNuGetpackagetoourTrackMyWalks.iOSproject.ThislibraryallowsyoutoexecuteyourXamarin.UITest,usingC#andtheNUnitframeworktovalidatethefunctionalityofiOSandAndroidappswithintheXamarinStudiodevelopmentenvironment.

Let'slookathowtoaddtheXamarinTestCloudNuGetpackagetoourTrackMyWalks.iOSproject,byperformingthefollowingsteps:

1. Right-clickonthePackagesfolderthatiscontainedwithintheTrackMyWalks.iOSproject,andchoosetheAddPackages...menuoption,asyoudidinthesectionentitled,AddingtheMoqNuGetpackagetotheunittestproject,locatedwithinthischapter.

2. ThiswilldisplaytheAddPackagesdialog.EnterinCloudAgentwithinthesearchdialog,andselecttheXamarinTestCloudAgentoptionwithinthelist,asshowninthefollowingscreenshot:

3. Finally,clickontheAddPackagebuttontoaddtheNuGetpackagetothePackagesfolder

Page 393: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

containedwithintheTrackMyWalks.iOSproject.

NowthatyouhaveaddedtheXamarinTestCloudAgentNuGetpackage,ournextstepistobeginbymodifyingtheAppDelegateclasswithintheTrackMyWalks.iOSportionofourproject.Wewillbecoveringthisinthenextsection.

Page 394: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

UpdatingtheTrackMyWalksAppDelegateclasstohandleXamarinTestCloudAgentPriortorunningUITestswithinXamarinStudio,wewillneedtoaddtheXamarinTestCloudAgentNuGetpackagetotheiOSportionofourTrackMyWalksapp.UnderAndroid,thisisnotrequiredastheXamarinTestCloudAgentisprovidedbytheUITestframework.

Inthissection,weneedtoupdatetheAppDelegateclass,bymodifyingtheFinishLaunchingmethodlocatedwithinourTrackMyWalks.iOSproject.ThiswillincludeacompilerdirectivethatwillstarttheXamarinTestCloudAgent.

Let'slookathowwecanachievethiswiththefollowingsteps:

1. OpentheAppDelegate.csfilelocatedwithintheTrackMyWalks.iOSproject.2. Next,ensurethattheAppDelegate.csfileisdisplayedwithinthecodeeditor,andlocate

theFinishLaunchingmethodandenterinthefollowinghighlightedcodesections:

//

//AppDelegate.cs

//TrackMyWalks

//

//CreatedbyStevenF.Danielon04/08/2016.

//Copyright©2016GENIESOFTSTUDIOS.Allrightsreserved.

//

usingFoundation;

usingUIKit;

namespaceTrackMyWalks.iOS

{

[Register("AppDelegate")]

publicpartialclassAppDelegate:global::Xamarin.Forms.

Platform.iOS.FormsApplicationDelegate

{

publicoverrideboolFinishedLaunching

(UIApplicationapp,NSDictionaryoptions)

{

global::Xamarin.Forms.Forms.Init();

//IntegrateXamarinFormsMaps

Xamarin.FormsMaps.Init();

#ifUSE_TEST_CLOUD

Xamarin.Calabash.Start();

#endif

LoadApplication(newApp());

returnbase.FinishedLaunching(app,options);

}

}

Page 395: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

}

Note

CalabashisbasicallyanAutomatedUIAcceptanceTestingframeworkthatallowsyoutowriteandexecuteteststhatvalidatethefunctionalityofyouriOSandAndroidapps.

Intheprecedingcodesnippet,youwillnoticethatwehavedefinedtheUSE_TEST_CLOUDcompilervariablethatiswrappedwithinthe#ifand#endifdirectiveandincludesacalltotheXamarin.Calabash.Start()methodthatwillonlybestartedwhenithasbeendefinedunderspecificconfigurationsasdefinedwithinthecompilerconfigurationsettingsfortheproject.

Note

IfyouareinterestedinlearningmoreabouttheCalabashframework,pleaserefertothesectiononanIntroductiontoCalabashwhichislocatedathttps://developer.xamarin.com/guides/testcloud/calabash/introduction-to-calabash/.

WehavejustaddedinthecodethatwillessentiallystartourXamarinTestCloudfunctionality.However,forthistowork,wewillneedtoperformoneadditionalstep,whichistomodifythecompilerconfigurationsforourTrackMyWalks.iOSproject.Performthefollowingtoachievethis:

1. Right-clickontheTrackMyWalks.iOSproject,andchoosetheOptionsmenuoption.2. Next,withintheProjectOptions-TrackMyWalks.iOSdialog,choosetheCompiler

optionlocatedundertheBuildsection.3. Then,ensurethatyouhavechosendebugfromtheConfigurationdropdownandthatyou

havechoseniPhoneSimulatorfromthePlatformdropdown.4. Next,addtheUSE_TEST_CLOUD;tothelistofexistingDefineSymbols,asshowninthe

followingscreenshot:

Page 396: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Then,clickonOKtosaveyourchangesandclosetheProjectOptions-TrackMyWalks.iOSdialog.

NowthatyouhavemodifiedthecompilerconfigurationsforouriOSportionoftheTrackMyWalksapp,wecanfinallybuildandrunourUITestsusingXamarinStudio,similarlytowhatwedidwhenexecutingourNUnittests.However,thisneedstobehandledverydifferently,andwewillbecoveringthisinthenextsection.

Page 397: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

RunningtheTrackMyWalksUITestsusingXamarinStudioPriortorunningyourUITestswithinXamarinStudio,youwillneedtoaddyouriOSorAndroidappstotheTestAppsnodeoftheUnitTestspane,oralternativelyspecifyingapathtoyourappwithintheAppInitializerclass.Ifyoudon'tdothis,yourtestswillcontinuetofailuntilyouaddtheseprojectstoyoursolution.

Inthissection,wewilllookathowtogoaboutaddingyourappstotheTestAppsnodewithintheUnitTestspane.Let'slookathowwecanachievethiswiththefollowingsteps:

1. ToaddyouriOSandAndroidappstoyourTrackMyWalks.UITestsproject,selecttheViewmenuoption,thenchoosethePadssub-menuitem,andthentheUnitTestsoption,asshowninthefollowingscreenshot:

2. Next,right-clickontheTestAppsitemwithintheUnitTestspaneandclickontheAddAppProject.ThiswilldisplaytheSelectaprojectorsolutiondialogthatallowsyoutoselecteachofyourprojectsforthevariousplatforms,asshowninthefollowingscreenshot:

Page 398: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. OnceyouhaveselectedtheprojectsthatyouwouldliketoaddtoyourTrackMyWalks.UITestssolution,clickOKanddismissthedialog.

Note

Ifforsomereason,youdon'tseeyouriOSappprojectlisted,youmayhaveforgottentoaddtheXamarinTestCloudAgentNuGetpackagetoyouriOSproject.

OnceyouhavesuccessfullyaddedyourprojectstotheTrackMyWalks.UITestssolutionproject,ournextstepistorunourappandseetheresults:

4. TorunyourUITests,selecttheRunmenuoption,thenchoosetheRunUnitTestsmenuitem,asshowninthefollowingscreenshot.

Page 399: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Whenyourappstartstorun,theUITestframeworkwillautomaticallydeployyourapptotheiOSorAndroidsimulator,andthenruntheappandprocessthrougheachofthestepsthatyouhavespecifiedwithinyourtestmethods.TheresultsfromeachofthetestswillappearwithintheTestResultspanewithinXamarinStudio.

Page 400: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,weupdatedtheTrackMyWalksapplicationbyaddinganewprojectsolution,TrackMyWalks.Tests,sothatwecanseparateourtestsfromthemainPortableClassLibrary.Thisgivesustheabilitytowritetestcases.WeaddedtheMockframeworksothatitwillprovideuswiththeabilitytosuccessfullytestourViewModelsaswellastoprovidethebusinesslogicbehindthem.

WethenmovedontoconsideringhowwecanleveragetheUITestframeworktowrite,test,andexecuteUItestslocallybyusingtheXamarinTestCloudAgentandtheCalabashframework,byaddingtheiOSandAndroidprojectstotheUITestsolutionproject.

Inthefinalchapter,you'lllearnhowtoprepareyouriOSappforsubmissiontoiTunesConnect,andlearnhowtosetupinternalandexternaluserswithinTestFlightsothatyouruserscandownloadandtestyourappsontheiriOSdevices.Toendthechapter,youwilllearnhowtocode-signyourAndroidappsbeforepublishing,andreleasingyourAndroidAPKfiletotheGooglePlayStore.

Page 401: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Chapter10.PackagingandDeployingYourXamarin.FormsApplicationsInourpreviouschapter,weupdatedourTrackMyWalksapplicationtoallowustocreateandrununittestsusingtheNUnitandUITesttestingframeworksrightwithintheXamarinStudioIDE.YoulearnedhowtowriteunittestsforourViewModelstotestthebusinesslogictovalidatethateverythingisworkingcorrectly,beforemovingontotestingtheuserinterfacesportionusingautomatedUItesting.

Inthischapter,you'lllookatwhatisrequiredtosubmityourTrackMyWalksiOSapptotheAppleAppStore,andshareyourcreationswiththerestofthecommunity.

You'lllearnthestepsrequiredtosetupyouriOSdevelopmentteam,aswellasthecertificatesforbothdevelopmentanddistribution,andlearnhowtocreatethenecessaryprovisioningprofilesforbothyourdevelopmentanddistributionbuilds,andcreatethenecessaryappIDsforyourapplication.

Attheendofthechapter,youwilllearnhowtoregisteryouriOSdevicessothatyouruserscandownloadandtestyourappsontheiriOSdevicesandlearnhowtoprepareyourTrackMyWalksiOSappforsubmissiontoiTunesConnect,usingtheXamarinStudioIDE.

Thischapterwillcoverthefollowingtopics:

SettingupyouriOSdevelopmentteamCreatingtheTrackMyWalksiOSdevelopmentcertificateObtainingthedevelopmentcertificatefromAppleRegisteringyouriOSdevicesfortestingCreatingyourTrackMyWalksiOSAppIDCreatingthedevelopmentprovisioningprofilesPreparingyourTrackMyWalksiOSappforsubmissionUsingtheprovisioningprofilestoinstalltheappontheiOSdeviceBuildingandarchivingyourappforpublishingusingXamarinStudioUsingXamarinStudiotosubmityourTrackMyWalksiOSapptoiTunesConnect

Page 402: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingandsettingupyouriOSdevelopmentteamYouhavefinallycompletedbuildingyourTrackMyWalksappandarereadytoreleaseittotherestoftheworld;allyouneedtodoisdecidehowtodeployandmarketit.BeforeyoucanbeginsubmittingyouriOSapplicationstotheAppleAppStoreforapproval,youwillneedtofirstsetupyouriOSdevelopmentteam,whichcanbeachievedbyfollowingthesesteps:

1. LogintotheiOSdeveloperportalwebsiteathttp://developer.apple.com/.2. ClickontheMemberCenterlinkthatislocatedrightatthetopofthescreen.3. SignintoyouraccountusingyourAppleIDandpassword.Thiswillthendisplaythe

developerprogramresourcespage,asshowninthefollowingscreenshot:

4. Next,clickontheiTunesConnectbutton,ashighlightedintheprecedingscreenshot.ThisiswhereyoucancheckonvariousthingssuchasSalesandTrends,PaymentsandFinancialReports,andAppAnalytics.Takealookatthefollowingimage:

Page 403: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Next,clickontheUsersandRolesbutton,ashighlightedintheprecedingscreenshot.ThiswillbringuptheUsersandRolesoptionpanefromwhereyoucanaddanewuser,asshowninthefollowingscreenshot:

Note

TheUsersandRolesscreenallowsyoutoaddyourselforthepeoplewithinyourorganizationwhowillbeabletologintotheiOSdeveloperprogramportal,testappsoniOSdevices,andaddadditionaliOSdevicestotheaccount.

6. EnsurethatyouarewithintheiTunesConnectUserssection,ashighlightedintheprecedingscreenshot.Then,clickonthe+buttontobringuptheAddNewUserscreenthatisshowninthefollowingscreenshot.

7. Next,fillintheUserInformationsectionforthepersonthatyouwillbeaddingtoyourdevelopmentteam.Onceyouhavefinished,clickontheNextbutton,asshowninthe

Page 404: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

followingscreenshot:

8. Next,undertheRolesection,fromthelistofrolesavailable,choosewhatrolestheusercanperformandthenclickontheNextbutton,asshowninthefollowingscreenshot:

Page 405: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

9. Next,fromundertheNotificationsandSettingssections,thisiswhereyouwillbeassigningthewaysinwhichyouwanttheusertobenotified.Fromthisscreen,youalsohavetheabilityofspecifyingwhatinformationrelatingtoalistofterritoriesyouwanttheusertobenotifiedabout,asshowninthefollowingscreenshot:

Page 406: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

10. Onceyouhavefinishedspecifyingeachofthedifferenttypesofnotificationmethods,clickontheSavebutton,asshownintheprecedingscreenshot.Thenewuseraccountwillthenbecreated,alongwithaconfirmatione-mailthatwillbesenttotheusers,accounts,requestingthemtoactivatetheiraccount:

Nowthatwehavecoveredthenecessarystepsrequiredtocreateandassignrolestonewusers,

Page 407: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

aswellassettingupwhichuserrolescanlogintotheiOSdeveloperportaltomanagenewandexistingusers,viewSalesandTrendsreports,aswellasPaymentsandFinancialstatements,ournextstepistolookatthestepsinvolvedtogenerateaniOSdevelopmentcertificate.

Thiscertificateisencryptedandservesthepurposeasyourdigitalidentificationsignature,andyoumustsignyourappsusingthiscertificatebeforeyoucansubmityourappstotheAppleAppStore.

Page 408: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheTrackMyWalksiOSdevelopmentcertificateInthissection,youwilllearnhowtocreatetheiOSdevelopmentcertificatethatwillenableustorunandtestourTrackMyWalksappontheiOSdevice.WewillbeginbygeneratingtheiOSdevelopmentcertificate,whichwillbeencryptedandwillservethepurposeofidentifyingyoudigitally.

YouwillthenneedtosignyourappsusingthiscertificatebeforeyoucanrunandtestanyapplicationthatyoudeveloponyouriOSdevice.Tobegin,performthefollowingsimplesteps:

1. LaunchtheKeychainAccessapplication,whichcanbefoundinthe/Applications/Utilitiesfolder.

2. Next,choosetheRequestaCertificateFromaCertificateAuthority...menuoptionfromtheKeychainAccess|CertificateAssistant,asshowninthefollowingscreenshot:

3. Then,weneedtoprovidesomeinformationbeforethecertificatecanbegeneratedundertheCertificateInformationsection.

4. Next,enterintherequiredinformation,asshowninthefollowingscreenshot,whilstensuringthatyouhaveselectedtheSavedtodiskandtheLetmespecifykeypairinformationoptions:

Page 409: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Oncealltheinformationhasbeenfilledout,clickontheContinuebutton.Youwillthenbeaskedtospecifyanameforthecertificate.Acceptthedefaultsuggestedname,andclickontheSavebutton.

Note

Atthispointthecertificateisbeingcreatedatthelocationspecified.YouwillthenbeaskedtospecifytheKeySizeandAlgorithmtouse.

6. Next,acceptthedefaultof2048bitsandRSAalgorithm.WeneedtoprovidesomeinformationbeforethecertificatecanbegeneratedundertheCertificateInformationsection,asshowninthefollowingscreenshot:

Page 410: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

7. ClickontheContinuebuttonandthenclickontheDonebuttonwhenthefinalscreenappears.

Upuntilnow,youlearnedhowtogenerateacertificaterequestforiOSdevelopment,usingtheCertificateSigningRequest(CSR)usingthepre-installedMacOSXKeychainAccessapplication,sothatwehavetheabilityofcode-signingourapplications,whichwillenableustodeployourapplicationstotheiOSdeviceforbothdevelopmentandtesting.

Inournextstep,wewilllearnhowtorequestadevelopmentcertificatefromApplethatwillprovideuswiththeabilityofcode-signingourapplicationsusingourgeneratedcertificateinformationfilethatwecreatedinthissection.

Page 411: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ObtainingtheiOSdevelopmentcertificatefromAppleInthissection,wewilllearnhowtoobtainthedevelopmentcertificatefromApple,toenableustobegindevelopingapps.

BeforeyoucanbeginsubmittingyourapplicationtotheAppleAppStore,youwillneedtoobtainyourowncopyoftheiOSdevelopmentcertificate.Thiscertificateisbasicallyyouruniqueidentityforeachofyourappsthatyousubmitforapproval,solet'sgetstarted:

1. LogintotheiOSdeveloperportalwebsiteathttp://developer.apple.com/.2. ClickontheMemberCenterlinkthatislocatedrightatthetopofthescreen.3. SignintoyouraccountusingyourAppleIDandpassword.Thiswillthendisplaythe

developerprogramresourcespage,asshowninthefollowingscreenshot:

4. Next,clickontheCertificates,Identifiers&Profilesbutton,ashighlightedintheprecedingscreenshot.

Page 412: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

5. Then,clickonthe+button,ashighlightedintheprecedingscreenshot.

Page 413: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Next,choosetheiOSAppDevelopmentoptionundertheDevelopmentsection,ashighlightedintheprecedingscreenshot,andclickontheContinuebuttontoproceedtothenextstep,asdisplayedfurtherdownthepage:

7. Then,clickontheContinuebutton,ashighlightedintheprecedingscreenshot,toproceedtothenextstep.

Page 414: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

8. Next,clickontheChooseFile...button,ashighlightedintheprecedingscreenshot.9. Then,selecttheCertificateSigningRequest.certSigningRequestfilethatyoucreated

intheprevioussectionsandclickontheContinuebuttontoproceedtothenextstepinthewizard.

10. Afterafewseconds,thepagewillrefreshandthecertificatewillbereadyandyouwillbeabletodownloadit.

Inthissection,weconsideredthestepsinvolvedinrequestingacertificatefromApplethatwillbeusedtoprovideuswiththeabilityofcode-signingourapplicationsrequiredtodeployontotheiOSdeviceandtheAppleAppStore.

Wethenmovedontolearnhowtousethegeneratedcertificaterequestfilethatwecreatedinourprevioussection,CreatingtheTrackMyWalksiOSdevelopmentcertificate,togeneratethedevelopmentcertificate.

Page 415: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheAppIDfortheTrackMyWalks(iOS)applicationInprevioussections,wehavelearnedhowtorequestacertificatefromAppletoprovideuswiththeabilityofcode-signingourapplications,aswellaslearninghowtousethegeneratedcertificaterequestfiletogenerateourdeploymentcertificate.

Inthissection,wewillbelookingathowtocreatetheapplicationAppIDssothatwecanusethesetodeployourapplicationstotestonaniOSdevice:

1. LogintotheiOSdeveloperportalwebsiteathttp://developer.apple.com/.2. ClickontheMemberCenterlinkthatislocatedrightatthetopofthescreen.3. SignintoyouraccountusingyourAppleIDandpassword.Thiswillthendisplaythe

developerprogramresourcespage,asshowninthefollowingscreenshot:

4. Next,clickontheCertificates,Identifiers&Profilesbutton,ashighlightedintheprecedingscreenshot.

5. Then,clickontheAppIDsitemlocatedunderneaththeIdentifiersgroupattheleft-handsideofthepageandclickonthe+buttontodisplaytheRegisteriOSAppIDssection,ashighlightedinthefollowingscreenshot:

Page 416: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Next,provideadescriptionfortheAppIDDescriptionfieldthatwillbeusedtoidentifyyourapp,asshownintheprecedingscreenshot.

7. Then,provideanamefortheBundleIDfield.Thisneedstobethesameasyourapplication'sbundleidentifier.

Note

TheBundleIDforyourappneedstobeunique.Applerecommendsthatyouusethereversedomainstyle(forexample,com.domainName.appName).

Considerthefollowingscreenshot:

Page 417: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

8. Next,choosefromthelistofAppServicesthatyouwouldliketoenableforyourapp,andthenclickontheContinuebutton,asshowninthefollowingscreenshot:

Page 418: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

9. Then,fromtheConfirmyourAppIDscreen,clickontheRegisterbutton.

Inthissection,wecoveredthenecessarystepsrequiredtocreatetheAppIDforourapplication.CreationofAppIDsarerequiredforeachapplicationthatyoucreateandmustcontainauniqueapplicationIDthatidentifiesitself.TheAppIDispartoftheprovisioningprofileandidentifiesanApporasuiteofrelatedapplications.

TheseareusedwhenyourapplicationscommunicatewiththeiOShardwareaccessories,theApplePushNotificationService(APNS),andwhensharingofdatahappensbetweeneachofyourapplications.

Page 419: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

CreatingtheTrackMyWalksdevelopmentprovisioningprofileInthissection,wewilllearnhowtocreatethedevelopmentprovisioningprofilessothatyourapplicationscanbeinstalledontheiOSdevicesothatyoucandeployandtestyourapplicationspriortodeployingyourapptotheAppleAppStore:

1. LogbackintotheiOSdeveloperportalathttp://developer.apple.com/.2. ClickontheMemberCenterlinkthatislocatedrightatthetopofthescreen.3. SignintoyouraccountusingyourAppleIDandpassword.Thiswillthendisplaythe

developerprogramresourcespage,asshowninthefollowingscreenshot:

4. Next,clickontheCertificates,Identifiers&Profilesbutton,asdonepreviously.5. Then,clickontheAllitemlocatedundertheProvisioningProfilessectionlocatedatthe

left-handsideofthepage.6. Next,clickonthe+buttontodisplaytheAddiOSProvisioningProfilessection,as

highlightedinthefollowingscreenshot:

Page 420: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

7. Then,choosetheiOSAppDevelopmentoptionfromtheDevelopmentsection,andthenclickontheContinuebuttontoproceedtothenextstep,asshownintheprecedingscreenshot.

Page 421: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

8. Next,selectyourAppIDfromthedrop-downlistavailable,asshownintheprecedingscreenshot,andclickontheContinuebuttontoproceedtothenextstepinthewizard:

Page 422: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

9. Then,chooseyourcertificatefromthelistofavailablecertificatesthatyouwouldliketoincludetobepartoftheProvisioningProfiles,andclickontheContinuebuttontoproceedtothenextstep,asshownintheprecedingscreenshot.

Page 423: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

10. Next,choosefromthelistofdevicesthatyouwouldliketoincludeaspartoftheProvisioningProfilesthatyouareabouttocreate,andclickontheContinuebuttontoproceedtothenextstep,asshownintheprecedingscreenshot.

Note

FormoreinformationabouthowtoregisteriOSdevicesusingtheMemberCenter,pleaserefertotheAppledistributionguidedocumentationusingthefollowinglink:https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingProfiles/MaintainingProfiles.html#//apple_ref/doc/uid/TP40012582-CH30-SW10.

Page 424: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

11. Then,specifyanamefortheProfileNamefieldtobeusedtoidentifytheprovisioningprofilewithintheiOSdeveloperportal,andclickontheContinuebuttontoproceedtothenextstep,asshownintheprecedingscreenshot.

Page 425: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

12. Finally,yourprovisioningprofilehasbeencreatedandisreadytobeused.YoucanchoosetoDownloadyourprovisioningprofilefromhere,oryoucanletXcodehandlethisforyou,whichwewillbecoveringinthenextsections.

13. Toclosethisscreen,andtakeyoubacktothelistofProvisioningProfiles,clickontheDonebutton,asshownintheprecedingscreenshot.

Inthissection,welearnedhowtocreateaprovisioningprofilethatwillallowyourapplicationstobeinstalledontoarealiOSdevice.Thiswillgiveyoutheabilitytoassignteammemberswhoareauthorizedtoinstallandtestanapplicationontoeachoftheirdevices.

Note

WheneveryoudeployanapplicationontoaniOSdevice,thiswillcontaintheiOSdevelopmentcertificateforeachteammember,aswellastheUniqueDeviceIdentifier(UDID),whichisa

Page 426: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

sequenceof40lettersandnumbersthatarespecifictoyourdevice,andtheAppid.

Page 427: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

PreparingtheTrackMyWalks(iOS)appforsubmissionNowthatyouhavetestedyourapplicationtoensurethateverythingworksfineandisfreefromerrors,youwillwanttostartpreparingyourapplicationsothatitisreadyforsubmissiontotheAppleAppStore.

Inthissection,wewillneedtouseXcodeandsigninwithourAppleIDsothatwecandownloadourprovisioningprofilesforbothdevelopmentanddistribution.ThisismainlysinceXamarinStudiousesXcodetoperformitscompilation,andifwedon'tsetthisup,wewon'tbeabletosubmitourTrackMyWalksiOSapptotheAppStoreandiTunesConnect.

TobeginpreparingyourapplicationusingXcode,followthesesimplesteps:

1. EnsurethatyouhavelaunchedtheXcodedevelopmentIDEanditisdisplayed.2. Next,choosethePreferences...menuoptionfromtheXcode|Preferences...menu,or

alternativelypresscommand+,asshowninthefollowingscreenshot:

Page 428: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

3. Next,ensurethattheAccountsbuttonhasbeenselected,thenclickonthe+button,andchoosetheAddAppleID...menuoption,asshownintheprecedingscreenshot.

4. Then,enterinyourAppleDevelopercredentialsbyspecifyingboththeAppleIDandPassword,ascanbeseenintheprecedingscreenshot.

Note

OnceXcodehasvalidatedyourApplecredentials,youwillbepresentedwithascreenliketheoneshownintheprecedingscreenshot.Thisscreenshowsyoutheteamthatyoubelongto,aswellasyourrolewithintheteam.YoucanalsoaddmultipleAppleIDstothisscreen.

NowthatwehavesetupourXcodedevelopmentIDEtouseouriOSdevelopmentanddistributionprovisioningprofiles,ournextstepistocreateanentryforourapplicationwithiniTunesConnect.

Page 429: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ThisissothatwhenwebegintosubmitourappusingXamarinStudioandtheApplicationLoaderapplicationtotheAppleAppStoreusingiTunesConnect,wewon'trunintoanyissues:

1. LogbackintotheiOSdeveloperportalathttp://developer.apple.com/.2. ClickontheMemberCenterlinkthatislocatedrightatthetopofthescreen.3. SignintoyouraccountusingyourAppleIDandpassword.Thiswillthendisplaythe

developerprogramresourcespage.4. Next,clickontheMyAppsbutton,asshowninthefollowingscreenshot:

5. Then,clickonthe+buttonandthenchoosetheNewAppmenuoption,asshowninthefollowingscreenshot:

Page 430: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Next,proceedtoenterintheapplicationdetailsfortheapplicationthatweareuploading.TheSKUnumberfieldisauniqueidentifierthatyoucreateforyourapp:

Page 431: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Note

TheBundleIDsuffixthatyouprovidemustmatchthesameonethatyouusedwithinyourTrackMyWalks.iOSapp'sinfo.plist;otherwise,youwillrunintoissueswhensubmittingyourappstotheAppStoreandiTunesConnect.

7. Then,clickontheCreatebuttontocreateyourappandproceedtothenextstep.8. Next,choosethePricingandAvailabilitymenuoption,locatedunderneaththeAPPSTORE

INFORMATIONsection,ontheleft-handsidepanel.9. Then,fromthePricingandAvailabilitysection,specifythevaluesforourPriceSchedule

aswellastheStartDateandEndDateforourapplication.Thiswilldeterminewhenourapplicationwillbemadeavailablefordownload,asshowninthefollowingscreenshot:

Page 432: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

10. Next,clickontheSavebuttontosaveanychangesmadewithinthisscreen.

Therearemorethan100pricingtierstochoosefrom,includinganoptionforsellingyourapplicationforfree.

Inthissection,welearnedthestepsinvolvedinpreparingourapplicationforsubmissiontotheAppleAppStoreusingiTunesConnect.Wealsolearnedthatbeforesubmittingourappsforapproval,youmustensurethateverythingworksproperly,andisfreefromproblems,andtheiOSsimulatorisagoodplacetostart.

Although,noteverythingcanbetestedwithintheiOSsimulator,itprovesagoodstartingpoint.ApplesuggeststhatyoushouldalwaysdeployyourappstoarealiOSdevicerunningthelatestiOSrelease,sothatyoucantestyourappforafewdaystoensurethatallissuesareironedout,priortosubmittingyourapptotheAppleAppStore.Next,welookedathowtocreateanewapplicationIDfortheapplicationthatwillbeuploadedtotheAppleAppStore,aswellasprovidingdetailedinformationabouttheapplication,andspecifyingadatewhentheapplicationwillbecomeavailable.

Page 433: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Note

FormoreinformationonhowtogoaboutsubmittingandmanagingyourappsusingiTunesConnect,youcanrefertothefollowinglinkatthislocation:https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/UsingiTunesConnect/UsingiTunesConnect.html#//apple_ref/doc/uid/TP40012582-CH22-SW3.

Page 434: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SubmittingtheTrackMyWalks(iOS)apptoiTunesConnectusingXamarinStudioIntheprevioussection,webeganbycreatingtheTrackMyWalksAppwithiniTunesConnectandlearnedthatbeforesubmittingappsforapproval,youmustensurethateverythingisworkingproperly,andisfreefromproblems.

Inthissection,wewillbegingettingourTrackMyWalks.iOSappreadyforsubmissiontotheAppleAppStore,usingXamarinStudioIDE.

Tobeginsubmittingyourapplication,followthesesimplesteps:

1. EnsurethattheTrackMyWalks.slnprojectisalreadyopenwithinXamarinStudioIDE.2. Next,right-clickontheTrackMyWalks.iOSproject,choosetheOptionsmenuoption,and

choosetheiOSBundleSigninglocatedundertheBuildsectionwithintheleftpane.3. Then,withintheiOSBundleSigningsection,chooseReleasefortheConfigurationand

iPhoneforthePlatformandensurethatyouhavechosentheDistribution(Automatic)optionwithintheSigningIdentitydropdownthatwillbeusedtosignourTrackMyWalksappwith.

4. Next,ensurethatyouhavechosentheAutomaticoptiontouseforourProvisioningProfile,andclickontheOKbuttontosavethesettingsanddismisstheProjectOptions-TrackMyWalks.iOSdialog.

Page 435: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Note

YouriOSprovisioningcertificatewillbeshowninbold,withyourprovisioningprofileingray.Ifyoudon'timportavalidprovisioningcertificate,youwon'tbeabletodeployoruploadyourTrackMyWalksiOSapplicationtotheAppleAppStore.

5. Then,ensurethatyouhavechosenRelease|iPhonetouseastheiOSdevicepriortochoosingtheArchiveforPublishingoptionwithintheBuildmenu,asshowninthefollowingscreenshot:

Page 436: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

6. Next,provideacommentforyourapplication,byclickingwithintheCommentfield,andthenclickontheSignandDistribute...buttontohaveXamarinsignandprepareyourappforsubmission,asshowninthefollowingscreenshot:

Note

OnceyouclickontheSignandDistribute...button,youwillbepresentedwiththeSelect

Page 437: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

iOSDistributionChanneldialog,whereyoucanchooseyourdistributionchanneltocreateapackageforyourapp.

7. Then,sincewewanttopublishourTrackMyWalksapptotheAppStore,choosetheAppStoreoptionwithinthelistandclickontheNextbuttontoproceedtothenextstepwithinthewizard,asshowninthefollowingscreenshot:

8. Next,youwillbepresentedwiththeProvisioningprofilescreenwhereyoucanselectyoursigningidentityandprovisioningprofile,orre-signusingadifferentidentity.ClickontheNextbuttontoproceedtothenextstepwithinthewizard,asshowninthefollowingscreenshot.

Page 438: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

9. UponclickingontheNextbutton,XamarinStudiowillproceedtocollectallthenecessaryfiles,andcreateaTrackMyWalks.ipafilewhich,bydefault,willbesavedwithinyourTrackMyWalksfolder.

10. YouwillbepresentedwiththePublishtoAppStoredialog,whereyouwillbepresentedwiththeabilityofpublishingyourapptotheappstore,asshowninthefollowingscreenshot:

Page 439: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

11. Then,clickonthePublishbuttontoproceedtothenextstepwithinthewizardwhereyoucanthenuploadyourbinaryarchive.

Page 440: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

12. OnceyouhaveclickedonthePublishbutton,andeverythingpasses,youwillbepresentedwiththePublishingSucceededdialogwhereyoucanbeginuploadingyourbinaryarchivebyclickingontheOpenApplicationLoaderbutton,ascanbeseenintheprecedingscreenshot.

Note

FormoreinformationonhowtogoaboutdeployingyourXamarin.FormsAndroidapp,pleaserefertothesectiononPreparinganApplicationforReleaseatthefollowinglink:https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/publishing_an_application/part_1_-_preparing_an_application_for_release/.

Page 441: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

ThiswillthenlaunchtheApplicationLoaderapplication,asshowninthefollowingscreenshot,whereyouwillneedtosign-intoiTunesConnectusingyouriTunesConnectcredentials.

13. Next,choosetheDeliverYourAppoptionandclickontheChoosebutton,asshowninthefollowingscreenshot:

14. OnceyouhaveclickedontheChoosebutton,youwillbepresentedwiththeDeliverYourAppdialogwhereyouwillneedtochoosetheTrackMyWalks.ipafilethatwasgeneratedduringtheSignandDistributeprocesswithintheSubmittingtheTrackMyWalks(iOS)apptoiTunesConnectusingXamarinStudiosectionlocatedwithinthischapter.

Page 442: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

15. Then,selectandchoosetheTrackMyWalks.ipafile,andclickontheOpenbutton,asshownintheprecedingscreenshot.

Page 443: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

TheApplicationLoaderwillreadtheinformationcontainedwithintheTrackMyWalks.ipabinaryfile,populatedfromiTunesConnect,anddisplaytheApplicationname,VersionNumber,SKUNumber,PrimaryLanguage,Type,andtheuser'sAppleID,asshownintheprecedingscreenshot.

16. Next,clickontheNextbuttontoproceedtothenextstepwithinthewizard,asshownintheprecedingscreenshot.

Page 444: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

Intheprecedingscreenshot,theApplicationLoaderapplicationwillbeginbyauthenticatingyourappwiththeAppleAppStoreandiTunesConnect,andthenvalidatingtoensurethateverythingpasses,atwhichpointyourbinaryarchivewillbeginuploading.

Note

ForinformationonhowtousetheApplicationLoadertopublishyourXamarin.iOSapps,youcanrefertoPublishingtotheAppStoreGuidefromtheXamarindeveloperdocumentation,whichcanbeaccessedbyusingthefollowinglink:https://developer.xamarin.com/guides/ios/deployment,_testing,_and_metrics/app_distribution/app-store-distribution/publishing_to_the_app_store/.

Page 445: Mastering Xamarin UI Developmentsd.blackball.lv/library/Mastering_Xamarin_UI_Development... · 2017-07-29 · Xamarin Studio and the Mono Platform to provide developers with the tools

SummaryInthischapter,youlearnedhowtocreateandsetupyouriOSdevelopmentteamandtheassociatediOSdevelopmentcertificatethatwillenableyoutorunandtestyourappsonaniOSdevice.WethenmovedontodescribehowtocreateanAppIDforourTrackMyWalksapp.

ThesespecialAppIDsareusedbothwithinXamarinandXcodetoassociateyourappwiththeoneassignedaspartofyouriOSprovisioningprofiles.Oncewecreatedallthenecessarydevelopmentcertificatesandprovisioningprofiles,youlearnedhowtopackage,sign,anddistributeyourappusingXamarinStudioIDE,anddeployittoiTunesConnectusingtheApplicationLoaderapplication,whereyoucanthendownloadandtestyourapponarealiOSdevice.

Thiswasthefinalchapter,andIsincerelyhopethatyouhadlotsoffundevelopingappsthroughoutourjourneyworkingthroughthisbook.YounowhaveenoughknowledgeandexpertisetounderstandwhatittakestobuildrichandengagingappsfortheXamarin.Formsplatform,byusingahostofexcitingconceptsandtechniquesthatareuniquetotheXamarin.Formsplatform.

YouhaveenoughknowledgetogetyourXamarin.Formsprojectsofftoagreatstart,andIcan'twaittoseewhatyoubuild.ThankyousomuchforpurchasingthisbookandIwishyoutheverybestofluckwithyourXamarin.Formsadventures.