Download pdf - SAP Fiori Mobile (v2.6.x)

Transcript
Page 1: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 1/22

SAPFioriMobile(v2.6.x)

Introduct ion

Whatarehybridmobileapps?

Hybridmobileappsarewebapplicationswrappeduptheirownbrowserwhichcanrunonanyofthemobileplatforms(Android,iOS,Windowsetc.).Thebigadvantageofahybridappisthatithasasinglecodebase,whereasanativeappmustbere-writtenforeachplatform.

ApacheCordovaisanopen-sourceframeworkfordevelopinghybridapps.Tousenativefeatures(beyondthosealreadyavailableviahmtl5,)appscanmakeuseofplugins.Thesepluginshandletheplatform-specificcodeandareavailableforsingleormultipleplatforms.PluginsareavailabletoaccesstheGPS,accelerometerorcamera,forexample.

SAPhavewrittentheirownplugins,brandedasKapsel,tohandlethingslikelogonandofflineOData.Thesebringanenterpriseflavourtohybridapps.

WhatisFioriMobile?

UntilrecentlySAP’srecommendedapproachwastousetheHybridApplicationToolkit(orHAT)inordertobuildhybridapps.Theappbuildtookplaceonthedeveloper’sPCorMac.TheHATgainedareputationforbeingtrickytosetupandthathinderedtheuseofhybridappswithintheSAPecosystem.

FioriMobilehasat it scoreacloud-buildservice,sothereisnoneedtoinstalltheHAT.WecantriggerthebuildfromWebIDE.Wespecifythe(alreadydeployed)Fioriapp(s)thatwewanttopackageandafterafewminuteswecandownloadthe.apk(forAndroid)and.ipa(foriOS)filesreadytobeinstalledonmobiledevices.

Doesit work?

Thecloudbuildserviceworkswell.Ittypicallybuildforbothplatformsinabout8minuteswithoutissueas.Therehaveonlybeenacoupleofoccasionswhenbuildsfailedduetotechnicalproblems.

Therearesomefacetstothetechnologywhichdon’tfeelmatureyet.OneareaistheofflineODatafeatures.WhenusingFioriMobilethingsworkdifferentlytothemoreconventionalhybridandnativeapps.Oneexamplewouldbethedestinations,becauseFioriMobileappsuseagenerateddestinationwhichreferencetheSAPCloudPlatform(CP)portalservice.

Page 2: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 2/22

MypointisnotthatofflineODataseemsimmature,ratherthattheofflinefeaturescanbetrickywhenusedwithFioriMobileapps.WearestillreceivingassistancefromSAPtogettheofflinefeaturesofourappoptimised.Thisisashame,becauseshareddataandthehandlingofdeltarequests,forexample,aretwofeatureswhichjustifythe‘middleware’approachtoofflinethatSAPhavetaken.

Authenticationhasalsobeenachallenge.OnapreviousprojectIusedtheFioriClientinconjunctionwithSAPCloudIdentity(nowofficiallySAPCloudPlatformIdentityAuthentication).TheFioriClientstoredtheusernameandpasswordonthedevicesothattheuserdidn’tneedtoenterthemeverytimetheirsessiontimedout.Wehaven’tachievedthatyetwithourFioriMobileapp.

Account andServices

SignupforafreeaccountfortheSAPHanaCloudPlatform,andactivateyouaccountfromyourmailactivationlinkthatyoureceive.OnceyouhaveactivatedyouraccountbrowseonHCPCockpit.ChooseTrialRegionandopenyourPersonalTrialAccount.

Page 3: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 3/22

TocreateFioriMobileApplicationyouwillneedtousePortal,SAPWebIDEandFioriMobileservices.

Page 4: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 4/22

GoinServicestabfindtheseservicesandenablethemiftheyaredisabled.

CreateFioriLaunchpad

TocreateFioriApplicationweneedtocreateandpublishtheSitewhereapplicationwillbedeployed.

Page 5: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 5/22

GotoPortalServiceandclickGotoService.

Inyourbrowseranewtabwillbeopened.InthisnewwindowgototheSiteDirectorytab,andclickonCreateSite.

Apopupwillbedisplayed.EnteryourSiteName,chooseSAPFioriLaunchpadasTemplateSourceandclickCreate

Page 6: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 6/22

FollowingthisyouwillberedirectedtoSAPFioriConfigurationCockpit.ClosethetabandgobacktoAdminSpaceforPortalService.

NowweneedtoPublishthisSiteandSetasdefault.

Page 7: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 7/22

CreateFioriProject

OncewecreateandpublishtheSitewecancreateourFioriproject.

GotoServicestabagain,openSAPWebIDEservice,andclickonGotoService

Page 8: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 8/22

Anewtabwillbeopened.FromherewewillstarttocreateourFioriproject.

ClickonNewProjectfromTemplate

ChooseSAPUI5ApplicationfromTemplateSelection

Page 9: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 9/22

SetyourProjectName

ChoosetheViewTypeandsettheViewName.InoursamplewewilluseXMLView.ClickFinishandyourFioriprojectiscreated.

Page 10: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 10/22

HowtousecmbSDKcordovaplugin

IntheSAPWebIDEWorkspacewecanseeallfilesthatourFioriprojectinludes.

OpenComponent.jsfile .

Component.jsisthefirstpointofourapplication,wecansaythatitservesasindexwhichencapsulatesallourapplicationsdetails,i.e .viewnames,routingdetails,mainview,applicationstype(FullScreenorSplitApp),applicationserviceconfigurationetc..

Hereininit functionwewillconfigureourplugin.Setpropertiesthatweneed,setcallbackfunctions,callsomemethods,etc..

sap.ui.define(["sap/ui/core/UIComponent","sap/ui/Device","MyFristFioriApp/model/models"],function(UIComponent,Device,models){"usestrict";

varoEventBus=sap.ui.getCore().getEventBus();varscannerIsInitialized=false;

returnUIComponent.extend("MyFristFioriApp.Component",{

metadata:{manifest:"json"},

/***ThecomponentisinitializedbyUI5automaticallyduringthestartupoftheappandcallstheinitmethodonce.*@public*@override*/init:function(){//callthebasecomponent'sinitfunctionUIComponent.prototype.init.apply(this,arguments);

//setthedevicemodelthis.setModel(models.createDeviceModel(),"device");

Page 11: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 11/22

if(!scannerIsInitialized){

scannerIsInitialized=true;

window.readerConnected=0;window.scannerActive=false;

cmbScanner.addOnResume(function(result){

cmbScanner.setAvailabilityCallback((readerAvailability)=>{if(readerAvailability===cmbScanner.CONSTANTS.AVAILABILITY_AVAILABLE){oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"AVAILABLE"});

cmbScanner.connect((result)=>{

});

}else{oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"NOTAVAILABLE"});}});

if(Device.os.android){cmbScanner.connect((result)=>{

});}});

cmbScanner.addOnPause(function(result){

if(Device.os.android){cmbScanner.disconnect();}cmbScanner.setAvailabilityCallback();});

cmbScanner.setPreviewContainerPositionAndSize(0,0,100,50);

cmbScanner.setConnectionStateDidChangeOfReaderCallback((connectionState)=>{

if(connectionState===cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED){

oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"CONNECTED"});

if(window.readerConnected!=connectionState){cmbScanner.setSymbologyEnabled("SYMBOL.DATAMATRIX",true);cmbScanner.setSymbologyEnabled("SYMBOL.C128",true);cmbScanner.sendCommand("SETTRIGGER.TYPE2");}

varsdkKEY="";if(Device.os.android)sdkKEY=this.getModel("i18n").getProperty("MX_MOBILE_LICENSE_ANDROID");else

Page 12: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 12/22

sdkKEY=this.getModel("i18n").getProperty("MX_MOBILE_LICENSE_iOS");

cmbScanner.registerSDK(sdkKEY,(res)=>{switch(res){casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_OK:

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_KEY:

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_CHECKSUM:

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_APPLICATION:

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_SDK_VERSION:

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_KEY_VERSION:

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_PLATFORM:

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_KEY_EXPIRED:

break;default:break;}});

}elseif(connectionState==cmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTED){oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"DISCONNECTED"});}elseif(connectionState==cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTING){oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"CONNECTING"});}elseif(connectionState==cmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTING){oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"DISCONNECTING"});}

window.readerConnected=connectionState;});

cmbScanner.setAvailabilityCallback((readerAvailability)=>{if(readerAvailability===cmbScanner.CONSTANTS.AVAILABILITY_AVAILABLE){oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"AVAILABLE"});

cmbScanner.connect((result)=>{

});

}else{

Page 13: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 13/22

oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"NOTAVAILABLE"});}});

cmbScanner.setActiveStartScanningCallback((result)=>{window.scannerActive=result;});

cmbScanner.setPreviewOptions(cmbScanner.CONSTANTS.PREVIEW_OPTIONS.DEFAULTS|cmbScanner.CONSTANTS.PREVIEW_OPTIONS.HARDWARE_TRIGGER);cmbScanner.setCameraMode(cmbScanner.CONSTANTS.CAMERA_MODES.NO_AIMER);

cmbScanner.loadScanner(0,(result)=>{cmbScanner.connect((result)=>{

});});

oEventBus.subscribe("Component","LoadScanner",this.loadScanner,this);}},

loadScanner:function(sChanel,sEvent,oData){

cmbScanner.disconnect((result)=>{cmbScanner.loadScanner(oData.selectedDevice,(result)=>{cmbScanner.connect((result)=>{

});});});},

onExit:function(){

oEventBus.unsubscribe("Component","LoadScanner",this.loadScanner,this);

cmbScanner.disconnect();cmbScanner.setAvailabilityCallback();}});});

cmbScannerisanobjectthatrepresentsourplugin.WiththisobjectwecanaccessallAPImethodsandConstantsfromourplugin.

scannerIsInit ialized-variabletomakesurethatwesetsomefunctionsforinitializationonlyonetimewindow.readerConnected-globalvariablethatischangedeverytimewhenthereaderconnectionstateischangedwindow.scannerAct ive-globalvariablethatshowsusifscanningisactiveornotcmbScanner.addOnPause-inthismethodwedisconnectionfromreaderdeviceonAndroid(oniOSthisishandledautomatically),andstoplisteningtoavailabilitychanging

Page 14: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 14/22

cmbScanner.addOnResume-inthismethodwetrytoconnectwithreaderdeviceagainandsetcallbackforavailabilitychangingcmbScanner.setPreviewContainerPosit ionAndSize-tosetthesizeandpositionofthepreviewcontainer.Learnmorehere.cmbScanner.setConnect ionStateDidChangeOfReaderCallback-allconnect /disconnect eventsshouldbehandledwithinthecallbackfunctionsetwiththisAPImethod.IfconnectionstateisconnectedwesetsomereaderdevicesettingswithAPImethodsordirectlywithsendCommand()method.Hereinthisexampleweenablesymbologiesandsettriggertype.AlsohereweshouldLicensingtheSDK.WewillspeakaboutthislaterinthissectioncmbScanner.setAvailabilit yCallback-tomonitorforavailabilityoftheMXdevice.IfMXdeviceisavailablewetrytoconnect.Learnmorehere.cmbScanner.setAct iveStartScanningCallback-tomonitorthestateofthescanner.Learnmorehere.cmbScanner.loadScanner-togetascannerupandrunning.Learnmorehere.

Hereweareonlyconfiguringreaderdevice,handlingconnections,availability,etc..Wewilldoscanningandgettingresultsinotherviews.IfwewanttonotifyusersabouteveryconnectionstatechangedorotherinfoaboutreaderdevicewewillbeusingEventBussapobject.Withthisobjectwecanpublishfunctionandcallthemfromanyviewintheapplication.InthisexampleonconnectionstatechangedwithEventBuswearecallingSetConnect ionStatusfunctionthatisimplementedinviewwherescanningisperformedandsetlabeltexttoshowusercurrentconnectionstate.

NowopenScanView.view.xmlandaddthiscode:

<mvc:Viewxmlns:mvc="sap.ui.core.mvc"xmlns:html="http://www.w3.org/1999/xhtml"xmlns:core="sap.ui.core"controllerName="MyFristFioriApp.controller.ScanView"displayBlock="true"><Appxmlns="sap.m"><pages><Pagetitle="MWBCameraDemo"showHeader="false"><subHeader><Toolbarid="__toolbar2"width="100%"><content><FlexBoxid="__box0"width="100%"alignContent="Center"alignItems="Start"direction="Column"fitContainer="true"justifyContent="Center"><items><Selectid="selectActiveDevice"items="{/Devices}"textAlign="Center"selectedKey="0"change="activeDeviceChanged"><core:Itemtext="{text}"key="{key}"/></Select></items></FlexBox><Labelid="lblStatus"text="DISCONNECTED"width="100%"textAlign="End"design="Bold"/></content></Toolbar></subHeader><content><FlexBoxid="flexBoxContainer"width="100%"alignContent="Start"alignItems="Start"direction="Column"fitContainer="true"/></content><footer><Toolbarid="__toolbar1"width="100%">

Page 15: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 15/22

<content><Buttonid="btnScan"press="btnScanPress"text="Scan"width="100%"/></content></Toolbar></footer></Page></pages></App></mvc:View>

YoucandesignviewwithCodeEditororwithLayoutEditor.

AfterthatopenScanView.cont roller.jsandaddthiscode

sap.ui.define(["sap/ui/core/mvc/Controller"],function(Controller){"usestrict";

varoEventBus=sap.ui.getCore().getEventBus();

varoModel=newsap.ui.model.json.JSONModel();

oModel.setData({Devices:[{key:"0",text:"MXDevice"

Page 16: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 16/22

},{key:"1",text:"MobileCamera"}]});

returnController.extend("MyFristFioriApp.controller.ScanView",{

onInit:function(){

this.getView().setModel(oModel);},

onAfterRendering:function(){

window.scannerActive=false;

switch(window.readerConnected){casecmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED:this.getView().byId("lblStatus").setText("CONNECTED");break;casecmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTED:this.getView().byId("lblStatus").setText("DISCONNECTED");break;casecmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTING:this.getView().byId("lblStatus").setText("CONNECTING");break;casecmbScanner.CONSTANTS.CONNECTION_STATE_DISCONNECTING:this.getView().byId("lblStatus").setText("DISCONNECTING");breakdefault:this.getView().byId("lblStatus").setText("UNKNOWN");break;}

oEventBus.subscribe("ScanView","SetConnectionStatus",this.setConnectionStatus,this);

cmbScanner.setResultCallback((result)=>{if(result&&result.readString){

varverticalLayoutContainer=newsap.ui.layout.VerticalLayout(null,{width:"100%"}).addStyleClass("sapUiSmallMarginTop");

verticalLayoutContainer.addContent(newsap.m.Label({text:result.symbologyString+":",textAlign:"Begin",design:"Bold"}).addStyleClass("sapUiSmallMarginBegin"));verticalLayoutContainer.addContent(newsap.m.Text({text:result.readString,textAlign:"Begin"}).addStyleClass("sapUiSmallMarginBegin"));

this.getView().byId("flexBoxContainer").addItem(verticalLayoutContainer);}});},

btnScanPress:function(){

Page 17: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 17/22

if(window.readerConnected===cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED){if(window.scannerActive===true){cmbScanner.stopScanning();}else{cmbScanner.startScanning();}}},

setConnectionStatus:function(sChanel,sEvent,oData){this.getView().byId("lblStatus").setText(oData.statusText);},

activeDeviceChanged:function(){cmbScanner.disconnect((result)=>{oEventBus.publish("Component","LoadScanner",{selectedDevice:parseInt(this.getView().byId("selectActiveDevice").getSelectedKey())});});},

onExit:function(){

oEventBus.unsubscribe("ScanView","SetConnectionStatus",this.setConnectionStatus,this);

if(window.readerConnected===cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED){if(window.scannerActive===true){cmbScanner.stopScanning();}}

cmbScanner.setResultCallback((result)=>{returnfalse;});}

});});

InthisviewwehaveaScanbuttontostartScanning()/stopScanning()andcmbScanner.setResultCallbacktohandlesuccessfulscanresults.

DeployapptoHCP

AfterwefinishcreatinganddevelopingourFioriprojectweneedtoprepareformobiledeployment.

FirstweneedtodeployourprojectonSAPHANACloudPlatform.

RightclickonprojectfolderthenselectDeployandchooseDeploytoSAPHANACloudPlatform

Page 18: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 18/22

SetapplicationdetailsandclickDeploy

Afterasuccessfuldeploy,thenextstepistoRegistertoSAPFiorilaunchpadthatwe'vecreatedintheprevioussection.

Page 19: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 19/22

Chooseaccountandsetapplicationname.

SetType(Staticbydefault),setTitle,andSubtitle.

ChooseSitethatwecreatebefore,catalog,andgroup(samplecatalogandgroupiscreatedbydefault).

Page 20: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 20/22

ClickfinishonConfirmationtabandifeverythingisfinethepopupbelowwillbeshown.ClickOKtoclosethispopup.

BuildFioriMobileApplicat ion

A

LicensingtheSDK

IfyouplantousethecmbSDKtodomobilescanningwithasmartphoneoratablet

Page 21: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 21/22

(withouttheMXmobileterminal),theSDKrequirestheinstallationofalicensekey.Withoutalicensekey,theSDKwillstilloperate,althoughscannedresultswillbeblurred(theSDKwillrandomlyreplacecharactersinthescanresultwithanasteriskcharacter).

ContactyourCognexSalesRepresentativeforinformationonhowtoobtainalicensekeyincludingtriallicenseswhichcanbeusedfor30daystoevaluatetheSDK.

Afterobtainingyourlicensekeyopeni18n.propertiesfile inyourprojectonSAPWEBIDEservice,andsetyourobtainedkeys.

ThengobacktotheComponent.jsfile andcheckthiscode:

cmbScanner.setConnectionStateDidChangeOfReaderCallback((connectionState)=>{

if(connectionState===cmbScanner.CONSTANTS.CONNECTION_STATE_CONNECTED){

oEventBus.publish("ScanView","SetConnectionStatus",{statusText:"CONNECTED"});

if(window.readerConnected!=connectionState){cmbScanner.setSymbologyEnabled("SYMBOL.DATAMATRIX",true);cmbScanner.setSymbologyEnabled("SYMBOL.C128",true);cmbScanner.sendCommand("SETTRIGGER.TYPE2");}

varsdkKEY="";if(Device.os.android)sdkKEY=this.getModel("i18n").getProperty("MX_MOBILE_LICENSE_ANDROID");elsesdkKEY=this.getModel("i18n").getProperty("MX_MOBILE_LICENSE_iOS");

cmbScanner.registerSDK(sdkKEY,(res)=>{switch(res){casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_OK:break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_KEY:break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_CHECKSUM:break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_APPLICATION:break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_SDK_VERSION:

Page 22: SAP Fiori Mobile (v2.6.x)

t it le:SAPFioriMobile(v2.6.x);ver:2.6.x 22/22

break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_KEY_VERSION:break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_INVALID_PLATFORM:break;casecmbScanner.CONSTANTS.REGISTER_RESULTS.REGISTRATION_KEY_EXPIRED:break;default:break;}});

...........

Youcanseethataftersuccessfulconnectionyoureadthiskeyfromi18n.propertiesandcallcmbScanner.registerSDKmethodtoregisterSDKwithyourlicensekey.

Checkingresultobjectwhichissentbackincallbackfunctioncantellusifregistrationissuccessfulorwhatistheproblem.


Recommended