You are on page 1of 25

openSAP

Developing Mobile Apps with SAP HANA Cloud


Platform
Week 5 Unit 1
00:00:09

Hi, welcome to Week 5 of this openSAP course on mobilizing SAP Fiori apps.

00:00:17

This week we're going to be focusing on how we could create an offline application with
what we call offline OData.
Offline OData is a part of the HANA Cloud Platform mobile services and also from an SDK
perspective,
it's in our SAP Mobile Platform SDK, so the two really work together. So during this week
we're going to see how offline OData works.
That's what we'll see in this unit. And then we're going to take a look at how we could best
develop our
OData services to get the most out of offline. And after that, we will actually develop an
offline OData service. OK.
Then we'll look at different configuration options on the HANA Cloud Platform mobile
services for offline to get the
best performance for our OData services that we're going to offline. OK. So let's get into
this unit here.
You know, how offline OData works. First, the question is, why offline? Why do we need
an offline app?
I think the answer is pretty simple, you know. Business doesn't always happen where
there is a network, right.
And sometimes, quite honestly, even if there is one, you want to be able to work in an
offline fashion. You can see different examples here of locations that don't always have
networks. Now

00:00:24
00:00:32
00:00:40
00:00:46
00:00:54
00:01:03
00:01:13
00:01:19
00:01:27

00:01:40
00:01:52
00:02:01
00:02:12
00:02:19
00:02:25
00:02:34
00:02:45
00:02:53
00:03:05
00:03:14

on top of that, I can think of even online scenarios where this offline functionality could
help. I think about applications that you want to let your users browse a product catalog.
OK. That product catalog, maybe you want to offline that data so that they get a better
experience and are able to quickly go through the products.
So while we're going to be focusing on offline, just know that there are options for even
online apps to use this kind of functionality as well, to cache data on the device.
OK. So on the HANA Cloud Platform mobile services, we have what we call the offline
OData service
here in the mid-tier. And it works in conjunction with the Mobile Platform SDK
to offline data from an OData Producer. Whether that OData is coming from SAP
Business Suite, maybe it's coming from HANA,
maybe it's coming from the HANA Cloud integration or so on, third parties, what not, right.
So as long as it's in OData format
and it's following the version we support, which is V2, Version 2 of OData, then we could
offline this data. And
essentially, this OData offline service is going to go out, fetch all the data that it should
offline, which you determine when you're using the SDK,
there's an API and you list what you want to offline. It's going to fetch that data, create a
database, and send that to our client application.
And the SDK knows how to query that database, even though the SDK from an API
perspective,

00:03:22
00:03:33
00:03:42
00:03:50
00:03:59
00:04:09
00:04:19
00:04:28
00:04:38
00:04:48
00:04:59
00:05:06
00:05:14
00:05:25
00:05:37
00:05:47
00:05:55
00:06:01
00:06:10
00:06:20
00:06:27
00:06:36
00:06:46
00:06:53
00:07:01
00:07:17

the developer is still using OData-type query commands and what not. And the SDK then
interprets that and sends it to the database.
Now so at the end of the day, the OData service gets sent up to the device and it
becomes a local OData service there.
OK, so again, your developers still work with it like it's OData. The data just happens to
exist on the device.
So that database is what we call UltraLite-type database. OK. This comes from the
Sybase days, it's well known from there.
And offline OData, this service, you see here it says optimized for OData services
supporting v4 delta queries.
Well, I mentioned earlier that we support Version Now, but we do support also this piece
of Version 4 for delta queries.
And this is very important for offline apps because if I offline a large amount of data on my
device and then I want to refresh it,
it's nice to have a delta-enabled query on my OData service. So I could send in a
timestamp, get all the changes from the back end,
and have them sent up and update my database. Otherwise I would have to go out and
get all that data and send it back to do a refresh.
OK. That said, we do have what we call middle- tier delta enablement for services that
don't support delta query. And
while, from the HANA Cloud Platform mobile services to the back-end OData service, we
still have to get all the data for these.
But we could compute a delta here in the middle tier and send that delta to the device. So
at least for even these services,
we are not sending all the data, just the delta that we're able to calculate in the middle tier.
We'll talk about how that works in a little bit more detail later on.
OK, now on top of this as well, we offer middle- tier caching of OData collections, OK. And
we say generic. What do we mean by generic? I like to use an example.
So things like master data, OK. Things like product data or product catalog. You know,
this data is the same for any user that wants to access it, right?
So for all my users, I don't want to send them back to get the same data. I should be able
to cache this data here in the middle tier
and send them the data that's already been cached. So we could do that with our offline
OData service.
And we'll take a look at how all this works later on. That's controlled by a configuration
property and we'll see this throughout the week.
OK. Now a little closer look at our offline OData service and how it works with the SDK. So
here we have our offline OData service
on the HANA Cloud Platform mobile services. And we can see that it has its OData cache,
delta enablement if it's for a service that doesn't support delta tokens, and then just
provisioning and refreshing of the OData store here.
So we have all this part of our OData offline service. Now, from an SDK perspective, the
developer determines when they're developing the app
what entity sets that belong to my OData service that I want to offline. And within the API,
they list these out
and then they're able to send that information to the HANA Cloud Platform mobile
services. It constructs a database
and then loads the data into that database and sends it to our client, alright. So now for
offline stores, we're able to access the data locally within that UltraLight database.
Now we could do this for both native applications, this is supported for Windows, iOS, and
Android. But we could also do it for our hybrid applications as well.

00:07:28

00:08:02

OK, and that's what, of course, we're focusing on here because Fiori being hybrid, kind of
HTML5 content, we're going to wrap it up
with Apache Cordova and use our Kapsel plugins. Now this communication here is over
what we call
MobiLink protocol but over HTTP. So we're not using any proprietary communication
channels, but the data format
is in MobiLink, but again it's going over HTTP. You don't have to open any special ports or
anything like this.
That's the nice thing about it. OK, so let's take a look at the three scenarios

00:08:09

that we talk about in offline. One, we want to create the initial database on the device.

00:08:14

We have to download that data onto the device. Two is refresh. We want to update our
data on the device.
And three is flush, meaning all the changes I've made to the data, I want to flush those
and send those to the back end.
So, but first thing you do is this initial download sequence. And I just make an API call with

00:07:36
00:07:46
00:07:54

00:08:21
00:08:30
00:08:37
00:08:45
00:08:54
00:09:04
00:09:13
00:09:21
00:09:32
00:09:41
00:09:49
00:10:00
00:10:06
00:10:15
00:10:22
00:10:29
00:10:41
00:10:50
00:11:04
00:11:11
00:11:20

the entity sets that I want offlined. We call these defining requests. We'll take a look at this
in more detail later.
More or less it's just listing out the entity sets that I want to have offlined. Now our HCPms
receives this,
and it's got to construct that database for the OData service that we want to offline. And it
does this by getting the metadata of that service
and, from there, constructing the database. Now, at this point, it's just an empty database,
right. So now we want to fill it with data.
OK. So now for each defining request, we're going to loop through each one of those and
we're going to request the data from the back end.
We get that data and we populate the database. Now if delta is not enabled, these delta
queries are not enabled on this service,
then what we're going to do at this point is create a bunch of cache keys that later on let
us calculate a delta
that we could compare against and see what's changed. So calculate this here on the
server and store that
within the database of the HANA Cloud Platform mobile services so it could be used later
on when we do a refresh. OK, but we've constructed the database at this point.
We notify the device. We've passed back saying, hey, here's the database file name, I've
created it.
And it turns around and requests to download that database. The database gets
downloaded, and now it's available on the device.
And at this point, you could go offline. Now that is the most simplistic scenario.
There are offline config parameters that could simplify this. OK, and optimize the process,
right.
I mentioned earlier that we could cache data for things like master data on the mid-tier. So
if you had that configured, it would not make the request for that data to the back end.
It would just use what's cached on the mid-tier. So different things to speed up the
process and make, you know, your offline experience better.
And it just depends on your scenario, what you're going to enable within the config. Now
we will go over these offline configuration options later on in Unit 5 of this week.
OK, so that was downloading the initial database sequence. Now how do we refresh?
So I've maybe been offline for a couple of days, and I want to go and get all the data from
the back end that has changed and update my local database.
So I have the data that looks like it represents what's on the back end at that point in time.
OK, so I send these defining requests in with the refresh API.

00:11:32
00:11:39
00:11:46
00:11:54
00:12:07
00:12:15
00:12:22
00:12:33
00:12:40
00:12:51
00:12:59
00:13:07
00:13:13
00:13:21
00:13:30

And for each one of these defining requests, the HANA Cloud Platform mobile services is
going to request the data on the back end.
Now this is if delta is enabled. Well, in that case, we make the request to the back end
with the delta token
which is more or less a timestamp. Now the back end then would use that to calculate all
the changes, updates, and deletes
and pass that data back to the HANA Cloud Platform mobile services. Now if delta is not
enabled, then HCPms has to get all the data for this service,
compare it to those cache keys, and from there it could compute a delta that it could send
to the device.
Now that said, just realize we do have to go back and get all the data here. OK, so
depending on the size of data,
this could take a bit of time, right, so just keep that in mind. And just understand that this
will never be as good a performance as you could have with delta tokens,
if you had that enabled on your OData services. Anyway, but we can do that and it works
really well actually with small data sets,
just you've got to think about it once these datasets get larger and larger. It makes a lot of
sense then to have delta- enabled queries on those.
OK, but now we have our delta. No matter if it was delta enabled or not, we've computed
one on the HANA Cloud Platform mobile services.
We passed this back to our client and it's able to take that information and apply the
changes to the local database.
So that's refresh, that's how it works. Let's take a look at flush.
In this case, we're offline. We're creating a bunch of different changes, we're creating
entries, updating entries
as well as deleting some perhaps, right. And all of these values or all of these transactions
we're doing offline
go into a request queue. OK. And then that queue, once we're back online,

00:13:38

we could send it back to HCPms, and then it will go and send those requests to the back
end. Now while you're offline as you're making changes, you know, this all gets reflected
in your local database

00:13:51

so when you query the data, you see all the data with the changes that you've made in
these different transactions.
But now we're back online, and I call the flush method and that's going to send that
request queue to HANA Cloud Platform mobile services.
And it, in turn, is just going to loop over each request and send those to the back end.
Now on the back end with OData, you have what we call ETags.
And it could use these to determine if there are conflicts or not. So maybe when you
offlined the data and then you updated a record,
maybe since that point in time somebody else has updated a record. Well, in that case,
that's a conflict and we don't want to overwrite what they did.
And we could capture this using ETags. Now whether it's success or failure, this is
reported back to HCPms for each request.
And all of this information is passed back to the client. And they could query the errors in
conflicts within the error archive with our API
and then determine what they want to do, it's up to the developer at that point. Do they
display it to the user and inform them that these records weren't updated for certain
reasons,

00:13:59
00:14:10
00:14:21
00:14:31
00:14:38
00:14:49
00:14:59

00:15:08
00:15:16

maybe there were conflicts or what not. Right, so after a flush, typically you do a refresh
right after that
because you want to then get your database looking exactly as it does on the back end.
OK, so that's again the three functionalities.

00:15:25
00:15:36
00:15:44
00:15:54
00:16:02
00:16:16
00:16:23
00:16:32
00:16:42
00:16:50
00:16:58
00:17:06
00:17:17
00:17:28
00:17:38
00:17:45
00:17:53
00:18:03
00:18:12
00:18:23
00:18:29
00:18:39
00:18:48
00:18:57
00:19:08
00:19:16
00:19:24

downloading the database, refreshing it, and flushing your changes. Ok. And this is all
done when we're doing Hybrid apps using the Kapsel SDK,
which is part of the mobile platform SDK. And we're going to use the OData plugin and
this enables offline support for us.
OK, and it's just some simple JavaScript APIs that we're going to interact with. So very
easy to do from Fiori-type apps, right, because they're all JavaScript-based.
The first thing you do is createOfflineStore and you send in properties, which is just a
JavaScript object and I'll show you what that looks like.
And it just has all the different values that are needed to create this offline store - things
like the name of the store, the host name, the port of the HCPms server
and the serviceRoot, of course, whether it's using https or not. Most importantly is
definingRequests.
OK. And this is where you list out all the entity sets that you want offlined. What we're
looking at here is as simple as it gets. One single entity set.
I've seen 60 definingRequests listed within this, alright. So lots of different things you
could do there, all depends on the scenario how you want to
configure that. And on the next slide, we'll take a deeper look. Anyway, once we have
these properties, then we can create our store.
Now at this point though, the store is just local, we haven't started the initial download
sequence yet. We'll take a look at how we do that in just a second.
But I want to take a second here to look at our defining requests. OK. And this is really
where you've got to put some thought into
how you're going to want to get the data onto your device, and what data you want on the
device, OK. So you can have one or more defining requests, like I said.
And more often than not, it's a lot more. Like I said, I've seen up to 60 in there. OK. And
also, for services that don't support delta tokens,
you want to use $expand to load entities and their relationships. So in this example, I have
products where each product has suppliers.
With OData, I could say give me all the products, and for each product, give me its
suppliers. This is basically what this line is saying.
And by using this as my defining request, it's going to construct that database with that
relationship between products and suppliers for me.
So, again, this is if our services do not support delta tokens. We would do this a different
way, if our services did support delta tokens.
And that's what we have here. So for services that have delta tokens, we would rather you
have multiple defining requests for each entity set.
So we say Products and Suppliers, OK. Now, but then how does it get linked up? What
about the relationships between them,
between products and suppliers? Well, when we're constructing that database,
we get the metadata of the OData service and within there it shows all the different
relationships. So we're able to construct that and still maintain that information here.
So, anyway, big picture, if you have delta token support, do it this way. If not, use your
$expand.
You could also use query parameters in our defining requests because sometimes
maybe, take this case example;
I have sales orders but I only want to offline sales orders for a specific customer, OK, so.
That's totally legit as well, and you could think of a lot of other use cases.
There's a lot of user-based data. I only want to download and offline the accounts that
belong to me. OK, my user.
So you could have user-specific defining requests or master data defining requests.
Remember I was mentioning earlier how we could cache data on the middle tier. It's these
kind of defining requests with master data that I'd want to cache.

00:19:33
00:19:42

00:19:57
00:20:05
00:20:14

00:20:24
00:20:31
00:20:38
00:20:51
00:21:01
00:21:12
00:21:24
00:21:31
00:21:40
00:21:50
00:21:57
00:22:08
00:22:18
00:22:26
00:22:33

This user-specific data that define our defining request, I wouldn't want to cache that in the
middle tier. So in this case products and suppliers, let's cache that.
User-specific sales orders that only belong to one user of my application - makes no
sense to cache. Again, it's configured with some config values we'll take a look at later this
week.
OK, now I've configured all that, now I'm ready to offline my data. On my store object, I
simply call open.
OK, so there's a method open, give it the callbacks whether it was error or successful.
And that is what starts that initial download sequence.
Of course, at this point we have to be online because we have to get the data downloaded
to the device. Now I have it downloaded to the device, and I'm ready to start working
offline.
And at this point, I have to call a method to start working offline. And it's called
applyHttpClient.
This is pretty neat because what it does is first off is our Fiori-style apps using UI5,
that's the JavaScript library underneath the covers that Fiori uses, is it uses an OData
layer called data JS to access OData services.
Now data JS uses an HTTP client underneath it. And that HTTP client is what sets up the
network connection and all that.
Well, when we call applyHttpClient, all we do is we switch the implementation of that
HTTP client. So that now instead of being that one that sets up network connections,
it sets up the connection to that local database and starts calling it, OK. Now the beauty of
this is the way I, as a developer of my Fiori apps that are calling the OData services,
it doesn't change anything in how I develop, alright. Everything in that regard stays the
same.
All I have to do is set up my offline store, call applyHttpClient, and the rest stays the same.
So that's what's really nice.
Of course, we could call removeHttpClient later on. But that said, typically you do not want
to write an app that is sometimes online and sometimes offline.
You really need to think when I'm going to write an offline app, it should be an offline app.
And you should always be accessing that offline data.
Not sometimes trying to access online data and sometimes offline. You'll just get into sync
issues and all of this, so that's our recommendation on that.
OK. Now the flush, simple flush API, call that. And that's just going to send all of those
transactions that I've created while I was offline
and send them to the back end and update the data back there. And then from there, of
course, it reports back with all its successes and failures
and I could query that information as well. OK, refresh, very similar, same way.

00:22:42

It's just going to send all our defining requests back, and instruct HCPms to get all the
deltas of what's changed and send that back to me.
And update my local database. OK, so that said,

00:22:49

that is offline OData at a high level there. I want to thank you for listening.

00:22:54

In the next unit, we're going to take a look at how we could best develop our OData
services to get most out of offline.
So if you're going to go into one of these projects for an offline app, it's really one of the
things you need to think about.
OK. Once again, thank you, and we'll talk to you soon, bye.

00:23:03
00:23:09

Week 5 Unit 2
00:00:09

Hi, Jeff here. And in this Unit 2 of Week 5, we're focusing on again offline OData.

00:00:17

Now we're going to take a look specifically at some service development considerations
for offline OData.
So we're talking about there are certain things when we're dealing with large data sets
that we could do with our OData services to make them work best
with offline OData and our offline apps. So here, we're just looking at our landscape.

00:00:24
00:00:33
00:00:40
00:00:51
00:01:02
00:01:11
00:01:19
00:01:28
00:01:41
00:01:50
00:02:02

00:02:16

We have, of course, OData services, HANA Cloud Platform mobile services. And we're
going to be able to take this data, you know, create our database,
transfer it up to the device, you know over HTTP and the MobiLink protocol here.
Remember HCPms uses a component that we've had around called MobiLink.
OK. So we get all that data up there. But what we're seeing here is that we're offlining, as
an example, large data sets here.
And we're running into performance issues. We could run into timeout issues of trying to
build that initial database.
I've seen it where you start getting some timeout exceptions here and the data never
makes it up. And not only that, but when we do our refresh of the data,
it could take quite a long time because we're not supporting on the back-end delta
queries. OK. So we're going to take a look at how we could improve this performance.
OK. And these two things could be fixed or improved with server-side paging and delta
tracking/queries.
OK. So first let's look at server-side paging. So if you have a large data set that you're
trying to offline,
the way HCPms works is it's going to make a call to that data set, that entity set you're
trying to offline and let's say there's 500,000 records in this entity set that it's trying to pull
back.

00:02:25

Now it's quite possible that it might have an HTTP timeout while trying to pull that many
records from the back end, OK.
So if you have HTTP timeout there, you're going to end up on your client device getting a
timeout exception and the data will never have been offlined and made it up to your
device.

00:02:35

So to get around this issue, there is with OData services server-side enforced paging. OK.

00:02:44

So we realize on our OData service that we don't want to make it possible to send
500,000 records. For each request, we only want to send at most
So I get the first 2,000 records. And you'll find at the bottom of that response

00:02:55
00:03:04
00:03:14

will be a link to get the next 2,000. So then I get the first, and the next 2,000 in this case,
as an example.
And then the next 2,000 and so on until you have finally gotten all the information.

00:03:20

So the HANA Cloud Platform mobile services, when it's offlining the data, takes this
server-side paging into account. and will follow these $skiptoken links to continue getting
the data

00:03:32

until it's gotten all of it and is then able to create the offline database. In this way, we will
not run into these timeouts
that might occur due to HTTP requests taking so long. OK. So, yes, with large data sets,
you're going to want to support this
on your OData services so that when I'm accessing all that data, it only sends back so
many at a time.
Now we've used 2,000 here as an example but it just depends on your data size

00:03:41
00:03:50
00:03:56
00:04:02

and how much data you're passing back and forth. You might be able to do 10,000.
Maybe 500 makes more sense.

00:04:09
00:04:22
00:04:30
00:04:38
00:04:46
00:04:54
00:05:01
00:05:10
00:05:22
00:05:32
00:05:41
00:05:49
00:06:00
00:06:11
00:06:24
00:06:31
00:06:40
00:06:46

It just depends on what your data size and your network performance is. OK. So now. let's
switch gears and talk more about the refresh.
So when we trigger a refresh to update the client database, we find that it's taking far too
long.
And that's because we're on our OData service, we're not supporting delta tokens or delta
queries, OK.
And with OData, we've learned that it supports these delta queries. And the whole point
being is, when I do a refresh
I certainly don't want to get all the data, I just want to get the subset that has changed
since I last did a refresh.
So I'm able to pass in the timestamp, it's what we call the delta token. OK. So there's two
pieces of this.
There's obviously tracking of delta. So on our back-end server, some way we need the
ability to track changes
so that later on when somebody does send in a delta token with their query, we can take
that timestamp into account and then find all the things that have changed, right.
Now if my OData service does support delta tokens, it will pass me back a link with the
delta token.
So I do my initial call to the service, get all the data, and then at the bottom of that
response will be this delta token.
So the next time I try to call this service, this entity set, to get all the data, I could also
pass in this delta token with it.
And then it should go, based on that timestamp, get all the updates and creates. OK. That
said, you need some way of tracking these things on the back-end system.
You need timestamps of when things have been updated, created, and deleted. OK. Now,
within the SAP Business Suite systems,
using SAP Gateway, we do have a framework for tracking these deltas. OK. We have a
couple of components, of course, we need SAP Gateway component.
And then what we have from Syclo Agentry, you know, when we purchased the Syclo
company and all their mobile apps and framework,
they have built in a really nice framework for tracking deltas. Because, of course, all their
apps were offline, they needed this ability.
And we could use this framework, and it comes licensed with SAP Gateway. You could
get this
and use it to track your changes of certain entities.

00:06:53

And then when a delta query comes in, use that framework to gather all that's been
changed, updated, and deleted. And that way be able to send back all the deltas based on
that.

00:07:06

OK. So that's for our SAP Business Suite systems. We have that framework.

00:07:11

So, again, if you're mobilizing Fiori apps and large data sets, please take into account
server-side paging
as well as supporting delta-enabled queries with large data sets. You know, if they're
small data sets, it's not as big an issue
and HCPms does a good job of calculating those being able to calculate the deltas right
there in the mid-tier.
That said, large data sets, again, take that into account. Another thing is there are some
constraints.
You know offline OData doesn't support everything that OData could do. One, with OData
and I mentioned this in the last unit, and we'll touch on it again is that
OData has many different versions. Right now, we support OData Version 2.

00:07:20
00:07:28
00:07:37
00:07:45
00:07:54
00:08:00

So if you have an OData Version 3 service, it will not work here with our offline OData.
Now we are working on - the latest spec is called Version 4.

00:08:11
00:08:21
00:08:32
00:08:43
00:08:51
00:09:01
00:09:12
00:09:18
00:09:23
00:09:33
00:09:40
00:09:47
00:09:55
00:10:03
00:10:10
00:10:20
00:10:31
00:10:40
00:10:47
00:10:57
00:11:04
00:11:13
00:11:21
00:11:27
00:11:37
00:11:51
00:12:01
00:12:07

And, like I said, delta queries are part of that spec, we do support that little piece. But I
can tell you, internally, we are working on supporting OData Version 4.
But, as of today, it is Version 2. But keep a lookout in SCN and all that, and you'll see
when we finally support Version 4.
OK, now, we also do not support function imports. And that's part of the offline OData
specification.
And it probably helps to know what a function import is. Well, first off, an OData entity
supports all the CRUD operations.
So, create, read, update, delete, as well as being able to query those entities. But, you
know, not all business methods fit nicely into that, right.
You might have some extra method you want to have on your object like calculate
balance across all sales orders, maybe, I don't know, something like that.
So this is what a function import is. It's just some extra business method that's above and
beyond what the CRUD and query operations do
that you could have on your OData services. And at the end of the day, it's just custom
logic.
And that's why we can't offline this thing because it is custom logic. We would have to reimplement that logic on the device as well
to be able to offline it and we don't know what you coded in that function import. So that's
next to impossible there.
So that's not supported offline. Now there are also a couple of caveats here as well.
When you create your entities for your OData service, it's essentially a table definition,
right.
And with any table, you have primary keys. Now if in your keys, you have a string
or a binary type, you can see here Edm.String, Edm.Binary. We can only support certain
MaxLength on these.
So the maximum length of one of these strings is 512 in the primary key. And if it's binary,
1536 bytes, OK.
Now you have to specify for these key properties, the MaxLength variable. Alright, or
attribute on these properties.
OK. So that's required for offlining this data as well for when you're using these types in
the key of any set that you're trying to offline.
Now there's a link here, you can follow that. There are a few more odds and ends around
what can be offlined and what can't.
But those are the major points there I want to hit on. OK. So now I just want to do a quick
demo and show you the server-side paging
as well as a delta-enabled query service. OK. So I'm going to switch over to here.
And here I'm just going to go out to this NorthWind service that has a bunch of products.
So we see I'm querying my product entity set here just in my REST client.
I click Send. And this guy here, the way it works is it does not want to let anybody get all
the products at once
because it wants to prevent timeouts as well as just be nicer to the server, right.
If you have 100,000 people hitting a server and it's trying to pass back performance on
there.
So if we look here, if I go to preview, I can scroll all the way down to the bottom. Oops, I'll
just scroll up a little bit here, sorry.
OK. Down here at the bottom, you see this link "next". And then it has skiptoken=20. So
it only passed me back twenty products.
To get the next 20, I would call this. So I click that, you see it goes up to here.
And now I've got the next 20. And then down at the bottom, again, it would say now go get
the next set,

00:12:15
00:12:23
00:12:33
00:12:42
00:12:53
00:12:58

starting at row 40. So each time, it basically says skip this many Get the next batch. OK,
that's what it means there.
Click that, Send, and so on. Alright. So that's how that works and, again, that's how
HCPms could take advantage of this
on large data sets and it will follow these Next links to get all the data so it won't do any
timeouts accessing large data sets.
But you have to implement this within your OData service. It's not hard to do, it's just
something you've got to go and implement for large data sets that you want offline.
OK. Now, I'm going to take a look at another service here that is delta enabled.

00:13:06

So here, I'm just going to click Send. And this returns back quite a few products, I could go
down to the bottom.
And at the end of this, you see here that it gives me a link for my deltas.

00:13:13

OK. So my link and the URL and most importantly this delta token

00:13:19

which is a timestamp in this case, right. So in my initial sync of the data,

00:13:27

I'm going to call the URL that I just called. But then when I want to go and refresh it later
on,
I am going to send in this link to get all the changes, OK. So I'm going to click on this guy,
and you can see now I'm going to submit this
with the delta token. And you can see no changes have occurred.

00:13:32
00:13:41
00:13:46

00:14:17

So I get an empty response back with no more product data, alright. And it also gives me
another delta token
with the timestamp of when I just did this query. So I could use that one the next time I'm
going to query this service. OK.
So, again, you can see how delta queries could work to improve our refresh performance.
So that I am not having to query and get all the back-end entities
and then calculate the delta in our HCPms. Have the back end do it, support delta queries

00:14:23

within your OData services for your large data sets. Same thing with that $skiptoken.

00:14:29

00:14:51

You're going to want to implement that so that we have that server-side paging and we
can prevent timeouts between HCPms
and the back end while it's loading up that database with data. OK. So that's what we had
here
for Unit 2 of our offline OData. In our next unit, we're going to take a look at actually
developing an offline application.
And we will see how easy it is with the SAP Web IDE and the Hybrid Application Toolkit.

00:14:58

OK. That said, thanks for listening, talk to you soon. Bye

00:13:56
00:14:06

00:14:36
00:14:43

10

Week 5 Unit 3
00:00:09

Hi, Jeff here. And in this unit, we're going to take a look at creating an offline application.

00:00:16

So we're just going to create a simple offline application using the project templates within
the SAP Web IDE.
So, again, simple but it really is a good place to start and understand how offline works.
OK, with OData and all these components we've been talking about.
So with that said, let's go ahead and take a look at the presentation. Like I was saying,
we're going to use a project template that will generate us the project
and it's called the Master Detail Kapsel Offline Application. And all we do is point at our
OData service and it takes us through a wizard of setting up
the UI fields for us. And it's going to go ahead and generate all the offline code that we
need.
Now, again, very simple, but it's a great first step in understanding how offline applications
work and the code that you need to have there.
OK, With Web IDE, of course, we could use our destinations we defined on the HANA
Cloud Platform. We'll be using our NorthWind destination to point to our OData service.
OK. And then we go through the template and we're just going to enter in the fields that
we want to display within our UI that's going to be generated for us.
Now the neat thing is, we could actually test this as a Web application and it will work in
preview mode as a Web application.
And it will still work online, OK. It will just ignore the offline pieces of the code because it's
not running
an Apache Cordova container with the Kapsel plugins that are required. So you could test
this pretty easily.
OK. Of course, we're going to do an offline app so when we build this with the Hybrid
Application Toolkit, we've got to let it know that it needs to use the Logon Manager to
onboard HCPms

00:00:25
00:00:37
00:00:46
00:00:56
00:01:03
00:01:13
00:01:26
00:01:38
00:01:48
00:01:56
00:02:07

00:02:18
00:02:30
00:02:37
00:02:47
00:02:54
00:03:04
00:03:13
00:03:23
00:03:31
00:03:41
00:03:52
00:04:02

and then the offline OData plugin to work with the offline capabilities that come with HANA
Cloud Platform mobile services.
OK. Of course, to use this, we've got to be using the HANA Cloud Platform mobile
services. So we have our application configured there.
We're going to continue to use the same one that we've used for our online app where we
did our simple online application and we added push plugins.
We could keep using this and that's what we'll do here. But, of course, just know this
offline functionality is possible
because of the HANA Cloud Platform mobile services, so we definitely need to use that.
OK, so offline project template.
Here we just say we're going to create a new project from a template. We select the SAP
Master Detail Kapsel Offline Application.
From there, we tell it which destination we want to use as well as the relative URL to our
OData service.
OK. Then we click the Next button. And, from there, we could select the entity sets that we
want to have offlined.
OK. You could select one or more here. Right, after that, it's going to take you through
configuring the UI, OK.
And on the left-hand side, this is setting up the values that it'll display in the list. In this
case, we're going to display products, so we're going to configure our products list here.
That's what's going to show up there. And then further down, this is like a long list here
that you're going to just scroll down through.
And then here we're just showing another shot of it in the Detail Section. And you'll set up
what's going to show when I click on a product in the detail area.

11

00:04:12
00:04:18
00:04:30
00:04:40
00:04:50
00:05:04
00:05:12
00:05:22

00:05:35
00:05:42
00:05:51
00:06:02
00:06:07
00:06:17
00:06:28
00:06:36
00:06:46
00:06:56
00:07:07
00:07:15
00:07:28
00:07:39
00:07:48
00:07:58
00:08:06

OK. And then you could also display navigation data. So we're going to display our
product details
as well as the supplier associated with this product. OK. Now when the application is
generated,
it's going to create the defining requests for you based on what you selected here. Now
quite often though, you're going to want to modify these to meet your needs.
Remember I was talking about how important defining requests are to your offline
application, and they really control what data is going to get offlined. And
in some cases the relationships between the entities that you're offlining. OK. So the
generated project includes a folder called dev and then a file called index.js.
Inside the initialize function, you'll see a line similar to this which will list out your defining
request.
Now you could go in there and modify this. And we'll do this in the next unit; I'll go through
an example of modifying this value.
Anyway, this example is saying, hey, maybe you don't want to return offline all products,
right. And in this case, we're going to only offline products that have a rating greater than
2. OK.
So that's just an example. What we're going to do in our example, and I demoed this, is
add a $expand. OK.
So I want to offline products and its related suppliers. I'll show you how to do that later on
in the next unit.
OK. Also you can modify these UIs of course; it's just generated code. What I like about
these generators is that they get you started
and then you could go in and modify it to meet your needs. I've seen a lot of UI generators
in my time.
In a lot of cases, it's really hard to modify what they generate out to you. I find that not to
be the case with these, so it's kind of nice.
OK. So here it's just displaying the Create UI. Because you could create fields or edit
fields. And in some cases, you might want to display some of these fields.
So I could easily go in, and in this case there's a file that will be generated, the
DetailEditMode.fragment.xml
This is just the UI for this little area here. And we could comment out the fields that we
don't want to have displayed, simple as that.
So, and again, it's up to you how you want to go in and modify this. But, again, a good
starting point, and you could start adding whatever your heart desires, right?
It's up to you to take it from there. OK. Your project must be configured to use the Logon
and the Offline OData plugin.
So within our project settings, we're going to go into the Device Configuration and we're
going to select these plugins.
OK. So Device Configuration. We go to Kapsel, Logon Manager, Offline OData. OK. And
down here, it's going to show you your HANA Cloud Platform mobile services.
It should default that, put yours in by default, if it's all activated. But you could change this
to use an on-premise version of the SAP mobile platform as well.
Of course, our focus here is on the cloud, but you have your options. Now I could run this
application
as well as an online app. I could go into preview mode, I just highlight index.html then I
could click Run as > Web Application.
And then it will display that application to me and I could work with it. So while, yes, this
has all the offline code in it,
we could still run it in online mode or preview mode to get a feeling for how the UI is
behaving in all of that. Now later on in the next unit, I'm going to take that application
though

12

00:08:17
00:08:27
00:08:36

and I'm going to wrap it up with the Hybrid Application Toolkit and deploy that out there to
one of my devices. And we'll take a look at that.
OK. That said, let's go ahead and do a demo. Go over here into my SAP Web IDE.

00:08:44

And say File>New>Project from Template And here you can see there's all sorts of
different templates; you've seen these already before.
You've been working with these. But now we're going to select the offline one here.

00:08:49

I'm going to click Next and give this our Project Name OpenSAPOfflineApp Click Next.

00:09:00

Now we want to go to our Service URL option down here. And I'm going to select my
NorthWind destination.
I thought I had that pasted in there, I'm just going to take that out, I'm going to go get mine
here. So I could just copy this right there, paste it in.
Click this button. There we go. So it was able to, through the destination, query this
service
and get all of the entity sets and different actions that belong to this OData service. OK.
So that's good, and I'm just going to click Next.
And I'm going to select Products and Suppliers that I want to offline. Click Next.

00:09:10
00:09:22
00:09:28
00:09:39
00:09:47
00:09:56
00:10:05
00:10:14
00:10:27
00:10:35
00:10:48
00:10:57
00:11:05
00:11:15

00:11:27
00:11:34
00:11:46
00:11:54
00:12:03
00:12:10
00:12:20

And now here I'm going to configure my UI. I've got to first give it a Namespace; I'm just
going to do com.sap.open.offline
And now I'm configuring this little area up here, the search area for my list. And I'm going
to say this is just Products.
And I'm going to say which entity set I want to display here. And I could do a Search
Placeholder that will show up there.
And I could say just Search, something like that. Search Tooltip: Search Product Name,
put a capital there.
And I specify the Search Field, there we go, so that looks good. And now I want to list the
Main Data Fields, which are these values here
that are going to show up in each individual list item. Now, again, I'm going to have my
product name show up right here.
And now it says Numeric Attribute and Units Attribute, now that's just a suggestion. There
is nothing to stop me from putting the ID there.
And then underneath that the Price. OK. But, you know, what they're saying here is
typically in a list, especially with products.
You're going to have, you know, the price, 20 dollars, and then the currency code, the unit
or maybe the weight and the unit, stuff like that.
But again, that's just a suggestion, I mean these are just three fields that are going to
show up, item tile here, and then this would be the numeric attribute, underneath there is
the units attribute.
It's up to you to determine what you want to put in there. And you could modify all that
code later on anyway, right.
OK. Now, the Detail Section here, I'm going to say Product Detail and I'm going to go
ahead and I want my Description to show up.
And maybe I want, I don't know, we can just select the Name. Again, we can modify this
later on.
Now down here, I'm going to do my OData navigation because remember a product, from
there we could navigate it to its supplier.
That's what we're talking about here, so from a product, we'd go to supplier. And this is
where this data will show up down here.
Ok, now I could display some values here, I'm going to display the Name, the City, and
how about the Country? Alright.
Now the Create/Edit screen. I'm going to say I want some input. I get to create input
values for my key properties.

13

00:12:29
00:12:35
00:12:45
00:12:49
00:13:03
00:13:12
00:13:22

So you could specify that so that I'll have input fields for the keys. But this depends on
your OData service.
Some OData services, the back end generates the keys, OK. Now, for this, I'm just going
to say I want to go ahead and enter those.
You could even generate dropdowns for some of your lists if that's applicable.
Because some values within your entity sets that you create could have a dropdown list,
OK. But in our case, we don't have that, we're just going to go ahead and click Next.
And now she's saying it's all done. Click the Finish button. And it's going to go ahead and
generate all the code for us.
So now I have my offline application. And I could go ahead and highlight index.html

00:13:32

And click Run. And it's just going to launch our preview mode here. And we could check
out how this application behaves and what it looks like.
Give that a second. There we go.

00:13:46

So now we have our application, we have all our data. And we just block this.

00:13:53

It's probably hitting some offline code pieces there, we just ignore that. Anyway, so we see
all that, it looks really good.
Again, I could switch resolutions here. See what it might look like on something like a
tablet, right.
This is the whole responsive UI that we're seeing here. And over here on the right, you
could see the product details.
As well as related supplier information. OK. So you see how we could use that template to
generate us an offline app.
Right. And you can see that we can also run this application online through the preview
mode. And it will, of course, ignore that offline code and enable us to do this.
Anyhow, that's telling you something here, right. Later on, we're going to run this in offline
mode.
But you could see the code, the OData code that is in here works both offline and online.

00:14:00
00:14:06
00:14:14
00:14:25
00:14:37
00:14:43
00:14:50
00:15:03
00:15:13
00:15:19
00:15:27

And it's all because the offline plugins that switched the underlying http implementation for
the OData consumption layer within UI5.
So pretty neat that you as a Fiori developer in UI5, a developer consuming OData, you
know you don't change your coding at all.
OK. That's it for this unit. In our next unit, we're going to take this application,
make a couple of modifications; I'm going to show you the offline portions of the code. And
then we're going to deploy it to our device. OK.
That's it. Thanks a lot. Bye

14

Week 5 Unit 4
00:00:10
00:00:20
00:00:26
00:00:33
00:00:42

Hi, Jeff here. Welcome to this unit where we're going to take a look at deploying our offline
application to our device.
Of course, you could do that in an emulator or simulator as well. But, again, I just like to
use a device.
You get much better performance when you're developing things. OK So that said, let's
take a look.
Now a checklist before we're going to go about deploying our application to the device is
one, we need our Hybrid Application Toolkit Connector up and running.
OK. It sets up the connection to Web IDE so that we can pull down all the contents of our
project and then wrap them up with our Apache Cordova and add in all our plugins and all
that fun stuff.

00:00:55

OK. So again, of course, we need Web IDE configured so it can talk to our Hybrid
Application Toolkit. We've already used these things in the past, so it should be good to
go.

00:01:06

We had our HANA Cloud Platform mobile services configured with our application config.
We're going to use the same one we've already had in the past, the name of that
application

00:01:16

you'll find there was com.sap.open. And then we're going to use SAP Web IDE.

00:01:25

Of course, we're going to go and configure the device configuration settings. We're going
to pick and choose the Kapsel plugins that we want to use.
And we're going to specify the HANA Cloud Platform mobile services that we're going to
be using as well for our application.
OK. The two plugins we're going to use in this case are the Logon plugin and the offline
OData plugin from our Kapsel SDK.
Alright. So deploying this thing, really simple, we've done it before. We just right-click on
index.html, Run, Run on, and then you pick what you want to run on.
Whether it's a simulator or device, iOS or Android. OK. And again, what happens is we
pull down all the content from our project.
We start our Apache Cordova build, we pull in the plugins we're using. And then we
deploy it out to our simulator or device. OK
Again, at the end of the day, you have a full- fledged application that could run offline.
Alright. Now we're going to test this.
So first thing is we're just going to onboard the application. So we're just going to enter in
our credentials here, onboard.
And then, from here, we are going to start that initial download sequence once the data is
downloaded onto the device, so it has that local database.
The data will be displayed as we see here. OK. And now, at this point, we could click an
item
and at this point we could go into airplane mode and start testing that way. One thing
about the iOS simulator, there's no airplane mode.
So another reason I like to work with the device. OK. So we click one of these items and
then go to the detail screen. And
by testing all that, again, you do all this in airplane mode. And you can see that it's all
offline and the data has been persisted on the device
based on the defining requests that you have entered in when creating the offline store.
OK. So now let's look at the other operation. So we just did the read operation.
Now let's look at the create operation here. You can see this little plus icon.

00:01:32
00:01:40
00:01:52
00:02:02
00:02:14
00:02:25
00:02:36
00:02:43
00:02:53
00:03:00
00:03:09
00:03:21
00:03:29
00:03:41
00:03:47
00:03:59

So that gets generated by that offline application template. Just click that. And it brings up
a UI screen with the input fields where you can enter in your data.
OK. So we type all that in. Now just one thing; you can see that this contains a date string.

15

00:04:05
00:04:11
00:04:19
00:04:25
00:04:34
00:04:42
00:04:49
00:04:58
00:05:08
00:05:19
00:05:31
00:05:41
00:05:52

And it's an input field. Now that's the only thing that's kind of tedious here, you have to
enter it in in an OData format
that they're expecting, that you can see here. Of course, we could change this, we could
add a calendar plugin
or a date picker, so somebody could use that. It would definitely be a better usability way
to do it.
But this is what the template generates and you can enter in the date like so. Now, from
there, we hit the Save button of course.
And that's going to persist it to our local store. OK But, at this point, it has not been
pushed back to the server.
So the data is saved locally. Now we could go and test this.
And make sure that the data is not yet on the server, right. So we could go and just open
up a browser, and we could call our OData REST service there
and I like to use Chrome because it formats the data pretty nice. And we just submit a
request or OData service to do a Git on all the products.
And we can see if that new product is there, and you'll find that it has not been persisted
there yet. And it's just telling you that offline is working. OK
So again the new entity is not here on the back end. Now, update is very similar, but we're
just going to go and click one of our products.
We're going to be able to go into edit mode by clicking the little pencil icon here for Edit.
Change some values, click Save. And
everything is persisted locally. And we could test it by going to a browser and calling a
REST service for the product's entity and seeing if anything has changed there.
OK. You'll find that that updated product, the changes you made, are not yet reflected.
Alright OK. Same thing with the Delete. You can pick an item, alright, then you've got the
Delete icon.

00:06:07

And, again, once you've done that you go back and check and make sure your changes
aren't there. OK, so. Not your changes, but make sure your product is still there because it
hasn't been deleted yet.

00:06:20

So, now, after all that's been done, we've created a bunch of offline transactions. These
are all being stored in the request queue.
Now it's time to do our Flush and Refresh and send these changes back to the back-end
server with the flush.
And then after that we'll do a refresh to get all the latest changes that other users might
have made. OK. So the way this application works is that there is a single button
for doing this, but in the code - and I'll show you this in a little bit - it actually calls the flush
function first on our offline store.
If that's successful, then it will call the refresh for you. OK, alright. So we just click that,
take a few moments.
And then all the changes have been synchronized with the back end. And, from there,
now we can go run our REST client again,
make sure what we deleted has been deleted, what we created is there and the changes
we made are there as well. Alright.
So, and that's how offline works. So remember there's just the three main stages, right.
You've got:
You've got your initial download, you've got your flush of the local transactions that you've
put in the request queue,
and then the refresh to synchronize all the data that other users have been changing as
well. OK. Of course, you could also deploy to a device, as I've been saying.
You just select device, whether it's Android or iOS. In this case, it's just showing iOS. And,
like I said, that's what I prefer to do just because it's so much faster.
OK, so that said, I'm going to show you a little bit of the code and a little bit of a demo
here.

00:06:29
00:06:38
00:06:48
00:06:58
00:07:09
00:07:16
00:07:25
00:07:30
00:07:36
00:07:48
00:08:00

16

00:08:06
00:08:14

00:09:10

So we're going to go over to our Web IDE that I have opened here in my Chrome browser.
And we have our project, and I what I want to do first is, you remember I was talking about
defining requests.
So, by default, this application when the template generates the defining request and it
creates a defining request for each entity that you choose to be offlined.
And you might remember I was talking about with defining requests that if your back end
doesn't support delta tokens,
that you want to use a $expand to load that data in. OK So we want a single defining
request in our case.
So we have products, and each product has a relationship to its supplier. So when you
have that kind of relationship, you could change it,
use a $expand, so that at the same time that I'm loading my products in, I'm also getting
each product's supplier data
that it has a relationship to. So I'm going to change this product's defining request.

00:09:15

I'm going to say $expand= And then we're just going to say

00:09:23

supplier like so. So we're loading in the supplier relationship that each product has.

00:09:31

Now because I did that, I could just go ahead and delete this defining request, the load in
the suppliers.
OK. So I have the one for products and it's going to, in turn, load all suppliers.

00:08:22
00:08:35
00:08:43
00:08:50
00:09:00

00:09:40
00:09:46

00:10:19

And it's going to create that relationship on the database between products and suppliers.
Now, if we are using OData services that supported delta tokens,
well, in that case, we would want to do what was already shown there. You want to have a
defining request for each of the entities.
And the relationship between them will be created based on what is read in the metadata
because the metadata also defines these relationships between entities.
OK. But this looks good. Now this is inside of what's the devapp.js

00:10:25

where there's some high-level variables created here. If we go into devlogon.js,

00:10:32

00:10:56

it's here where you'll find the code that interacts with these plugins. OK. You'll find the
code that starts the Logon plugin.
And then you'll find the code from there that kicks off the offlining process and does the
flush and refresh as well.
So if I go down through this, we'll see that here's where I'm interacting with the Logon
plugin and kicking off that process.
Now if Logon is successful, it calls this function. So let's go ahead and search for that.

00:11:02

It's right here. So, and after the Logon succeeds, then it's going to go out and start the

00:11:09

opening up of the offline store. OK. So you can see here is another function it calls on
success
for starting this offline store process, so we'll scroll down to here. And it looks very similar
to the code I've shown in
earlier slides here, but you can see I'm setting up a properties variable here. And within
this is where you're setting up your defining request
and all those other properties I was showing you. And then you create an offline store
object right here.
OK. Create offline store, alright, and we pass in those properties. And then the actual
download sequence of that offline store is started when you call open.
Now, just a reminder, depending on the size of your data, this could take a while, right.

00:09:59
00:10:07

00:10:40
00:10:48

00:11:15
00:11:25
00:11:34
00:11:41
00:11:52
00:12:00
00:12:09
00:12:18

I mean if you're downloading hundreds of megabytes of data, be prepared that this, your
application will be waiting to be downloaded, maybe up to 10 minutes, right.
It just depends on what your offline scenario is and how much data is being downloaded.
OK, but on success, you can see that it calls this function.
And then on error this one. Now I wanted to show you now we could go and look for flush

17

00:12:25
00:12:41
00:12:48
00:12:59
00:13:09
00:13:20
00:13:30
00:13:39
00:13:47
00:13:58
00:14:08
00:14:14
00:14:23
00:14:31
00:14:41
00:14:50
00:14:58
00:15:07
00:15:16
00:15:25
00:15:31
00:15:39
00:15:47
00:15:54
00:16:02
00:16:10

because I was telling you when that little refresh icon is clicked, it's going to call flush. And
then it is going to, in turn, if the flush is successful, call a refresh.
So that it gets all the changes that other users have made. So here we see
flushAppOfflineStore.
If we look through the code here, we will see on our store object, we're calling the flush
method on it. OK
And, again if it's successful, it's going to call this function. So let's just go see we'll go to
there, and you can see, on success, it turns around and calls this function
to start the refresh of your store. So we can go look at that as well. There we go. And
here, it just goes to this code.
And it gets down to this point here, for on the store object, it calls refresh. OK. So that's
the three major phases that we've been talking about.
The initial download sequence, the flush of our local transactions, and then pulling down
and refreshing all of the data
based on other users' changes to that back-end data. OK So that's it in a nutshell.
What we can do now is, I just want to save this file here that has my defining request in it.
And let's go into the properties of our project
and make sure we've selected all the proper plugins before I kick off a build. And now we
can see, yes, I've configured my app.
The App ID is set up. The Version is looking good. And I'm set up to run on iOS, we'll
keep it like that.
Although, again, you could do this on Android as well. And I can select Logon Manager
and Offline OData plugins here. OK
So you've got those two plugins. It defaulted in my HANA Cloud Platform mobile services
host name.
So we're looking good. Now I could just save this if I've made any changes. And now I just
right-click Run
then Run on Simulator or iOS device. Now at this point, I'm going to go ahead and kick
this off.
And once the build's done, I'll come back and we'll demo the actual application running
and take a look at that.
And then we'll talk about what we're going to get into in the next unit. OK. I'm back, I've
got the app deployed here
onto my phone that I have here, which is a really old phone. It didn't take long to deploy it
but the phone went haywire.
I had to go in to reboot it to get it to work again. Unfortunately, my power button wasn't
working so I pried open the display,
undid the battery, put it back on, so it would reboot. And now I could actually click some
buttons on the thing, so.
I'm able to do this demo for you now, this is good. And that's just life when you have a lot
of devices, you're an app developer, you've got to
get into the device sometimes and do some hardware work, which is kind of fun,
sometimes not. Anyway, we're going, I've got my app.
I've entered in my user credentials, you didn't have to see my type that in. I'm going to go
ahead and register here.
And it's registering, we can see that on the screen. Now, I can enter in my passcode, and
click
disable that, and click submit. And now the initial download sequence occurring,

00:16:17

pulling all that data down, creating the database, and dropping it onto my device here.
Once that's done, we'll see the data show up.
There we go. And it happened pretty quickly, there's not a lot of data here.

00:16:22

But we do have our local database. What I'm going to do now is close this,

18

00:16:32

go into airplane mode, so you can see that. Alright. Go back to my application.

00:16:39

00:16:58

And we'll see this is still working, you know, because we are in offline mode, we see the
airplane displayed.
what I'm going to do is just make a small change here, I'm going to go into Edit mode. And
we'll try to name this
Chocolate Milk, if I could spell it right. There we go, Chocolate Milk, Done, looks good.

00:17:12

I'm going to click my Save button. Save was successful, I navigate back.

00:17:18

And now we see Chocolate Milk displayed here. Just to show you, I'm going to re-run my
service out here that I'm going against.
We could search for the word Milk, and we see that it is still Milk, alright. OK. Maybe I
want to go and delete one of these items, I'm going to delete this Pink Lemonade.
I never liked the Pink Lemonade, so it's gone. Things are looking good. Now, let's go out
of here, go back
and connect back to the network. And now I'm ready to sync my changes.

00:16:48

00:17:28
00:17:42
00:17:51
00:17:58
00:18:07

I'm going to hit Refresh here. We're going to let that go. The actual flush of the changes
happens very quickly, OK.
So I deleted that. And I'm going to hit refresh.

00:18:14

I'm going to search for Milk again. And we see that now it says Chocolate Milk. OK

00:18:21

Let's see if we could find our Pink Lemonade in here. And there is no Pink Lemonade. OK

00:18:29

So that's looking good. So now we see our app,

00:18:34

worked offline, made some changes, went back online and then was able to flush those
changes
and refresh the data on our device here. OK So that's great. You can see how easy it is to
create one of these offline applications
with our template. Now that template is just sample code.

00:18:42
00:18:53
00:18:59
00:19:09
00:19:16
00:19:24
00:19:32
00:19:40
00:19:51
00:19:58

There's a lot of different ways you could develop your own Fiori apps to support offline
and there's different APIs you could use there to
develop your own application, right. But it's a great place to start and for you to
understand
how offline works and create a quick app and get it up and going. Now, of course, you
could do the same thing with a native app.
You could write an iOS or an Android app and go that route as well. Or even a Windows
phone app, right?
So lots of different options. And I hope you enjoyed this unit on getting our app running on
our device here.
Now in the next unit, we're going to take a look at different offline configuration properties
we could use to get better performance based on our offline scenario.
So a lot of different things you could do on the server side with an offline config file. And
we'll take a look at that in the next unit.
Thanks a lot. Talk to you then. Bye

19

Week 5 Unit 5
00:00:10
00:00:18
00:00:28
00:00:35
00:00:45
00:00:54
00:01:04
00:01:11
00:01:21
00:01:30
00:01:38
00:01:47
00:01:54
00:02:03
00:02:13
00:02:21
00:02:29
00:02:36
00:02:43
00:02:53
00:03:03
00:03:10
00:03:21
00:03:29
00:03:41
00:03:49

Hi, Jeff here. And in this unit, we're going to take a look at the offline configuration
possibilities on HANA Cloud Platform mobile services.
So there's a lot of different ways you could configure your offline database that gets sent
to the client devices to behave.
Different things, you could cache data and what not. So we're going to take a look at these
options that could help you tune
to get the most out of the offline OData service and get the best performance for your
scenario. OK. So we've already learned that on the HANA Cloud Platform mobile services,
we have this offline OData service. And it's what goes ahead and constructs us the initial
database and sends it to our client devices.
It also has the ability to take an offline request queue that gets sent from the client and
then send those back to the back-end server.
And then give the responses back to our client devices. Then, of course, the ability to do
our refreshes.
So we receive a refresh call from one of our devices. And we go and get all the deltas that
have changed since whenever it was last refreshed
based on some timestamp there. OK, but there's a lot of other options we could do for
caching data
as well as creating things like indexes on properties of some of the tables that exist within
that offline database.
So that's one of the things we can configure, as you can see. A lot of times when you're
searching across a table with many rows,
it makes a lot of sense to have indexes on it. It'll speed up performance and, within this
configuration, we can specify
which of our properties in our OData service we want to have indexed. You can configure
what data gets cached on the server.
You can go so far as changing the default delta determination behavior. We'll take a look
at those things in more detail going forward.
Now all of these offline configuration properties, you just enter these things into a file. Use
some sort of a text editor.
And once you're done with that, you're able to upload it to your application configuration
you have defined out there on the HANA Cloud Platform mobile services
using the admin UI. OK. Now this is only required if you want to change the default
behavior
of the offline store service. So, if you're happy with that and it meets your scenario, you
don't have to do any of this, right.
You don't have to upload any file or anything like that. That said, in a lot of scenarios, it
makes a lot of sense to take some of this into account.
OK. Now this offline configuration file is broken up between end-point configurations and
then more granular defining request configurations.
Now with your application, typically you have one end point, one back-end OData service.
But, that said, it's possible to have multiple of these end points defined, OK. And, for each
one, then you could have many defining requests
and you could configure all of these different things. Now at the end-point configuration
level, that's where you could set your indexes
on the entity properties that you want indexes on. Where you will configure what data will
be allowed in the database that's initially sent to the device, OK.
So, and then you go into a little more detail here. So this database that gets constructed,
you could say whether you want the data loaded inside the HANA Cloud Platform mobile
services. Or you might send an empty database to the client

20

00:03:58
00:04:08
00:04:15
00:04:26
00:04:36
00:04:47

00:05:01
00:05:08
00:05:17

00:05:32
00:05:42
00:05:53
00:05:58
00:06:06
00:06:15
00:06:22
00:06:33
00:06:40
00:06:48
00:06:58
00:07:09
00:07:19
00:07:29
00:07:38
00:07:44
00:07:51

which then you would refresh from there and load the data in that way. More typical, I
think you're going to have the data prepopulated
on the HANA Cloud Platform mobile services but you have different options because
maybe some of this data you don't want to have it loaded
in the middle tier there because you don't want to wait for it to load that data maybe you
want to get that database faster to your users and then let it refresh from the device.
Anyway, different options there, and you pick what matches your scenario. So you could
also of course configure if the data is cached or not.
Refresh interval on the cached data. OK, so you might have some data there and what
the HANA Cloud Platform mobile services will do is when this interval
is met, whatever time value you put in, it will go out and then refresh and call the back-end
OData service and then refresh that cached data at the HANA Cloud Platform mobile
services level.
OK. Now the defining request configuration. This is where we can configure, again,
whether data is cached or not.
So this is a more granular level. The refresh interval on that cached data and whether we
want to change the default delta tracking behavior.
Typically, I don't see a lot of need for changing that but there might be scenarios where
that makes sense. Default behavior is to take deltas into account, and typically that's what
you'd want to do. OK
So, the offline configuration possibilities are a little bit more. The application configuration
file and looking at the end-point configuration, OK.
So our end-point configuration is made up of a name of our end point, and your default
end point, the back-end connection, is just the name of your application configuration.
And in our case, that is com.sap.open So we would give it that name.
Now if I created any secondary end points for my application, then I would use the name
that I gave those secondary end points.
But in our case, we just have a single one. So it's just com.sap.open Then we could
specify if we want to prepopulate the offline db.
If we want to change the default behavior. Default behavior is yes, we want to prepopulate
it on the HANA Cloud Platform mobile services.
Or we could set it to no, that would send an empty database. Or maybe we only want to
prepopulate it with the shared type of data, with that master type of data that we have.
OK, index_type This is where you could specify different indexes we want on our OData
properties.
We'll take a look at an example of this but it's made up of listing out the namespace of
your OData service, then a period,
and then the entity type, and then the properties that we want indexes on. And you can
mark them as ascending or descending here.
OK. Now also request_format. Depending on the back-end OData service, the default is to
request the data in json format.
But some of these only support xml. So we requested to get it back as atom+xml here. OK
On top of that for delta requests, you could change those to request the data in xml as
well
and/or json here. Because some, for example, on SAP Gateway, their delta only supports
passing the data back as xml
when it comes to delta requests. So that's why we've got to be able to have that property
there to configure it
so that we could call back-end SAP systems with OData delta tracking.
OK, now defining request configuration options. So now we're at a more granular level
where we're below the end point now and we could set

21

00:08:01
00:08:06
00:08:16
00:08:23
00:08:33
00:08:43
00:08:51
00:09:00
00:09:09
00:09:20
00:09:27
00:09:35
00:09:48
00:09:55
00:10:01
00:10:15
00:10:24
00:10:29
00:10:36
00:10:46
00:10:53
00:11:01
00:11:08
00:11:17
00:11:23
00:11:32
00:11:40

configuration on each defining request we have. And, again, we use the name of our
defining request.
This would be the same name that you set up in your properties job descript object when
you're creating your defining request
when you're coding the application, so it'd be the same name. You mark whether it's going
to be shared or not.
Again, if it's product data, I'd say yes, it makes a lot of sense. Default is no though.
refresh_interval: How often do I want to go and refresh this cached data
that's going to be on the database with the HANA Cloud Platform mobile services. Also,
whether we want to change the default behavior of how deltas are tracked.
OK. And then also delta_token_lifetime. You know, sometimes maybe if one of these delta
tokens is weeks old,
you have that timed out so that it's ignored and next time that device does a refresh, it just
gets all the data, things like that.
OK. So those are the things for the defining request. Now here's an example of what one
of these configuration files might look like.
We'd have our end point. We would specify our prepopulate db settings here, how often
we're going to refresh things. And then maybe a couple of
what we see here are some indexes that we're going to define on our database that we're
going to send over to the clients.
Then for each defining request, we would go in and say whether we want shared data or
not. If we do say shared data, yes here.
Then you could see that we're entering in a refresh interval, OK. Then you could change
this to a value that makes sense to you. This is in seconds.
OK. From here, we're going to take that file and upload it into our application configuration
area.
You can see when we go in and configure our application configuration, there is an Offline
Configuration area.
I could go here now, select my back-end connection here and then import the offline
configuration for it, OK.
OK. So now let's take a look at a demo. I'll show how we could edit one of these
configuration files and upload it to the HANA Cloud Platform mobile services.
Let's go ahead and do that. First thing I want to do is show you my configuration file.
All I've done here is create my end-point configuration and then my defining request
configuration.
And this is very simple. I only have one defining request that I have within my application.
If we go up here, what we're saying is this is our name,
which is going to be com.sap.open This is the settings for our offline db
if we only want to prepopulate it with shared only data. And I'm just setting the refresh rate
of that to be,
that's basically in seconds, so 15 minutes. Setting too here a couple of properties, OK.
And these properties, you might be wondering where this comes from. So
ODataDemo.Product and then, of course, the name of the properties.
Let's go ahead and look at the metadata of our OData service here. And that will make a
little more sense.
So that OData demo comes from the Namespace of our service here. You see that, it's
ODataDemo right there.
And then the product is the name of the entity type that we want to set an index on. So
that corresponds to a table, right.
This would correspond to the entire database, and this would correspond to a table within
the database.

22

00:11:46
00:11:52
00:12:02
00:12:11
00:12:19
00:12:27
00:12:33

And then the property would be Name, which corresponds to a column, right. So I'm
picking Name and Description.
And if I go back now to my file, we see that, you know, product, and then I'm setting an
ascending index on this.
And then I'm setting here another index on these two columns here with descending on
description.
OK, and now, then I go down to my defining request area here. And I'm just saying yes,
this is shared data for the Products defining request.
And Products just comes from the name of the defining request we gave it within our code
when we were creating that offline store.
And then a refresh rate we could specify on this. OK, so we're prepopulating all the data

00:12:43

only for shared data. Of course, in this case, we only have shared data. So I only have
one defining request, but just to give you an idea of the things you might see here.
OK, so now if we go over to our mobile services here. I'm going to go to com.sap.open

00:12:53

Click Configure. And over here, we see we have Offline Configuration.

00:12:59

And now I could see within this, that I have this back-end connection here with this name.
Now just to briefly go to Backend.
So if we go over here, you could see I have one back end that we've created for the backend URL.
OK. And you can see the connection name, that's where that comes from. So the URL
you put in for the default back end
will take on the name of your application configuration. Now you could see here, though, I
could create more of these.
So that's why you could have multiple end points here. So just go back here to offline
configuration.
And I'm going to go ahead now and import that file. Click Browse, select my offline file.

00:13:09
00:13:15
00:13:23
00:13:29
00:13:37
00:13:45
00:13:52
00:14:02
00:14:12
00:14:23
00:14:36
00:14:45
00:14:52
00:15:02
00:15:11
00:15:24
00:15:32
00:15:39
00:15:47

Click Upload. Now it's going to upload it to the server here. You can see it's uploaded
successfully.
And now I could even click these links and see which defining requests I have and
whether they're shared and how often they're going to be refreshed.
You can see the Client Indexes here. And I can look at the entire configuration as well. OK
So that's how we configure this and how you're able to tune the offline service to give you
the best performance based on your scenario.
Alright. Thank you for listening. This is going to end our unit here as well as this week
where we focus on offline OData.
So what have we learned here over this past week? We've learned that we could create
online and offline applications using
HANA Cloud Platform mobile services on top of using our SAP Mobile Platform SDK.
We could create these for hybrid applications or for native applications. And we saw how
easy it is using the SAP Web IDE
and the Hybrid Application Toolkit to quickly create an offline application. And it was a
great way for us to learn how offline works
and to get an application going within the framework of our openSAP course. Then we
saw how, with offline OData, we could configure it using that application configuration file
to upload it to the HANA Cloud Platform mobile services and get the best performance
based on our offline scenario.
OK. I hope it was a good week for you, I hope you learned a lot. And thank you for
listening.
Next week, we're going to take a look at SAP Mobile Secure and what it offers us to
do different things to secure our apps, you know, using what we call Mobile Place, to
hosting our apps in an app store for your employees.

23

00:15:56
00:16:04

As well as taking a look at how we could create different applications for Fiori and have it
actually build us a Fiori Client.
Anyway, lots of neat stuff. I look forward to hearing from you next week. Thanks for
listening. Goodbye

24

www.sap.com

2015 SAP SE or an SAP affiliate company. All rights reserved.


No part of this publication may be reproduced or transmitted in any form
or for any purpose without the express permission of SAP SE or an SAP
affiliate company.
SAP and other SAP products and services mentioned herein as well as their
respective logos are trademarks or registered trademarks of SAP SE (or an
SAP affiliate company) in Germany and other countries. Please see
http://www.sap.com/corporate-en/legal/copyright/index.epx#trademark for
additional trademark information and notices. Some software products
marketed by SAP SE and its distributors contain proprietary software
components of other software vendors.
National product specifications may vary.
These materials are provided by SAP SE or an SAP affiliate company for
informational purposes only, without representation or warranty of any kind,
and SAP SE or its affiliated companies shall not be liable for errors or
omissions with respect to the materials. The only warranties for SAP SE or
SAP affiliate company products and services are those that are set forth in
the express warranty statements accompanying such products and services,
if any. Nothing herein should be construed as constituting an additional
warranty.
In particular, SAP SE or its affiliated companies have no obligation to pursue
any course of business outlined in this document or any related presentation,
or to develop or release any functionality mentioned therein. This document,
or any related presentation, and SAP SEs or its affiliated companies
strategy and possible future developments, products, and/or platform
directions and functionality are all subject to change and may be changed by
SAP SE or its affiliated companies at any time for any reason without notice.
The information in this document is not a commitment, promise, or legal
obligation to deliver any material, code, or functionality. All forward-looking
statements are subject to various risks and uncertainties that could cause
actual results to differ materially from expectations. Readers are cautioned
not to place undue reliance on these forward-looking statements, which
speak only as of their dates, and they should not be relied upon in making
purchasing decisions.

You might also like