cancel
Showing results for 
Search instead for 
Did you mean: 

Get Entity SODataOfflineStore iOS - SMP3

Former Member
0 Kudos

Hi all,

I migrated the OnlineStore to the OfflineStore and I have some worries.

Requests that worked well on the OnlineStore no longer works on the OfflineStore.

I think that my definingRequest do not populate my local base.

On OnlineStore I used :

[self.onlineStore scheduleReadEntitySet:@"etplnrgrpSet"options:nil...]


And it's working fine.


On Offline I used :


    SODataOfflineStoreOptions *storeOptions = [[SODataOfflineStoreOptions alloc] init];

    storeOptions.host = regData.serverHost;

    storeOptions.port = regData.serverPort;

    storeOptions.enableHttps = YES;

    storeOptions.urlSuffix = [NSString stringWithFormat:@"/%@/%@", regData.resourcePath, regData.farmId];

    storeOptions.serviceRoot = [NSString stringWithFormat:@"/%@", regData.applicationId];

    storeOptions.conversationManager = self.appDelegate.logonHandler.httpConvManager;

    [storeOptions addDefiningRequestWithName:@"req1" url:@"/etplnrgrpSet" retrieveStreams:false];

    offlineStore = [[SODataOfflineStore alloc] init];

   

    [offlineStore setOfflineStoreDelegate:self];

    [offlineStore openStoreWithOptions:storeOptions error:&error];

And :

[self.offlineStore scheduleReadEntitySet:@"etplnrgrpSet"options:nil...]


And I receive an empty response.


Should the entity be declared in particular way on the server?

We can read the entitySet in the same way that Entity?


I tried to set definingRequest and scheduleReadEntitySet like :

     [self.onlineStore scheduleReadEntitySet:@"etplnrgrpSet"options:nil...]

     [storeOptions addDefiningRequestWithName:@"req1" url:@"/etplnrgrp" retrieveStreams:false];

But it's doesn't work.


The data base have too navigations property. Can I use them in OfflineStore? If so how?

How can I check that my local base well populated before making a request?

With a break point for example?



Regards.

Accepted Solutions (1)

Accepted Solutions (1)

kenichi_unnai
Advisor
Advisor
0 Kudos

Okie there should be a clue on the server side trace log. Bump up the trace level as written here (#2):

And - as written in #3, you might want to check how many of your entities are - by using $count. The chances are that the offline store got a timeout error simply it is too large.

You can use the navigation property as written here (Defining Request): http://scn.sap.com/community/developer-center/mobility-platform/blog/2014/10/28/11-smp3-odata-sdk-fo...

Former Member
0 Kudos

Data is synchronized if I specify a definingRequest is not it?

If so, that can not be a timeout because for now I tried to recover a single table, which contains only three strings.

I recovered the server logs but I have the impression that everything is encrypted. (please find attachment)

Are there any way to verify that my base is well filled at the opening of offlinestore ?

Because I don't know how to know if my problem come to my DefiningRequest or my request in local after.

kenichi_unnai
Advisor
Advisor
0 Kudos

A few checklist:

- I see the log indicates you enabled .ini cache (as written here: #14 SMP3 OData SDK - Performance Tuning with Offline Store), can you remove the .ini cache setting in SMP Admin Console and see if the date is properly loaded?

- Do you properly fetch your OData collection and run the CRUD operation in the REST client with the direct connection to the OData source as you want to do with the offline store?

>any way to verify that my base is well filled

The SODataOfflineStoreOpen will be called back as written here:

- Can you double check what callback events are actually called by using the break points?

Former Member
0 Kudos

- I did not find settings for offline here:

I await confirmation from the back-end manager concerning the ini cache.

- On the second point, for now no I don't fetch collection with web navigator because we have problems with SAML authentication with Rest Client. But it is an error 401 : unauthorized, probably related at certificate on my computer.

I don't think this is linked because I can do the same request via OnlineStore with success, with calls for the SAML authentication before in both cases.

And my offlineStore well recognize the different entities on the server:

- For the last point, indeed thanks to offlineStoreDelegate method I note that I spent well in the opening and open status but never in initializing, populating and downloading status ...

Just in case, I tried with :

[storeOptions addDefiningRequestWithName:@"req1" url:@"/etplnrgrpSet" retrieveStreams:false];

[storeOptions addDefiningRequestWithName:@"req1" url:@"/etplnrgrp" retrieveStreams:false];

[storeOptions addDefiningRequestWithName:@"req1" url:@"/plnrgrp" retrieveStreams:false];

kenichi_unnai
Advisor
Advisor
0 Kudos

Okie so you're saying the metadata is properly loaded into the offline store and they are all working fine with online store..good to clarify.

One thing -

[storeOptions addDefiningRequestWithName:@"req1" url:@"/etplnrgrpSet" retrieveStreams:false];

[storeOptions addDefiningRequestWithName:@"req1" url:@"/etplnrgrp" retrieveStreams:false];

...

the req1 is used to identify your OData Endpoint URL string, so you can't re-use the same req1 for other endpoints. Make them like req2, req3.

Is a single req1 working fine?

Former Member
0 Kudos

Yes I know, my example is a single line. Just wanted to say I was replacing my request by another to try and it was not working in any of the cases.

kenichi_unnai
Advisor
Advisor
0 Kudos

Probably you might want to clean up the trace log on the server side and run the app from the very beginning - either Xcode console or server trace log of the offline store should give you some clue.

Former Member
0 Kudos

I added the logs and I installed the application by deleting the previous every time. Indeed, if I install the application after removing the previous one, it causes changes.

When I open my store for the first time without to use addDefiningRequestWithName method, it opens correctly.

If I open it the first time with using addDefiningRequestWithName method, I have an error:

NetworkDomain Code = 3 "[-10,210] The operation failed due to an error on the server." UserInfo = 0x7f9a33957810 NSLocalizedDescription = {[- 10210] The operation failed due to an error on the server.

I attach the logs on success and on error.

For information, I tried the same way as previously, namely by installing the application 3 times with 3 differents DefiningRequest. I have the same error each time.

kenichi_unnai
Advisor
Advisor
0 Kudos

> after removing the previous one, it causes changes.


Actually you just drop the local DB to clean it up as written here: , but you can also reset the app if you want.


>If I open it the first time with using addDefiningRequestWithName method, I have an error:


Can you replace your addDefiningRequestWithName with this depreciated method?


--

    options.definingRequests[@"req1"] = @"/etplnrgrpSet";

--

If you made it work that should mean your SMP server has older SP which doesn't work with the addDefininingRequestWithName. (As you could build it on your Xcode, your SDK should be new enough)

Former Member
0 Kudos

Ok, I'm a little confused but for the web-service etlnrgrpSet, it's totally my fault, I made a careless mistake, I did not copy / paste correctly the web-service. It isn't name etlnrgrpSet but etplnrgrp.

So this web-service is working fine.

Sorry for the lost time.

However, I've still a problem on other web-services more complex.

For example, etordertypes. It is downloaded correctly (I see the delegate method called) for

[storeOptions addDefiningRequestWithName:@"req1" url:@"/etordertypesSet" retrieveStreams:false];


but when I do the query:

[self.store scheduleReadEntitySet:@"etordertypesSet?$filter=OrderType eq 'PM01' or OrderType eq 'PM02' or OrderType eq 'PM03' or OrderType eq 'PM04' or OrderType eq 'PM05' &expand=navworead,navwoop" option:nil completion:...]

I have a success response but it's empty. I have no entity.

Filters and queries work the same way online as offline?

This filter was creating for the online process on the server. To apply a filter in offline, use a different syntax?

The server filters are not imported with definingRequest is not it?

I have to create different on the device?

Former Member
0 Kudos

I followed this tutorial and I can get my entities offline the same way online like this :

[storeOptions addDefiningRequestWithName:@"req1" url:@"/etordertypesSet?$filter=OrderType eq 'PM01' or OrderType eq 'PM02' or OrderType eq 'PM03' or OrderType eq 'PM04' or OrderType eq 'PM05' &expand=navworead,navwoop" retrieveStreams:false];


and


[self.store scheduleReadEntitySet:@"etordertypesSet?&expand=navworead,navwoop" option:nil completion:...]

To get my entities navworead and navwoop using a filter in order type to get all.


But I can't filtering in scheduleReadEntitySet method to get only navworead of one order type. For example, I get an empty response with :[self.store scheduleReadEntitySet:@"etordertypesSet?$filter=OrderType eq 'PM01'&expand=navworead,navwoop" option:nil completion:...]


How to filter navigation properties with Onfline Request ?

Former Member
0 Kudos

I solved my problem !

When I call OrderType that extend navworead and navwoop in my DefiningRequest, this set automatically entities etworead and etwoop in my local data base.

So I can use my filter directly to the entity like this:

[self.store scheduleReadEntitySet:@"etworeadSet?&filter=OrderType eq 'PM01'" option:nil completion:...]


Thank you very much for you help Kenichi.

kenichi_unnai
Advisor
Advisor
0 Kudos

Happy to hear you made it work.

Just to clarify, after you create your OData entities in the offline store, the store works like your local OData server. So generic query strings such as $filter works even if your OData service doesn't implement on the server side. That's a neat bonus feature of Offline store.

And actually $expand should work in the Read operation too. I think you forgot to add $ string as written above.

And yes, if you load the collections via $expand, all the data are loaded in your offline store so generally you just need to use $filter, etc against that local OData server (= offline store).

Former Member
0 Kudos

An other fast question :

I have not found how to make synchronous requests with offlineStore. How is it done?

kenichi_unnai
Advisor
Advisor
0 Kudos

As a rule of thumb:

online store = sync

offline store = async

So you make use of Flush & Refresh with offline store.

Former Member
0 Kudos

Sorry I misspoke, I mean make a request locally.

How to make a synchronous request in my database?

kenichi_unnai
Advisor
Advisor
0 Kudos

As written here:

You can use the same CRUD methods for both online & offline store (that's a beauty of the API).

Probably you might want to check how the sample code looks like:

0 Kudos

Hi Kenichi ,

I have got a big problem

I have opened two online and offline stores with two different base URL's, MWORKLIST_SRV and INVOICE_SRV.

But when i am trying to run  my application in offline, Second base url's web service call (Ex: Tracks)  are  hitting first base url "MWORKLIST_SRV", As it should hit second base URL "INVOICE_SRV".

Attached the screen shot for your reference

Please help me on this

Thanks,

Khaleel

kenichi_unnai
Advisor
Advisor
0 Kudos

Hi Khaleel,

Perhaps you might want to open a new thread on this? Please don't forget the screenshot too.

0 Kudos

Hi Kenichi,


This is the code which i have written to open offline stores.


Sorry, I could not attach the screen shot,Please find attachment now


-(void)openOfflineStoreForKTSServices

{

   

    ApplicationSettings *settings = [ApplicationSettings getSettingsFromUserDefaults];

    NSError *error = nil;

   

    self.offlineStoreForInnovapptiveServices = [[SODataOfflineStore alloc]init];

   

    SODataOfflineStoreOptions *options = [[SODataOfflineStoreOptions alloc] init];

    options.host = settings.smpHostAddress;

    options.port = [settings.mbsPort integerValue];

    options.serviceRoot = settings.appID;

    options.conversationManager = self.httpConversationManager;

    options.enableHttps = settings.enableHttps;

    options.enableRepeatableRequests = YES;

    //options.storeName = @"Innovapptive";

   

    NSLog(@"Options :%@",options);

    options.storeEncryptionKey = @"MyEncryptionKey";

    [options addDefiningRequestWithName:@"req1" url:@"UserWorkitemsCollection" retrieveStreams:NO];



    [self.offlineStoreForInnovapptiveServices setOfflineStoreDelegate:self];

    [self.offlineStoreForInnovapptiveServices openStoreWithOptions:options error:&error];

   

   

   

}

-(void)openOfflineStoreForPTS_Services

{

   

    ApplicationSettings *settings = [ApplicationSettings getSettingsFromUserDefaults];

    NSError *error = nil;

   

    self.offlineStoreForPTS_Services = [[SODataOfflineStore alloc]init];

    SODataOfflineStoreOptions *options = [[SODataOfflineStoreOptions alloc] init];

   

    options.host = settings.smpHostAddress;

    options.port = [settings.mbsPort integerValue];

    options.serviceRoot = @"com.innovapptive.pts";//com.innovapptive.pts

    options.conversationManager = self.httpConversationManager;

    options.enableHttps = settings.enableHttps;

//    options.enableRepeatableRequests = YES;

//    options.storeName = @"PTS";

    options.storeEncryptionKey = @"MyEncryptionKeyPTS";

    [options addDefiningRequestWithName:@"req1" url:@"Tracks" retrieveStreams:NO]; //?$filter=MyApprovals eq true&$inlinecount=allpages

   

    [self.offlineStoreForPTS_Services setOfflineStoreDelegate:self];

    [self.offlineStoreForPTS_Services openStoreWithOptions:options error:&error];

   

}


Correct me if i have wriiten anything wrong.


Thanks,

Khaleel

0 Kudos

Opened the new Thread at the above link

Answers (0)